@mshuja288/aksuicore 0.4.0 → 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/index.cjs CHANGED
@@ -849,11 +849,31 @@ function useIsClient2() {
849
849
  () => false
850
850
  );
851
851
  }
852
+ function useHoverTooltipsEnabled() {
853
+ return react.useSyncExternalStore(
854
+ (onStoreChange) => {
855
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
856
+ return () => {
857
+ };
858
+ }
859
+ const media = window.matchMedia("(hover: hover) and (pointer: fine)");
860
+ media.addEventListener("change", onStoreChange);
861
+ return () => media.removeEventListener("change", onStoreChange);
862
+ },
863
+ () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(hover: hover) and (pointer: fine)").matches,
864
+ () => false
865
+ );
866
+ }
852
867
  var EXPORT_FORMAT_OPTIONS = [
853
868
  { format: "csv", label: "CSV" },
854
869
  { format: "xlsx", label: "Excel" },
855
870
  { format: "json", label: "JSON" }
856
871
  ];
872
+ var BULK_IMPORT_MODE_OPTIONS = [
873
+ { mode: "insert", label: "Insert" },
874
+ { mode: "update", label: "Update" },
875
+ { mode: "upsert", label: "Upsert" }
876
+ ];
857
877
  function defaultVisibleKeys(columns) {
858
878
  return columns.filter((column) => column.defaultVisible !== false).map((column) => column.key);
859
879
  }
@@ -930,6 +950,13 @@ function PreviewIcon() {
930
950
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "2.4", fill: "none", stroke: "currentColor", strokeWidth: "1.6" })
931
951
  ] });
932
952
  }
953
+ function UploadIcon() {
954
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", children: [
955
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 16.5V7.3", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
956
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.5 10.8 10 7.2l3.5 3.6", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }),
957
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 4.5h12", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" })
958
+ ] });
959
+ }
933
960
  function DownloadIcon() {
934
961
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", children: [
935
962
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 3.5v8.2", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
@@ -944,6 +971,19 @@ function MoreIcon() {
944
971
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "15.5", cy: "10", r: "1.5", fill: "currentColor" })
945
972
  ] });
946
973
  }
