@wordrhyme/auto-crud 0.3.0 → 0.4.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/dist/index.cjs CHANGED
@@ -169,6 +169,55 @@ function DataTablePagination({ table, pageSizeOptions = [
169
169
  });
170
170
  }
171
171
 
172
+ //#endregion
173
+ //#region src/components/ui/table.tsx
174
+ function Table({ className,...props }) {
175
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
176
+ "data-slot": "table-container",
177
+ className: "relative w-full overflow-x-auto",
178
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("table", {
179
+ "data-slot": "table",
180
+ className: cn("w-full caption-bottom text-sm", className),
181
+ ...props
182
+ })
183
+ });
184
+ }
185
+ function TableHeader({ className,...props }) {
186
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", {
187
+ "data-slot": "table-header",
188
+ className: cn("[&_tr]:border-b", className),
189
+ ...props
190
+ });
191
+ }
192
+ function TableBody({ className,...props }) {
193
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", {
194
+ "data-slot": "table-body",
195
+ className: cn("[&_tr:last-child]:border-0", className),
196
+ ...props
197
+ });
198
+ }
199
+ function TableRow({ className,...props }) {
200
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", {
201
+ "data-slot": "table-row",
202
+ className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
203
+ ...props
204
+ });
205
+ }
206
+ function TableHead({ className,...props }) {
207
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
208
+ "data-slot": "table-head",
209
+ className: cn("h-10 whitespace-nowrap px-2 text-left align-middle font-medium text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
210
+ ...props
211
+ });
212
+ }
213
+ function TableCell({ className,...props }) {
214
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
215
+ "data-slot": "table-cell",
216
+ className: cn("whitespace-nowrap p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
217
+ ...props
218
+ });
219
+ }
220
+
172
221
  //#endregion
173
222
  //#region src/config/data-table.ts
174
223
  const dataTableConfig = {
@@ -401,17 +450,17 @@ function DataTable({ table, actionBar, children, className,...props }) {
401
450
  children,
402
451
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
403
452
  className: "overflow-hidden rounded-md border",
404
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Table, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableHead, {
453
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Table, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableHead, {
405
454
  colSpan: header.colSpan,
406
455
  style: { ...getColumnPinningStyle({ column: header.column }) },
407
456
  children: header.isPlaceholder ? null : (0, __tanstack_react_table.flexRender)(header.column.columnDef.header, header.getContext())
408
- }, header.id)) }, headerGroup.id)) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableRow, {
457
+ }, header.id)) }, headerGroup.id)) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableRow, {
409
458
  "data-state": row.getIsSelected() && "selected",
410
- children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableCell, {
459
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
411
460
  style: { ...getColumnPinningStyle({ column: cell.column }) },
412
461
  children: (0, __tanstack_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext())
413
462
  }, cell.id))
414
- }, row.id)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TableCell, {
463
+ }, row.id)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
415
464
  colSpan: table.getAllColumns().length,
416
465
  className: "h-24 text-center",
417
466
  children: "No results."
@@ -4201,7 +4250,7 @@ const filterModeConfig = {
4201
4250
  tooltip: "Linear-style command filters"
4202
4251
  }
4203
4252
  };
4204
- function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, initialSorting }) {
4253
+ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, initialSorting, enableExport = true }) {
4205
4254
  const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : [
4206
4255
  "simple",
4207
4256
  "advanced",
@@ -4318,6 +4367,7 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4318
4367
  onUpdateSelected,
4319
4368
  batchUpdateFields,
4320
4369
  enableDelete: !!onDeleteSelected,
4370
+ enableExport,
4321
4371
  extraActions: actionBarExtra
4322
4372
  })
4323
4373
  ]
@@ -4599,8 +4649,8 @@ function buildFormOverrides(fields, legacyOverrides) {
4599
4649
  /**
4600
4650
  * 从统一配置生成隐藏列列表
4601
4651
  */
4602
- function buildHiddenColumns(fields, legacyHidden) {
4603
- const hidden = new Set(legacyHidden ?? []);
4652
+ function buildHiddenColumns(fields, legacyHidden, denyFields) {
4653
+ const hidden = new Set([...legacyHidden ?? [], ...denyFields ?? []]);
4604
4654
  if (fields) {
4605
4655
  for (const [key, config] of Object.entries(fields)) if (config.hidden || config.table?.hidden) hidden.add(key);
4606
4656
  }
@@ -4715,10 +4765,16 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
4715
4765
  *
4716
4766
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
4717
4767
  */
4718
- function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots }) {
4768
+ function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions }) {
4769
+ const can = {
4770
+ create: permissions?.can?.create ?? true,
4771
+ update: permissions?.can?.update ?? true,
4772
+ delete: permissions?.can?.delete ?? true,
4773
+ export: permissions?.can?.export ?? true
4774
+ };
4719
4775
  const tableOverrides = buildTableOverrides(fields, tableConfig?.overrides);
4720
4776
  const formOverrides = buildFormOverrides(fields, formConfig?.overrides);
4721
- const hiddenColumns = buildHiddenColumns(fields, tableConfig?.hidden);
4777
+ const hiddenColumns = buildHiddenColumns(fields, tableConfig?.hidden, permissions?.deny);
4722
4778
  const batchFields = buildBatchUpdateFields(schema, tableConfig?.batchFields, fields);
4723
4779
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4724
4780
  className: "space-y-4",
@@ -4740,7 +4796,7 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
4740
4796
  children: slots?.toolbarStart
4741
4797
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4742
4798
  className: "flex items-center gap-2",
4743
- children: [slots?.toolbarEnd, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
4799
+ children: [slots?.toolbarEnd, can.create && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
4744
4800
  onClick: resource.handlers.openCreate,
4745
4801
  children: "新建"
4746
4802
  })]
