fix: refs #8691 proposal split core
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
commit
af9eb19658
|
@ -0,0 +1,384 @@
|
||||||
|
import { onMounted, computed } from 'vue';
|
||||||
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
||||||
|
import { buildFilter } from 'filters/filterPanel';
|
||||||
|
import { isDialogOpened } from 'src/filters';
|
||||||
|
|
||||||
|
const arrayDataStore = useArrayDataStore();
|
||||||
|
|
||||||
|
export function arrayDataCore(key, userOptions) {
|
||||||
|
let route = null;
|
||||||
|
let router = null;
|
||||||
|
|
||||||
|
// Si no hay key, intentamos obtenerla del route
|
||||||
|
if (!key) {
|
||||||
|
key = initialRoute?.meta?.moduleName;
|
||||||
|
route = initialRoute;
|
||||||
|
router = initialRouter;
|
||||||
|
}
|
||||||
|
if (!key) throw new Error('ArrayData: A key is required to use this composable');
|
||||||
|
|
||||||
|
if (!arrayDataStore.get(key)) arrayDataStore.set(key);
|
||||||
|
|
||||||
|
const store = arrayDataStore.get(key);
|
||||||
|
let canceller = null;
|
||||||
|
|
||||||
|
const { route: initialRoute, router: initialRouter } = (() => {
|
||||||
|
if (!route) route = useRoute();
|
||||||
|
if (!router) router = useRouter();
|
||||||
|
return { route, router };
|
||||||
|
})();
|
||||||
|
function setupMountedHook() {
|
||||||
|
setOptions();
|
||||||
|
reset(['skip']);
|
||||||
|
route = initialRoute;
|
||||||
|
router = initialRouter;
|
||||||
|
const searchUrl = store.searchUrl;
|
||||||
|
const query = route.query[searchUrl];
|
||||||
|
if (query) {
|
||||||
|
const params = JSON.parse(query);
|
||||||
|
const filter =
|
||||||
|
params?.filter && typeof params?.filter == 'object'
|
||||||
|
? params?.filter
|
||||||
|
: JSON.parse(params?.filter ?? '{}');
|
||||||
|
delete params.filter;
|
||||||
|
|
||||||
|
store.userParams = params;
|
||||||
|
store.filter = { ...filter, ...store.userFilter };
|
||||||
|
if (filter?.order) store.order = filter.order;
|
||||||
|
}
|
||||||
|
setCurrentFilter();
|
||||||
|
}
|
||||||
|
if (key && userOptions) setOptions();
|
||||||
|
|
||||||
|
function setOptions() {
|
||||||
|
const allowedOptions = [
|
||||||
|
'url',
|
||||||
|
'filter',
|
||||||
|
'where',
|
||||||
|
'order',
|
||||||
|
'limit',
|
||||||
|
'skip',
|
||||||
|
'userParams',
|
||||||
|
'userFilter',
|
||||||
|
'exprBuilder',
|
||||||
|
'searchUrl',
|
||||||
|
'navigate',
|
||||||
|
'mapKey',
|
||||||
|
'keepData',
|
||||||
|
'oneRecord',
|
||||||
|
];
|
||||||
|
if (typeof userOptions === 'object') {
|
||||||
|
for (const option in userOptions) {
|
||||||
|
const isEmpty = userOptions[option] == null || userOptions[option] === '';
|
||||||
|
if (isEmpty || !allowedOptions.includes(option)) continue;
|
||||||
|
|
||||||
|
if (Object.hasOwn(store, option)) {
|
||||||
|
const defaultOpts = userOptions[option];
|
||||||
|
store[option] = userOptions.keepOpts?.includes(option)
|
||||||
|
? Object.assign(defaultOpts, store[option])
|
||||||
|
: defaultOpts;
|
||||||
|
if (option === 'userParams') store.defaultParams = store[option];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetch({ append = false, updateRouter = true }) {
|
||||||
|
if (!store.url) return;
|
||||||
|
|
||||||
|
cancelRequest();
|
||||||
|
canceller = new AbortController();
|
||||||
|
const { params, limit } = setCurrentFilter();
|
||||||
|
|
||||||
|
let exprFilter;
|
||||||
|
if (store?.exprBuilder) {
|
||||||
|
exprFilter = buildFilter(params, (param, value) => {
|
||||||
|
if (param == 'filter') return;
|
||||||
|
const res = store.exprBuilder(param, value);
|
||||||
|
if (res) delete params[param];
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.filter.where || exprFilter)
|
||||||
|
params.filter.where = { ...params.filter.where, ...exprFilter };
|
||||||
|
|
||||||
|
if (!params?.filter?.order?.length) delete params?.filter?.order;
|
||||||
|
|
||||||
|
params.filter = JSON.stringify(params.filter);
|
||||||
|
|
||||||
|
store.isLoading = true;
|
||||||
|
const response = await axios.get(store.url, {
|
||||||
|
signal: canceller.signal,
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
|
||||||
|
store.hasMoreData = limit && response.data.length >= limit;
|
||||||
|
|
||||||
|
if (!append && !isDialogOpened() && updateRouter) {
|
||||||
|
if (updateStateParams(response.data)?.redirect && !store.keepData) return;
|
||||||
|
}
|
||||||
|
store.isLoading = false;
|
||||||
|
canceller = null;
|
||||||
|
|
||||||
|
processData(response.data, {
|
||||||
|
map: !!store.mapKey,
|
||||||
|
append,
|
||||||
|
oneRecord: store.oneRecord,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy() {
|
||||||
|
if (arrayDataStore.get(key)) {
|
||||||
|
arrayDataStore.clear(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteOption(option) {
|
||||||
|
delete store[option];
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset(opts = []) {
|
||||||
|
if (arrayDataStore.get(key)) arrayDataStore.reset(key, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetPagination() {
|
||||||
|
if (arrayDataStore.get(key)) arrayDataStore.resetPagination(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelRequest() {
|
||||||
|
if (canceller) {
|
||||||
|
canceller.abort();
|
||||||
|
canceller = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyFilter({ filter, params }, fetchOptions = {}) {
|
||||||
|
if (filter) store.filter = filter;
|
||||||
|
if (params) store.userParams = { ...params };
|
||||||
|
|
||||||
|
const response = await fetch(fetchOptions);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addFilter({ filter, params }) {
|
||||||
|
if (filter) store.filter = filter;
|
||||||
|
|
||||||
|
let userParams = { ...store.userParams, ...params };
|
||||||
|
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
||||||
|
|
||||||
|
store.userParams = userParams;
|
||||||
|
resetPagination();
|
||||||
|
|
||||||
|
await fetch({});
|
||||||
|
return { filter, params };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addFilterWhere(where) {
|
||||||
|
const storedFilter = { ...store.filter };
|
||||||
|
if (!storedFilter?.where) storedFilter.where = {};
|
||||||
|
where = { ...storedFilter.where, ...where };
|
||||||
|
await addFilter({ filter: { where } });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addOrder(field, direction = 'ASC') {
|
||||||
|
const newOrder = field + ' ' + direction;
|
||||||
|
const order = toArray(store.order);
|
||||||
|
|
||||||
|
let index = getOrderIndex(order, field);
|
||||||
|
if (index > -1) {
|
||||||
|
order[index] = newOrder;
|
||||||
|
} else {
|
||||||
|
index = order.length;
|
||||||
|
order.push(newOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.order = order;
|
||||||
|
resetPagination();
|
||||||
|
fetch({});
|
||||||
|
index++;
|
||||||
|
|
||||||
|
return { index, order };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteOrder(field) {
|
||||||
|
const order = toArray(store.order);
|
||||||
|
const index = getOrderIndex(order, field);
|
||||||
|
if (index > -1) order.splice(index, 1);
|
||||||
|
|
||||||
|
store.order = order;
|
||||||
|
fetch({});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOrderIndex(order, field) {
|
||||||
|
return order.findIndex((o) => o.split(' ')[0] === field);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toArray(str = []) {
|
||||||
|
if (!str) return [];
|
||||||
|
if (Array.isArray(str)) return str;
|
||||||
|
if (typeof str === 'string') return str.split(',').map((item) => item.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizerParams(params, exprBuilder) {
|
||||||
|
for (const param in params) {
|
||||||
|
if (params[param] === '' || params[param] === null) {
|
||||||
|
delete store.userParams[param];
|
||||||
|
delete params[param];
|
||||||
|
if (store.filter?.where) {
|
||||||
|
let key;
|
||||||
|
if (exprBuilder) {
|
||||||
|
const result = exprBuilder(param);
|
||||||
|
if (result !== undefined && result !== null)
|
||||||
|
key = Object.keys(result);
|
||||||
|
} else {
|
||||||
|
if (typeof param === 'object' && param !== null)
|
||||||
|
key = Object.keys(param);
|
||||||
|
}
|
||||||
|
if (key && key[0]) {
|
||||||
|
delete store.filter.where[key[0]];
|
||||||
|
if (Object.keys(store.filter.where).length === 0) {
|
||||||
|
delete store.filter.where;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadMore() {
|
||||||
|
if (!store.hasMoreData) return;
|
||||||
|
|
||||||
|
store.skip = (store?.filter?.limit ?? store.limit) * store.page;
|
||||||
|
store.page += 1;
|
||||||
|
|
||||||
|
await fetch({ append: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
if (Object.values(store.userParams).length) await fetch({});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStateParams(data) {
|
||||||
|
if (!route?.path) return;
|
||||||
|
const newUrl = { path: route.path, query: { ...(route.query ?? {}) } };
|
||||||
|
if (store?.searchUrl)
|
||||||
|
newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter);
|
||||||
|
|
||||||
|
if (store.navigate) {
|
||||||
|
const { customRouteRedirectName, searchText } = store.navigate;
|
||||||
|
if (customRouteRedirectName)
|
||||||
|
return router.push({
|
||||||
|
name: customRouteRedirectName,
|
||||||
|
params: { id: searchText },
|
||||||
|
});
|
||||||
|
const { matched: matches } = router.currentRoute.value;
|
||||||
|
const { path } = matches.at(-1);
|
||||||
|
|
||||||
|
const to =
|
||||||
|
data?.length === 1
|
||||||
|
? path.replace(/\/(list|:id)|-list/, `/${data[0].id}`)
|
||||||
|
: path.replace(/:id.*/, '');
|
||||||
|
|
||||||
|
if (route.path != to) {
|
||||||
|
const pushUrl = { path: to };
|
||||||
|
if (to.endsWith('/list') || to.endsWith('/'))
|
||||||
|
pushUrl.query = newUrl.query;
|
||||||
|
return router.push(pushUrl) && { redirect: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
router.replace(newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentFilter() {
|
||||||
|
if (!Object.keys(store.userParams).length)
|
||||||
|
store.userParams = store.defaultParams ?? {};
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
limit: store.limit,
|
||||||
|
...store.userFilter,
|
||||||
|
};
|
||||||
|
|
||||||
|
let where;
|
||||||
|
if (filter?.where || store.filter?.where)
|
||||||
|
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
||||||
|
Object.assign(filter, store.filter);
|
||||||
|
filter.where = where;
|
||||||
|
const params = { filter };
|
||||||
|
|
||||||
|
Object.assign(params, store.userParams);
|
||||||
|
if (params.filter) params.filter.skip = store.skip;
|
||||||
|
if (store.order) params.filter.order = toArray(store.order);
|
||||||
|
else delete params.filter.order;
|
||||||
|
|
||||||
|
return { filter, params, limit: filter.limit };
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCurrentFilter() {
|
||||||
|
const { params, limit } = getCurrentFilter();
|
||||||
|
store.currentFilter = JSON.parse(JSON.stringify(params));
|
||||||
|
delete store.currentFilter.filter.include;
|
||||||
|
store.currentFilter.filter = JSON.stringify(store.currentFilter.filter);
|
||||||
|
return { params, limit };
|
||||||
|
}
|
||||||
|
|
||||||
|
function processData(data, { map = true, append = true, oneRecord = false }) {
|
||||||
|
if (oneRecord) {
|
||||||
|
store.data = Array.isArray(data) ? data[0] : data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!append) {
|
||||||
|
store.data = [];
|
||||||
|
store.map = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(data)) store.data = data;
|
||||||
|
else if (!map && append) for (const row of data) store.data.push(row);
|
||||||
|
else
|
||||||
|
for (const row of data) {
|
||||||
|
const key = row[store.mapKey];
|
||||||
|
const val = { ...row, key };
|
||||||
|
if (key && store.map.has(key)) {
|
||||||
|
const { position } = store.map.get(key);
|
||||||
|
val.position = position;
|
||||||
|
store.map.set(key, val);
|
||||||
|
store.data[position] = val;
|
||||||
|
} else {
|
||||||
|
val.position = store.map.size;
|
||||||
|
store.map.set(key, val);
|
||||||
|
store.data.push(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalRows = computed(() => (store.data && store.data.length) || 0);
|
||||||
|
const isLoading = computed(() => store.isLoading || false);
|
||||||
|
|
||||||
|
return {
|
||||||
|
setupMountedHook,
|
||||||
|
fetch,
|
||||||
|
applyFilter,
|
||||||
|
addFilter,
|
||||||
|
getCurrentFilter,
|
||||||
|
setCurrentFilter,
|
||||||
|
addFilterWhere,
|
||||||
|
addOrder,
|
||||||
|
deleteOrder,
|
||||||
|
refresh,
|
||||||
|
destroy,
|
||||||
|
loadMore,
|
||||||
|
store,
|
||||||
|
totalRows,
|
||||||
|
updateStateParams,
|
||||||
|
isLoading,
|
||||||
|
deleteOption,
|
||||||
|
reset,
|
||||||
|
resetPagination,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,373 +1,7 @@
|
||||||
import { onMounted, computed } from 'vue';
|
import { arrayDataCore } from './arrayDataCore';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
|
||||||
import axios from 'axios';
|
|
||||||
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
|
||||||
import { buildFilter } from 'filters/filterPanel';
|
|
||||||
import { isDialogOpened } from 'src/filters';
|
|
||||||
|
|
||||||
const arrayDataStore = useArrayDataStore();
|
export function useArrayData(key, options) {
|
||||||
|
const arrayData = arrayDataCore(key, options);
|
||||||
export function useArrayData(key, userOptions) {
|
arrayData.setupMountedHook();
|
||||||
key ??= useRoute().meta.moduleName;
|
return arrayData;
|
||||||
|
|
||||||
if (!key) throw new Error('ArrayData: A key is required to use this composable');
|
|
||||||
|
|
||||||
if (!arrayDataStore.get(key)) arrayDataStore.set(key);
|
|
||||||
|
|
||||||
const store = arrayDataStore.get(key);
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
let canceller = null;
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
setOptions();
|
|
||||||
reset(['skip']);
|
|
||||||
|
|
||||||
const query = route.query;
|
|
||||||
const searchUrl = store.searchUrl;
|
|
||||||
if (query[searchUrl]) {
|
|
||||||
const params = JSON.parse(query[searchUrl]);
|
|
||||||
const filter =
|
|
||||||
params?.filter && typeof params?.filter == 'object'
|
|
||||||
? params?.filter
|
|
||||||
: JSON.parse(params?.filter ?? '{}');
|
|
||||||
delete params.filter;
|
|
||||||
|
|
||||||
store.userParams = params;
|
|
||||||
store.filter = { ...filter, ...store.userFilter };
|
|
||||||
if (filter?.order) store.order = filter.order;
|
|
||||||
}
|
|
||||||
setCurrentFilter();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (key && userOptions) setOptions();
|
|
||||||
|
|
||||||
function setOptions() {
|
|
||||||
const allowedOptions = [
|
|
||||||
'url',
|
|
||||||
'filter',
|
|
||||||
'where',
|
|
||||||
'order',
|
|
||||||
'limit',
|
|
||||||
'skip',
|
|
||||||
'userParams',
|
|
||||||
'userFilter',
|
|
||||||
'exprBuilder',
|
|
||||||
'searchUrl',
|
|
||||||
'navigate',
|
|
||||||
'mapKey',
|
|
||||||
'keepData',
|
|
||||||
'oneRecord',
|
|
||||||
];
|
|
||||||
if (typeof userOptions === 'object') {
|
|
||||||
for (const option in userOptions) {
|
|
||||||
const isEmpty = userOptions[option] == null || userOptions[option] === '';
|
|
||||||
if (isEmpty || !allowedOptions.includes(option)) continue;
|
|
||||||
|
|
||||||
if (Object.hasOwn(store, option)) {
|
|
||||||
const defaultOpts = userOptions[option];
|
|
||||||
store[option] = userOptions.keepOpts?.includes(option)
|
|
||||||
? Object.assign(defaultOpts, store[option])
|
|
||||||
: defaultOpts;
|
|
||||||
if (option === 'userParams') store.defaultParams = store[option];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetch({ append = false, updateRouter = true }) {
|
|
||||||
if (!store.url) return;
|
|
||||||
|
|
||||||
cancelRequest();
|
|
||||||
canceller = new AbortController();
|
|
||||||
const { params, limit } = setCurrentFilter();
|
|
||||||
|
|
||||||
let exprFilter;
|
|
||||||
if (store?.exprBuilder) {
|
|
||||||
exprFilter = buildFilter(params, (param, value) => {
|
|
||||||
if (param == 'filter') return;
|
|
||||||
const res = store.exprBuilder(param, value);
|
|
||||||
if (res) delete params[param];
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.filter.where || exprFilter)
|
|
||||||
params.filter.where = { ...params.filter.where, ...exprFilter };
|
|
||||||
|
|
||||||
if (!params?.filter?.order?.length) delete params?.filter?.order;
|
|
||||||
|
|
||||||
params.filter = JSON.stringify(params.filter);
|
|
||||||
|
|
||||||
store.isLoading = true;
|
|
||||||
const response = await axios.get(store.url, {
|
|
||||||
signal: canceller.signal,
|
|
||||||
params,
|
|
||||||
});
|
|
||||||
|
|
||||||
store.hasMoreData = limit && response.data.length >= limit;
|
|
||||||
|
|
||||||
if (!append && !isDialogOpened() && updateRouter) {
|
|
||||||
if (updateStateParams(response.data)?.redirect && !store.keepData) return;
|
|
||||||
}
|
|
||||||
store.isLoading = false;
|
|
||||||
canceller = null;
|
|
||||||
|
|
||||||
processData(response.data, {
|
|
||||||
map: !!store.mapKey,
|
|
||||||
append,
|
|
||||||
oneRecord: store.oneRecord,
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy() {
|
|
||||||
if (arrayDataStore.get(key)) {
|
|
||||||
arrayDataStore.clear(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteOption(option) {
|
|
||||||
delete store[option];
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset(opts = []) {
|
|
||||||
if (arrayDataStore.get(key)) arrayDataStore.reset(key, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetPagination() {
|
|
||||||
if (arrayDataStore.get(key)) arrayDataStore.resetPagination(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancelRequest() {
|
|
||||||
if (canceller) {
|
|
||||||
canceller.abort();
|
|
||||||
canceller = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function applyFilter({ filter, params }, fetchOptions = {}) {
|
|
||||||
if (filter) store.filter = filter;
|
|
||||||
if (params) store.userParams = { ...params };
|
|
||||||
|
|
||||||
const response = await fetch(fetchOptions);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addFilter({ filter, params }) {
|
|
||||||
if (filter) store.filter = filter;
|
|
||||||
|
|
||||||
let userParams = { ...store.userParams, ...params };
|
|
||||||
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
|
||||||
|
|
||||||
store.userParams = userParams;
|
|
||||||
resetPagination();
|
|
||||||
|
|
||||||
await fetch({});
|
|
||||||
return { filter, params };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addFilterWhere(where) {
|
|
||||||
const storedFilter = { ...store.filter };
|
|
||||||
if (!storedFilter?.where) storedFilter.where = {};
|
|
||||||
where = { ...storedFilter.where, ...where };
|
|
||||||
await addFilter({ filter: { where } });
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addOrder(field, direction = 'ASC') {
|
|
||||||
const newOrder = field + ' ' + direction;
|
|
||||||
const order = toArray(store.order);
|
|
||||||
|
|
||||||
let index = getOrderIndex(order, field);
|
|
||||||
if (index > -1) {
|
|
||||||
order[index] = newOrder;
|
|
||||||
} else {
|
|
||||||
index = order.length;
|
|
||||||
order.push(newOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
store.order = order;
|
|
||||||
resetPagination();
|
|
||||||
fetch({});
|
|
||||||
index++;
|
|
||||||
|
|
||||||
return { index, order };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteOrder(field) {
|
|
||||||
const order = toArray(store.order);
|
|
||||||
const index = getOrderIndex(order, field);
|
|
||||||
if (index > -1) order.splice(index, 1);
|
|
||||||
|
|
||||||
store.order = order;
|
|
||||||
fetch({});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOrderIndex(order, field) {
|
|
||||||
return order.findIndex((o) => o.split(' ')[0] === field);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toArray(str = []) {
|
|
||||||
if (!str) return [];
|
|
||||||
if (Array.isArray(str)) return str;
|
|
||||||
if (typeof str === 'string') return str.split(',').map((item) => item.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
function sanitizerParams(params, exprBuilder) {
|
|
||||||
for (const param in params) {
|
|
||||||
if (params[param] === '' || params[param] === null) {
|
|
||||||
delete store.userParams[param];
|
|
||||||
delete params[param];
|
|
||||||
if (store.filter?.where) {
|
|
||||||
let key;
|
|
||||||
if (exprBuilder) {
|
|
||||||
const result = exprBuilder(param);
|
|
||||||
if (result !== undefined && result !== null)
|
|
||||||
key = Object.keys(result);
|
|
||||||
} else {
|
|
||||||
if (typeof param === 'object' && param !== null)
|
|
||||||
key = Object.keys(param);
|
|
||||||
}
|
|
||||||
if (key && key[0]) {
|
|
||||||
delete store.filter.where[key[0]];
|
|
||||||
if (Object.keys(store.filter.where).length === 0) {
|
|
||||||
delete store.filter.where;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadMore() {
|
|
||||||
if (!store.hasMoreData) return;
|
|
||||||
|
|
||||||
store.skip = (store?.filter?.limit ?? store.limit) * store.page;
|
|
||||||
store.page += 1;
|
|
||||||
|
|
||||||
await fetch({ append: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
async function refresh() {
|
|
||||||
if (Object.values(store.userParams).length) await fetch({});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStateParams(data) {
|
|
||||||
if (!route?.path) return;
|
|
||||||
const newUrl = { path: route.path, query: { ...(route.query ?? {}) } };
|
|
||||||
if (store?.searchUrl)
|
|
||||||
newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter);
|
|
||||||
|
|
||||||
if (store.navigate) {
|
|
||||||
const { customRouteRedirectName, searchText } = store.navigate;
|
|
||||||
if (customRouteRedirectName)
|
|
||||||
return router.push({
|
|
||||||
name: customRouteRedirectName,
|
|
||||||
params: { id: searchText },
|
|
||||||
});
|
|
||||||
const { matched: matches } = router.currentRoute.value;
|
|
||||||
const { path } = matches.at(-1);
|
|
||||||
|
|
||||||
const to =
|
|
||||||
data?.length === 1
|
|
||||||
? path.replace(/\/(list|:id)|-list/, `/${data[0].id}`)
|
|
||||||
: path.replace(/:id.*/, '');
|
|
||||||
|
|
||||||
if (route.path != to) {
|
|
||||||
const pushUrl = { path: to };
|
|
||||||
if (to.endsWith('/list') || to.endsWith('/'))
|
|
||||||
pushUrl.query = newUrl.query;
|
|
||||||
return router.push(pushUrl) && { redirect: true };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
router.replace(newUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentFilter() {
|
|
||||||
if (!Object.keys(store.userParams).length)
|
|
||||||
store.userParams = store.defaultParams ?? {};
|
|
||||||
|
|
||||||
const filter = {
|
|
||||||
limit: store.limit,
|
|
||||||
...store.userFilter,
|
|
||||||
};
|
|
||||||
|
|
||||||
let where;
|
|
||||||
if (filter?.where || store.filter?.where)
|
|
||||||
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
|
||||||
Object.assign(filter, store.filter);
|
|
||||||
filter.where = where;
|
|
||||||
const params = { filter };
|
|
||||||
|
|
||||||
Object.assign(params, store.userParams);
|
|
||||||
if (params.filter) params.filter.skip = store.skip;
|
|
||||||
if (store.order) params.filter.order = toArray(store.order);
|
|
||||||
else delete params.filter.order;
|
|
||||||
|
|
||||||
return { filter, params, limit: filter.limit };
|
|
||||||
}
|
|
||||||
|
|
||||||
function setCurrentFilter() {
|
|
||||||
const { params, limit } = getCurrentFilter();
|
|
||||||
store.currentFilter = JSON.parse(JSON.stringify(params));
|
|
||||||
delete store.currentFilter.filter.include;
|
|
||||||
store.currentFilter.filter = JSON.stringify(store.currentFilter.filter);
|
|
||||||
return { params, limit };
|
|
||||||
}
|
|
||||||
|
|
||||||
function processData(data, { map = true, append = true, oneRecord = false }) {
|
|
||||||
if (oneRecord) {
|
|
||||||
store.data = Array.isArray(data) ? data[0] : data;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!append) {
|
|
||||||
store.data = [];
|
|
||||||
store.map = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Array.isArray(data)) store.data = data;
|
|
||||||
else if (!map && append) for (const row of data) store.data.push(row);
|
|
||||||
else
|
|
||||||
for (const row of data) {
|
|
||||||
const key = row[store.mapKey];
|
|
||||||
const val = { ...row, key };
|
|
||||||
if (key && store.map.has(key)) {
|
|
||||||
const { position } = store.map.get(key);
|
|
||||||
val.position = position;
|
|
||||||
store.map.set(key, val);
|
|
||||||
store.data[position] = val;
|
|
||||||
} else {
|
|
||||||
val.position = store.map.size;
|
|
||||||
store.map.set(key, val);
|
|
||||||
store.data.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalRows = computed(() => (store.data && store.data.length) || 0);
|
|
||||||
const isLoading = computed(() => store.isLoading || false);
|
|
||||||
|
|
||||||
return {
|
|
||||||
fetch,
|
|
||||||
applyFilter,
|
|
||||||
addFilter,
|
|
||||||
getCurrentFilter,
|
|
||||||
setCurrentFilter,
|
|
||||||
addFilterWhere,
|
|
||||||
addOrder,
|
|
||||||
deleteOrder,
|
|
||||||
refresh,
|
|
||||||
destroy,
|
|
||||||
loadMore,
|
|
||||||
store,
|
|
||||||
totalRows,
|
|
||||||
updateStateParams,
|
|
||||||
isLoading,
|
|
||||||
deleteOption,
|
|
||||||
reset,
|
|
||||||
resetPagination,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue