@wordrhyme/auto-crud 1.13.0 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -11
- package/dist/index.cjs +44 -27
- package/dist/index.d.cts +29 -19
- package/dist/index.d.ts +13 -3
- package/dist/index.js +44 -27
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -172,20 +172,20 @@ Zod Schema → 自动推断字段类型 → 生成表格列 + 表单字段
|
|
|
172
172
|
```typescript
|
|
173
173
|
import { createMemoryDataSource } from '@wordrhyme/auto-crud';
|
|
174
174
|
|
|
175
|
-
const dataSource = createMemoryDataSource(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
/* ... */
|
|
185
|
-
},
|
|
175
|
+
const dataSource = createMemoryDataSource(initialData);
|
|
176
|
+
const result = await dataSource.list({
|
|
177
|
+
page: 1,
|
|
178
|
+
perPage: 10,
|
|
179
|
+
filters: [{ id: 'status', operator: 'inArray', value: ['draft', 'published'] }],
|
|
180
|
+
sort: [
|
|
181
|
+
{ id: 'createdAt', desc: true },
|
|
182
|
+
{ id: 'id', desc: false },
|
|
183
|
+
],
|
|
186
184
|
});
|
|
187
185
|
```
|
|
188
186
|
|
|
187
|
+
筛选支持省略 operator / `eq`(严格相等)和 `inArray`(字段值属于给定数组);其他 operator 会报错。排序按配置顺序比较,前一字段相同时使用下一字段,再进行分页。内存数据源不执行全文搜索。
|
|
188
|
+
|
|
189
189
|
#### 2. tRPC 数据源(tRPC Data Source)
|
|
190
190
|
|
|
191
191
|
适合:全栈 TypeScript 项目
|
|
@@ -328,6 +328,37 @@ interface AutoCrudTableProps<TSchema> {
|
|
|
328
328
|
|
|
329
329
|
`expandedRow` 的第二个参数是当前 TanStack `Row`,可通过 `row.getAllCells()` 读取已解析的列和单元格上下文,复用字段渲染器及数据源标签。只接收订单数据的单参数回调仍可使用。
|
|
330
330
|
|
|
331
|
+
#### 表格状态与 URL 参数
|
|
332
|
+
|
|
333
|
+
同页显示多个表格时,在资源 Hook 中配置独立的分页、排序和条件连接符参数名,`AutoCrudTable` 会自动传给表格:
|
|
334
|
+
|
|
335
|
+
```tsx
|
|
336
|
+
const resource = useAutoCrudResource({
|
|
337
|
+
router: trpc.orders,
|
|
338
|
+
schema: orderSchema,
|
|
339
|
+
queryKeys: {
|
|
340
|
+
page: 'ordersPage',
|
|
341
|
+
perPage: 'ordersSize',
|
|
342
|
+
sort: 'ordersSort',
|
|
343
|
+
joinOperator: 'ordersJoin',
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
<AutoCrudTable
|
|
348
|
+
id="orders"
|
|
349
|
+
schema={orderSchema}
|
|
350
|
+
resource={resource}
|
|
351
|
+
table={{
|
|
352
|
+
enableRowSelection: false,
|
|
353
|
+
initialColumnVisibility: { createdAt: false },
|
|
354
|
+
}}
|
|
355
|
+
/>;
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
未配置的参数名保留默认值。搜索仍使用共享的 `search` 参数,字段筛选仍使用字段名;`queryKeys` 不隔离这些值。筛选或搜索变化时,仅重置该表格对应的页码。直接使用 `AutoTable` 时传入相同的 `queryKeys`;`table.queryKeys` 可覆盖资源提供的整组配置。
|
|
359
|
+
|
|
360
|
+
`enableRowSelection` 默认 `true`,设为 `false` 后关闭行选择并隐藏选择列和批量操作栏。`initialColumnVisibility` 只设置首次显示的列,用户仍可通过列设置切换;它不同于 `table.hidden` 对列的排除。
|
|
361
|
+
|
|
331
362
|
### `useAutoCrudResource()`
|
|
332
363
|
|
|
333
364
|
连接数据源到组件的 Hook。
|
|
@@ -1751,6 +1782,13 @@ Table-only hidden fields remain available in details; shared `hidden` and
|
|
|
1751
1782
|
`permissions.deny` always take precedence. Labels are resolved from the selected
|
|
1752
1783
|
record, including when it is absent from the current list page.
|
|
1753
1784
|
|
|
1785
|
+
Details share the form's column count, field spans and `x-index` order (including
|
|
1786
|
+
`form.overrides`). Fields without an index retain schema order. List column order
|
|
1787
|
+
does not control detail layout, even with `view.presentation: 'table'`.
|
|
1788
|
+
`view.overrides[field].index` takes precedence for detail-only ordering. Fields
|
|
1789
|
+
hidden only in forms remain available in details; use detail ordering to place
|
|
1790
|
+
read-only business fields next to related information or audit fields at the end.
|
|
1791
|
+
|
|
1754
1792
|
```tsx
|
|
1755
1793
|
<AutoCrudTable
|
|
1756
1794
|
schema={schema}
|
package/dist/index.cjs
CHANGED
|
@@ -5122,7 +5122,7 @@ function useDataTable(props) {
|
|
|
5122
5122
|
...tableProps.defaultColumn,
|
|
5123
5123
|
enableColumnFilter: false
|
|
5124
5124
|
},
|
|
5125
|
-
enableRowSelection: true,
|
|
5125
|
+
enableRowSelection: tableProps.enableRowSelection ?? true,
|
|
5126
5126
|
onRowSelectionChange: setRowSelection,
|
|
5127
5127
|
onPaginationChange,
|
|
5128
5128
|
onSortingChange,
|
|
@@ -5188,7 +5188,7 @@ const filterModeConfig = {
|
|
|
5188
5188
|
tooltip: "Linear-style command filters"
|
|
5189
5189
|
}
|
|
5190
5190
|
};
|
|
5191
|
-
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, toolbarExtra, locale = enUSTableControls, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows, exportTableRef }) {
|
|
5191
|
+
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, queryKeys, initialColumnVisibility, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, toolbarExtra, locale = enUSTableControls, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows, exportTableRef }) {
|
|
5192
5192
|
if (expandedRow && !getRowId) throw new Error("AutoTable requires getRowId when expandedRow is provided.");
|
|
5193
5193
|
const enableExpansion = !!expandedRow;
|
|
5194
5194
|
const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
|
|
@@ -5198,7 +5198,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5198
5198
|
shallow: false,
|
|
5199
5199
|
clearOnDefault: true
|
|
5200
5200
|
});
|
|
5201
|
-
const [, setSearchPage] = useUrlState("page", parseAsInteger.withDefault(1), {
|
|
5201
|
+
const [, setSearchPage] = useUrlState(queryKeys?.page ?? "page", parseAsInteger.withDefault(1), {
|
|
5202
5202
|
shallow: false,
|
|
5203
5203
|
clearOnDefault: true
|
|
5204
5204
|
});
|
|
@@ -5265,6 +5265,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5265
5265
|
]);
|
|
5266
5266
|
const stableInitialState = (0, react.useMemo)(() => ({
|
|
5267
5267
|
sorting: initialSorting,
|
|
5268
|
+
columnVisibility: initialColumnVisibility,
|
|
5268
5269
|
expanded: enableExpansion && defaultExpanded ? true : {},
|
|
5269
5270
|
columnPinning: pinnedColumns ?? {
|
|
5270
5271
|
left: [...enableExpansion ? [expandColumnId] : [], ...enableRowSelection ? ["select"] : []],
|
|
@@ -5272,6 +5273,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5272
5273
|
}
|
|
5273
5274
|
}), [
|
|
5274
5275
|
initialSorting,
|
|
5276
|
+
initialColumnVisibility,
|
|
5275
5277
|
pinnedColumns,
|
|
5276
5278
|
enableRowSelection,
|
|
5277
5279
|
enableExpansion,
|
|
@@ -5283,6 +5285,8 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5283
5285
|
const { table, shallow, debounceMs, throttleMs } = useDataTable({
|
|
5284
5286
|
data,
|
|
5285
5287
|
columns,
|
|
5288
|
+
queryKeys,
|
|
5289
|
+
enableRowSelection,
|
|
5286
5290
|
getRowId,
|
|
5287
5291
|
getRowCanExpand: () => enableExpansion,
|
|
5288
5292
|
getExpandedRowModel: enableExpansion ? expandedRowModel : void 0,
|
|
@@ -7817,12 +7821,13 @@ function ViewModalContent({ open, onOpenChange, variant, data, schema, fields: f
|
|
|
7817
7821
|
const detailSchema = react.useMemo(() => schema.omit(Object.fromEntries(excluded.map((key) => [key, true]))), [schema, excluded]);
|
|
7818
7822
|
const overrides = buildFormOverrides(fieldConfig, form?.overrides, denyFields, "view");
|
|
7819
7823
|
const renderers = {};
|
|
7820
|
-
for (const
|
|
7824
|
+
for (const cell of table.getRowModel().rows[0]?.getAllCells() ?? []) {
|
|
7821
7825
|
const key = cell.column.id;
|
|
7826
|
+
const index$1 = view?.overrides?.[key]?.index;
|
|
7822
7827
|
overrides[key] = {
|
|
7823
7828
|
...overrides[key],
|
|
7824
7829
|
title: cell.column.columnDef.meta?.label ?? humanize(key),
|
|
7825
|
-
"x-index": index$1
|
|
7830
|
+
...index$1 !== void 0 ? { "x-index": index$1 } : {}
|
|
7826
7831
|
};
|
|
7827
7832
|
renderers[key] = () => (0, __tanstack_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext());
|
|
7828
7833
|
delete overrides[key]["x-data-source"];
|
|
@@ -8309,6 +8314,9 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
8309
8314
|
pageCount: resource.tableData.pageCount,
|
|
8310
8315
|
pagination: paginationOptions,
|
|
8311
8316
|
...resource.tableData.total !== void 0 ? { total: resource.tableData.total } : {},
|
|
8317
|
+
queryKeys: tableConfig?.queryKeys ?? resource.queryKeys,
|
|
8318
|
+
enableRowSelection: tableConfig?.enableRowSelection,
|
|
8319
|
+
initialColumnVisibility: tableConfig?.initialColumnVisibility,
|
|
8312
8320
|
getRowId: tableConfig?.getRowId,
|
|
8313
8321
|
expandedRow: tableConfig?.expandedRow,
|
|
8314
8322
|
defaultExpanded: tableConfig?.defaultExpanded,
|
|
@@ -9154,7 +9162,7 @@ function modalReducer(state, action$1) {
|
|
|
9154
9162
|
/**
|
|
9155
9163
|
* Hook 主函数
|
|
9156
9164
|
*/
|
|
9157
|
-
function useAutoCrudResource({ router, schema, query: queryTransform, fields, options = {} }) {
|
|
9165
|
+
function useAutoCrudResource({ router, queryKeys, schema, query: queryTransform, fields, options = {} }) {
|
|
9158
9166
|
const { idKey = "id", defaultVariant = "dialog", hooks, toast: toastAdapter, exportFetcher, defaultSort: defaultSortOption } = options;
|
|
9159
9167
|
const toast$1 = (0, react.useMemo)(() => toastAdapter === false ? noopToastAdapter : toastAdapter ?? defaultToastAdapter, [toastAdapter]);
|
|
9160
9168
|
const hooksRef = (0, react.useRef)(hooks);
|
|
@@ -9175,31 +9183,36 @@ function useAutoCrudResource({ router, schema, query: queryTransform, fields, op
|
|
|
9175
9183
|
fields,
|
|
9176
9184
|
metadataFields
|
|
9177
9185
|
]);
|
|
9178
|
-
const [
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
+
const [page] = useQueryState(queryKeys?.page ?? "page", parseAsInteger.withDefault(1));
|
|
9187
|
+
const [perPage] = useQueryState(queryKeys?.perPage ?? "perPage", parseAsInteger.withDefault(10));
|
|
9188
|
+
const [sort] = useQueryState(queryKeys?.sort ?? "sort", getSortingStateParser().withDefault(defaultSorting));
|
|
9189
|
+
const [joinOperator] = useQueryState(queryKeys?.joinOperator ?? "joinOperator", parseAsStringEnum(["and", "or"]).withDefault("and"));
|
|
9190
|
+
const [search] = useQueryState("search", parseAsString.withDefault(""), { shallow: false });
|
|
9191
|
+
const [filters] = useReadableFilters(columns, {
|
|
9192
|
+
shallow: false,
|
|
9193
|
+
resetPageKey: queryKeys?.page ?? "page"
|
|
9194
|
+
});
|
|
9186
9195
|
const metadataPending = Boolean(metadataQuery?.isPending);
|
|
9187
9196
|
const [filtersReady, setFiltersReady] = (0, react.useState)(!metadataPending);
|
|
9188
9197
|
(0, react.useEffect)(() => setFiltersReady(!metadataPending), [metadataPending]);
|
|
9189
9198
|
const listReady = !metadataPending && filtersReady;
|
|
9190
9199
|
const queryInput = (0, react.useMemo)(() => {
|
|
9191
9200
|
const autoParams = {
|
|
9192
|
-
page
|
|
9193
|
-
perPage
|
|
9194
|
-
sort
|
|
9201
|
+
page,
|
|
9202
|
+
perPage,
|
|
9203
|
+
sort,
|
|
9195
9204
|
filters,
|
|
9196
|
-
joinOperator
|
|
9197
|
-
...
|
|
9205
|
+
joinOperator,
|
|
9206
|
+
...search.trim() ? { search: search.trim() } : {}
|
|
9198
9207
|
};
|
|
9199
9208
|
return queryTransform ? queryTransform(autoParams) : autoParams;
|
|
9200
9209
|
}, [
|
|
9201
|
-
|
|
9210
|
+
page,
|
|
9211
|
+
perPage,
|
|
9212
|
+
sort,
|
|
9202
9213
|
filters,
|
|
9214
|
+
joinOperator,
|
|
9215
|
+
search,
|
|
9203
9216
|
queryTransform
|
|
9204
9217
|
]);
|
|
9205
9218
|
const hasReadyListData = (0, react.useRef)(false);
|
|
@@ -9475,6 +9488,7 @@ function useAutoCrudResource({ router, schema, query: queryTransform, fields, op
|
|
|
9475
9488
|
}, [listQuery, listReady]);
|
|
9476
9489
|
return {
|
|
9477
9490
|
idKey,
|
|
9491
|
+
queryKeys,
|
|
9478
9492
|
tableData: {
|
|
9479
9493
|
data: tableRows,
|
|
9480
9494
|
pageCount: listData?.pageCount ?? 0,
|
|
@@ -9762,18 +9776,21 @@ function createMemoryDataSource(initialData = []) {
|
|
|
9762
9776
|
let filtered = [...data];
|
|
9763
9777
|
if (params.filters) filtered = filtered.filter((item) => {
|
|
9764
9778
|
return params.filters.every((filter) => {
|
|
9765
|
-
|
|
9779
|
+
const value = item[filter.id];
|
|
9780
|
+
if (filter.operator === "inArray") return Array.isArray(filter.value) && filter.value.includes(value);
|
|
9781
|
+
if (!filter.operator || filter.operator === "eq") return value === filter.value;
|
|
9782
|
+
throw new Error(`Unsupported memory filter operator: ${filter.operator}`);
|
|
9766
9783
|
});
|
|
9767
9784
|
});
|
|
9768
|
-
if (params.sort && params.sort.length > 0) {
|
|
9769
|
-
const sortItem
|
|
9770
|
-
filtered.sort((a, b) => {
|
|
9785
|
+
if (params.sort && params.sort.length > 0) filtered.sort((a, b) => {
|
|
9786
|
+
for (const sortItem of params.sort) {
|
|
9771
9787
|
const aVal = a[sortItem.id];
|
|
9772
9788
|
const bVal = b[sortItem.id];
|
|
9773
9789
|
const result = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
|
|
9774
|
-
return sortItem.desc ? -result : result;
|
|
9775
|
-
}
|
|
9776
|
-
|
|
9790
|
+
if (result) return sortItem.desc ? -result : result;
|
|
9791
|
+
}
|
|
9792
|
+
return 0;
|
|
9793
|
+
});
|
|
9777
9794
|
const start = (params.page - 1) * params.perPage;
|
|
9778
9795
|
const end = start + params.perPage;
|
|
9779
9796
|
return {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { a as positionActions, i as matchesPosition, n as actionPositionSchema, r as compareOrder, t as ActionPosition } from "./position-DoBV7yB6.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
4
|
import { ComponentProps, ReactNode } from "react";
|
|
5
5
|
import * as _tanstack_react_table0 from "@tanstack/react-table";
|
|
6
|
-
import { Column, ColumnDef, ColumnMeta, ColumnSort, Row, RowData, Table, TableOptions, TableState } from "@tanstack/react-table";
|
|
6
|
+
import { Column, ColumnDef, ColumnMeta, ColumnSort, Row, RowData, Table, TableOptions, TableState, VisibilityState } from "@tanstack/react-table";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { JsonSchemaFormScope } from "@wordrhyme/formily-shadcn";
|
|
9
9
|
import { ISchema } from "@formily/json-schema";
|
|
@@ -471,6 +471,7 @@ interface ImportResult {
|
|
|
471
471
|
* Hook 返回值类型
|
|
472
472
|
*/
|
|
473
473
|
interface UseAutoCrudResourceReturn<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem> {
|
|
474
|
+
queryKeys?: Partial<QueryKeys>;
|
|
474
475
|
/** 主键字段名(默认: "id") */
|
|
475
476
|
idKey?: keyof TListItem & string;
|
|
476
477
|
tableData: {
|
|
@@ -574,6 +575,8 @@ interface AutoQueryParams {
|
|
|
574
575
|
interface UseAutoCrudResourceParams<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem> {
|
|
575
576
|
/** tRPC router (如 trpc.tasks) */
|
|
576
577
|
router: CrudRouter;
|
|
578
|
+
/** URL keys shared with the table, for multiple resources on one page. */
|
|
579
|
+
queryKeys?: Partial<QueryKeys>;
|
|
577
580
|
/** Zod schema */
|
|
578
581
|
schema: TSchema;
|
|
579
582
|
/** Field filter configuration shared with AutoCrudTable. */
|
|
@@ -602,6 +605,7 @@ interface UseAutoCrudResourceParams<TSchema extends z.ZodObject<z.ZodRawShape>,
|
|
|
602
605
|
*/
|
|
603
606
|
declare function useAutoCrudResource<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem = z.output<TSchema>>({
|
|
604
607
|
router,
|
|
608
|
+
queryKeys,
|
|
605
609
|
schema,
|
|
606
610
|
query: queryTransform,
|
|
607
611
|
fields,
|
|
@@ -672,7 +676,7 @@ declare function DataTable<TData>({
|
|
|
672
676
|
className,
|
|
673
677
|
classNames,
|
|
674
678
|
...props
|
|
675
|
-
}: DataTableProps<TData>):
|
|
679
|
+
}: DataTableProps<TData>): react_jsx_runtime9.JSX.Element;
|
|
676
680
|
//#endregion
|
|
677
681
|
//#region src/components/auto-crud/auto-table-action-bar.d.ts
|
|
678
682
|
/** 批量更新字段配置 */
|
|
@@ -761,7 +765,7 @@ declare function AutoTableActionBar<TData>({
|
|
|
761
765
|
extraActions,
|
|
762
766
|
actions,
|
|
763
767
|
deleteConfirmation
|
|
764
|
-
}: AutoTableActionBarProps<TData>):
|
|
768
|
+
}: AutoTableActionBarProps<TData>): react_jsx_runtime9.JSX.Element;
|
|
765
769
|
//#endregion
|
|
766
770
|
//#region src/lib/schema-bridge/types.d.ts
|
|
767
771
|
/**
|
|
@@ -1016,6 +1020,10 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> extends Pick<Data
|
|
|
1016
1020
|
/** 按元素分组的全局表格类名 */
|
|
1017
1021
|
classNames?: DataTableClassNames;
|
|
1018
1022
|
enableRowSelection?: boolean;
|
|
1023
|
+
/** URL keys shared with useAutoCrudResource. */
|
|
1024
|
+
queryKeys?: Partial<QueryKeys>;
|
|
1025
|
+
/** Initial visibility; users can still toggle columns in the view options. */
|
|
1026
|
+
initialColumnVisibility?: VisibilityState;
|
|
1019
1027
|
exclude?: (keyof z.infer<T>)[];
|
|
1020
1028
|
filterOnly?: string[];
|
|
1021
1029
|
actions?: ActionsColumnConfig<z.infer<T>>;
|
|
@@ -1078,6 +1086,8 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
1078
1086
|
overrides,
|
|
1079
1087
|
classNames,
|
|
1080
1088
|
enableRowSelection,
|
|
1089
|
+
queryKeys,
|
|
1090
|
+
initialColumnVisibility,
|
|
1081
1091
|
exclude,
|
|
1082
1092
|
filterOnly,
|
|
1083
1093
|
actions,
|
|
@@ -1099,7 +1109,7 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
1099
1109
|
onSelectedRowsChange,
|
|
1100
1110
|
getSelectedRows,
|
|
1101
1111
|
exportTableRef
|
|
1102
|
-
}: AutoTableProps<T>):
|
|
1112
|
+
}: AutoTableProps<T>): react_jsx_runtime9.JSX.Element;
|
|
1103
1113
|
//#endregion
|
|
1104
1114
|
//#region src/components/auto-crud/auto-form.d.ts
|
|
1105
1115
|
type AutoFormProps<T extends z.ZodObject<z.ZodRawShape>> = {
|
|
@@ -1142,7 +1152,7 @@ declare function AutoFormInner<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
1142
1152
|
labelAlign,
|
|
1143
1153
|
labelWidth,
|
|
1144
1154
|
showSubmitButton
|
|
1145
|
-
}: AutoFormProps<T>, ref: React.Ref<AutoFormRef>):
|
|
1155
|
+
}: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime9.JSX.Element;
|
|
1146
1156
|
declare const AutoForm: <T extends z.ZodObject<z.ZodRawShape>>(props: AutoFormProps<T> & {
|
|
1147
1157
|
ref?: React.Ref<AutoFormRef>;
|
|
1148
1158
|
}) => ReturnType<typeof AutoFormInner>;
|
|
@@ -1481,7 +1491,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
|
|
|
1481
1491
|
* 支持共用配置(label, hidden)+ 表格/表单特定配置
|
|
1482
1492
|
*/
|
|
1483
1493
|
fields?: Fields;
|
|
1484
|
-
/**
|
|
1494
|
+
/** Details share form layout and field formatting by default. */
|
|
1485
1495
|
view?: {
|
|
1486
1496
|
/** Explicitly reuse custom list cells with a separate, single-row table context. */
|
|
1487
1497
|
presentation?: 'table';
|
|
@@ -1523,7 +1533,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
|
|
|
1523
1533
|
batchActions?: BatchActionConfig<z.output<TSchema>>;
|
|
1524
1534
|
/** 默认排序 */
|
|
1525
1535
|
defaultSort?: any[];
|
|
1526
|
-
} & Pick<AutoTableProps<TSchema>, 'getRowId' | 'expandedRow' | 'defaultExpanded'>;
|
|
1536
|
+
} & Pick<AutoTableProps<TSchema>, 'getRowId' | 'expandedRow' | 'defaultExpanded' | 'enableRowSelection' | 'initialColumnVisibility' | 'queryKeys'>;
|
|
1527
1537
|
/** 表单配置 */
|
|
1528
1538
|
form?: {
|
|
1529
1539
|
/** 表单覆盖配置(兼容旧 API,优先级低于 fieldOverrides) */
|
|
@@ -1612,7 +1622,7 @@ declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
|
|
|
1612
1622
|
locale: localeProp,
|
|
1613
1623
|
onCreate,
|
|
1614
1624
|
onExport
|
|
1615
|
-
}: AutoCrudTableProps<TSchema>):
|
|
1625
|
+
}: AutoCrudTableProps<TSchema>): react_jsx_runtime9.JSX.Element;
|
|
1616
1626
|
//#endregion
|
|
1617
1627
|
//#region src/components/auto-crud/auto-table-simple-filters.d.ts
|
|
1618
1628
|
interface AutoTableSimpleFiltersProps<TData> {
|
|
@@ -1628,7 +1638,7 @@ declare function AutoTableSimpleFilters<TData>({
|
|
|
1628
1638
|
filters: externalFilters,
|
|
1629
1639
|
onFiltersChange,
|
|
1630
1640
|
leading
|
|
1631
|
-
}: AutoTableSimpleFiltersProps<TData>):
|
|
1641
|
+
}: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime9.JSX.Element | null;
|
|
1632
1642
|
//#endregion
|
|
1633
1643
|
//#region src/components/auto-crud/form-modal.d.ts
|
|
1634
1644
|
type ModalVariant = 'dialog' | 'sheet';
|
|
@@ -1677,7 +1687,7 @@ declare function CrudFormModal<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
1677
1687
|
labelAlign,
|
|
1678
1688
|
labelWidth,
|
|
1679
1689
|
className
|
|
1680
|
-
}: CrudFormModalProps<T> & CrudFormModalMode<T>):
|
|
1690
|
+
}: CrudFormModalProps<T> & CrudFormModalMode<T>): react_jsx_runtime9.JSX.Element;
|
|
1681
1691
|
//#endregion
|
|
1682
1692
|
//#region src/components/auto-crud/import-dialog.d.ts
|
|
1683
1693
|
interface ImportDialogProps {
|
|
@@ -1699,7 +1709,7 @@ declare function ImportDialog({
|
|
|
1699
1709
|
columns,
|
|
1700
1710
|
title,
|
|
1701
1711
|
locale
|
|
1702
|
-
}: ImportDialogProps):
|
|
1712
|
+
}: ImportDialogProps): react_jsx_runtime9.JSX.Element;
|
|
1703
1713
|
//#endregion
|
|
1704
1714
|
//#region src/components/auto-crud/export-dialog.d.ts
|
|
1705
1715
|
type ExportMode = 'selected' | 'filtered';
|
|
@@ -1719,7 +1729,7 @@ declare function ExportDialog({
|
|
|
1719
1729
|
selectedCount,
|
|
1720
1730
|
onExport,
|
|
1721
1731
|
canExportFiltered
|
|
1722
|
-
}: ExportDialogProps):
|
|
1732
|
+
}: ExportDialogProps): react_jsx_runtime9.JSX.Element;
|
|
1723
1733
|
//#endregion
|
|
1724
1734
|
//#region src/components/data-table/data-table-advanced-toolbar.d.ts
|
|
1725
1735
|
interface DataTableAdvancedToolbarProps<TData> extends React$1.ComponentProps<'div'> {
|
|
@@ -1730,7 +1740,7 @@ declare function DataTableAdvancedToolbar<TData>({
|
|
|
1730
1740
|
children,
|
|
1731
1741
|
className,
|
|
1732
1742
|
...props
|
|
1733
|
-
}: DataTableAdvancedToolbarProps<TData>):
|
|
1743
|
+
}: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime9.JSX.Element;
|
|
1734
1744
|
//#endregion
|
|
1735
1745
|
//#region src/components/data-table/data-table-column-header.d.ts
|
|
1736
1746
|
interface DataTableColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {
|
|
@@ -1742,7 +1752,7 @@ declare function DataTableColumnHeader<TData, TValue>({
|
|
|
1742
1752
|
label,
|
|
1743
1753
|
className,
|
|
1744
1754
|
...props
|
|
1745
|
-
}: DataTableColumnHeaderProps<TData, TValue>):
|
|
1755
|
+
}: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime9.JSX.Element;
|
|
1746
1756
|
//#endregion
|
|
1747
1757
|
//#region src/components/data-table/data-table-faceted-filter.d.ts
|
|
1748
1758
|
interface DataTableFacetedFilterProps<TData, TValue> {
|
|
@@ -1756,7 +1766,7 @@ declare function DataTableFacetedFilter<TData, TValue>({
|
|
|
1756
1766
|
title,
|
|
1757
1767
|
options,
|
|
1758
1768
|
multiple
|
|
1759
|
-
}: DataTableFacetedFilterProps<TData, TValue>):
|
|
1769
|
+
}: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime9.JSX.Element;
|
|
1760
1770
|
//#endregion
|
|
1761
1771
|
//#region src/components/data-table/data-table-pagination.d.ts
|
|
1762
1772
|
interface DataTablePaginationProps<TData> extends React.ComponentProps<'div'>, TablePaginationOptions {
|
|
@@ -1772,7 +1782,7 @@ declare function DataTablePagination<TData>({
|
|
|
1772
1782
|
pageJumpLabel,
|
|
1773
1783
|
className,
|
|
1774
1784
|
...props
|
|
1775
|
-
}: DataTablePaginationProps<TData>):
|
|
1785
|
+
}: DataTablePaginationProps<TData>): react_jsx_runtime9.JSX.Element;
|
|
1776
1786
|
//#endregion
|
|
1777
1787
|
//#region src/components/data-table/data-table-toolbar.d.ts
|
|
1778
1788
|
interface DataTableToolbarProps<TData> extends React$1.ComponentProps<'div'> {
|
|
@@ -1783,7 +1793,7 @@ declare function DataTableToolbar<TData>({
|
|
|
1783
1793
|
children,
|
|
1784
1794
|
className,
|
|
1785
1795
|
...props
|
|
1786
|
-
}: DataTableToolbarProps<TData>):
|
|
1796
|
+
}: DataTableToolbarProps<TData>): react_jsx_runtime9.JSX.Element;
|
|
1787
1797
|
//#endregion
|
|
1788
1798
|
//#region src/components/data-table/data-table-view-options.d.ts
|
|
1789
1799
|
interface DataTableViewOptionsProps<TData> extends PopoverContentProps {
|
|
@@ -1796,7 +1806,7 @@ declare function DataTableViewOptions<TData>({
|
|
|
1796
1806
|
disabled,
|
|
1797
1807
|
locale,
|
|
1798
1808
|
...props
|
|
1799
|
-
}: DataTableViewOptionsProps<TData>):
|
|
1809
|
+
}: DataTableViewOptionsProps<TData>): react_jsx_runtime9.JSX.Element;
|
|
1800
1810
|
//#endregion
|
|
1801
1811
|
//#region src/lib/crud-actions.d.ts
|
|
1802
1812
|
type CrudActionZone = 'toolbar' | 'row' | 'batch';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { a as positionActions, i as matchesPosition, n as actionPositionSchema,
|
|
|
2
2
|
import * as React$1 from "react";
|
|
3
3
|
import { ComponentProps, ReactNode } from "react";
|
|
4
4
|
import * as _tanstack_react_table0 from "@tanstack/react-table";
|
|
5
|
-
import { Column, ColumnDef, ColumnMeta, ColumnSort, Row, RowData, Table, TableOptions, TableState } from "@tanstack/react-table";
|
|
5
|
+
import { Column, ColumnDef, ColumnMeta, ColumnSort, Row, RowData, Table, TableOptions, TableState, VisibilityState } from "@tanstack/react-table";
|
|
6
6
|
import { DropdownMenuTrigger, PopoverContentProps } from "@wordrhyme/shadcn";
|
|
7
7
|
import { ClassValue } from "clsx";
|
|
8
8
|
import * as react_jsx_runtime8 from "react/jsx-runtime";
|
|
@@ -471,6 +471,7 @@ interface ImportResult {
|
|
|
471
471
|
* Hook 返回值类型
|
|
472
472
|
*/
|
|
473
473
|
interface UseAutoCrudResourceReturn<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem> {
|
|
474
|
+
queryKeys?: Partial<QueryKeys>;
|
|
474
475
|
/** 主键字段名(默认: "id") */
|
|
475
476
|
idKey?: keyof TListItem & string;
|
|
476
477
|
tableData: {
|
|
@@ -574,6 +575,8 @@ interface AutoQueryParams {
|
|
|
574
575
|
interface UseAutoCrudResourceParams<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem> {
|
|
575
576
|
/** tRPC router (如 trpc.tasks) */
|
|
576
577
|
router: CrudRouter;
|
|
578
|
+
/** URL keys shared with the table, for multiple resources on one page. */
|
|
579
|
+
queryKeys?: Partial<QueryKeys>;
|
|
577
580
|
/** Zod schema */
|
|
578
581
|
schema: TSchema;
|
|
579
582
|
/** Field filter configuration shared with AutoCrudTable. */
|
|
@@ -602,6 +605,7 @@ interface UseAutoCrudResourceParams<TSchema extends z.ZodObject<z.ZodRawShape>,
|
|
|
602
605
|
*/
|
|
603
606
|
declare function useAutoCrudResource<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem = z.output<TSchema>>({
|
|
604
607
|
router,
|
|
608
|
+
queryKeys,
|
|
605
609
|
schema,
|
|
606
610
|
query: queryTransform,
|
|
607
611
|
fields,
|
|
@@ -1016,6 +1020,10 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> extends Pick<Data
|
|
|
1016
1020
|
/** 按元素分组的全局表格类名 */
|
|
1017
1021
|
classNames?: DataTableClassNames;
|
|
1018
1022
|
enableRowSelection?: boolean;
|
|
1023
|
+
/** URL keys shared with useAutoCrudResource. */
|
|
1024
|
+
queryKeys?: Partial<QueryKeys>;
|
|
1025
|
+
/** Initial visibility; users can still toggle columns in the view options. */
|
|
1026
|
+
initialColumnVisibility?: VisibilityState;
|
|
1019
1027
|
exclude?: (keyof z.infer<T>)[];
|
|
1020
1028
|
filterOnly?: string[];
|
|
1021
1029
|
actions?: ActionsColumnConfig<z.infer<T>>;
|
|
@@ -1078,6 +1086,8 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
1078
1086
|
overrides,
|
|
1079
1087
|
classNames,
|
|
1080
1088
|
enableRowSelection,
|
|
1089
|
+
queryKeys,
|
|
1090
|
+
initialColumnVisibility,
|
|
1081
1091
|
exclude,
|
|
1082
1092
|
filterOnly,
|
|
1083
1093
|
actions,
|
|
@@ -1481,7 +1491,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
|
|
|
1481
1491
|
* 支持共用配置(label, hidden)+ 表格/表单特定配置
|
|
1482
1492
|
*/
|
|
1483
1493
|
fields?: Fields;
|
|
1484
|
-
/**
|
|
1494
|
+
/** Details share form layout and field formatting by default. */
|
|
1485
1495
|
view?: {
|
|
1486
1496
|
/** Explicitly reuse custom list cells with a separate, single-row table context. */
|
|
1487
1497
|
presentation?: 'table';
|
|
@@ -1523,7 +1533,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
|
|
|
1523
1533
|
batchActions?: BatchActionConfig<z.output<TSchema>>;
|
|
1524
1534
|
/** 默认排序 */
|
|
1525
1535
|
defaultSort?: any[];
|
|
1526
|
-
} & Pick<AutoTableProps<TSchema>, 'getRowId' | 'expandedRow' | 'defaultExpanded'>;
|
|
1536
|
+
} & Pick<AutoTableProps<TSchema>, 'getRowId' | 'expandedRow' | 'defaultExpanded' | 'enableRowSelection' | 'initialColumnVisibility' | 'queryKeys'>;
|
|
1527
1537
|
/** 表单配置 */
|
|
1528
1538
|
form?: {
|
|
1529
1539
|
/** 表单覆盖配置(兼容旧 API,优先级低于 fieldOverrides) */
|
package/dist/index.js
CHANGED
|
@@ -5106,7 +5106,7 @@ function useDataTable(props) {
|
|
|
5106
5106
|
...tableProps.defaultColumn,
|
|
5107
5107
|
enableColumnFilter: false
|
|
5108
5108
|
},
|
|
5109
|
-
enableRowSelection: true,
|
|
5109
|
+
enableRowSelection: tableProps.enableRowSelection ?? true,
|
|
5110
5110
|
onRowSelectionChange: setRowSelection,
|
|
5111
5111
|
onPaginationChange,
|
|
5112
5112
|
onSortingChange,
|
|
@@ -5172,7 +5172,7 @@ const filterModeConfig = {
|
|
|
5172
5172
|
tooltip: "Linear-style command filters"
|
|
5173
5173
|
}
|
|
5174
5174
|
};
|
|
5175
|
-
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, toolbarExtra, locale = enUSTableControls, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows, exportTableRef }) {
|
|
5175
|
+
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, queryKeys, initialColumnVisibility, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, toolbarExtra, locale = enUSTableControls, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows, exportTableRef }) {
|
|
5176
5176
|
if (expandedRow && !getRowId) throw new Error("AutoTable requires getRowId when expandedRow is provided.");
|
|
5177
5177
|
const enableExpansion = !!expandedRow;
|
|
5178
5178
|
const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
|
|
@@ -5182,7 +5182,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5182
5182
|
shallow: false,
|
|
5183
5183
|
clearOnDefault: true
|
|
5184
5184
|
});
|
|
5185
|
-
const [, setSearchPage] = useUrlState("page", parseAsInteger.withDefault(1), {
|
|
5185
|
+
const [, setSearchPage] = useUrlState(queryKeys?.page ?? "page", parseAsInteger.withDefault(1), {
|
|
5186
5186
|
shallow: false,
|
|
5187
5187
|
clearOnDefault: true
|
|
5188
5188
|
});
|
|
@@ -5249,6 +5249,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5249
5249
|
]);
|
|
5250
5250
|
const stableInitialState = useMemo(() => ({
|
|
5251
5251
|
sorting: initialSorting,
|
|
5252
|
+
columnVisibility: initialColumnVisibility,
|
|
5252
5253
|
expanded: enableExpansion && defaultExpanded ? true : {},
|
|
5253
5254
|
columnPinning: pinnedColumns ?? {
|
|
5254
5255
|
left: [...enableExpansion ? [expandColumnId] : [], ...enableRowSelection ? ["select"] : []],
|
|
@@ -5256,6 +5257,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5256
5257
|
}
|
|
5257
5258
|
}), [
|
|
5258
5259
|
initialSorting,
|
|
5260
|
+
initialColumnVisibility,
|
|
5259
5261
|
pinnedColumns,
|
|
5260
5262
|
enableRowSelection,
|
|
5261
5263
|
enableExpansion,
|
|
@@ -5267,6 +5269,8 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
5267
5269
|
const { table, shallow, debounceMs, throttleMs } = useDataTable({
|
|
5268
5270
|
data,
|
|
5269
5271
|
columns,
|
|
5272
|
+
queryKeys,
|
|
5273
|
+
enableRowSelection,
|
|
5270
5274
|
getRowId,
|
|
5271
5275
|
getRowCanExpand: () => enableExpansion,
|
|
5272
5276
|
getExpandedRowModel: enableExpansion ? expandedRowModel : void 0,
|
|
@@ -7801,12 +7805,13 @@ function ViewModalContent({ open, onOpenChange, variant, data, schema, fields: f
|
|
|
7801
7805
|
const detailSchema = React.useMemo(() => schema.omit(Object.fromEntries(excluded.map((key) => [key, true]))), [schema, excluded]);
|
|
7802
7806
|
const overrides = buildFormOverrides(fieldConfig, form?.overrides, denyFields, "view");
|
|
7803
7807
|
const renderers = {};
|
|
7804
|
-
for (const
|
|
7808
|
+
for (const cell of table.getRowModel().rows[0]?.getAllCells() ?? []) {
|
|
7805
7809
|
const key = cell.column.id;
|
|
7810
|
+
const index$1 = view?.overrides?.[key]?.index;
|
|
7806
7811
|
overrides[key] = {
|
|
7807
7812
|
...overrides[key],
|
|
7808
7813
|
title: cell.column.columnDef.meta?.label ?? humanize(key),
|
|
7809
|
-
"x-index": index$1
|
|
7814
|
+
...index$1 !== void 0 ? { "x-index": index$1 } : {}
|
|
7810
7815
|
};
|
|
7811
7816
|
renderers[key] = () => flexRender(cell.column.columnDef.cell, cell.getContext());
|
|
7812
7817
|
delete overrides[key]["x-data-source"];
|
|
@@ -8293,6 +8298,9 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
8293
8298
|
pageCount: resource.tableData.pageCount,
|
|
8294
8299
|
pagination: paginationOptions,
|
|
8295
8300
|
...resource.tableData.total !== void 0 ? { total: resource.tableData.total } : {},
|
|
8301
|
+
queryKeys: tableConfig?.queryKeys ?? resource.queryKeys,
|
|
8302
|
+
enableRowSelection: tableConfig?.enableRowSelection,
|
|
8303
|
+
initialColumnVisibility: tableConfig?.initialColumnVisibility,
|
|
8296
8304
|
getRowId: tableConfig?.getRowId,
|
|
8297
8305
|
expandedRow: tableConfig?.expandedRow,
|
|
8298
8306
|
defaultExpanded: tableConfig?.defaultExpanded,
|
|
@@ -9138,7 +9146,7 @@ function modalReducer(state, action$1) {
|
|
|
9138
9146
|
/**
|
|
9139
9147
|
* Hook 主函数
|
|
9140
9148
|
*/
|
|
9141
|
-
function useAutoCrudResource({ router, schema, query: queryTransform, fields, options = {} }) {
|
|
9149
|
+
function useAutoCrudResource({ router, queryKeys, schema, query: queryTransform, fields, options = {} }) {
|
|
9142
9150
|
const { idKey = "id", defaultVariant = "dialog", hooks, toast: toastAdapter, exportFetcher, defaultSort: defaultSortOption } = options;
|
|
9143
9151
|
const toast$1 = useMemo(() => toastAdapter === false ? noopToastAdapter : toastAdapter ?? defaultToastAdapter, [toastAdapter]);
|
|
9144
9152
|
const hooksRef = useRef(hooks);
|
|
@@ -9159,31 +9167,36 @@ function useAutoCrudResource({ router, schema, query: queryTransform, fields, op
|
|
|
9159
9167
|
fields,
|
|
9160
9168
|
metadataFields
|
|
9161
9169
|
]);
|
|
9162
|
-
const [
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
+
const [page] = useQueryState(queryKeys?.page ?? "page", parseAsInteger.withDefault(1));
|
|
9171
|
+
const [perPage] = useQueryState(queryKeys?.perPage ?? "perPage", parseAsInteger.withDefault(10));
|
|
9172
|
+
const [sort] = useQueryState(queryKeys?.sort ?? "sort", getSortingStateParser().withDefault(defaultSorting));
|
|
9173
|
+
const [joinOperator] = useQueryState(queryKeys?.joinOperator ?? "joinOperator", parseAsStringEnum(["and", "or"]).withDefault("and"));
|
|
9174
|
+
const [search] = useQueryState("search", parseAsString.withDefault(""), { shallow: false });
|
|
9175
|
+
const [filters] = useReadableFilters(columns, {
|
|
9176
|
+
shallow: false,
|
|
9177
|
+
resetPageKey: queryKeys?.page ?? "page"
|
|
9178
|
+
});
|
|
9170
9179
|
const metadataPending = Boolean(metadataQuery?.isPending);
|
|
9171
9180
|
const [filtersReady, setFiltersReady] = useState(!metadataPending);
|
|
9172
9181
|
useEffect(() => setFiltersReady(!metadataPending), [metadataPending]);
|
|
9173
9182
|
const listReady = !metadataPending && filtersReady;
|
|
9174
9183
|
const queryInput = useMemo(() => {
|
|
9175
9184
|
const autoParams = {
|
|
9176
|
-
page
|
|
9177
|
-
perPage
|
|
9178
|
-
sort
|
|
9185
|
+
page,
|
|
9186
|
+
perPage,
|
|
9187
|
+
sort,
|
|
9179
9188
|
filters,
|
|
9180
|
-
joinOperator
|
|
9181
|
-
...
|
|
9189
|
+
joinOperator,
|
|
9190
|
+
...search.trim() ? { search: search.trim() } : {}
|
|
9182
9191
|
};
|
|
9183
9192
|
return queryTransform ? queryTransform(autoParams) : autoParams;
|
|
9184
9193
|
}, [
|
|
9185
|
-
|
|
9194
|
+
page,
|
|
9195
|
+
perPage,
|
|
9196
|
+
sort,
|
|
9186
9197
|
filters,
|
|
9198
|
+
joinOperator,
|
|
9199
|
+
search,
|
|
9187
9200
|
queryTransform
|
|
9188
9201
|
]);
|
|
9189
9202
|
const hasReadyListData = useRef(false);
|
|
@@ -9459,6 +9472,7 @@ function useAutoCrudResource({ router, schema, query: queryTransform, fields, op
|
|
|
9459
9472
|
}, [listQuery, listReady]);
|
|
9460
9473
|
return {
|
|
9461
9474
|
idKey,
|
|
9475
|
+
queryKeys,
|
|
9462
9476
|
tableData: {
|
|
9463
9477
|
data: tableRows,
|
|
9464
9478
|
pageCount: listData?.pageCount ?? 0,
|
|
@@ -9746,18 +9760,21 @@ function createMemoryDataSource(initialData = []) {
|
|
|
9746
9760
|
let filtered = [...data];
|
|
9747
9761
|
if (params.filters) filtered = filtered.filter((item) => {
|
|
9748
9762
|
return params.filters.every((filter) => {
|
|
9749
|
-
|
|
9763
|
+
const value = item[filter.id];
|
|
9764
|
+
if (filter.operator === "inArray") return Array.isArray(filter.value) && filter.value.includes(value);
|
|
9765
|
+
if (!filter.operator || filter.operator === "eq") return value === filter.value;
|
|
9766
|
+
throw new Error(`Unsupported memory filter operator: ${filter.operator}`);
|
|
9750
9767
|
});
|
|
9751
9768
|
});
|
|
9752
|
-
if (params.sort && params.sort.length > 0) {
|
|
9753
|
-
const sortItem
|
|
9754
|
-
filtered.sort((a, b) => {
|
|
9769
|
+
if (params.sort && params.sort.length > 0) filtered.sort((a, b) => {
|
|
9770
|
+
for (const sortItem of params.sort) {
|
|
9755
9771
|
const aVal = a[sortItem.id];
|
|
9756
9772
|
const bVal = b[sortItem.id];
|
|
9757
9773
|
const result = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
|
|
9758
|
-
return sortItem.desc ? -result : result;
|
|
9759
|
-
}
|
|
9760
|
-
|
|
9774
|
+
if (result) return sortItem.desc ? -result : result;
|
|
9775
|
+
}
|
|
9776
|
+
return 0;
|
|
9777
|
+
});
|
|
9761
9778
|
const start = (params.page - 1) * params.perPage;
|
|
9762
9779
|
const end = start + params.perPage;
|
|
9763
9780
|
return {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordrhyme/auto-crud",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.14.1",
|
|
5
5
|
"description": "Schema-first CRUD components with auto-generated tables and forms",
|
|
6
6
|
"author": "wordrhyme",
|
|
7
7
|
"license": "MIT",
|
|
@@ -95,9 +95,9 @@
|
|
|
95
95
|
"typescript": "^5.9.3",
|
|
96
96
|
"vitest": "^3.2.4",
|
|
97
97
|
"@internal/eslint-config": "0.3.0",
|
|
98
|
+
"@internal/tsconfig": "0.1.0",
|
|
98
99
|
"@internal/prettier-config": "0.0.1",
|
|
99
100
|
"@internal/tsdown-config": "0.1.0",
|
|
100
|
-
"@internal/tsconfig": "0.1.0",
|
|
101
101
|
"@internal/vitest-config": "0.1.0"
|
|
102
102
|
},
|
|
103
103
|
"prettier": "@internal/prettier-config",
|