Added dataKey for cache identifier & search redirect
This commit is contained in:
parent
874db2752b
commit
f9a196e7e9
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue