2023-03-01 15:20:28 +00:00
|
|
|
import { onMounted, ref, computed } from 'vue';
|
2023-01-14 12:48:57 +00:00
|
|
|
import { useRouter, useRoute } from 'vue-router';
|
2023-01-05 13:57:47 +00:00
|
|
|
import axios from 'axios';
|
|
|
|
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
|
|
|
|
|
|
|
const arrayDataStore = useArrayDataStore();
|
|
|
|
|
|
|
|
export function useArrayData(key, userOptions) {
|
|
|
|
if (!key) throw new Error('ArrayData: A key is required to use this composable');
|
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
if (!arrayDataStore.get(key)) {
|
|
|
|
arrayDataStore.set(key);
|
|
|
|
}
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
const store = arrayDataStore.get(key);
|
2023-02-14 13:59:39 +00:00
|
|
|
const hasMoreData = ref(false);
|
2023-01-14 12:48:57 +00:00
|
|
|
const router = useRouter();
|
|
|
|
const route = useRoute();
|
2023-02-23 14:01:40 +00:00
|
|
|
let canceller = null;
|
2023-01-14 12:48:57 +00:00
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
const page = ref(1);
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-02-13 13:08:18 +00:00
|
|
|
onMounted(() => {
|
2023-03-15 10:28:18 +00:00
|
|
|
setOptions();
|
2023-03-13 09:07:52 +00:00
|
|
|
|
2023-02-13 13:08:18 +00:00
|
|
|
const query = route.query;
|
|
|
|
if (query.params) {
|
|
|
|
store.userParams = JSON.parse(query.params);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-03-13 09:07:52 +00:00
|
|
|
function setOptions() {
|
2023-03-21 08:49:47 +00:00
|
|
|
const allowedOptions = [
|
|
|
|
'url',
|
|
|
|
'filter',
|
|
|
|
'where',
|
|
|
|
'order',
|
|
|
|
'limit',
|
|
|
|
'skip',
|
|
|
|
'userParams',
|
2023-09-27 11:41:50 +00:00
|
|
|
'userFilter',
|
2023-03-21 08:49:47 +00:00
|
|
|
];
|
2023-03-13 09:07:52 +00:00
|
|
|
if (typeof userOptions === 'object') {
|
|
|
|
for (const option in userOptions) {
|
2023-09-27 11:41:50 +00:00
|
|
|
const isEmpty = userOptions[option] == null || userOptions[option] == '';
|
2023-03-21 08:49:47 +00:00
|
|
|
if (isEmpty || !allowedOptions.includes(option)) continue;
|
2023-03-15 10:28:18 +00:00
|
|
|
|
2023-03-13 09:07:52 +00:00
|
|
|
if (Object.prototype.hasOwnProperty.call(store, option)) {
|
|
|
|
store[option] = userOptions[option];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
async function fetch({ append = false }) {
|
2023-01-14 12:48:57 +00:00
|
|
|
if (!store.url) return;
|
2023-01-10 13:58:24 +00:00
|
|
|
|
2023-02-23 14:01:40 +00:00
|
|
|
cancelRequest();
|
|
|
|
canceller = new AbortController();
|
|
|
|
|
2023-01-14 12:48:57 +00:00
|
|
|
const filter = {
|
|
|
|
order: store.order,
|
|
|
|
limit: store.limit,
|
|
|
|
skip: store.skip,
|
2023-01-05 13:57:47 +00:00
|
|
|
};
|
|
|
|
|
2023-01-14 12:48:57 +00:00
|
|
|
Object.assign(filter, store.userFilter);
|
2023-03-01 15:20:28 +00:00
|
|
|
Object.assign(store.filter, filter);
|
2023-01-10 13:58:24 +00:00
|
|
|
|
2023-01-17 13:57:12 +00:00
|
|
|
const params = {
|
2023-03-06 13:29:21 +00:00
|
|
|
filter: JSON.stringify(store.filter),
|
2023-01-17 13:57:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Object.assign(params, store.userParams);
|
|
|
|
|
2023-09-27 11:41:50 +00:00
|
|
|
store.isLoading = true;
|
2023-02-23 14:01:40 +00:00
|
|
|
const response = await axios.get(store.url, {
|
|
|
|
signal: canceller.signal,
|
|
|
|
params,
|
|
|
|
});
|
2023-09-29 11:59:06 +00:00
|
|
|
|
2023-01-14 12:48:57 +00:00
|
|
|
const { limit } = filter;
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
hasMoreData.value = response.data.length === limit;
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
if (append === true) {
|
2023-03-01 15:20:28 +00:00
|
|
|
if (!store.data) store.data = [];
|
2023-01-10 13:58:24 +00:00
|
|
|
for (const row of response.data) store.data.push(row);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (append === false) {
|
|
|
|
store.data = response.data;
|
2023-01-14 12:48:57 +00:00
|
|
|
|
2023-01-27 08:43:10 +00:00
|
|
|
updateStateParams();
|
|
|
|
}
|
2023-02-23 14:01:40 +00:00
|
|
|
|
2023-09-27 11:41:50 +00:00
|
|
|
store.isLoading = false;
|
2023-03-21 08:49:47 +00:00
|
|
|
|
2023-02-23 14:01:40 +00:00
|
|
|
canceller = null;
|
2023-01-14 12:48:57 +00:00
|
|
|
}
|
|
|
|
|
2023-03-01 15:20:28 +00:00
|
|
|
function destroy() {
|
2023-02-24 10:04:02 +00:00
|
|
|
if (arrayDataStore.get(key)) {
|
|
|
|
arrayDataStore.clear(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-23 14:01:40 +00:00
|
|
|
function cancelRequest() {
|
|
|
|
if (canceller) {
|
|
|
|
canceller.abort();
|
|
|
|
canceller = null;
|
|
|
|
}
|
|
|
|
}
|
2023-01-14 12:48:57 +00:00
|
|
|
|
2023-02-15 14:51:31 +00:00
|
|
|
async function applyFilter({ filter, params }) {
|
2023-01-14 12:48:57 +00:00
|
|
|
if (filter) store.userFilter = filter;
|
2023-02-09 06:26:08 +00:00
|
|
|
if (params) store.userParams = Object.assign({}, params);
|
2023-01-10 13:58:24 +00:00
|
|
|
|
|
|
|
await fetch({ append: false });
|
|
|
|
}
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-02-15 14:51:31 +00:00
|
|
|
async function addFilter({ filter, params }) {
|
|
|
|
if (filter) store.userFilter = Object.assign(store.userFilter, filter);
|
|
|
|
if (params) store.userParams = Object.assign(store.userParams, params);
|
|
|
|
|
|
|
|
await fetch({ append: false });
|
|
|
|
}
|
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
async function loadMore() {
|
|
|
|
if (!hasMoreData.value) return;
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-03-01 15:20:28 +00:00
|
|
|
store.skip = store.limit * page.value;
|
2023-01-10 13:58:24 +00:00
|
|
|
page.value += 1;
|
2023-01-05 13:57:47 +00:00
|
|
|
|
2023-01-10 13:58:24 +00:00
|
|
|
await fetch({ append: true });
|
2023-01-05 13:57:47 +00:00
|
|
|
}
|
|
|
|
|
2023-09-27 11:41:50 +00:00
|
|
|
async function refresh(showAll = true) {
|
2023-09-29 11:59:06 +00:00
|
|
|
if (showAll || (!showAll && Object.values(store.userParams).length))
|
|
|
|
await fetch({ append: false });
|
2023-01-14 12:48:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function updateStateParams() {
|
2023-02-16 14:01:02 +00:00
|
|
|
const query = {};
|
|
|
|
if (store.order) query.order = store.order;
|
|
|
|
if (store.limit) query.limit = store.limit;
|
|
|
|
if (store.skip) query.skip = store.skip;
|
|
|
|
if (store.userParams && Object.keys(store.userParams).length !== 0)
|
|
|
|
query.params = JSON.stringify(store.userParams);
|
|
|
|
|
2023-01-14 12:48:57 +00:00
|
|
|
router.replace({
|
|
|
|
path: route.path,
|
2023-02-16 14:01:02 +00:00
|
|
|
query: query,
|
2023-01-14 12:48:57 +00:00
|
|
|
});
|
2023-01-05 13:57:47 +00:00
|
|
|
}
|
|
|
|
|
2023-09-27 11:41:50 +00:00
|
|
|
const totalRows = computed(() => (store.data && store.data.length) || 0);
|
|
|
|
const isLoading = computed(() => store.isLoading || false);
|
2023-03-01 15:20:28 +00:00
|
|
|
|
2023-01-05 13:57:47 +00:00
|
|
|
return {
|
|
|
|
fetch,
|
2023-02-15 14:51:31 +00:00
|
|
|
applyFilter,
|
|
|
|
addFilter,
|
2023-01-05 13:57:47 +00:00
|
|
|
refresh,
|
2023-03-01 15:20:28 +00:00
|
|
|
destroy,
|
2023-01-10 13:58:24 +00:00
|
|
|
loadMore,
|
|
|
|
store,
|
|
|
|
hasMoreData,
|
2023-03-01 15:20:28 +00:00
|
|
|
totalRows,
|
2023-01-14 12:48:57 +00:00
|
|
|
updateStateParams,
|
2023-09-27 11:41:50 +00:00
|
|
|
isLoading,
|
2023-01-05 13:57:47 +00:00
|
|
|
};
|
|
|
|
}
|