Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b20c558db2
commit
9ae44f98c8
21 changed files with 530 additions and 183 deletions
|
@ -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' }"
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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' } }
|
||||
|
|
|
@ -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' } }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. |
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue