feat: save datatable filters & options

refactor/issue-1/first-setup
Frédérik Benoist 2024-01-01 22:24:01 +01:00
parent fb3a7f1b97
commit 6ae66dd274
2 changed files with 113 additions and 8 deletions

View File

@ -1,7 +1,11 @@
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'
import { VDataTable } from 'vuetify/labs/VDataTable'
import { useDataTableStore } from '@/stores/datatable.store'
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const headers = computed(() => [
{ title: 'ID', key: 'id_structure' },
@ -30,8 +34,6 @@ const { data: dtListData } = await useApi<any>(createUrl('/stores'))
storesList.value = dtListData.value
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
const country = computed(() => {
const allItems = storesList.value.map((store: { pays: any }) => store.pays)
// eslint-disable-next-line @typescript-eslint/no-shadow
@ -68,9 +70,11 @@ const filteredData = computed(() => {
if (selectedBrand.value)
filtered = filtered.filter((store: { enseigne: any }) => store.enseigne === selectedBrand.value)
// If a country is selected, filter the records for this country
if (selectedCountry.value)
filtered = filtered.filter((store: { pays: any }) => store.pays === selectedCountry.value)
// If a number of POS is selected, filter the records for this number
if (selectedNbPos.value)
filtered = filtered.filter((store: { nbcaisses: any }) => store.nbcaisses === selectedNbPos.value)
@ -121,6 +125,48 @@ const reloadStores = async () => {
isLoading.value = false
}
// pinia store for datatable filters & options
const stStoreList = useDataTableStore()
const saveDtFilters = () => {
stStoreList.setFilters('selectedCountry', selectedCountry.value)
stStoreList.setFilters('selectedBrand', selectedBrand.value)
stStoreList.setFilters('selectedNbPos', selectedNbPos.value)
stStoreList.searchText = searchQuery.value
}
const restoreDtFilters = () => {
if (stStoreList.filters.selectedCountry)
selectedCountry.value = stStoreList.filters.selectedCountry
if (stStoreList.filters.selectedBrand)
selectedBrand.value = stStoreList.filters.selectedBrand
if (stStoreList.filters.selectedNbPos)
selectedNbPos.value = stStoreList.filters.selectedNbPos
if (stStoreList.searchText)
searchQuery.value = stStoreList.searchText
}
const navigateToStoreDetails = (item: { ip_master: string; id_structure: number }) => {
// Save datatable filters state
saveDtFilters()
// go to store details
router.push(`/store/details?dbHost=${item.ip_master}&storeId=${item.id_structure}`)
}
onMounted(() => {
// Restore datatable filters state on page load
restoreDtFilters()
})
watch(route, (to, from) => {
if (from && from.path !== '/store/details')
stStoreList.clearState()
}, { immediate: true })
</script>
<template>
@ -196,6 +242,7 @@ const reloadStores = async () => {
:placeholder="$t('Search')"
density="compact"
style="inline-size: 200px;"
type="text"
class="me-3"
/>
</div>
@ -220,20 +267,27 @@ const reloadStores = async () => {
color="primary"
/>
</div>
<!-- 👉 Datatable -->
<!-- 👉 Datatable https://vuetifyjs.com/en/api/v-data-table/#props -->
<VDataTable
v-else
:headers="headers"
:items="filteredData"
:items-per-page="options.itemsPerPage"
:page="options.page"
:options="options"
:items-per-page="stStoreList.itemsPerPage"
:page="stStoreList.currentPage"
:sort-by="stStoreList.getSortBy()"
@update:sort-by="sortBy => { stStoreList.setSortBy(sortBy[0]?.key) ; stStoreList.setSortOrder(sortBy[0]?.order) }"
@update:items-per-page="itemsPerPage => { stStoreList.setItemsPerPage(itemsPerPage) }"
@update:page="page => { stStoreList.setCurrentPage(page) }"
>
<!-- Store details hyperlink -->
<template #item.nom="{ item }">
<RouterLink :to="`/store/details?dbHost=${item.ip_master}&storeId=${item.id_structure}`">
<a
href="#"
class="router-link"
@click.prevent="navigateToStoreDetails(item)"
>
{{ item.nom }}
</RouterLink>
</a>
</template>
<!-- Pos count -->

View File

@ -0,0 +1,51 @@
import type { SortItem } from '@/@core/types'
export const useDataTableStore = defineStore({
id: 'dataTable',
state: () => ({
filters: {} as Record<string, string>,
currentPage: 1,
itemsPerPage: 10,
searchText: '',
sortBy: '',
sortOrder: false,
}),
actions: {
clearState() {
this.filters = {} as Record<string, string>
this.currentPage = 1
this.itemsPerPage = 10
this.searchText = ''
this.sortBy = ''
this.sortOrder = false
},
setFilters(filterName: string, value: any) {
this.filters[filterName] = value
},
setCurrentPage(page: number) {
this.currentPage = page
},
setItemsPerPage(value: number) {
this.itemsPerPage = value
},
setSearchText(value: string) {
this.searchText = value
},
setSortBy(value: string) {
this.sortBy = value
},
setSortOrder(value: string) {
if (value === 'asc')
this.sortOrder = true
else
this.sortOrder = false
},
getSortBy(): SortItem[] {
return [{
key: this.sortBy,
order: this.sortOrder ? 'asc' : 'desc',
}]
},
},
},
)