1<script>
2import { GlButton, GlModalDirective } from '@gitlab/ui';
3import { uniqueId } from 'lodash';
4import { __, sprintf } from '~/locale';
5import Tracking from '~/tracking';
6import eventHub from '../event_hub';
7import updateMixin from '../mixins/update';
8import getIssueStateQuery from '../queries/get_issue_state.query.graphql';
9import DeleteIssueModal from './delete_issue_modal.vue';
10
11const issuableTypes = {
12  issue: __('Issue'),
13  epic: __('Epic'),
14  incident: __('Incident'),
15};
16
17const trackingMixin = Tracking.mixin({ label: 'delete_issue' });
18
19export default {
20  components: {
21    DeleteIssueModal,
22    GlButton,
23  },
24  directives: {
25    GlModal: GlModalDirective,
26  },
27  mixins: [trackingMixin, updateMixin],
28  props: {
29    canDestroy: {
30      type: Boolean,
31      required: true,
32    },
33    endpoint: {
34      required: true,
35      type: String,
36    },
37    formState: {
38      type: Object,
39      required: true,
40    },
41    showDeleteButton: {
42      type: Boolean,
43      required: false,
44      default: true,
45    },
46    issuableType: {
47      type: String,
48      required: true,
49    },
50  },
51  data() {
52    return {
53      deleteLoading: false,
54      skipApollo: false,
55      issueState: {},
56      modalId: uniqueId('delete-issuable-modal-'),
57    };
58  },
59  apollo: {
60    issueState: {
61      query: getIssueStateQuery,
62      skip() {
63        return this.skipApollo;
64      },
65      result() {
66        this.skipApollo = true;
67      },
68    },
69  },
70  computed: {
71    deleteIssuableButtonText() {
72      return sprintf(__('Delete %{issuableType}'), {
73        issuableType: this.typeToShow.toLowerCase(),
74      });
75    },
76    isSubmitEnabled() {
77      return this.formState.title.trim() !== '';
78    },
79    shouldShowDeleteButton() {
80      return this.canDestroy && this.showDeleteButton;
81    },
82    typeToShow() {
83      const { issueState, issuableType } = this;
84      const type = issueState.issueType ?? issuableType;
85      return issuableTypes[type];
86    },
87  },
88  methods: {
89    closeForm() {
90      eventHub.$emit('close.form');
91    },
92    deleteIssuable() {
93      this.deleteLoading = true;
94      eventHub.$emit('delete.issuable');
95    },
96  },
97};
98</script>
99
100<template>
101  <div class="gl-mt-3 gl-mb-3 gl-display-flex gl-justify-content-space-between">
102    <div>
103      <gl-button
104        :loading="formState.updateLoading"
105        :disabled="formState.updateLoading || !isSubmitEnabled"
106        category="primary"
107        variant="confirm"
108        class="qa-save-button gl-mr-3"
109        data-testid="issuable-save-button"
110        type="submit"
111        @click.prevent="updateIssuable"
112      >
113        {{ __('Save changes') }}
114      </gl-button>
115      <gl-button data-testid="issuable-cancel-button" @click="closeForm">
116        {{ __('Cancel') }}
117      </gl-button>
118    </div>
119    <div v-if="shouldShowDeleteButton">
120      <gl-button
121        v-gl-modal="modalId"
122        :loading="deleteLoading"
123        :disabled="deleteLoading"
124        category="secondary"
125        variant="danger"
126        class="qa-delete-button"
127        data-testid="issuable-delete-button"
128        @click="track('click_button')"
129      >
130        {{ deleteIssuableButtonText }}
131      </gl-button>
132      <delete-issue-modal
133        :issue-path="endpoint"
134        :issue-type="typeToShow"
135        :modal-id="modalId"
136        :title="deleteIssuableButtonText"
137        @delete="deleteIssuable"
138      />
139    </div>
140  </div>
141</template>
142