@mshuja288/aksuicore 0.4.1 → 0.4.2
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/aksui.css +75 -1
- package/dist/index.cjs +133 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.js +133 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
- package/src/patterns/RecordWorkspace.tsx +157 -1
- package/src/patterns/index.ts +3 -0
- package/src/theme/patterns.css +75 -1
package/dist/index.d.cts
CHANGED
|
@@ -196,7 +196,20 @@ type ExportColumnRef = {
|
|
|
196
196
|
key: string;
|
|
197
197
|
header: string;
|
|
198
198
|
};
|
|
199
|
-
|
|
199
|
+
type BulkImportMode = "insert" | "update" | "upsert";
|
|
200
|
+
type BulkImportError = {
|
|
201
|
+
row: number;
|
|
202
|
+
field?: string | null;
|
|
203
|
+
code: string;
|
|
204
|
+
message: string;
|
|
205
|
+
};
|
|
206
|
+
type BulkImportResult = {
|
|
207
|
+
totalRows: number;
|
|
208
|
+
failed: number;
|
|
209
|
+
applied: boolean;
|
|
210
|
+
errors: BulkImportError[];
|
|
211
|
+
};
|
|
212
|
+
declare function RecordWorkspace<T>({ title, columns, items, rowKey, empty, onAdd, addLabel, canAdd, onView, onUpdate, onDelete, canUpdate, canDelete, onDownload, canDownload, canExport, downloadBusy, onBulkImport, canImport, importBusy, showColumnPicker, columnPrefsKey, visibleColumnKeys, defaultVisibleColumnKeys, onVisibleColumnKeysChange, toolbar, form, }: {
|
|
200
213
|
title: string;
|
|
201
214
|
columns: TableColumn<T>[];
|
|
202
215
|
items: T[];
|
|
@@ -215,8 +228,13 @@ declare function RecordWorkspace<T>({ title, columns, items, rowKey, empty, onAd
|
|
|
215
228
|
* Second argument lists currently visible columns (exportKey ?? key).
|
|
216
229
|
*/
|
|
217
230
|
onDownload?: (format: ExportDownloadFormat, columns: ExportColumnRef[]) => void;
|
|
231
|
+
/** Alias for `canDownload` (RBAC). When set, export requires this and `canDownload` to be true. */
|
|
232
|
+
canExport?: boolean;
|
|
218
233
|
canDownload?: boolean;
|
|
219
234
|
downloadBusy?: boolean;
|
|
235
|
+
onBulkImport?: (mode: BulkImportMode, file: File) => Promise<BulkImportResult>;
|
|
236
|
+
canImport?: boolean;
|
|
237
|
+
importBusy?: boolean;
|
|
220
238
|
/** Column checklist in the side rail. Default true. */
|
|
221
239
|
showColumnPicker?: boolean;
|
|
222
240
|
/** Persist visible column keys in localStorage under this key. */
|
|
@@ -233,4 +251,4 @@ declare function RecordWorkspace<T>({ title, columns, items, rowKey, empty, onAd
|
|
|
233
251
|
/** @deprecated Prefer RecordWorkspace — alias kept for configurator migration */
|
|
234
252
|
declare const RecordTable: typeof RecordWorkspace;
|
|
235
253
|
|
|
236
|
-
export { type AksuiTokenName, AppSelect, type AppSelectOption, AppShell, type AppShellProps, Button, type ButtonVariant, ConfirmDeleteDialog, DateField, Dialog, type ExportColumnRef, type ExportDownloadFormat, FormActions, FormDialog, type MobileNavMode, type PageSizeOption, Pagination, RecordTable, RecordWorkspace, Select, type SelectOption, SideNav, type SideNavItem, Snackbar, StatusMessage, type TableColumn, Topbar, aksuiThemeVersion, aksuiTokens };
|
|
254
|
+
export { type AksuiTokenName, AppSelect, type AppSelectOption, AppShell, type AppShellProps, type BulkImportError, type BulkImportMode, type BulkImportResult, Button, type ButtonVariant, ConfirmDeleteDialog, DateField, Dialog, type ExportColumnRef, type ExportDownloadFormat, FormActions, FormDialog, type MobileNavMode, type PageSizeOption, Pagination, RecordTable, RecordWorkspace, Select, type SelectOption, SideNav, type SideNavItem, Snackbar, StatusMessage, type TableColumn, Topbar, aksuiThemeVersion, aksuiTokens };
|
package/dist/index.d.ts
CHANGED
|
@@ -196,7 +196,20 @@ type ExportColumnRef = {
|
|
|
196
196
|
key: string;
|
|
197
197
|
header: string;
|
|
198
198
|
};
|
|
199
|
-
|
|
199
|
+
type BulkImportMode = "insert" | "update" | "upsert";
|
|
200
|
+
type BulkImportError = {
|
|
201
|
+
row: number;
|
|
202
|
+
field?: string | null;
|
|
203
|
+
code: string;
|
|
204
|
+
message: string;
|
|
205
|
+
};
|
|
206
|
+
type BulkImportResult = {
|
|
207
|
+
totalRows: number;
|
|
208
|
+
failed: number;
|
|
209
|
+
applied: boolean;
|
|
210
|
+
errors: BulkImportError[];
|
|
211
|
+
};
|
|
212
|
+
declare function RecordWorkspace<T>({ title, columns, items, rowKey, empty, onAdd, addLabel, canAdd, onView, onUpdate, onDelete, canUpdate, canDelete, onDownload, canDownload, canExport, downloadBusy, onBulkImport, canImport, importBusy, showColumnPicker, columnPrefsKey, visibleColumnKeys, defaultVisibleColumnKeys, onVisibleColumnKeysChange, toolbar, form, }: {
|
|
200
213
|
title: string;
|
|
201
214
|
columns: TableColumn<T>[];
|
|
202
215
|
items: T[];
|
|
@@ -215,8 +228,13 @@ declare function RecordWorkspace<T>({ title, columns, items, rowKey, empty, onAd
|
|
|
215
228
|
* Second argument lists currently visible columns (exportKey ?? key).
|
|
216
229
|
*/
|
|
217
230
|
onDownload?: (format: ExportDownloadFormat, columns: ExportColumnRef[]) => void;
|
|
231
|
+
/** Alias for `canDownload` (RBAC). When set, export requires this and `canDownload` to be true. */
|
|
232
|
+
canExport?: boolean;
|
|
218
233
|
canDownload?: boolean;
|
|
219
234
|
downloadBusy?: boolean;
|
|
235
|
+
onBulkImport?: (mode: BulkImportMode, file: File) => Promise<BulkImportResult>;
|
|
236
|
+
canImport?: boolean;
|
|
237
|
+
importBusy?: boolean;
|
|
220
238
|
/** Column checklist in the side rail. Default true. */
|
|
221
239
|
showColumnPicker?: boolean;
|
|
222
240
|
/** Persist visible column keys in localStorage under this key. */
|
|
@@ -233,4 +251,4 @@ declare function RecordWorkspace<T>({ title, columns, items, rowKey, empty, onAd
|
|
|
233
251
|
/** @deprecated Prefer RecordWorkspace — alias kept for configurator migration */
|
|
234
252
|
declare const RecordTable: typeof RecordWorkspace;
|
|
235
253
|
|
|
236
|
-
export { type AksuiTokenName, AppSelect, type AppSelectOption, AppShell, type AppShellProps, Button, type ButtonVariant, ConfirmDeleteDialog, DateField, Dialog, type ExportColumnRef, type ExportDownloadFormat, FormActions, FormDialog, type MobileNavMode, type PageSizeOption, Pagination, RecordTable, RecordWorkspace, Select, type SelectOption, SideNav, type SideNavItem, Snackbar, StatusMessage, type TableColumn, Topbar, aksuiThemeVersion, aksuiTokens };
|
|
254
|
+
export { type AksuiTokenName, AppSelect, type AppSelectOption, AppShell, type AppShellProps, type BulkImportError, type BulkImportMode, type BulkImportResult, Button, type ButtonVariant, ConfirmDeleteDialog, DateField, Dialog, type ExportColumnRef, type ExportDownloadFormat, FormActions, FormDialog, type MobileNavMode, type PageSizeOption, Pagination, RecordTable, RecordWorkspace, Select, type SelectOption, SideNav, type SideNavItem, Snackbar, StatusMessage, type TableColumn, Topbar, aksuiThemeVersion, aksuiTokens };
|
package/dist/index.js
CHANGED
|
@@ -867,6 +867,11 @@ var EXPORT_FORMAT_OPTIONS = [
|
|
|
867
867
|
{ format: "xlsx", label: "Excel" },
|
|
868
868
|
{ format: "json", label: "JSON" }
|
|
869
869
|
];
|
|
870
|
+
var BULK_IMPORT_MODE_OPTIONS = [
|
|
871
|
+
{ mode: "insert", label: "Insert" },
|
|
872
|
+
{ mode: "update", label: "Update" },
|
|
873
|
+
{ mode: "upsert", label: "Upsert" }
|
|
874
|
+
];
|
|
870
875
|
function defaultVisibleKeys(columns) {
|
|
871
876
|
return columns.filter((column) => column.defaultVisible !== false).map((column) => column.key);
|
|
872
877
|
}
|
|
@@ -943,6 +948,13 @@ function PreviewIcon() {
|
|
|
943
948
|
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "2.4", fill: "none", stroke: "currentColor", strokeWidth: "1.6" })
|
|
944
949
|
] });
|
|
945
950
|
}
|
|
951
|
+
function UploadIcon() {
|
|
952
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", children: [
|
|
953
|
+
/* @__PURE__ */ jsx("path", { d: "M10 16.5V7.3", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
|
|
954
|
+
/* @__PURE__ */ jsx("path", { d: "M6.5 10.8 10 7.2l3.5 3.6", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
955
|
+
/* @__PURE__ */ jsx("path", { d: "M4 4.5h12", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" })
|
|
956
|
+
] });
|
|
957
|
+
}
|
|
946
958
|
function DownloadIcon() {
|
|
947
959
|
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", children: [
|
|
948
960
|
/* @__PURE__ */ jsx("path", { d: "M10 3.5v8.2", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
|
|
@@ -992,7 +1004,11 @@ function RecordWorkspace({
|
|
|
992
1004
|
canDelete,
|
|
993
1005
|
onDownload,
|
|
994
1006
|
canDownload = true,
|
|
1007
|
+
canExport,
|
|
995
1008
|
downloadBusy = false,
|
|
1009
|
+
onBulkImport,
|
|
1010
|
+
canImport = true,
|
|
1011
|
+
importBusy = false,
|
|
996
1012
|
showColumnPicker = true,
|
|
997
1013
|
columnPrefsKey,
|
|
998
1014
|
visibleColumnKeys,
|
|
@@ -1015,6 +1031,11 @@ function RecordWorkspace({
|
|
|
1015
1031
|
const [sideOpen, setSideOpen] = useState(false);
|
|
1016
1032
|
const [toolsDrawerOpen, setToolsDrawerOpen] = useState(false);
|
|
1017
1033
|
const [downloadOpen, setDownloadOpen] = useState(false);
|
|
1034
|
+
const [bulkOpen, setBulkOpen] = useState(false);
|
|
1035
|
+
const [bulkMode, setBulkMode] = useState("upsert");
|
|
1036
|
+
const [bulkFile, setBulkFile] = useState(null);
|
|
1037
|
+
const [bulkReport, setBulkReport] = useState(null);
|
|
1038
|
+
const bulkFileInputRef = useRef(null);
|
|
1018
1039
|
const [columnsOpen, setColumnsOpen] = useState(false);
|
|
1019
1040
|
const [previewEnabled, setPreviewEnabled] = useState(false);
|
|
1020
1041
|
const [previewKey, setPreviewKey] = useState(null);
|
|
@@ -1109,7 +1130,9 @@ function RecordWorkspace({
|
|
|
1109
1130
|
const start = showAll ? 0 : (currentPage - 1) * numericPageSize;
|
|
1110
1131
|
const pageItems = showAll ? sorted : sorted.slice(start, start + numericPageSize);
|
|
1111
1132
|
const showAdd = canAdd && Boolean(onAdd);
|
|
1112
|
-
const
|
|
1133
|
+
const exportAllowed = (canExport ?? true) && canDownload;
|
|
1134
|
+
const showDownload = Boolean(onDownload) && exportAllowed;
|
|
1135
|
+
const showBulkImport = Boolean(onBulkImport) && canImport;
|
|
1113
1136
|
const showFilters = filterableColumns.length > 0;
|
|
1114
1137
|
const showColumns = showColumnPicker && columns.length > 0;
|
|
1115
1138
|
const previewItem = previewKey === null ? null : sorted.find((item) => rowKey(item) === previewKey) ?? null;
|
|
@@ -1154,6 +1177,29 @@ function RecordWorkspace({
|
|
|
1154
1177
|
onDownload(format, exportColumns);
|
|
1155
1178
|
setDownloadOpen(false);
|
|
1156
1179
|
}
|
|
1180
|
+
async function submitBulkImport() {
|
|
1181
|
+
if (!onBulkImport || importBusy || !bulkFile) {
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
setBulkReport(null);
|
|
1185
|
+
try {
|
|
1186
|
+
const report = await onBulkImport(bulkMode, bulkFile);
|
|
1187
|
+
setBulkReport(report);
|
|
1188
|
+
if (report.applied) {
|
|
1189
|
+
setBulkFile(null);
|
|
1190
|
+
if (bulkFileInputRef.current) {
|
|
1191
|
+
bulkFileInputRef.current.value = "";
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
} catch {
|
|
1195
|
+
setBulkReport({
|
|
1196
|
+
totalRows: 0,
|
|
1197
|
+
failed: 1,
|
|
1198
|
+
applied: false,
|
|
1199
|
+
errors: [{ row: 0, code: "ImportFailed", message: "Import request failed." }]
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1157
1203
|
function cellText(column, item) {
|
|
1158
1204
|
const raw = column.display ? column.display(item) : column.value(item);
|
|
1159
1205
|
return raw === null || raw === void 0 || raw === "" ? "\u2014" : String(raw);
|
|
@@ -1274,6 +1320,21 @@ function RecordWorkspace({
|
|
|
1274
1320
|
children: /* @__PURE__ */ jsx(DownloadIcon, {})
|
|
1275
1321
|
}
|
|
1276
1322
|
) : null,
|
|
1323
|
+
showBulkImport ? /* @__PURE__ */ jsx(
|
|
1324
|
+
"button",
|
|
1325
|
+
{
|
|
1326
|
+
type: "button",
|
|
1327
|
+
className: "ghost side-rail-icon",
|
|
1328
|
+
title: "Bulk entry",
|
|
1329
|
+
"aria-label": "Bulk entry",
|
|
1330
|
+
disabled: importBusy,
|
|
1331
|
+
onClick: () => {
|
|
1332
|
+
setSideOpen(true);
|
|
1333
|
+
setBulkOpen(true);
|
|
1334
|
+
},
|
|
1335
|
+
children: /* @__PURE__ */ jsx(UploadIcon, {})
|
|
1336
|
+
}
|
|
1337
|
+
) : null,
|
|
1277
1338
|
showFilters ? /* @__PURE__ */ jsxs(
|
|
1278
1339
|
"button",
|
|
1279
1340
|
{
|
|
@@ -1398,6 +1459,77 @@ function RecordWorkspace({
|
|
|
1398
1459
|
option.format
|
|
1399
1460
|
)) }) : null
|
|
1400
1461
|
] }) : null,
|
|
1462
|
+
showBulkImport ? /* @__PURE__ */ jsxs("div", { className: "side-rail-bulk", children: [
|
|
1463
|
+
/* @__PURE__ */ jsxs(
|
|
1464
|
+
"button",
|
|
1465
|
+
{
|
|
1466
|
+
type: "button",
|
|
1467
|
+
className: "ghost side-rail-bulk-toggle",
|
|
1468
|
+
"aria-expanded": bulkOpen,
|
|
1469
|
+
disabled: importBusy,
|
|
1470
|
+
onClick: () => setBulkOpen((open) => !open),
|
|
1471
|
+
children: [
|
|
1472
|
+
/* @__PURE__ */ jsx(UploadIcon, {}),
|
|
1473
|
+
/* @__PURE__ */ jsx("span", { children: importBusy ? "Importing\u2026" : "Bulk entry" })
|
|
1474
|
+
]
|
|
1475
|
+
}
|
|
1476
|
+
),
|
|
1477
|
+
bulkOpen ? /* @__PURE__ */ jsxs("div", { className: "side-rail-bulk-panel", role: "group", "aria-label": "Bulk entry", children: [
|
|
1478
|
+
/* @__PURE__ */ jsxs("label", { className: "side-rail-bulk-mode", children: [
|
|
1479
|
+
"Mode",
|
|
1480
|
+
/* @__PURE__ */ jsx(
|
|
1481
|
+
Select,
|
|
1482
|
+
{
|
|
1483
|
+
value: bulkMode,
|
|
1484
|
+
options: BULK_IMPORT_MODE_OPTIONS.map((option) => ({ value: option.mode, label: option.label })),
|
|
1485
|
+
onChange: (value) => setBulkMode(value)
|
|
1486
|
+
}
|
|
1487
|
+
)
|
|
1488
|
+
] }),
|
|
1489
|
+
/* @__PURE__ */ jsxs("label", { className: "side-rail-bulk-file", children: [
|
|
1490
|
+
"File",
|
|
1491
|
+
/* @__PURE__ */ jsx(
|
|
1492
|
+
"input",
|
|
1493
|
+
{
|
|
1494
|
+
ref: bulkFileInputRef,
|
|
1495
|
+
type: "file",
|
|
1496
|
+
accept: ".csv,.xlsx,.json",
|
|
1497
|
+
disabled: importBusy,
|
|
1498
|
+
onChange: (event) => {
|
|
1499
|
+
setBulkFile(event.target.files?.[0] ?? null);
|
|
1500
|
+
setBulkReport(null);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
)
|
|
1504
|
+
] }),
|
|
1505
|
+
/* @__PURE__ */ jsx(
|
|
1506
|
+
"button",
|
|
1507
|
+
{
|
|
1508
|
+
type: "button",
|
|
1509
|
+
className: "side-rail-bulk-submit",
|
|
1510
|
+
disabled: importBusy || !bulkFile,
|
|
1511
|
+
onClick: () => void submitBulkImport(),
|
|
1512
|
+
children: importBusy ? "Importing\u2026" : "Import"
|
|
1513
|
+
}
|
|
1514
|
+
),
|
|
1515
|
+
bulkReport ? /* @__PURE__ */ jsxs("div", { className: "side-rail-bulk-report", role: "status", children: [
|
|
1516
|
+
/* @__PURE__ */ jsx("p", { children: bulkReport.applied ? `Applied ${bulkReport.totalRows} row(s).` : `${bulkReport.failed} error(s) in ${bulkReport.totalRows} row(s).` }),
|
|
1517
|
+
bulkReport.errors.length > 0 ? /* @__PURE__ */ jsxs("ul", { className: "side-rail-bulk-errors", children: [
|
|
1518
|
+
bulkReport.errors.slice(0, 8).map((error, index) => /* @__PURE__ */ jsxs("li", { children: [
|
|
1519
|
+
"Row ",
|
|
1520
|
+
error.row,
|
|
1521
|
+
": ",
|
|
1522
|
+
error.message
|
|
1523
|
+
] }, `${error.row}-${error.code}-${index}`)),
|
|
1524
|
+
bulkReport.errors.length > 8 ? /* @__PURE__ */ jsxs("li", { children: [
|
|
1525
|
+
"\u2026and ",
|
|
1526
|
+
bulkReport.errors.length - 8,
|
|
1527
|
+
" more"
|
|
1528
|
+
] }) : null
|
|
1529
|
+
] }) : null
|
|
1530
|
+
] }) : null
|
|
1531
|
+
] }) : null
|
|
1532
|
+
] }) : null,
|
|
1401
1533
|
showFilters ? /* @__PURE__ */ jsxs("div", { className: "side-rail-filters", children: [
|
|
1402
1534
|
/* @__PURE__ */ jsxs("div", { className: "filter-panel-head", children: [
|
|
1403
1535
|
/* @__PURE__ */ jsx("h3", { children: "Filters" }),
|