974
+ function ToolsIcon() {
975
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
976
+ "path",
977
+ {
978
+ d: "M11.5 3.5h5v5M16.2 3.8 10 10M8.2 5.2H3.8v11h11V12",
979
+ fill: "none",
980
+ stroke: "currentColor",
981
+ strokeWidth: "1.6",
982
+ strokeLinecap: "round",
983
+ strokeLinejoin: "round"
984
+ }
985
+ ) });
986
+ }
947
987
  function DetailList({ lines }) {
948
988
  return /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "record-detail-list", children: lines.map((line) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "record-detail-row", children: [
949
989
  /* @__PURE__ */ jsxRuntime.jsx("dt", { children: line.label }),
@@ -966,7 +1006,11 @@ function RecordWorkspace({
966
1006
  canDelete,
967
1007
  onDownload,
968
1008
  canDownload = true,
1009
+ canExport,
969
1010
  downloadBusy = false,
1011
+ onBulkImport,
1012
+ canImport = true,
1013
+ importBusy = false,
970
1014
  showColumnPicker = true,
971
1015
  columnPrefsKey,
972
1016
  visibleColumnKeys,
@@ -987,16 +1031,23 @@ function RecordWorkspace({
987
1031
  const [filters, setFilters] = react.useState({});
988
1032
  const [sort, setSort] = react.useState(null);
989
1033
  const [sideOpen, setSideOpen] = react.useState(false);
1034
+ const [toolsDrawerOpen, setToolsDrawerOpen] = react.useState(false);
990
1035
  const [downloadOpen, setDownloadOpen] = react.useState(false);
1036
+ const [bulkOpen, setBulkOpen] = react.useState(false);
1037
+ const [bulkMode, setBulkMode] = react.useState("upsert");
1038
+ const [bulkFile, setBulkFile] = react.useState(null);
1039
+ const [bulkReport, setBulkReport] = react.useState(null);
1040
+ const bulkFileInputRef = react.useRef(null);
991
1041
  const [columnsOpen, setColumnsOpen] = react.useState(false);
992
1042
  const [previewEnabled, setPreviewEnabled] = react.useState(false);
993
1043
  const [previewKey, setPreviewKey] = react.useState(null);
994
1044
  const [tooltip, setTooltip] = react.useState(null);
995
1045
  const [pageSize, setPageSize] = react.useState("15");
996
1046
  const [page, setPage] = react.useState(1);
997
- const [actionsMenuKey, setActionsMenuKey] = react.useState(null);
1047
+ const [actionsMenu, setActionsMenu] = react.useState(null);
998
1048
  const actionsMenuRef = react.useRef(null);
999
1049
  const isClient = useIsClient2();
1050
+ const hoverTooltipsEnabled = useHoverTooltipsEnabled();
1000
1051
  react.useEffect(() => {
1001
1052
  if (isControlled) {
1002
1053
  return;
@@ -1073,6 +1124,7 @@ function RecordWorkspace({
1073
1124
  [filterableColumns, filters]
1074
1125
  );
1075
1126
  const hiddenColumnCount = columns.length - visibleColumns.length;
1127
+ const toolsBadgeCount = activeFilterCount + (hiddenColumnCount > 0 ? 1 : 0) + (previewEnabled ? 1 : 0);
1076
1128
  const showAll = pageSize === "all";
1077
1129
  const numericPageSize = showAll ? Math.max(sorted.length, 1) : Number(pageSize);
1078
1130
  const pageCount = showAll ? 1 : Math.max(1, Math.ceil(sorted.length / numericPageSize));
@@ -1080,7 +1132,9 @@ function RecordWorkspace({
1080
1132
  const start = showAll ? 0 : (currentPage - 1) * numericPageSize;
1081
1133
  const pageItems = showAll ? sorted : sorted.slice(start, start + numericPageSize);
1082
1134
  const showAdd = canAdd && Boolean(onAdd);
1083
- const showDownload = Boolean(onDownload) && canDownload;
1135
+ const exportAllowed = (canExport ?? true) && canDownload;
1136
+ const showDownload = Boolean(onDownload) && exportAllowed;
1137
+ const showBulkImport = Boolean(onBulkImport) && canImport;
1084
1138
  const showFilters = filterableColumns.length > 0;
1085
1139
  const showColumns = showColumnPicker && columns.length > 0;
1086
1140
  const previewItem = previewKey === null ? null : sorted.find((item) => rowKey(item) === previewKey) ?? null;
@@ -1088,18 +1142,36 @@ function RecordWorkspace({
1088
1142
  key: column.exportKey ?? column.key,
1089
1143
  header: column.header
1090
1144
  }));
1145
+ const canShowTooltip = hoverTooltipsEnabled && !previewEnabled && actionsMenu === null;
1091
1146
  react.useEffect(() => {
1092
- if (actionsMenuKey === null) {
1147
+ if (actionsMenu === null) {
1093
1148
  return;
1094
1149
  }
1095
1150
  function onPointerDown(event) {
1096
1151
  if (actionsMenuRef.current && !actionsMenuRef.current.contains(event.target)) {
1097
- setActionsMenuKey(null);
1152
+ setActionsMenu(null);
1098
1153
  }
1099
1154
  }
1100
1155
  document.addEventListener("mousedown", onPointerDown);
1101
1156
  return () => document.removeEventListener("mousedown", onPointerDown);
1102
- }, [actionsMenuKey]);
1157
+ }, [actionsMenu]);
1158
+ react.useEffect(() => {
1159
+ if (!toolsDrawerOpen) {
1160
+ return;
1161
+ }
1162
+ function onKeyDown(event) {
1163
+ if (event.key === "Escape") {
1164
+ setToolsDrawerOpen(false);
1165
+ }
1166
+ }
1167
+ document.addEventListener("keydown", onKeyDown);
1168
+ const previousOverflow = document.body.style.overflow;
1169
+ document.body.style.overflow = "hidden";
1170
+ return () => {
1171
+ document.removeEventListener("keydown", onKeyDown);
1172
+ document.body.style.overflow = previousOverflow;
1173
+ };
1174
+ }, [toolsDrawerOpen]);
1103
1175
  function requestDownload(format) {
1104
1176
  if (!onDownload || downloadBusy) {
1105
1177
  return;
@@ -1107,6 +1179,29 @@ function RecordWorkspace({
1107
1179
  onDownload(format, exportColumns);
1108
1180
  setDownloadOpen(false);
1109
1181
  }
1182
+ async function submitBulkImport() {
1183
+ if (!onBulkImport || importBusy || !bulkFile) {
1184
+ return;
1185
+ }
1186
+ setBulkReport(null);
1187
+ try {
1188
+ const report = await onBulkImport(bulkMode, bulkFile);
1189
+ setBulkReport(report);
1190
+ if (report.applied) {
1191
+ setBulkFile(null);
1192
+ if (bulkFileInputRef.current) {
1193
+ bulkFileInputRef.current.value = "";
1194
+ }
1195
+ }
1196
+ } catch {
1197
+ setBulkReport({
1198
+ totalRows: 0,
1199
+ failed: 1,
1200
+ applied: false,
1201
+ errors: [{ row: 0, code: "ImportFailed", message: "Import request failed." }]
1202
+ });
1203
+ }
1204
+ }
1110
1205
  function cellText(column, item) {
1111
1206
  const raw = column.display ? column.display(item) : column.value(item);
1112
1207
  return raw === null || raw === void 0 || raw === "" ? "\u2014" : String(raw);
@@ -1154,13 +1249,330 @@ function RecordWorkspace({
1154
1249
  }
1155
1250
  }
1156
1251
  function showTooltip(item, event) {
1252
+ if (!canShowTooltip) {
1253
+ return;
1254
+ }
1157
1255
  const padding = 16;
1158
1256
  const width = 280;
1159
1257
  const x = Math.min(event.clientX + 14, window.innerWidth - width - padding);
1160
1258
  const y = Math.min(event.clientY + 14, window.innerHeight - padding - 24);
1161
1259
  setTooltip({ x, y, lines: detailLines(item) });
1162
1260
  }
1261
+ function openRowActions(item, event) {
1262
+ event.stopPropagation();
1263
+ setTooltip(null);
1264
+ const key = rowKey(item);
1265
+ if (actionsMenu?.key === key) {
1266
+ setActionsMenu(null);
1267
+ return;
1268
+ }
1269
+ const rect = event.currentTarget.getBoundingClientRect();
1270
+ const menuWidth = 168;
1271
+ const menuHeight = 148;
1272
+ const x = Math.min(Math.max(8, rect.right - menuWidth), window.innerWidth - menuWidth - 8);
1273
+ const y = Math.min(rect.bottom + 6, window.innerHeight - menuHeight - 8);
1274
+ setActionsMenu({ key, item, x, y });
1275
+ }
1163
1276
  const summary = sorted.length === 0 ? "0 records" : showAll ? `1\u2013${sorted.length} of ${sorted.length}` : `${start + 1}\u2013${Math.min(start + numericPageSize, sorted.length)} of ${sorted.length}`;
1277
+ function renderToolsBody({ compactIcons }) {
1278
+ if (compactIcons) {
1279
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-icons", children: [
1280
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "side-rail-icon preview-check-icon", title: "Preview", children: [
1281
+ /* @__PURE__ */ jsxRuntime.jsx(
1282
+ "input",
1283
+ {
1284
+ type: "checkbox",
1285
+ checked: previewEnabled,
1286
+ onChange: (event) => setPreviewEnabledValue(event.target.checked),
1287
+ "aria-label": "Preview"
1288
+ }
1289
+ ),
1290
+ /* @__PURE__ */ jsxRuntime.jsx(PreviewIcon, {})
1291
+ ] }),
1292
+ showAdd ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost side-rail-icon", title: addLabel, "aria-label": addLabel, onClick: onAdd, children: /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, {}) }) : null,
1293
+ showColumns ? /* @__PURE__ */ jsxRuntime.jsxs(
1294
+ "button",
1295
+ {
1296
+ type: "button",
1297
+ className: "ghost side-rail-icon",
1298
+ title: "Columns",
1299
+ "aria-label": "Columns",
1300
+ onClick: () => {
1301
+ setSideOpen(true);
1302
+ setColumnsOpen(true);
1303
+ },
1304
+ children: [
1305
+ /* @__PURE__ */ jsxRuntime.jsx(ColumnsIcon, {}),
1306
+ hiddenColumnCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "filter-badge", children: hiddenColumnCount }) : null
1307
+ ]
1308
+ }
1309
+ ) : null,
1310
+ showDownload ? /* @__PURE__ */ jsxRuntime.jsx(
1311
+ "button",
1312
+ {
1313
+ type: "button",
1314
+ className: "ghost side-rail-icon",
1315
+ title: "Download",
1316
+ "aria-label": "Download",
1317
+ disabled: downloadBusy,
1318
+ onClick: () => {
1319
+ setSideOpen(true);
1320
+ setDownloadOpen(true);
1321
+ },
1322
+ children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {})
1323
+ }
1324
+ ) : null,
1325
+ showBulkImport ? /* @__PURE__ */ jsxRuntime.jsx(
1326
+ "button",
1327
+ {
1328
+ type: "button",
1329
+ className: "ghost side-rail-icon",
1330
+ title: "Bulk entry",
1331
+ "aria-label": "Bulk entry",
1332
+ disabled: importBusy,
1333
+ onClick: () => {
1334
+ setSideOpen(true);
1335
+ setBulkOpen(true);
1336
+ },
1337
+ children: /* @__PURE__ */ jsxRuntime.jsx(UploadIcon, {})
1338
+ }
1339
+ ) : null,
1340
+ showFilters ? /* @__PURE__ */ jsxRuntime.jsxs(
1341
+ "button",
1342
+ {
1343
+ type: "button",
1344
+ className: "ghost side-rail-icon",
1345
+ title: "Show filters",
1346
+ "aria-label": "Show filters",
1347
+ onClick: () => setSideOpen(true),
1348
+ children: [
1349
+ /* @__PURE__ */ jsxRuntime.jsx(FilterIcon, {}),
1350
+ activeFilterCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "filter-badge", children: activeFilterCount }) : null
1351
+ ]
1352
+ }
1353
+ ) : null,
1354
+ showFilters ? /* @__PURE__ */ jsxRuntime.jsx(
1355
+ "button",
1356
+ {
1357
+ type: "button",
1358
+ className: "ghost side-rail-icon",
1359
+ title: "Reset filters",
1360
+ "aria-label": "Reset filters",
1361
+ disabled: activeFilterCount === 0,
1362
+ onClick: clearFilters,
1363
+ children: /* @__PURE__ */ jsxRuntime.jsx(ResetIcon, {})
1364
+ }
1365
+ ) : null
1366
+ ] });
1367
+ }
1368
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-body", children: [
1369
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "preview-check", children: [
1370
+ /* @__PURE__ */ jsxRuntime.jsx(
1371
+ "input",
1372
+ {
1373
+ type: "checkbox",
1374
+ checked: previewEnabled,
1375
+ onChange: (event) => setPreviewEnabledValue(event.target.checked),
1376
+ "aria-label": "Preview"
1377
+ }
1378
+ ),
1379
+ /* @__PURE__ */ jsxRuntime.jsx(PreviewIcon, {}),
1380
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "Preview" })
1381
+ ] }),
1382
+ showAdd ? /* @__PURE__ */ jsxRuntime.jsxs(
1383
+ "button",
1384
+ {
1385
+ type: "button",
1386
+ className: "side-rail-add",
1387
+ onClick: () => {
1388
+ setToolsDrawerOpen(false);
1389
+ onAdd?.();
1390
+ },
1391
+ children: [
1392
+ /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, {}),
1393
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: addLabel })
1394
+ ]
1395
+ }
1396
+ ) : null,
1397
+ showColumns ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-columns", children: [
1398
+ /* @__PURE__ */ jsxRuntime.jsxs(
1399
+ "button",
1400
+ {
1401
+ type: "button",
1402
+ className: "ghost side-rail-columns-toggle",
1403
+ "aria-expanded": columnsOpen,
1404
+ onClick: () => setColumnsOpen((open) => !open),
1405
+ children: [
1406
+ /* @__PURE__ */ jsxRuntime.jsx(ColumnsIcon, {}),
1407
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1408
+ "Columns",
1409
+ hiddenColumnCount > 0 ? ` (${visibleColumns.length}/${columns.length})` : ""
1410
+ ] })
1411
+ ]
1412
+ }
1413
+ ),
1414
+ columnsOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-columns-panel", role: "group", "aria-label": "Visible columns", children: [
1415
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-columns-actions", children: [
1416
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost", onClick: selectAllColumns, children: "Select all" }),
1417
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost", onClick: resetColumns, children: "Reset" })
1418
+ ] }),
1419
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "side-rail-columns-list", children: columns.map((column) => {
1420
+ const checked = resolvedVisibleKeys.includes(column.key);
1421
+ const disableUncheck = checked && resolvedVisibleKeys.length <= 1;
1422
+ return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "side-rail-column-option", children: [
1423
+ /* @__PURE__ */ jsxRuntime.jsx(
1424
+ "input",
1425
+ {
1426
+ type: "checkbox",
1427
+ checked,
1428
+ disabled: disableUncheck,
1429
+ onChange: (event) => toggleColumnVisible(column.key, event.target.checked)
1430
+ }
1431
+ ),
1432
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: column.header })
1433
+ ] }, column.key);
1434
+ }) })
1435
+ ] }) : null
1436
+ ] }) : null,
1437
+ showDownload ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-download", children: [
1438
+ /* @__PURE__ */ jsxRuntime.jsxs(
1439
+ "button",
1440
+ {
1441
+ type: "button",
1442
+ className: "ghost side-rail-download-toggle",
1443
+ "aria-expanded": downloadOpen,
1444
+ disabled: downloadBusy,
1445
+ onClick: () => setDownloadOpen((open) => !open),
1446
+ children: [
1447
+ /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {}),
1448
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: downloadBusy ? "Downloading\u2026" : "Download" })
1449
+ ]
1450
+ }
1451
+ ),
1452
+ downloadOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "side-rail-download-formats", role: "group", "aria-label": "Download format", children: EXPORT_FORMAT_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
1453
+ "button",
1454
+ {
1455
+ type: "button",
1456
+ className: "ghost side-rail-download-format",
1457
+ disabled: downloadBusy,
1458
+ onClick: () => requestDownload(option.format),
1459
+ children: option.label
1460
+ },
1461
+ option.format
1462
+ )) }) : null
1463
+ ] }) : null,
1464
+ showBulkImport ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-bulk", children: [
1465
+ /* @__PURE__ */ jsxRuntime.jsxs(
1466
+ "button",
1467
+ {
1468
+ type: "button",
1469
+ className: "ghost side-rail-bulk-toggle",
1470
+ "aria-expanded": bulkOpen,
1471
+ disabled: importBusy,
1472
+ onClick: () => setBulkOpen((open) => !open),
1473
+ children: [
1474
+ /* @__PURE__ */ jsxRuntime.jsx(UploadIcon, {}),
1475
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: importBusy ? "Importing\u2026" : "Bulk entry" })
1476
+ ]
1477
+ }
1478
+ ),
1479
+ bulkOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-bulk-panel", role: "group", "aria-label": "Bulk entry", children: [
1480
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "side-rail-bulk-mode", children: [
1481
+ "Mode",
1482
+ /* @__PURE__ */ jsxRuntime.jsx(
1483
+ Select,
1484
+ {
1485
+ value: bulkMode,
1486
+ options: BULK_IMPORT_MODE_OPTIONS.map((option) => ({ value: option.mode, label: option.label })),
1487
+ onChange: (value) => setBulkMode(value)
1488
+ }
1489
+ )
1490
+ ] }),
1491
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "side-rail-bulk-file", children: [
1492
+ "File",
1493
+ /* @__PURE__ */ jsxRuntime.jsx(
1494
+ "input",
1495
+ {
1496
+ ref: bulkFileInputRef,
1497
+ type: "file",
1498
+ accept: ".csv,.xlsx,.json",
1499
+ disabled: importBusy,
1500
+ onChange: (event) => {
1501
+ setBulkFile(event.target.files?.[0] ?? null);
1502
+ setBulkReport(null);
1503
+ }
1504
+ }
1505
+ )
1506
+ ] }),
1507
+ /* @__PURE__ */ jsxRuntime.jsx(
1508
+ "button",
1509
+ {
1510
+ type: "button",
1511
+ className: "side-rail-bulk-submit",
1512
+ disabled: importBusy || !bulkFile,
1513
+ onClick: () => void submitBulkImport(),
1514
+ children: importBusy ? "Importing\u2026" : "Import"
1515
+ }
1516
+ ),
1517
+ bulkReport ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-bulk-report", role: "status", children: [
1518
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: bulkReport.applied ? `Applied ${bulkReport.totalRows} row(s).` : `${bulkReport.failed} error(s) in ${bulkReport.totalRows} row(s).` }),
1519
+ bulkReport.errors.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "side-rail-bulk-errors", children: [
1520
+ bulkReport.errors.slice(0, 8).map((error, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
1521
+ "Row ",
1522
+ error.row,
1523
+ ": ",
1524
+ error.message
1525
+ ] }, `${error.row}-${error.code}-${index}`)),
1526
+ bulkReport.errors.length > 8 ? /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
1527
+ "\u2026and ",
1528
+ bulkReport.errors.length - 8,
1529
+ " more"
1530
+ ] }) : null
1531
+ ] }) : null
1532
+ ] }) : null
1533
+ ] }) : null
1534
+ ] }) : null,
1535
+ showFilters ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-filters", children: [
1536
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "filter-panel-head", children: [
1537
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: "Filters" }),
1538
+ /* @__PURE__ */ jsxRuntime.jsxs(
1539
+ "button",
1540
+ {
1541
+ type: "button",
1542
+ className: "ghost filter-clear",
1543
+ title: "Reset filters",
1544
+ "aria-label": "Reset filters",
1545
+ disabled: activeFilterCount === 0,
1546
+ onClick: clearFilters,
1547
+ children: [
1548
+ /* @__PURE__ */ jsxRuntime.jsx(ResetIcon, {}),
1549
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Reset" })
1550
+ ]
1551
+ }
1552
+ )
1553
+ ] }),
1554
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "filter-panel-stack", children: filterableColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1555
+ column.header,
1556
+ column.filterOptions ? /* @__PURE__ */ jsxRuntime.jsx(
1557
+ Select,
1558
+ {
1559
+ value: filters[column.key] ?? "",
1560
+ options: [{ value: "", label: column.filterPlaceholder ?? "All" }, ...column.filterOptions],
1561
+ onChange: (value) => changeFilter(column.key, value),
1562
+ placeholder: column.filterPlaceholder ?? "All"
1563
+ }
1564
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1565
+ "input",
1566
+ {
1567
+ value: filters[column.key] ?? "",
1568
+ onChange: (event) => changeFilter(column.key, event.target.value),
1569
+ placeholder: `Filter ${column.header.toLowerCase()}`
1570
+ }
1571
+ )
1572
+ ] }, column.key)) })
1573
+ ] }) : null
1574
+ ] });
1575
+ }
1164
1576
  function renderRowActions(item) {
1165
1577
  const key = rowKey(item);
1166
1578
  const updateAllowed = canUpdate ? canUpdate(item) : Boolean(onUpdate);
@@ -1195,66 +1607,45 @@ function RecordWorkspace({
1195
1607
  }
1196
1608
  ) : null
1197
1609
  ] }),
1198
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "row-actions row-actions-mobile", ref: actionsMenuKey === key ? actionsMenuRef : void 0, children: [
1199
- /* @__PURE__ */ jsxRuntime.jsx(
1200
- "button",
1201
- {
1202
- type: "button",
1203
- className: "ghost row-action-menu-trigger",
1204
- "aria-haspopup": "menu",
1205
- "aria-expanded": actionsMenuKey === key,
1206
- "aria-label": "Row actions",
1207
- onClick: () => setActionsMenuKey((current) => current === key ? null : key),
1208
- children: /* @__PURE__ */ jsxRuntime.jsx(MoreIcon, {})
1209
- }
1210
- ),
1211
- actionsMenuKey === key ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "row-action-menu", role: "menu", children: [
1212
- onView ? /* @__PURE__ */ jsxRuntime.jsx(
1213
- "button",
1214
- {
1215
- type: "button",
1216
- role: "menuitem",
1217
- className: "ghost",
1218
- onClick: () => {
1219
- setActionsMenuKey(null);
1220
- onView(item);
1221
- },
1222
- children: "View"
1223
- }
1224
- ) : null,
1225
- onUpdate ? /* @__PURE__ */ jsxRuntime.jsx(
1226
- "button",
1227
- {
1228
- type: "button",
1229
- role: "menuitem",
1230
- className: "ghost",
1231
- disabled: !updateAllowed,
1232
- onClick: () => {
1233
- setActionsMenuKey(null);
1234
- onUpdate(item);
1235
- },
1236
- children: "Update"
1237
- }
1238
- ) : null,
1239
- onDelete ? /* @__PURE__ */ jsxRuntime.jsx(
1240
- "button",
1241
- {
1242
- type: "button",
1243
- role: "menuitem",
1244
- className: "ghost danger",
1245
- disabled: !deleteAllowed,
1246
- onClick: () => {
1247
- setActionsMenuKey(null);
1248
- onDelete(item);
1249
- },
1250
- children: "Delete"
1251
- }
1252
- ) : null
1253
- ] }) : null
1254
- ] })
1610
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "row-actions row-actions-mobile", children: /* @__PURE__ */ jsxRuntime.jsx(
1611
+ "button",
1612
+ {
1613
+ type: "button",
1614
+ className: actionsMenu?.key === key ? "ghost row-action-menu-trigger open" : "ghost row-action-menu-trigger",
1615
+ "aria-haspopup": "menu",
1616
+ "aria-expanded": actionsMenu?.key === key,
1617
+ "aria-label": "Row actions",
1618
+ onClick: (event) => openRowActions(item, event),
1619
+ children: /* @__PURE__ */ jsxRuntime.jsx(MoreIcon, {})
1620
+ }
1621
+ ) })
1255
1622
  ] });
