diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-14 15:09:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-14 15:09:51 +0300 |
commit | 3a19c55d3a1dda9e0ea041d910bf31d1ddda7acd (patch) | |
tree | 2ef73d75c8206531027f7e7718ac7ce00ce13126 /app | |
parent | 8a7464317976dc9e2bdad560505dd0959bb03f1f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
9 files changed, 139 insertions, 33 deletions
diff --git a/app/assets/javascripts/ci/pipeline_details/graph/components/job_item.vue b/app/assets/javascripts/ci/pipeline_details/graph/components/job_item.vue index c6340e6787a..a1554288e51 100644 --- a/app/assets/javascripts/ci/pipeline_details/graph/components/job_item.vue +++ b/app/assets/javascripts/ci/pipeline_details/graph/components/job_item.vue @@ -343,7 +343,7 @@ export default { </div> <gl-badge v-if="isBridge" - class="gl-mt-3" + class="gl-mt-3 gl-ml-7" variant="info" size="sm" data-testid="job-bridge-badge" diff --git a/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipeline.vue b/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipeline.vue index 26521f87426..e01bc33497f 100644 --- a/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipeline.vue +++ b/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipeline.vue @@ -287,7 +287,7 @@ export default { /> <div v-else :class="$options.styles.actionSizeClasses"></div> </div> - <div class="gl-pt-2"> + <div class="gl-pt-2 gl-ml-7"> <gl-badge size="sm" variant="info" data-testid="downstream-pipeline-label"> {{ label }} </gl-badge> diff --git a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue index 9c23f239b4c..440d0344ae0 100644 --- a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue +++ b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue @@ -7,6 +7,7 @@ import { createAlert } from '~/alert'; import { TYPE_ISSUE } from '~/issues/constants'; import { __ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import eventHub from '../../event_hub'; import getMergeRequestReviewersQuery from '../../queries/get_merge_request_reviewers.query.graphql'; import mergeRequestReviewersUpdatedSubscription from '../../queries/merge_request_reviewers.subscription.graphql'; @@ -26,6 +27,7 @@ export default { ReviewerTitle, Reviewers, }, + mixins: [glFeatureFlagsMixin()], props: { mediator: { type: Object, @@ -56,6 +58,7 @@ export default { return { iid: this.issuableIid, fullPath: this.projectPath, + mrRequestChanges: this.glFeatures.mrRequestChanges, }; }, update(data) { @@ -74,6 +77,7 @@ export default { variables() { return { issuableId: this.issuable?.id, + mrRequestChanges: this.glFeatures.mrRequestChanges, }; }, skip() { diff --git a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue index 99f9d5e872c..c345f8f07fc 100644 --- a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue +++ b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue @@ -2,12 +2,36 @@ import { GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui'; import { TYPE_ISSUE } from '~/issues/constants'; import { __, sprintf, s__ } from '~/locale'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import ReviewerAvatarLink from './reviewer_avatar_link.vue'; const LOADING_STATE = 'loading'; const SUCCESS_STATE = 'success'; const JUST_APPROVED = 'approved'; +const REVIEW_STATE_ICONS = { + APPROVED: { + name: 'status-success', + class: 'gl-text-green-500', + title: __('Reviewer approved changes'), + }, + REQUESTED_CHANGES: { + name: 'status-alert', + class: 'gl-text-red-500', + title: __('Reviewer requested changes'), + }, + REVIEWED: { + name: 'comment', + class: 'gl-bg-blue-500 gl-text-white gl-icon s16 gl-rounded-full gl--flex-center', + size: 8, + title: __('Reviewer commented'), + }, + UNREVIEWED: { + name: 'dotted-circle', + title: __('Awaiting review'), + }, +}; + export default { i18n: { reRequestReview: __('Re-request review'), @@ -20,6 +44,7 @@ export default { directives: { GlTooltip: GlTooltipDirective, }, + mixins: [glFeatureFlagsMixin()], props: { users: { type: Array, @@ -105,6 +130,18 @@ export default { this.loadingStates[userId] = null; } }, + reviewStateIcon(user) { + if (user.mergeRequestInteraction.approved) return REVIEW_STATE_ICONS.APPROVED; + + return REVIEW_STATE_ICONS[user.mergeRequestInteraction.reviewState]; + }, + showRequestReviewButton(user) { + if (this.glFeatures.mrRequestChanges) { + return user.mergeRequestInteraction.reviewState !== 'UNREVIEWED'; + } + + return true; + }, }, LOADING_STATE, SUCCESS_STATE, @@ -134,7 +171,7 @@ export default { </div> </reviewer-avatar-link> <gl-button - v-if="user.mergeRequestInteraction.canUpdate && user.mergeRequestInteraction.reviewed" + v-if="user.mergeRequestInteraction.canUpdate && showRequestReviewButton(user)" v-gl-tooltip.left :title="$options.i18n.reRequestReview" :aria-label="$options.i18n.reRequestReview" @@ -146,25 +183,42 @@ export default { data-testid="re-request-button" @click="reRequestReview(user.id)" /> - <gl-icon - v-if="user.mergeRequestInteraction.approved" - v-gl-tooltip.left - :size="16" - :title="approvedByTooltipTitle(user)" - name="status-success" - class="float-right gl-my-2 gl-ml-auto gl-text-green-500 gl-flex-shrink-0" - :class="approveAnimation(user.id)" - data-testid="approved" - /> - <gl-icon - v-else-if="user.mergeRequestInteraction.reviewed" - v-gl-tooltip.left - :size="16" - :title="reviewedButNotApprovedTooltip(user)" - name="dotted-circle" - class="float-right gl-my-2 gl-ml-auto gl-text-gray-400 gl-flex-shrink-0" - data-testid="reviewed-not-approved" - /> + <template v-if="glFeatures.mrRequestChanges"> + <span + v-gl-tooltip.top.viewport + :title="reviewStateIcon(user).title" + :class="reviewStateIcon(user).class" + class="float-right gl-my-2 gl-ml-auto gl-flex-shrink-0" + > + <gl-icon + :size="reviewStateIcon(user).size || 16" + :name="reviewStateIcon(user).name" + :aria-label="reviewStateIcon(user).title" + data-testid="reviewer-state-icon" + /> + </span> + </template> + <template v-else> + <gl-icon + v-if="user.mergeRequestInteraction.approved" + v-gl-tooltip.left + :size="16" + :title="approvedByTooltipTitle(user)" + name="status-success" + class="float-right gl-my-2 gl-ml-auto gl-text-green-500 gl-flex-shrink-0" + :class="approveAnimation(user.id)" + data-testid="approved" + /> + <gl-icon + v-else-if="user.mergeRequestInteraction.reviewed" + v-gl-tooltip.left + :size="16" + :title="reviewedButNotApprovedTooltip(user)" + name="dotted-circle" + class="float-right gl-my-2 gl-ml-auto gl-text-gray-400 gl-flex-shrink-0" + data-testid="reviewed-not-approved" + /> + </template> </div> </div> </template> diff --git a/app/assets/javascripts/sidebar/queries/get_merge_request_reviewers.query.graphql b/app/assets/javascripts/sidebar/queries/get_merge_request_reviewers.query.graphql index f087ca6c982..6d3d2302a19 100644 --- a/app/assets/javascripts/sidebar/queries/get_merge_request_reviewers.query.graphql +++ b/app/assets/javascripts/sidebar/queries/get_merge_request_reviewers.query.graphql @@ -1,7 +1,7 @@ #import "~/graphql_shared/fragments/user.fragment.graphql" #import "~/graphql_shared/fragments/user_availability.fragment.graphql" -query mergeRequestReviewers($fullPath: ID!, $iid: String!) { +query mergeRequestReviewers($fullPath: ID!, $iid: String!, $mrRequestChanges: Boolean!) { workspace: project(fullPath: $fullPath) { id issuable: mergeRequest(iid: $iid) { @@ -14,7 +14,8 @@ query mergeRequestReviewers($fullPath: ID!, $iid: String!) { canMerge canUpdate approved - reviewed + reviewed @skip(if: $mrRequestChanges) + reviewState @include(if: $mrRequestChanges) } } } diff --git a/app/assets/javascripts/sidebar/queries/merge_request_reviewers.subscription.graphql b/app/assets/javascripts/sidebar/queries/merge_request_reviewers.subscription.graphql index a1b16b378b3..0fcfe297394 100644 --- a/app/assets/javascripts/sidebar/queries/merge_request_reviewers.subscription.graphql +++ b/app/assets/javascripts/sidebar/queries/merge_request_reviewers.subscription.graphql @@ -1,7 +1,7 @@ #import "~/graphql_shared/fragments/user.fragment.graphql" #import "~/graphql_shared/fragments/user_availability.fragment.graphql" -subscription mergeRequestReviewersUpdated($issuableId: IssuableID!) { +subscription mergeRequestReviewersUpdated($issuableId: IssuableID!, $mrRequestChanges: Boolean!) { mergeRequestReviewersUpdated(issuableId: $issuableId) { ... on MergeRequest { id @@ -13,7 +13,8 @@ subscription mergeRequestReviewersUpdated($issuableId: IssuableID!) { canMerge canUpdate approved - reviewed + reviewed @skip(if: $mrRequestChanges) + reviewState @include(if: $mrRequestChanges) } } } diff --git a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue index 5f7cfce93b1..b8618e09761 100644 --- a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue +++ b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue @@ -1,6 +1,8 @@ <script> import { GlButton } from '@gitlab/ui'; +import { GlBreakpointInstance, breakpoints } from '@gitlab/ui/dist/utils'; import { Mousetrap } from '~/lib/mousetrap'; +import { TAB_KEY_CODE } from '~/lib/utils/keycodes'; import { keysFor, TOGGLE_SUPER_SIDEBAR } from '~/behaviors/shortcuts/keybindings'; import { __, s__ } from '~/locale'; import Tracking from '~/tracking'; @@ -68,6 +70,13 @@ export default { }; }, }, + watch: { + 'sidebarState.isCollapsed': { + handler() { + this.setupFocusTrapListener(); + }, + }, + }, created() { const { is_logged_in: isLoggedIn, @@ -80,9 +89,11 @@ export default { } }, mounted() { + this.setupFocusTrapListener(); Mousetrap.bind(keysFor(TOGGLE_SUPER_SIDEBAR), this.toggleSidebar); }, beforeDestroy() { + document.removeEventListener('keydown', this.focusTrap); Mousetrap.unbind(keysFor(TOGGLE_SUPER_SIDEBAR)); }, methods: { @@ -93,6 +104,17 @@ export default { }); toggleSuperSidebarCollapsed(!isCollapsed(), true); }, + setupFocusTrapListener() { + /** + * Only trap focus when sidebar displays over page content to avoid + * focus moving to page content and being obscured by the sidebar + */ + if (GlBreakpointInstance.windowWidth() < breakpoints.xl && !this.sidebarState.isCollapsed) { + document.addEventListener('keydown', this.focusTrap); + } else { + document.removeEventListener('keydown', this.focusTrap); + } + }, collapseSidebar() { toggleSuperSidebarCollapsed(true, false); }, @@ -122,6 +144,23 @@ export default { this.sidebarState.isCollapsed = true; } }, + focusTrap(event) { + const { keyCode, shiftKey } = event; + const firstFocusableElement = this.$refs.userBar.$el.querySelector('a'); + const lastFocusableElement = this.$refs.helpCenter.$el.querySelector('button'); + + if (keyCode !== TAB_KEY_CODE) return; + + if (shiftKey) { + if (document.activeElement === firstFocusableElement) { + lastFocusableElement.focus(); + event.preventDefault(); + } + } else if (document.activeElement === lastFocusableElement) { + firstFocusableElement.focus(); + event.preventDefault(); + } + }, }, }; </script> @@ -152,7 +191,7 @@ export default { <h2 id="super-sidebar-heading" class="gl-sr-only"> {{ $options.i18n.primaryNavigation }} </h2> - <user-bar :has-collapse-button="!showOverlay" :sidebar-data="sidebarData" /> + <user-bar ref="userBar" :has-collapse-button="!showOverlay" :sidebar-data="sidebarData" /> <div v-if="showTrialStatusWidget" class="gl-px-2 gl-py-2"> <trial-status-widget class="gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-mb-1 gl-px-3 gl-line-height-normal gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-py-3" @@ -180,7 +219,7 @@ export default { <sidebar-portal-target /> </div> <div class="gl-p-3"> - <help-center :sidebar-data="sidebarData" /> + <help-center ref="helpCenter" :sidebar-data="sidebarData" /> </div> </div> </nav> diff --git a/app/assets/stylesheets/page_bundles/pipeline.scss b/app/assets/stylesheets/page_bundles/pipeline.scss index aaec277cf08..6b68fa75001 100644 --- a/app/assets/stylesheets/page_bundles/pipeline.scss +++ b/app/assets/stylesheets/page_bundles/pipeline.scss @@ -303,7 +303,7 @@ .pipeline-show-container, .pipeline-links-container { @media (max-width: $breakpoint-sm) { - width: 100%; + flex-basis: 100%; } } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 8e0fab04ab2..e8e8607a0b5 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -1136,10 +1136,7 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio; } .user-activity-content { - &::before { - @include vertical-line(80px, 25px); - background: var(--gray-50, $gray-50); - } + @include gl-relative; .system-note-image { @include gl--flex-center; @@ -1153,6 +1150,16 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio; } } +.user-profile-activity { + @include gl-relative; + + &:not(:last-child)::before { + @include vertical-line(16px, 10px); + height: 100%; + background: var(--gray-50, $gray-50); + } +} + //This needs to be deleted when Snippet/Commit comments are convered to Vue // See https://gitlab.com/gitlab-org/gitlab-foss/issues/53918#note_117038785 .unstyled-comments { |