1<script>
2import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
3import { mapGetters, mapActions } from 'vuex';
4import { getLocationHash, doesHashExistInUrl } from '../../lib/utils/url_utility';
5import {
6  DISCUSSION_FILTERS_DEFAULT_VALUE,
7  HISTORY_ONLY_FILTER_VALUE,
8  COMMENTS_ONLY_FILTER_VALUE,
9  DISCUSSION_TAB_LABEL,
10  DISCUSSION_FILTER_TYPES,
11  NOTE_UNDERSCORE,
12} from '../constants';
13import notesEventHub from '../event_hub';
14
15export default {
16  components: {
17    GlDropdown,
18    GlDropdownItem,
19    GlDropdownDivider,
20  },
21  props: {
22    filters: {
23      type: Array,
24      required: true,
25    },
26    selectedValue: {
27      type: Number,
28      default: DISCUSSION_FILTERS_DEFAULT_VALUE,
29      required: false,
30    },
31  },
32  data() {
33    return {
34      currentValue: doesHashExistInUrl(NOTE_UNDERSCORE)
35        ? DISCUSSION_FILTERS_DEFAULT_VALUE
36        : this.selectedValue,
37      defaultValue: DISCUSSION_FILTERS_DEFAULT_VALUE,
38      displayFilters: true,
39    };
40  },
41  computed: {
42    ...mapGetters(['getNotesDataByProp', 'timelineEnabled', 'isLoading']),
43    currentFilter() {
44      if (!this.currentValue) return this.filters[0];
45      return this.filters.find((filter) => filter.value === this.currentValue);
46    },
47  },
48  created() {
49    if (window.mrTabs) {
50      const { eventHub, currentTab } = window.mrTabs;
51
52      eventHub.$on('MergeRequestTabChange', this.toggleFilters);
53      this.toggleFilters(currentTab);
54    }
55
56    notesEventHub.$on('dropdownSelect', this.selectFilter);
57    window.addEventListener('hashchange', this.handleLocationHash);
58  },
59  mounted() {
60    this.toggleCommentsForm();
61  },
62  destroyed() {
63    notesEventHub.$off('dropdownSelect', this.selectFilter);
64    window.removeEventListener('hashchange', this.handleLocationHash);
65  },
66  methods: {
67    ...mapActions([
68      'filterDiscussion',
69      'setCommentsDisabled',
70      'setTargetNoteHash',
71      'setTimelineView',
72    ]),
73    selectFilter(value, persistFilter = true) {
74      const filter = parseInt(value, 10);
75
76      if (filter === this.currentValue) return;
77
78      if (this.timelineEnabled && filter !== COMMENTS_ONLY_FILTER_VALUE) {
79        this.setTimelineView(false);
80      }
81      this.currentValue = filter;
82      this.filterDiscussion({
83        path: this.getNotesDataByProp('discussionsPath'),
84        filter,
85        persistFilter,
86      });
87      this.toggleCommentsForm();
88    },
89    toggleCommentsForm() {
90      this.setCommentsDisabled(this.currentValue === HISTORY_ONLY_FILTER_VALUE);
91    },
92    toggleFilters(tab) {
93      this.displayFilters = tab === DISCUSSION_TAB_LABEL;
94    },
95    handleLocationHash() {
96      const hash = getLocationHash();
97
98      if (/^note_/.test(hash) && this.currentValue !== DISCUSSION_FILTERS_DEFAULT_VALUE) {
99        this.selectFilter(this.defaultValue, false);
100        this.setTargetNoteHash(hash);
101      }
102    },
103    filterType(value) {
104      if (value === 0) {
105        return DISCUSSION_FILTER_TYPES.ALL;
106      } else if (value === 1) {
107        return DISCUSSION_FILTER_TYPES.COMMENTS;
108      }
109      return DISCUSSION_FILTER_TYPES.HISTORY;
110    },
111  },
112};
113</script>
114
115<template>
116  <gl-dropdown
117    v-if="displayFilters"
118    id="discussion-filter-dropdown"
119    class="gl-mr-3 full-width-mobile discussion-filter-container js-discussion-filter-container"
120    data-qa-selector="discussion_filter_dropdown"
121    :text="currentFilter.title"
122    :disabled="isLoading"
123  >
124    <div v-for="filter in filters" :key="filter.value" class="dropdown-item-wrapper">
125      <gl-dropdown-item
126        :is-check-item="true"
127        :is-checked="filter.value === currentValue"
128        :class="{ 'is-active': filter.value === currentValue }"
129        :data-filter-type="filterType(filter.value)"
130        data-qa-selector="filter_menu_item"
131        @click.prevent="selectFilter(filter.value)"
132      >
133        {{ filter.title }}
134      </gl-dropdown-item>
135      <gl-dropdown-divider v-if="filter.value === defaultValue" />
136    </div>
137  </gl-dropdown>
138</template>
139