1256
1623
  }
1257
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "list-workspace", "aria-label": title, children: [
1624
+ const actionsMenuItem = actionsMenu?.item;
1625
+ const actionsUpdateAllowed = actionsMenuItem ? canUpdate ? canUpdate(actionsMenuItem) : Boolean(onUpdate) : false;
1626
+ const actionsDeleteAllowed = actionsMenuItem ? canDelete ? canDelete(actionsMenuItem) : Boolean(onDelete) : false;
1627
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: toolsDrawerOpen ? "list-workspace tools-drawer-open" : "list-workspace", "aria-label": title, children: [
1628
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tools-mobile-bar", children: [
1629
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tools-mobile-bar-start", children: showAdd ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "tools-mobile-add", onClick: onAdd, children: [
1630
+ /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, {}),
1631
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: addLabel })
1632
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tools-mobile-title", children: title }) }),
1633
+ /* @__PURE__ */ jsxRuntime.jsxs(
1634
+ "button",
1635
+ {
1636
+ type: "button",
1637
+ className: "ghost tools-mobile-toggle",
1638
+ "aria-expanded": toolsDrawerOpen,
1639
+ "aria-controls": "aksui-tools-drawer",
1640
+ onClick: () => setToolsDrawerOpen(true),
1641
+ children: [
1642
+ /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}),
1643
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tools" }),
1644
+ toolsBadgeCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "filter-badge", children: toolsBadgeCount }) : null
1645
+ ]
1646
+ }
1647
+ )
1648
+ ] }),
1258
1649
  /* @__PURE__ */ jsxRuntime.jsxs(
1259
1650
  "div",
1260
1651
  {
@@ -1297,16 +1688,10 @@ function RecordWorkspace({
1297
1688
  {
1298
1689
  className: selected ? "data-row selected" : "data-row",
1299
1690
  onMouseEnter: (event) => {
1300
- if (!previewEnabled) {
1301
- showTooltip(item, event);
1302
- }
1691
+ showTooltip(item, event);
1303
1692
  focusRecord(item);
1304
1693
  },
1305
- onMouseMove: (event) => {
1306
- if (!previewEnabled) {
1307
- showTooltip(item, event);
1308
- }
1309
- },
1694
+ onMouseMove: (event) => showTooltip(item, event),
1310
1695
  onMouseLeave: () => setTooltip(null),
1311
1696
  onClick: () => focusRecord(item),
1312
1697
  children: [
@@ -1338,7 +1723,7 @@ function RecordWorkspace({
1338
1723
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "preview-kicker", children: "Preview" }),
1339
1724
  /* @__PURE__ */ jsxRuntime.jsx("h3", { children: previewTitle ?? "No record selected" })
1340
1725
  ] }) }),
1341
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "preview-panel-body", children: previewItem ? /* @__PURE__ */ jsxRuntime.jsx(DetailList, { lines: detailLines(previewItem) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "preview-empty", children: "Hover or click a row to preview its details here." }) })
1726
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "preview-panel-body", children: previewItem ? /* @__PURE__ */ jsxRuntime.jsx(DetailList, { lines: detailLines(previewItem) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "preview-empty", children: "Select a row to preview its details here." }) })
1342
1727
  ] }) : null,
