Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-08 06:09:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-08 06:09:21 +0300
commita6db6a23d11a981c6d1fd6b875be863a6c36d934 (patch)
tree148a9ad5fdf04b511fabe74c7e1ffc41fe92659b /app/assets/javascripts/work_items
parent00871a937dabdf0a100e465c2820e69b82556898 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/work_items')
-rw-r--r--app/assets/javascripts/work_items/components/work_item_assignees.vue81
-rw-r--r--app/assets/javascripts/work_items/graphql/provider.js14
2 files changed, 66 insertions, 29 deletions
diff --git a/app/assets/javascripts/work_items/components/work_item_assignees.vue b/app/assets/javascripts/work_items/components/work_item_assignees.vue
index 9ff424aa20f..f1b12e6478f 100644
--- a/app/assets/javascripts/work_items/components/work_item_assignees.vue
+++ b/app/assets/javascripts/work_items/components/work_item_assignees.vue
@@ -18,11 +18,17 @@ import { n__, s__ } from '~/locale';
import Tracking from '~/tracking';
import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
-import localUpdateWorkItemMutation from '../graphql/local_update_work_item.mutation.graphql';
+import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
import { i18n, TRACKING_CATEGORY_SHOW } from '../constants';
function isTokenSelectorElement(el) {
- return el?.classList.contains('gl-token-close') || el?.classList.contains('dropdown-item');
+ return (
+ el?.classList.contains('gl-token-close') ||
+ el?.classList.contains('dropdown-item') ||
+ // TODO: replace this logic when we have a class added to clear-all button in GitLab UI
+ (el?.classList.contains('gl-button') &&
+ el?.closest('.form-control')?.classList.contains('gl-token-selector'))
+ );
}
function addClass(el) {
@@ -130,7 +136,7 @@ export default {
if (this.searchUsers.some((user) => user.username === this.currentUser.username)) {
return this.moveCurrentUserToStart(this.searchUsers);
}
- return [this.currentUser, ...this.searchUsers];
+ return [addClass(this.currentUser), ...this.searchUsers];
}
return this.searchUsers;
},
@@ -142,12 +148,18 @@ export default {
? s__('WorkItem|Add assignees')
: s__('WorkItem|Add assignee');
},
+ assigneeIds() {
+ return this.localAssignees.map(({ id }) => id);
+ },
},
watch: {
- assignees(newVal) {
- if (!this.isEditing) {
- this.localAssignees = newVal.map(addClass);
- }
+ assignees: {
+ handler(newVal) {
+ if (!this.isEditing) {
+ this.localAssignees = newVal.map(addClass);
+ }
+ },
+ deep: true,
},
},
created() {
@@ -169,19 +181,33 @@ export default {
handleBlur(e) {
if (isTokenSelectorElement(e.relatedTarget) || !this.isEditing) return;
this.isEditing = false;
- this.setAssignees(this.localAssignees);
+ this.setAssignees(this.assigneeIds);
},
- setAssignees(assignees) {
- this.$apollo.mutate({
- mutation: localUpdateWorkItemMutation,
- variables: {
- input: {
- id: this.workItemId,
- assignees,
+ async setAssignees(assigneeIds) {
+ try {
+ const {
+ data: {
+ workItemUpdate: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: updateWorkItemMutation,
+ variables: {
+ input: {
+ id: this.workItemId,
+ assigneesWidget: {
+ assigneeIds,
+ },
+ },
},
- },
- });
- this.track('updated_assignees');
+ });
+ if (errors.length > 0) {
+ this.throwUpdateError();
+ return;
+ }
+ this.track('updated_assignees');
+ } catch {
+ this.throwUpdateError();
+ }
},
handleFocus() {
this.isEditing = true;
@@ -205,13 +231,25 @@ export default {
},
moveCurrentUserToStart(users = []) {
if (this.currentUser) {
- return [this.currentUser, ...users.filter((user) => user.id !== this.currentUser.id)];
+ return [
+ addClass(this.currentUser),
+ ...users.filter((user) => user.id !== this.currentUser.id),
+ ];
}
return users;
},
closeDropdown() {
this.$refs.tokenSelector.closeDropdown();
},
+ assignToCurrentUser() {
+ this.setAssignees([this.currentUser.id]);
+ this.localAssignees = [addClass(this.currentUser)];
+ },
+ throwUpdateError() {
+ this.$emit('error', i18n.updateError);
+ // If mutation is rejected, we're rolling back to initial state
+ this.localAssignees = this.assignees.map(addClass);
+ },
},
};
</script>
@@ -227,11 +265,12 @@ export default {
ref="tokenSelector"
:selected-tokens="localAssignees"
:container-class="containerClass"
- class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0!"
:class="{ 'gl-hover-border-gray-200': canUpdate }"
:dropdown-items="dropdownItems"
:loading="isLoadingUsers"
:view-only="!canUpdate"
+ :allow-clear-all="isEditing"
+ class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0!"
@input="handleAssigneesInput"
@text-input="debouncedSearchKeyUpdate"
@focus="handleFocus"
@@ -251,7 +290,7 @@ export default {
size="small"
class="assign-myself"
data-testid="assign-self"
- @click.stop="setAssignees([currentUser])"
+ @click.stop="assignToCurrentUser"
>{{ __('Assign myself') }}</gl-button
>
</div>
diff --git a/app/assets/javascripts/work_items/graphql/provider.js b/app/assets/javascripts/work_items/graphql/provider.js
index 1feef8bcaf8..b70c06fddea 100644
--- a/app/assets/javascripts/work_items/graphql/provider.js
+++ b/app/assets/javascripts/work_items/graphql/provider.js
@@ -2,7 +2,7 @@ import produce from 'immer';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import { WIDGET_TYPE_ASSIGNEES, WIDGET_TYPE_LABELS } from '../constants';
+import { WIDGET_TYPE_LABELS } from '../constants';
import typeDefs from './typedefs.graphql';
import workItemQuery from './work_item.query.graphql';
@@ -29,6 +29,11 @@ export const temporaryConfig = {
);
},
},
+ widgets: {
+ merge(_, incoming) {
+ return incoming;
+ },
+ },
},
},
},
@@ -44,13 +49,6 @@ export const resolvers = {
});
const data = produce(sourceData, (draftData) => {
- if (input.assignees) {
- const assigneesWidget = draftData.workItem.widgets.find(
- (widget) => widget.type === WIDGET_TYPE_ASSIGNEES,
- );
- assigneesWidget.assignees.nodes = [...input.assignees];
- }
-
if (input.labels) {
const labelsWidget = draftData.workItem.mockWidgets.find(
(widget) => widget.type === WIDGET_TYPE_LABELS,