Commit 8cf61afc authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents b2f66c39 dca443fc
...@@ -308,12 +308,17 @@ gem 'rack-attack', '~> 6.3.0' ...@@ -308,12 +308,17 @@ gem 'rack-attack', '~> 6.3.0'
gem 'sentry-raven', '~> 3.1' gem 'sentry-raven', '~> 3.1'
# PostgreSQL query parsing # PostgreSQL query parsing
gem 'pg_query', '~> 2.0.3' #
# We need this fork until https://github.com/pganalyze/pg_query/pull/212
# and https://github.com/pganalyze/pg_query/pull/213 are
# released. gitlab-labkit will need to be updated to use the pg_query
# version.
gem 'gitlab-pg_query', '~> 2.0.4', require: 'pg_query'
gem 'premailer-rails', '~> 1.10.3' gem 'premailer-rails', '~> 1.10.3'
# LabKit: Tracing and Correlation # LabKit: Tracing and Correlation
gem 'gitlab-labkit', '~> 0.17.1' gem 'gitlab-labkit', '~> 0.18.0'
# Thrift is a dependency of gitlab-labkit, we want a version higher than 0.14.0 # Thrift is a dependency of gitlab-labkit, we want a version higher than 0.14.0
# because of https://gitlab.com/gitlab-org/gitlab/-/issues/321900 # because of https://gitlab.com/gitlab-org/gitlab/-/issues/321900
gem 'thrift', '>= 0.14.0' gem 'thrift', '>= 0.14.0'
...@@ -483,7 +488,7 @@ gem 'gitaly', '~> 13.12.0.pre.rc1' ...@@ -483,7 +488,7 @@ gem 'gitaly', '~> 13.12.0.pre.rc1'
gem 'grpc', '~> 1.30.2' gem 'grpc', '~> 1.30.2'
gem 'google-protobuf', '~> 3.15.8' gem 'google-protobuf', '~> 3.17.1'
gem 'toml-rb', '~> 1.0.0' gem 'toml-rb', '~> 1.0.0'
......
...@@ -467,13 +467,13 @@ GEM ...@@ -467,13 +467,13 @@ GEM
fog-xml (~> 0.1.0) fog-xml (~> 0.1.0)
google-api-client (>= 0.44.2, < 0.51) google-api-client (>= 0.44.2, < 0.51)
google-cloud-env (~> 1.2) google-cloud-env (~> 1.2)
gitlab-labkit (0.17.1) gitlab-labkit (0.18.0)
actionpack (>= 5.0.0, < 7.0.0) actionpack (>= 5.0.0, < 7.0.0)
activesupport (>= 5.0.0, < 7.0.0) activesupport (>= 5.0.0, < 7.0.0)
gitlab-pg_query (~> 2.0)
grpc (~> 1.19) grpc (~> 1.19)
jaeger-client (~> 1.1) jaeger-client (~> 1.1)
opentracing (~> 0.4) opentracing (~> 0.4)
pg_query (~> 2.0)
redis (> 3.0.0, < 5.0.0) redis (> 3.0.0, < 5.0.0)
gitlab-license (1.5.0) gitlab-license (1.5.0)
gitlab-mail_room (0.0.9) gitlab-mail_room (0.0.9)
...@@ -483,6 +483,8 @@ GEM ...@@ -483,6 +483,8 @@ GEM
addressable (~> 2.7) addressable (~> 2.7)
omniauth (~> 1.9) omniauth (~> 1.9)
openid_connect (~> 1.2) openid_connect (~> 1.2)
gitlab-pg_query (2.0.4)
google-protobuf (>= 3.17.1)
gitlab-sidekiq-fetcher (0.5.6) gitlab-sidekiq-fetcher (0.5.6)
sidekiq (~> 5) sidekiq (~> 5)
gitlab-styles (6.2.0) gitlab-styles (6.2.0)
...@@ -516,7 +518,7 @@ GEM ...@@ -516,7 +518,7 @@ GEM
signet (~> 0.12) signet (~> 0.12)
google-cloud-env (1.4.0) google-cloud-env (1.4.0)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.3, < 2.0)
google-protobuf (3.15.8) google-protobuf (3.17.1)
googleapis-common-protos-types (1.0.6) googleapis-common-protos-types (1.0.6)
google-protobuf (~> 3.14) google-protobuf (~> 3.14)
googleauth (0.14.0) googleauth (0.14.0)
...@@ -903,8 +905,6 @@ GEM ...@@ -903,8 +905,6 @@ GEM
peek (1.1.0) peek (1.1.0)
railties (>= 4.0.0) railties (>= 4.0.0)
pg (1.2.3) pg (1.2.3)
pg_query (2.0.3)
google-protobuf (~> 3.15.5)
plist (3.6.0) plist (3.6.0)
png_quantizator (0.2.1) png_quantizator (0.2.1)
po_to_json (1.0.1) po_to_json (1.0.1)
...@@ -1477,19 +1477,20 @@ DEPENDENCIES ...@@ -1477,19 +1477,20 @@ DEPENDENCIES
gitlab-experiment (~> 0.5.4) gitlab-experiment (~> 0.5.4)
gitlab-fog-azure-rm (~> 1.0.1) gitlab-fog-azure-rm (~> 1.0.1)
gitlab-fog-google (~> 1.13) gitlab-fog-google (~> 1.13)
gitlab-labkit (~> 0.17.1) gitlab-labkit (~> 0.18.0)
gitlab-license (~> 1.5) gitlab-license (~> 1.5)
gitlab-mail_room (~> 0.0.9) gitlab-mail_room (~> 0.0.9)
gitlab-markup (~> 1.7.1) gitlab-markup (~> 1.7.1)
gitlab-net-dns (~> 0.9.1) gitlab-net-dns (~> 0.9.1)
gitlab-omniauth-openid-connect (~> 0.4.0) gitlab-omniauth-openid-connect (~> 0.4.0)
gitlab-pg_query (~> 2.0.4)
gitlab-sidekiq-fetcher (= 0.5.6) gitlab-sidekiq-fetcher (= 0.5.6)
gitlab-styles (~> 6.2.0) gitlab-styles (~> 6.2.0)
gitlab_chronic_duration (~> 0.10.6.2) gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1) gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.4.0) gon (~> 6.4.0)
google-api-client (~> 0.33) google-api-client (~> 0.33)
google-protobuf (~> 3.15.8) google-protobuf (~> 3.17.1)
gpgme (~> 2.0.19) gpgme (~> 2.0.19)
grape (~> 1.5.2) grape (~> 1.5.2)
grape-entity (~> 0.9.0) grape-entity (~> 0.9.0)
...@@ -1570,7 +1571,6 @@ DEPENDENCIES ...@@ -1570,7 +1571,6 @@ DEPENDENCIES
parslet (~> 1.8) parslet (~> 1.8)
peek (~> 1.1) peek (~> 1.1)
pg (~> 1.1) pg (~> 1.1)
pg_query (~> 2.0.3)
png_quantizator (~> 0.2.1) png_quantizator (~> 0.2.1)
premailer-rails (~> 1.10.3) premailer-rails (~> 1.10.3)
prometheus-client-mmap (~> 0.12.0) prometheus-client-mmap (~> 0.12.0)
......
...@@ -39,8 +39,8 @@ export default { ...@@ -39,8 +39,8 @@ export default {
components: { components: {
IntegrationsList, IntegrationsList,
AlertSettingsForm, AlertSettingsForm,
GlButton,
GlAlert, GlAlert,
GlButton,
}, },
inject: { inject: {
projectPath: { projectPath: {
......
...@@ -79,6 +79,7 @@ export const hideMenu = (el) => { ...@@ -79,6 +79,7 @@ export const hideMenu = (el) => {
el.style.display = ''; el.style.display = '';
el.style.transform = ''; el.style.transform = '';
el.classList.remove(IS_ABOVE_CLASS); el.classList.remove(IS_ABOVE_CLASS);
el.classList.remove('fly-out-list');
parentEl.classList.remove(IS_OVER_CLASS); parentEl.classList.remove(IS_OVER_CLASS);
parentEl.classList.remove(IS_SHOWING_FLY_OUT_CLASS); parentEl.classList.remove(IS_SHOWING_FLY_OUT_CLASS);
......
...@@ -42,6 +42,7 @@ export default { ...@@ -42,6 +42,7 @@ export default {
<div class="settings-content"> <div class="settings-content">
<gl-tabs> <gl-tabs>
<service-level-agreement-form />
<gl-tab <gl-tab
v-for="(tab, index) in $options.tabs" v-for="(tab, index) in $options.tabs"
v-if="tab.active" v-if="tab.active"
...@@ -50,7 +51,6 @@ export default { ...@@ -50,7 +51,6 @@ export default {
> >
<component :is="tab.component" class="gl-pt-3" :data-testid="`${tab.component}-tab`" /> <component :is="tab.component" class="gl-pt-3" :data-testid="`${tab.component}-tab`" />
</gl-tab> </gl-tab>
<service-level-agreement-form />
</gl-tabs> </gl-tabs>
</div> </div>
</section> </section>
......
//
// TEMPORARY OVERRIDES
// Needed while we serve both *_base and *_variant stylesheets
// TODO: These have to be removed during the feature flag rollout
//
&.gl-dark .nav-sidebar li.active {
box-shadow: none;
}
&.gl-dark .nav-sidebar li a,
.toggle-sidebar-button .collapse-text,
.toggle-sidebar-button .icon-chevron-double-lg-left,
.toggle-sidebar-button .icon-chevron-double-lg-right {
color: $gray-darkest;
}
.nav-sidebar {
box-shadow: none;
li.active {
background-color: transparent;
box-shadow: none;
}
}
//
// MIXINS
//
@mixin collapse-contextual-sidebar-content { @mixin collapse-contextual-sidebar-content {
@include context-header-collapsed; @include context-header-collapsed;
...@@ -55,6 +84,63 @@ ...@@ -55,6 +84,63 @@
} }
} }
@mixin sub-level-items-flyout {
.sidebar-sub-level-items {
@include media-breakpoint-up(sm) {
position: fixed;
top: 0;
left: 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;
&::before {
content: '';
position: absolute;
top: -30px;
bottom: -30px;
left: -10px;
right: -30px;
z-index: -1;
}
&.is-above {
margin-top: 1px;
}
.divider {
height: 1px;
margin: 4px -1px;
padding: 0;
background-color: $dropdown-divider-bg;
}
}
.fly-out-top-item {
> a {
display: flex;
}
.fly-out-badge {
margin-left: 8px;
}
}
.fly-out-top-item-name {
flex: 1;
}
}
}
//
// PAGE-LAYOUT
//
.page-with-contextual-sidebar { .page-with-contextual-sidebar {
transition: padding-left $sidebar-transition-duration; transition: padding-left $sidebar-transition-duration;
...@@ -77,14 +163,9 @@ ...@@ -77,14 +163,9 @@
} }
} }
.settings-avatar { //
background-color: $white; // THE PANEL
//
svg {
fill: $gl-text-color-secondary;
margin: auto;
}
}
.nav-sidebar { .nav-sidebar {
transition: width $sidebar-transition-duration, left $sidebar-transition-duration; transition: width $sidebar-transition-duration, left $sidebar-transition-duration;
...@@ -94,8 +175,7 @@ ...@@ -94,8 +175,7 @@
top: $header-height; top: $header-height;
bottom: 0; bottom: 0;
left: 0; left: 0;
background: linear-gradient($purple-200, $orange-200); background-color: $gray-50;
box-shadow: inset -1px 0 0 $border-color;
transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0);
&:not(.sidebar-collapsed-desktop) { &:not(.sidebar-collapsed-desktop) {
...@@ -113,36 +193,50 @@ ...@@ -113,36 +193,50 @@
} }
a { a {
text-decoration: none; @include gl-text-decoration-none;
} @include gl-line-height-normal;
color: $purple-900;
ul {
padding-left: 0;
list-style: none;
} }
li { li {
white-space: nowrap; white-space: nowrap;
a {
transition: padding $sidebar-transition-duration;
display: flex;
align-items: center;
padding: 12px $gl-padding;
color: $gl-text-color-secondary;
}
.nav-item-name { .nav-item-name {
flex: 1; flex: 1;
} }
> a {
@include gl-mx-2;
@include gl-px-4;
@include gl-py-3;
@include gl-display-flex;
@include gl-align-items-center;
@include gl-rounded-base;
@include gl-w-auto;
transition: padding $sidebar-transition-duration;
margin-bottom: 1px;
&:hover {
background-color: $indigo-900-alpha-008;
}
}
&.active { &.active {
> a { > a {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
} }
> a:not(.has-sub-items) {
background-color: $indigo-900-alpha-008;
}
} }
} }
ul {
padding-left: 0;
list-style: none;
}
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
left: (-$contextual-sidebar-width); left: (-$contextual-sidebar-width);
} }
...@@ -175,143 +269,69 @@ ...@@ -175,143 +269,69 @@
overflow: auto; overflow: auto;
} }
.sidebar-sub-level-items {
display: none;
padding-bottom: 8px;
> li {
a {
padding: 8px 16px 8px 40px;
&:hover,
&:focus {
background: $link-active-background;
color: $gl-text-color;
}
}
&.active {
a {
&,
&:hover,
&:focus {
background: $link-active-background;
}
}
}
}
}
.sidebar-top-level-items { .sidebar-top-level-items {
margin-bottom: 60px; margin-bottom: 60px;
> li { > li {
> a {
@include media-breakpoint-up(sm) {
margin-right: 1px;
}
&:hover {
color: $gl-text-color;
}
}
&.is-showing-fly-out {
> a {
margin-right: 1px;
}
.sidebar-sub-level-items {
@include media-breakpoint-up(sm) {
position: fixed;
top: 0;
left: 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;
&::before {
content: '';
position: absolute;
top: -30px;
bottom: -30px;
left: -10px;
right: -30px;
z-index: -1;
}
&.is-above {
margin-top: 1px;
}
.divider {
height: 1px;
margin: 4px -1px;
padding: 0;
background-color: $dropdown-divider-bg;
}
> .active {
box-shadow: none;
> a {
background-color: transparent;
}
}
a {
padding: 8px 16px;
color: $gl-text-color;
&:hover,
&:focus {
background-color: $gray-darker;
}
}
}
}
}
.badge.badge-pill { .badge.badge-pill {
background-color: $inactive-badge-background; @include gl-rounded-lg;
color: $gl-text-color-secondary; @include gl-py-1;
@include gl-px-3;
background-color: $blue-100;
color: $blue-700;
} }
&.active { &.active {
background: $link-active-background; .sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
> a {
margin-left: 4px;
// Subtract width of left border on active element
padding-left: $gl-padding-12;
} }
.badge.badge-pill { .badge.badge-pill {
font-weight: $gl-font-weight-bold; @include gl-font-weight-normal; // TODO: update in `theme_indigo.scss`
} color: $blue-700; // TODO: update in `theme_indigo.scss`
.sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
} }
} }
}
}
.sidebar-sub-level-items {
@include gl-pb-0;
display: none;
&.active > a:hover, &:not(.fly-out-list) {
&.is-over > a { li > a {
background-color: $link-hover-background; // The calculation formula:
// 12px: normal padding on the menu anchors
// +
// 16px: the width of the SVG icon in the top-level links
// +
// 8px: margin-right on the SVG icon in the top-level links
// =
// 36px (4.5 times the $grid-size)
padding-left: $grid-size * 4.5;
} }
} }
} }
// Collapsed nav .is-showing-fly-out {
@include sub-level-items-flyout;
}
//
// COLLAPSED STATE
//
.toggle-sidebar-button, .toggle-sidebar-button,
.close-nav-button { .close-nav-button {
@include side-panel-toggle; @include side-panel-toggle;
background-color: $gray-50;
color: $purple-900;
.collapse-text,
.icon-chevron-double-lg-left,
.icon-chevron-double-lg-right {
color: inherit;
}
} }
.toggle-sidebar-button, .toggle-sidebar-button,
...@@ -339,21 +359,9 @@ ...@@ -339,21 +359,9 @@
@include collapse-contextual-sidebar-content; @include collapse-contextual-sidebar-content;
} }
.fly-out-top-item { //
> a { // MOBILE PANEL
display: flex; //
}
.fly-out-badge {
margin-left: 8px;
}
}
.fly-out-top-item-name {
flex: 1;
}
// Mobile nav
.close-nav-button { .close-nav-button {
display: none; display: none;
...@@ -382,3 +390,17 @@ ...@@ -382,3 +390,17 @@
} }
} }
//
// PANELS-SPECIFIC
// TODO: Check whether we can remove these in favor of the utility-classes
//
.settings-avatar {
background-color: $white;
svg {
fill: $gl-text-color-secondary;
margin: auto;
}
}
...@@ -112,6 +112,7 @@ export default { ...@@ -112,6 +112,7 @@ export default {
v-if="available" v-if="available"
key="service-level-agreement" key="service-level-agreement"
:title="s__('IncidentSettings|Incident settings')" :title="s__('IncidentSettings|Incident settings')"
active
> >
<gl-form class="gl-pt-3" @submit.prevent="updateServiceLevelAgreementSettings"> <gl-form class="gl-pt-3" @submit.prevent="updateServiceLevelAgreementSettings">
<p class="gl-line-height-20"> <p class="gl-line-height-20">
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
exports[`Alert integration settings form should match the default snapshot 1`] = ` exports[`Alert integration settings form should match the default snapshot 1`] = `
<gl-tab-stub <gl-tab-stub
active=""
title="Incident settings" title="Incident settings"
titlelinkclass="" titlelinkclass=""
> >
......
...@@ -83,6 +83,16 @@ module Sidebars ...@@ -83,6 +83,16 @@ module Sidebars
insert_element_after(@items, after_item, new_item) insert_element_after(@items, after_item, new_item)
end end
override :container_html_options
def container_html_options
super.tap do |html_options|
# Flagging menus that can be rendered and with renderable menu items
if render? && has_renderable_items?
html_options[:class] = [*html_options[:class], 'has-sub-items'].join(' ')
end
end
end
private private
override :index_of override :index_of
......
...@@ -34,6 +34,11 @@ module Sidebars ...@@ -34,6 +34,11 @@ module Sidebars
{ class: 'context-header' } { class: 'context-header' }
end end
override :render?
def render?
true
end
end end
end end
end end
......
...@@ -41,6 +41,8 @@ exports[`IncidentsSettingTabs should render the component 1`] = ` ...@@ -41,6 +41,8 @@ exports[`IncidentsSettingTabs should render the component 1`] = `
<gl-tabs-stub <gl-tabs-stub
theme="indigo" theme="indigo"
> >
<!---->
<gl-tab-stub <gl-tab-stub
title="Alert integration" title="Alert integration"
titlelinkclass="" titlelinkclass=""
...@@ -60,8 +62,6 @@ exports[`IncidentsSettingTabs should render the component 1`] = ` ...@@ -60,8 +62,6 @@ exports[`IncidentsSettingTabs should render the component 1`] = `
/> />
</gl-tab-stub> </gl-tab-stub>
<!----> <!---->
<!---->
</gl-tabs-stub> </gl-tabs-stub>
</div> </div>
</section> </section>
......
...@@ -144,4 +144,50 @@ RSpec.describe Sidebars::Menu do ...@@ -144,4 +144,50 @@ RSpec.describe Sidebars::Menu do
end end
end end
end end
describe '#container_html_options' do
before do
allow(menu).to receive(:title).and_return('Foo Menu')
end
context 'when menu can be rendered' do
before do
allow(menu).to receive(:render?).and_return(true)
end
context 'when menu has renderable items' do
before do
menu.add_item(Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: { path: 'bar' }))
end
it 'contains the special class' do
expect(menu.container_html_options[:class]).to eq 'has-sub-items'
end
context 'when menu already has other classes' do
it 'appends special class' do
allow(menu).to receive(:extra_container_html_options).and_return(class: 'foo')
expect(menu.container_html_options[:class]).to eq 'foo has-sub-items'
end
end
end
context 'when menu does not have renderable items' do
it 'does not contain the special class' do
expect(menu.container_html_options[:class]).to be_nil
end
end
end
context 'when menu cannot be rendered' do
before do
allow(menu).to receive(:render?).and_return(false)
end
it 'does not contain special class' do
expect(menu.container_html_options[:class]).to be_nil
end
end
end
end end
...@@ -11,14 +11,14 @@ RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do ...@@ -11,14 +11,14 @@ RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do
describe '#container_html_options' do describe '#container_html_options' do
subject { described_class.new(context).container_html_options } subject { described_class.new(context).container_html_options }
specify { is_expected.to match(hash_including(class: 'shortcuts-project-information')) } specify { is_expected.to match(hash_including(class: 'shortcuts-project-information has-sub-items')) }
context 'when feature flag :sidebar_refactor is disabled' do context 'when feature flag :sidebar_refactor is disabled' do
before do before do
stub_feature_flags(sidebar_refactor: false) stub_feature_flags(sidebar_refactor: false)
end end
specify { is_expected.to match(hash_including(class: 'shortcuts-project rspec-project-link')) } specify { is_expected.to match(hash_including(class: 'shortcuts-project rspec-project-link has-sub-items')) }
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment