@wordrhyme/auto-crud 1.1.1 → 1.1.3

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/dist/index.cjs CHANGED
@@ -59,6 +59,8 @@ let __pixpilot_formily_shadcn = require("@pixpilot/formily-shadcn");
59
59
  __pixpilot_formily_shadcn = __toESM(__pixpilot_formily_shadcn);
60
60
  let __formily_react = require("@formily/react");
61
61
  __formily_react = __toESM(__formily_react);
62
+ let __pixpilot_shadcn_ui = require("@pixpilot/shadcn-ui");
63
+ __pixpilot_shadcn_ui = __toESM(__pixpilot_shadcn_ui);
62
64
  let sonner = require("sonner");
63
65
  sonner = __toESM(sonner);
64
66
 
@@ -2705,8 +2707,17 @@ function DataTableViewOptions({ table, disabled,...props }) {
2705
2707
 
2706
2708
  //#endregion
2707
2709
  //#region src/components/auto-crud/auto-table-simple-filters.tsx
2708
- function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilters, onFiltersChange }) {
2709
- const columns = react.useMemo(() => table.getAllColumns().filter((col) => col.getCanFilter()), [table]);
2710
+ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilters, onFiltersChange, leading }) {
2711
+ const columns = react.useMemo(() => table.getAllColumns().filter((col) => col.getCanFilter()).sort((a, b) => {
2712
+ const readOrder = (column) => {
2713
+ const metaIndex = column.columnDef.meta?.index;
2714
+ const columnIndex = column.columnDef.index;
2715
+ return typeof metaIndex === "number" ? metaIndex : typeof columnIndex === "number" ? columnIndex : 1e4;
2716
+ };
2717
+ const orderDiff = readOrder(a) - readOrder(b);
2718
+ if (orderDiff !== 0) return orderDiff;
2719
+ return a.getIndex() - b.getIndex();
2720
+ }), [table]);
2710
2721
  const queryStateOptions = table.options.meta?.queryStateOptions;
2711
2722
  const [queryFilters, setQueryFilters] = useReadableFilters(columns, {
2712
2723
  ...queryStateOptions,
@@ -2823,8 +2834,9 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
2823
2834
  if (!mounted) return null;
2824
2835
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2825
2836
  ref: containerRef,
2826
- className: "flex flex-wrap items-center gap-2 min-w-0",
2837
+ className: "flex flex-1 flex-wrap items-center gap-2 min-w-0",
2827
2838
  children: [
2839
+ leading,
2828
2840
  filterColumns.map((column, index) => {
2829
2841
  const meta = column.columnDef.meta;
2830
2842
  const value = getFilterValue(column.id);
@@ -3957,7 +3969,7 @@ function createTableSchema(schema, options) {
3957
3969
  if (cached) return [...cached];
3958
3970
  }
3959
3971
  const shape = schema.shape;
3960
- const columns = [];
3972
+ const columnEntries = [];
3961
3973
  for (const [key, fieldSchema] of Object.entries(shape)) {
3962
3974
  if (exclude.includes(key)) continue;
3963
3975
  const override = overrides?.[key];
@@ -3978,20 +3990,31 @@ function createTableSchema(schema, options) {
3978
3990
  options: override?.meta?.options ?? autoOptions
3979
3991
  };
3980
3992
  const { meta: _ignoredMeta,...restOverride } = override ?? {};
3981
- columns.push({
3982
- id: key,
3983
- accessorKey: key,
3984
- header: ({ column }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableColumnHeader, {
3985
- column,
3986
- label
3987
- }),
3988
- cell: ({ row }) => renderCell(row.getValue(key), parsed.type),
3989
- enableColumnFilter: true,
3990
- enableSorting: true,
3991
- meta,
3992
- ...restOverride
3993
+ const sourceIndex = columnEntries.length;
3994
+ const order = typeof restOverride.index === "number" ? restOverride.index : typeof meta.index === "number" ? meta.index : 1e4 + sourceIndex;
3995
+ columnEntries.push({
3996
+ order,
3997
+ sourceIndex,
3998
+ column: {
3999
+ id: key,
4000
+ accessorKey: key,
4001
+ header: ({ column }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableColumnHeader, {
4002
+ column,
4003
+ label
4004
+ }),
4005
+ cell: ({ row }) => renderCell(row.getValue(key), parsed.type),
4006
+ enableColumnFilter: true,
4007
+ enableSorting: true,
4008
+ meta,
4009
+ ...restOverride
4010
+ }
3993
4011
  });
3994
4012
  }
4013
+ const columns = columnEntries.sort((a, b) => {
4014
+ const orderDiff = a.order - b.order;
4015
+ if (orderDiff !== 0) return orderDiff;
4016
+ return a.sourceIndex - b.sourceIndex;
4017
+ }).map((entry) => entry.column);
3995
4018
  if (canCache) baseTableSchemaCache.set(schema, columns);
3996
4019
  return columns;
3997
4020
  }
@@ -4318,12 +4341,12 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
4318
4341
  if (action.component) return renderComponent(action.component);
4319
4342
  if (action.type === "batchUpdate") return renderBatchUpdate(action.type);
4320
4343
  if (action.type === "export") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBarItem, {
4321
- onClick: () => action.onClick ? action.onClick(selectedRows, actionContext) : onExport(),
4344
+ onClick: (event) => action.onClick ? action.onClick(selectedRows, actionContext, event) : onExport(),
4322
4345
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, {}), action.label ?? "Export"]
4323
4346
  }, "export");
4324
4347
  if (action.type === "delete") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBarItem, {
4325
4348
  variant: "destructive",
4326
- onClick: () => action.onClick ? action.onClick(selectedRows, actionContext) : onDelete(),
4349
+ onClick: (event) => action.onClick ? action.onClick(selectedRows, actionContext, event) : onDelete(),
4327
4350
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, {}), action.label ?? "Delete"]
4328
4351
  }, "delete");
4329
4352
  return null;
@@ -4345,7 +4368,7 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
4345
4368
  if (!action.label || !action.onClick) return null;
4346
4369
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarItem, {
4347
4370
  variant: action.variant === "destructive" ? "destructive" : "secondary",
4348
- onClick: () => action.onClick?.(selectedRows, actionContext),
4371
+ onClick: (event) => action.onClick?.(selectedRows, actionContext, event),
4349
4372
  children: action.label
4350
4373
  }, `custom-${index}`);
4351
4374
  }, [
@@ -4663,10 +4686,19 @@ const filterModeConfig = {
4663
4686
  tooltip: "Linear-style command filters"
4664
4687
  }
4665
4688
  };
4666
- function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, getSelectedRows }) {
4689
+ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, getSelectedRows }) {
4667
4690
  const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
4668
4691
  const [currentMode, setCurrentMode] = useQueryState("filterMode", parseAsStringEnum(modes).withDefault(modes[0] ?? "simple"));
4669
4692
  const showToggle = modes.length > 1;
4693
+ const [searchValue, setSearchValue] = useUrlState("search", parseAsString.withDefault(""), {
4694
+ shallow: false,
4695
+ clearOnDefault: true
4696
+ });
4697
+ const [, setSearchPage] = useUrlState("page", parseAsInteger.withDefault(1), {
4698
+ shallow: false,
4699
+ clearOnDefault: true
4700
+ });
4701
+ const searchConfig = search && typeof search === "object" ? search : {};
4670
4702
  const { table, shallow, debounceMs, throttleMs } = useDataTable({
4671
4703
  data,
4672
4704
  columns: (0, react.useMemo)(() => {
@@ -4738,11 +4770,21 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4738
4770
  })
4739
4771
  })
4740
4772
  })] }) : null;
