import { ActionTree, Module, MutationTree, GetterTree } from 'vuex'; import type RootState from '../types/RootStateModel'; import AssetStoreModel from '../types/AssetStoreModel'; import { Asset, AssetSortField, AssetSortOrder, AssetTypeFilter } from '../../types/api'; import AssetApi, { AssetSearchPayload, AssetSearchResult } from '../../api/asset-api'; import _cloneDeep from 'lodash/cloneDeep'; const namespaced = true; export interface AssetSearchState { filters: { query?: string; assetTypeFilter?: AssetTypeFilter; assetSortField?: AssetSortField; assetSortOrder?: AssetSortOrder; tagFilter?: string[]; }; page?: number; } export const INITIAL_SEARCH_STATE: AssetSearchState = { filters: { query: '', assetSortField: AssetSortField.DateModified, assetSortOrder: AssetSortOrder.Descending, assetTypeFilter: AssetTypeFilter.All, tagFilter: [] }, page: 1 }; const state: AssetStoreModel = { allAssets: [], result: undefined, isLoadingAssets: true, lastSearchQueryTimestamp: 0, searchState: _cloneDeep(INITIAL_SEARCH_STATE) }; const actions: ActionTree = { async $init({ dispatch }) { dispatch('fetchItems'); }, async fetchItems({ state, commit }) { commit('isLoading', true); const timestamp = Date.now(); commit('setLastSearchQueryTimestamp', timestamp); const assetSearchPayload: AssetSearchPayload = { query: state.searchState.filters.query, page: state.searchState.page, assetTypeFilter: state.searchState.filters.assetTypeFilter, assetSortField: state.searchState.filters.assetSortField, assetSortOrder: state.searchState.filters.assetSortOrder, tagFilter: state.searchState.filters.tagFilter || undefined, timestamp: timestamp }; const response = await AssetApi.search(assetSearchPayload); if (response.timestamp !== state.lastSearchQueryTimestamp) { commit('isLoading', false); return; } const result = response.result; commit('setResult', result); commit('setAssets', result.items); commit('isLoading', false); }, async updateAsset({ dispatch }, asset: Asset) { const updatedAsset = await AssetApi.updateAsset(asset); dispatch('fetchItems'); return updatedAsset; }, async createAsset({ dispatch }, data: FormData) { const createdAsset = await AssetApi.createAsset(data); dispatch('fetchItems'); return createdAsset; }, async deleteAsset({ dispatch }, id: string) { await AssetApi.deleteAsset(id); dispatch('fetchItems'); return true; }, async updateSearchState({ commit, dispatch }, searchState: AssetSearchState) { commit('searchState', searchState); dispatch('fetchItems'); } }; export const getters: GetterTree = { result: (state) => (): AssetSearchResult | undefined => { return state.result; }, searchState: (state) => (): AssetSearchState => { return state.searchState; }, nextDisabled: (state) => (): boolean => { const dataPage = state.result; if (dataPage && dataPage.totalPages === 0) { return true; } return dataPage && dataPage.currentPage ? dataPage.currentPage === dataPage.totalPages : true; }, previousDisabled: (state) => (): boolean => { const dataPage = state.result; if (dataPage && dataPage.totalPages === 0) { return true; } return dataPage && dataPage.currentPage ? dataPage.currentPage === 1 : true; } }; const mutations: MutationTree = { setAssets(assetsState, assets: Asset[]) { assetsState.allAssets = assets; }, isLoading(assetsState, isLoading: boolean) { assetsState.isLoadingAssets = isLoading; }, setResult(assetsState, result: AssetSearchResult) { assetsState.result = result; }, setLastSearchQueryTimestamp(assetsState, timestamp: number) { assetsState.lastSearchQueryTimestamp = timestamp; }, searchState(state, searchState: AssetSearchState) { state.searchState = searchState; }, setQuery(state, query: string) { state.searchState.filters.query = query; state.searchState.page = 1; }, setAssetTypeFilter(state, filter: AssetTypeFilter) { state.searchState.filters.assetTypeFilter = filter; state.searchState.page = 1; }, setTagFilter(state, filter: string[]) { state.searchState.filters.tagFilter = filter; state.searchState.page = 1; }, resetFilters(state) { state.searchState = _cloneDeep(INITIAL_SEARCH_STATE); } }; export const assetStore: Module = { namespaced, state, getters, actions, mutations };