diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-09 09:13:16 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-09 09:13:16 +0000 |
commit | ece36a21699c2a218b8bd14b22bea47d22218354 (patch) | |
tree | 8e08e12d70ead67a9b1f6951d29661463fda6387 /app/assets | |
parent | e168d3919a2c82eafa1d1f81e4b96aedae28717a (diff) | |
download | gitlab-ce-ece36a21699c2a218b8bd14b22bea47d22218354.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
6 files changed, 152 insertions, 128 deletions
diff --git a/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue b/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue index 08aec58e89d..789cf77a88a 100644 --- a/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue +++ b/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue @@ -130,8 +130,11 @@ export default { }, }, watch: { - message() { - this.renderPreview(); + message: { + handler() { + this.renderPreview(); + }, + immediate: true, }, }, methods: { diff --git a/app/assets/javascripts/boards/components/board_app.vue b/app/assets/javascripts/boards/components/board_app.vue index da472ad3d72..3a247819850 100644 --- a/app/assets/javascripts/boards/components/board_app.vue +++ b/app/assets/javascripts/boards/components/board_app.vue @@ -1,24 +1,42 @@ <script> import { mapGetters } from 'vuex'; import { refreshCurrentPage, queryToObject } from '~/lib/utils/url_utility'; +import { s__ } from '~/locale'; 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 { listsQuery } from 'ee_else_ce/boards/constants'; +import { formatBoardLists } from 'ee_else_ce/boards/boards_util'; import activeBoardItemQuery from 'ee_else_ce/boards/graphql/client/active_board_item.query.graphql'; export default { + i18n: { + fetchError: s__( + 'Boards|An error occurred while fetching the board lists. Please reload the page.', + ), + }, components: { BoardContent, BoardSettingsSidebar, BoardTopBar, }, - inject: ['initialBoardId', 'initialFilterParams', 'isIssueBoard', 'isApolloBoard'], + inject: [ + 'fullPath', + 'initialBoardId', + 'initialFilterParams', + 'isIssueBoard', + 'isGroupBoard', + 'issuableType', + 'boardType', + 'isApolloBoard', + ], data() { return { activeListId: '', boardId: this.initialBoardId, filterParams: { ...this.initialFilterParams }, isShowingEpicsSwimlanes: Boolean(queryToObject(window.location.search).group_by), + apolloError: null, }; }, apollo: { @@ -38,10 +56,39 @@ export default { return !this.isApolloBoard; }, }, + boardListsApollo: { + query() { + return listsQuery[this.issuableType].query; + }, + variables() { + return this.listQueryVariables; + }, + skip() { + return !this.isApolloBoard; + }, + update(data) { + const { lists } = data[this.boardType].board; + return formatBoardLists(lists); + }, + error() { + this.apolloError = this.$options.i18n.fetchError; + }, + }, }, computed: { ...mapGetters(['isSidebarOpen']), + listQueryVariables() { + return { + ...(this.isIssueBoard && { + isGroup: this.isGroupBoard, + isProject: !this.isGroupBoard, + }), + fullPath: this.fullPath, + boardId: this.boardId, + filters: this.filterParams, + }; + }, isSwimlanesOn() { return (gon?.licensed_features?.swimlanes && this.isShowingEpicsSwimlanes) ?? false; }, @@ -51,6 +98,9 @@ export default { } return this.isSidebarOpen; }, + activeList() { + return this.activeListId ? this.boardListsApollo[this.activeListId] : undefined; + }, }, created() { window.addEventListener('popstate', refreshCurrentPage); @@ -85,14 +135,20 @@ export default { @toggleSwimlanes="isShowingEpicsSwimlanes = $event" /> <board-content + v-if="!isApolloBoard || boardListsApollo" :board-id="boardId" :is-swimlanes-on="isSwimlanesOn" :filter-params="filterParams" + :board-lists-apollo="boardListsApollo" + :apollo-error="apolloError" @setActiveList="setActiveId" /> <board-settings-sidebar + v-if="!isApolloBoard || activeList" + :list="activeList" :list-id="activeListId" :board-id="boardId" + :query-variables="listQueryVariables" @unsetActiveId="setActiveId('')" /> </div> diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue index 1d22b79fba6..ed87a86e5b6 100644 --- a/app/assets/javascripts/boards/components/board_content.vue +++ b/app/assets/javascripts/boards/components/board_content.vue @@ -5,20 +5,13 @@ import { sortBy, throttle } from 'lodash'; import Draggable from 'vuedraggable'; import { mapState, mapActions } from 'vuex'; import { contentTop } from '~/lib/utils/common_utils'; -import { s__ } from '~/locale'; import eventHub from '~/boards/eventhub'; -import { formatBoardLists } from 'ee_else_ce/boards/boards_util'; import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue'; import { defaultSortableOptions } from '~/sortable/constants'; -import { DraggableItemTypes, listsQuery } from 'ee_else_ce/boards/constants'; +import { DraggableItemTypes } from 'ee_else_ce/boards/constants'; import BoardColumn from './board_column.vue'; export default { - i18n: { - fetchError: s__( - 'Boards|An error occurred while fetching the board lists. Please reload the page.', - ), - }, draggableItemTypes: DraggableItemTypes, components: { BoardAddNewColumn, @@ -29,17 +22,7 @@ export default { EpicsSwimlanes: () => import('ee_component/boards/components/epics_swimlanes.vue'), GlAlert, }, - inject: [ - 'canAdminList', - 'boardType', - 'fullPath', - 'issuableType', - 'isIssueBoard', - 'isEpicBoard', - 'isGroupBoard', - 'disabled', - 'isApolloBoard', - ], + inject: ['canAdminList', 'isIssueBoard', 'isEpicBoard', 'disabled', 'isApolloBoard'], props: { boardId: { type: String, @@ -53,56 +36,27 @@ export default { type: Boolean, required: true, }, + boardListsApollo: { + type: Object, + required: false, + default: () => {}, + }, + apolloError: { + type: String, + required: false, + default: null, + }, }, data() { return { boardHeight: null, - boardListsApollo: {}, - apolloError: null, - updatedBoardId: this.boardId, }; }, - apollo: { - boardListsApollo: { - query() { - return listsQuery[this.issuableType].query; - }, - variables() { - return this.queryVariables; - }, - skip() { - return !this.isApolloBoard; - }, - update(data) { - const { lists } = data[this.boardType].board; - return formatBoardLists(lists); - }, - result() { - // this allows us to delay fetching lists when we switch a board to fetch the actual board lists - // instead of fetching lists for the "previous" board - this.updatedBoardId = this.boardId; - }, - error() { - this.apolloError = this.$options.i18n.fetchError; - }, - }, - }, computed: { ...mapState(['boardLists', 'error', 'addColumnForm']), addColumnFormVisible() { return this.addColumnForm?.visible; }, - queryVariables() { - return { - ...(this.isIssueBoard && { - isGroup: this.isGroupBoard, - isProject: !this.isGroupBoard, - }), - fullPath: this.fullPath, - boardId: this.boardId, - filters: this.filterParams, - }; - }, boardListsToUse() { const lists = this.isApolloBoard ? this.boardListsApollo : this.boardLists; return sortBy([...Object.values(lists)], 'position'); diff --git a/app/assets/javascripts/boards/components/board_settings_sidebar.vue b/app/assets/javascripts/boards/components/board_settings_sidebar.vue index edf3bfd865c..23e0f2510a7 100644 --- a/app/assets/javascripts/boards/components/board_settings_sidebar.vue +++ b/app/assets/javascripts/boards/components/board_settings_sidebar.vue @@ -1,8 +1,15 @@ <script> -import { GlButton, GlDrawer, GlLabel, GlLoadingIcon, GlModal, GlModalDirective } from '@gitlab/ui'; +import produce from 'immer'; +import { GlButton, GlDrawer, GlLabel, GlModal, GlModalDirective } from '@gitlab/ui'; import { MountingPortal } from 'portal-vue'; import { mapActions, mapState, mapGetters } from 'vuex'; -import { LIST, ListType, ListTypeTitles, listsQuery } from 'ee_else_ce/boards/constants'; +import { + LIST, + ListType, + ListTypeTitles, + listsQuery, + deleteListQueries, +} from 'ee_else_ce/boards/constants'; import { isScopedLabel } from '~/lib/utils/common_utils'; import { __ } from '~/locale'; import eventHub from '~/sidebar/event_hub'; @@ -21,7 +28,6 @@ export default { GlModal, GlDrawer, GlLabel, - GlLoadingIcon, MountingPortal, BoardSettingsSidebarWipLimit: () => import('ee_component/boards/components/board_settings_wip_limit.vue'), @@ -35,11 +41,9 @@ export default { inject: [ 'boardType', 'canAdminList', - 'fullPath', 'issuableType', 'scopedLabelsAvailable', 'isIssueBoard', - 'isGroupBoard', 'isApolloBoard', ], inheritAttrs: false, @@ -52,57 +56,33 @@ export default { type: String, required: true, }, + list: { + type: Object, + required: false, + default: () => null, + }, + queryVariables: { + type: Object, + required: true, + }, }, data() { return { ListType, - list: {}, }; }, modalId: 'board-settings-sidebar-modal', - apollo: { - list: { - query() { - return listsQuery[this.issuableType].query; - }, - variables() { - return this.queryVariables; - }, - update(data) { - const { lists } = data[this.boardType].board; - return lists.nodes[0]; - }, - skip() { - return !this.isApolloBoard || !this.listId; - }, - error() { - this.error = this.$options.i18n.fetchError; - }, - }, - }, computed: { ...mapGetters(['isSidebarOpen']), ...mapState(['activeId', 'sidebarType', 'boardLists']), isWipLimitsOn() { return this.glFeatures.wipLimits && this.isIssueBoard; }, - queryVariables() { - return { - ...(this.isIssueBoard && { - isGroup: this.isGroupBoard, - isProject: !this.isGroupBoard, - }), - fullPath: this.fullPath, - boardId: this.boardId, - filters: this.filterParams, - listId: this.activeListId, - }; - }, activeListId() { return this.isApolloBoard ? this.listId : this.activeId; }, activeList() { - return this.isApolloBoard ? this.list : this.boardLists[this.activeId] || {}; + return (this.isApolloBoard ? this.list : this.boardLists[this.activeId]) || {}; }, activeListLabel() { return this.activeList.label; @@ -119,9 +99,6 @@ export default { } return this.sidebarType === LIST && this.isSidebarOpen; }, - isLoading() { - return this.isApolloBoard && this.$apollo.queries.list.loading; - }, }, created() { eventHub.$on('sidebar.closeAll', this.unsetActiveListId); @@ -132,14 +109,18 @@ export default { methods: { ...mapActions(['unsetActiveId', 'removeList']), handleModalPrimary() { - this.deleteBoard(); + this.deleteBoardList(); }, showScopedLabels(label) { return this.scopedLabelsAvailable && isScopedLabel(label); }, - deleteBoard() { + async deleteBoardList() { this.track('click_button', { label: 'remove_list' }); - this.removeList(this.activeId); + if (this.isApolloBoard) { + await this.deleteList(this.activeListId); + } else { + this.removeList(this.activeId); + } this.unsetActiveListId(); }, unsetActiveListId() { @@ -149,6 +130,25 @@ export default { this.unsetActiveId(); } }, + async deleteList(listId) { + await this.$apollo.mutate({ + mutation: deleteListQueries[this.issuableType].mutation, + variables: { + listId, + }, + update: (store) => { + store.updateQuery( + { query: listsQuery[this.issuableType].query, variables: this.queryVariables }, + (sourceData) => + produce(sourceData, (draftData) => { + draftData[this.boardType].board.lists.nodes = draftData[ + this.boardType + ].board.lists.nodes.filter((list) => list.id !== listId); + }), + ); + }, + }); + }, }, }; </script> @@ -166,9 +166,8 @@ export default { <h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24"> {{ $options.listSettingsText }} </h2> - <gl-loading-icon v-if="isLoading" /> </template> - <template v-if="!isLoading" #header> + <template #header> <div v-if="canAdminList && activeList.id" class="gl-mt-3"> <gl-button v-gl-modal="$options.modalId" @@ -179,7 +178,7 @@ export default { </gl-button> </div> </template> - <template v-if="showSidebar && !isLoading"> + <template v-if="showSidebar"> <div v-if="boardListType === ListType.label"> <label class="js-list-label gl-display-block">{{ listTypeTitle }}</label> <gl-label diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue index 4aec286a5f4..fddb58c45fe 100644 --- a/app/assets/javascripts/boards/components/boards_selector.vue +++ b/app/assets/javascripts/boards/components/boards_selector.vue @@ -144,6 +144,9 @@ export default { }, methods: { ...mapActions(['setError', 'fetchBoard', 'unsetActiveId']), + fullBoardId(boardId) { + return fullBoardId(boardId); + }, showPage(page) { this.currentPage = page; }, @@ -254,7 +257,8 @@ export default { if (isMetaKey(e)) { window.open(`${this.boardBaseUrl}/${boardId}`, '_blank'); } else if (this.isApolloBoard) { - this.$emit('switchBoard', fullBoardId(boardId)); + // Epic board ID is supported in EE version of this file + this.$emit('switchBoard', this.fullBoardId(boardId)); updateHistory({ url: `${this.boardBaseUrl}/${boardId}` }); } else { this.unsetActiveId(); diff --git a/app/assets/javascripts/branches/components/delete_merged_branches.vue b/app/assets/javascripts/branches/components/delete_merged_branches.vue index 70974f2e725..73d7a59e67e 100644 --- a/app/assets/javascripts/branches/components/delete_merged_branches.vue +++ b/app/assets/javascripts/branches/components/delete_merged_branches.vue @@ -1,11 +1,10 @@ <script> -import { GlButton, GlFormInput, GlModal, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; +import { GlDisclosureDropdown, GlButton, GlFormInput, GlModal, GlSprintf } from '@gitlab/ui'; import csrf from '~/lib/utils/csrf'; import { sprintf, s__, __ } from '~/locale'; export const i18n = { deleteButtonText: s__('Branches|Delete merged branches'), - buttonTooltipText: s__("Branches|Delete all branches that are merged into '%{defaultBranch}'"), modalTitle: s__('Branches|Delete all merged branches?'), modalMessage: s__( 'Branches|You are about to %{strongStart}delete all branches%{strongEnd} that were merged into %{codeStart}%{defaultBranch}%{codeEnd}.', @@ -28,14 +27,12 @@ export const i18n = { export default { csrf, components: { - GlModal, + GlDisclosureDropdown, GlButton, + GlModal, GlFormInput, GlSprintf, }, - directives: { - GlTooltip: GlTooltipDirective, - }, props: { formPath: { type: String, @@ -53,9 +50,6 @@ export default { }; }, computed: { - buttonTooltipText() { - return sprintf(this.$options.i18n.buttonTooltipText, { defaultBranch: this.defaultBranch }); - }, modalMessage() { return sprintf(this.$options.i18n.modalMessage, { defaultBranch: this.defaultBranch, @@ -67,6 +61,20 @@ export default { isDeleteButtonDisabled() { return !this.isDeletingConfirmed; }, + dropdownItems() { + return [ + { + text: this.$options.i18n.deleteButtonText, + action: () => { + this.openModal(); + }, + extraAttrs: { + 'data-qa-selector': 'delete_merged_branches_button', + class: 'gl-text-red-500!', + }, + }, + ]; + }, }, methods: { openModal() { @@ -87,15 +95,15 @@ export default { <template> <div> - <gl-button - v-gl-tooltip="buttonTooltipText" - class="gl-mr-3" - data-qa-selector="delete_merged_branches_button" - category="secondary" - variant="danger" - @click="openModal" - >{{ $options.i18n.deleteButtonText }} - </gl-button> + <gl-disclosure-dropdown + :toggle-text="$options.i18n.actionsToggleText" + text-sr-only + icon="ellipsis_v" + category="tertiary" + no-caret + placement="right" + :items="dropdownItems" + /> <gl-modal ref="modal" size="sm" |