diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-23 18:09:54 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-23 18:09:54 +0300 |
commit | 9dbca64417abbec779a219b9e0df9d289d945032 (patch) | |
tree | 3721592153aa2c991a4a5fe686eb4471dabd98b4 /app | |
parent | 5c9f6c66fabf22927e862b2b60362e4ea25b250b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
12 files changed, 113 insertions, 121 deletions
diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js index 04ca65b4a8b..55dc155df0c 100644 --- a/app/assets/javascripts/boards/boards_util.js +++ b/app/assets/javascripts/boards/boards_util.js @@ -1,5 +1,4 @@ import { sortBy } from 'lodash'; -import axios from '~/lib/utils/axios_utils'; import { ListType } from './constants'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; @@ -121,15 +120,6 @@ export function moveIssueListHelper(issue, fromList, toList) { return updatedIssue; } -export function getBoardsPath(endpoint, board) { - const path = `${endpoint}${board.id ? `/${board.id}` : ''}.json`; - - if (board.id) { - return axios.put(path, { board }); - } - return axios.post(path, { board }); -} - export function isListDraggable(list) { return list.listType !== ListType.backlog && list.listType !== ListType.closed; } @@ -146,6 +136,5 @@ export default { fullBoardId, fullLabelId, fullIterationId, - getBoardsPath, isListDraggable, }; diff --git a/app/assets/javascripts/boards/components/board_configuration_options.vue b/app/assets/javascripts/boards/components/board_configuration_options.vue index 99d1e4a2611..b8ee930a8c9 100644 --- a/app/assets/javascripts/boards/components/board_configuration_options.vue +++ b/app/assets/javascripts/boards/components/board_configuration_options.vue @@ -6,36 +6,13 @@ export default { GlFormCheckbox, }, props: { - currentBoard: { - type: Object, - required: true, - }, - board: { - type: Object, + hideBacklogList: { + type: Boolean, required: true, }, - isNewForm: { + hideClosedList: { type: Boolean, - required: false, - default: false, - }, - }, - data() { - const { hide_backlog_list: hideBacklogList, hide_closed_list: hideClosedList } = this.isNewForm - ? this.board - : this.currentBoard; - - return { - hideClosedList, - hideBacklogList, - }; - }, - methods: { - changeClosedList(checked) { - this.board.hideClosedList = !checked; - }, - changeBacklogList(checked) { - this.board.hideBacklogList = !checked; + required: true, }, }, }; @@ -52,13 +29,13 @@ export default { <gl-form-checkbox :checked="!hideBacklogList" data-testid="backlog-list-checkbox" - @change="changeBacklogList" + @change="$emit('update:hideBacklogList', !hideBacklogList)" >{{ __('Show the Open list') }} </gl-form-checkbox> <gl-form-checkbox :checked="!hideClosedList" data-testid="closed-list-checkbox" - @change="changeClosedList" + @change="$emit('update:hideClosedList', !hideClosedList)" >{{ __('Show the Closed list') }} </gl-form-checkbox> </div> diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue index 7507874e951..78e94638cac 100644 --- a/app/assets/javascripts/boards/components/board_form.vue +++ b/app/assets/javascripts/boards/components/board_form.vue @@ -1,14 +1,15 @@ <script> import { GlModal } from '@gitlab/ui'; -import { pick } from 'lodash'; import { __, s__ } from '~/locale'; import { deprecatedCreateFlash as Flash } from '~/flash'; -import { visitUrl } from '~/lib/utils/url_utility'; +import { visitUrl, stripFinalUrlSegment } from '~/lib/utils/url_utility'; +import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils'; import boardsStore from '~/boards/stores/boards_store'; -import { fullBoardId, getBoardsPath } from '../boards_util'; +import { fullLabelId, fullBoardId } from '../boards_util'; import BoardConfigurationOptions from './board_configuration_options.vue'; -import createBoardMutation from '../graphql/board.mutation.graphql'; +import updateBoardMutation from '../graphql/board_update.mutation.graphql'; +import createBoardMutation from '../graphql/board_create.mutation.graphql'; const boardDefaults = { id: false, @@ -91,8 +92,8 @@ export default { }, }, inject: { - endpoints: { - default: {}, + fullPath: { + default: '', }, }, data() { @@ -155,14 +156,38 @@ export default { text: this.$options.i18n.cancelButtonText, }; }, - boardPayload() { - const { assignee, milestone, labels } = this.board; - return { - ...this.board, - assignee_id: assignee?.id, - milestone_id: milestone?.id, - label_ids: labels.length ? labels.map(b => b.id) : [''], + currentMutation() { + return this.board.id ? updateBoardMutation : createBoardMutation; + }, + mutationVariables() { + const { board } = this; + /* eslint-disable @gitlab/require-i18n-strings */ + const baseMutationVariables = { + name: board.name, + weight: board.weight, + assigneeId: board.assignee?.id ? convertToGraphQLId('User', board.assignee.id) : null, + milestoneId: + board.milestone?.id || board.milestone?.id === 0 + ? convertToGraphQLId('Milestone', board.milestone.id) + : null, + labelIds: board.labels.map(fullLabelId), + hideBacklogList: board.hide_backlog_list, + hideClosedList: board.hide_closed_list, + iterationId: board.iteration_id + ? convertToGraphQLId('Iteration', board.iteration_id) + : null, }; + /* eslint-enable @gitlab/require-i18n-strings */ + return board.id + ? { + ...baseMutationVariables, + id: fullBoardId(board.id), + } + : { + ...baseMutationVariables, + projectPath: this.projectId ? this.fullPath : null, + groupPath: this.groupId ? this.fullPath : null, + }; }, }, mounted() { @@ -175,55 +200,39 @@ export default { setIteration(iterationId) { this.board.iteration_id = iterationId; }, - callBoardMutation(id) { - return this.$apollo.mutate({ - mutation: createBoardMutation, - variables: { - ...pick(this.boardPayload, ['hideClosedList', 'hideBacklogList']), - id, - }, + async createOrUpdateBoard() { + const response = await this.$apollo.mutate({ + mutation: this.currentMutation, + variables: { input: this.mutationVariables }, }); - }, - async updateBoard() { - const responses = await Promise.all([ - // Remove unnecessary REST API call when https://gitlab.com/gitlab-org/gitlab/-/issues/282299#note_462996301 is resolved - getBoardsPath(this.endpoints.boardsEndpoint, this.boardPayload), - this.callBoardMutation(fullBoardId(this.boardPayload.id)), - ]); - return responses[0].data; + return this.board.id + ? getIdFromGraphQLId(response.data.updateBoard.board.id) + : getIdFromGraphQLId(response.data.createBoard.board.id); }, - async createBoard() { - // TODO: change this to use `createBoard` mutation https://gitlab.com/gitlab-org/gitlab/-/issues/292466 is resolved - const boardData = await getBoardsPath(this.endpoints.boardsEndpoint, this.boardPayload); - this.callBoardMutation(fullBoardId(boardData.data.id)); - - return boardData.data || boardData; - }, - submit() { + async submit() { if (this.board.name.length === 0) return; this.isLoading = true; if (this.isDeleteForm) { - boardsStore - .deleteBoard(this.currentBoard) - .then(() => { - this.isLoading = false; - visitUrl(boardsStore.rootPath); - }) - .catch(() => { - Flash(this.$options.i18n.deleteErrorMessage); - this.isLoading = false; - }); + try { + await boardsStore.deleteBoard(this.currentBoard); + visitUrl(boardsStore.rootPath); + } catch { + Flash(this.$options.i18n.deleteErrorMessage); + } finally { + this.isLoading = false; + } } else { - const boardAction = this.boardPayload.id ? this.updateBoard : this.createBoard; - boardAction() - .then(data => { - visitUrl(data.board_path); - }) - .catch(() => { - Flash(this.$options.i18n.saveErrorMessage); - this.isLoading = false; - }); + try { + const path = await this.createOrUpdateBoard(); + const strippedUrl = stripFinalUrlSegment(window.location.href); + const url = strippedUrl.includes('boards') ? `${path}` : `boards/${path}`; + visitUrl(url); + } catch { + Flash(this.$options.i18n.saveErrorMessage); + } finally { + this.isLoading = false; + } } }, cancel() { @@ -277,9 +286,8 @@ export default { </div> <board-configuration-options - :is-new-form="isNewForm" - :board="board" - :current-board="currentBoard" + :hide-backlog-list.sync="board.hide_backlog_list" + :hide-closed-list.sync="board.hide_closed_list" /> <board-scope diff --git a/app/assets/javascripts/boards/graphql/board.mutation.graphql b/app/assets/javascripts/boards/graphql/board.mutation.graphql deleted file mode 100644 index fc3bb2285ee..00000000000 --- a/app/assets/javascripts/boards/graphql/board.mutation.graphql +++ /dev/null @@ -1,11 +0,0 @@ -mutation UpdateBoard($id: BoardID!, $hideClosedList: Boolean, $hideBacklogList: Boolean) { - updateBoard( - input: { id: $id, hideClosedList: $hideClosedList, hideBacklogList: $hideBacklogList } - ) { - board { - id - hideClosedList - hideBacklogList - } - } -} diff --git a/app/assets/javascripts/boards/graphql/board_create.mutation.graphql b/app/assets/javascripts/boards/graphql/board_create.mutation.graphql new file mode 100644 index 00000000000..e26d67dcc0e --- /dev/null +++ b/app/assets/javascripts/boards/graphql/board_create.mutation.graphql @@ -0,0 +1,7 @@ +mutation createBoard($input: CreateBoardInput!) { + createBoard(input: $input) { + board { + id + } + } +} diff --git a/app/assets/javascripts/boards/graphql/board_update.mutation.graphql b/app/assets/javascripts/boards/graphql/board_update.mutation.graphql new file mode 100644 index 00000000000..6b4ea2bef1a --- /dev/null +++ b/app/assets/javascripts/boards/graphql/board_update.mutation.graphql @@ -0,0 +1,9 @@ +mutation UpdateBoard($input: UpdateBoardInput!) { + updateBoard(input: $input) { + board { + id + hideClosedList + hideBacklogList + } + } +} diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 37248f0400b..fac26c54519 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -335,7 +335,6 @@ export default () => { } mountMultipleBoardsSwitcher({ - boardsEndpoint: $boardApp.dataset.boardsEndpoint, - recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint, + fullPath: $boardApp.dataset.fullPath, }); }; diff --git a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js index df65ebb7526..71463010898 100644 --- a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js +++ b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js @@ -10,7 +10,7 @@ const apolloProvider = new VueApollo({ defaultClient: createDefaultClient(), }); -export default (endpoints = {}) => { +export default (params = {}) => { const boardsSwitcherElement = document.getElementById('js-multiple-boards-switcher'); return new Vue({ el: boardsSwitcherElement, @@ -36,7 +36,7 @@ export default (endpoints = {}) => { return { boardsSelectorProps }; }, provide: { - endpoints, + fullPath: params.fullPath, }, render(createElement) { return createElement(BoardsSelector, { diff --git a/app/assets/javascripts/tooltips/components/tooltips.vue b/app/assets/javascripts/tooltips/components/tooltips.vue index 05927006ea6..15fc84368b2 100644 --- a/app/assets/javascripts/tooltips/components/tooltips.vue +++ b/app/assets/javascripts/tooltips/components/tooltips.vue @@ -50,7 +50,8 @@ export default { addTooltips(elements, config) { const newTooltips = elements .filter(element => !this.tooltipExists(element)) - .map(element => newTooltip(element, config)); + .map(element => newTooltip(element, config)) + .filter(tooltip => tooltip.title); newTooltips.forEach(tooltip => this.observe(tooltip)); @@ -93,6 +94,9 @@ export default { return this.tooltips.find(tooltip => tooltip.target === element); }, }, + safeHtmlConfig: { + ADD_TAGS: ['gl-emoji'], + }, }; </script> <template> @@ -110,7 +114,7 @@ export default { :disabled="tooltip.disabled" :show="tooltip.show" > - <span v-if="tooltip.html" v-safe-html="tooltip.title"></span> + <span v-if="tooltip.html" v-safe-html:[$options.safeHtmlConfig]="tooltip.title"></span> <span v-else>{{ tooltip.title }}</span> </gl-tooltip> </div> diff --git a/app/assets/javascripts/tooltips/index.js b/app/assets/javascripts/tooltips/index.js index f7cad6639ae..335925aec5f 100644 --- a/app/assets/javascripts/tooltips/index.js +++ b/app/assets/javascripts/tooltips/index.js @@ -68,7 +68,7 @@ const invokeBootstrapApi = (elements, method) => { } }; -const isGlTooltipsEnabled = () => Boolean(window.gon.glTooltipsEnabled); +const isGlTooltipsEnabled = () => Boolean(window.gon.features?.glTooltips); const tooltipApiInvoker = ({ glHandler, bsHandler }) => (elements, ...params) => { if (isGlTooltipsEnabled()) { diff --git a/app/views/shared/wikis/_sidebar.html.haml b/app/views/shared/wikis/_sidebar.html.haml index a906bf7aa63..4e9fdc8b95a 100644 --- a/app/views/shared/wikis/_sidebar.html.haml +++ b/app/views/shared/wikis/_sidebar.html.haml @@ -1,13 +1,23 @@ +- editing ||= false + %aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } } .sidebar-container .block.wiki-sidebar-header.gl-mb-3.w-100 %a.gutter-toggle.float-right.d-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" } = sprite_icon('chevron-double-lg-right', css_class: 'gl-icon') - - git_access_url = wiki_path(@wiki, action: :git_access) - = link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '', data: { qa_selector: 'clone_repository_link' } do - = sprite_icon('download', css_class: 'gl-mr-2') - %span= _("Clone repository") + .gl-display-flex.gl-flex-wrap + - git_access_url = wiki_path(@wiki, action: :git_access) + = link_to git_access_url, class: 'gl-mr-5' + (active_nav_link?(path: 'wikis#git_access') ? ' active' : ''), data: { qa_selector: 'clone_repository_link' } do + = sprite_icon('download', css_class: 'gl-mr-2') + %span= _("Clone repository") + + - if can?(current_user, :create_wiki, @wiki) + - edit_sidebar_url = wiki_page_path(@wiki, Wiki::SIDEBAR, action: :edit) + - link_class = (editing && @page&.slug == Wiki::SIDEBAR) ? 'active' : '' + = link_to edit_sidebar_url, class: link_class, data: { qa_selector: 'edit_sidebar_link' } do + = sprite_icon('pencil-square', css_class: 'gl-mr-2') + %span= _("Edit sidebar") - if @sidebar_error.present? = render 'shared/alert_info', body: s_('Wiki|The sidebar failed to load. You can reload the page to try again.') diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml index 834749caaba..b289c018015 100644 --- a/app/views/shared/wikis/edit.html.haml +++ b/app/views/shared/wikis/edit.html.haml @@ -23,4 +23,4 @@ = render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url -= render 'shared/wikis/sidebar' += render 'shared/wikis/sidebar', editing: true |