@@ -4755,13 +4811,14 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
4755
4811
  filterMode: tableConfig?.filterModes,
4756
4812
  actions: {
4757
4813
  onView: resource.handlers.openView,
4758
- onEdit: resource.handlers.openEdit,
4759
- onCopy: resource.handlers.copyRow,
4760
- onDelete: resource.handlers.openDelete
4814
+ onEdit: can.update ? resource.handlers.openEdit : void 0,
4815
+ onCopy: can.create ? resource.handlers.copyRow : void 0,
4816
+ onDelete: can.delete ? resource.handlers.openDelete : void 0
4761
4817
  },
4762
- onDeleteSelected: resource.handlers.deleteMany,
4763
- onUpdateSelected: resource.handlers.updateMany,
4764
- batchUpdateFields: batchFields,
4818
+ onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
4819
+ onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
4820
+ batchUpdateFields: can.update ? batchFields : void 0,
4821
+ enableExport: can.export,
4765
4822
  initialSorting: tableConfig?.defaultSort
4766
4823
  }),
4767
4824
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CrudFormModal, {
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime2 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime3 from "react/jsx-runtime";
2
2
  import { z } from "zod";
3
3
  import * as _tanstack_react_table0 from "@tanstack/react-table";
4
4
  import { Column, ColumnDef, ColumnSort, Row, RowData, Table, TableOptions, TableState } from "@tanstack/react-table";
@@ -164,6 +164,50 @@ declare function useAutoCrudResource<TSchema extends z.ZodObject<z.ZodRawShape>,
164
164
  options
165
165
  }: UseAutoCrudResourceParams<TSchema, TListItem>): UseAutoCrudResourceReturn<TSchema, TListItem>;
166
166
  //#endregion
167
+ //#region src/types/permissions.d.ts
168
+ /**
169
+ * CRUD 操作权限
170
+ * 控制工具栏按钮、行操作按钮、批量操作按钮的显示
171
+ */
172
+ interface CrudOperationPermissions {
173
+ /** 是否允许创建(新建按钮、复制行操作) */
174
+ create?: boolean;
175
+ /** 是否允许更新(编辑按钮、批量更新) */
176
+ update?: boolean;
177
+ /** 是否允许删除(删除按钮、批量删除) */
178
+ delete?: boolean;
179
+ /** 是否允许导出 */
180
+ export?: boolean;
181
+ }
182
+ /**
183
+ * AutoCrudTable 权限配置
184
+ *
185
+ * @example
186
+ * ```tsx
187
+ * const permissions = useMemo(() => ({
188
+ * can: {
189
+ * create: user.role === 'admin',
190
+ * update: user.role === 'admin' || user.role === 'editor',
191
+ * delete: user.role === 'admin',
192
+ * export: true,
193
+ * },
194
+ * deny: user.role === 'user' ? ['salary', 'ssn'] : [],
195
+ * }), [user.role]);
196
+ *
197
+ * <AutoCrudTable
198
+ * schema={employeeSchema}
199
+ * resource={resource}
200
+ * permissions={permissions}
201
+ * />
202
+ * ```
203
+ */
204
+ interface CrudPermissions {
205
+ /** 操作权限(默认全部为 true) */
206
+ can?: CrudOperationPermissions;
207
+ /** 禁止访问的字段列表(表格列和表单字段都会隐藏) */
208
+ deny?: string[];
209
+ }
210
+ //#endregion
167
211
  //#region src/components/auto-crud/auto-table-action-bar.d.ts
168
212
  /** 批量更新字段配置 */
169
213
  interface BatchUpdateField {
@@ -199,7 +243,7 @@ declare function AutoTableActionBar<TData>({
199
243
  enableExport,
200
244
  enableDelete,
201
245
  extraActions
202
- }: AutoTableActionBarProps<TData>): react_jsx_runtime2.JSX.Element;
246
+ }: AutoTableActionBarProps<TData>): react_jsx_runtime3.JSX.Element;
203
247
  //#endregion
204
248
  //#region src/lib/schema-bridge/types.d.ts
205
249
  /**
@@ -323,6 +367,8 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> {
323
367
  actionBarExtra?: React.ReactNode;
324
368
  /** 初始排序 */
325
369
  initialSorting?: any[];
370
+ /** 是否启用导出功能 (默认 true) */
371
+ enableExport?: boolean;
326
372
  }
327
373
  declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
328
374
  schema,
@@ -338,8 +384,9 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
338
384
  onUpdateSelected,
339
385
  batchUpdateFields,
340
386
  actionBarExtra,
341
- initialSorting
342
- }: AutoTableProps<T>): react_jsx_runtime2.JSX.Element;
387
+ initialSorting,
388
+ enableExport
389
+ }: AutoTableProps<T>): react_jsx_runtime3.JSX.Element;
343
390
  //#endregion
344
391
  //#region src/components/auto-crud/auto-crud-table.d.ts
