Skip to content

Commit 9dbca64

Browse files
author
GitLab Bot
committed
Add latest changes from gitlab-org/gitlab@master
1 parent 5c9f6c6 commit 9dbca64

36 files changed

+3236
-484
lines changed

.prettierignore

+2,470
Large diffs are not rendered by default.

.prettierrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"printWidth": 100,
33
"singleQuote": true,
4-
"arrowParens": "avoid",
4+
"arrowParens": "always",
55
"trailingComma": "all"
66
}

app/assets/javascripts/boards/boards_util.js

-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { sortBy } from 'lodash';
2-
import axios from '~/lib/utils/axios_utils';
32
import { ListType } from './constants';
43
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
54

@@ -121,15 +120,6 @@ export function moveIssueListHelper(issue, fromList, toList) {
121120
return updatedIssue;
122121
}
123122

124-
export function getBoardsPath(endpoint, board) {
125-
const path = `${endpoint}${board.id ? `/${board.id}` : ''}.json`;
126-
127-
if (board.id) {
128-
return axios.put(path, { board });
129-
}
130-
return axios.post(path, { board });
131-
}
132-
133123
export function isListDraggable(list) {
134124
return list.listType !== ListType.backlog && list.listType !== ListType.closed;
135125
}
@@ -146,6 +136,5 @@ export default {
146136
fullBoardId,
147137
fullLabelId,
148138
fullIterationId,
149-
getBoardsPath,
150139
isListDraggable,
151140
};

app/assets/javascripts/boards/components/board_configuration_options.vue

