import { toReactive } from "@vueuse/core"; import { reactive, ref, shallowRef, toRaw, watchEffect } from "vue"; import * as Element from "../element"; import { useI18n } from "vue3-i18n"; import { PageResponse } from "../http"; import { clearAndAssign, deepCopy } from "../util/objectUtil"; const { showMessage } = Element; export interface TableColumn { code: string; name?: string; i18n?: string; type?: string; width?: string | number; fixed?: boolean | "left" | "right"; align?: "left" | "center" | "right"; slot?: boolean; dict?: string; timestamp?: boolean; filesize?: boolean; [others: string]: any; } export interface TableData { rows: PageResponse; example: Record; } interface Options { query: (example: any) => Promise | Record[] | undefined>; initialPage?: number; initialPageSize?: number; initExample?: Record; disableAutoQuery?: boolean; deep?: boolean; } export function useListTable(options: Options) { const { t } = useI18n(); const { initialPage, initialPageSize, initExample, deep } = options; type Row = Record; type Rows = Row[] | PageResponse; const empty = () => [] as T[]; const rows = deep ? ref(empty()) : shallowRef(empty()); const setRows = (resp?: Rows) => { if (resp == null) { rows.value = empty(); } else { rows.value = resp; if (Array.isArray(resp) || resp.total == null) { for (const key in pageParams) { delete example[key]; } } } }; const pageParams = { page: initialPage || 1, size: initialPageSize || 10, }; const defaultExample = () => ({ ...pageParams, ...initExample, }); const example = reactive(defaultExample()); const setExample = (params: Record) => { clearAndAssign(example, { ...defaultExample(), ...params }); }; const query = async () => { try { const resp = await options.query(deepCopy(toRaw(example))); setRows(resp); } catch (error) { console.error(error); showMessage("error", t("common.errors.listTableQueryError")); } }; if (!options.disableAutoQuery) { watchEffect(query); } return { rows: toReactive(rows), example, setRows, setExample, query, }; }