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-07-19 18:09:10 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-19 18:09:10 +0300
commit9c8e8b5ffc6e11d827fa42f2dce5f90c4dc19493 (patch)
treefef494515627439a22a06addc7ff5f57d418778a /app/assets/javascripts/work_items
parent690c904b5e340f14c04f93ff688b647b46f7d1a2 (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_links/index.js2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue9
-rw-r--r--app/assets/javascripts/work_items/components/work_item_links/work_item_links_menu.vue101
-rw-r--r--app/assets/javascripts/work_items/graphql/change_work_item_parent_link.mutation.graphql13
4 files changed, 123 insertions, 2 deletions
diff --git a/app/assets/javascripts/work_items/components/work_item_links/index.js b/app/assets/javascripts/work_items/components/work_item_links/index.js
index 7ac9395c725..176f84f6c1a 100644
--- a/app/assets/javascripts/work_items/components/work_item_links/index.js
+++ b/app/assets/javascripts/work_items/components/work_item_links/index.js
@@ -1,9 +1,11 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
+import { GlToast } from '@gitlab/ui';
import createDefaultClient from '~/lib/graphql';
import WorkItemLinks from './work_item_links.vue';
Vue.use(VueApollo);
+Vue.use(GlToast);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue
index 60b30a82e9d..89f086cfca5 100644
--- a/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue
+++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue
@@ -11,6 +11,7 @@ import {
} from '../../constants';
import getWorkItemLinksQuery from '../../graphql/work_item_links.query.graphql';
import WorkItemLinksForm from './work_item_links_form.vue';
+import WorkItemLinksMenu from './work_item_links_menu.vue';
export default {
components: {
@@ -19,6 +20,7 @@ export default {
GlIcon,
GlLoadingIcon,
WorkItemLinksForm,
+ WorkItemLinksMenu,
},
props: {
workItemId: {
@@ -156,19 +158,22 @@ export default {
<div
v-for="child in children"
:key="child.id"
- class="gl-relative gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-overflow-break-word gl-min-w-0 gl-bg-white gl-mb-3 gl-py-3 gl-px-4 gl-border gl-border-gray-100 gl-rounded-base"
+ class="gl-relative gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-overflow-break-word gl-min-w-0 gl-bg-white gl-mb-3 gl-py-3 gl-px-4 gl-border gl-border-gray-100 gl-rounded-base gl-line-height-32"
data-testid="links-child"
>
<div>
<gl-icon :name="$options.WIDGET_TYPE_TASK_ICON" class="gl-mr-3 gl-text-gray-700" />
<span class="gl-word-break-all">{{ child.title }}</span>
</div>
- <div class="gl-ml-0 gl-sm-ml-auto! gl-mt-3 gl-sm-mt-0">
+ <div
+ class="gl-ml-0 gl-sm-ml-auto! gl-mt-3 gl-sm-mt-0 gl-display-inline-flex gl-align-items-center"
+ >
<gl-badge :variant="badgeVariant(child.state)">
<span class="gl-sm-display-block">{{
$options.WORK_ITEM_STATUS_TEXT[child.state]
}}</span>
</gl-badge>
+ <work-item-links-menu :work-item-id="child.id" :parent-work-item-id="issuableGid" />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_links_menu.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_links_menu.vue
new file mode 100644
index 00000000000..6deb87c5dca
--- /dev/null
+++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_links_menu.vue
@@ -0,0 +1,101 @@
+<script>
+import { GlIcon, GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { produce } from 'immer';
+import { s__ } from '~/locale';
+import changeWorkItemParentMutation from '../../graphql/change_work_item_parent_link.mutation.graphql';
+import getWorkItemLinksQuery from '../../graphql/work_item_links.query.graphql';
+import { WIDGET_TYPE_HIERARCHY } from '../../constants';
+
+export default {
+ components: {
+ GlDropdownItem,
+ GlDropdown,
+ GlIcon,
+ },
+ props: {
+ workItemId: {
+ type: String,
+ required: true,
+ },
+ parentWorkItemId: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ activeToast: null,
+ };
+ },
+ methods: {
+ toggleChildFromCache(data, store) {
+ const sourceData = store.readQuery({
+ query: getWorkItemLinksQuery,
+ variables: { id: this.parentWorkItemId },
+ });
+
+ const newData = produce(sourceData, (draftState) => {
+ const widgetHierarchy = draftState.workItem.widgets.find(
+ (widget) => widget.type === WIDGET_TYPE_HIERARCHY,
+ );
+
+ const index = widgetHierarchy.children.nodes.findIndex(
+ (child) => child.id === this.workItemId,
+ );
+
+ if (index >= 0) {
+ widgetHierarchy.children.nodes.splice(index, 1);
+ } else {
+ widgetHierarchy.children.nodes.push(data.workItemUpdate.workItem);
+ }
+ });
+
+ store.writeQuery({
+ query: getWorkItemLinksQuery,
+ variables: { id: this.parentWorkItemId },
+ data: newData,
+ });
+ },
+ async addChild(data) {
+ const { data: resp } = await this.$apollo.mutate({
+ mutation: changeWorkItemParentMutation,
+ variables: { id: this.workItemId, parentId: this.parentWorkItemId },
+ update: this.toggleChildFromCache.bind(this, data),
+ });
+
+ if (resp.workItemUpdate.errors.length === 0) {
+ this.activeToast?.hide();
+ }
+ },
+ async removeChild() {
+ const { data } = await this.$apollo.mutate({
+ mutation: changeWorkItemParentMutation,
+ variables: { id: this.workItemId, parentId: null },
+ update: this.toggleChildFromCache.bind(this, null),
+ });
+
+ if (data.workItemUpdate.errors.length === 0) {
+ this.activeToast = this.$toast.show(s__('WorkItem|Child removed'), {
+ action: {
+ text: s__('WorkItem|Undo'),
+ onClick: this.addChild.bind(this, data),
+ },
+ });
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <span class="gl-ml-2">
+ <gl-dropdown category="tertiary" toggle-class="btn-icon" :right="true">
+ <template #button-content>
+ <gl-icon name="ellipsis_v" :size="14" />
+ </template>
+ <gl-dropdown-item @click="removeChild">
+ {{ s__('WorkItem|Remove') }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+ </span>
+</template>
diff --git a/app/assets/javascripts/work_items/graphql/change_work_item_parent_link.mutation.graphql b/app/assets/javascripts/work_items/graphql/change_work_item_parent_link.mutation.graphql
new file mode 100644
index 00000000000..dc5286174d8
--- /dev/null
+++ b/app/assets/javascripts/work_items/graphql/change_work_item_parent_link.mutation.graphql
@@ -0,0 +1,13 @@
+mutation changeWorkItemParentLink($id: WorkItemID!, $parentId: WorkItemID) {
+ workItemUpdate(input: { id: $id, hierarchyWidget: { parentId: $parentId } }) {
+ workItem {
+ id
+ workItemType {
+ id
+ }
+ title
+ state
+ }
+ errors
+ }
+}