345
392
  /**
@@ -430,6 +477,26 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
430
477
  onClick: () => void;
431
478
  }>;
432
479
  };
480
+ /**
481
+ * 权限配置
482
+ * 控制按钮显示和字段访问
483
+ *
484
+ * @example
485
+ * ```tsx
486
+ * const permissions = useMemo(() => ({
487
+ * can: {
488
+ * create: user.role === 'admin',
489
+ * update: user.role === 'admin' || user.role === 'editor',
490
+ * delete: user.role === 'admin',
491
+ * export: true,
492
+ * },
493
+ * deny: user.role === 'user' ? ['salary', 'ssn'] : [],
494
+ * }), [user.role]);
495
+ *
496
+ * <AutoCrudTable permissions={permissions} ... />
497
+ * ```
498
+ */
499
+ permissions?: CrudPermissions;
433
500
  }
434
501
  /**
435
502
  * AutoCrudTable 组件
@@ -444,8 +511,9 @@ declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
444
511
  fields,
445
512
  table: tableConfig,
446
513
  form: formConfig,
447
- slots
448
- }: AutoCrudTableProps<TSchema>): react_jsx_runtime2.JSX.Element;
514
+ slots,
515
+ permissions
516
+ }: AutoCrudTableProps<TSchema>): react_jsx_runtime3.JSX.Element;
449
517
  //#endregion
450
518
  //#region src/components/auto-crud/auto-form.d.ts
451
519
  interface AutoFormProps<T extends z.ZodObject<z.ZodRawShape>> {
@@ -477,7 +545,7 @@ declare function AutoFormInner<T extends z.ZodObject<z.ZodRawShape>>({
477
545
  labelAlign,
478
546
  labelWidth,
479
547
  showSubmitButton
480
- }: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime2.JSX.Element;
548
+ }: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime3.JSX.Element;
481
549
  declare const AutoForm: <T extends z.ZodObject<z.ZodRawShape>>(props: AutoFormProps<T> & {
482
550
  ref?: React.Ref<AutoFormRef>;
483
551
  }) => ReturnType<typeof AutoFormInner>;
@@ -691,12 +759,12 @@ declare const filterItemSchema: z.ZodObject<{
691
759
  variant: z.ZodEnum<{
692
760
  number: "number";
693
761
  boolean: "boolean";
694
- date: "date";
695
762
  text: "text";
763
+ range: "range";
764
+ date: "date";
765
+ dateRange: "dateRange";
696
766
  select: "select";
697
767
  multiSelect: "multiSelect";
698
- dateRange: "dateRange";
699
- range: "range";
700
768
  }>;
701
769
  operator: z.ZodEnum<{
702
770
  iLike: "iLike";
@@ -772,7 +840,7 @@ declare function AutoTableSimpleFilters<TData>({
772
840
  shallow,
773
841
  filters: externalFilters,
774
842
  onFiltersChange
775
- }: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime2.JSX.Element | null;
843
+ }: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime3.JSX.Element | null;
776
844
  //#endregion
777
845
  //#region src/components/auto-crud/form-modal.d.ts
778
846
  type ModalVariant = "dialog" | "sheet";
@@ -807,7 +875,7 @@ declare function CrudFormModal<T extends z.ZodObject<z.ZodRawShape>>({
807
875
  title,
808
876
  labelAlign,
809
877
  labelWidth
810
- }: CrudFormModalProps<T>): react_jsx_runtime2.JSX.Element;
878
+ }: CrudFormModalProps<T>): react_jsx_runtime3.JSX.Element;
811
879
  //#endregion
812
880
  //#region src/components/data-table/data-table.d.ts
813
881
  interface DataTableProps<TData> extends React$1.ComponentProps<"div"> {
@@ -820,7 +888,7 @@ declare function DataTable<TData>({
820
888
  children,
821
889
  className,
822
890
  ...props
823
- }: DataTableProps<TData>): react_jsx_runtime2.JSX.Element;
891
+ }: DataTableProps<TData>): react_jsx_runtime3.JSX.Element;
824
892
  //#endregion
825
893
  //#region src/components/data-table/data-table-advanced-toolbar.d.ts
826
894
  interface DataTableAdvancedToolbarProps<TData> extends React$1.ComponentProps<"div"> {
@@ -831,7 +899,7 @@ declare function DataTableAdvancedToolbar<TData>({
831
899
  children,
832
900
  className,
833
901
  ...props
834
- }: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime2.JSX.Element;
902
+ }: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime3.JSX.Element;
835
903
  //#endregion
836
904
  //#region src/components/data-table/data-table-column-header.d.ts
837
905
  interface DataTableColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {
@@ -843,7 +911,7 @@ declare function DataTableColumnHeader<TData, TValue>({
843
911
  label,
844
912
  className,
845
913
  ...props
846
- }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime2.JSX.Element;
914
+ }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime3.JSX.Element;
847
915
  //#endregion
848
916
  //#region src/components/data-table/data-table-faceted-filter.d.ts
849
917
  interface DataTableFacetedFilterProps<TData, TValue> {
@@ -857,7 +925,7 @@ declare function DataTableFacetedFilter<TData, TValue>({
857
925
  title,
858
926
  options,
859
927
  multiple
860
- }: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime2.JSX.Element;
928
+ }: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime3.JSX.Element;
861
929
  //#endregion
862
930
  //#region src/components/data-table/data-table-pagination.d.ts
863
931
  interface DataTablePaginationProps<TData> extends React.ComponentProps<"div"> {
@@ -869,7 +937,7 @@ declare function DataTablePagination<TData>({
869
937
  pageSizeOptions,
870
938
  className,
871
939
  ...props
872
- }: DataTablePaginationProps<TData>): react_jsx_runtime2.JSX.Element;
940
+ }: DataTablePaginationProps<TData>): react_jsx_runtime3.JSX.Element;
873
941
  //#endregion
874
942
  //#region src/components/data-table/data-table-toolbar.d.ts
875
943
  interface DataTableToolbarProps<TData> extends React$1.ComponentProps<"div"> {
@@ -880,7 +948,7 @@ declare function DataTableToolbar<TData>({
880
948
  children,
881
949
  className,
882
950
  ...props
883
- }: DataTableToolbarProps<TData>): react_jsx_runtime2.JSX.Element;
951
+ }: DataTableToolbarProps<TData>): react_jsx_runtime3.JSX.Element;
884
952
  //#endregion
885
953
  //#region src/components/data-table/data-table-view-options.d.ts
886
954
  interface DataTableViewOptionsProps<TData> extends React$1.ComponentProps<typeof PopoverContent> {
@@ -891,7 +959,7 @@ declare function DataTableViewOptions<TData>({
891
959
  table,
892
960
  disabled,
893
961
  ...props
894
- }: DataTableViewOptionsProps<TData>): react_jsx_runtime2.JSX.Element;
962
+ }: DataTableViewOptionsProps<TData>): react_jsx_runtime3.JSX.Element;
895
963
  //#endregion
896
964
  //#region src/hooks/use-data-table.d.ts
897
965
  interface UseDataTableProps<TData> extends Omit<TableOptions<TData>, "state" | "pageCount" | "getCoreRowModel" | "manualFiltering" | "manualPagination" | "manualSorting">, Required<Pick<TableOptions<TData>, "pageCount">> {
@@ -1162,4 +1230,4 @@ declare function formatDate(date: Date | string | number | undefined, opts?: Int
1162
1230
  */
