adrema/resources/js/composables/useApiIndex.ts

97 lines
2.4 KiB
TypeScript

import {ref, inject, onBeforeUnmount} from 'vue';
import {router} from '@inertiajs/vue3';
import type {Ref} from 'vue';
import useQueueEvents from './useQueueEvents.js';
import { Axios } from 'axios';
export function useApiIndex<D, M extends Custom.PageMetadata>(firstUrl, siteName = null) {
const axios = inject<Axios>('axios');
if (siteName !== null) {
var {startListener, stopListener} = useQueueEvents(siteName, () => reload());
}
const single: Ref<D|null> = ref(null);
const url = ref(firstUrl);
const inner: {data: Ref<D[]|null>, meta: Ref<M|null>} = {
data: ref(null),
meta: ref(null),
};
async function reload(resetPage = true, p = {}) {
const params = {
page: resetPage ? 1 : inner.meta.value?.current_page,
...p,
};
const response = (await axios.get(url.value, {params})).data;
inner.data.value = response.data;
inner.meta.value = response.meta;
}
async function reloadPage(page: number, p = {}) {
if (inner.meta.value?.current_page) {
inner.meta.value.current_page = page;
}
await reload(false, p);
}
function create() {
single.value = JSON.parse(JSON.stringify(inner.meta.value?.default));
}
function edit(model: D) {
single.value = JSON.parse(JSON.stringify(model));
}
async function submit() {
if (single.value === null) {
return;
}
single.value.id ? await axios.patch(single.value.links.update, single.value) : await axios.post(inner.meta.value.links.store, single.value);
await reload();
single.value = null;
}
async function remove(model: D) {
await axios.delete(model.links.destroy);
await reload();
}
function toFilterString(data) {
return btoa(encodeURIComponent(JSON.stringify(data)));
}
function cancel() {
single.value = null;
}
function updateUrl(newUrl: string) {
url.value = newUrl;
}
if (siteName !== null) {
startListener();
onBeforeUnmount(() => stopListener());
}
return {
data: inner.data,
meta: inner.meta,
single,
create,
edit,
reload,
reloadPage,
router,
submit,
remove,
cancel,
axios,
toFilterString,
updateUrl,
url,
};
}