4773
+ const searchInput = search ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Input, {
4774
+ value: searchValue,
4775
+ onChange: (event) => {
4776
+ setSearchValue(event.target.value);
4777
+ setSearchPage(1);
4778
+ },
4779
+ placeholder: searchConfig.placeholder ?? "搜索",
4780
+ className: "h-8 w-48 shrink-0"
4781
+ }) : null;
4741
4782
  const filtersContent = (0, react.useMemo)(() => {
4742
4783
  switch (currentMode) {
4743
4784
  case "simple": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoTableSimpleFilters, {
4744
4785
  table,
4745
- shallow
4786
+ shallow,
4787
+ leading: searchInput
4746
4788
  });
4747
4789
  case "command": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableFilterMenu, {
4748
4790
  table,
@@ -4762,6 +4804,7 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4762
4804
  currentMode,
4763
4805
  table,
4764
4806
  shallow,
4807
+ searchInput,
4765
4808
  debounceMs,
4766
4809
  throttleMs
4767
4810
  ]);
@@ -4773,10 +4816,14 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4773
4816
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4774
4817
  className: "flex flex-1 items-start gap-2 min-h-[40px]",
4775
4818
  "data-filter-parent": true,
4776
- children: [currentMode !== "simple" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableSortList, {
4777
- table,
4778
- align: "start"
4779
- }), filtersContent]
4819
+ children: [
4820
+ currentMode !== "simple" && searchInput,
4821
+ currentMode !== "simple" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableSortList, {
4822
+ table,
4823
+ align: "start"
4824
+ }),
4825
+ filtersContent
4826
+ ]
4780
4827
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4781
4828
  className: "flex items-center gap-2",