1163
1231
  declare function humanize(str: string): string;
1164
1232
  //#endregion
1165
- export { type ActionsColumnConfig, AutoCrudTable, type AutoCrudTableProps, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldType, type Fields, FilterOperator, type FilterVariant, type FormSchemaOverrides, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, Option, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, cn, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, formatDate, getUrlParams, humanize, noopToastAdapter, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseZodField, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates };
1233
+ export { type ActionsColumnConfig, AutoCrudTable, type AutoCrudTableProps, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type CrudOperationPermissions, type CrudPermissions, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldType, type Fields, FilterOperator, type FilterVariant, type FormSchemaOverrides, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, Option, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, cn, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, formatDate, getUrlParams, humanize, noopToastAdapter, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseZodField, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as _tanstack_react_table0 from "@tanstack/react-table";
3
3
  import { Column, ColumnDef, ColumnSort, Row, RowData, Table, TableOptions, TableState } from "@tanstack/react-table";
4
4
  import { DropdownMenuTrigger, PopoverContent } from "@pixpilot/shadcn";
5
5
  import { ClassValue } from "clsx";
6
- import * as react_jsx_runtime7 from "react/jsx-runtime";
6
+ import * as react_jsx_runtime2 from "react/jsx-runtime";
7
7
  import { z } from "zod";
8
8
  import { ISchema } from "@formily/json-schema";
9
9
 
@@ -164,6 +164,50 @@ declare function useAutoCrudResource<TSchema extends z.ZodObject<z.ZodRawShape>,
164
164
  options
165
165
  }: UseAutoCrudResourceParams<TSchema, TListItem>): UseAutoCrudResourceReturn<TSchema, TListItem>;
166
166
  //#endregion
167
+ //#region src/types/permissions.d.ts
168
+ /**
169
+ * CRUD 操作权限
170
+ * 控制工具栏按钮、行操作按钮、批量操作按钮的显示
171
+ */
172
+ interface CrudOperationPermissions {
173
+ /** 是否允许创建(新建按钮、复制行操作) */
174
+ create?: boolean;
175
+ /** 是否允许更新(编辑按钮、批量更新) */
176
+ update?: boolean;
177
+ /** 是否允许删除(删除按钮、批量删除) */
178
+ delete?: boolean;
179
+ /** 是否允许导出 */
180
+ export?: boolean;
181
+ }
182
+ /**
183
+ * AutoCrudTable 权限配置
184
+ *
185
+ * @example
186
+ * ```tsx
187
+ * const permissions = useMemo(() => ({
188
+ * can: {
189
+ * create: user.role === 'admin',
190
+ * update: user.role === 'admin' || user.role === 'editor',
191
+ * delete: user.role === 'admin',
192
+ * export: true,
193
+ * },
194
+ * deny: user.role === 'user' ? ['salary', 'ssn'] : [],
195
+ * }), [user.role]);
196
+ *
197
+ * <AutoCrudTable
198
+ * schema={employeeSchema}
199
+ * resource={resource}
200
+ * permissions={permissions}
201
+ * />
202
+ * ```
203
+ */
204
+ interface CrudPermissions {
205
+ /** 操作权限(默认全部为 true) */
206
+ can?: CrudOperationPermissions;
207
+ /** 禁止访问的字段列表(表格列和表单字段都会隐藏) */
208
+ deny?: string[];
209
+ }
210
+ //#endregion
167
211
  //#region src/components/auto-crud/auto-table-action-bar.d.ts
168
212
  /** 批量更新字段配置 */
