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"> <script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'
import { VDataTable } from 'vuetify/labs/VDataTable' import { VDataTable } from 'vuetify/labs/VDataTable'
import { useDataTableStore } from '@/stores/datatable.store'
const { t } = useI18n() const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const headers = computed(() => [ const headers = computed(() => [
{ title: 'ID', key: 'id_structure' }, { title: 'ID', key: 'id_structure' },
@ -30,8 +34,6 @@ const { data: dtListData } = await useApi<any>(createUrl('/stores'))
storesList.value = dtListData.value storesList.value = dtListData.value
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
const country = computed(() => { const country = computed(() => {
const allItems = storesList.value.map((store: { pays: any }) => store.pays) const allItems = storesList.value.map((store: { pays: any }) => store.pays)
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
@ -68,9 +70,11 @@ const filteredData = computed(() => {
if (selectedBrand.value) if (selectedBrand.value)
filtered = filtered.filter((store: { enseigne: any }) => store.enseigne === 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) if (selectedCountry.value)
filtered = filtered.filter((store: { pays: any }) => store.pays === 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) if (selectedNbPos.value)
filtered = filtered.filter((store: { nbcaisses: any }) => store.nbcaisses === selectedNbPos.value) filtered = filtered.filter((store: { nbcaisses: any }) => store.nbcaisses === selectedNbPos.value)
@ -121,6 +125,48 @@ const reloadStores = async () => {
isLoading.value = false 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> </script>
<template> <template>
@ -196,6 +242,7 @@ const reloadStores = async () => {
:placeholder="$t('Search')" :placeholder="$t('Search')"
density="compact" density="compact"
style="inline-size: 200px;" style="inline-size: 200px;"
type="text"
class="me-3" class="me-3"
/> />
</div> </div>
@ -220,20 +267,27 @@ const reloadStores = async () => {
color="primary" color="primary"
/> />
</div> </div>
<!-- 👉 Datatable --> <!-- 👉 Datatable https://vuetifyjs.com/en/api/v-data-table/#props -->
<VDataTable <VDataTable
v-else v-else
:headers="headers" :headers="headers"
:items="filteredData" :items="filteredData"
:items-per-page="options.itemsPerPage" :items-per-page="stStoreList.itemsPerPage"
:page="options.page" :page="stStoreList.currentPage"
:options="options" :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 --> <!-- Store details hyperlink -->
<template #item.nom="{ item }"> <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 }} {{ item.nom }}
</RouterLink> </a>
</template> </template>
<!-- Pos count --> <!-- 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',
}]
},
},
},
)