{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "useAntdTable", "title": "useAntdTable", "description": "useAntdTable hook", "registryDependencies": [ "https://shadcn-ahooks.vercel.app/r/usePagination.json", "https://shadcn-ahooks.vercel.app/r/useMemoizedFn.json", "https://shadcn-ahooks.vercel.app/r/useUpdateEffect.json" ], "files": [ { "path": "packages/hooks/src/useAntdTable/index.tsx", "content": "import { useEffect, useRef, useState } from 'react';\nimport useMemoizedFn from '../useMemoizedFn';\nimport usePagination from '../usePagination';\nimport useUpdateEffect from '../useUpdateEffect';\n\nimport type {\n Antd4ValidateFields,\n AntdTableOptions,\n Data,\n Params,\n Service,\n AntdTableResult,\n} from './types';\n\nconst useAntdTable = (\n service: Service,\n options: AntdTableOptions = {},\n) => {\n const {\n form,\n defaultType = 'simple',\n defaultParams,\n manual = false,\n refreshDeps = [],\n ready = true,\n ...rest\n } = options;\n\n const result = usePagination(service, {\n ready,\n manual: true,\n ...rest,\n onSuccess(...args) {\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n runSuccessRef.current = true;\n rest.onSuccess?.(...args);\n },\n });\n\n const { params = [], run } = result;\n\n const cacheFormTableData = params[2] || ({} as any);\n\n const [type, setType] = useState(cacheFormTableData?.type || defaultType);\n\n const allFormDataRef = useRef>({});\n const defaultDataSourceRef = useRef([]);\n const runSuccessRef = useRef(false);\n\n const isAntdV4 = !!form?.getInternalHooks;\n\n // get current active field values\n const getActiveFieldValues = () => {\n if (!form) {\n return {};\n }\n\n // antd 4\n if (isAntdV4) {\n return form.getFieldsValue(null, () => true);\n }\n\n // antd 3\n const allFieldsValue = form.getFieldsValue();\n const activeFieldsValue: Record = {};\n Object.keys(allFieldsValue).forEach((key: string) => {\n if (form.getFieldInstance ? form.getFieldInstance(key) : true) {\n activeFieldsValue[key] = allFieldsValue[key];\n }\n });\n\n return activeFieldsValue;\n };\n\n const validateFields = (): Promise> => {\n if (!form) {\n return Promise.resolve({});\n }\n const activeFieldsValue = getActiveFieldValues();\n const fields = Object.keys(activeFieldsValue);\n\n // antd 4\n if (isAntdV4) {\n return (form.validateFields as Antd4ValidateFields)(fields);\n }\n // antd 3\n return new Promise((resolve, reject) => {\n form.validateFields(fields, (errors, values) => {\n if (errors) {\n reject(errors);\n } else {\n resolve(values);\n }\n });\n });\n };\n\n const restoreForm = () => {\n if (!form) {\n return;\n }\n\n // antd v4\n if (isAntdV4) {\n return form.setFieldsValue(allFormDataRef.current);\n }\n\n // antd v3\n const activeFieldsValue: Record = {};\n Object.keys(allFormDataRef.current).forEach((key) => {\n if (form.getFieldInstance ? form.getFieldInstance(key) : true) {\n activeFieldsValue[key] = allFormDataRef.current[key];\n }\n });\n form.setFieldsValue(activeFieldsValue);\n };\n\n const changeType = () => {\n const activeFieldsValue = getActiveFieldValues();\n allFormDataRef.current = {\n ...allFormDataRef.current,\n ...activeFieldsValue,\n };\n setType((t: string) => (t === 'simple' ? 'advance' : 'simple'));\n };\n\n const _submit = (initPagination?: TParams[0]) => {\n if (!ready) {\n return;\n }\n setTimeout(() => {\n validateFields()\n .then((values = {}) => {\n const pagination = initPagination || {\n pageSize: options.defaultPageSize || 10,\n ...(params?.[0] || {}),\n current: 1,\n };\n if (!form) {\n // @ts-ignore\n run(pagination);\n return;\n }\n\n // record all form data\n allFormDataRef.current = {\n ...allFormDataRef.current,\n ...values,\n };\n\n // @ts-ignore\n run(pagination, values, {\n allFormData: allFormDataRef.current,\n type,\n });\n })\n .catch((err) => err);\n });\n };\n\n const reset = () => {\n if (form) {\n form.resetFields();\n }\n _submit({\n ...(defaultParams?.[0] || {}),\n pageSize: options.defaultPageSize || options.defaultParams?.[0]?.pageSize || 10,\n current: 1,\n });\n };\n\n const submit = (e?: any) => {\n e?.preventDefault?.();\n _submit(\n runSuccessRef.current\n ? undefined\n : {\n pageSize: options.defaultPageSize || options.defaultParams?.[0]?.pageSize || 10,\n current: 1,\n ...(defaultParams?.[0] || {}),\n },\n );\n };\n\n const onTableChange = (pagination: any, filters: any, sorter: any, extra: any) => {\n const [oldPaginationParams, ...restParams] = params || [];\n run(\n // @ts-ignore\n {\n ...oldPaginationParams,\n current: pagination.current,\n pageSize: pagination.pageSize,\n filters,\n sorter,\n extra,\n },\n ...restParams,\n );\n };\n\n // init\n useEffect(() => {\n // if has cache, use cached params. ignore manual and ready.\n if (params.length > 0) {\n allFormDataRef.current = cacheFormTableData?.allFormData || {};\n restoreForm();\n // @ts-ignore\n run(...params);\n return;\n }\n if (ready) {\n allFormDataRef.current = defaultParams?.[1] || {};\n restoreForm();\n if (!manual) {\n _submit(defaultParams?.[0]);\n }\n }\n }, []);\n\n // change search type, restore form data\n useUpdateEffect(() => {\n if (!ready) {\n return;\n }\n restoreForm();\n }, [type]);\n\n // refresh & ready change on the same time\n const hasAutoRun = useRef(false);\n hasAutoRun.current = false;\n\n useUpdateEffect(() => {\n if (!manual && ready) {\n hasAutoRun.current = true;\n if (form) {\n form.resetFields();\n }\n allFormDataRef.current = defaultParams?.[1] || {};\n restoreForm();\n _submit(defaultParams?.[0]);\n }\n }, [ready]);\n\n useUpdateEffect(() => {\n if (hasAutoRun.current) {\n return;\n }\n if (!ready) {\n return;\n }\n if (!manual) {\n hasAutoRun.current = true;\n if (options.refreshDepsAction) {\n options.refreshDepsAction();\n } else {\n result.pagination.changeCurrent(1);\n }\n }\n }, [...refreshDeps]);\n\n return {\n ...result,\n tableProps: {\n dataSource: result.data?.list || defaultDataSourceRef.current,\n loading: result.loading,\n onChange: useMemoizedFn(onTableChange),\n pagination: {\n current: result.pagination.current,\n pageSize: result.pagination.pageSize,\n total: result.pagination.total,\n },\n },\n search: {\n submit: useMemoizedFn(submit),\n type,\n changeType: useMemoizedFn(changeType),\n reset: useMemoizedFn(reset),\n },\n } as AntdTableResult;\n};\n\nexport default useAntdTable;\n", "type": "registry:file", "target": "src/hooks/ahooks/useAntdTable/index.tsx" }, { "path": "packages/hooks/src/useAntdTable/types.ts", "content": "import type { PaginationOptions, PaginationResult } from '../usePagination/types';\n\nexport type Data = { total: number; list: any[] };\n\nexport type Params = [\n {\n current: number;\n pageSize: number;\n sorter?: any;\n filters?: any;\n extra?: any;\n [key: string]: any;\n },\n ...any[],\n];\n\nexport type Service = (\n ...args: TParams\n) => Promise;\n\nexport type Antd3ValidateFields = (\n fieldNames: string[],\n callback: (errors: any, values: Record) => void,\n) => void;\nexport type Antd4ValidateFields = (fieldNames?: string[]) => Promise>;\n\nexport interface AntdFormUtils {\n getFieldInstance?: (name: string) => Record;\n setFieldsValue: (value: Record) => void;\n getFieldsValue: (...args: any) => Record;\n resetFields: (...args: any) => void;\n validateFields: Antd3ValidateFields | Antd4ValidateFields;\n getInternalHooks?: any;\n [key: string]: any;\n}\n\nexport interface AntdTableResult\n extends PaginationResult {\n tableProps: {\n dataSource: TData['list'];\n loading: boolean;\n onChange: (pagination: any, filters?: any, sorter?: any) => void;\n pagination: any;\n [key: string]: any;\n };\n search: {\n type: 'simple' | 'advance';\n changeType: () => void;\n submit: () => void;\n reset: () => void;\n };\n}\n\nexport interface AntdTableOptions\n extends PaginationOptions {\n form?: AntdFormUtils;\n defaultType?: 'simple' | 'advance';\n}\n", "type": "registry:file", "target": "src/hooks/ahooks/useAntdTable/types.ts" } ], "type": "registry:hook" }