1343
1728
  /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: sideOpen ? "side-rail open" : "side-rail", "aria-label": "Actions and filters", children: [
1344
1729
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1355,210 +1740,102 @@ function RecordWorkspace({
1355
1740
  ]
1356
1741
  }
1357
1742
  ),
1358
- sideOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-body", children: [
1359
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "preview-check", children: [
1360
- /* @__PURE__ */ jsxRuntime.jsx(
1361
- "input",
1362
- {
1363
- type: "checkbox",
1364
- checked: previewEnabled,
1365
- onChange: (event) => setPreviewEnabledValue(event.target.checked),
1366
- "aria-label": "Preview"
1367
- }
1368
- ),
1369
- /* @__PURE__ */ jsxRuntime.jsx(PreviewIcon, {}),
1370
- /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "Preview" })
1371
- ] }),
1372
- showAdd ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "side-rail-add", onClick: onAdd, children: [
1373
- /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, {}),
1374
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: addLabel })
1375
- ] }) : null,
1376
- showColumns ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-columns", children: [
1377
- /* @__PURE__ */ jsxRuntime.jsxs(
1378
- "button",
1379
- {
1380
- type: "button",
1381
- className: "ghost side-rail-columns-toggle",
1382
- "aria-expanded": columnsOpen,
1383
- onClick: () => setColumnsOpen((open) => !open),
1384
- children: [
1385
- /* @__PURE__ */ jsxRuntime.jsx(ColumnsIcon, {}),
1386
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1387
- "Columns",
1388
- hiddenColumnCount > 0 ? ` (${visibleColumns.length}/${columns.length})` : ""
1389
- ] })
1390
- ]
1391
- }
1392
- ),
1393
- columnsOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-columns-panel", role: "group", "aria-label": "Visible columns", children: [
1394
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-columns-actions", children: [
1395
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost", onClick: selectAllColumns, children: "Select all" }),
1396
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost", onClick: resetColumns, children: "Reset" })
1397
- ] }),
1398
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "side-rail-columns-list", children: columns.map((column) => {
1399
- const checked = resolvedVisibleKeys.includes(column.key);
1400
- const disableUncheck = checked && resolvedVisibleKeys.length <= 1;
1401
- return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "side-rail-column-option", children: [
1402
- /* @__PURE__ */ jsxRuntime.jsx(
1403
- "input",
1404
- {
1405
- type: "checkbox",
1406
- checked,
1407
- disabled: disableUncheck,
1408
- onChange: (event) => toggleColumnVisible(column.key, event.target.checked)
1409
- }
1410
- ),
1411
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: column.header })
1412
- ] }, column.key);
1413
- }) })
1414
- ] }) : null
1415
- ] }) : null,
1416
- showDownload ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-download", children: [
1417
- /* @__PURE__ */ jsxRuntime.jsxs(
1418
- "button",
1419
- {
1420
- type: "button",
1421
- className: "ghost side-rail-download-toggle",
1422
- "aria-expanded": downloadOpen,
1423
- disabled: downloadBusy,
1424
- onClick: () => setDownloadOpen((open) => !open),
1425
- children: [
1426
- /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {}),
1427
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: downloadBusy ? "Downloading\u2026" : "Download" })
1428
- ]
1429
- }
1430
- ),
1431
- downloadOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "side-rail-download-formats", role: "group", "aria-label": "Download format", children: EXPORT_FORMAT_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
1432
- "button",
1433
- {
1434
- type: "button",
1435
- className: "ghost side-rail-download-format",
1436
- disabled: downloadBusy,
1437
- onClick: () => requestDownload(option.format),
1438
- children: option.label
1439
- },
1440
- option.format
1441
- )) }) : null
1442
- ] }) : null,
1443
- showFilters ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-filters", children: [
1444
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "filter-panel-head", children: [
1445
- /* @__PURE__ */ jsxRuntime.jsx("h3", { children: "Filters" }),
1446
- /* @__PURE__ */ jsxRuntime.jsxs(
1447
- "button",
1448
- {
1449
- type: "button",
1450
- className: "ghost filter-clear",
1451
- title: "Reset filters",
1452
- "aria-label": "Reset filters",
1453
- disabled: activeFilterCount === 0,
1454
- onClick: clearFilters,
1455
- children: [
1456
- /* @__PURE__ */ jsxRuntime.jsx(ResetIcon, {}),
1457
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Reset" })
1458
- ]
1459
- }
1460
- )
1461
- ] }),
1462
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "filter-panel-stack", children: filterableColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1463
- column.header,
1464
- column.filterOptions ? /* @__PURE__ */ jsxRuntime.jsx(
1465
- Select,
1466
- {
1467
- value: filters[column.key] ?? "",
1468
- options: [{ value: "", label: column.filterPlaceholder ?? "All" }, ...column.filterOptions],
1469
- onChange: (value) => changeFilter(column.key, value),
1470
- placeholder: column.filterPlaceholder ?? "All"
1471
- }
1472
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1473
- "input",
1474
- {
1475
- value: filters[column.key] ?? "",
1476
- onChange: (event) => changeFilter(column.key, event.target.value),
1477
- placeholder: `Filter ${column.header.toLowerCase()}`
1478
- }
1479
- )
1480
- ] }, column.key)) })
1481
- ] }) : null
1482
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "side-rail-icons", children: [
1483
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "side-rail-icon preview-check-icon", title: "Preview", children: [
1484
- /* @__PURE__ */ jsxRuntime.jsx(
1485
- "input",
1486
- {
1487
- type: "checkbox",
1488
- checked: previewEnabled,
1489
- onChange: (event) => setPreviewEnabledValue(event.target.checked),
1490
- "aria-label": "Preview"
1491
- }
1492
- ),
1493
- /* @__PURE__ */ jsxRuntime.jsx(PreviewIcon, {})
1494
- ] }),
1495
- showAdd ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost side-rail-icon", title: addLabel, "aria-label": addLabel, onClick: onAdd, children: /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, {}) }) : null,
1496
- showColumns ? /* @__PURE__ */ jsxRuntime.jsxs(
1497
- "button",
1498
- {
1499
- type: "button",
1500
- className: "ghost side-rail-icon",
1501
- title: "Columns",
1502
- "aria-label": "Columns",
1503
- onClick: () => {
1504
- setSideOpen(true);
1505
- setColumnsOpen(true);
1506
- },
1507
- children: [
1508
- /* @__PURE__ */ jsxRuntime.jsx(ColumnsIcon, {}),
1509
- hiddenColumnCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "filter-badge", children: hiddenColumnCount }) : null
1510
- ]
1511
- }
1512
- ) : null,
1513
- showDownload ? /* @__PURE__ */ jsxRuntime.jsx(
1514
- "button",
1515
- {
1516
- type: "button",
1517
- className: "ghost side-rail-icon",
1518
- title: "Download",
1519
- "aria-label": "Download",
1520
- "aria-expanded": downloadOpen,
1521
- disabled: downloadBusy,
1522
- onClick: () => {
1523
- setSideOpen(true);
1524
- setDownloadOpen(true);
1525
- },
1526
- children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {})
1527
- }
1528
- ) : null,
1529
- showFilters ? /* @__PURE__ */ jsxRuntime.jsxs(
1530
- "button",
1531
- {
1532
- type: "button",
1533
- className: "ghost side-rail-icon",
1534
- title: "Show filters",
1535
- "aria-label": "Show filters",
1536
- onClick: () => setSideOpen(true),
1537
- children: [
1538
- /* @__PURE__ */ jsxRuntime.jsx(FilterIcon, {}),
1539
- activeFilterCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "filter-badge", children: activeFilterCount }) : null
1540
- ]
1541
- }
1542
- ) : null,
1543
- showFilters ? /* @__PURE__ */ jsxRuntime.jsx(
1544
- "button",
1545
- {
1546
- type: "button",
1547
- className: "ghost side-rail-icon",
1548
- title: "Reset filters",
1549
- "aria-label": "Reset filters",
1550
- disabled: activeFilterCount === 0,
1551
- onClick: clearFilters,
1552
- children: /* @__PURE__ */ jsxRuntime.jsx(ResetIcon, {})
1553
- }
1554
- ) : null
1555
- ] })
1743
+ sideOpen ? renderToolsBody({ compactIcons: false }) : renderToolsBody({ compactIcons: true })
1556
1744
  ] })