169
213
  interface BatchUpdateField {
@@ -199,7 +243,7 @@ declare function AutoTableActionBar<TData>({
199
243
  enableExport,
200
244
  enableDelete,
201
245
  extraActions
202
- }: AutoTableActionBarProps<TData>): react_jsx_runtime7.JSX.Element;
246
+ }: AutoTableActionBarProps<TData>): react_jsx_runtime2.JSX.Element;
203
247
  //#endregion
204
248
  //#region src/lib/schema-bridge/types.d.ts
205
249
  /**
@@ -323,6 +367,8 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> {
323
367
  actionBarExtra?: React.ReactNode;
324
368
  /** 初始排序 */
325
369
  initialSorting?: any[];
370
+ /** 是否启用导出功能 (默认 true) */
371
+ enableExport?: boolean;
326
372
  }
327
373
  declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
328
374
  schema,
@@ -338,8 +384,9 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
338
384
  onUpdateSelected,
339
385
  batchUpdateFields,
340
386
  actionBarExtra,
341
- initialSorting
342
- }: AutoTableProps<T>): react_jsx_runtime7.JSX.Element;
387
+ initialSorting,
388
+ enableExport
389
+ }: AutoTableProps<T>): react_jsx_runtime2.JSX.Element;
343
390
  //#endregion
344
391
  //#region src/components/auto-crud/auto-crud-table.d.ts
345
392
  /**
@@ -430,6 +477,26 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
430
477
  onClick: () => void;
431
478
  }>;
432
479
  };
480
+ /**
481
+ * 权限配置
482
+ * 控制按钮显示和字段访问
483
+ *
484
+ * @example
485
+ * ```tsx
486
+ * const permissions = useMemo(() => ({
487
+ * can: {
488
+ * create: user.role === 'admin',
489
+ * update: user.role === 'admin' || user.role === 'editor',
490
+ * delete: user.role === 'admin',
491
+ * export: true,
492
+ * },
493
+ * deny: user.role === 'user' ? ['salary', 'ssn'] : [],
494
+ * }), [user.role]);
495
+ *
496
+ * <AutoCrudTable permissions={permissions} ... />
497
+ * ```
498
+ */
499
+ permissions?: CrudPermissions;
433
500
  }