+6-29
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,13 @@ export default {
66
GlFormCheckbox,
77
},
88
props: {
9-
currentBoard: {
10-
type: Object,
11-
required: true,
12-
},
13-
board: {
14-
type: Object,
9+
hideBacklogList: {
10+
type: Boolean,
1511
required: true,
1612
},
17-
isNewForm: {
13+
hideClosedList: {
1814
type: Boolean,
19-
required: false,
20-
default: false,
21-
},
22-
},
23-
data() {
24-
const { hide_backlog_list: hideBacklogList, hide_closed_list: hideClosedList } = this.isNewForm
25-
? this.board
26-
: this.currentBoard;
27-
28-
return {
29-
hideClosedList,
30-
hideBacklogList,
31-
};
32-
},
33-
methods: {
34-
changeClosedList(checked) {
35-
this.board.hideClosedList = !checked;
36-
},
37-
changeBacklogList(checked) {
38-
this.board.hideBacklogList = !checked;
15+
required: true,
3916
},
4017
},
4118
};
@@ -52,13 +29,13 @@ export default {
5229
<gl-form-checkbox
5330
:checked="!hideBacklogList"
5431
data-testid="backlog-list-checkbox"
55-
@change="changeBacklogList"
32+
@change="$emit('update:hideBacklogList', !hideBacklogList)"
5633
>{{ __('Show the Open list') }}
5734
</gl-form-checkbox>
5835
<gl-form-checkbox
5936
:checked="!hideClosedList"
6037
data-testid="closed-list-checkbox"
61-
@change="changeClosedList"
38+
@change="$emit('update:hideClosedList', !hideClosedList)"
6239
>{{ __('Show the Closed list') }}
6340
</gl-form-checkbox>
6441
</div>

app/assets/javascripts/boards/components/board_form.vue

+66-58
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
<script>
22
import { GlModal } from '@gitlab/ui';
3-
import { pick } from 'lodash';
43
import { __, s__ } from '~/locale';
54
import { deprecatedCreateFlash as Flash } from '~/flash';
6-
import { visitUrl } from '~/lib/utils/url_utility';
5+
import { visitUrl, stripFinalUrlSegment } from '~/lib/utils/url_utility';
6+
import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils';
77
import boardsStore from '~/boards/stores/boards_store';
8-
import { fullBoardId, getBoardsPath } from '../boards_util';
8+
import { fullLabelId, fullBoardId } from '../boards_util';
99
1010
import BoardConfigurationOptions from './board_configuration_options.vue';
11-
import createBoardMutation from '../graphql/board.mutation.graphql';
11+
import updateBoardMutation from '../graphql/board_update.mutation.graphql';
12+
import createBoardMutation from '../graphql/board_create.mutation.graphql';
1213
1314
const boardDefaults = {
1415
id: false,
@@ -91,8 +92,8 @@ export default {
9192
},
9293
},
9394
inject: {
94-
endpoints: {
95-
default: {},
95+
fullPath: {
96+
default: '',
9697
},
9798
},
9899
data() {
@@ -155,14 +156,38 @@ export default {
155156
text: this.$options.i18n.cancelButtonText,
156157
};
157158
},
158-
boardPayload() {
159-
const { assignee, milestone, labels } = this.board;
160-
return {
161-
...this.board,
162-
assignee_id: assignee?.id,
163-
milestone_id: milestone?.id,
164-
label_ids: labels.length ? labels.map(b => b.id) : [''],
159+
currentMutation() {
160+
return this.board.id ? updateBoardMutation : createBoardMutation;
161+
},
162+
mutationVariables() {
163+
const { board } = this;
164+
/* eslint-disable @gitlab/require-i18n-strings */
165+
const baseMutationVariables = {
166+
name: board.name,
167+
weight: board.weight,
168+
assigneeId: board.assignee?.id ? convertToGraphQLId('User', board.assignee.id) : null,
169+
milestoneId:
170+
board.milestone?.id || board.milestone?.id === 0
171+
? convertToGraphQLId('Milestone', board.milestone.id)
172+
: null,
173+
labelIds: board.labels.map(fullLabelId),
174+
hideBacklogList: board.hide_backlog_list,
175+
hideClosedList: board.hide_closed_list,
176+
iterationId: board.iteration_id
177+
? convertToGraphQLId('Iteration', board.iteration_id)
178+
: null,
165179
};
180+
/* eslint-enable @gitlab/require-i18n-strings */
181+
return board.id
182+
? {
183+
...baseMutationVariables,
184+
id: fullBoardId(board.id),
185+
}
186+
: {
187+
...baseMutationVariables,
188+
projectPath: this.projectId ? this.fullPath : null,
189+
groupPath: this.groupId ? this.fullPath : null,
190+
};
166191
},
167192
},
168193
mounted() {
@@ -175,55 +200,39 @@ export default {
175200
setIteration(iterationId) {
176201
this.board.iteration_id = iterationId;
177202
},
178-
callBoardMutation(id) {
179-
return this.$apollo.mutate({
180-
mutation: createBoardMutation,
181-
variables: {
182-
...pick(this.boardPayload, ['hideClosedList', 'hideBacklogList']),
183-
id,
184-
},
203+
async createOrUpdateBoard() {
204+
const response = await this.$apollo.mutate({
205+
mutation: this.currentMutation,
206+
variables: { input: this.mutationVariables },
185207
});
186-
},
187-
async updateBoard() {
188-
const responses = await Promise.all([
189-
// Remove unnecessary REST API call when https://gitlab.com/gitlab-org/gitlab/-/issues/282299#note_462996301 is resolved
190-
getBoardsPath(this.endpoints.boardsEndpoint, this.boardPayload),
191-
this.callBoardMutation(fullBoardId(this.boardPayload.id)),
192-
]);
193208
194-
return responses[0].data;
209+
return this.board.id
210+
? getIdFromGraphQLId(response.data.updateBoard.board.id)
211+
: getIdFromGraphQLId(response.data.createBoard.board.id);
195212
},
196-
async createBoard() {
197-
// TODO: change this to use `createBoard` mutation https://gitlab.com/gitlab-org/gitlab/-/issues/292466 is resolved
198-
const boardData = await getBoardsPath(this.endpoints.boardsEndpoint, this.boardPayload);
199-
this.callBoardMutation(fullBoardId(boardData.data.id));
200-
201-
return boardData.data || boardData;
202-
},
203-
submit() {
213+
async submit() {
204214
if (this.board.name.length === 0) return;
205215
this.isLoading = true;
206216
if (this.isDeleteForm) {
207-
boardsStore
208-
.deleteBoard(this.currentBoard)
209-
.then(() => {
210-
this.isLoading = false;
211-
visitUrl(boardsStore.rootPath);
212-
})
213-
.catch(() => {
214-
Flash(this.$options.i18n.deleteErrorMessage);
215-
this.isLoading = false;
216-
});
217+
try {
218+
await boardsStore.deleteBoard(this.currentBoard);
219+
visitUrl(boardsStore.rootPath);
220+
} catch {
221+
Flash(this.$options.i18n.deleteErrorMessage);
222+
} finally {
223+
this.isLoading = false;
224+
}
217225
} else {
218-
const boardAction = this.boardPayload.id ? this.updateBoard : this.createBoard;
219-
boardAction()
220-
.then(data => {
221-
visitUrl(data.board_path);
222-
})
223-
.catch(() => {
224-
Flash(this.$options.i18n.saveErrorMessage);
225-
this.isLoading = false;
226-
});
226+
try {
227+
const path = await this.createOrUpdateBoard();
228+
const strippedUrl = stripFinalUrlSegment(window.location.href);
229+
const url = strippedUrl.includes('boards') ? `${path}` : `boards/${path}`;
230+
visitUrl(url);
231+
} catch {
232+
Flash(this.$options.i18n.saveErrorMessage);
233+
} finally {
234+
this.isLoading = false;
235+
}
227236
}
228237
},
229238
cancel() {
@@ -277,9 +286,8 @@ export default {
277286
</div>
278287

279288
<board-configuration-options
280-
:is-new-form="isNewForm"
281-
:board="board"
282-
:current-board="currentBoard"
289+
:hide-backlog-list.sync="board.hide_backlog_list"
290+
:hide-closed-list.sync="board.hide_closed_list"
283291
/>
284292

285293
<board-scope

app/assets/javascripts/boards/graphql/board.mutation.graphql

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mutation createBoard($input: CreateBoardInput!) {
2+
createBoard(input: $input) {
3+
board {
4+
id
5+
}
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
mutation UpdateBoard($input: UpdateBoardInput!) {
2+
updateBoard(input: $input) {
3+
board {
4+
id
5+
hideClosedList
6+
hideBacklogList
7+
}
8+
}
9+
}

app/assets/javascripts/boards/index.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,6 @@ export default () => {
335335
}
336336

337337
mountMultipleBoardsSwitcher({
338-
boardsEndpoint: $boardApp.dataset.boardsEndpoint,
339-
recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
338+
fullPath: $boardApp.dataset.fullPath,
340339
});
341340
};

app/assets/javascripts/boards/mount_multiple_boards_switcher.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const apolloProvider = new VueApollo({
1010
defaultClient: createDefaultClient(),
1111
});
1212

13-
export default (endpoints = {}) => {
13+
export default (params = {}) => {
1414
const boardsSwitcherElement = document.getElementById('js-multiple-boards-switcher');
1515
return new Vue({
1616
el: boardsSwitcherElement,
@@ -36,7 +36,7 @@ export default (endpoints = {}) => {
3636
return { boardsSelectorProps };
3737
},
3838
provide: {
39-
endpoints,
39+
fullPath: params.fullPath,
4040
},
4141
render(createElement) {
4242
return createElement(BoardsSelector, {

app/assets/javascripts/tooltips/components/tooltips.vue

+6-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export default {
5050
addTooltips(elements, config) {
5151
const newTooltips = elements
5252
.filter(element => !this.tooltipExists(element))
53-
.map(element => newTooltip(element, config));
53+
.map(element => newTooltip(element, config))
54+
.filter(tooltip => tooltip.title);
5455
5556
newTooltips.forEach(tooltip => this.observe(tooltip));
5657
@@ -93,6 +94,9 @@ export default {
9394
return this.tooltips.find(tooltip => tooltip.target === element);
9495
},
9596
},
97+
safeHtmlConfig: {
98+
ADD_TAGS: ['gl-emoji'],
99+
},
96100
};
97101
</script>
98102
<template>
@@ -110,7 +114,7 @@ export default {
110114
:disabled="tooltip.disabled"
111115
:show="tooltip.show"
112116
>
113-
<span v-if="tooltip.html" v-safe-html="tooltip.title"></span>
117+
<span v-if="tooltip.html" v-safe-html:[$options.safeHtmlConfig]="tooltip.title"></span>
114118
<span v-else>{{ tooltip.title }}</span>
115119
</gl-tooltip>
116120
</div>

app/assets/javascripts/tooltips/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const invokeBootstrapApi = (elements, method) => {
6868
}
6969
};
7070

71-
const isGlTooltipsEnabled = () => Boolean(window.gon.glTooltipsEnabled);
71+
const isGlTooltipsEnabled = () => Boolean(window.gon.features?.glTooltips);
7272

7373
const tooltipApiInvoker = ({ glHandler, bsHandler }) => (elements, ...params) => {
7474
if (isGlTooltipsEnabled()) {

app/views/shared/wikis/_sidebar.html.haml

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
- editing ||= false
2+
13
%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
24
.sidebar-container
35
.block.wiki-sidebar-header.gl-mb-3.w-100
46
%a.gutter-toggle.float-right.d-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
57
= sprite_icon('chevron-double-lg-right', css_class: 'gl-icon')
68

7-
- git_access_url = wiki_path(@wiki, action: :git_access)
8-
= link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '', data: { qa_selector: 'clone_repository_link' } do
9-
= sprite_icon('download', css_class: 'gl-mr-2')
10-
%span= _("Clone repository")
9+
.gl-display-flex.gl-flex-wrap
10+
- git_access_url = wiki_path(@wiki, action: :git_access)
11+
= link_to git_access_url, class: 'gl-mr-5' + (active_nav_link?(path: 'wikis#git_access') ? ' active' : ''), data: { qa_selector: 'clone_repository_link' } do
12+
= sprite_icon('download', css_class: 'gl-mr-2')
13+
%span= _("Clone repository")
14+
15+
- if can?(current_user, :create_wiki, @wiki)
16+
- edit_sidebar_url = wiki_page_path(@wiki, Wiki::SIDEBAR, action: :edit)
17+
- link_class = (editing && @page&.slug == Wiki::SIDEBAR) ? 'active' : ''
18+
= link_to edit_sidebar_url, class: link_class, data: { qa_selector: 'edit_sidebar_link' } do
19+
= sprite_icon('pencil-square', css_class: 'gl-mr-2')
20+
%span= _("Edit sidebar")
1121

1222
- if @sidebar_error.present?
1323
= render 'shared/alert_info', body: s_('Wiki|The sidebar failed to load. You can reload the page to try again.')

app/views/shared/wikis/edit.html.haml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323

2424
= render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
2525

26-
= render 'shared/wikis/sidebar'
26+
= render 'shared/wikis/sidebar', editing: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
title: Add snippet repository storage move API endpoints
3+
merge_request: 49228
4+
author:
5+
type: added

0 commit comments

Comments
 (0)