@open-mercato/ui 0.7.1-develop.7193.1.910a5b0a1e → 0.7.1-develop.7195.1.b5efd1d51a
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/.turbo/turbo-build.log +2 -2
- package/dist/backend/AppShell.js +66 -7
- package/dist/backend/AppShell.js.map +2 -2
- package/dist/backend/CrudForm.js +14 -8
- package/dist/backend/CrudForm.js.map +2 -2
- package/dist/backend/DataTable.js +108 -11
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/forms/ActionsDropdown.js +35 -5
- package/dist/backend/forms/ActionsDropdown.js.map +2 -2
- package/dist/backend/forms/index.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.generated.js +6 -0
- package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
- package/dist/backend/injection/spotIds.js +2 -0
- package/dist/backend/injection/spotIds.js.map +2 -2
- package/dist/backend/inputs/DurationInput.js +182 -0
- package/dist/backend/inputs/DurationInput.js.map +7 -0
- package/dist/backend/inputs/EventSelect.js.map +2 -2
- package/dist/backend/inputs/index.js +1 -0
- package/dist/backend/inputs/index.js.map +2 -2
- package/dist/backend/nav/navBadges.js +38 -0
- package/dist/backend/nav/navBadges.js.map +7 -0
- package/dist/primitives/segmented-control.js +4 -4
- package/dist/primitives/segmented-control.js.map +1 -1
- package/dist/primitives/sheet.js +21 -11
- package/dist/primitives/sheet.js.map +2 -2
- package/dist/primitives/textarea.js +54 -4
- package/dist/primitives/textarea.js.map +2 -2
- package/package.json +3 -3
- package/src/backend/AppShell.tsx +106 -2
- package/src/backend/CrudForm.tsx +28 -9
- package/src/backend/DataTable.tsx +176 -22
- package/src/backend/__tests__/CrudForm.density.test.tsx +113 -0
- package/src/backend/__tests__/DataTable.propBulkActions.test.tsx +200 -0
- package/src/backend/__tests__/DataTable.render.test.tsx +76 -0
- package/src/backend/__tests__/navBadges.test.ts +57 -0
- package/src/backend/forms/ActionsDropdown.tsx +73 -6
- package/src/backend/forms/index.ts +1 -1
- package/src/backend/icons/lucideRegistry.generated.tsx +6 -0
- package/src/backend/injection/spotIds.ts +8 -0
- package/src/backend/inputs/DurationInput.tsx +207 -0
- package/src/backend/inputs/EventSelect.tsx +2 -0
- package/src/backend/inputs/__tests__/DurationInput.test.tsx +220 -0
- package/src/backend/inputs/index.ts +1 -0
- package/src/backend/nav/navBadges.ts +61 -0
- package/src/primitives/__tests__/segmented-control.test.tsx +2 -2
- package/src/primitives/__tests__/textarea.test.tsx +50 -0
- package/src/primitives/segmented-control.tsx +7 -7
- package/src/primitives/sheet.tsx +7 -1
- package/src/primitives/textarea.tsx +77 -4
|
@@ -3,11 +3,12 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { useRouter } from "next/navigation";
|
|
5
5
|
import { flexRender } from "@tanstack/react-table";
|
|
6
|
-
import { useLegacyTable, getCoreRowModel, getSortedRowModel } from "@tanstack/react-table/legacy";
|
|
6
|
+
import { useLegacyTable, getCoreRowModel, getSortedRowModel, getExpandedRowModel } from "@tanstack/react-table/legacy";
|
|
7
7
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
8
|
-
import { RefreshCw, Loader2, SlidersHorizontal, MoreHorizontal, Circle, Filter, ChevronUp, ChevronDown, ChevronsUpDown, Check, Inbox, Save } from "lucide-react";
|
|
8
|
+
import { RefreshCw, Loader2, SlidersHorizontal, MoreHorizontal, Circle, Filter, ChevronUp, ChevronDown, ChevronRight, ChevronsUpDown, Check, Inbox, Save } from "lucide-react";
|
|
9
9
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../primitives/table.js";
|
|
10
10
|
import { Button } from "../primitives/button.js";
|
|
11
|
+
import { IconButton } from "../primitives/icon-button.js";
|
|
11
12
|
import { Checkbox } from "../primitives/checkbox.js";
|
|
12
13
|
import {
|
|
13
14
|
Select,
|
|
@@ -789,7 +790,11 @@ function DataTable({
|
|
|
789
790
|
advancedFilter: advancedFilterInput,
|
|
790
791
|
columnChooser,
|
|
791
792
|
activeFilterChips,
|
|
792
|
-
filterAwareEmptyState
|
|
793
|
+
filterAwareEmptyState,
|
|
794
|
+
getSubRows,
|
|
795
|
+
expandable,
|
|
796
|
+
expanded: expandedProp,
|
|
797
|
+
onExpandedChange
|
|
793
798
|
}) {
|
|
794
799
|
const t = useT();
|
|
795
800
|
const { confirm, ConfirmDialogElement } = useConfirmDialog();
|
|
@@ -835,6 +840,7 @@ function DataTable({
|
|
|
835
840
|
const queryClient = useQueryClient();
|
|
836
841
|
const perspectiveConfig = perspective ?? null;
|
|
837
842
|
const perspectiveTableId = perspectiveConfig?.tableId ?? null;
|
|
843
|
+
const perspectiveAlign = perspectiveConfig?.align ?? "left";
|
|
838
844
|
const perspectiveEnabled = Boolean(perspectiveTableId);
|
|
839
845
|
const initialSnapshotRef = React.useRef(null);
|
|
840
846
|
const snapshotHydratedTableRef = React.useRef(null);
|
|
@@ -1192,14 +1198,34 @@ function DataTable({
|
|
|
1192
1198
|
const [rowSelection, setRowSelection] = React.useState({});
|
|
1193
1199
|
const selectionScopeKeyRef = React.useRef(selectionScopeKey);
|
|
1194
1200
|
const enableClientSorting = sortable && !manualSorting;
|
|
1201
|
+
const expansionEnabled = getSubRows !== void 0 || expandable !== void 0;
|
|
1202
|
+
const [internalExpanded, setInternalExpanded] = React.useState({});
|
|
1203
|
+
const expandedState = expandedProp !== void 0 ? expandedProp : internalExpanded;
|
|
1204
|
+
const handleExpandedChange = React.useCallback((updater) => {
|
|
1205
|
+
if (onExpandedChange) {
|
|
1206
|
+
onExpandedChange(updater);
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
setInternalExpanded((prev) => typeof updater === "function" ? updater(prev) : updater);
|
|
1210
|
+
}, [onExpandedChange]);
|
|
1195
1211
|
const table = useLegacyTable({
|
|
1196
1212
|
data: clientFilteredData,
|
|
1197
1213
|
columns: mergedColumns,
|
|
1198
1214
|
getCoreRowModel: getCoreRowModel(),
|
|
1199
1215
|
...enableClientSorting ? { getSortedRowModel: getSortedRowModel() } : {},
|
|
1216
|
+
...expansionEnabled ? {
|
|
1217
|
+
getSubRows,
|
|
1218
|
+
getExpandedRowModel: getExpandedRowModel(),
|
|
1219
|
+
getRowCanExpand: (row) => {
|
|
1220
|
+
if (typeof expandable === "function") return expandable(row.original);
|
|
1221
|
+
if (expandable === true) return true;
|
|
1222
|
+
return (row.subRows?.length ?? 0) > 0;
|
|
1223
|
+
},
|
|
1224
|
+
onExpandedChange: handleExpandedChange
|
|
1225
|
+
} : {},
|
|
1200
1226
|
manualSorting: manualSorting === true,
|
|
1201
1227
|
getRowId: resolveDataTableRowId,
|
|
1202
|
-
state: { sorting, columnVisibility, columnOrder, rowSelection },
|
|
1228
|
+
state: { sorting, columnVisibility, columnOrder, rowSelection, ...expansionEnabled ? { expanded: expandedState } : {} },
|
|
1203
1229
|
enableRowSelection: hasInjectedBulkActions,
|
|
1204
1230
|
onSortingChange: (updater) => {
|
|
1205
1231
|
const next = typeof updater === "function" ? updater(sorting) : updater;
|
|
@@ -2200,12 +2226,44 @@ function DataTable({
|
|
|
2200
2226
|
);
|
|
2201
2227
|
const runPropBulkAction = React.useCallback(
|
|
2202
2228
|
async (action) => {
|
|
2203
|
-
|
|
2204
|
-
|
|
2229
|
+
try {
|
|
2230
|
+
const result = await action.onExecute(selectedRows);
|
|
2231
|
+
if (result === false) return;
|
|
2232
|
+
if (!result || typeof result !== "object") {
|
|
2233
|
+
setRowSelection({});
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
if (result.ok === false) {
|
|
2237
|
+
if (result.message === void 0) return;
|
|
2238
|
+
flash(result.message, "error");
|
|
2239
|
+
return;
|
|
2240
|
+
}
|
|
2205
2241
|
setRowSelection({});
|
|
2242
|
+
if (result.progressJobId) {
|
|
2243
|
+
trackedBulkProgressJobIdsRef.current.add(result.progressJobId);
|
|
2244
|
+
flash(
|
|
2245
|
+
result.message ?? t("ui.dataTable.bulkAction.started", "Bulk action started. Track progress in the top bar."),
|
|
2246
|
+
"success"
|
|
2247
|
+
);
|
|
2248
|
+
return;
|
|
2249
|
+
}
|
|
2250
|
+
flash(
|
|
2251
|
+
result.message ?? t("ui.dataTable.bulkAction.success", "Bulk action completed."),
|
|
2252
|
+
"success"
|
|
2253
|
+
);
|
|
2254
|
+
if (refreshButton?.onRefresh) {
|
|
2255
|
+
refreshButton.onRefresh();
|
|
2256
|
+
} else {
|
|
2257
|
+
scheduleRouterRefresh(router);
|
|
2258
|
+
}
|
|
2259
|
+
} catch (error2) {
|
|
2260
|
+
flash(
|
|
2261
|
+
error2 instanceof Error ? error2.message : t("ui.dataTable.bulkAction.error", "Bulk action failed."),
|
|
2262
|
+
"error"
|
|
2263
|
+
);
|
|
2206
2264
|
}
|
|
2207
2265
|
},
|
|
2208
|
-
[selectedRows]
|
|
2266
|
+
[refreshButton, router, selectedRows, t]
|
|
2209
2267
|
);
|
|
2210
2268
|
const builtToolbar = React.useMemo(() => {
|
|
2211
2269
|
if (toolbar) return toolbar;
|
|
@@ -2286,6 +2344,7 @@ function DataTable({
|
|
|
2286
2344
|
}
|
|
2287
2345
|
)
|
|
2288
2346
|
] }) : null;
|
|
2347
|
+
const perspectiveButtonLeading = perspectiveAlign === "right" ? null : perspectiveButton;
|
|
2289
2348
|
const saveViewButton = showSaveViewButton && canUsePerspectives ? /* @__PURE__ */ jsxs(
|
|
2290
2349
|
Button,
|
|
2291
2350
|
{
|
|
@@ -2305,9 +2364,9 @@ function DataTable({
|
|
|
2305
2364
|
]
|
|
2306
2365
|
}
|
|
2307
2366
|
) : null;
|
|
2308
|
-
const leadingItems = advancedFilterButton ||
|
|
2367
|
+
const leadingItems = advancedFilterButton || perspectiveButtonLeading || saveViewButton ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2309
2368
|
advancedFilterButton,
|
|
2310
|
-
|
|
2369
|
+
perspectiveButtonLeading,
|
|
2311
2370
|
saveViewButton
|
|
2312
2371
|
] }) : null;
|
|
2313
2372
|
const trailingItems = hasBulkButtons ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
@@ -2351,6 +2410,7 @@ function DataTable({
|
|
|
2351
2410
|
}) : null
|
|
2352
2411
|
] }) : null;
|
|
2353
2412
|
const searchTrailingNode = searchTrailingInjectionSpotId && onSearchChange ? /* @__PURE__ */ jsx(InjectionSpot, { spotId: searchTrailingInjectionSpotId, context: resolvedInjectionContext }) : null;
|
|
2413
|
+
if (perspectiveAlign === "right" && !anySearch && combined.length === 0 && !advancedFilterButton && !saveViewButton && !trailingItems && !fieldsetSelector) return null;
|
|
2354
2414
|
return /* @__PURE__ */ jsx(
|
|
2355
2415
|
FilterBar,
|
|
2356
2416
|
{
|
|
@@ -2383,6 +2443,7 @@ function DataTable({
|
|
|
2383
2443
|
onFiltersApply,
|
|
2384
2444
|
onFiltersClear,
|
|
2385
2445
|
canUsePerspectives,
|
|
2446
|
+
perspectiveAlign,
|
|
2386
2447
|
embedded,
|
|
2387
2448
|
supportsCustomFieldFilterFieldsets,
|
|
2388
2449
|
resolvedEntityIds,
|
|
@@ -2478,7 +2539,18 @@ function DataTable({
|
|
|
2478
2539
|
]
|
|
2479
2540
|
}
|
|
2480
2541
|
) : null,
|
|
2481
|
-
canUsePerspectives ? /* @__PURE__ */
|
|
2542
|
+
canUsePerspectives ? perspectiveAlign === "right" ? /* @__PURE__ */ jsx(
|
|
2543
|
+
ViewSwitcherDropdown,
|
|
2544
|
+
{
|
|
2545
|
+
activePerspectiveId,
|
|
2546
|
+
perspectives: perspectiveData?.perspectives ?? [],
|
|
2547
|
+
rolePerspectives: perspectiveData?.rolePerspectives ?? [],
|
|
2548
|
+
onClear: () => applyPerspectiveSettings({}, null),
|
|
2549
|
+
onActivate: handlePerspectiveActivate,
|
|
2550
|
+
onOpenSidebar: () => setPerspectiveOpen(true),
|
|
2551
|
+
t
|
|
2552
|
+
}
|
|
2553
|
+
) : /* @__PURE__ */ jsxs(
|
|
2482
2554
|
Button,
|
|
2483
2555
|
{
|
|
2484
2556
|
type: "button",
|
|
@@ -2679,12 +2751,37 @@ function DataTable({
|
|
|
2679
2751
|
const sizedWidth = enableColumnResize && columnId ? columnSizing[columnId] : void 0;
|
|
2680
2752
|
const effectiveMaxWidth = typeof sizedWidth === "number" ? `${sizedWidth}px` : maxWidth;
|
|
2681
2753
|
const wrappedContent = shouldTruncate ? /* @__PURE__ */ jsx(TruncatedCell, { maxWidth: effectiveMaxWidth, tooltipContent: tooltipText, children: content }) : content;
|
|
2754
|
+
const expandAffordance = expansionEnabled && cellIndex === 0 ? /* @__PURE__ */ jsx(
|
|
2755
|
+
"span",
|
|
2756
|
+
{
|
|
2757
|
+
className: "inline-flex shrink-0 items-center",
|
|
2758
|
+
style: { paddingLeft: `${row.depth * 1.25}rem` },
|
|
2759
|
+
children: row.getCanExpand() ? /* @__PURE__ */ jsx(
|
|
2760
|
+
IconButton,
|
|
2761
|
+
{
|
|
2762
|
+
type: "button",
|
|
2763
|
+
variant: "ghost",
|
|
2764
|
+
size: "xs",
|
|
2765
|
+
"aria-label": row.getIsExpanded() ? t("ui.dataTable.expand.collapseRow", "Collapse row") : t("ui.dataTable.expand.expandRow", "Expand row"),
|
|
2766
|
+
"aria-expanded": row.getIsExpanded(),
|
|
2767
|
+
onClick: (event) => {
|
|
2768
|
+
event.stopPropagation();
|
|
2769
|
+
row.toggleExpanded();
|
|
2770
|
+
},
|
|
2771
|
+
children: row.getIsExpanded() ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "size-4", "aria-hidden": "true" })
|
|
2772
|
+
}
|
|
2773
|
+
) : /* @__PURE__ */ jsx("span", { className: "inline-block size-6", "aria-hidden": "true" })
|
|
2774
|
+
}
|
|
2775
|
+
) : null;
|
|
2682
2776
|
return /* @__PURE__ */ jsx(
|
|
2683
2777
|
TableCell,
|
|
2684
2778
|
{
|
|
2685
2779
|
className: responsiveClass(priority, columnMeta?.hidden) + (isStickyCell ? ` md:sticky md:left-0 md:z-10 md:bg-background ${STICKY_LEFT_SHADOW_CLASS}` : ""),
|
|
2686
2780
|
style: typeof sizedWidth === "number" ? { width: sizedWidth, minWidth: sizedWidth, maxWidth: sizedWidth } : void 0,
|
|
2687
|
-
children:
|
|
2781
|
+
children: expandAffordance ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
2782
|
+
expandAffordance,
|
|
2783
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: wrappedContent })
|
|
2784
|
+
] }) : wrappedContent
|
|
2688
2785
|
},
|
|
2689
2786
|
cell.id
|
|
2690
2787
|
);
|