salix-front/src/composables/useArrayData.js

157 lines
3.9 KiB
JavaScript
Raw Normal View History

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
onMounted(() => {
setOptions();
2023-03-13 09:07:52 +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() {
if (typeof userOptions === 'object') {
for (const option in userOptions) {
if (userOptions[option] == null) continue;
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 = {
filter: JSON.stringify(store.filter),
2023-01-17 13:57:12 +00:00
};
Object.assign(params, store.userParams);
2023-02-23 14:01:40 +00:00
const response = await axios.get(store.url, {
signal: canceller.signal,
params,
});
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
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
}
async function refresh() {
2023-02-21 14:05:57 +00:00
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-03-01 15:20:28 +00:00
const totalRows = computed(() => store.data && store.data.length | 0);
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-01-05 13:57:47 +00:00
};
}