434
501
  /**
435
502
  * AutoCrudTable 组件
@@ -444,8 +511,9 @@ declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
444
511
  fields,
445
512
  table: tableConfig,
446
513
  form: formConfig,
447
- slots
448
- }: AutoCrudTableProps<TSchema>): react_jsx_runtime7.JSX.Element;
514
+ slots,
515
+ permissions
516
+ }: AutoCrudTableProps<TSchema>): react_jsx_runtime2.JSX.Element;
449
517
  //#endregion
450
518
  //#region src/components/auto-crud/auto-form.d.ts
451
519
  interface AutoFormProps<T extends z.ZodObject<z.ZodRawShape>> {
@@ -477,7 +545,7 @@ declare function AutoFormInner<T extends z.ZodObject<z.ZodRawShape>>({
477
545
  labelAlign,
478
546
  labelWidth,
479
547
  showSubmitButton
480
- }: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime7.JSX.Element;
548
+ }: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime2.JSX.Element;
481
549
  declare const AutoForm: <T extends z.ZodObject<z.ZodRawShape>>(props: AutoFormProps<T> & {
482
550
  ref?: React.Ref<AutoFormRef>;
483
551
  }) => ReturnType<typeof AutoFormInner>;
@@ -691,12 +759,12 @@ declare const filterItemSchema: z.ZodObject<{
691
759
  variant: z.ZodEnum<{
692
760
  number: "number";
693
761
  boolean: "boolean";
694
- date: "date";
695
762
  text: "text";
763
+ range: "range";
764
+ date: "date";
765
+ dateRange: "dateRange";
696
766
  select: "select";
697
767
  multiSelect: "multiSelect";
698
- dateRange: "dateRange";
699
- range: "range";
700
768
  }>;
701
769
  operator: z.ZodEnum<{
702
770
  iLike: "iLike";
@@ -772,7 +840,7 @@ declare function AutoTableSimpleFilters<TData>({
772
840
  shallow,
773
841
  filters: externalFilters,
774
842
  onFiltersChange
775
- }: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime7.JSX.Element | null;
843
+ }: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime2.JSX.Element | null;
776
844
  //#endregion
777
845
  //#region src/components/auto-crud/form-modal.d.ts
778
846
  type ModalVariant = "dialog" | "sheet";
@@ -807,7 +875,7 @@ declare function CrudFormModal<T extends z.ZodObject<z.ZodRawShape>>({
807
875
  title,
808
876
  labelAlign,
809
877
  labelWidth
810
- }: CrudFormModalProps<T>): react_jsx_runtime7.JSX.Element;
878
+ }: CrudFormModalProps<T>): react_jsx_runtime2.JSX.Element;
811
879
  //#endregion
812
880
  //#region src/components/data-table/data-table.d.ts
813
881
  interface DataTableProps<TData> extends React$1.ComponentProps<"div"> {
@@ -820,7 +888,7 @@ declare function DataTable<TData>({
820
888
  children,
821
889
  className,
822
890
  ...props
823
- }: DataTableProps<TData>): react_jsx_runtime7.JSX.Element;
891
+ }: DataTableProps<TData>): react_jsx_runtime2.JSX.Element;
824
892
  //#endregion
825
893
  //#region src/components/data-table/data-table-advanced-toolbar.d.ts
826
894
  interface DataTableAdvancedToolbarProps<TData> extends React$1.ComponentProps<"div"> {
@@ -831,7 +899,7 @@ declare function DataTableAdvancedToolbar<TData>({
831
899
  children,
832
900
  className,
833
901
  ...props
834
- }: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime7.JSX.Element;
902
+ }: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime2.JSX.Element;
835
903
  //#endregion
836
904
  //#region src/components/data-table/data-table-column-header.d.ts
837
905
  interface DataTableColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {
@@ -843,7 +911,7 @@ declare function DataTableColumnHeader<TData, TValue>({
843
911
  label,
844
912
  className,
845
913
  ...props
846
- }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime7.JSX.Element;
914
+ }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime2.JSX.Element;
847
915
  //#endregion
848
916
  //#region src/components/data-table/data-table-faceted-filter.d.ts
849
917
  interface DataTableFacetedFilterProps<TData, TValue> {
@@ -857,7 +925,7 @@ declare function DataTableFacetedFilter<TData, TValue>({
857
925
  title,
858
926
  options,
859
927
  multiple
860
- }: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime7.JSX.Element;
928
+ }: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime2.JSX.Element;
861
929
  //#endregion
862
930
  //#region src/components/data-table/data-table-pagination.d.ts
863
931
  interface DataTablePaginationProps<TData> extends React.ComponentProps<"div"> {
@@ -869,7 +937,7 @@ declare function DataTablePagination<TData>({
869
937
  pageSizeOptions,
870
938
  className,
871
939
  ...props
872
- }: DataTablePaginationProps<TData>): react_jsx_runtime7.JSX.Element;
940
+ }: DataTablePaginationProps<TData>): react_jsx_runtime2.JSX.Element;
873
941
  //#endregion
874
942
  //#region src/components/data-table/data-table-toolbar.d.ts
875
943
  interface DataTableToolbarProps<TData> extends React$1.ComponentProps<"div"> {
@@ -880,7 +948,7 @@ declare function DataTableToolbar<TData>({
880
948
  children,
881
949
  className,
882
950
  ...props
883
- }: DataTableToolbarProps<TData>): react_jsx_runtime7.JSX.Element;
951
+ }: DataTableToolbarProps<TData>): react_jsx_runtime2.JSX.Element;
884
952
  //#endregion
885
953
  //#region src/components/data-table/data-table-view-options.d.ts
886
954
  interface DataTableViewOptionsProps<TData> extends React$1.ComponentProps<typeof PopoverContent> {
@@ -891,7 +959,7 @@ declare function DataTableViewOptions<TData>({
891
959
  table,
892
960
  disabled,
893
961
  ...props
894
- }: DataTableViewOptionsProps<TData>): react_jsx_runtime7.JSX.Element;
962
+ }: DataTableViewOptionsProps<TData>): react_jsx_runtime2.JSX.Element;
895
963
  //#endregion
896
964
  //#region src/hooks/use-data-table.d.ts
897
965
  interface UseDataTableProps<TData> extends Omit<TableOptions<TData>, "state" | "pageCount" | "getCoreRowModel" | "manualFiltering" | "manualPagination" | "manualSorting">, Required<Pick<TableOptions<TData>, "pageCount">> {
@@ -1162,4 +1230,4 @@ declare function formatDate(date: Date | string | number | undefined, opts?: Int
1162
1230
  */
1163
1231
  declare function humanize(str: string): string;
1164
1232
  //#endregion
