diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-11 21:08:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-11 21:08:31 +0300 |
commit | 1a2f754734eb189e371e25e685413808f69a7f2c (patch) | |
tree | 2c97884971f36d9026600897b74364d2e212a109 /app/assets/javascripts/boards | |
parent | f1ce71c88c407709987dd4a7b40bdb7596b6baa2 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/boards')
6 files changed, 170 insertions, 58 deletions
diff --git a/app/assets/javascripts/boards/components/board_app.vue b/app/assets/javascripts/boards/components/board_app.vue index 48dfcf81f1e..c7e6cb38d15 100644 --- a/app/assets/javascripts/boards/components/board_app.vue +++ b/app/assets/javascripts/boards/components/board_app.vue @@ -4,6 +4,7 @@ import { refreshCurrentPage, queryToObject } from '~/lib/utils/url_utility'; import BoardContent from '~/boards/components/board_content.vue'; import BoardSettingsSidebar from '~/boards/components/board_settings_sidebar.vue'; import BoardTopBar from '~/boards/components/board_top_bar.vue'; +import activeBoardItemQuery from 'ee_else_ce/boards/graphql/client/active_board_item.query.graphql'; export default { components: { @@ -11,7 +12,7 @@ export default { BoardSettingsSidebar, BoardTopBar, }, - inject: ['initialBoardId', 'initialFilterParams'], + inject: ['initialBoardId', 'initialFilterParams', 'isIssueBoard', 'isApolloBoard'], data() { return { boardId: this.initialBoardId, @@ -19,11 +20,31 @@ export default { isShowingEpicsSwimlanes: Boolean(queryToObject(window.location.search).group_by), }; }, + apollo: { + activeBoardItem: { + query: activeBoardItemQuery, + variables() { + return { + isIssue: this.isIssueBoard, + }; + }, + skip() { + return !this.isApolloBoard; + }, + }, + }, + computed: { ...mapGetters(['isSidebarOpen']), isSwimlanesOn() { return (gon?.licensed_features?.swimlanes && this.isShowingEpicsSwimlanes) ?? false; }, + isAnySidebarOpen() { + if (this.isApolloBoard) { + return this.activeBoardItem?.id; + } + return this.isSidebarOpen; + }, }, created() { window.addEventListener('popstate', refreshCurrentPage); @@ -45,7 +66,7 @@ export default { </script> <template> - <div class="boards-app gl-relative" :class="{ 'is-compact': isSidebarOpen }"> + <div class="boards-app gl-relative" :class="{ 'is-compact': isAnySidebarOpen }"> <board-top-bar :board-id="boardId" :is-swimlanes-on="isSwimlanesOn" diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue index 3071c1f334e..18495f285da 100644 --- a/app/assets/javascripts/boards/components/board_card.vue +++ b/app/assets/javascripts/boards/components/board_card.vue @@ -1,6 +1,8 @@ <script> import { mapActions, mapState } from 'vuex'; import Tracking from '~/tracking'; +import setActiveBoardItemMutation from 'ee_else_ce/boards/graphql/client/set_active_board_item.mutation.graphql'; +import activeBoardItemQuery from 'ee_else_ce/boards/graphql/client/active_board_item.query.graphql'; import BoardCardInner from './board_card_inner.vue'; export default { @@ -9,7 +11,7 @@ export default { BoardCardInner, }, mixins: [Tracking.mixin()], - inject: ['disabled', 'isApolloBoard'], + inject: ['disabled', 'isIssueBoard', 'isApolloBoard'], props: { list: { type: Object, @@ -37,14 +39,30 @@ export default { default: true, }, }, + apollo: { + activeBoardItem: { + query: activeBoardItemQuery, + variables() { + return { + isIssue: this.isIssueBoard, + }; + }, + skip() { + return !this.isApolloBoard; + }, + }, + }, computed: { ...mapState(['selectedBoardItems', 'activeId']), + activeItemId() { + return this.isApolloBoard ? this.activeBoardItem?.id : this.activeId; + }, isActive() { - return this.item.id === this.activeId; + return this.item.id === this.activeItemId; }, multiSelectVisible() { return ( - !this.activeId && + !this.activeItemId && this.selectedBoardItems.findIndex((boardItem) => boardItem.id === this.item.id) > -1 ); }, @@ -83,10 +101,23 @@ export default { if (isMultiSelect && gon?.features?.boardMultiSelect) { this.toggleBoardItemMultiSelection(this.item); } else { - this.toggleBoardItem({ boardItem: this.item }); + if (this.isApolloBoard) { + this.toggleItem(); + } else { + this.toggleBoardItem({ boardItem: this.item }); + } this.track('click_card', { label: 'right_sidebar' }); } }, + toggleItem() { + this.$apollo.mutate({ + mutation: setActiveBoardItemMutation, + variables: { + boardItem: this.item, + isIssue: this.isIssueBoard, + }, + }); + }, }, }; </script> diff --git a/app/assets/javascripts/boards/components/board_content_sidebar.vue b/app/assets/javascripts/boards/components/board_content_sidebar.vue index 779fd1be918..1b97214ff8b 100644 --- a/app/assets/javascripts/boards/components/board_content_sidebar.vue +++ b/app/assets/javascripts/boards/components/board_content_sidebar.vue @@ -3,10 +3,12 @@ import { GlDrawer } from '@gitlab/ui'; import { MountingPortal } from 'portal-vue'; import { mapState, mapActions, mapGetters } from 'vuex'; import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdown_widget.vue'; +import activeBoardItemQuery from 'ee_else_ce/boards/graphql/client/active_board_item.query.graphql'; +import setActiveBoardItemMutation from 'ee_else_ce/boards/graphql/client/set_active_board_item.mutation.graphql'; import { __, sprintf } from '~/locale'; import BoardSidebarTimeTracker from '~/boards/components/sidebar/board_sidebar_time_tracker.vue'; import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue'; -import { ISSUABLE, INCIDENT } from '~/boards/constants'; +import { INCIDENT } from '~/boards/constants'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { TYPE_ISSUE, WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants'; import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue'; @@ -16,7 +18,6 @@ import SidebarSeverityWidget from '~/sidebar/components/severity/sidebar_severit import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue'; import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue'; import SidebarLabelsWidget from '~/sidebar/components/labels/labels_select_widget/labels_select_root.vue'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; export default { components: { @@ -39,7 +40,6 @@ export default { SidebarWeightWidget: () => import('ee_component/sidebar/components/weight/sidebar_weight_widget.vue'), }, - mixins: [glFeatureFlagMixin()], inject: { multipleAssigneesFeatureAvailable: { default: false, @@ -71,31 +71,46 @@ export default { isGroupBoard: { default: false, }, + isApolloBoard: { + default: false, + }, }, inheritAttrs: false, + apollo: { + activeBoardCard: { + query: activeBoardItemQuery, + variables: { + isIssue: true, + }, + update(data) { + if (!data.activeBoardItem?.id) { + return { id: '', iid: '' }; + } + return { + ...data.activeBoardItem, + assignees: data.activeBoardItem.assignees?.nodes || [], + }; + }, + skip() { + return !this.isApolloBoard; + }, + }, + }, computed: { - ...mapGetters([ - 'isSidebarOpen', - 'activeBoardItem', - 'groupPathForActiveIssue', - 'projectPathForActiveIssue', - ]), + ...mapGetters(['activeBoardItem']), ...mapState(['sidebarType']), - isIssuableSidebar() { - return this.sidebarType === ISSUABLE; + activeBoardIssuable() { + return this.isApolloBoard ? this.activeBoardCard : this.activeBoardItem; }, - isIncidentSidebar() { - return this.activeBoardItem.type === INCIDENT; + isSidebarOpen() { + return Boolean(this.activeBoardIssuable?.id); }, - showSidebar() { - return this.isIssuableSidebar && this.isSidebarOpen; + isIncidentSidebar() { + return this.activeBoardIssuable?.type === INCIDENT; }, sidebarTitle() { return this.isIncidentSidebar ? __('Incident details') : __('Issue details'); }, - fullPath() { - return this.activeBoardItem?.referencePath?.split('#')[0] || ''; - }, parentType() { return this.isGroupBoard ? WORKSPACE_GROUP : WORKSPACE_PROJECT; }, @@ -120,6 +135,14 @@ export default { ? this.labelsFilterBasePath.replace(':project_path', this.projectPathForActiveIssue) : this.labelsFilterBasePath; }, + groupPathForActiveIssue() { + const { referencePath = '' } = this.activeBoardIssuable; + return referencePath.slice(0, referencePath.lastIndexOf('/')); + }, + projectPathForActiveIssue() { + const { referencePath = '' } = this.activeBoardIssuable; + return referencePath.slice(0, referencePath.indexOf('#')); + }, }, methods: { ...mapActions([ @@ -131,7 +154,19 @@ export default { 'setActiveItemHealthStatus', ]), handleClose() { - this.toggleBoardItem({ boardItem: this.activeBoardItem, sidebarType: this.sidebarType }); + if (this.isApolloBoard) { + this.$apollo.mutate({ + mutation: setActiveBoardItemMutation, + variables: { + boardItem: null, + }, + }); + } else { + this.toggleBoardItem({ + boardItem: this.activeBoardIssuable, + sidebarType: this.sidebarType, + }); + } }, handleUpdateSelectedLabels({ labels, id }) { this.setActiveBoardItemLabels({ @@ -143,7 +178,7 @@ export default { }, handleLabelRemove(removeLabelId) { this.setActiveBoardItemLabels({ - iid: this.activeBoardItem.iid, + iid: this.activeBoardIssuable.iid, projectPath: this.projectPathForActiveIssue, removeLabelIds: [removeLabelId], }); @@ -156,7 +191,7 @@ export default { <mounting-portal mount-to="#js-right-sidebar-portal" name="board-content-sidebar" append> <gl-drawer v-bind="$attrs" - :open="showSidebar" + :open="isSidebarOpen" class="boards-sidebar" variant="sidebar" @close="handleClose" @@ -167,26 +202,27 @@ export default { <template #header> <sidebar-todo-widget class="gl-mt-3" - :issuable-id="activeBoardItem.id" - :issuable-iid="activeBoardItem.iid" - :full-path="fullPath" + :issuable-id="activeBoardIssuable.id" + :issuable-iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" :issuable-type="issuableType" /> </template> <template #default> - <board-sidebar-title data-testid="sidebar-title" /> + <board-sidebar-title :active-item="activeBoardIssuable" data-testid="sidebar-title" /> <sidebar-assignees-widget - :iid="activeBoardItem.iid" - :full-path="fullPath" - :initial-assignees="activeBoardItem.assignees" + v-if="activeBoardItem.assignees" + :iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" + :initial-assignees="activeBoardIssuable.assignees" :allow-multiple-assignees="multipleAssigneesFeatureAvailable" :editable="canUpdate" - @assignees-updated="setAssignees" + @assignees-updated="!isApolloBoard && setAssignees($event)" /> <sidebar-dropdown-widget v-if="epicFeatureAvailable && !isIncidentSidebar" :key="`epic-${activeBoardItem.iid}`" - :iid="activeBoardItem.iid" + :iid="activeBoardIssuable.iid" issuable-attribute="epic" :workspace-path="projectPathForActiveIssue" :attr-workspace-path="groupPathForActiveIssue" @@ -196,7 +232,7 @@ export default { <div> <sidebar-dropdown-widget :key="`milestone-${activeBoardItem.iid}`" - :iid="activeBoardItem.iid" + :iid="activeBoardIssuable.iid" issuable-attribute="milestone" :workspace-path="projectPathForActiveIssue" :attr-workspace-path="projectPathForActiveIssue" @@ -206,7 +242,7 @@ export default { <sidebar-iteration-widget v-if="iterationFeatureAvailable && !isIncidentSidebar" :key="`iteration-${activeBoardItem.iid}`" - :iid="activeBoardItem.iid" + :iid="activeBoardIssuable.iid" :workspace-path="projectPathForActiveIssue" :attr-workspace-path="groupPathForActiveIssue" :issuable-type="issuableType" @@ -216,14 +252,14 @@ export default { </div> <board-sidebar-time-tracker /> <sidebar-date-widget - :iid="activeBoardItem.iid" - :full-path="fullPath" + :iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" :issuable-type="issuableType" data-testid="sidebar-due-date" /> <sidebar-labels-widget class="block labels" - :iid="activeBoardItem.iid" + :iid="activeBoardIssuable.iid" :full-path="projectPathForActiveIssue" :allow-label-remove="allowLabelEdit" :allow-multiselect="true" @@ -235,40 +271,40 @@ export default { workspace-type="project" :issuable-type="issuableType" :label-create-type="labelType" - @onLabelRemove="handleLabelRemove" - @updateSelectedLabels="handleUpdateSelectedLabels" + @onLabelRemove="!isApolloBoard && handleLabelRemove($event)" + @updateSelectedLabels="!isApolloBoard && handleUpdateSelectedLabels($event)" > {{ __('None') }} </sidebar-labels-widget> <sidebar-severity-widget v-if="isIncidentSidebar" - :iid="activeBoardItem.iid" - :project-path="fullPath" - :initial-severity="activeBoardItem.severity" + :iid="activeBoardIssuable.iid" + :project-path="projectPathForActiveIssue" + :initial-severity="activeBoardIssuable.severity" /> <sidebar-weight-widget v-if="weightFeatureAvailable && !isIncidentSidebar" - :iid="activeBoardItem.iid" - :full-path="fullPath" + :iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" :issuable-type="issuableType" - @weightUpdated="setActiveItemWeight($event)" + @weightUpdated="!isApolloBoard && setActiveItemWeight($event)" /> <sidebar-health-status-widget v-if="healthStatusFeatureAvailable" - :iid="activeBoardItem.iid" - :full-path="fullPath" + :iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" :issuable-type="issuableType" - @statusUpdated="setActiveItemHealthStatus($event)" + @statusUpdated="!isApolloBoard && setActiveItemHealthStatus($event)" /> <sidebar-confidentiality-widget - :iid="activeBoardItem.iid" - :full-path="fullPath" + :iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" :issuable-type="issuableType" - @confidentialityUpdated="setActiveItemConfidential($event)" + @confidentialityUpdated="!isApolloBoard && setActiveItemConfidential($event)" /> <sidebar-subscriptions-widget - :iid="activeBoardItem.iid" - :full-path="fullPath" + :iid="activeBoardIssuable.iid" + :full-path="projectPathForActiveIssue" :issuable-type="issuableType" data-testid="sidebar-notifications" /> diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue index 43a2b13b81c..f92c06956a8 100644 --- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue +++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue @@ -19,6 +19,13 @@ export default { directives: { autofocusonshow, }, + inject: ['isApolloBoard'], + props: { + activeItem: { + type: Object, + required: true, + }, + }, data() { return { title: '', @@ -27,7 +34,10 @@ export default { }; }, computed: { - ...mapGetters({ item: 'activeBoardItem' }), + ...mapGetters(['activeBoardItem']), + item() { + return this.isApolloBoard ? this.activeItem : this.activeBoardItem; + }, pendingChangesStorageKey() { return this.getPendingChangesKey(this.item); }, diff --git a/app/assets/javascripts/boards/graphql/client/active_board_item.query.graphql b/app/assets/javascripts/boards/graphql/client/active_board_item.query.graphql new file mode 100644 index 00000000000..81b1b68a038 --- /dev/null +++ b/app/assets/javascripts/boards/graphql/client/active_board_item.query.graphql @@ -0,0 +1,7 @@ +#import "ee_else_ce/boards/graphql/issue.fragment.graphql" + +query activeBoardItem { + activeBoardItem @client { + ...Issue + } +} diff --git a/app/assets/javascripts/boards/graphql/client/set_active_board_item.mutation.graphql b/app/assets/javascripts/boards/graphql/client/set_active_board_item.mutation.graphql new file mode 100644 index 00000000000..cce558c649e --- /dev/null +++ b/app/assets/javascripts/boards/graphql/client/set_active_board_item.mutation.graphql @@ -0,0 +1,7 @@ +#import "ee_else_ce/boards/graphql/issue.fragment.graphql" + +mutation setActiveBoardItem($boardItem: Issue) { + setActiveBoardItem(boardItem: $boardItem) @client { + ...Issue + } +} |