debian-mirror-gitlab/app/assets/javascripts/frequent_items/components/app.vue

126 lines
3.8 KiB
Vue
Raw Normal View History

2018-11-08 19:23:39 +05:30
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
2019-02-15 15:39:39 +05:30
import { GlLoadingIcon } from '@gitlab/ui';
2020-01-01 13:55:28 +05:30
import AccessorUtilities from '~/lib/utils/accessor';
2018-11-08 19:23:39 +05:30
import eventHub from '../event_hub';
import store from '../store/';
import { FREQUENT_ITEMS, STORAGE_KEY } from '../constants';
2020-02-01 01:16:34 +05:30
import { isMobile, updateExistingFrequentItem, sanitizeItem } from '../utils';
2018-11-08 19:23:39 +05:30
import FrequentItemsSearchInput from './frequent_items_search_input.vue';
import FrequentItemsList from './frequent_items_list.vue';
import frequentItemsMixin from './frequent_items_mixin';
export default {
store,
components: {
FrequentItemsSearchInput,
FrequentItemsList,
2018-12-13 13:39:08 +05:30
GlLoadingIcon,
2018-11-08 19:23:39 +05:30
},
mixins: [frequentItemsMixin],
props: {
currentUserName: {
type: String,
required: true,
},
currentItem: {
type: Object,
required: true,
},
},
computed: {
...mapState(['searchQuery', 'isLoadingItems', 'isFetchFailed', 'items']),
...mapGetters(['hasSearchQuery']),
translations() {
return this.getTranslations(['loadingMessage', 'header']);
},
},
created() {
const { namespace, currentUserName, currentItem } = this;
const storageKey = `${currentUserName}/${STORAGE_KEY[namespace]}`;
this.setNamespace(namespace);
this.setStorageKey(storageKey);
if (currentItem.id) {
this.logItemAccess(storageKey, currentItem);
}
eventHub.$on(`${this.namespace}-dropdownOpen`, this.dropdownOpenHandler);
2019-03-02 22:35:43 +05:30
// As we init it through requestIdleCallback it could be that the dropdown is already open
const namespaceDropdown = document.getElementById(`nav-${this.namespace}-dropdown`);
if (namespaceDropdown && namespaceDropdown.classList.contains('show')) {
this.dropdownOpenHandler();
}
2018-11-08 19:23:39 +05:30
},
beforeDestroy() {
eventHub.$off(`${this.namespace}-dropdownOpen`, this.dropdownOpenHandler);
},
methods: {
...mapActions(['setNamespace', 'setStorageKey', 'fetchFrequentItems']),
dropdownOpenHandler() {
if (this.searchQuery === '' || isMobile()) {
this.fetchFrequentItems();
}
},
2020-02-01 01:16:34 +05:30
logItemAccess(storageKey, unsanitizedItem) {
const item = sanitizeItem(unsanitizedItem);
2018-11-08 19:23:39 +05:30
if (!AccessorUtilities.isLocalStorageAccessSafe()) {
return false;
}
// Check if there's any frequent items list set
const storedRawItems = localStorage.getItem(storageKey);
const storedFrequentItems = storedRawItems
? JSON.parse(storedRawItems)
: [{ ...item, frequency: 1 }]; // No frequent items list set, set one up.
// Check if item already exists in list
const itemMatchIndex = storedFrequentItems.findIndex(
frequentItem => frequentItem.id === item.id,
);
if (itemMatchIndex > -1) {
storedFrequentItems[itemMatchIndex] = updateExistingFrequentItem(
storedFrequentItems[itemMatchIndex],
item,
);
} else {
if (storedFrequentItems.length === FREQUENT_ITEMS.MAX_COUNT) {
storedFrequentItems.shift();
}
storedFrequentItems.push({ ...item, frequency: 1 });
}
return localStorage.setItem(storageKey, JSON.stringify(storedFrequentItems));
},
},
};
</script>
<template>
<div>
2019-02-15 15:39:39 +05:30
<frequent-items-search-input :namespace="namespace" />
2018-12-05 23:21:45 +05:30
<gl-loading-icon
2018-11-08 19:23:39 +05:30
v-if="isLoadingItems"
:label="translations.loadingMessage"
2018-12-05 23:21:45 +05:30
:size="2"
2018-11-08 19:23:39 +05:30
class="loading-animation prepend-top-20"
/>
2019-02-15 15:39:39 +05:30
<div v-if="!isLoadingItems && !hasSearchQuery" class="section-header">
2018-11-08 19:23:39 +05:30
{{ translations.header }}
</div>
<frequent-items-list
v-if="!isLoadingItems"
:items="items"
:namespace="namespace"
:has-search-query="hasSearchQuery"
:is-fetch-failed="isFetchFailed"
:matcher="searchQuery"
/>
</div>
</template>