1165
- export { type ActionsColumnConfig, AutoCrudTable, type AutoCrudTableProps, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldType, type Fields, FilterOperator, type FilterVariant, type FormSchemaOverrides, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, Option, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, cn, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, formatDate, getUrlParams, humanize, noopToastAdapter, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseZodField, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates };
1233
+ export { type ActionsColumnConfig, AutoCrudTable, type AutoCrudTableProps, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type CrudOperationPermissions, type CrudPermissions, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldType, type Fields, FilterOperator, type FilterVariant, type FormSchemaOverrides, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, Option, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, cn, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, formatDate, getUrlParams, humanize, noopToastAdapter, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseZodField, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { forwardRef, useCallback, useImperativeHandle, useMemo, useReducer, useRef, useState } from "react";
3
3
  import { ArrowDownUp, BadgeCheck, CalendarIcon, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ChevronsLeft, ChevronsRight, ChevronsUpDown, CommandIcon, Download, Ellipsis, EyeOff, FileSpreadsheetIcon, GripVertical, ListFilter, ListFilterIcon, PlusCircle, Settings2, Text, Trash2, X, XCircle } from "lucide-react";
4
4
  import { flexRender, getCoreRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
5
- import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Calendar, Checkbox, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, Input, Label, Popover, PopoverContent, PopoverTrigger, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, Slider, Switch, Table as Table$1, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@pixpilot/shadcn";
5
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Calendar, Checkbox, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, Input, Label, Popover, PopoverContent, PopoverTrigger, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, Slider, Switch } from "@pixpilot/shadcn";
6
6
  import { clsx } from "clsx";
7
7
  import { twMerge } from "tailwind-merge";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -127,6 +127,55 @@ function DataTablePagination({ table, pageSizeOptions = [
127
127
  });
128
128
  }
129
129
 
130
+ //#endregion
131
+ //#region src/components/ui/table.tsx
132
+ function Table$1({ className,...props }) {
133
+ return /* @__PURE__ */ jsx("div", {
134
+ "data-slot": "table-container",
135
+ className: "relative w-full overflow-x-auto",
136
+ children: /* @__PURE__ */ jsx("table", {
137
+ "data-slot": "table",
138
+ className: cn("w-full caption-bottom text-sm", className),
139
+ ...props
140
+ })
141
+ });
142
+ }
143
+ function TableHeader({ className,...props }) {
144
+ return /* @__PURE__ */ jsx("thead", {
145
+ "data-slot": "table-header",
146
+ className: cn("[&_tr]:border-b", className),
147
+ ...props
148
+ });
149
+ }
150
+ function TableBody({ className,...props }) {
151
+ return /* @__PURE__ */ jsx("tbody", {
152
+ "data-slot": "table-body",
153
+ className: cn("[&_tr:last-child]:border-0", className),
154
+ ...props
155
+ });
156
+ }
157
+ function TableRow({ className,...props }) {
158
+ return /* @__PURE__ */ jsx("tr", {
159
+ "data-slot": "table-row",
160
+ className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
161
+ ...props
162
+ });
163
+ }
164
+ function TableHead({ className,...props }) {
165
+ return /* @__PURE__ */ jsx("th", {
166
+ "data-slot": "table-head",
167
+ className: cn("h-10 whitespace-nowrap px-2 text-left align-middle font-medium text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
168
+ ...props
169
+ });
170
+ }
171
+ function TableCell({ className,...props }) {
172
+ return /* @__PURE__ */ jsx("td", {
173
+ "data-slot": "table-cell",
174
+ className: cn("whitespace-nowrap p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
175
+ ...props
176
+ });
177
+ }
178
+
130
179
  //#endregion
131
180
  //#region src/config/data-table.ts
132
181
  const dataTableConfig = {
@@ -4159,7 +4208,7 @@ const filterModeConfig = {
4159
4208
  tooltip: "Linear-style command filters"
4160
4209
  }
4161
4210
  };
4162
- function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, initialSorting }) {
4211
+ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, initialSorting, enableExport = true }) {
4163
4212
  const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : [
4164
4213
  "simple",
4165
4214
  "advanced",
@@ -4276,6 +4325,7 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4276
4325
  onUpdateSelected,
4277
4326
  batchUpdateFields,
4278
4327
  enableDelete: !!onDeleteSelected,
4328
+ enableExport,
4279
4329
  extraActions: actionBarExtra
4280
4330
  })
4281
4331
  ]
