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 | 173 |
1 files changed, 84 insertions, 89 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 c8dee81d746..353dee862d0 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 @@ -1,23 +1,25 @@ <script> import { mapState, mapGetters, mapActions } from 'vuex'; -import { GlLoadingIcon, GlButton, GlSearchBoxByType, GlLink } from '@gitlab/ui'; +import { + GlIntersectionObserver, + GlLoadingIcon, + GlButton, + GlSearchBoxByType, + GlLink, +} from '@gitlab/ui'; import fuzzaldrinPlus from 'fuzzaldrin-plus'; import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; -import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue'; import LabelItem from './label_item.vue'; -import { LIST_BUFFER_SIZE } from './constants'; - export default { - LIST_BUFFER_SIZE, components: { + GlIntersectionObserver, GlLoadingIcon, GlButton, GlSearchBoxByType, GlLink, - SmartVirtualList, LabelItem, }, data() { @@ -46,15 +48,8 @@ export default { } return this.labels; }, - showListContainer() { - if (this.isDropdownVariantSidebar) { - return !this.labelsFetchInProgress; - } - - return true; - }, showNoMatchingResultsMessage() { - return !this.labelsFetchInProgress && !this.visibleLabels.length; + return Boolean(this.searchKey) && this.visibleLabels.length === 0; }, }, watch: { @@ -67,14 +62,12 @@ export default { } }, }, - mounted() { - this.fetchLabels(); - }, methods: { ...mapActions([ 'toggleDropdownContents', 'toggleDropdownContentsCreateView', 'fetchLabels', + 'receiveLabelsSuccess', 'updateSelectedLabels', 'toggleDropdownContents', ]), @@ -100,6 +93,17 @@ export default { } }, /** + * 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. */ @@ -135,84 +139,75 @@ export default { </script> <template> - <div class="labels-select-contents-list js-labels-list" @keydown="handleKeyDown"> - <gl-loading-icon - v-if="labelsFetchInProgress" - class="labels-fetch-loading position-absolute gl-display-flex gl-align-items-center w-100 h-100" - size="md" - /> - <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')" - variant="link" - 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 - v-model="searchKey" - :autofocus="true" - data-qa-selector="dropdown_input_field" - /> - </div> - <div - v-show="showListContainer" - ref="labelsListContainer" - class="dropdown-content" - data-testid="dropdown-content" - > - <smart-virtual-list - :length="visibleLabels.length" - :remain="$options.LIST_BUFFER_SIZE" - :size="$options.LIST_BUFFER_SIZE" - wclass="list-unstyled mb-0" - wtag="ul" - class="h-100" + <gl-intersection-observer @appear="fetchLabels" @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" > - <li v-for="(label, index) in visibleLabels" :key="label.id" class="d-block text-left"> + <span class="flex-grow-1">{{ labelsListTitle }}</span> + <gl-button + :aria-label="__('Close')" + variant="link" + 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 + v-model="searchKey" + :autofocus="true" + :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" + /> + <ul v-else class="list-unstyled mb-0"> <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> - <li v-show="showNoMatchingResultsMessage" class="gl-p-3 gl-text-center"> - {{ __('No matching results') }} - </li> - </smart-virtual-list> - </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="toggleDropdownContentsCreateView" - > - {{ 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> + <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> </div> - </div> + </gl-intersection-observer> </template> |