summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
blob: d7be8927c29c75cb02cbe0c17bbad54eab173dd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<script>
import $ from 'jquery';
import { difference, union } from 'lodash';
import { mapState, mapActions } from 'vuex';
import flash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
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';

export default {
  components: {
    LabelsSelect,
  },
  variant: DropdownVariant.Sidebar,
  inject: [
    'allowLabelCreate',
    'allowLabelEdit',
    'allowScopedLabels',
    'iid',
    'initiallySelectedLabels',
    'issuableType',
    'labelsFetchPath',
    'labelsManagePath',
    'labelsUpdatePath',
    'projectIssuesPath',
    'projectPath',
  ],
  data: () => ({
    labelsSelectInProgress: false,
  }),
  computed: {
    ...mapState(['selectedLabels']),
  },
  mounted() {
    this.setInitialState({
      selectedLabels: this.initiallySelectedLabels,
    });
  },
  methods: {
    ...mapActions(['setInitialState', 'replaceSelectedLabels']),
    handleDropdownClose() {
      $(this.$el).trigger('hidden.gl.dropdown');
    },
    handleUpdateSelectedLabels(labels) {
      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);

      const issuableLabels = difference(
        union(currentLabelIds, userAddedLabelIds),
        userRemovedLabelIds,
      );

      this.labelsSelectInProgress = true;

      axios({
        data: {
          [this.issuableType]: {
            label_ids: issuableLabels,
          },
        },
        method: 'put',
        url: this.labelsUpdatePath,
      })
        .then(({ data }) => this.replaceSelectedLabels(data.labels))
        .catch(() => flash(__('An error occurred while updating labels.')))
        .finally(() => {
          this.labelsSelectInProgress = false;
        });
    },
  },
};
</script>

<template>
  <labels-select
    class="block labels js-labels-block"
    :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="labelsSelectInProgress"
    :selected-labels="selectedLabels"
    :variant="$options.sidebar"
    @onDropdownClose="handleDropdownClose"
    @updateSelectedLabels="handleUpdateSelectedLabels"
  >
    {{ __('None') }}
  </labels-select>
</template>