debian-mirror-gitlab/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
2021-11-18 22:05:49 +05:30

191 lines
6.1 KiB
Vue

<script>
import $ from 'jquery';
import { camelCase, difference, union } from 'lodash';
import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
import createFlash from '~/flash';
import { getIdFromGraphQLId, MutationOperationMode } from '~/graphql_shared/utils';
import { IssuableType } from '~/issue_show/constants';
import { __ } from '~/locale';
import updateMergeRequestLabelsMutation from '~/sidebar/queries/update_merge_request_labels.mutation.graphql';
import { toLabelGid } from '~/sidebar/utils';
import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_vue/constants';
import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue';
import LabelsSelectWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
const mutationMap = {
[IssuableType.Issue]: {
mutation: updateIssueLabelsMutation,
mutationName: 'updateIssue',
},
[IssuableType.MergeRequest]: {
mutation: updateMergeRequestLabelsMutation,
mutationName: 'mergeRequestSetLabels',
},
};
export default {
components: {
LabelsSelect,
LabelsSelectWidget,
},
variant: DropdownVariant.Sidebar,
mixins: [glFeatureFlagMixin()],
inject: [
'allowLabelCreate',
'allowLabelEdit',
'allowScopedLabels',
'iid',
'fullPath',
'initiallySelectedLabels',
'issuableType',
'labelsFetchPath',
'labelsManagePath',
'projectIssuesPath',
'projectPath',
],
data() {
return {
isLabelsSelectInProgress: false,
selectedLabels: this.initiallySelectedLabels,
};
},
methods: {
handleDropdownClose() {
$(this.$el).trigger('hidden.gl.dropdown');
},
getUpdateVariables(labels) {
let labelIds = [];
if (this.glFeatures.labelsWidget) {
labelIds = labels.map(({ id }) => toLabelGid(id));
} else {
const currentLabelIds = this.selectedLabels.map((label) => label.id);
const userAddedLabelIds = labels.filter((label) => label.set).map((label) => label.id);
const userRemovedLabelIds = labels.filter((label) => !label.set).map((label) => label.id);
labelIds = difference(union(currentLabelIds, userAddedLabelIds), userRemovedLabelIds).map(
toLabelGid,
);
}
switch (this.issuableType) {
case IssuableType.Issue:
return {
iid: this.iid,
projectPath: this.projectPath,
labelIds,
};
case IssuableType.MergeRequest:
return {
iid: this.iid,
labelIds,
operationMode: MutationOperationMode.Replace,
projectPath: this.projectPath,
};
default:
return {};
}
},
handleUpdateSelectedLabels(dropdownLabels) {
this.updateSelectedLabels(this.getUpdateVariables(dropdownLabels));
},
getRemoveVariables(labelId) {
switch (this.issuableType) {
case IssuableType.Issue:
return {
iid: this.iid,
projectPath: this.projectPath,
removeLabelIds: [labelId],
};
case IssuableType.MergeRequest:
return {
iid: this.iid,
labelIds: [toLabelGid(labelId)],
operationMode: MutationOperationMode.Remove,
projectPath: this.projectPath,
};
default:
return {};
}
},
handleLabelRemove(labelId) {
this.updateSelectedLabels(this.getRemoveVariables(labelId));
},
updateSelectedLabels(inputVariables) {
this.isLabelsSelectInProgress = true;
this.$apollo
.mutate({
mutation: mutationMap[this.issuableType].mutation,
variables: { input: inputVariables },
})
.then(({ data }) => {
const { mutationName } = mutationMap[this.issuableType];
if (data[mutationName]?.errors?.length) {
throw new Error();
}
const issuableType = camelCase(this.issuableType);
this.selectedLabels = data[mutationName]?.[issuableType]?.labels?.nodes?.map((label) => ({
...label,
id: getIdFromGraphQLId(label.id),
}));
})
.catch(() => createFlash({ message: __('An error occurred while updating labels.') }))
.finally(() => {
this.isLabelsSelectInProgress = false;
});
},
},
};
</script>
<template>
<labels-select-widget
v-if="glFeatures.labelsWidget"
class="block labels js-labels-block"
:iid="iid"
:full-path="fullPath"
:allow-label-remove="allowLabelEdit"
:allow-multiselect="true"
:footer-create-label-title="__('Create project label')"
:footer-manage-label-title="__('Manage project labels')"
:labels-create-title="__('Create project label')"
:labels-filter-base-path="projectIssuesPath"
:labels-select-in-progress="isLabelsSelectInProgress"
:selected-labels="selectedLabels"
:variant="$options.variant"
:issuable-type="issuableType"
data-qa-selector="labels_block"
@onLabelRemove="handleLabelRemove"
@updateSelectedLabels="handleUpdateSelectedLabels"
>
{{ __('None') }}
</labels-select-widget>
<labels-select
v-else
class="block labels js-labels-block"
:allow-label-remove="allowLabelEdit"
:allow-label-create="allowLabelCreate"
:allow-label-edit="allowLabelEdit"
:allow-multiselect="true"
:allow-scoped-labels="allowScopedLabels"
:footer-create-label-title="__('Create project label')"
:footer-manage-label-title="__('Manage project labels')"
:labels-create-title="__('Create project label')"
:labels-fetch-path="labelsFetchPath"
:labels-filter-base-path="projectIssuesPath"
:labels-manage-path="labelsManagePath"
:labels-select-in-progress="isLabelsSelectInProgress"
:selected-labels="selectedLabels"
:variant="$options.sidebar"
data-qa-selector="labels_block"
@onDropdownClose="handleDropdownClose"
@onLabelRemove="handleLabelRemove"
@updateSelectedLabels="handleUpdateSelectedLabels"
>
{{ __('None') }}
</labels-select>
</template>