summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue5
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js5
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue2
-rw-r--r--app/assets/javascripts/ensure_data.js2
-rw-r--r--app/assets/javascripts/environments/components/deploy_board.vue2
-rw-r--r--app/assets/javascripts/feature_highlight/feature_highlight_popover.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/charts/empty_chart.vue2
-rw-r--r--app/assets/javascripts/pages/groups/new/components/app.vue4
-rw-r--r--app/assets/javascripts/projects/new/components/app.vue8
-rw-r--r--app/assets/javascripts/security_configuration/components/constants.js4
-rw-r--r--app/assets/javascripts/super_sidebar/components/super_sidebar.vue63
-rw-r--r--app/assets/javascripts/super_sidebar/components/user_bar.vue3
-rw-r--r--app/assets/javascripts/super_sidebar/super_sidebar_collapsed_state_manager.js20
-rw-r--r--app/assets/javascripts/surveys/merge_request_experience/app.vue2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail.vue2
-rw-r--r--app/assets/stylesheets/framework/super_sidebar.scss40
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss7
-rw-r--r--app/assets/stylesheets/startup/startup-general.scss7
-rw-r--r--app/services/jira_connect_installations/proxy_lifecycle_event_service.rb6
-rw-r--r--app/views/devise/confirmations/almost_there.haml7
-rw-r--r--app/views/projects/pages_domains/_certificate.html.haml8
-rw-r--r--config/webpack.config.js1
-rw-r--r--jest.config.base.js7
-rw-r--r--locale/gitlab.pot6
-rwxr-xr-xscripts/pipeline_test_report_builder.rb2
-rw-r--r--spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb12
-rw-r--r--spec/frontend/boards/mock_data.js3
-rw-r--r--spec/frontend/super_sidebar/components/super_sidebar_spec.js21
-rw-r--r--spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js132
-rw-r--r--spec/services/jira_connect_installations/proxy_lifecycle_event_service_spec.rb6
-rw-r--r--spec/views/devise/confirmations/almost_there.html.haml_spec.rb17
34 files changed, 318 insertions, 96 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 45f6226a5e1..bee87e17ed9 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-c7695bd902060be80b3499ffd2bd9e86d89c4f4f
+e6c3f8fa60ab4b5af91b5f893876c130d97fe37c
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 64b94fcefcf..a47db661445 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -129,7 +129,7 @@ export default {
};
},
listItemsCount() {
- return this.isEpicBoard ? this.list.epicsCount : this.boardList?.issuesCount;
+ return this.isEpicBoard ? this.list.metadata.epicsCount : this.boardList?.issuesCount;
},
paginatedIssueText() {
return sprintf(__('Showing %{pageSize} of %{total} %{issuableType}'), {
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index 165941ff938..93096777d64 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -90,6 +90,9 @@ export default {
listType() {
return this.list.listType;
},
+ itemsCount() {
+ return this.isEpicBoard ? this.list.metadata.epicsCount : this.boardList?.issuesCount;
+ },
listAssignee() {
return this.list?.assignee?.username || '';
},
@@ -452,7 +455,7 @@ export default {
<gl-icon class="gl-mr-2" :name="countIcon" :size="14" />
<item-count
v-if="!isLoading"
- :items-size="isEpicBoard ? list.epicsCount : boardList.issuesCount"
+ :items-size="itemsCount"
:max-issue-count="list.maxIssueCount"
/>
</span>
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 91669bf3562..047a14508f3 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -9,10 +9,9 @@ import * as mutationTypes from './mutation_types';
const updateListItemsCount = ({ state, listId, value }) => {
const list = state.boardLists[listId];
if (state.issuableType === TYPE_EPIC) {
- Vue.set(state.boardLists, listId, { ...list, epicsCount: list.epicsCount + value });
- } else {
- Vue.set(state.boardLists, listId, { ...list });
+ list.metadata.epicsCount += value;
}
+ Vue.set(state.boardLists, listId, { ...list });
};
export const removeItemFromList = ({ state, listId, itemId, reordering = false }) => {
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue
index f633ba053ee..39ac55bb9c5 100644
--- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue
@@ -1,5 +1,5 @@
<script>
-import scheduleSvg from '@gitlab/svgs/dist/illustrations/schedule-md.svg';
+import scheduleSvg from '@gitlab/svgs/dist/illustrations/schedule-md.svg?raw';
import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
import { s__ } from '~/locale';
diff --git a/app/assets/javascripts/ensure_data.js b/app/assets/javascripts/ensure_data.js
index 69c81c35bd4..4566ab20258 100644
--- a/app/assets/javascripts/ensure_data.js
+++ b/app/assets/javascripts/ensure_data.js
@@ -1,4 +1,4 @@
-import emptySvg from '@gitlab/svgs/dist/illustrations/security-dashboard-empty-state.svg';
+import emptySvg from '@gitlab/svgs/dist/illustrations/security-dashboard-empty-state.svg?raw';
import { GlEmptyState } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/environments/components/deploy_board.vue b/app/assets/javascripts/environments/components/deploy_board.vue
index 31bc462f0b9..caf375a16cf 100644
--- a/app/assets/javascripts/environments/components/deploy_board.vue
+++ b/app/assets/javascripts/environments/components/deploy_board.vue
@@ -8,7 +8,7 @@
* - Button Actions.
* [Mockup](https://gitlab.com/gitlab-org/gitlab-foss/uploads/2f655655c0eadf655d0ae7467b53002a/environments__deploy-graphic.png)
*/
-import deployBoardSvg from '@gitlab/svgs/dist/illustrations/deploy-boards.svg';
+import deployBoardSvg from '@gitlab/svgs/dist/illustrations/deploy-boards.svg?raw';
import {
GlIcon,
GlLoadingIcon,
diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue b/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue
index 1c6e6380e76..24f7d567ea7 100644
--- a/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue
+++ b/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue
@@ -1,5 +1,5 @@
<script>
-import clusterPopover from '@gitlab/svgs/dist/illustrations/cluster_popover.svg';
+import clusterPopover from '@gitlab/svgs/dist/illustrations/cluster_popover.svg?raw';
import { GlPopover, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
index da4c92df711..6419c45c20c 100644
--- a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
+++ b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
@@ -1,5 +1,5 @@
<script>
-import chartEmptyStateIllustration from '@gitlab/svgs/dist/illustrations/chart-empty-state.svg';
+import chartEmptyStateIllustration from '@gitlab/svgs/dist/illustrations/chart-empty-state.svg?raw';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { chartHeight } from '../../constants';
diff --git a/app/assets/javascripts/pages/groups/new/components/app.vue b/app/assets/javascripts/pages/groups/new/components/app.vue
index 68ddcf3d868..68f813d9375 100644
--- a/app/assets/javascripts/pages/groups/new/components/app.vue
+++ b/app/assets/javascripts/pages/groups/new/components/app.vue
@@ -1,6 +1,6 @@
<script>
-import importGroupIllustration from '@gitlab/svgs/dist/illustrations/group-import.svg';
-import newGroupIllustration from '@gitlab/svgs/dist/illustrations/group-new.svg';
+import importGroupIllustration from '@gitlab/svgs/dist/illustrations/group-import.svg?raw';
+import newGroupIllustration from '@gitlab/svgs/dist/illustrations/group-new.svg?raw';
import { s__ } from '~/locale';
import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue';
diff --git a/app/assets/javascripts/projects/new/components/app.vue b/app/assets/javascripts/projects/new/components/app.vue
index 4f3924b04bf..8d883e7126c 100644
--- a/app/assets/javascripts/projects/new/components/app.vue
+++ b/app/assets/javascripts/projects/new/components/app.vue
@@ -1,8 +1,8 @@
<script>
-import createFromTemplateIllustration from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg';
-import blankProjectIllustration from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg';
-import importProjectIllustration from '@gitlab/svgs/dist/illustrations/project-import-sm.svg';
-import ciCdProjectIllustration from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg';
+import createFromTemplateIllustration from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg?raw';
+import blankProjectIllustration from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg?raw';
+import importProjectIllustration from '@gitlab/svgs/dist/illustrations/project-import-sm.svg?raw';
+import ciCdProjectIllustration from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg?raw';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__ } from '~/locale';
import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue';
diff --git a/app/assets/javascripts/security_configuration/components/constants.js b/app/assets/javascripts/security_configuration/components/constants.js
index 6beb6cd4d34..1321624fe7d 100644
--- a/app/assets/javascripts/security_configuration/components/constants.js
+++ b/app/assets/javascripts/security_configuration/components/constants.js
@@ -15,8 +15,8 @@ import {
REPORT_TYPE_LICENSE_COMPLIANCE,
} from '~/vue_shared/security_reports/constants';
-import kontraLogo from 'images/vulnerability/kontra-logo.svg';
-import scwLogo from 'images/vulnerability/scw-logo.svg';
+import kontraLogo from 'images/vulnerability/kontra-logo.svg?raw';
+import scwLogo from 'images/vulnerability/scw-logo.svg?raw';
import configureSastMutation from '../graphql/configure_sast.mutation.graphql';
import configureSastIacMutation from '../graphql/configure_iac.mutation.graphql';
import configureSecretDetectionMutation from '../graphql/configure_secret_detection.mutation.graphql';
diff --git a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue
index 2da71c029fd..630537f0323 100644
--- a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue
+++ b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue
@@ -1,5 +1,6 @@
<script>
import { GlCollapse } from '@gitlab/ui';
+import { isCollapsed, toggleSuperSidebarCollapsed } from '../super_sidebar_collapsed_state_manager';
import UserBar from './user_bar.vue';
import SidebarPortalTarget from './sidebar_portal_target.vue';
import ContextSwitcherToggle from './context_switcher_toggle.vue';
@@ -26,6 +27,7 @@ export default {
data() {
return {
contextSwitcherOpened: false,
+ isCollapased: isCollapsed(),
};
},
computed: {
@@ -33,34 +35,45 @@ export default {
return this.sidebarData.current_menu_items || [];
},
},
+ methods: {
+ collapseSidebar() {
+ toggleSuperSidebarCollapsed(true, false);
+ },
+ },
};
</script>
<template>
- <aside
- id="super-sidebar"
- class="super-sidebar gl-display-flex gl-flex-direction-column"
- data-testid="super-sidebar"
- data-qa-selector="navbar"
- >
- <user-bar :sidebar-data="sidebarData" />
- <div class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-overflow-hidden">
- <div class="gl-flex-grow-1 gl-overflow-auto">
- <context-switcher-toggle
- :context="sidebarData.current_context_header"
- :expanded="contextSwitcherOpened"
- />
- <gl-collapse id="context-switcher" v-model="contextSwitcherOpened">
- <context-switcher />
- </gl-collapse>
- <gl-collapse :visible="!contextSwitcherOpened">
- <sidebar-menu :items="menuItems" />
- <sidebar-portal-target />
- </gl-collapse>
- </div>
- <div class="gl-p-3">
- <help-center :sidebar-data="sidebarData" />
+ <div>
+ <div class="super-sidebar-overlay" @click="collapseSidebar"></div>
+ <aside
+ id="super-sidebar"
+ :aria-hidden="String(isCollapased)"
+ class="super-sidebar"
+ data-testid="super-sidebar"
+ data-qa-selector="navbar"
+ :inert="isCollapased"
+ tabindex="-1"
+ >
+ <user-bar :sidebar-data="sidebarData" />
+ <div class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-overflow-hidden">
+ <div class="gl-flex-grow-1 gl-overflow-auto">
+ <context-switcher-toggle
+ :context="sidebarData.current_context_header"
+ :expanded="contextSwitcherOpened"
+ />
+ <gl-collapse id="context-switcher" v-model="contextSwitcherOpened">
+ <context-switcher />
+ </gl-collapse>
+ <gl-collapse :visible="!contextSwitcherOpened">
+ <sidebar-menu :items="menuItems" />
+ <sidebar-portal-target />
+ </gl-collapse>
+ </div>
+ <div class="gl-p-3">
+ <help-center :sidebar-data="sidebarData" />
+ </div>
</div>
- </div>
- </aside>
+ </aside>
+ </div>
</template>
diff --git a/app/assets/javascripts/super_sidebar/components/user_bar.vue b/app/assets/javascripts/super_sidebar/components/user_bar.vue
index 82db6a2e351..32ce4abd646 100644
--- a/app/assets/javascripts/super_sidebar/components/user_bar.vue
+++ b/app/assets/javascripts/super_sidebar/components/user_bar.vue
@@ -2,7 +2,7 @@
import { GlBadge, GlButton, GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale';
import SafeHtml from '~/vue_shared/directives/safe_html';
-import logo from '../../../../views/shared/_logo.svg';
+import logo from '../../../../views/shared/_logo.svg?raw';
import { toggleSuperSidebarCollapsed } from '../super_sidebar_collapsed_state_manager';
import CreateMenu from './create_menu.vue';
import Counter from './counter.vue';
@@ -93,7 +93,6 @@ export default {
<counter
v-gl-tooltip:super-sidebar.hover.bottom="$options.i18n.mergeRequests"
class="gl-w-full"
- tabindex="-1"
icon="merge-request-open"
:count="sidebarData.total_merge_requests_count"
:label="$options.i18n.mergeRequests"
diff --git a/app/assets/javascripts/super_sidebar/super_sidebar_collapsed_state_manager.js b/app/assets/javascripts/super_sidebar/super_sidebar_collapsed_state_manager.js
index 1dfd132d522..a4eb65dc08c 100644
--- a/app/assets/javascripts/super_sidebar/super_sidebar_collapsed_state_manager.js
+++ b/app/assets/javascripts/super_sidebar/super_sidebar_collapsed_state_manager.js
@@ -7,9 +7,10 @@ export const SIDEBAR_COLLAPSED_COOKIE = 'super_sidebar_collapsed';
export const SIDEBAR_COLLAPSED_COOKIE_EXPIRATION = 365 * 10;
export const findPage = () => document.querySelector('.page-with-super-sidebar');
-export const findToggle = () => document.querySelector('.js-super-sidebar-toggle');
+export const findSidebar = () => document.querySelector('.super-sidebar');
+export const findToggles = () => document.querySelectorAll('.js-super-sidebar-toggle');
-const isCollapsed = () => findPage().classList.contains(SIDEBAR_COLLAPSED_CLASS);
+export const isCollapsed = () => findPage().classList.contains(SIDEBAR_COLLAPSED_CLASS);
// See documentation: https://design.gitlab.com/patterns/navigation#left-sidebar
// NOTE: at 1200px nav sidebar should not overlap the content
@@ -19,6 +20,12 @@ export const isDesktopBreakpoint = () => bp.windowWidth() >= breakpoints.xl;
export const getCollapsedCookie = () => getCookie(SIDEBAR_COLLAPSED_COOKIE) === 'true';
export const toggleSuperSidebarCollapsed = (collapsed, saveCookie) => {
+ const sidebar = findSidebar();
+ sidebar.ariaHidden = collapsed;
+ sidebar.inert = collapsed;
+
+ if (!collapsed) sidebar.focus();
+
findPage().classList.toggle(SIDEBAR_COLLAPSED_CLASS, collapsed);
if (saveCookie && isDesktopBreakpoint()) {
@@ -34,12 +41,11 @@ export const initSuperSidebarCollapsedState = () => {
};
export const bindSuperSidebarCollapsedEvents = () => {
- if (findToggle()) {
- findToggle().addEventListener('click', () => {
- const value = !isCollapsed();
- toggleSuperSidebarCollapsed(value, true);
+ findToggles().forEach((elem) => {
+ elem.addEventListener('click', () => {
+ toggleSuperSidebarCollapsed(!isCollapsed(), true);
});
- }
+ });
window.addEventListener('resize', debounce(initSuperSidebarCollapsedState, 100));
};
diff --git a/app/assets/javascripts/surveys/merge_request_experience/app.vue b/app/assets/javascripts/surveys/merge_request_experience/app.vue
index 6e90ad2e0fd..333059b5340 100644
--- a/app/assets/javascripts/surveys/merge_request_experience/app.vue
+++ b/app/assets/javascripts/surveys/merge_request_experience/app.vue
@@ -1,6 +1,6 @@
<script>
import { GlButton, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
-import gitlabLogo from '@gitlab/svgs/dist/illustrations/gitlab_logo.svg';
+import gitlabLogo from '@gitlab/svgs/dist/illustrations/gitlab_logo.svg?raw';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__, __ } from '~/locale';
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue
index d4ee84f0255..eb715518451 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -11,7 +11,7 @@ import {
GlTooltipDirective,
GlEmptyState,
} from '@gitlab/ui';
-import noAccessSvg from '@gitlab/svgs/dist/illustrations/analytics/no-access.svg';
+import noAccessSvg from '@gitlab/svgs/dist/illustrations/analytics/no-access.svg?raw';
import * as Sentry from '@sentry/browser';
import { s__ } from '~/locale';
import { parseBoolean } from '~/lib/utils/common_utils';
diff --git a/app/assets/stylesheets/framework/super_sidebar.scss b/app/assets/stylesheets/framework/super_sidebar.scss
index dd723d9f4f4..659e8c5b37d 100644
--- a/app/assets/stylesheets/framework/super_sidebar.scss
+++ b/app/assets/stylesheets/framework/super_sidebar.scss
@@ -24,16 +24,17 @@
}
.super-sidebar {
- @include gl-fixed;
- @include gl-top-0;
- @include gl-bottom-0;
- @include gl-left-0;
- @include gl-bg-gray-10;
- @include gl-border-r;
- @include gl-border-gray-a-08;
+ display: flex;
+ flex-direction: column;
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--gray-10, $gray-10);
+ border-right: 1px solid $t-gray-a-08;
transform: translate3d(0, 0, 0);
width: $super-sidebar-width;
- z-index: 600;
+ z-index: $super-sidebar-z-index;
&.super-sidebar-loading {
transform: translate3d(-100%, 0, 0);
@@ -139,12 +140,33 @@
}
}
+.super-sidebar-overlay {
+ display: none;
+}
+
.page-with-super-sidebar {
padding-left: 0;
transition: padding-left $gl-transition-duration-medium;
+ &:not(.page-with-super-sidebar-collapsed) {
+ .super-sidebar-overlay {
+ display: block;
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: $black-transparent;
+ z-index: $super-sidebar-z-index - 1;
+
+ @include media-breakpoint-up(md) {
+ display: none;
+ }
+ }
+ }
+
@include media-breakpoint-up(xl) {
- padding-left: $contextual-sidebar-width;
+ padding-left: $super-sidebar-width;
.super-sidebar-toggle {
display: none;
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index e032961a253..dff0ca9a819 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -12,6 +12,8 @@ $contextual-sidebar-collapsed-width: 56px;
$toggle-sidebar-height: 48px;
$super-sidebar-width: 256px;
$super-sidebar-toggle-position-breakpoint: 1360px;
+$super-sidebar-z-index: 600;
+$super-sidebar-overlay-z-index: 599;
/**
🚨 Do not use this spacing scale — it is deprecated and being removed. 🚨
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index accc50697c5..ac74096e97c 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -1494,13 +1494,14 @@ kbd {
}
}
.super-sidebar {
+ display: flex;
+ flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
left: 0;
- background-color: #1f1e24;
- border-right: solid 1px #434248;
- border-color: rgba(251, 250, 253, 0.08);
+ background-color: var(--gray-10, #1f1e24);
+ border-right: 1px solid rgba(251, 250, 253, 0.08);
transform: translate3d(0, 0, 0);
width: 256px;
z-index: 600;
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index 511c270d556..fc3da60d3b8 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -1494,13 +1494,14 @@ kbd {
}
}
.super-sidebar {
+ display: flex;
+ flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
left: 0;
- background-color: #fbfafd;
- border-right: solid 1px #dcdcde;
- border-color: rgba(31, 30, 36, 0.08);
+ background-color: var(--gray-10, #fbfafd);
+ border-right: 1px solid rgba(31, 30, 36, 0.08);
transform: translate3d(0, 0, 0);
width: 256px;
z-index: 600;
diff --git a/app/services/jira_connect_installations/proxy_lifecycle_event_service.rb b/app/services/jira_connect_installations/proxy_lifecycle_event_service.rb
index d94d9e1324e..9f3b4a37672 100644
--- a/app/services/jira_connect_installations/proxy_lifecycle_event_service.rb
+++ b/app/services/jira_connect_installations/proxy_lifecycle_event_service.rb
@@ -82,9 +82,9 @@ module JiraConnectInstallations
Gitlab::IntegrationsLogger.info(
integration: 'JiraConnect',
message: 'Proxy lifecycle event received error response',
- event_type: event,
- status_code: status_code,
- body: body
+ jira_event_type: event,
+ jira_status_code: status_code,
+ jira_body: body
)
end
end
diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml
index 01f9595f35c..c22eeba2f01 100644
--- a/app/views/devise/confirmations/almost_there.haml
+++ b/app/views/devise/confirmations/almost_there.haml
@@ -1,6 +1,7 @@
- user_email = "(#{params[:email]})" if Devise.email_regexp.match?(params[:email])
- request_link_start = '<a href="%{new_user_confirmation_path}">'.html_safe % { new_user_confirmation_path: new_user_confirmation_path }
-- request_link_end = '</a>'.html_safe
+- registration_link_start = '<a href="%{new_user_registration_path}">'.html_safe % { new_user_registration_path: new_user_registration_path }
+- link_end = '</a>'.html_safe
- content_for :page_specific_javascripts do
= render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
@@ -12,9 +13,11 @@
= _("Almost there...")
%p{ class: 'gl-mb-6 gl-font-lg!' }
= _('Please check your email %{email} to confirm your account') % { email: user_email }
+ %br
+ = _('If the email address is incorrect, you can %{registration_link_start}register again with a different email%{registration_link_end}.').html_safe % { registration_link_start: registration_link_start, registration_link_end: link_end }
%hr
- if Gitlab::CurrentSettings.after_sign_up_text.present?
.well-confirmation.gl-text-center
= markdown_field(Gitlab::CurrentSettings, :after_sign_up_text)
%p.gl-text-center
- = _("No confirmation email received? Check your spam folder or %{request_link_start}request new confirmation email%{request_link_end}.").html_safe % { request_link_start: request_link_start, request_link_end: request_link_end }
+ = _("No confirmation email received? Check your spam folder or %{request_link_start}request new confirmation email%{request_link_end}.").html_safe % { request_link_start: request_link_start, request_link_end: link_end }
diff --git a/app/views/projects/pages_domains/_certificate.html.haml b/app/views/projects/pages_domains/_certificate.html.haml
index 4ba3e084dc4..3433958a397 100644
--- a/app/views/projects/pages_domains/_certificate.html.haml
+++ b/app/views/projects/pages_domains/_certificate.html.haml
@@ -30,10 +30,10 @@
- if has_user_defined_certificate
.row
.col-sm-10.offset-sm-2
- .card
- .card-header
- = _('Certificate')
- .d-flex.justify-content-between.align-items-center.p-3
+ = render Pajamas::CardComponent.new(body_options: { class: 'gl-display-flex gl-align-items-center gl-justify-content-space-between gl-p-5' }) do |c|
+ - c.header do
+ = s_('Certificate')
+ - c.body do
%span
= domain_presenter.pages_domain.subject || _('missing')
= link_to _('Remove'),
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 550a3a62e24..ba7a1f70acc 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -393,6 +393,7 @@ module.exports = {
},
},
{
+ resourceQuery: /raw/,
loader: 'raw-loader',
},
],
diff --git a/jest.config.base.js b/jest.config.base.js
index 34134d6983b..cc275c3ed0f 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -47,6 +47,9 @@ module.exports = (path, options = {}) => {
// temporary alias until we replace all `flash` imports for `alert`
// https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109449
'^~/flash$': '<rootDir>/app/assets/javascripts/alert',
+ [TEST_FIXTURES_PATTERN]: '<rootDir>/tmp/tests/frontend/fixtures$1',
+ '^test_fixtures_static(/.*)$': '<rootDir>/spec/frontend/fixtures/static$1',
+ '\\.(jpg|jpeg|png|svg|css)(\\?\\w+)?$': '<rootDir>/spec/frontend/__mocks__/file_mock.js',
'^~(/.*)\\?(worker|raw)$': '<rootDir>/app/assets/javascripts$1',
'^(.*)\\?(worker|raw)$': '$1',
'^~(/.*)$': '<rootDir>/app/assets/javascripts$1',
@@ -60,10 +63,6 @@ module.exports = (path, options = {}) => {
'^any_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1',
'^helpers(/.*)$': '<rootDir>/spec/frontend/__helpers__$1',
'^vendor(/.*)$': '<rootDir>/vendor/assets/javascripts$1',
- [TEST_FIXTURES_PATTERN]: '<rootDir>/tmp/tests/frontend/fixtures$1',
- '^test_fixtures_static(/.*)$': '<rootDir>/spec/frontend/fixtures/static$1',
- '\\.(jpg|jpeg|png|svg|css)$': '<rootDir>/spec/frontend/__mocks__/file_mock.js',
- '\\.svg\\?url$': '<rootDir>/spec/frontend/__mocks__/file_mock.js',
'^public(/.*)$': '<rootDir>/public$1',
'emojis(/.*).json': '<rootDir>/fixtures/emojis$1.json',
'^spec/test_constants$': '<rootDir>/spec/frontend/__helpers__/test_constants',
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index fbb92f4b14e..fc126de2e55 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -21424,6 +21424,9 @@ msgstr ""
msgid "If enabled, only protected branches will be mirrored."
msgstr ""
+msgid "If the email address is incorrect, you can %{registration_link_start}register again with a different email%{registration_link_end}."
+msgstr ""
+
msgid "If the number of active users exceeds the user limit, you will be charged for the number of %{users_over_license_link} at your next license reconciliation."
msgstr ""
@@ -38764,6 +38767,9 @@ msgstr ""
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Non-existing tags have been detected in the policy yaml. As a result, rule mode has been disabled. To enable rule mode, remove those non-existing tags from the policy yaml."
+msgstr ""
+
msgid "SecurityOrchestration|Not enabled"
msgstr ""
diff --git a/scripts/pipeline_test_report_builder.rb b/scripts/pipeline_test_report_builder.rb
index 15a78969266..c84acf2fd94 100755
--- a/scripts/pipeline_test_report_builder.rb
+++ b/scripts/pipeline_test_report_builder.rb
@@ -19,7 +19,7 @@ require_relative 'api/default_options'
# Push into expected format for failed tests
class PipelineTestReportBuilder
DEFAULT_OPTIONS = {
- target_project: Host::DEFAULT_OPTIONS[:target_project],
+ target_project: Host::DEFAULT_OPTIONS[:target_project] || API::DEFAULT_OPTIONS[:project],
current_pipeline_id: API::DEFAULT_OPTIONS[:pipeline_id],
mr_iid: Host::DEFAULT_OPTIONS[:mr_iid],
api_endpoint: API::DEFAULT_OPTIONS[:endpoint],
diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
index a7da59200e9..16e64ade665 100644
--- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
@@ -48,13 +48,13 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled, feature_categor
expect(domain.auto_ssl_enabled).to eq false
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false'
- expect(page).to have_selector '.card-header', text: 'Certificate'
+ expect(page).to have_selector '.gl-card-header', text: 'Certificate'
expect(page).to have_text domain.subject
find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true'
- expect(page).not_to have_selector '.card-header', text: 'Certificate'
+ expect(page).not_to have_selector '.gl-card-header', text: 'Certificate'
expect(page).not_to have_text domain.subject
click_on 'Save Changes'
@@ -108,7 +108,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled, feature_categor
it 'user do not see private key' do
visit project_pages_domain_path(project, domain)
- expect(page).not_to have_selector '.card-header', text: 'Certificate'
+ expect(page).not_to have_selector '.gl-card-header', text: 'Certificate'
expect(page).not_to have_text domain.subject
end
end
@@ -131,16 +131,16 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled, feature_categor
it 'user sees certificate subject' do
visit project_pages_domain_path(project, domain)
- expect(page).to have_selector '.card-header', text: 'Certificate'
+ expect(page).to have_selector '.gl-card-header', text: 'Certificate'
expect(page).to have_text domain.subject
end
it 'user can delete the certificate', :js do
visit project_pages_domain_path(project, domain)
- expect(page).to have_selector '.card-header', text: 'Certificate'
+ expect(page).to have_selector '.gl-card-header', text: 'Certificate'
expect(page).to have_text domain.subject
- within('.card') { click_on 'Remove' }
+ within('.gl-card') { click_on 'Remove' }
accept_gl_confirm(button_text: 'Remove certificate')
expect(page).to have_field 'Certificate (PEM)', with: ''
expect(page).to have_field 'Key (PEM)', with: ''
diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js
index 1d011eacf1c..0f58d7cf9fa 100644
--- a/spec/frontend/boards/mock_data.js
+++ b/spec/frontend/boards/mock_data.js
@@ -477,6 +477,9 @@ export const mockList = {
loading: false,
issuesCount: 1,
maxIssueCount: 0,
+ metadata: {
+ epicsCount: 1,
+ },
__typename: 'BoardList',
};
diff --git a/spec/frontend/super_sidebar/components/super_sidebar_spec.js b/spec/frontend/super_sidebar/components/super_sidebar_spec.js
index 57c84bc87a6..32921da23aa 100644
--- a/spec/frontend/super_sidebar/components/super_sidebar_spec.js
+++ b/spec/frontend/super_sidebar/components/super_sidebar_spec.js
@@ -3,11 +3,17 @@ import SuperSidebar from '~/super_sidebar/components/super_sidebar.vue';
import HelpCenter from '~/super_sidebar/components/help_center.vue';
import UserBar from '~/super_sidebar/components/user_bar.vue';
import SidebarPortalTarget from '~/super_sidebar/components/sidebar_portal_target.vue';
+import { isCollapsed } from '~/super_sidebar/super_sidebar_collapsed_state_manager';
import { sidebarData } from '../mock_data';
+jest.mock('~/super_sidebar/super_sidebar_collapsed_state_manager', () => ({
+ isCollapsed: jest.fn(),
+}));
+
describe('SuperSidebar component', () => {
let wrapper;
+ const findSidebar = () => wrapper.find('.super-sidebar');
const findUserBar = () => wrapper.findComponent(UserBar);
const findHelpCenter = () => wrapper.findComponent(HelpCenter);
const findSidebarPortalTarget = () => wrapper.findComponent(SidebarPortalTarget);
@@ -22,19 +28,32 @@ describe('SuperSidebar component', () => {
};
describe('default', () => {
- beforeEach(() => {
+ it('add aria-hidden and inert attributes when collapsed', () => {
+ isCollapsed.mockReturnValue(true);
+ createWrapper();
+ expect(findSidebar().attributes('aria-hidden')).toBe('true');
+ expect(findSidebar().attributes('inert')).toBe('inert');
+ });
+
+ it('does not add aria-hidden and inert attributes when expanded', () => {
+ isCollapsed.mockReturnValue(false);
createWrapper();
+ expect(findSidebar().attributes('aria-hidden')).toBe('false');
+ expect(findSidebar().attributes('inert')).toBe(undefined);
});
it('renders UserBar with sidebarData', () => {
+ createWrapper();
expect(findUserBar().props('sidebarData')).toBe(sidebarData);
});
it('renders HelpCenter with sidebarData', () => {
+ createWrapper();
expect(findHelpCenter().props('sidebarData')).toBe(sidebarData);
});
it('renders SidebarPortalTarget', () => {
+ createWrapper();
expect(findSidebarPortalTarget().exists()).toBe(true);
});
});
diff --git a/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js b/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js
new file mode 100644
index 00000000000..27fa451cf7b
--- /dev/null
+++ b/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js
@@ -0,0 +1,132 @@
+import { GlBreakpointInstance as bp, breakpoints } from '@gitlab/ui/dist/utils';
+import { getCookie, setCookie } from '~/lib/utils/common_utils';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import {
+ SIDEBAR_COLLAPSED_CLASS,
+ SIDEBAR_COLLAPSED_COOKIE,
+ SIDEBAR_COLLAPSED_COOKIE_EXPIRATION,
+ toggleSuperSidebarCollapsed,
+ initSuperSidebarCollapsedState,
+ bindSuperSidebarCollapsedEvents,
+ findPage,
+ findSidebar,
+ findToggles,
+} from '~/super_sidebar/super_sidebar_collapsed_state_manager';
+
+const { xl, sm } = breakpoints;
+
+jest.mock('~/lib/utils/common_utils', () => ({
+ getCookie: jest.fn(),
+ setCookie: jest.fn(),
+}));
+
+const pageHasCollapsedClass = (hasClass) => {
+ if (hasClass) {
+ expect(findPage().classList).toContain(SIDEBAR_COLLAPSED_CLASS);
+ } else {
+ expect(findPage().classList).not.toContain(SIDEBAR_COLLAPSED_CLASS);
+ }
+};
+
+describe('Super Sidebar Collapsed State Manager', () => {
+ beforeEach(() => {
+ setHTMLFixture(`
+ <button class="js-super-sidebar-toggle"></button>
+ <div class="page-with-super-sidebar"></div>
+ <aside class="super-sidebar"></aside>
+ `);
+ });
+
+ afterEach(() => {
+ resetHTMLFixture();
+ });
+
+ describe('toggleSuperSidebarCollapsed', () => {
+ it.each`
+ collapsed | saveCookie | windowWidth | hasClass
+ ${true} | ${true} | ${xl} | ${true}
+ ${true} | ${false} | ${xl} | ${true}
+ ${true} | ${true} | ${sm} | ${true}
+ ${true} | ${false} | ${sm} | ${true}
+ ${false} | ${true} | ${xl} | ${false}
+ ${false} | ${false} | ${xl} | ${false}
+ ${false} | ${true} | ${sm} | ${false}
+ ${false} | ${false} | ${sm} | ${false}
+ `(
+ 'when collapsed is $collapsed, saveCookie is $saveCookie, and windowWidth is $windowWidth then page class contains `page-with-super-sidebar-collapsed` is $hasClass',
+ ({ collapsed, saveCookie, windowWidth, hasClass }) => {
+ jest.spyOn(bp, 'windowWidth').mockReturnValue(windowWidth);
+
+ toggleSuperSidebarCollapsed(collapsed, saveCookie);
+
+ pageHasCollapsedClass(hasClass);
+ expect(findSidebar().ariaHidden).toBe(collapsed);
+ expect(findSidebar().inert).toBe(collapsed);
+
+ if (saveCookie && windowWidth >= xl) {
+ expect(setCookie).toHaveBeenCalledWith(SIDEBAR_COLLAPSED_COOKIE, collapsed, {
+ expires: SIDEBAR_COLLAPSED_COOKIE_EXPIRATION,
+ });
+ } else {
+ expect(setCookie).not.toHaveBeenCalled();
+ }
+ },
+ );
+ });
+
+ describe('initSuperSidebarCollapsedState', () => {
+ it.each`
+ windowWidth | cookie | hasClass
+ ${xl} | ${undefined} | ${false}
+ ${sm} | ${undefined} | ${true}
+ ${xl} | ${'true'} | ${true}
+ ${sm} | ${'true'} | ${true}
+ `(
+ 'sets page class to `page-with-super-sidebar-collapsed` when windowWidth is $windowWidth and cookie value is $cookie',
+ ({ windowWidth, cookie, hasClass }) => {
+ jest.spyOn(bp, 'windowWidth').mockReturnValue(windowWidth);
+ getCookie.mockReturnValue(cookie);
+
+ initSuperSidebarCollapsedState();
+
+ pageHasCollapsedClass(hasClass);
+ expect(setCookie).not.toHaveBeenCalled();
+ },
+ );
+ });
+
+ describe('bindSuperSidebarCollapsedEvents', () => {
+ it.each`
+ windowWidth | cookie | hasClass
+ ${xl} | ${undefined} | ${true}
+ ${sm} | ${undefined} | ${true}
+ ${xl} | ${'true'} | ${false}
+ ${sm} | ${'true'} | ${false}
+ `(
+ 'toggle click sets page class to `page-with-super-sidebar-collapsed` when windowWidth is $windowWidth and cookie value is $cookie',
+ ({ windowWidth, cookie, hasClass }) => {
+ setHTMLFixture(`
+ <button class="js-super-sidebar-toggle"></button>
+ <div class="page-with-super-sidebar ${cookie ? SIDEBAR_COLLAPSED_CLASS : ''}"></div>
+ <aside class="super-sidebar"></aside>
+ `);
+ jest.spyOn(bp, 'windowWidth').mockReturnValue(windowWidth);
+ getCookie.mockReturnValue(cookie);
+
+ bindSuperSidebarCollapsedEvents();
+
+ findToggles()[0].click();
+
+ pageHasCollapsedClass(hasClass);
+
+ if (windowWidth >= xl) {
+ expect(setCookie).toHaveBeenCalledWith(SIDEBAR_COLLAPSED_COOKIE, !cookie, {
+ expires: SIDEBAR_COLLAPSED_COOKIE_EXPIRATION,
+ });
+ } else {
+ expect(setCookie).not.toHaveBeenCalled();
+ }
+ },
+ );
+ });
+});
diff --git a/spec/services/jira_connect_installations/proxy_lifecycle_event_service_spec.rb b/spec/services/jira_connect_installations/proxy_lifecycle_event_service_spec.rb
index c621388a734..3c144de2208 100644
--- a/spec/services/jira_connect_installations/proxy_lifecycle_event_service_spec.rb
+++ b/spec/services/jira_connect_installations/proxy_lifecycle_event_service_spec.rb
@@ -94,9 +94,9 @@ RSpec.describe JiraConnectInstallations::ProxyLifecycleEventService, feature_cat
expect(Gitlab::IntegrationsLogger).to receive(:info).with(
integration: 'JiraConnect',
message: 'Proxy lifecycle event received error response',
- event_type: evnet_type,
- status_code: 422,
- body: 'Error message'
+ jira_event_type: evnet_type,
+ jira_status_code: 422,
+ jira_body: 'Error message'
)
execute_service
diff --git a/spec/views/devise/confirmations/almost_there.html.haml_spec.rb b/spec/views/devise/confirmations/almost_there.html.haml_spec.rb
index c091efe9295..8e12fb5a17e 100644
--- a/spec/views/devise/confirmations/almost_there.html.haml_spec.rb
+++ b/spec/views/devise/confirmations/almost_there.html.haml_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
RSpec.describe 'devise/confirmations/almost_there' do
- describe 'confirmations text' do
- subject { render(template: 'devise/confirmations/almost_there') }
+ subject { render(template: 'devise/confirmations/almost_there') }
+ describe 'confirmations text' do
before do
allow(view).to receive(:params).and_return(email: email)
end
@@ -34,4 +34,17 @@ RSpec.describe 'devise/confirmations/almost_there' do
end
end
end
+
+ describe 'register again prompt' do
+ specify do
+ subject
+
+ expect(rendered).to have_content(
+ 'If the email address is incorrect, you can register again with a different email'
+ )
+ expect(rendered).to have_link(
+ 'register again with a different email', href: new_user_registration_path
+ )
+ end
+ end
end