@@ -4557,8 +4607,8 @@ function buildFormOverrides(fields, legacyOverrides) {
4557
4607
  /**
4558
4608
  * 从统一配置生成隐藏列列表
4559
4609
  */
4560
- function buildHiddenColumns(fields, legacyHidden) {
4561
- const hidden = new Set(legacyHidden ?? []);
4610
+ function buildHiddenColumns(fields, legacyHidden, denyFields) {
4611
+ const hidden = new Set([...legacyHidden ?? [], ...denyFields ?? []]);
4562
4612
  if (fields) {
4563
4613
  for (const [key, config] of Object.entries(fields)) if (config.hidden || config.table?.hidden) hidden.add(key);
4564
4614
  }
@@ -4673,10 +4723,16 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
4673
4723
  *
4674
4724
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
4675
4725
  */
4676
- function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots }) {
4726
+ function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions }) {
4727
+ const can = {
4728
+ create: permissions?.can?.create ?? true,
4729
+ update: permissions?.can?.update ?? true,
4730
+ delete: permissions?.can?.delete ?? true,
4731
+ export: permissions?.can?.export ?? true
4732
+ };
4677
4733
  const tableOverrides = buildTableOverrides(fields, tableConfig?.overrides);
4678
4734
  const formOverrides = buildFormOverrides(fields, formConfig?.overrides);
4679
- const hiddenColumns = buildHiddenColumns(fields, tableConfig?.hidden);
4735
+ const hiddenColumns = buildHiddenColumns(fields, tableConfig?.hidden, permissions?.deny);
4680
4736
  const batchFields = buildBatchUpdateFields(schema, tableConfig?.batchFields, fields);
4681
4737
  return /* @__PURE__ */ jsxs("div", {
4682
4738
  className: "space-y-4",
@@ -4698,7 +4754,7 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
4698
4754
  children: slots?.toolbarStart
4699
4755
  }), /* @__PURE__ */ jsxs("div", {
4700
4756
  className: "flex items-center gap-2",
4701
- children: [slots?.toolbarEnd, /* @__PURE__ */ jsx(Button, {
4757
+ children: [slots?.toolbarEnd, can.create && /* @__PURE__ */ jsx(Button, {
4702
4758
  onClick: resource.handlers.openCreate,
4703
4759
  children: "新建"
4704
4760
  })]
@@ -4713,13 +4769,14 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
4713
4769
  filterMode: tableConfig?.filterModes,
4714
4770
  actions: {
4715
4771
  onView: resource.handlers.openView,
4716
- onEdit: resource.handlers.openEdit,
4717
- onCopy: resource.handlers.copyRow,
4718
- onDelete: resource.handlers.openDelete
4772
+ onEdit: can.update ? resource.handlers.openEdit : void 0,
4773
+ onCopy: can.create ? resource.handlers.copyRow : void 0,
4774
+ onDelete: can.delete ? resource.handlers.openDelete : void 0
4719
4775
  },
4720
- onDeleteSelected: resource.handlers.deleteMany,
4721
- onUpdateSelected: resource.handlers.updateMany,
4722
- batchUpdateFields: batchFields,
4776
+ onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
4777
+ onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
4778
+ batchUpdateFields: can.update ? batchFields : void 0,
4779
+ enableExport: can.export,
4723
4780
  initialSorting: tableConfig?.defaultSort
4724
4781
  }),
4725
4782
  /* @__PURE__ */ jsx(CrudFormModal, {
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@wordrhyme/auto-crud",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.4.1",
5
+ "packageManager": "pnpm@10.25.0",
5
6
  "description": "Schema-first CRUD components with auto-generated tables and forms",
6
7
  "author": "wordrhyme",
7
8
  "license": "MIT",
@@ -26,6 +27,20 @@
26
27
  "publishConfig": {
27
28
  "access": "public"
28
29
  },
30
+ "scripts": {
31
+ "prepublishOnly": "pnpm run clean && pnpm run build",
32
+ "clean": "git clean -xdf .cache .turbo dist",
33
+ "clean:all": "git clean -xdf .cache .turbo dist node_modules",
34
+ "build": "tsdown",
35
+ "build:watch": "tsdown --watch",
36
+ "test": "vitest --run --passWithNoTests",
37
+ "test:watch": "vitest --watch",
38
+ "test:ui": "vitest --ui",
39
+ "test:coverage": "vitest --coverage",
40
+ "typecheck": "tsc --noEmit",
41
+ "lint": "eslint",
42
+ "format": "prettier --check . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore"
43
+ },
29
44
  "peerDependencies": {
30
45
  "react": "^18.0.0 || ^19.0.0",
31
46
  "react-dom": "^18.0.0 || ^19.0.0",
@@ -41,6 +56,9 @@
41
56
  "@formily/json-schema": "^2.3.7",
42
57
  "@formily/react": "^2.3.7",
43
58
  "@formily/reactive": "^2.3.7",
59
+ "@pixpilot/formily-shadcn": "workspace:*",
60
+ "@pixpilot/shadcn": "workspace:*",
61
+ "@pixpilot/shadcn-ui": "workspace:*",
44
62
  "@radix-ui/react-alert-dialog": "^1.1.15",
45
63
  "@radix-ui/react-checkbox": "^1.3.3",
46
64
  "@radix-ui/react-dialog": "^1.1.15",
@@ -59,46 +77,30 @@
59
77
  "@tanstack/react-table": "^8.21.3",
60
78
  "@tanstack/react-virtual": "^3.13.18",
61
79
  "class-variance-authority": "^0.7.1",
62
- "clsx": "^2.1.1",
80
+ "clsx": "catalog:prod",
63
81
  "cmdk": "^1.1.1",
64
- "lucide-react": "0.553.0",
82
+ "lucide-react": "catalog:prod",
65
83
  "nanoid": "^5.1.6",
66
- "tailwind-merge": "^3.4.0",
67
- "vaul": "^1.1.2",
68
- "@pixpilot/formily-shadcn": "0.44.3",
69
- "@pixpilot/shadcn": "0.9.0",
70
- "@pixpilot/shadcn-ui": "0.47.0"
84
+ "tailwind-merge": "catalog:prod",
85
+ "vaul": "^1.1.2"
71
86
  },
72
87
  "devDependencies": {
88
+ "@internal/eslint-config": "workspace:*",
89
+ "@internal/prettier-config": "workspace:*",
90
+ "@internal/tsconfig": "workspace:*",
91
+ "@internal/tsdown-config": "workspace:*",
92
+ "@internal/vitest-config": "workspace:*",
73
93
  "@tanstack/react-query": "^5.90.15",
74
94
  "@trpc/server": "^11.0.0",
75
- "@types/node": "^22.19.3",
76
- "@types/react": "^19.2.7",
77
- "@types/react-dom": "^19.2.3",
95
+ "@types/node": "catalog:dev",
96
+ "@types/react": "catalog:dev",
97
+ "@types/react-dom": "catalog:dev",
78
98
  "drizzle-orm": "^0.45.1",
79
- "eslint": "^9.39.2",
80
- "react": "19.2.4",
81
- "react-dom": "19.2.4",
82
- "tsdown": "^0.15.12",
83
- "typescript": "^5.9.3",
84
- "@internal/eslint-config": "0.3.0",
85
- "@internal/tsconfig": "0.1.0",
86
- "@internal/tsdown-config": "0.1.0",
87
- "@internal/vitest-config": "0.1.0",
88
- "@internal/prettier-config": "0.0.1"
99
+ "eslint": "catalog:dev",
100
+ "react": "catalog:prod",
101
+ "react-dom": "catalog:prod",
102
+ "tsdown": "catalog:dev",
103
+ "typescript": "catalog:dev"
89
104
  },
90
- "prettier": "@internal/prettier-config",
91
- "scripts": {
92
- "clean": "git clean -xdf .cache .turbo dist",
93
- "clean:all": "git clean -xdf .cache .turbo dist node_modules",
94
- "build": "tsdown",
95
- "build:watch": "tsdown --watch",
96
- "test": "vitest --run --passWithNoTests",
97
- "test:watch": "vitest --watch",
98
- "test:ui": "vitest --ui",
99
- "test:coverage": "vitest --coverage",
100
- "typecheck": "tsc --noEmit",
101
- "lint": "eslint",
102
- "format": "prettier --check . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore"
103
- }
104
- }
105
+ "prettier": "@internal/prettier-config"
106
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Pixpilot
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.