@wordrhyme/auto-crud 1.11.0 → 1.11.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 +16 -3
- package/dist/index.cjs +62 -74
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +62 -74
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -673,10 +673,22 @@ table={{
|
|
|
673
673
|
|
|
674
674
|
## 🔧 工具栏操作配置
|
|
675
675
|
|
|
676
|
-
`toolbar`
|
|
676
|
+
`toolbar` 数组控制工具栏操作,设计思路完全对齐行操作 `actions`。旧 prop `toolbarActions` 仍兼容读取,但新代码请使用 `toolbar`。
|
|
677
677
|
|
|
678
678
|
内置操作类型:`refresh`(刷新)、`create`(新建)、`import`(导入)、`export`(导出)。
|
|
679
679
|
|
|
680
|
+
刷新固定显示在搜索筛选行右侧,顺序为 `[排序] [刷新] [列设置]`;其 `label`、`onClick`、`component` 和隐藏配置仍由 `toolbar` 控制。其余操作保留在上方工具栏,没有可见操作时不占空行。
|
|
681
|
+
|
|
682
|
+
直接使用 `AutoTable` 时,可通过 `toolbarExtra` 插入排序与列设置之间的控件:
|
|
683
|
+
|
|
684
|
+
```tsx
|
|
685
|
+
<AutoTable
|
|
686
|
+
schema={schema}
|
|
687
|
+
data={rows}
|
|
688
|
+
toolbarExtra={<Button onClick={refresh}>刷新</Button>}
|
|
689
|
+
/>
|
|
690
|
+
```
|
|
691
|
+
|
|
680
692
|
### 只添加自定义按钮(内置保持默认)
|
|
681
693
|
|
|
682
694
|
只传 `type: "custom"` 项时,所有内置按钮(刷新、导入、导出、新建)保持原样,custom 项按 `position` 插入首部或尾部。
|
|
@@ -692,12 +704,13 @@ table={{
|
|
|
692
704
|
{ type: 'custom', component: <Button variant="outline">批量标签</Button> }, // 默认 position: "end"
|
|
693
705
|
]}
|
|
694
706
|
/>
|
|
695
|
-
//
|
|
707
|
+
// 上方工具栏: 分类管理 · [导入] · [导出] · [新建] · 批量标签
|
|
708
|
+
// 搜索筛选行右侧: [排序] · [刷新] · [列设置]
|
|
696
709
|
```
|
|
697
710
|
|
|
698
711
|
### 调整内置按钮顺序
|
|
699
712
|
|
|
700
|
-
数组中只要包含任意内置 `type`,就会**完全接管工具栏** ——
|
|
713
|
+
数组中只要包含任意内置 `type`,就会**完全接管工具栏** —— 未列出的内置按钮**直接隐藏**。刷新保持在搜索筛选行,其他按钮的渲染顺序**严格按数组**。
|
|
701
714
|
|
|
702
715
|
```tsx
|
|
703
716
|
<AutoCrudTable
|
package/dist/index.cjs
CHANGED
|
@@ -4430,7 +4430,7 @@ const filterModeConfig = {
|
|
|
4430
4430
|
tooltip: "Linear-style command filters"
|
|
4431
4431
|
}
|
|
4432
4432
|
};
|
|
4433
|
-
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
|
|
4433
|
+
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, toolbarExtra, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
|
|
4434
4434
|
if (expandedRow && !getRowId) throw new Error("AutoTable requires getRowId when expandedRow is provided.");
|
|
4435
4435
|
const enableExpansion = !!expandedRow;
|
|
4436
4436
|
const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
|
|
@@ -4649,6 +4649,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
4649
4649
|
table,
|
|
4650
4650
|
align: "end"
|
|
4651
4651
|
}),
|
|
4652
|
+
toolbarExtra,
|
|
4652
4653
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableViewOptions, {
|
|
4653
4654
|
table,
|
|
4654
4655
|
align: "end"
|
|
@@ -7766,6 +7767,60 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7766
7767
|
rowActionDefaults,
|
|
7767
7768
|
openComponent
|
|
7768
7769
|
]);
|
|
7770
|
+
const normalizedToolbarActions = resolvedToolbarActions.length > 0 ? resolveOwnerToolbarActions(resolvedToolbarActions) : [];
|
|
7771
|
+
const renderBuiltinButton = (type, overrides) => {
|
|
7772
|
+
if (type === "refresh") {
|
|
7773
|
+
const onRefresh = overrides?.onClick ?? toolbarRefresh;
|
|
7774
|
+
const label = overrides?.label ?? locale.toolbar.refresh;
|
|
7775
|
+
if (!onRefresh) return null;
|
|
7776
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7777
|
+
variant: "outline",
|
|
7778
|
+
size: "icon-sm",
|
|
7779
|
+
"aria-label": label,
|
|
7780
|
+
title: label,
|
|
7781
|
+
onClick: onRefresh,
|
|
7782
|
+
disabled: resource.tableData.isFetching,
|
|
7783
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.RefreshCw, { className: resource.tableData.isFetching ? "h-4 w-4 animate-spin" : "h-4 w-4" })
|
|
7784
|
+
}, "refresh");
|
|
7785
|
+
}
|
|
7786
|
+
if (type === "import" && canImport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7787
|
+
variant: "outline",
|
|
7788
|
+
size: "sm",
|
|
7789
|
+
onClick: overrides?.onClick ?? toolbarOpenImport,
|
|
7790
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.import]
|
|
7791
|
+
}, "import");
|
|
7792
|
+
if (type === "export" && canExport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7793
|
+
variant: "outline",
|
|
7794
|
+
size: "sm",
|
|
7795
|
+
onClick: overrides?.onClick ?? toolbarExportData,
|
|
7796
|
+
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
7797
|
+
children: [exporting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "mr-2 h-4 w-4" }), overrides?.label ?? (selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export)]
|
|
7798
|
+
}, "export");
|
|
7799
|
+
if (type === "create" && can.create) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7800
|
+
onClick: overrides?.onClick ?? toolbarOpenCreate,
|
|
7801
|
+
children: overrides?.label ?? locale.toolbar.create
|
|
7802
|
+
}, "create");
|
|
7803
|
+
return null;
|
|
7804
|
+
};
|
|
7805
|
+
const renderToolbarComponent = (component) => typeof component === "function" ? component(toolbarContext) : component;
|
|
7806
|
+
const renderToolbarAction = (action$1, index$1) => {
|
|
7807
|
+
if (action$1.type === "custom") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, `custom-${index$1}`);
|
|
7808
|
+
if (!(() => {
|
|
7809
|
+
switch (action$1.type) {
|
|
7810
|
+
case "refresh": return !!(resource.handlers.refresh || action$1.onClick || action$1.component);
|
|
7811
|
+
case "import": return canImport;
|
|
7812
|
+
case "export": return canExport;
|
|
7813
|
+
case "create": return can.create;
|
|
7814
|
+
}
|
|
7815
|
+
})()) return null;
|
|
7816
|
+
if (action$1.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, action$1.type);
|
|
7817
|
+
return renderBuiltinButton(action$1.type, {
|
|
7818
|
+
onClick: action$1.onClick,
|
|
7819
|
+
label: action$1.label
|
|
7820
|
+
});
|
|
7821
|
+
};
|
|
7822
|
+
const toolbarNodes = normalizedToolbarActions.filter((action$1) => action$1.type !== "refresh").map(renderToolbarAction).filter((node) => node !== null);
|
|
7823
|
+
const refreshNodes = normalizedToolbarActions.filter((action$1) => action$1.type === "refresh").map(renderToolbarAction);
|
|
7769
7824
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7770
7825
|
className: "space-y-4",
|
|
7771
7826
|
children: [
|
|
@@ -7779,80 +7834,12 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7779
7834
|
children: description
|
|
7780
7835
|
})]
|
|
7781
7836
|
}),
|
|
7782
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7837
|
+
toolbarNodes.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7783
7838
|
className: "flex items-center justify-end gap-4",
|
|
7784
|
-
children: ((
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
const label = overrides?.label ?? locale.toolbar.refresh;
|
|
7789
|
-
if (!onRefresh) return null;
|
|
7790
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7791
|
-
variant: "outline",
|
|
7792
|
-
size: "icon-sm",
|
|
7793
|
-
"aria-label": label,
|
|
7794
|
-
title: label,
|
|
7795
|
-
onClick: onRefresh,
|
|
7796
|
-
disabled: resource.tableData.isFetching,
|
|
7797
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.RefreshCw, { className: resource.tableData.isFetching ? "h-4 w-4 animate-spin" : "h-4 w-4" })
|
|
7798
|
-
}, "refresh");
|
|
7799
|
-
}
|
|
7800
|
-
if (type === "import" && canImport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7801
|
-
variant: "outline",
|
|
7802
|
-
size: "sm",
|
|
7803
|
-
onClick: overrides?.onClick ?? toolbarOpenImport,
|
|
7804
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.import]
|
|
7805
|
-
}, "import");
|
|
7806
|
-
if (type === "export" && canExport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7807
|
-
variant: "outline",
|
|
7808
|
-
size: "sm",
|
|
7809
|
-
onClick: overrides?.onClick ?? toolbarExportData,
|
|
7810
|
-
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
7811
|
-
children: [exporting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "mr-2 h-4 w-4" }), overrides?.label ?? (selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export)]
|
|
7812
|
-
}, "export");
|
|
7813
|
-
if (type === "create" && can.create) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7814
|
-
onClick: overrides?.onClick ?? toolbarOpenCreate,
|
|
7815
|
-
children: overrides?.label ?? locale.toolbar.create
|
|
7816
|
-
}, "create");
|
|
7817
|
-
return null;
|
|
7818
|
-
};
|
|
7819
|
-
const renderToolbarComponent = (component) => typeof component === "function" ? component(toolbarContext) : component;
|
|
7820
|
-
if (!resolvedToolbarActions || resolvedToolbarActions.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "flex items-center gap-2" });
|
|
7821
|
-
if (!resolvedToolbarActions.some((i) => i.type !== "custom")) {
|
|
7822
|
-
const startNodes = resolvedToolbarActions.filter((i) => i.type === "custom" && i.position === "start").map((a, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(a.component) }, `start-${i}`));
|
|
7823
|
-
const endNodes = resolvedToolbarActions.filter((i) => i.type === "custom" && i.position !== "start").map((a, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(a.component) }, `end-${i}`));
|
|
7824
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7825
|
-
className: "flex items-center gap-2",
|
|
7826
|
-
children: [
|
|
7827
|
-
startNodes,
|
|
7828
|
-
renderBuiltinButton("refresh"),
|
|
7829
|
-
renderBuiltinButton("import"),
|
|
7830
|
-
renderBuiltinButton("export"),
|
|
7831
|
-
renderBuiltinButton("create"),
|
|
7832
|
-
endNodes
|
|
7833
|
-
]
|
|
7834
|
-
});
|
|
7835
|
-
}
|
|
7836
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7837
|
-
className: "flex items-center gap-2",
|
|
7838
|
-
children: resolvedToolbarActions.map((action$1, index$1) => {
|
|
7839
|
-
if (action$1.type === "custom") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, `custom-${index$1}`);
|
|
7840
|
-
if (!(() => {
|
|
7841
|
-
switch (action$1.type) {
|
|
7842
|
-
case "refresh": return !!(resource.handlers.refresh || action$1.onClick || action$1.component);
|
|
7843
|
-
case "import": return canImport;
|
|
7844
|
-
case "export": return canExport;
|
|
7845
|
-
case "create": return can.create;
|
|
7846
|
-
}
|
|
7847
|
-
})()) return null;
|
|
7848
|
-
if (action$1.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, action$1.type);
|
|
7849
|
-
return renderBuiltinButton(action$1.type, {
|
|
7850
|
-
onClick: action$1.onClick,
|
|
7851
|
-
label: action$1.label
|
|
7852
|
-
});
|
|
7853
|
-
})
|
|
7854
|
-
});
|
|
7855
|
-
})()
|
|
7839
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7840
|
+
className: "flex items-center gap-2",
|
|
7841
|
+
children: toolbarNodes
|
|
7842
|
+
})
|
|
7856
7843
|
}),
|
|
7857
7844
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoTable, {
|
|
7858
7845
|
data: resource.tableData.data,
|
|
@@ -7872,6 +7859,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7872
7859
|
filterOnly,
|
|
7873
7860
|
filterMode: tableConfig?.filterModes,
|
|
7874
7861
|
search: searchConfig,
|
|
7862
|
+
toolbarExtra: refreshNodes,
|
|
7875
7863
|
actions: tableRowActions,
|
|
7876
7864
|
onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
|
|
7877
7865
|
onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
|
package/dist/index.d.cts
CHANGED
|
@@ -902,6 +902,8 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> extends Pick<Data
|
|
|
902
902
|
search?: boolean | {
|
|
903
903
|
placeholder?: string;
|
|
904
904
|
};
|
|
905
|
+
/** Extra table controls rendered between sorting and column visibility. */
|
|
906
|
+
toolbarExtra?: React.ReactNode;
|
|
905
907
|
/** 批量删除回调 */
|
|
906
908
|
onDeleteSelected?: (rows: z.infer<T>[]) => void;
|
|
907
909
|
/** 批量更新回调 */
|
|
@@ -945,6 +947,7 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
945
947
|
pinnedColumns,
|
|
946
948
|
filterMode,
|
|
947
949
|
search,
|
|
950
|
+
toolbarExtra,
|
|
948
951
|
onDeleteSelected,
|
|
949
952
|
onUpdateSelected,
|
|
950
953
|
batchUpdateFields,
|
package/dist/index.d.ts
CHANGED
|
@@ -902,6 +902,8 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> extends Pick<Data
|
|
|
902
902
|
search?: boolean | {
|
|
903
903
|
placeholder?: string;
|
|
904
904
|
};
|
|
905
|
+
/** Extra table controls rendered between sorting and column visibility. */
|
|
906
|
+
toolbarExtra?: React.ReactNode;
|
|
905
907
|
/** 批量删除回调 */
|
|
906
908
|
onDeleteSelected?: (rows: z.infer<T>[]) => void;
|
|
907
909
|
/** 批量更新回调 */
|
|
@@ -945,6 +947,7 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
|
|
|
945
947
|
pinnedColumns,
|
|
946
948
|
filterMode,
|
|
947
949
|
search,
|
|
950
|
+
toolbarExtra,
|
|
948
951
|
onDeleteSelected,
|
|
949
952
|
onUpdateSelected,
|
|
950
953
|
batchUpdateFields,
|
package/dist/index.js
CHANGED
|
@@ -4415,7 +4415,7 @@ const filterModeConfig = {
|
|
|
4415
4415
|
tooltip: "Linear-style command filters"
|
|
4416
4416
|
}
|
|
4417
4417
|
};
|
|
4418
|
-
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
|
|
4418
|
+
function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = false, pageCount = 1, pagination, total, overrides, classNames, enableRowSelection = true, exclude, filterOnly, actions, pinnedColumns, filterMode, search = false, toolbarExtra, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
|
|
4419
4419
|
if (expandedRow && !getRowId) throw new Error("AutoTable requires getRowId when expandedRow is provided.");
|
|
4420
4420
|
const enableExpansion = !!expandedRow;
|
|
4421
4421
|
const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
|
|
@@ -4634,6 +4634,7 @@ function AutoTable({ schema, data, getRowId, expandedRow, defaultExpanded = fals
|
|
|
4634
4634
|
table,
|
|
4635
4635
|
align: "end"
|
|
4636
4636
|
}),
|
|
4637
|
+
toolbarExtra,
|
|
4637
4638
|
/* @__PURE__ */ jsx(DataTableViewOptions, {
|
|
4638
4639
|
table,
|
|
4639
4640
|
align: "end"
|
|
@@ -7751,6 +7752,60 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7751
7752
|
rowActionDefaults,
|
|
7752
7753
|
openComponent
|
|
7753
7754
|
]);
|
|
7755
|
+
const normalizedToolbarActions = resolvedToolbarActions.length > 0 ? resolveOwnerToolbarActions(resolvedToolbarActions) : [];
|
|
7756
|
+
const renderBuiltinButton = (type, overrides) => {
|
|
7757
|
+
if (type === "refresh") {
|
|
7758
|
+
const onRefresh = overrides?.onClick ?? toolbarRefresh;
|
|
7759
|
+
const label = overrides?.label ?? locale.toolbar.refresh;
|
|
7760
|
+
if (!onRefresh) return null;
|
|
7761
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
7762
|
+
variant: "outline",
|
|
7763
|
+
size: "icon-sm",
|
|
7764
|
+
"aria-label": label,
|
|
7765
|
+
title: label,
|
|
7766
|
+
onClick: onRefresh,
|
|
7767
|
+
disabled: resource.tableData.isFetching,
|
|
7768
|
+
children: /* @__PURE__ */ jsx(RefreshCw, { className: resource.tableData.isFetching ? "h-4 w-4 animate-spin" : "h-4 w-4" })
|
|
7769
|
+
}, "refresh");
|
|
7770
|
+
}
|
|
7771
|
+
if (type === "import" && canImport) return /* @__PURE__ */ jsxs(Button, {
|
|
7772
|
+
variant: "outline",
|
|
7773
|
+
size: "sm",
|
|
7774
|
+
onClick: overrides?.onClick ?? toolbarOpenImport,
|
|
7775
|
+
children: [/* @__PURE__ */ jsx(Download, { className: "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.import]
|
|
7776
|
+
}, "import");
|
|
7777
|
+
if (type === "export" && canExport) return /* @__PURE__ */ jsxs(Button, {
|
|
7778
|
+
variant: "outline",
|
|
7779
|
+
size: "sm",
|
|
7780
|
+
onClick: overrides?.onClick ?? toolbarExportData,
|
|
7781
|
+
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
7782
|
+
children: [exporting ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Upload, { className: "mr-2 h-4 w-4" }), overrides?.label ?? (selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export)]
|
|
7783
|
+
}, "export");
|
|
7784
|
+
if (type === "create" && can.create) return /* @__PURE__ */ jsx(Button, {
|
|
7785
|
+
onClick: overrides?.onClick ?? toolbarOpenCreate,
|
|
7786
|
+
children: overrides?.label ?? locale.toolbar.create
|
|
7787
|
+
}, "create");
|
|
7788
|
+
return null;
|
|
7789
|
+
};
|
|
7790
|
+
const renderToolbarComponent = (component) => typeof component === "function" ? component(toolbarContext) : component;
|
|
7791
|
+
const renderToolbarAction = (action$1, index$1) => {
|
|
7792
|
+
if (action$1.type === "custom") return /* @__PURE__ */ jsx(React.Fragment, { children: renderToolbarComponent(action$1.component) }, `custom-${index$1}`);
|
|
7793
|
+
if (!(() => {
|
|
7794
|
+
switch (action$1.type) {
|
|
7795
|
+
case "refresh": return !!(resource.handlers.refresh || action$1.onClick || action$1.component);
|
|
7796
|
+
case "import": return canImport;
|
|
7797
|
+
case "export": return canExport;
|
|
7798
|
+
case "create": return can.create;
|
|
7799
|
+
}
|
|
7800
|
+
})()) return null;
|
|
7801
|
+
if (action$1.component) return /* @__PURE__ */ jsx(React.Fragment, { children: renderToolbarComponent(action$1.component) }, action$1.type);
|
|
7802
|
+
return renderBuiltinButton(action$1.type, {
|
|
7803
|
+
onClick: action$1.onClick,
|
|
7804
|
+
label: action$1.label
|
|
7805
|
+
});
|
|
7806
|
+
};
|
|
7807
|
+
const toolbarNodes = normalizedToolbarActions.filter((action$1) => action$1.type !== "refresh").map(renderToolbarAction).filter((node) => node !== null);
|
|
7808
|
+
const refreshNodes = normalizedToolbarActions.filter((action$1) => action$1.type === "refresh").map(renderToolbarAction);
|
|
7754
7809
|
return /* @__PURE__ */ jsxs("div", {
|
|
7755
7810
|
className: "space-y-4",
|
|
7756
7811
|
children: [
|
|
@@ -7764,80 +7819,12 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7764
7819
|
children: description
|
|
7765
7820
|
})]
|
|
7766
7821
|
}),
|
|
7767
|
-
/* @__PURE__ */ jsx("div", {
|
|
7822
|
+
toolbarNodes.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
7768
7823
|
className: "flex items-center justify-end gap-4",
|
|
7769
|
-
children: (
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
const label = overrides?.label ?? locale.toolbar.refresh;
|
|
7774
|
-
if (!onRefresh) return null;
|
|
7775
|
-
return /* @__PURE__ */ jsx(Button, {
|
|
7776
|
-
variant: "outline",
|
|
7777
|
-
size: "icon-sm",
|
|
7778
|
-
"aria-label": label,
|
|
7779
|
-
title: label,
|
|
7780
|
-
onClick: onRefresh,
|
|
7781
|
-
disabled: resource.tableData.isFetching,
|
|
7782
|
-
children: /* @__PURE__ */ jsx(RefreshCw, { className: resource.tableData.isFetching ? "h-4 w-4 animate-spin" : "h-4 w-4" })
|
|
7783
|
-
}, "refresh");
|
|
7784
|
-
}
|
|
7785
|
-
if (type === "import" && canImport) return /* @__PURE__ */ jsxs(Button, {
|
|
7786
|
-
variant: "outline",
|
|
7787
|
-
size: "sm",
|
|
7788
|
-
onClick: overrides?.onClick ?? toolbarOpenImport,
|
|
7789
|
-
children: [/* @__PURE__ */ jsx(Download, { className: "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.import]
|
|
7790
|
-
}, "import");
|
|
7791
|
-
if (type === "export" && canExport) return /* @__PURE__ */ jsxs(Button, {
|
|
7792
|
-
variant: "outline",
|
|
7793
|
-
size: "sm",
|
|
7794
|
-
onClick: overrides?.onClick ?? toolbarExportData,
|
|
7795
|
-
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
7796
|
-
children: [exporting ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Upload, { className: "mr-2 h-4 w-4" }), overrides?.label ?? (selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export)]
|
|
7797
|
-
}, "export");
|
|
7798
|
-
if (type === "create" && can.create) return /* @__PURE__ */ jsx(Button, {
|
|
7799
|
-
onClick: overrides?.onClick ?? toolbarOpenCreate,
|
|
7800
|
-
children: overrides?.label ?? locale.toolbar.create
|
|
7801
|
-
}, "create");
|
|
7802
|
-
return null;
|
|
7803
|
-
};
|
|
7804
|
-
const renderToolbarComponent = (component) => typeof component === "function" ? component(toolbarContext) : component;
|
|
7805
|
-
if (!resolvedToolbarActions || resolvedToolbarActions.length === 0) return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2" });
|
|
7806
|
-
if (!resolvedToolbarActions.some((i) => i.type !== "custom")) {
|
|
7807
|
-
const startNodes = resolvedToolbarActions.filter((i) => i.type === "custom" && i.position === "start").map((a, i) => /* @__PURE__ */ jsx(React.Fragment, { children: renderToolbarComponent(a.component) }, `start-${i}`));
|
|
7808
|
-
const endNodes = resolvedToolbarActions.filter((i) => i.type === "custom" && i.position !== "start").map((a, i) => /* @__PURE__ */ jsx(React.Fragment, { children: renderToolbarComponent(a.component) }, `end-${i}`));
|
|
7809
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
7810
|
-
className: "flex items-center gap-2",
|
|
7811
|
-
children: [
|
|
7812
|
-
startNodes,
|
|
7813
|
-
renderBuiltinButton("refresh"),
|
|
7814
|
-
renderBuiltinButton("import"),
|
|
7815
|
-
renderBuiltinButton("export"),
|
|
7816
|
-
renderBuiltinButton("create"),
|
|
7817
|
-
endNodes
|
|
7818
|
-
]
|
|
7819
|
-
});
|
|
7820
|
-
}
|
|
7821
|
-
return /* @__PURE__ */ jsx("div", {
|
|
7822
|
-
className: "flex items-center gap-2",
|
|
7823
|
-
children: resolvedToolbarActions.map((action$1, index$1) => {
|
|
7824
|
-
if (action$1.type === "custom") return /* @__PURE__ */ jsx(React.Fragment, { children: renderToolbarComponent(action$1.component) }, `custom-${index$1}`);
|
|
7825
|
-
if (!(() => {
|
|
7826
|
-
switch (action$1.type) {
|
|
7827
|
-
case "refresh": return !!(resource.handlers.refresh || action$1.onClick || action$1.component);
|
|
7828
|
-
case "import": return canImport;
|
|
7829
|
-
case "export": return canExport;
|
|
7830
|
-
case "create": return can.create;
|
|
7831
|
-
}
|
|
7832
|
-
})()) return null;
|
|
7833
|
-
if (action$1.component) return /* @__PURE__ */ jsx(React.Fragment, { children: renderToolbarComponent(action$1.component) }, action$1.type);
|
|
7834
|
-
return renderBuiltinButton(action$1.type, {
|
|
7835
|
-
onClick: action$1.onClick,
|
|
7836
|
-
label: action$1.label
|
|
7837
|
-
});
|
|
7838
|
-
})
|
|
7839
|
-
});
|
|
7840
|
-
})()
|
|
7824
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
7825
|
+
className: "flex items-center gap-2",
|
|
7826
|
+
children: toolbarNodes
|
|
7827
|
+
})
|
|
7841
7828
|
}),
|
|
7842
7829
|
/* @__PURE__ */ jsx(AutoTable, {
|
|
7843
7830
|
data: resource.tableData.data,
|
|
@@ -7857,6 +7844,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7857
7844
|
filterOnly,
|
|
7858
7845
|
filterMode: tableConfig?.filterModes,
|
|
7859
7846
|
search: searchConfig,
|
|
7847
|
+
toolbarExtra: refreshNodes,
|
|
7860
7848
|
actions: tableRowActions,
|
|
7861
7849
|
onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
|
|
7862
7850
|
onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordrhyme/auto-crud",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.11.
|
|
4
|
+
"version": "1.11.1",
|
|
5
5
|
"description": "Schema-first CRUD components with auto-generated tables and forms",
|
|
6
6
|
"author": "wordrhyme",
|
|
7
7
|
"license": "MIT",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"nanoid": "^5.1.6",
|
|
71
71
|
"tailwind-merge": "^3.5.0",
|
|
72
72
|
"vaul": "^1.1.2",
|
|
73
|
-
"@wordrhyme/formily-shadcn": "2.1.1",
|
|
74
73
|
"@wordrhyme/shadcn": "2.0.1",
|
|
74
|
+
"@wordrhyme/formily-shadcn": "2.1.1",
|
|
75
75
|
"@wordrhyme/shadcn-ui": "2.1.1"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
@@ -94,10 +94,10 @@
|
|
|
94
94
|
"typescript": "^5.9.3",
|
|
95
95
|
"vitest": "^3.2.4",
|
|
96
96
|
"@internal/eslint-config": "0.3.0",
|
|
97
|
-
"@internal/
|
|
98
|
-
"@internal/vitest-config": "0.1.0",
|
|
97
|
+
"@internal/prettier-config": "0.0.1",
|
|
99
98
|
"@internal/tsdown-config": "0.1.0",
|
|
100
|
-
"@internal/
|
|
99
|
+
"@internal/tsconfig": "0.1.0",
|
|
100
|
+
"@internal/vitest-config": "0.1.0"
|
|
101
101
|
},
|
|
102
102
|
"prettier": "@internal/prettier-config",
|
|
103
103
|
"scripts": {
|