1557
1745
  ]
1558
1746
  }
1559
1747
  ),
1748
+ isClient ? reactDom.createPortal(
1749
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1750
+ /* @__PURE__ */ jsxRuntime.jsx(
1751
+ "button",
1752
+ {
1753
+ type: "button",
1754
+ className: toolsDrawerOpen ? "tools-drawer-backdrop open" : "tools-drawer-backdrop",
1755
+ "aria-label": "Close tools",
1756
+ tabIndex: toolsDrawerOpen ? 0 : -1,
1757
+ onClick: () => setToolsDrawerOpen(false)
1758
+ }
1759
+ ),
1760
+ /* @__PURE__ */ jsxRuntime.jsxs(
1761
+ "aside",
1762
+ {
1763
+ id: "aksui-tools-drawer",
1764
+ className: toolsDrawerOpen ? "tools-drawer open" : "tools-drawer",
1765
+ "aria-label": "Workspace tools",
1766
+ "aria-hidden": !toolsDrawerOpen,
1767
+ children: [
1768
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tools-drawer-head", children: [
1769
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1770
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tools-drawer-kicker", children: "Workspace" }),
1771
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: "Tools" })
1772
+ ] }),
1773
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "ghost tools-drawer-close", onClick: () => setToolsDrawerOpen(false), children: "Close" })
1774
+ ] }),
1775
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tools-drawer-body", children: renderToolsBody({ compactIcons: false }) })
1776
+ ]
1777
+ }
1778
+ )
1779
+ ] }),
1780
+ document.body
1781
+ ) : null,
1560
1782
  form,
