diff options
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue | 230 |
1 files changed, 0 insertions, 230 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 deleted file mode 100644 index e235bfde394..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue +++ /dev/null @@ -1,230 +0,0 @@ -<script> -import { - GlIntersectionObserver, - GlLoadingIcon, - GlButton, - GlSearchBoxByType, - GlLink, -} from '@gitlab/ui'; -import fuzzaldrinPlus from 'fuzzaldrin-plus'; -import { mapState, mapGetters, mapActions } from 'vuex'; - -import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; - -import LabelItem from './label_item.vue'; - -// @deprecated This component should only be used when there is no GraphQL API. -// In most cases you should use -// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue` instead. -export default { - components: { - GlIntersectionObserver, - GlLoadingIcon, - GlButton, - GlSearchBoxByType, - GlLink, - LabelItem, - }, - data() { - return { - searchKey: '', - currentHighlightItem: -1, - }; - }, - computed: { - ...mapState([ - 'allowLabelCreate', - 'allowMultiselect', - 'labelsManagePath', - 'labels', - 'labelsFetchInProgress', - 'labelsListTitle', - 'footerCreateLabelTitle', - 'footerManageLabelTitle', - ]), - ...mapGetters(['selectedLabelsList', 'isDropdownVariantSidebar', 'isDropdownVariantEmbedded']), - visibleLabels() { - if (this.searchKey) { - return fuzzaldrinPlus.filter(this.labels, this.searchKey, { - key: ['title'], - }); - } - return this.labels; - }, - showDropdownFooter() { - return ( - (this.isDropdownVariantSidebar || this.isDropdownVariantEmbedded) && - (this.allowLabelCreate || this.labelsManagePath) - ); - }, - showNoMatchingResultsMessage() { - return Boolean(this.searchKey) && this.visibleLabels.length === 0; - }, - }, - watch: { - searchKey(value) { - // When there is search string present - // and there are matching results, - // highlight first item by default. - if (value && this.visibleLabels.length) { - this.currentHighlightItem = 0; - } - }, - }, - methods: { - ...mapActions([ - 'toggleDropdownContents', - 'toggleDropdownContentsCreateView', - 'fetchLabels', - 'receiveLabelsSuccess', - 'updateSelectedLabels', - 'toggleDropdownContents', - ]), - isLabelSelected(label) { - return this.selectedLabelsList.includes(label.id); - }, - /** - * This method scrolls item from dropdown into - * the view if it is off the viewable area of the - * container. - */ - scrollIntoViewIfNeeded() { - const highlightedLabel = this.$refs.labelsListContainer.querySelector('.is-focused'); - - if (highlightedLabel) { - const container = this.$refs.labelsListContainer.getBoundingClientRect(); - const label = highlightedLabel.getBoundingClientRect(); - - if (label.bottom > container.bottom) { - this.$refs.labelsListContainer.scrollTop += label.bottom - container.bottom; - } else if (label.top < container.top) { - this.$refs.labelsListContainer.scrollTop -= container.top - label.top; - } - } - }, - 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(); - }, - /** - * This method enables keyboard navigation support for - * the dropdown. - */ - handleKeyDown(e) { - if (e.keyCode === UP_KEY_CODE && this.currentHighlightItem > 0) { - this.currentHighlightItem -= 1; - } else if ( - e.keyCode === DOWN_KEY_CODE && - this.currentHighlightItem < this.visibleLabels.length - 1 - ) { - this.currentHighlightItem += 1; - } 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(); - } - - if (e.keyCode !== ESC_KEY_CODE) { - // Scroll the list only after highlighting - // styles are rendered completely. - this.$nextTick(() => { - this.scrollIntoViewIfNeeded(); - }); - } - }, - handleLabelClick(label) { - this.updateSelectedLabels([label]); - if (!this.allowMultiselect) this.toggleDropdownContents(); - }, - }, -}; -</script> - -<template> - <gl-intersection-observer @appear="handleComponentAppear" @disappear="handleComponentDisappear"> - <div class="labels-select-contents-list js-labels-list" @keydown="handleKeyDown"> - <div - v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded" - class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!" - data-testid="dropdown-title" - > - <span class="flex-grow-1">{{ labelsListTitle }}</span> - <gl-button - :aria-label="__('Close')" - category="tertiary" - size="small" - class="dropdown-header-button gl-p-0!" - icon="close" - @click="toggleDropdownContents" - /> - </div> - <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="lg" - /> - <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" - :is-label-indeterminate="label.indeterminate" - :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="showDropdownFooter" 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 v-if="labelsManagePath"> - <gl-link - :href="labelsManagePath" - class="gl-display-flex flex-row text-break-word label-item" - > - {{ footerManageLabelTitle }} - </gl-link> - </li> - </ul> - </div> - </div> - </gl-intersection-observer> -</template> |