Added dataKey for cache identifier & search redirect

This commit is contained in:
Joan Sanchez 2023-02-13 14:08:18 +01:00
parent 874db2752b
commit f9a196e7e9
8 changed files with 162 additions and 132 deletions

View File

@ -30,12 +30,12 @@ quasar.iconMapFn = (iconName) => {
const name = iconName.substring(3);
return {
cls: `icon-${name}`,
cls: `icon-${name} notranslate`,
};
}
return {
cls: 'material-symbols-outlined',
cls: 'material-symbols-outlined notranslate',
content: iconName,
};
};

View File

@ -5,7 +5,11 @@ import { useArrayData } from 'composables/useArrayData';
const { t } = useI18n();
const $props = defineProps({
const props = defineProps({
dataKey: {
type: String,
required: true,
},
autoLoad: {
type: Boolean,
default: false,
@ -43,46 +47,46 @@ const $props = defineProps({
const emit = defineEmits(['onFetch', 'onPaginate']);
const isLoading = ref(false);
const pagination = ref({
sortBy: $props.order,
rowsPerPage: $props.limit,
sortBy: props.order,
rowsPerPage: props.limit,
page: 1,
});
const arrayData = useArrayData('customers', {
url: $props.url,
filter: $props.filter,
where: $props.where,
limit: $props.limit,
order: $props.order,
const arrayData = useArrayData(props.dataKey, {
url: props.url,
filter: props.filter,
where: props.where,
limit: props.limit,
order: props.order,
});
const store = arrayData.store;
onMounted(() => {
if ($props.autoLoad) paginate();
if (props.autoLoad) paginate();
});
watch(
() => $props.data,
() => props.data,
() => {
store.data = $props.data;
store.data = props.data;
}
);
async function paginate() {
const { page, rowsPerPage, sortBy, descending } = pagination.value;
if (!$props.url) return;
if (!props.url) return;
// const filter = {
// limit: rowsPerPage,
// skip: rowsPerPage * (page - 1),
// };
// Object.assign(filter, $props.filter);
// Object.assign(filter, props.filter);
// if ($props.where) filter.where = $props.where;
// if ($props.sortBy) filter.order = $props.sortBy;
// if ($props.limit) filter.limit = $props.limit;
// if (props.where) filter.where = props.where;
// if (props.sortBy) filter.order = props.sortBy;
// if (props.limit) filter.limit = props.limit;
// if (sortBy) filter.order = sortBy;
@ -107,7 +111,7 @@ async function paginate() {
async function onLoad(...params) {
const done = params[1];
if (!store.data || store.data.length === 0 || !$props.url) return done(false);
if (!store.data || store.data.length === 0 || !props.url) return done(false);
pagination.value.page = pagination.value.page + 1;
@ -122,7 +126,10 @@ async function onLoad(...params) {
<q-infinite-scroll @load="onLoad" :offset="offset" class="column items-center">
<div v-if="store" class="card-list q-gutter-y-md">
<slot name="body" :rows="store.data"></slot>
<div v-if="!store.data.length && !isLoading" class="info-row q-pa-md text-center">
<div
v-if="!store.data.length && !isLoading"
class="info-row q-pa-md text-center"
>
<h5>
{{ t('components.smartCard.noData') }}
</h5>

View File

@ -1,33 +1,52 @@
<script setup>
import { ref } from 'vue';
import { onMounted, ref, computed } from 'vue';
import { useArrayData } from 'composables/useArrayData';
const arrayData = useArrayData('customers');
// const store = arrayData.store;
const props = defineProps({
dataKey: {
type: String,
required: true,
},
searchButton: {
type: Boolean,
required: false,
default: false,
},
});
const arrayData = useArrayData(props.dataKey);
const store = arrayData.store;
const userParams = ref({});
onMounted(() => {
const params = store.userParams;
if (params) {
userParams.value = params;
}
});
async function search() {
const params = userParams.value;
await arrayData.apply({ params });
}
// async function remove(key) {
// delete userParams.value[key];
// await search();
// }
const tags = computed(() => {
const params = [];
// const tags = computed(() => {
// const params = [];
for (const param in store.userParams) {
params.push({
label: param,
value: store.userParams[param],
});
}
// for (const param in store.userParams) {
// params.push({
// label: param,
// value: store.userParams[param],
// });
// }
return params;
});
// return params;
// });
async function remove(key) {
delete userParams.value[key];
await search();
}
</script>
<template>
<div>
@ -36,7 +55,7 @@ async function search() {
Applied filters
</q-item-label>
</q-list>
<!-- <div class="q-pa-sm truncate-chip-labels">
<div class="q-pa-sm truncate-chip-labels">
<span v-if="tags.length === 0">You didn't enter any filter</span>
<q-chip
v-for="chip of tags"
@ -51,9 +70,23 @@ async function search() {
<span>"{{ chip.value }}"</span>
</q-chip>
</div>
<q-separator /> -->
<q-form @submit="search">
<slot name="body"></slot>
<div v-show="props.searchButton">
<q-separator />
<q-item>
<q-item-section>
<q-btn
label="Search"
type="submit"
color="primary"
class="full-width"
rounded
/>
</q-item-section>
</q-item>
</div>
<q-separator />
<q-form @submit="search" @keyup.enter="search">
<slot name="body" :params="userParams"></slot>
</q-form>
</div>
</template>

View File

@ -1,16 +1,46 @@
<script setup>
import { ref } from 'vue';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useArrayData } from 'composables/useArrayData';
const arrayData = useArrayData('customers');
const props = defineProps({
dataKey: {
type: String,
required: true,
},
redirect: {
type: Boolean,
required: false,
default: true,
},
});
const searchPanel = ref();
const searchParams = ref({});
const router = useRouter();
const arrayData = useArrayData(props.dataKey);
const store = arrayData.store;
const searchText = ref();
onMounted(() => {
const params = store.userParams;
if (params && params.search) {
searchText.value = params.search;
}
});
async function search() {
await arrayData.apply({ params: searchParams.value });
await arrayData.apply({
params: {
search: searchText.value,
},
});
if (!props.redirect) return;
searchPanel.value.hide();
const rows = store.data;
if (rows.length === 1) {
const firstRow = rows[0];
router.push({ path: `/customer/${firstRow.id}` });
}
}
</script>
@ -18,8 +48,8 @@ async function search() {
<q-form @submit="search">
<q-input
id="searchbar"
v-model="searchParams.search"
label="Search"
v-model="searchText"
label="Search by customer id or name"
dense
standout
autofocus

View File

@ -1,4 +1,4 @@
import { ref, onUnmounted } from 'vue';
import { onMounted, onUnmounted, ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import axios from 'axios';
import { useArrayDataStore } from 'stores/useArrayDataStore';
@ -30,6 +30,13 @@ export function useArrayData(key, userOptions) {
// if (typeof userOptions === 'object' && userOptions.filter) {
// Object.assign(filter.value, userOptions.filter);
// }
onMounted(() => {
const query = route.query;
if (query.params) {
store.userParams = JSON.parse(query.params);
}
});
onUnmounted(() => {
if (arrayDataStore.get(key)) {
arrayDataStore.clear(key);

View File

@ -48,8 +48,16 @@ const filterOptions = {
@on-fetch="setWorkers"
auto-load
/>
<fetch-data url="ContactChannels" @on-fetch="(data) => contactChannels = data" auto-load />
<fetch-data url="BusinessTypes" @on-fetch="(data) => businessTypes = data" auto-load />
<fetch-data
url="ContactChannels"
@on-fetch="(data) => (contactChannels = data)"
auto-load
/>
<fetch-data
url="BusinessTypes"
@on-fetch="(data) => (businessTypes = data)"
auto-load
/>
<div class="container">
<q-card>
<form-model :url="`Clients/${route.params.id}`" model="customer">
@ -125,11 +133,14 @@ const filterOptions = {
:label="t('customer.basicData.salesPerson')"
map-options
use-input
@filter="(value, update) => filter(value, update, filterOptions)"
@filter="
(value, update) =>
filter(value, update, filterOptions)
"
:rules="validate('client.salesPersonFk')"
:input-debounce="0"
>
<template #before>
<template #prepend>
<q-avatar color="orange">
<q-img
v-if="data.salesPersonFk"

View File

@ -57,13 +57,13 @@ function setWorkers(data) {
auto-load
/>
<teleport-slot to="#rightPanel">
<VnFilterPanel>
<template #body>
<VnFilterPanel data-key="CustomerList">
<template #body="{ params }">
<q-list>
<q-item>
<!-- <q-item>
<q-item-section>
<q-input
v-model="userParams.search"
v-model="params.search"
label="Search by id or name"
class="full-width"
lazy-rules
@ -82,10 +82,10 @@ function setWorkers(data) {
/>
</q-item-section>
</q-item>
<q-separator />
<q-separator /> -->
<q-item>
<q-item-section>
<q-input label="Fiscal ID" v-model="userParams.fi" lazy-rules>
<q-input label="Fiscal ID" v-model="params.fi" lazy-rules>
<template #prepend>
<q-icon name="badge" size="sm"></q-icon>
</template>
@ -94,14 +94,14 @@ function setWorkers(data) {
</q-item>
<q-item>
<q-item-section>
<q-input label="Name" v-model="userParams.name" lazy-rules />
<q-input label="Name" v-model="params.name" lazy-rules />
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-input
label="Social name"
v-model="userParams.socialName"
v-model="params.socialName"
lazy-rules
/>
</q-item-section>
@ -109,7 +109,7 @@ function setWorkers(data) {
<q-item>
<q-item-section>
<q-select
v-model="userParams.salesPersonFk"
v-model="params.salesPersonFk"
:options="workers"
option-value="id"
option-label="name"
@ -122,8 +122,8 @@ function setWorkers(data) {
<template #prepend>
<q-avatar color="orange" size="xs">
<q-img
v-if="userParams.salesPersonFk"
:src="`/api/Images/user/160x160/${userParams.salesPersonFk}/download?access_token=${token}`"
v-if="params.salesPersonFk"
:src="`/api/Images/user/160x160/${params.salesPersonFk}/download?access_token=${token}`"
spinner-color="white"
/>
</q-avatar>
@ -133,7 +133,7 @@ function setWorkers(data) {
</q-item>
<q-item>
<q-item-section>
<q-input label="Phone" v-model="userParams.phone" lazy-rules>
<q-input label="Phone" v-model="params.phone" lazy-rules>
<template #prepend>
<q-icon name="phone" size="sm"></q-icon>
</template>
@ -142,7 +142,7 @@ function setWorkers(data) {
</q-item>
<q-item>
<q-item-section>
<q-input label="Email" v-model="userParams.email" lazy-rules>
<q-input label="Email" v-model="params.email" lazy-rules>
<template #prepend>
<q-icon name="email" size="sm"></q-icon>
</template>
@ -153,7 +153,7 @@ function setWorkers(data) {
<q-item-section>
<q-select
label="Province"
v-model="userParams.provinceFk"
v-model="params.provinceFk"
:options="provinces"
option-value="id"
option-label="name"
@ -162,14 +162,14 @@ function setWorkers(data) {
/>
</q-item-section>
<q-item-section>
<q-input label="City" v-model="userParams.city" lazy-rules />
<q-input label="City" v-model="params.city" lazy-rules />
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-select
label="Zone"
v-model="userParams.zoneFk"
v-model="params.zoneFk"
:options="zones"
option-value="id"
option-label="name"
@ -180,7 +180,7 @@ function setWorkers(data) {
<q-item-section>
<q-input
label="Postcode"
v-model="userParams.postcode"
v-model="params.postcode"
lazy-rules
/>
</q-item-section>
@ -190,7 +190,7 @@ function setWorkers(data) {
</VnFilterPanel>
</teleport-slot>
<q-page class="q-pa-md">
<paginate url="/Clients/filter" order="id DESC" auto-load>
<paginate data-key="CustomerList" url="/Clients/filter" order="id DESC" auto-load>
<template #body="{ rows }">
<q-card class="card" v-for="row of rows" :key="row.id">
<q-item

View File

@ -1,5 +1,4 @@
<script setup>
// import { useSession } from 'src/composables/useSession';
import { useStateStore } from 'stores/useStateStore';
import LeftMenu from 'components/LeftMenu.vue';
import TeleportSlot from 'components/ui/TeleportSlot.vue';
@ -7,68 +6,11 @@ import CustomerSearch from './CustomerSearch.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
const stateStore = useStateStore();
// const arrayData = useArrayData('customers');
// const session = useSession();
// const token = session.getToken();
// const searchBackdrop = ref(false);
// const searchPanel = ref();
// const userParams = reactive({});
// const tags = computed(() => {
// const params = [];
// for (const param in userParams) {
// params.push({
// label: param,
// value: userParams[param],
// });
// }
// return params;
// });
// async function doSearch() {
// // let filter = {};
// // if (search.value != '') {
// // filter = {
// // where: {
// // id: search.value,
// // },
// // };
// // }
// const params = userParams;
// await arrayData.apply({ params });
// searchPanel.value.hide();
// }
// const searchRows = ref([])
// async function pre(value) {
// let filter = {};
// if (value != '') {
// filter = {
// where: {
// id: value,
// },
// };
// }
// console.log(filter)
// const rows = await arrayData.request({ userFilter: filter });
// searchRows.value = rows
// }
// function searchParams(params) {
// switch (params) {
// }
// }
</script>
<template>
<teleport-slot to="#searchbar">
<VnSearchbar data-key="customerList">
<VnSearchbar data-key="CustomerList">
<template #panel="{ scope }">
<customer-search :scope="scope" />
</template>