1561
- isClient && tooltip && !previewEnabled ? reactDom.createPortal(
1783
+ isClient && actionsMenu && actionsMenuItem ? reactDom.createPortal(
1784
+ /* @__PURE__ */ jsxRuntime.jsxs(
1785
+ "div",
1786
+ {
1787
+ ref: actionsMenuRef,
1788
+ className: "row-action-menu row-action-menu-portal",
1789
+ role: "menu",
1790
+ style: { left: actionsMenu.x, top: actionsMenu.y },
1791
+ children: [
1792
+ onView ? /* @__PURE__ */ jsxRuntime.jsx(
1793
+ "button",
1794
+ {
1795
+ type: "button",
1796
+ role: "menuitem",
1797
+ className: "ghost",
1798
+ onClick: () => {
1799
+ setActionsMenu(null);
1800
+ onView(actionsMenuItem);
1801
+ },
1802
+ children: "View"
1803
+ }
1804
+ ) : null,
1805
+ onUpdate ? /* @__PURE__ */ jsxRuntime.jsx(
1806
+ "button",
1807
+ {
1808
+ type: "button",
1809
+ role: "menuitem",
1810
+ className: "ghost",
1811
+ disabled: !actionsUpdateAllowed,
1812
+ onClick: () => {
1813
+ setActionsMenu(null);
1814
+ onUpdate(actionsMenuItem);
1815
+ },
1816
+ children: "Update"
1817
+ }
1818
+ ) : null,
1819
+ onDelete ? /* @__PURE__ */ jsxRuntime.jsx(
1820
+ "button",
1821
+ {
1822
+ type: "button",
1823
+ role: "menuitem",
1824
+ className: "ghost danger",
1825
+ disabled: !actionsDeleteAllowed,
1826
+ onClick: () => {
1827
+ setActionsMenu(null);
1828
+ onDelete(actionsMenuItem);
1829
+ },
1830
+ children: "Delete"
1831
+ }
1832
+ ) : null
1833
+ ]
1834
+ }
1835
+ ),
1836
+ document.body
1837
+ ) : null,
1838
+ isClient && tooltip && canShowTooltip ? reactDom.createPortal(
1562
1839
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "record-tooltip", style: { left: tooltip.x, top: tooltip.y }, role: "tooltip", children: [
1563
1840
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "record-tooltip-title", children: title }),
1564
1841
  /* @__PURE__ */ jsxRuntime.jsx(DetailList, { lines: tooltip.lines })