diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 09:08:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 09:08:42 +0000 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/assets/javascripts/vue_shared/components/sidebar | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) | |
download | gitlab-ce-b76ae638462ab0f673e5915986070518dd3f9ad3.tar.gz |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/sidebar')
17 files changed, 274 insertions, 201 deletions
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue index 9914bfc6026..623e7799493 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue @@ -132,6 +132,9 @@ export default { } else if (e.keyCode === ENTER_KEY_CODE && this.currentHighlightItem > -1) { this.updateSelectedLabels([this.visibleLabels[this.currentHighlightItem]]); this.searchKey = ''; + + // Prevent parent form submission upon hitting enter. + e.preventDefault(); } else if (e.keyCode === ESC_KEY_CODE) { this.toggleDropdownContents(); } diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue index aad754e15b0..7989ad40b5a 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue @@ -28,8 +28,9 @@ export default { <template v-if="allowLabelEdit"> <gl-loading-icon v-show="labelsSelectInProgress" size="sm" inline /> <gl-button - variant="link" - class="float-right gl-text-gray-900! gl-hover-text-blue-800! js-sidebar-dropdown-toggle" + category="tertiary" + size="small" + class="float-right js-sidebar-dropdown-toggle gl-mr-n2" data-qa-selector="labels_edit_button" @click="toggleDropdownContents" > diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue index 87af3ffc52c..4234bc72f3a 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue @@ -142,6 +142,7 @@ export default { this.setInitialState({ selectedLabels, }); + setTimeout(() => this.updateLabelsSetState(), 100); }, showDropdownContents(showDropdownContents) { this.setContentIsOnViewport(showDropdownContents); @@ -184,7 +185,7 @@ export default { document.removeEventListener('click', this.handleDocumentClick); }, methods: { - ...mapActions(['setInitialState', 'toggleDropdownContents']), + ...mapActions(['setInitialState', 'toggleDropdownContents', 'updateLabelsSetState']), /** * This method differentiates between * dispatched actions and calls necessary method. @@ -315,7 +316,7 @@ export default { </dropdown-value> <dropdown-button v-show="dropdownButtonVisible" class="gl-mt-2" /> <dropdown-contents - v-show="dropdownButtonVisible && showDropdownContents" + v-if="dropdownButtonVisible && showDropdownContents" ref="dropdownContents" :render-on-top="!contentIsOnViewport" /> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js index 178be0f6da0..0c697e624ab 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js @@ -20,7 +20,11 @@ export const receiveLabelsFailure = ({ commit }) => { message: __('Error fetching labels.'), }); }; -export const fetchLabels = ({ state, dispatch }) => { +export const fetchLabels = ({ state, dispatch }, options) => { + if (state.labelsFetched && (!options || !options.refetch)) { + return Promise.resolve(); + } + dispatch('requestLabels'); return axios .get(state.labelsFetchPath) @@ -46,6 +50,7 @@ export const createLabel = ({ state, dispatch }, label) => { }) .then(({ data }) => { if (data.id) { + dispatch('fetchLabels', { refetch: true }); dispatch('receiveCreateLabelSuccess'); dispatch('toggleDropdownContentsCreateView'); } else { @@ -60,3 +65,5 @@ export const createLabel = ({ state, dispatch }, label) => { export const updateSelectedLabels = ({ commit }, labels) => commit(types.UPDATE_SELECTED_LABELS, { labels }); + +export const updateLabelsSetState = ({ commit }) => commit(types.UPDATE_LABELS_SET_STATE); diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutation_types.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutation_types.js index 2e044dc3b3c..f26e36031f4 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutation_types.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutation_types.js @@ -18,3 +18,5 @@ export const TOGGLE_DROPDOWN_CONTENTS = 'TOGGLE_DROPDOWN_CONTENTS'; export const UPDATE_SELECTED_LABELS = 'UPDATE_SELECTED_LABELS'; export const TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW = 'TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW'; + +export const UPDATE_LABELS_SET_STATE = 'UPDATE_LABELS_SET_STATE'; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js index 2e0a57f15dd..8853dc8b9e3 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js @@ -34,15 +34,12 @@ export default { // Iterate over every label and add a `set` prop // to determine whether it is already a part of // selectedLabels array. - const selectedLabelIds = state.selectedLabels.map((label) => label.id); state.labelsFetchInProgress = false; - state.labels = labels.reduce((allLabels, label) => { - allLabels.push({ - ...label, - set: selectedLabelIds.includes(label.id), - }); - return allLabels; - }, []); + state.labelsFetched = true; + state.labels = labels.map((label) => ({ + ...label, + set: state.selectedLabels.some((selectedLabel) => selectedLabel.id === label.id), + })); }, [types.RECEIVE_SET_LABELS_FAILURE](state) { state.labelsFetchInProgress = false; @@ -79,4 +76,11 @@ export default { } } }, + + [types.UPDATE_LABELS_SET_STATE](state) { + state.labels = state.labels.map((label) => ({ + ...label, + set: state.selectedLabels.some((selectedLabel) => selectedLabel.id === label.id), + })); + }, }; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js index d66cfed4163..0185d5f88e1 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js @@ -1,6 +1,7 @@ export default () => ({ // Initial Data labels: [], + labelsFetched: false, selectedLabels: [], labelsListTitle: '', labelsCreateTitle: '', diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue index 1f0704f7308..6694e349b6e 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue @@ -21,9 +21,29 @@ export default { type: String, required: true, }, + selectedLabels: { + type: Array, + required: true, + }, + allowMultiselect: { + type: Boolean, + required: true, + }, + labelsListTitle: { + type: String, + required: true, + }, + footerCreateLabelTitle: { + type: String, + required: true, + }, + footerManageLabelTitle: { + type: String, + required: true, + }, }, computed: { - ...mapState(['showDropdownContentsCreateView', 'labelsListTitle']), + ...mapState(['showDropdownContentsCreateView']), ...mapGetters(['isDropdownVariantSidebar', 'isDropdownVariantEmbedded']), dropdownContentsView() { if (this.showDropdownContentsCreateView) { @@ -75,6 +95,16 @@ export default { @click="toggleDropdownContents" /> </div> - <component :is="dropdownContentsView" @hideCreateView="toggleDropdownContentsCreateView" /> + <component + :is="dropdownContentsView" + :selected-labels="selectedLabels" + :allow-multiselect="allowMultiselect" + :labels-list-title="labelsListTitle" + :footer-create-label-title="footerCreateLabelTitle" + :footer-manage-label-title="footerManageLabelTitle" + @hideCreateView="toggleDropdownContentsCreateView" + @closeDropdown="$emit('closeDropdown', $event)" + @toggleDropdownContentsCreateView="toggleDropdownContentsCreateView" + /> </div> </template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue index bff34743344..ffa37424c2c 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue @@ -1,38 +1,91 @@ <script> -import { GlIntersectionObserver, GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui'; +import { GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui'; import fuzzaldrinPlus from 'fuzzaldrin-plus'; -import { mapState, mapGetters, mapActions } from 'vuex'; - +import { debounce } from 'lodash'; +import createFlash from '~/flash'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; - +import { __ } from '~/locale'; +import { DropdownVariant } from './constants'; +import projectLabelsQuery from './graphql/project_labels.query.graphql'; import LabelItem from './label_item.vue'; export default { components: { - GlIntersectionObserver, GlLoadingIcon, GlSearchBoxByType, GlLink, LabelItem, }, + inject: ['projectPath', 'allowLabelCreate', 'labelsManagePath', 'variant'], + props: { + selectedLabels: { + type: Array, + required: true, + }, + allowMultiselect: { + type: Boolean, + required: true, + }, + labelsListTitle: { + type: String, + required: true, + }, + footerCreateLabelTitle: { + type: String, + required: true, + }, + footerManageLabelTitle: { + type: String, + required: true, + }, + }, data() { return { searchKey: '', + labels: [], currentHighlightItem: -1, + localSelectedLabels: [...this.selectedLabels], }; }, + apollo: { + labels: { + query: projectLabelsQuery, + variables() { + return { + fullPath: this.projectPath, + searchTerm: this.searchKey, + }; + }, + skip() { + return this.searchKey.length === 1; + }, + update: (data) => data.workspace?.labels?.nodes || [], + async result() { + if (this.$refs.searchInput) { + await this.$nextTick(); + this.$refs.searchInput.focusInput(); + } + }, + error() { + createFlash({ message: __('Error fetching labels.') }); + }, + }, + }, computed: { - ...mapState([ - 'allowLabelCreate', - 'allowMultiselect', - 'labelsManagePath', - 'labels', - 'labelsFetchInProgress', - 'labelsListTitle', - 'footerCreateLabelTitle', - 'footerManageLabelTitle', - ]), - ...mapGetters(['selectedLabelsList', 'isDropdownVariantSidebar', 'isDropdownVariantEmbedded']), + isDropdownVariantSidebar() { + return this.variant === DropdownVariant.Sidebar; + }, + isDropdownVariantEmbedded() { + return this.variant === DropdownVariant.Embedded; + }, + labelsFetchInProgress() { + return this.$apollo.queries.labels.loading; + }, + localSelectedLabelsIds() { + return this.localSelectedLabels.map((label) => label.id); + }, visibleLabels() { if (this.searchKey) { return fuzzaldrinPlus.filter(this.labels, this.searchKey, { @@ -55,17 +108,16 @@ export default { } }, }, + created() { + this.debouncedSearchKeyUpdate = debounce(this.setSearchKey, DEFAULT_DEBOUNCE_AND_THROTTLE_MS); + }, + beforeDestroy() { + this.$emit('closeDropdown', this.localSelectedLabels); + this.debouncedSearchKeyUpdate.cancel(); + }, methods: { - ...mapActions([ - 'toggleDropdownContents', - 'toggleDropdownContentsCreateView', - 'fetchLabels', - 'receiveLabelsSuccess', - 'updateSelectedLabels', - 'toggleDropdownContents', - ]), isLabelSelected(label) { - return this.selectedLabelsList.includes(label.id); + return this.localSelectedLabelsIds.includes(getIdFromGraphQLId(label.id)); }, /** * This method scrolls item from dropdown into @@ -86,23 +138,17 @@ export default { } } }, - handleComponentAppear() { - // We can avoid putting `catch` block here - // as failure is handled within actions.js already. - return this.fetchLabels().then(() => { - this.$refs.searchInput.focusInput(); - }); - }, - /** - * We want to remove loaded labels to ensure component - * fetches fresh set of labels every time when shown. - */ - handleComponentDisappear() { - this.receiveLabelsSuccess([]); - }, - handleCreateLabelClick() { - this.receiveLabelsSuccess([]); - this.toggleDropdownContentsCreateView(); + updateSelectedLabels(label) { + if (this.isLabelSelected(label)) { + this.localSelectedLabels = this.localSelectedLabels.filter( + ({ id }) => id !== getIdFromGraphQLId(label.id), + ); + } else { + this.localSelectedLabels.push({ + ...label, + id: getIdFromGraphQLId(label.id), + }); + } }, /** * This method enables keyboard navigation support for @@ -117,10 +163,10 @@ export default { ) { this.currentHighlightItem += 1; } else if (e.keyCode === ENTER_KEY_CODE && this.currentHighlightItem > -1) { - this.updateSelectedLabels([this.visibleLabels[this.currentHighlightItem]]); + this.updateSelectedLabels(this.visibleLabels[this.currentHighlightItem]); this.searchKey = ''; } else if (e.keyCode === ESC_KEY_CODE) { - this.toggleDropdownContents(); + this.$emit('closeDropdown', this.localSelectedLabels); } if (e.keyCode !== ESC_KEY_CODE) { @@ -132,68 +178,82 @@ export default { } }, handleLabelClick(label) { - this.updateSelectedLabels([label]); - if (!this.allowMultiselect) this.toggleDropdownContents(); + this.updateSelectedLabels(label); + if (!this.allowMultiselect) { + this.$emit('closeDropdown', this.localSelectedLabels); + } + }, + setSearchKey(value) { + this.searchKey = value; }, }, }; </script> <template> - <gl-intersection-observer @appear="handleComponentAppear" @disappear="handleComponentDisappear"> - <div class="labels-select-contents-list js-labels-list" @keydown="handleKeyDown"> - <div class="dropdown-input" @click.stop="() => {}"> - <gl-search-box-by-type - ref="searchInput" - v-model="searchKey" - :disabled="labelsFetchInProgress" - data-qa-selector="dropdown_input_field" - /> - </div> - <div ref="labelsListContainer" class="dropdown-content" data-testid="dropdown-content"> - <gl-loading-icon - v-if="labelsFetchInProgress" - class="labels-fetch-loading gl-align-items-center w-100 h-100" - size="md" + <div + class="labels-select-contents-list js-labels-list" + data-testid="dropdown-wrapper" + @keydown="handleKeyDown" + > + <div class="dropdown-input" @click.stop="() => {}"> + <gl-search-box-by-type + ref="searchInput" + :value="searchKey" + :disabled="labelsFetchInProgress" + data-qa-selector="dropdown_input_field" + data-testid="dropdown-input-field" + @input="debouncedSearchKeyUpdate" + /> + </div> + <div ref="labelsListContainer" class="dropdown-content" data-testid="dropdown-content"> + <gl-loading-icon + v-if="labelsFetchInProgress" + class="labels-fetch-loading gl-align-items-center gl-w-full gl-h-full" + size="md" + /> + <ul v-else class="list-unstyled gl-mb-0 gl-word-break-word" data-testid="labels-list"> + <label-item + v-for="(label, index) in visibleLabels" + :key="label.id" + :label="label" + :is-label-set="isLabelSelected(label)" + :highlight="index === currentHighlightItem" + @clickLabel="handleLabelClick(label)" /> - <ul v-else class="list-unstyled gl-mb-0 gl-word-break-word"> - <label-item - v-for="(label, index) in visibleLabels" - :key="label.id" - :label="label" - :is-label-set="label.set" - :highlight="index === currentHighlightItem" - @clickLabel="handleLabelClick(label)" - /> - <li v-show="showNoMatchingResultsMessage" class="gl-p-3 gl-text-center"> - {{ __('No matching results') }} - </li> - </ul> - </div> - <div - v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded" - class="dropdown-footer" - data-testid="dropdown-footer" - > - <ul class="list-unstyled"> - <li v-if="allowLabelCreate"> - <gl-link - class="gl-display-flex w-100 flex-row text-break-word label-item" - @click="handleCreateLabelClick" - > - {{ footerCreateLabelTitle }} - </gl-link> - </li> - <li> - <gl-link - :href="labelsManagePath" - class="gl-display-flex flex-row text-break-word label-item" - > - {{ footerManageLabelTitle }} - </gl-link> - </li> - </ul> - </div> + <li + v-show="showNoMatchingResultsMessage" + class="gl-p-3 gl-text-center" + data-testid="no-results" + > + {{ __('No matching results') }} + </li> + </ul> + </div> + <div + v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded" + class="dropdown-footer" + data-testid="dropdown-footer" + > + <ul class="list-unstyled"> + <li v-if="allowLabelCreate"> + <gl-link + class="gl-display-flex gl-flex-direction-row gl-w-full gl-overflow-break-word label-item" + data-testid="create-label-button" + @click="$emit('toggleDropdownContentsCreateView')" + > + {{ footerCreateLabelTitle }} + </gl-link> + </li> + <li> + <gl-link + :href="labelsManagePath" + class="gl-display-flex gl-flex-direction-row gl-w-full gl-overflow-break-word label-item" + > + {{ footerManageLabelTitle }} + </gl-link> + </li> + </ul> </div> - </gl-intersection-observer> + </div> </template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue index b6d14965cfa..46edfa1c42a 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue @@ -28,8 +28,9 @@ export default { <template v-if="allowLabelEdit"> <gl-loading-icon v-show="labelsSelectInProgress" size="sm" inline /> <gl-button - variant="link" - class="float-right js-sidebar-dropdown-toggle" + category="tertiary" + size="small" + class="float-right js-sidebar-dropdown-toggle gl-mr-n2" data-qa-selector="labels_edit_button" @click="toggleDropdownContents" >{{ __('Edit') }}</gl-button diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql new file mode 100644 index 00000000000..dc39220487d --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql @@ -0,0 +1,12 @@ +query projectLabels($fullPath: ID!, $searchTerm: String) { + workspace: project(fullPath: $fullPath) { + labels(searchTerm: $searchTerm, includeAncestorGroups: true) { + nodes { + id + title + color + description + } + } + } +} diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue index 87f36a5bb72..0499dfe468f 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue @@ -197,23 +197,6 @@ export default { methods: { ...mapActions(['setInitialState', 'toggleDropdownContents']), /** - * This method differentiates between - * dispatched actions and calls necessary method. - */ - handleVuexActionDispatch(action, state) { - if ( - action.type === 'toggleDropdownContents' && - !state.showDropdownButton && - !state.showDropdownContents - ) { - let filterFn = (label) => label.touched; - if (this.isDropdownVariantEmbedded) { - filterFn = (label) => label.set; - } - this.handleDropdownClose(state.labels.filter(filterFn)); - } - }, - /** * This method stores a mousedown event's target. * Required by the click listener because the click * event itself has no reference to this element. @@ -276,6 +259,9 @@ export default { handleDropdownClose(labels) { // Only emit label updates if there are any labels to update // on UI. + if (this.showDropdownContents) { + this.toggleDropdownContents(); + } if (labels.length) this.$emit('updateSelectedLabels', labels); this.$emit('onDropdownClose'); }, @@ -330,10 +316,16 @@ export default { </dropdown-value> <dropdown-button v-show="dropdownButtonVisible" class="gl-mt-2" /> <dropdown-contents - v-show="dropdownButtonVisible && showDropdownContents" + v-if="dropdownButtonVisible && showDropdownContents" ref="dropdownContents" + :allow-multiselect="allowMultiselect" + :labels-list-title="labelsListTitle" + :footer-create-label-title="footerCreateLabelTitle" + :footer-manage-label-title="footerManageLabelTitle" :render-on-top="!contentIsOnViewport" :labels-create-title="labelsCreateTitle" + :selected-labels="selectedLabels" + @closeDropdown="handleDropdownClose" /> </template> <template v-if="isDropdownVariantStandalone || isDropdownVariantEmbedded"> @@ -341,7 +333,13 @@ export default { <dropdown-contents v-if="dropdownButtonVisible && showDropdownContents" ref="dropdownContents" + :allow-multiselect="allowMultiselect" + :labels-list-title="labelsListTitle" + :footer-create-label-title="footerCreateLabelTitle" + :footer-manage-label-title="footerManageLabelTitle" :render-on-top="!contentIsOnViewport" + :selected-labels="selectedLabels" + @closeDropdown="handleDropdownClose" /> </template> </div> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js index 935f020f559..b3d4a204a81 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js @@ -1,6 +1,3 @@ -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; -import { __ } from '~/locale'; import * as types from './mutation_types'; export const setInitialState = ({ commit }, props) => commit(types.SET_INITIAL_STATE, props); @@ -11,24 +8,5 @@ export const toggleDropdownContents = ({ commit }) => commit(types.TOGGLE_DROPDO export const toggleDropdownContentsCreateView = ({ commit }) => commit(types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW); -export const requestLabels = ({ commit }) => commit(types.REQUEST_LABELS); -export const receiveLabelsSuccess = ({ commit }, labels) => - commit(types.RECEIVE_SET_LABELS_SUCCESS, labels); -export const receiveLabelsFailure = ({ commit }) => { - commit(types.RECEIVE_SET_LABELS_FAILURE); - createFlash({ - message: __('Error fetching labels.'), - }); -}; -export const fetchLabels = ({ state, dispatch }) => { - dispatch('requestLabels'); - return axios - .get(state.labelsFetchPath) - .then(({ data }) => { - dispatch('receiveLabelsSuccess', data); - }) - .catch(() => dispatch('receiveLabelsFailure')); -}; - export const updateSelectedLabels = ({ commit }, labels) => commit(types.UPDATE_SELECTED_LABELS, { labels }); diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js index b8da7a90b36..bd71c3b85f1 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js @@ -1,13 +1,5 @@ export const SET_INITIAL_STATE = 'SET_INITIAL_STATE'; -export const REQUEST_LABELS = 'REQUEST_LABELS'; -export const RECEIVE_LABELS_SUCCESS = 'RECEIVE_LABELS_SUCCESS'; -export const RECEIVE_LABELS_FAILURE = 'RECEIVE_LABELS_FAILURE'; - -export const REQUEST_SET_LABELS = 'REQUEST_SET_LABELS'; -export const RECEIVE_SET_LABELS_SUCCESS = 'RECEIVE_SET_LABELS_SUCCESS'; -export const RECEIVE_SET_LABELS_FAILURE = 'RECEIVE_SET_LABELS_FAILURE'; - export const TOGGLE_DROPDOWN_BUTTON = 'TOGGLE_DROPDOWN_VISIBILITY'; export const TOGGLE_DROPDOWN_CONTENTS = 'TOGGLE_DROPDOWN_CONTENTS'; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js index 1c03d95f37b..45ec4d7ae04 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js @@ -26,27 +26,6 @@ export default { [types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW](state) { state.showDropdownContentsCreateView = !state.showDropdownContentsCreateView; }, - - [types.REQUEST_LABELS](state) { - state.labelsFetchInProgress = true; - }, - [types.RECEIVE_SET_LABELS_SUCCESS](state, labels) { - // Iterate over every label and add a `set` prop - // to determine whether it is already a part of - // selectedLabels array. - const selectedLabelIds = state.selectedLabels.map((label) => label.id); - state.labelsFetchInProgress = false; - state.labels = labels.reduce((allLabels, label) => { - allLabels.push({ - ...label, - set: selectedLabelIds.includes(label.id), - }); - return allLabels; - }, []); - }, - [types.RECEIVE_SET_LABELS_FAILURE](state) { - state.labelsFetchInProgress = false; - }, [types.UPDATE_SELECTED_LABELS](state, { labels }) { // Find the label to update from all the labels // and change `set` prop value to represent their current state. diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue index e6229cf0a93..cdc7422c7df 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue @@ -1,6 +1,6 @@ <script> import { GlButton } from '@gitlab/ui'; -import { todoLabel } from './utils'; +import { todoLabel, updateGlobalTodoCount } from './utils'; export default { components: { @@ -19,23 +19,11 @@ export default { }, }, methods: { - updateGlobalTodoCount(additionalTodoCount) { - const countContainer = document.querySelector('.js-todos-count'); - if (countContainer === null) return; - const currentCount = parseInt(countContainer.innerText, 10); - const todoToggleEvent = new CustomEvent('todo:toggle', { - detail: { - count: Math.max(currentCount + additionalTodoCount, 0), - }, - }); - - document.dispatchEvent(todoToggleEvent); - }, incrementGlobalTodoCount() { - this.updateGlobalTodoCount(1); + updateGlobalTodoCount(1); }, decrementGlobalTodoCount() { - this.updateGlobalTodoCount(-1); + updateGlobalTodoCount(-1); }, onToggle(event) { if (this.isTodo) { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js index 59e72a2ffe3..098ab72dfb5 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js @@ -3,3 +3,19 @@ import { __ } from '~/locale'; export const todoLabel = (hasTodo) => { return hasTodo ? __('Mark as done') : __('Add a to do'); }; + +export const updateGlobalTodoCount = (additionalTodoCount) => { + const countContainer = document.querySelector('.js-todos-count'); + + if (countContainer === null) return; + + const currentCount = parseInt(countContainer.innerText, 10); + + const todoToggleEvent = new CustomEvent('todo:toggle', { + detail: { + count: Math.max(currentCount + additionalTodoCount, 0), + }, + }); + + document.dispatchEvent(todoToggleEvent); +}; |