store/resources/js/composables/useDataTableQuery.ts
Yoga Pangestu 765e74d8a9
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (8.3) (push) Waiting to run
tests / ci (8.4) (push) Waiting to run
tests / ci (8.5) (push) Waiting to run
feat: add loading state and enhance media thumbnail functionality in data tables for improved user experience
2026-07-07 22:41:55 +07:00

98 lines
2.5 KiB
TypeScript

import { router } from '@inertiajs/vue3';
import { useDebounceFn } from '@vueuse/core';
import { ref, watch } from 'vue';
import type {WatchSource} from 'vue';
import type { DataTableQuery, DataTableSort } from '@/types/data-table';
type UseDataTableQueryOptions = {
url: string;
initial: DataTableQuery;
filterKeys?: string[];
debounceMs?: number;
only?: string[];
};
function buildParams(query: DataTableQuery, filterKeys: string[]): Record<string, string | undefined> {
const params: Record<string, string | undefined> = {
search: query.search || undefined,
sort: query.sort || undefined,
direction: query.direction || undefined,
};
for (const key of filterKeys) {
params[key] = query[key] || undefined;
}
return params;
}
export function useDataTableQuery(options: UseDataTableQueryOptions) {
const filterKeys = options.filterKeys ?? [];
const query = ref<DataTableQuery>({ ...options.initial });
const isLoading = ref(false);
const reload = useDebounceFn(() => {
router.get(options.url, buildParams(query.value, filterKeys), {
preserveState: true,
replace: true,
preserveScroll: true,
showProgress: false,
only: options.only,
onBefore: () => {
isLoading.value = true;
},
onFinish: () => {
isLoading.value = false;
},
});
}, options.debounceMs ?? 300);
function setSearch(value: string): void {
query.value.search = value;
reload();
}
function setSort(sort: DataTableSort | null): void {
query.value.sort = sort?.column;
query.value.direction = sort?.direction;
reload();
}
function setFilter(key: string, value: string): void {
query.value[key] = value;
reload();
}
function resetFilters(): void {
for (const key of filterKeys) {
query.value[key] = '';
}
reload();
}
function syncFromServer(filters: DataTableQuery): void {
query.value = { ...filters };
}
return {
query,
isLoading,
setSearch,
setSort,
setFilter,
resetFilters,
reload,
syncFromServer,
};
}
export function useDataTableQuerySync(
filters: WatchSource<DataTableQuery>,
syncFromServer: (filters: DataTableQuery) => void,
): void {
watch(filters, (value) => {
syncFromServer(value);
});
}