4782
4829
  children: [
@@ -4965,10 +5012,44 @@ function createEditFormSchema(schema, options) {
4965
5012
 
4966
5013
  //#endregion
4967
5014
  //#region src/components/auto-crud/auto-form.tsx
5015
+ const COMBOBOX_LIST_CLASS = "[&_[cmdk-list]]:max-h-[360px]";
4968
5016
  const FormilySwitch = (0, __formily_react.connect)(__pixpilot_shadcn.Switch, (0, __formily_react.mapProps)({
4969
5017
  value: "checked",
4970
5018
  onInput: "onCheckedChange"
4971
5019
  }));
5020
+ const FormilyCombobox = (0, __formily_react.connect)(AutoCrudCombobox, (0, __formily_react.mapProps)({ dataSource: "options" }));
5021
+ function AutoCrudCombobox({ options = [], filter, className,...props }) {
5022
+ const resolvedFilter = (0, react.useMemo)(() => {
5023
+ if (typeof filter === "function") return filter;
5024
+ return createComboboxFilter(options);
5025
+ }, [filter, options]);
5026
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn_ui.Combobox, {
5027
+ ...props,
5028
+ options,
5029
+ filter: resolvedFilter,
5030
+ className: (0, __pixpilot_shadcn.cn)(COMBOBOX_LIST_CLASS, className)
5031
+ });
5032
+ }
5033
+ function createComboboxFilter(options) {
5034
+ const searchTextByValue = new Map(options.map((option) => [option.value, collectSearchText(option.value, option.label, option.searchText, option.keywords).toLocaleLowerCase()]));
5035
+ return (value, search, keywords) => {
5036
+ const query = search.trim().toLocaleLowerCase();
5037
+ if (!query) return 1;
5038
+ const searchText = collectSearchText(searchTextByValue.get(value), keywords).toLocaleLowerCase();
5039
+ if (searchText === query) return 2;
5040
+ return searchText.includes(query) ? 1 : 0;
5041
+ };
5042
+ }
5043
+ function collectSearchText(...parts) {
5044
+ const texts = [];
5045
+ for (const part of parts) {
5046
+ if (!part) continue;
5047
+ if (Array.isArray(part)) texts.push(...part.map(String));
5048
+ else if (typeof part === "object") texts.push(...Object.values(part).filter(Boolean).map(String));
5049
+ else texts.push(String(part));
5050
+ }
5051
+ return texts.join(" ");
5052
+ }
4972
5053
  function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides, mode = "create", loading = false, gridColumns = 1, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
4973
5054
  const form = (0, react.useMemo)(() => (0, __formily_core.createForm)({ initialValues }), [JSON.stringify(initialValues)]);
4974
5055
  const formSchema = (0, react.useMemo)(() => createEditFormSchema(zodSchema, {
@@ -4993,10 +5074,16 @@ function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides,
4993
5074
  form,
4994
5075
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_formily_shadcn.JsonSchemaField, {
4995
5076
  schema: formSchema,
4996
- components: { fields: { Switch: {
4997
- component: FormilySwitch,
4998
- decorator: "FormItem"
4999
- } } }
5077
+ components: { fields: {
5078
+ Combobox: {
5079
+ component: FormilyCombobox,
5080
+ decorator: "FormItem"
5081
+ },
5082
+ Switch: {
5083
+ component: FormilySwitch,
5084
+ decorator: "FormItem"
5085
+ }
5086
+ } }
5000
5087
  }), showSubmitButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5001
5088
  className: "flex justify-end gap-2 mt-6",
5002
5089
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
@@ -6088,6 +6175,11 @@ function resolveActions(actionsOrFn, defaults, rowActionsLocale) {
6088
6175
  */
6089
6176
  function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, permissions, actions: actionItems, toolbarActions, locale: localeProp, onCreate }) {
6090
6177
  const locale = resolveLocale(localeProp);
6178
+ const resolvedSchema = resource.schema ?? schema;
6179
+ const resolvedFields = react.useMemo(() => ({
6180
+ ...fields,
6181
+ ...resource.fields
6182
+ }), [fields, resource.fields]);
6091
6183
  const can = {
6092
6184
  create: permissions?.can?.create ?? true,
6093
6185
  update: permissions?.can?.update ?? true,
@@ -6103,10 +6195,10 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6103
6195
  const [exporting, setExporting] = react.useState(false);
6104
6196
  const getSelectedRowsRef = react.useRef(null);
6105
6197
  const importColumns = react.useMemo(() => {
6106
- const shape = schema.shape;
6198
+ const shape = resolvedSchema.shape;
6107
6199
  const denySet = new Set(denyFields ?? []);
6108
6200
  return Object.keys(shape).filter((key) => !denySet.has(key));
6109
- }, [schema, denyFields]);
6201
+ }, [resolvedSchema, denyFields]);
6110
6202
  const handleExport = react.useCallback(async (mode) => {
6111
6203
  const filename = title ?? "export";
6112
6204
  const excludeColumns = denyFields;
@@ -6138,21 +6230,34 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6138
6230
  setExporting(false);
6139
6231
  }
6140
6232
  }, [selectedCount, handleExport]);
6141
- const tableOverrides = react.useMemo(() => buildTableOverrides(fields, tableConfig?.overrides), [fields, tableConfig?.overrides]);
6142
- const formOverrides = react.useMemo(() => buildFormOverrides(fields, formConfig?.overrides, denyFields), [
6143
- fields,
6233
+ const tableOverrides = react.useMemo(() => buildTableOverrides(resolvedFields, tableConfig?.overrides), [resolvedFields, tableConfig?.overrides]);
6234
+ const formOverrides = react.useMemo(() => buildFormOverrides(resolvedFields, formConfig?.overrides, denyFields), [
6235
+ resolvedFields,
6144
6236
  formConfig?.overrides,
6145
6237
  denyFields
6146
6238
  ]);
6147
- const hiddenColumns = react.useMemo(() => buildHiddenColumns(fields, tableConfig?.hidden, denyFields), [
6148
- fields,
6239
+ const hiddenColumns = react.useMemo(() => buildHiddenColumns(resolvedFields, tableConfig?.hidden, denyFields), [
6240
+ resolvedFields,
6149
6241
  tableConfig?.hidden,
6150
6242
  denyFields
6151
6243
  ]);
6152
- const batchFields = react.useMemo(() => buildBatchUpdateFields(schema, tableConfig?.batchFields, fields), [
6153
- schema,
6244
+ const searchConfig = react.useMemo(() => {
6245
+ const tableSearch = tableConfig?.search;
6246
+ if (tableSearch === false) return false;
6247
+ if (tableSearch && typeof tableSearch === "object") return tableSearch;
6248
+ return Object.values(resolvedFields).some((field) => field?.search === true) ? true : false;
6249
+ }, [resolvedFields, tableConfig?.search]);
6250
+ const batchFields = react.useMemo(() => buildBatchUpdateFields(resolvedSchema, tableConfig?.batchFields, resolvedFields), [
6251
+ resolvedSchema,
6154
6252
  tableConfig?.batchFields,
6155
- fields
6253
+ resolvedFields
6254
+ ]);
6255
+ const formInitialValues = react.useMemo(() => {
6256
+ return resource.modal.createOpen ? resource.modal.copySource ?? void 0 : resource.modal.selected ?? void 0;
6257
+ }, [
6258
+ resource.modal.createOpen,
6259
+ resource.modal.copySource,
6260
+ resource.modal.selected
6156
6261
  ]);
6157
6262
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6158
6263
  className: "space-y-4",
@@ -6233,11 +6338,12 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6233
6338
  }),
6234
6339
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoTable, {
6235
6340
  data: resource.tableData.data,
6236
- schema,
6341
+ schema: resolvedSchema,
6237
6342
  pageCount: resource.tableData.pageCount,
6238
6343
  overrides: tableOverrides,
6239
6344
  exclude: hiddenColumns,
6240
6345
  filterMode: tableConfig?.filterModes,
6346
+ search: searchConfig,
6241
6347
  actions: resolveActions(actionItems, {
6242
6348
  openView: resource.handlers.openView,
6243
6349
  openEdit: can.update ? resource.handlers.openEdit : void 0,
@@ -6258,8 +6364,8 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6258
6364
  open: resource.modal.createOpen || resource.modal.editOpen,
6259
6365
  onOpenChange: (open) => !open && resource.handlers.closeModals(),
6260
6366
  mode: resource.modal.createOpen ? "create" : "edit",
6261
- schema,
6262
- initialValues: resource.modal.createOpen ? resource.modal.copySource ?? void 0 : resource.modal.selected ?? void 0,
6367
+ schema: resolvedSchema,
6368
+ initialValues: formInitialValues,
6263
6369
  onSubmit: (values) => {
6264
6370
  if (resource.modal.createOpen) resource.handlers.submitCreate(values);
6265
6371
  else resource.handlers.submitUpdate(values);
@@ -6276,8 +6382,8 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6276
6382
  onOpenChange: (open) => !open && resource.handlers.closeModals(),
6277
6383
  variant: resource.modal.variant,
6278
6384
  data: resource.modal.selected,
6279
- schema,
6280
- fields,
6385
+ schema: resolvedSchema,
6386
+ fields: resolvedFields,
6281
6387
  denyFields,
6282
6388
  locale
6283
6389
  }),
@@ -6996,6 +7102,53 @@ const noopToastAdapter = {
6996
7102
  info: () => {},
6997
7103
  warning: () => {}
6998
7104
  };
7105
+ function isRecord(value) {
7106
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7107
+ }
7108
+ function isJsonSchemaObject(value) {
7109
+ return isRecord(value) && isRecord(value.properties);
7110
+ }
7111
+ function readJsonSchemaType(property) {
7112
+ return Array.isArray(property.type) ? property.type.find((item) => item !== "null") : property.type;
7113
+ }
7114
+ function jsonPropertyToZod(property, required) {
7115
+ const enumValues = property.enum?.filter((value) => typeof value === "string");
7116
+ let schema;
7117
+ if (enumValues && enumValues.length > 0) schema = zod.z.enum(enumValues);
7118
+ else switch (readJsonSchemaType(property)) {
7119
+ case "number":
7120
+ case "integer":
7121
+ schema = zod.z.number();
7122
+ break;
7123
+ case "boolean":
7124
+ schema = zod.z.boolean();
7125
+ break;
7126
+ case "array":
7127
+ schema = zod.z.array(zod.z.unknown());
7128
+ break;
7129
+ case "object":
7130
+ schema = zod.z.record(zod.z.string(), zod.z.unknown());
7131
+ break;
7132
+ case "string":
7133
+ schema = property.format === "date" || property.format === "date-time" ? zod.z.coerce.date() : zod.z.string();
7134
+ break;
7135
+ default: schema = zod.z.unknown();
7136
+ }
7137
+ return required ? schema : schema.optional();
7138
+ }
7139
+ function mergeMetadataSchema(baseSchema, metadataSchema) {
7140
+ if (!isJsonSchemaObject(metadataSchema)) return baseSchema;
7141
+ const required = new Set(Array.isArray(metadataSchema.required) ? metadataSchema.required.filter((field) => typeof field === "string") : []);
7142
+ const extensionShape = {};
7143
+ for (const [field, property] of Object.entries(metadataSchema.properties ?? {})) {
7144
+ if (field in baseSchema.shape) continue;
7145
+ extensionShape[field] = jsonPropertyToZod(property, required.has(field));
7146
+ }
7147
+ return Object.keys(extensionShape).length > 0 ? baseSchema.extend(extensionShape) : baseSchema;
7148
+ }
7149
+ function readMetadataFields(fields) {
7150
+ return isRecord(fields) ? fields : void 0;
7151
+ }
6999
7152
  /**
7000
7153
  * Modal 状态 Reducer
7001
7154
  */
@@ -7054,12 +7207,16 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
7054
7207
  (0, react.useEffect)(() => {
7055
7208
  hooksRef.current = hooks;
7056
7209
  }, [hooks]);
7057
- const columns = (0, react.useMemo)(() => createTableSchema(schema), [schema]);
7210
+ const metadata = (router.meta?.useQuery(void 0, { staleTime: 3e4 }))?.data;
7211
+ const resolvedSchema = (0, react.useMemo)(() => mergeMetadataSchema(schema, metadata?.schema), [schema, metadata?.schema]);
7212
+ const metadataFields = (0, react.useMemo)(() => readMetadataFields(metadata?.fields), [metadata?.fields]);
7213
+ const columns = (0, react.useMemo)(() => createTableSchema(resolvedSchema), [resolvedSchema]);
7058
7214
  const [urlParams] = useQueryStates({
7059
7215
  page: parseAsInteger.withDefault(1),
7060
7216
  perPage: parseAsInteger.withDefault(10),
7061
7217
  sort: getSortingStateParser().withDefault([]),
7062
- joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and")
7218
+ joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"),
7219
+ search: parseAsString.withDefault("")
7063
7220
  }, { shallow: false });
7064
7221
  const [filters] = useReadableFilters(columns, { shallow: false });
7065
7222
  const queryInput = (0, react.useMemo)(() => {
@@ -7068,7 +7225,8 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
7068
7225
  perPage: urlParams.perPage,
7069
7226
  sort: urlParams.sort,
7070
7227
  filters,
7071
- joinOperator: urlParams.joinOperator
7228
+ joinOperator: urlParams.joinOperator,
7229
+ ...urlParams.search.trim() ? { search: urlParams.search.trim() } : {}
7072
7230
  };
7073
7231
  return queryTransform ? queryTransform(autoParams) : autoParams;
7074
7232
  }, [
@@ -7080,6 +7238,7 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
7080
7238
  placeholderData: keepPreviousData,
7081
7239
  staleTime: 0
7082
7240
  });
7241
+ const tableRows = listQuery.data?.data ?? [];
7083
7242
  const createMutation = router.create.useMutation();
7084
7243
  const updateMutation = router.update.useMutation();
7085
7244
  const deleteMutation = router.delete.useMutation();
@@ -7332,11 +7491,13 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
7332
7491
  const canExport = !!(exportFetcher || exportQuery);
7333
7492
  return {
7334
7493
  tableData: {
7335
- data: listQuery.data?.data ?? [],
7494
+ data: tableRows,
7336
7495
  pageCount: listQuery.data?.pageCount ?? 0,
7337
7496
  isLoading: listQuery.isLoading,
7338
7497
  isFetching: listQuery.isFetching
7339
7498
  },
7499
+ schema: resolvedSchema,
7500
+ fields: metadataFields,
7340
7501
  modal,
7341
7502
  mutations: {
7342
7503
  isCreating: createMutation.isPending,