Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-06-11 00:10:14 +00:00
parent b20c558db2
commit 9ae44f98c8
21 changed files with 530 additions and 183 deletions

View file

@ -107,7 +107,6 @@ export default {
:items="users"
:fields="$options.fields"
:empty-text="s__('AdminUsers|No users found')"
data-qa-selector="user_row_content"
show-empty
stacked="md"
:tbody-tr-attr="{ 'data-qa-selector': 'user_row_content' }"

View file

@ -1,7 +1,9 @@
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { SIDEBAR_COLLAPSED_CLASS } from './contextual_sidebar';
const isRefactoring = document.body.classList.contains('sidebar-refactoring');
const HIDE_INTERVAL_TIMEOUT = 300;
const COLLAPSED_PANEL_WIDTH = isRefactoring ? 48 : 50;
const IS_OVER_CLASS = 'is-over';
const IS_ABOVE_CLASS = 'is-above';
const IS_SHOWING_FLY_OUT_CLASS = 'is-showing-fly-out';
@ -22,12 +24,7 @@ export const setOpenMenu = (menu = null) => {
export const slope = (a, b) => (b.y - a.y) / (b.x - a.x);
let headerHeight = 50;
export const getHeaderHeight = () => headerHeight;
const setHeaderHeight = () => {
headerHeight = sidebar.offsetTop;
};
export const getHeaderHeight = () => sidebar?.offsetTop || 0;
export const isSidebarCollapsed = () =>
sidebar && sidebar.classList.contains(SIDEBAR_COLLAPSED_CLASS);
@ -87,14 +84,20 @@ export const hideMenu = (el) => {
};
export const moveSubItemsToPosition = (el, subItems) => {
const hasSubItems = subItems.parentNode.querySelector('.has-sub-items');
const header = subItems.querySelector('.fly-out-top-item');
const boundingRect = el.getBoundingClientRect();
const top = calculateTop(boundingRect, subItems.offsetHeight);
const left = sidebar ? sidebar.offsetWidth : 50;
const left = sidebar ? sidebar.offsetWidth : COLLAPSED_PANEL_WIDTH;
let top = calculateTop(boundingRect, subItems.offsetHeight);
if (isRefactoring && hasSubItems) {
top -= header.offsetHeight;
} else if (isRefactoring) {
top = boundingRect.top;
}
const isAbove = top < boundingRect.top;
subItems.classList.add('fly-out-list');
subItems.style.transform = `translate3d(${left}px, ${Math.floor(top) - headerHeight}px, 0)`; // eslint-disable-line no-param-reassign
subItems.style.transform = `translate3d(${left}px, ${Math.floor(top) - getHeaderHeight()}px, 0)`; // eslint-disable-line no-param-reassign
const subItemsRect = subItems.getBoundingClientRect();
menuCornerLocs = [
@ -188,8 +191,6 @@ export default () => {
});
}
requestIdleCallback(setHeaderHeight);
items.forEach((el) => {
const subItems = el.querySelector('.sidebar-sub-level-items');

View file

@ -22,7 +22,7 @@ $top-level-item-color: $purple-900;
color: $gray-darkest;
}
&.ui-indigo .nav-sidebar li.active > a {
&.ui-indigo .nav-sidebar li.active:not(.fly-out-top-item) > a {
color: $top-level-item-color;
}
@ -99,15 +99,15 @@ $top-level-item-color: $purple-900;
min-height: unset;
}
.fly-out-top-item {
display: block;
.fly-out-top-item:not(.divider) {
display: block !important;
}
.avatar-container {
margin: 0 auto;
}
li.active > a {
li.active:not(.fly-out-top-item) > a {
background-color: $indigo-900-alpha-008;
}
}
@ -115,38 +115,39 @@ $top-level-item-color: $purple-900;
@mixin sub-level-items-flyout {
.sidebar-sub-level-items {
@include media-breakpoint-up(sm) {
position: fixed;
top: 0;
left: 0;
@include gl-fixed;
@include gl-top-0;
@include gl-left-0;
@include gl-ml-3;
@include gl-mt-0;
@include gl-px-0;
@include gl-pb-2;
@include gl-pt-0;
min-width: 150px;
margin-top: -1px;
padding: 4px 1px;
background-color: $white;
box-shadow: 2px 1px 3px $dropdown-shadow-color;
border: 1px solid $gray-darker;
border-left: 0;
border-radius: 0 3px 3px 0;
background-color: $gray-10;
box-shadow: 0 $gl-spacing-scale-2 $gl-spacing-scale-5 $t-gray-a-24, 0 0 $gl-spacing-scale-1 $t-gray-a-24;
border-style: none;
border-radius: $border-radius-default;
&::before {
content: '';
position: absolute;
top: -30px;
bottom: -30px;
left: -10px;
right: -30px;
z-index: -1;
.divider {
@include gl-display-none;
}
.divider + li > a {
@include gl-mt-2;
}
li:last-of-type a {
@include gl-mb-0;
}
&.is-above {
margin-top: 1px;
@include gl-mt-0;
}
}
.divider {
height: 1px;
margin: 4px -1px;
padding: 0;
background-color: $dropdown-divider-bg;
}
a {
@include gl-px-4;
}
.fly-out-top-item {
@ -200,6 +201,8 @@ $top-level-item-color: $purple-900;
@include gl-align-items-center;
@include gl-rounded-base;
@include gl-w-auto;
@include gl-line-height-normal;
transition: none;
margin: $sidebar-top-item-tb-margin $sidebar-top-item-lr-margin;
&:hover {
@ -207,6 +210,52 @@ $top-level-item-color: $purple-900;
}
}
@mixin fly-out-top-item($has-sub-items: false) {
@include gl-display-none;
a,
a:hover,
&.active a,
.fly-out-top-item-container {
@include gl-mx-0;
@include gl-px-5;
@include gl-cursor-default;
@include gl-pointer-events-none;
@include gl-font-sm;
background-color: $purple-900;
color: $white;
@if $has-sub-items {
@include gl-mt-n2;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
} @else {
@include gl-my-n2;
@include gl-mt-0;
@include gl-relative;
background-color: $black;
strong {
@include gl-font-weight-normal;
}
&::before {
@include gl-absolute;
content: '';
display: block;
top: 50%;
left: $gl-spacing-scale-3/-2;
margin-top: -$gl-spacing-scale-3;
width: 0;
height: 0;
border-top: $gl-spacing-scale-3 solid transparent;
border-bottom: $gl-spacing-scale-3 solid transparent;
border-right: $gl-spacing-scale-3 solid $black;
}
}
}
}
//
// PAGE-LAYOUT
//
@ -258,7 +307,6 @@ $top-level-item-color: $purple-900;
a {
@include gl-text-decoration-none;
@include gl-line-height-normal;
color: $top-level-item-color;
}
@ -269,7 +317,8 @@ $top-level-item-color: $purple-900;
flex: 1;
}
> a {
> a,
> .fly-out-top-item-container {
@include top-level-item;
}
@ -278,8 +327,10 @@ $top-level-item-color: $purple-900;
font-weight: $gl-font-weight-bold;
}
> a:not(.has-sub-items) {
background-color: $indigo-900-alpha-008;
&:not(.fly-out-top-item) {
> a:not(.has-sub-items) {
background-color: $indigo-900-alpha-008;
}
}
}
}
@ -298,8 +349,16 @@ $top-level-item-color: $purple-900;
margin-right: 8px;
}
.fly-out-top-item {
display: none;
a:not(.has-sub-items) + .sidebar-sub-level-items {
.fly-out-top-item {
@include fly-out-top-item($has-sub-items: false);
}
}
a.has-sub-items + .sidebar-sub-level-items {
.fly-out-top-item {
@include fly-out-top-item($has-sub-items: true);
}
}
@media (min-width: map-get($grid-breakpoints, md)) and (max-width: map-get($grid-breakpoints, xl) - 1px) {
@ -356,8 +415,8 @@ $top-level-item-color: $purple-900;
}
.sidebar-sub-level-items {
@include gl-pb-0;
display: none;
@include gl-py-0;
@include gl-display-none;
&:not(.fly-out-list) {
li > a {

View file

@ -1251,7 +1251,10 @@ body.sidebar-refactoring.gl-dark
.sidebar-context-title {
color: #c4c4c4;
}
body.sidebar-refactoring.ui-indigo .nav-sidebar li.active > a {
body.sidebar-refactoring.ui-indigo
.nav-sidebar
li.active:not(.fly-out-top-item)
> a {
color: #2f2a6b;
}
body.sidebar-refactoring.ui-indigo
@ -1325,20 +1328,22 @@ body.sidebar-refactoring
}
body.sidebar-refactoring
.nav-sidebar.sidebar-collapsed-desktop
.fly-out-top-item {
display: block;
.fly-out-top-item:not(.divider) {
display: block !important;
}
body.sidebar-refactoring
.nav-sidebar.sidebar-collapsed-desktop
.avatar-container {
margin: 0 auto;
}
body.sidebar-refactoring .nav-sidebar.sidebar-collapsed-desktop li.active > a {
body.sidebar-refactoring
.nav-sidebar.sidebar-collapsed-desktop
li.active:not(.fly-out-top-item)
> a {
background-color: rgba(41, 41, 97, 0.08);
}
body.sidebar-refactoring .nav-sidebar a {
text-decoration: none;
line-height: 1rem;
color: #2f2a6b;
}
body.sidebar-refactoring .nav-sidebar li {
@ -1347,7 +1352,8 @@ body.sidebar-refactoring .nav-sidebar li {
body.sidebar-refactoring .nav-sidebar li .nav-item-name {
flex: 1;
}
body.sidebar-refactoring .nav-sidebar li > a {
body.sidebar-refactoring .nav-sidebar li > a,
body.sidebar-refactoring .nav-sidebar li > .fly-out-top-item-container {
padding-left: 0.75rem;
padding-right: 0.75rem;
padding-top: 0.5rem;
@ -1356,12 +1362,16 @@ body.sidebar-refactoring .nav-sidebar li > a {
align-items: center;
border-radius: 0.25rem;
width: auto;
line-height: 1rem;
margin: 1px 4px;
}
body.sidebar-refactoring .nav-sidebar li.active > a {
font-weight: 600;
}
body.sidebar-refactoring .nav-sidebar li.active > a:not(.has-sub-items) {
body.sidebar-refactoring
.nav-sidebar
li.active:not(.fly-out-top-item)
> a:not(.has-sub-items) {
background-color: rgba(41, 41, 97, 0.08);
}
body.sidebar-refactoring .nav-sidebar ul {
@ -1377,9 +1387,137 @@ body.sidebar-refactoring .nav-sidebar .nav-icon-container {
display: flex;
margin-right: 8px;
}
body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item {
display: none;
}
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
a,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item.active
a,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container {
margin-left: 0;
margin-right: 0;
padding-left: 1rem;
padding-right: 1rem;
cursor: default;
pointer-events: none;
font-size: 0.75rem;
background-color: #2f2a6b;
color: #333;
margin-top: -0.25rem;
margin-bottom: -0.25rem;
margin-top: 0;
position: relative;
background-color: #fff;
}
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
a
strong,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item.active
a
strong,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container
strong {
font-weight: 400;
}
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
a::before,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item.active
a::before,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container::before {
position: absolute;
content: "";
display: block;
top: 50%;
left: -0.25rem;
margin-top: -0.5rem;
width: 0;
height: 0;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-right: 0.5rem solid #fff;
}
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item {
display: none;
}
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item
a,
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item.active
a,
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container {
margin-left: 0;
margin-right: 0;
padding-left: 1rem;
padding-right: 1rem;
cursor: default;
pointer-events: none;
font-size: 0.75rem;
background-color: #2f2a6b;
color: #333;
margin-top: -0.25rem;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
@media (min-width: 768px) and (max-width: 1199px) {
body.sidebar-refactoring .nav-sidebar:not(.sidebar-expanded-mobile) {
width: 48px;
@ -1417,8 +1555,8 @@ body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
}
body.sidebar-refactoring
.nav-sidebar:not(.sidebar-expanded-mobile)
.fly-out-top-item {
display: block;
.fly-out-top-item:not(.divider) {
display: block !important;
}
body.sidebar-refactoring
.nav-sidebar:not(.sidebar-expanded-mobile)
@ -1427,7 +1565,7 @@ body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
}
body.sidebar-refactoring
.nav-sidebar:not(.sidebar-expanded-mobile)
li.active
li.active:not(.fly-out-top-item)
> a {
background-color: rgba(41, 41, 97, 0.08);
}
@ -1516,6 +1654,7 @@ body.sidebar-refactoring .nav-sidebar-inner-scroll > div.context-header a {
align-items: center;
border-radius: 0.25rem;
width: auto;
line-height: 1rem;
margin: 1px 4px;
padding: 0.25rem;
margin-bottom: 0.25rem;
@ -1617,6 +1756,7 @@ body.sidebar-refactoring
color: #9dc7f1;
}
body.sidebar-refactoring .sidebar-sub-level-items {
padding-top: 0;
padding-bottom: 0;
display: none;
}

View file

@ -1213,7 +1213,10 @@ input {
display: none;
}
}
body.sidebar-refactoring.ui-indigo .nav-sidebar li.active > a {
body.sidebar-refactoring.ui-indigo
.nav-sidebar
li.active:not(.fly-out-top-item)
> a {
color: #2f2a6b;
}
body.sidebar-refactoring.ui-indigo
@ -1287,20 +1290,22 @@ body.sidebar-refactoring
}
body.sidebar-refactoring
.nav-sidebar.sidebar-collapsed-desktop
.fly-out-top-item {
display: block;
.fly-out-top-item:not(.divider) {
display: block !important;
}
body.sidebar-refactoring
.nav-sidebar.sidebar-collapsed-desktop
.avatar-container {
margin: 0 auto;
}
body.sidebar-refactoring .nav-sidebar.sidebar-collapsed-desktop li.active > a {
body.sidebar-refactoring
.nav-sidebar.sidebar-collapsed-desktop
li.active:not(.fly-out-top-item)
> a {
background-color: rgba(41, 41, 97, 0.08);
}
body.sidebar-refactoring .nav-sidebar a {
text-decoration: none;
line-height: 1rem;
color: #2f2a6b;
}
body.sidebar-refactoring .nav-sidebar li {
@ -1309,7 +1314,8 @@ body.sidebar-refactoring .nav-sidebar li {
body.sidebar-refactoring .nav-sidebar li .nav-item-name {
flex: 1;
}
body.sidebar-refactoring .nav-sidebar li > a {
body.sidebar-refactoring .nav-sidebar li > a,
body.sidebar-refactoring .nav-sidebar li > .fly-out-top-item-container {
padding-left: 0.75rem;
padding-right: 0.75rem;
padding-top: 0.5rem;
@ -1318,12 +1324,16 @@ body.sidebar-refactoring .nav-sidebar li > a {
align-items: center;
border-radius: 0.25rem;
width: auto;
line-height: 1rem;
margin: 1px 4px;
}
body.sidebar-refactoring .nav-sidebar li.active > a {
font-weight: 600;
}
body.sidebar-refactoring .nav-sidebar li.active > a:not(.has-sub-items) {
body.sidebar-refactoring
.nav-sidebar
li.active:not(.fly-out-top-item)
> a:not(.has-sub-items) {
background-color: rgba(41, 41, 97, 0.08);
}
body.sidebar-refactoring .nav-sidebar ul {
@ -1339,9 +1349,137 @@ body.sidebar-refactoring .nav-sidebar .nav-icon-container {
display: flex;
margin-right: 8px;
}
body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item {
display: none;
}
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
a,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item.active
a,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container {
margin-left: 0;
margin-right: 0;
padding-left: 1rem;
padding-right: 1rem;
cursor: default;
pointer-events: none;
font-size: 0.75rem;
background-color: #2f2a6b;
color: #fff;
margin-top: -0.25rem;
margin-bottom: -0.25rem;
margin-top: 0;
position: relative;
background-color: #000;
}
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
a
strong,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item.active
a
strong,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container
strong {
font-weight: 400;
}
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
a::before,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item.active
a::before,
body.sidebar-refactoring
.nav-sidebar
a:not(.has-sub-items)
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container::before {
position: absolute;
content: "";
display: block;
top: 50%;
left: -0.25rem;
margin-top: -0.5rem;
width: 0;
height: 0;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-right: 0.5rem solid #000;
}
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item {
display: none;
}
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item
a,
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item.active
a,
body.sidebar-refactoring
.nav-sidebar
a.has-sub-items
+ .sidebar-sub-level-items
.fly-out-top-item
.fly-out-top-item-container {
margin-left: 0;
margin-right: 0;
padding-left: 1rem;
padding-right: 1rem;
cursor: default;
pointer-events: none;
font-size: 0.75rem;
background-color: #2f2a6b;
color: #fff;
margin-top: -0.25rem;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
@media (min-width: 768px) and (max-width: 1199px) {
body.sidebar-refactoring .nav-sidebar:not(.sidebar-expanded-mobile) {
width: 48px;
@ -1379,8 +1517,8 @@ body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
}
body.sidebar-refactoring
.nav-sidebar:not(.sidebar-expanded-mobile)
.fly-out-top-item {
display: block;
.fly-out-top-item:not(.divider) {
display: block !important;
}
body.sidebar-refactoring
.nav-sidebar:not(.sidebar-expanded-mobile)
@ -1389,7 +1527,7 @@ body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
}
body.sidebar-refactoring
.nav-sidebar:not(.sidebar-expanded-mobile)
li.active
li.active:not(.fly-out-top-item)
> a {
background-color: rgba(41, 41, 97, 0.08);
}
@ -1478,6 +1616,7 @@ body.sidebar-refactoring .nav-sidebar-inner-scroll > div.context-header a {
align-items: center;
border-radius: 0.25rem;
width: auto;
line-height: 1rem;
margin: 1px 4px;
padding: 0.25rem;
margin-bottom: 0.25rem;
@ -1579,6 +1718,7 @@ body.sidebar-refactoring
color: #0b5cad;
}
body.sidebar-refactoring .sidebar-sub-level-items {
padding-top: 0;
padding-bottom: 0;
display: none;
}

View file

@ -161,7 +161,7 @@ class Packages::Package < ApplicationRecord
after_commit :update_composer_cache, on: :destroy, if: -> { composer? }
def self.only_maven_packages_with_path(path, use_cte: false)
if use_cte && Feature.enabled?(:maven_metadata_by_path_with_optimization_fence, default_enabled: :yaml)
if use_cte
# This is an optimization fence which assumes that looking up the Metadatum record by path (globally)
# and then filter down the packages (by project or by group and subgroups) will be cheaper than
# looking up all packages within a project or group and filter them by path.

View file

@ -2,7 +2,7 @@
- if group_packages_nav?
= nav_link(controller: ['groups/packages', 'groups/registry/repositories', 'groups/dependency_proxies']) do
= link_to packages_link, title: _('Packages') do
= link_to packages_link, title: _('Packages'), class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('package')
%span.nav-item-name

View file

@ -11,7 +11,7 @@
= _('Admin Area')
%ul.sidebar-top-level-items{ data: { qa_selector: 'admin_sidebar_overview_submenu_content' } }
= nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do
= link_to admin_root_path do
= link_to admin_root_path, class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('overview')
%span.nav-item-name
@ -52,7 +52,7 @@
= _('Gitaly Servers')
= nav_link(controller: admin_analytics_nav_links) do
= link_to admin_dev_ops_report_path, data: { qa_selector: 'admin_analytics_link' } do
= link_to admin_dev_ops_report_path, data: { qa_selector: 'admin_analytics_link' }, class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('chart')
%span.nav-item-name
@ -74,7 +74,7 @@
= _('Usage Trends')
= nav_link(controller: admin_monitoring_nav_links) do
= link_to admin_system_info_path, data: { qa_selector: 'admin_monitoring_link' } do
= link_to admin_system_info_path, data: { qa_selector: 'admin_monitoring_link' }, class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('monitor')
%span.nav-item-name
@ -247,7 +247,7 @@
= _('Appearance')
= nav_link(controller: [:application_settings, :integrations]) do
= link_to general_admin_application_settings_path do
= link_to general_admin_application_settings_path, class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('settings')
%span.nav-item-name.qa-admin-settings-item

View file

@ -4,7 +4,7 @@
- if navbar_links.any?
= nav_link(path: all_paths) do
= link_to analytics_link.link, {class: 'shortcuts-analytics', data: { qa_selector: 'analytics_anchor' } } do
= link_to analytics_link.link, {class: 'shortcuts-analytics has-sub-items', data: { qa_selector: 'analytics_anchor' } } do
.nav-icon-container
= sprite_icon('chart')
%span.nav-item-name{ data: { qa_selector: 'analytics_link' } }

View file

@ -19,7 +19,7 @@
- paths = group_overview_nav_link_paths
= nav_link(path: paths, unless: -> { current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
- information_link = sidebar_refactor_enabled? ? activity_group_path(@group) : group_path(@group)
= link_to information_link do
= link_to information_link, class: 'has-sub-items' do
.nav-icon-container
- sprite = sidebar_refactor_enabled? ? 'group' : 'home'
= sprite_icon(sprite)
@ -62,7 +62,7 @@
- if group_sidebar_link?(:issues)
= nav_link(path: group_issues_sub_menu_items, unless: -> { current_path?('issues_analytics#show') }) do
= link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' } do
= link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' }, class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('issues')
%span.nav-item-name
@ -157,7 +157,7 @@
- if group_sidebar_link?(:settings)
= nav_link(path: group_settings_nav_link_paths) do
= link_to edit_group_path(@group) do
= link_to edit_group_path(@group), class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('settings')
%span.nav-item-name{ data: { qa_selector: 'group_settings' } }

View file

@ -18,7 +18,7 @@
= f.label :auto_cancel_pending_pipelines, class: 'form-check-label' do
%strong= _("Auto-cancel redundant pipelines")
.form-text.text-muted
= _("New pipelines cause older pending pipelines on the same branch to be cancelled.")
= _("New pipelines cause older pending or running pipelines on the same branch to be cancelled.")
= link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'auto-cancel-redundant-pipelines'), target: '_blank'
.form-group

View file

@ -16,11 +16,12 @@
%ul.sidebar-sub-level-items{ class: ('is-fly-out-only' unless sidebar_menu.has_renderable_items?) }
= nav_link(**sidebar_menu.all_active_routes, html_options: { class: 'fly-out-top-item' } ) do
- if sidebar_refactor_disabled?
= link_to sidebar_menu.link, **sidebar_menu.collapsed_container_html_options do
= link_to sidebar_menu.link, class: "'has-sub-items' if sidebar_menu.has_renderable_items?", **sidebar_menu.collapsed_container_html_options do
= render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu
- else
= render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu
%span.fly-out-top-item-container
= render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu
- if sidebar_menu.has_items?
- if sidebar_menu.has_renderable_items?
%li.divider.fly-out-top-item
= render partial: 'shared/nav/sidebar_menu_item', collection: sidebar_menu.renderable_items

View file

@ -1,8 +0,0 @@
---
name: maven_metadata_by_path_with_optimization_fence
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57041
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/325460
milestone: '13.11'
type: development
group: group::optimize
default_enabled: true

View file

@ -49,8 +49,12 @@ When a user is being [impersonated](../user/admin_area/index.md#user-impersonati
### Group events **(PREMIUM)**
A user with a Owner role (or above) can retrieve group audit events of all users.
A user with a Developer or Maintainer role is limited to group audit events based on their individual actions.
A user with:
- Owner role (or above) can retrieve group audit events of all users.
- Developer or Maintainer role is limited to group audit events based on their individual actions.
Group events do not include project audit events.
To view a group's audit events, navigate to **Group > Security & Compliance > Audit Events**.
From there, you can see the following actions:
@ -120,10 +124,11 @@ Server-wide audit events introduce the ability to observe user actions across
the entire instance of your GitLab server, making it easy to understand who
changed what and when for audit purposes.
Instance events do not include group or project audit events.
To view the server-wide administrator log, visit **Admin Area > Monitoring > Audit Events**.
In addition to the group and project events, the following user actions are also
recorded:
The following user actions are recorded:
- Sign-in events and the authentication type (such as standard, LDAP, or OmniAuth)
- Failed sign-ins

View file

@ -11,6 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## Instance Audit Events **(PREMIUM SELF)**
The Audit Events API allows you to retrieve [instance audit events](../administration/audit_events.md#instance-events).
This API cannot retrieve group or project audit events.
To retrieve audit events using the API, you must [authenticate yourself](README.md#authentication) as an Administrator.
@ -133,6 +134,7 @@ Example response:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34078) in GitLab 12.5.
The Group Audit Events API allows you to retrieve [group audit events](../administration/audit_events.md#group-events).
This API cannot retrieve project audit events.
A user with a Owner role (or above) can retrieve group audit events of all users.
A user with a Developer or Maintainer role is limited to group audit events based on their individual actions.

View file

@ -7229,6 +7229,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="boardepicchildreniid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="boardepicchildreniidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="boardepicchildreniids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="boardepicchildrenincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="boardepicchildrenincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="boardepicchildrenlabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="boardepicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
@ -8418,6 +8419,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="epicchildreniid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="epicchildreniidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="epicchildreniids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="epicchildrenincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="epicchildrenincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="epicchildrenlabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="epicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
@ -9020,6 +9022,7 @@ Returns [`Epic`](#epic).
| <a id="groupepiciid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="groupepiciidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="groupepiciids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="groupepicincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="groupepicincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="groupepiclabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="groupepicmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
@ -9063,6 +9066,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupepicsiid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="groupepicsiidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="groupepicsiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="groupepicsincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="groupepicsincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="groupepicslabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="groupepicsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |

View file

@ -795,6 +795,10 @@ Parameters:
| `shared_runners_minutes_limit` | integer | no | **(PREMIUM SELF)** Pipeline minutes quota for this group (included in plan). Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0` |
| `extra_shared_runners_minutes_limit` | integer | no | **(PREMIUM SELF)** Extra pipeline minutes quota for this group (purchased in addition to the minutes included in the plan). |
NOTE:
On GitLab SaaS, you must use the GitLab UI to create groups without a parent group. You cannot
use the API to do this.
### Options for `default_branch_protection`
The `default_branch_protection` attribute determines whether developers and maintainers can push to the applicable [default branch](../user/project/repository/branches/default.md), as described in the following table:

View file

@ -109,7 +109,7 @@ Create an issue when you want to track bugs or future work.
Prerequisites:
- A minimum of Contributor access to a project in GitLab.
- You must have at least the Developer role for a project.
To create an issue:

View file

@ -611,8 +611,11 @@ Now navigate to your project's **Packages & Registries** page and view the publi
### Publishing a package with the same name or version
When you publish a package with the same name or version as an existing package,
the existing package is overwritten.
When you publish a package with the same name and version as an existing package, the new package
files are added to the existing package. You can still use the UI or API to access and view the
existing package's older files.
To delete these older package versions, consider using the Packages API or the UI.
#### Do not allow duplicate Maven packages

View file

@ -22006,7 +22006,7 @@ msgstr ""
msgid "New password"
msgstr ""
msgid "New pipelines cause older pending pipelines on the same branch to be cancelled."
msgid "New pipelines cause older pending or running pipelines on the same branch to be cancelled."
msgstr ""
msgid "New project"
@ -28898,6 +28898,21 @@ msgstr ""
msgid "SecurityOrchestration|Security policy project"
msgstr ""
msgid "SecurityPolicies|Description"
msgstr ""
msgid "SecurityPolicies|Enforcement status"
msgstr ""
msgid "SecurityPolicies|Latest scan"
msgstr ""
msgid "SecurityPolicies|Scan execution"
msgstr ""
msgid "SecurityPolicies|view results"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""

View file

@ -17,107 +17,89 @@ RSpec.describe ::Packages::Maven::PackageFinder do
group.add_developer(user)
end
shared_examples 'Packages::Maven::PackageFinder examples' do
describe '#execute!' do
subject { finder.execute! }
describe '#execute!' do
subject { finder.execute! }
shared_examples 'handling valid and invalid paths' do
context 'with a valid path' do
let(:param_path) { package.maven_metadatum.path }
shared_examples 'handling valid and invalid paths' do
context 'with a valid path' do
let(:param_path) { package.maven_metadatum.path }
it { is_expected.to eq(package) }
end
context 'with an invalid path' do
let(:param_path) { 'com/example/my-app/1.0-SNAPSHOT' }
it 'raises an error' do
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
end
end
context 'with an uninstallable package' do
let(:param_path) { package.maven_metadatum.path }
before do
package.update_column(:status, 1)
end
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end
it { is_expected.to eq(package) }
end
context 'within the project' do
let(:project_or_group) { project }
context 'with an invalid path' do
let(:param_path) { 'com/example/my-app/1.0-SNAPSHOT' }
it_behaves_like 'handling valid and invalid paths'
end
context 'within a group' do
let(:project_or_group) { group }
it_behaves_like 'handling valid and invalid paths'
end
context 'across all projects' do
it 'raises an error' do
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
end
end
context 'versionless maven-metadata.xml package' do
let_it_be(:sub_group1) { create(:group, parent: group) }
let_it_be(:sub_group2) { create(:group, parent: group) }
let_it_be(:project1) { create(:project, group: sub_group1) }
let_it_be(:project2) { create(:project, group: sub_group2) }
let_it_be(:project3) { create(:project, group: sub_group1) }
let_it_be(:package_name) { 'foo' }
let_it_be(:package1) { create(:maven_package, project: project1, name: package_name, version: nil) }
let_it_be(:package2) { create(:maven_package, project: project2, name: package_name, version: nil) }
let_it_be(:package3) { create(:maven_package, project: project3, name: package_name, version: nil) }
let(:project_or_group) { group }
let(:param_path) { package_name }
context 'with an uninstallable package' do
let(:param_path) { package.maven_metadatum.path }
before do
sub_group1.add_developer(user)
sub_group2.add_developer(user)
# the package with the most recently published file should be returned
create(:package_file, :xml, package: package2)
package.update_column(:status, 1)
end
context 'without order by package file' do
it { is_expected.to eq(package3) }
end
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end
end
context 'with order by package file' do
let(:param_order_by_package_file) { true }
context 'within the project' do
let(:project_or_group) { project }
it { is_expected.to eq(package2) }
end
it_behaves_like 'handling valid and invalid paths'
end
context 'within a group' do
let(:project_or_group) { group }
it_behaves_like 'handling valid and invalid paths'
end
context 'across all projects' do
it 'raises an error' do
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
end
end
context 'versionless maven-metadata.xml package' do
let_it_be(:sub_group1) { create(:group, parent: group) }
let_it_be(:sub_group2) { create(:group, parent: group) }
let_it_be(:project1) { create(:project, group: sub_group1) }
let_it_be(:project2) { create(:project, group: sub_group2) }
let_it_be(:project3) { create(:project, group: sub_group1) }
let_it_be(:package_name) { 'foo' }
let_it_be(:package1) { create(:maven_package, project: project1, name: package_name, version: nil) }
let_it_be(:package2) { create(:maven_package, project: project2, name: package_name, version: nil) }
let_it_be(:package3) { create(:maven_package, project: project3, name: package_name, version: nil) }
let(:project_or_group) { group }
let(:param_path) { package_name }
before do
sub_group1.add_developer(user)
sub_group2.add_developer(user)
# the package with the most recently published file should be returned
create(:package_file, :xml, package: package2)
end
context 'without order by package file' do
it { is_expected.to eq(package3) }
end
context 'with order by package file' do
let(:param_order_by_package_file) { true }
it { is_expected.to eq(package2) }
end
end
end
context 'when the maven_metadata_by_path_with_optimization_fence feature flag is off' do
before do
stub_feature_flags(maven_metadata_by_path_with_optimization_fence: false)
end
it 'uses CTE in the query' do
sql = described_class.new(user, group, path: package.maven_metadatum.path).send(:packages).to_sql
it_behaves_like 'Packages::Maven::PackageFinder examples'
end
context 'when the maven_metadata_by_path_with_optimization_fence feature flag is on' do
before do
stub_feature_flags(maven_metadata_by_path_with_optimization_fence: true)
end
it_behaves_like 'Packages::Maven::PackageFinder examples'
it 'uses CTE in the query' do
sql = described_class.new(user, group, path: package.maven_metadatum.path).send(:packages).to_sql
expect(sql).to include('WITH "maven_metadata_by_path" AS')
end
expect(sql).to include('WITH "maven_metadata_by_path" AS')
end
end