@12-apps/ui 6.13.1 → 6.14.0
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/_internal/components/data-display/Carousel/Carousel.js +4 -4
- package/dist/_internal/components/data-display/Chart/Chart.js +3 -3
- package/dist/_internal/components/data-display/Chart/SpecChart.js +7 -7
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +2 -2
- package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +2 -2
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +24 -21
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +29 -26
- package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +2 -2
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +20 -18
- package/dist/_internal/components/data-display/DataViews/data-views-header-row.js +12 -0
- package/dist/_internal/components/data-display/DataViews/data-views-header-row.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-selection-extra.js +8 -0
- package/dist/_internal/components/data-display/DataViews/data-views-selection-extra.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-selection.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-writers.js +9 -0
- package/dist/_internal/components/data-display/DataViews/data-views-writers.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +3 -2
- package/dist/_internal/components/data-display/index.js +23 -23
- package/dist/_internal/components/index.js +24 -24
- package/dist/_internal/components/layout/ContentToolbar/ContentToolbar.js +1 -1
- package/dist/_internal/components/layout/index.js +1 -1
- package/dist/charts.js +17 -17
- package/dist/{chunk-BV5XTGKB.js → chunk-2UCJJACD.js} +7 -9
- package/dist/chunk-2UCJJACD.js.map +1 -0
- package/dist/{chunk-JKLWHENB.js → chunk-62WEMJV3.js} +3 -3
- package/dist/chunk-62WEMJV3.js.map +1 -0
- package/dist/chunk-A4YWFX5C.js +39 -0
- package/dist/chunk-A4YWFX5C.js.map +1 -0
- package/dist/{chunk-CXA6UNFF.js → chunk-AP3PVR3T.js} +5 -5
- package/dist/{chunk-NPEKJXVV.js → chunk-BPCYXLWY.js} +7 -7
- package/dist/{chunk-XULTDO56.js → chunk-BVGR7OYA.js} +4 -4
- package/dist/{chunk-BZTFPSWT.js → chunk-DFLTUI7W.js} +7 -7
- package/dist/{chunk-AWTERXCW.js → chunk-GNAAHDCN.js} +4 -2
- package/dist/chunk-GNAAHDCN.js.map +1 -0
- package/dist/{chunk-HGBZZDP6.js → chunk-J4DDXHLB.js} +4 -4
- package/dist/chunk-KX75HM5U.js +20 -0
- package/dist/chunk-KX75HM5U.js.map +1 -0
- package/dist/chunk-LLZWB32X.js +36 -0
- package/dist/chunk-LLZWB32X.js.map +1 -0
- package/dist/{chunk-T4BFDZGU.js → chunk-LNIVT62P.js} +16 -40
- package/dist/chunk-LNIVT62P.js.map +1 -0
- package/dist/{chunk-WLCVOQCJ.js → chunk-LPNF4YJ7.js} +3 -3
- package/dist/{chunk-QQE2PVLO.js → chunk-M6365FGG.js} +2 -2
- package/dist/{chunk-RDYBS45D.js → chunk-O6MZPB64.js} +2 -2
- package/dist/{chunk-4KSOSI3U.js → chunk-O6V7KKW7.js} +4 -4
- package/dist/{chunk-JPDKRGYI.js → chunk-PDGAFQ6Z.js} +3 -3
- package/dist/{chunk-IN642YHK.js → chunk-PHA3NFZM.js} +2 -2
- package/dist/{chunk-NC2AATCC.js → chunk-QIKTIKO6.js} +2 -2
- package/dist/{chunk-GOWBYHYW.js → chunk-R6SBP5M5.js} +4 -4
- package/dist/{chunk-X5MPHXG5.js → chunk-RPWEXIAW.js} +6 -6
- package/dist/{chunk-2WWKBD4D.js → chunk-TSPHRZ4U.js} +5 -1
- package/dist/chunk-TSPHRZ4U.js.map +1 -0
- package/dist/chunk-U5FOJBLG.js +19 -0
- package/dist/chunk-U5FOJBLG.js.map +1 -0
- package/dist/{chunk-DEOC5OI7.js → chunk-U5RIDMMV.js} +2 -2
- package/dist/chunk-U5RIDMMV.js.map +1 -0
- package/dist/{chunk-ZHPKFV7Y.js → chunk-UENDC45F.js} +2 -2
- package/dist/{chunk-WXBBWSNU.js → chunk-ZNGUDGKW.js} +6 -5
- package/dist/chunk-ZNGUDGKW.js.map +1 -0
- package/dist/data-display/CardKit.js +7 -7
- package/dist/data-display/Carousel.js +4 -4
- package/dist/data-display/Chart.js +17 -17
- package/dist/data-display/DataGrid.js +2 -2
- package/dist/data-display/DataViews.js +38 -35
- package/dist/layout/ContentToolbar.js +1 -1
- package/dist/types/components/data-display/DataViews/DataViewsGrid.d.ts +12 -0
- package/dist/types/components/data-display/DataViews/DataViewsGrid.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/DataViewsTableBase.d.ts +3 -0
- package/dist/types/components/data-display/DataViews/DataViewsTableBase.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts +3 -0
- package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-header-row.d.ts +18 -0
- package/dist/types/components/data-display/DataViews/data-views-header-row.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-selection-extra.d.ts +50 -0
- package/dist/types/components/data-display/DataViews/data-views-selection-extra.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-selection.d.ts +31 -2
- package/dist/types/components/data-display/DataViews/data-views-selection.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-shell-toolbar.d.ts +3 -1
- package/dist/types/components/data-display/DataViews/data-views-shell-toolbar.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-toolbar.d.ts +2 -0
- package/dist/types/components/data-display/DataViews/data-views-toolbar.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-writers.d.ts +20 -0
- package/dist/types/components/data-display/DataViews/data-views-writers.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/index.d.ts +1 -0
- package/dist/types/components/data-display/DataViews/index.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/use-data-views-state.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +15 -0
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/DataViews/DataViewsGrid.tsx +12 -0
- package/src/components/data-display/DataViews/DataViewsTableBase.tsx +3 -0
- package/src/components/data-display/DataViews/data-views-grid-parts.tsx +5 -50
- package/src/components/data-display/DataViews/data-views-header-row.tsx +52 -0
- package/src/components/data-display/DataViews/data-views-selection-extra.ts +67 -0
- package/src/components/data-display/DataViews/data-views-selection.ts +61 -6
- package/src/components/data-display/DataViews/data-views-shell-toolbar.tsx +4 -0
- package/src/components/data-display/DataViews/data-views-toolbar.tsx +3 -0
- package/src/components/data-display/DataViews/data-views-writers.ts +45 -0
- package/src/components/data-display/DataViews/index.ts +1 -0
- package/src/components/data-display/DataViews/use-data-views-state.ts +4 -11
- package/src/components/layout/ContentToolbar/ContentToolbar.md +10 -3
- package/src/components/layout/ContentToolbar/ContentToolbar.tsx +5 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +15 -0
- package/dist/chunk-2WWKBD4D.js.map +0 -1
- package/dist/chunk-AWTERXCW.js.map +0 -1
- package/dist/chunk-BV5XTGKB.js.map +0 -1
- package/dist/chunk-DEOC5OI7.js.map +0 -1
- package/dist/chunk-JKLWHENB.js.map +0 -1
- package/dist/chunk-T4BFDZGU.js.map +0 -1
- package/dist/chunk-WTOTWP6A.js +0 -27
- package/dist/chunk-WTOTWP6A.js.map +0 -1
- package/dist/chunk-WXBBWSNU.js.map +0 -1
- /package/dist/{chunk-CXA6UNFF.js.map → chunk-AP3PVR3T.js.map} +0 -0
- /package/dist/{chunk-NPEKJXVV.js.map → chunk-BPCYXLWY.js.map} +0 -0
- /package/dist/{chunk-XULTDO56.js.map → chunk-BVGR7OYA.js.map} +0 -0
- /package/dist/{chunk-BZTFPSWT.js.map → chunk-DFLTUI7W.js.map} +0 -0
- /package/dist/{chunk-HGBZZDP6.js.map → chunk-J4DDXHLB.js.map} +0 -0
- /package/dist/{chunk-WLCVOQCJ.js.map → chunk-LPNF4YJ7.js.map} +0 -0
- /package/dist/{chunk-QQE2PVLO.js.map → chunk-M6365FGG.js.map} +0 -0
- /package/dist/{chunk-RDYBS45D.js.map → chunk-O6MZPB64.js.map} +0 -0
- /package/dist/{chunk-4KSOSI3U.js.map → chunk-O6V7KKW7.js.map} +0 -0
- /package/dist/{chunk-JPDKRGYI.js.map → chunk-PDGAFQ6Z.js.map} +0 -0
- /package/dist/{chunk-IN642YHK.js.map → chunk-PHA3NFZM.js.map} +0 -0
- /package/dist/{chunk-NC2AATCC.js.map → chunk-QIKTIKO6.js.map} +0 -0
- /package/dist/{chunk-GOWBYHYW.js.map → chunk-R6SBP5M5.js.map} +0 -0
- /package/dist/{chunk-X5MPHXG5.js.map → chunk-RPWEXIAW.js.map} +0 -0
- /package/dist/{chunk-ZHPKFV7Y.js.map → chunk-UENDC45F.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GridToolbar
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZNGUDGKW.js";
|
|
4
4
|
|
|
5
5
|
// src/components/data-display/DataViews/data-views-shell-toolbar.tsx
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -10,6 +10,7 @@ function ShellToolbar({
|
|
|
10
10
|
testIdPrefix,
|
|
11
11
|
rowActions,
|
|
12
12
|
bulkActions,
|
|
13
|
+
selectionExtra,
|
|
13
14
|
toolbarRightSlot,
|
|
14
15
|
showInline,
|
|
15
16
|
compactControls,
|
|
@@ -42,6 +43,7 @@ function ShellToolbar({
|
|
|
42
43
|
clearSelection: c.clearSelection,
|
|
43
44
|
rowActions,
|
|
44
45
|
bulkActions,
|
|
46
|
+
selectionExtra,
|
|
45
47
|
sortFields: c.resolvedSortFields,
|
|
46
48
|
activeSortField: c.activeSortField,
|
|
47
49
|
activeSortOrder: c.activeSortOrder,
|
|
@@ -62,4 +64,4 @@ function ShellToolbar({
|
|
|
62
64
|
export {
|
|
63
65
|
ShellToolbar
|
|
64
66
|
};
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
67
|
+
//# sourceMappingURL=chunk-GNAAHDCN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-shell-toolbar.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * The toolbar band, fed from the controller — ~25 props of pure forwarding and\n * nothing else, which is why it lives in its own file rather than in the shell.\n */\nimport { type ColumnVisibilityOption } from \"../../layout/ContentToolbar\";\n\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport { GridToolbar } from \"./data-views-toolbar\";\nimport type { RowAction } from \"./data-views-types\";\nimport type { DataViewsController } from \"./use-data-views-state\";\n\n/**\n * The toolbar band, fed from the controller. Split out of `GridShell` for that\n * function's size budget — it is ~25 props of pure forwarding and nothing else.\n */\nexport function ShellToolbar<T extends Record<string, unknown>>({\n c,\n rows,\n testIdPrefix,\n rowActions,\n bulkActions,\n selectionExtra,\n toolbarRightSlot,\n showInline,\n compactControls,\n counterHidden,\n sortKinds,\n displayView,\n exportConfig,\n filterControls,\n barRef,\n}: {\n c: DataViewsController<T>;\n rows: T[];\n testIdPrefix: string;\n sortKinds?: Record<string, string>;\n displayView?: DisplayPanelView;\n exportConfig?: DataViewExport;\n rowActions?: RowAction<T>[];\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /** Already resolved by the shell, which is the party that knows the page. */\n selectionExtra?: React.ReactNode;\n toolbarRightSlot?: React.ReactNode;\n /** Search + filters, rendered on the toolbar line (see `GridToolbar`). */\n filterControls?: React.ReactNode;\n barRef?: React.Ref<HTMLDivElement>;\n showInline: boolean;\n /** Step 2 of the ladder: Exibir/Exportar as icons only. */\n compactControls?: boolean;\n /** Step 5, last resort: drop the counter so the row still fits one line. */\n counterHidden?: boolean;\n}): React.JSX.Element {\n const columnOptions: ColumnVisibilityOption[] = c.hideableColumns.map((col) => ({\n id: col.id,\n label: col.label,\n visible: c.state.visibleColumns.includes(col.id),\n }));\n return (\n <GridToolbar\n c={c}\n sortKinds={sortKinds}\n displayView={displayView}\n exportConfig={exportConfig}\n filterControls={filterControls}\n barRef={barRef}\n compactControls={compactControls}\n counterHidden={counterHidden}\n testIdPrefix={testIdPrefix}\n selectedRows={c.selectedRows}\n selectAll={c.selectAll}\n clearSelection={c.clearSelection}\n rowActions={rowActions}\n bulkActions={bulkActions}\n selectionExtra={selectionExtra}\n sortFields={c.resolvedSortFields}\n activeSortField={c.activeSortField}\n activeSortOrder={c.activeSortOrder}\n onChangeSort={(field, order) => c.patch({ sortBy: [{ id: field, dir: order }] })}\n matchedCount={c.matched.length}\n totalCount={c.serverMode ? c.serverTotalCount : rows.length}\n toolbarRightSlot={toolbarRightSlot}\n columnOptions={columnOptions}\n onToggleColumn={c.toggleColumn}\n filterOpen={c.filterOpen}\n setFilterOpen={c.setFilterOpen}\n activeFilterCount={c.activeFilterCount}\n showFilterTrigger={!showInline}\n />\n );\n}\n\n/** Wires the controller into the shared toolbar + filter panel + grid/cards body. */\n"],"mappings":";;;;;AA6DI;AA3CG,SAAS,aAAgD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAoBsB;AACpB,QAAM,gBAA0C,EAAE,gBAAgB,IAAI,CAAC,SAAS;AAAA,IAC9E,IAAI,IAAI;AAAA,IACR,OAAO,IAAI;AAAA,IACX,SAAS,EAAE,MAAM,eAAe,SAAS,IAAI,EAAE;AAAA,EACjD,EAAE;AACF,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,EAAE;AAAA,MAChB,WAAW,EAAE;AAAA,MACb,gBAAgB,EAAE;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,EAAE;AAAA,MACd,iBAAiB,EAAE;AAAA,MACnB,iBAAiB,EAAE;AAAA,MACnB,cAAc,CAAC,OAAO,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,IAAI,OAAO,KAAK,MAAM,CAAC,EAAE,CAAC;AAAA,MAC/E,cAAc,EAAE,QAAQ;AAAA,MACxB,YAAY,EAAE,aAAa,EAAE,mBAAmB,KAAK;AAAA,MACrD;AAAA,MACA;AAAA,MACA,gBAAgB,EAAE;AAAA,MAClB,YAAY,EAAE;AAAA,MACd,eAAe,EAAE;AAAA,MACjB,mBAAmB,EAAE;AAAA,MACrB,mBAAmB,CAAC;AAAA;AAAA,EACtB;AAEJ;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ColumnsTab
|
|
3
|
-
} from "./chunk-2PPWKCMW.js";
|
|
4
1
|
import {
|
|
5
2
|
DisplayTab,
|
|
6
3
|
SortTab
|
|
7
4
|
} from "./chunk-SCGVB7DS.js";
|
|
5
|
+
import {
|
|
6
|
+
ColumnsTab
|
|
7
|
+
} from "./chunk-2PPWKCMW.js";
|
|
8
8
|
import {
|
|
9
9
|
ViewActions,
|
|
10
10
|
ViewFooter,
|
|
@@ -261,4 +261,4 @@ function DataViewsDisplayPanel({
|
|
|
261
261
|
export {
|
|
262
262
|
DataViewsDisplayPanel
|
|
263
263
|
};
|
|
264
|
-
//# sourceMappingURL=chunk-
|
|
264
|
+
//# sourceMappingURL=chunk-J4DDXHLB.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/components/data-display/DataViews/data-views-selection-extra.ts
|
|
2
|
+
function resolveSelectionExtra({
|
|
3
|
+
c,
|
|
4
|
+
getRowId,
|
|
5
|
+
selectionExtra
|
|
6
|
+
}) {
|
|
7
|
+
if (selectionExtra === void 0 || c.selectedRows.length === 0) return void 0;
|
|
8
|
+
const page = c.matched;
|
|
9
|
+
return selectionExtra({
|
|
10
|
+
selectedRows: c.selectedRows,
|
|
11
|
+
clearSelection: c.clearSelection,
|
|
12
|
+
allOnPageSelected: page.length > 0 && page.every((row) => c.selectedIds.has(getRowId(row))),
|
|
13
|
+
pageRowCount: page.length
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
resolveSelectionExtra
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=chunk-KX75HM5U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-selection-extra.ts"],"sourcesContent":["/**\n * The selection-WIDENING slot: what a paginated grid needs so an operator can\n * act on \"everything matching the filter\" rather than on the page in front of\n * them.\n *\n * It is a slot of its own rather than a share of the bulk-actions menu because\n * the two answer different questions — `actions` is what HAPPENS to the\n * selection, this is what the selection IS. Folding a widening into the actions\n * menu files \"change what I picked\" under \"do this to what I picked\", where\n * every entry is expected to write something.\n */\nimport type { DataViewsController } from \"./use-data-views-state\";\n\n/**\n * What a widening control gets to decide with.\n *\n * `allOnPageSelected` is the one thing a host cannot compute for itself, and\n * the whole reason this is a context rather than a bare node: the grid owns\n * which rows the page is currently rendering — server mode pages at the\n * backend, so the host's `rows` prop and the page can differ mid-fetch — and\n * \"every row here is ticked\" is the trigger a select-all-matching control\n * hangs on. Deriving it host-side would be a second, slightly different answer\n * to the question the grid already answers to draw its own header checkbox.\n */\nexport interface SelectionExtraContext<T extends Record<string, unknown>> {\n /** The selected rows, off-page ones included. */\n selectedRows: T[];\n /** Drop the whole selection. */\n clearSelection: () => void;\n /** Every row the page is rendering is selected — and the page is not empty. */\n allOnPageSelected: boolean;\n /** How many rows the page is rendering. */\n pageRowCount: number;\n}\n\n/** The host's widening control, called only while something is selected. */\nexport type SelectionExtraRender<T extends Record<string, unknown>> = (\n context: SelectionExtraContext<T>,\n) => React.ReactNode;\n\n/**\n * Resolve the host's control against the page on screen.\n *\n * Measured against `c.matched` — which in server mode IS the page — rather than\n * the `rows` prop, so the answer cannot lag a page change.\n *\n * Returns `undefined` with nothing selected, so the toolbar renders no empty\n * slot: a widening with nothing to widen is not a control.\n */\nexport function resolveSelectionExtra<T extends Record<string, unknown>>({\n c,\n getRowId,\n selectionExtra,\n}: {\n c: DataViewsController<T>;\n getRowId: (row: T) => string | number;\n selectionExtra?: SelectionExtraRender<T>;\n}): React.ReactNode {\n if (selectionExtra === undefined || c.selectedRows.length === 0) return undefined;\n const page = c.matched;\n return selectionExtra({\n selectedRows: c.selectedRows,\n clearSelection: c.clearSelection,\n allOnPageSelected: page.length > 0 && page.every((row) => c.selectedIds.has(getRowId(row))),\n pageRowCount: page.length,\n });\n}\n"],"mappings":";AAiDO,SAAS,sBAAyD;AAAA,EACvE;AAAA,EACA;AAAA,EACA;AACF,GAIoB;AAClB,MAAI,mBAAmB,UAAa,EAAE,aAAa,WAAW,EAAG,QAAO;AACxE,QAAM,OAAO,EAAE;AACf,SAAO,eAAe;AAAA,IACpB,cAAc,EAAE;AAAA,IAChB,gBAAgB,EAAE;AAAA,IAClB,mBAAmB,KAAK,SAAS,KAAK,KAAK,MAAM,CAAC,QAAQ,EAAE,YAAY,IAAI,SAAS,GAAG,CAAC,CAAC;AAAA,IAC1F,cAAc,KAAK;AAAA,EACrB,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/components/data-display/DataViews/data-views-selection.ts
|
|
2
|
+
import { useMemo, useRef, useState } from "react";
|
|
3
|
+
function useSelection(matched, getRowId, options = {}) {
|
|
4
|
+
const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
|
|
5
|
+
const remembered = useRef(/* @__PURE__ */ new Map());
|
|
6
|
+
const selectedRows = useMemo(() => {
|
|
7
|
+
const onPage = matched.filter((row) => selectedIds.has(getRowId(row)));
|
|
8
|
+
if (!options.rememberOffPage) return onPage;
|
|
9
|
+
const cache = remembered.current;
|
|
10
|
+
for (const row of onPage) cache.set(getRowId(row), row);
|
|
11
|
+
for (const id of cache.keys()) if (!selectedIds.has(id)) cache.delete(id);
|
|
12
|
+
const onPageIds = new Set(onPage.map(getRowId));
|
|
13
|
+
const offPage = [...cache.entries()].flatMap(
|
|
14
|
+
([id, row]) => onPageIds.has(id) ? [] : [row]
|
|
15
|
+
);
|
|
16
|
+
return [...onPage, ...offPage];
|
|
17
|
+
}, [matched, selectedIds, getRowId, options.rememberOffPage]);
|
|
18
|
+
return {
|
|
19
|
+
selectedIds,
|
|
20
|
+
setSelectedIds,
|
|
21
|
+
toggleId: (id) => setSelectedIds((prev) => {
|
|
22
|
+
const next = new Set(prev);
|
|
23
|
+
if (next.has(id)) next.delete(id);
|
|
24
|
+
else next.add(id);
|
|
25
|
+
return next;
|
|
26
|
+
}),
|
|
27
|
+
selectedRows,
|
|
28
|
+
clearSelection: () => setSelectedIds(/* @__PURE__ */ new Set()),
|
|
29
|
+
selectAll: () => setSelectedIds(new Set(matched.map((row) => getRowId(row))))
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
useSelection
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=chunk-LLZWB32X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-selection.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef, useState } from \"react\";\n\n/** The multi-select model, identical in every layout (table, cards, board). */\ninterface DataViewsSelection<T> {\n selectedIds: Set<string | number>;\n setSelectedIds: (ids: Set<string | number>) => void;\n /** Add/remove ONE id — what a card's or board card's checkbox calls. */\n toggleId: (id: string | number) => void;\n /** The selected rows, INCLUDING ones the current page no longer renders. */\n selectedRows: T[];\n clearSelection: () => void;\n selectAll: () => void;\n}\n\n/**\n * Owns the DataViews selection. ONE set of ids across every layout, so switching\n * from the board to the table (or to the cards) keeps exactly the same rows\n * selected and offers exactly the same bulk actions.\n *\n * Extracted from {@link useDataViewsState} for that hook's size budget, and\n * because `toggleId` needs a functional update: two cards toggled in the same\n * tick would otherwise both read the pre-render set and the second would drop\n * the first's change.\n *\n * ## A selection has to survive PAGING\n *\n * `selectedIds` always did — nothing clears it when the page changes — but\n * `selectedRows` was `matched.filter(...)`, and in SERVER mode `matched` is one\n * page. So ticking three rows, paging, and ticking two more left the checkboxes\n * claiming five and the bulk action receiving two, silently, with the other\n * three still ticked on a page nobody was looking at.\n *\n * That is the worst shape a bug can have here: the UI and the write disagree,\n * neither says so, and the rows that did not move are exactly the ones out of\n * sight. So a row is REMEMBERED for as long as its id is selected, and\n * `selectedRows` answers from that memory for anything the current page does\n * not hold.\n *\n * **Server mode only** ({@link SelectionOptions.rememberOffPage}), and the\n * distinction is not a hedge. In client mode `matched` is the whole filtered\n * result, so nothing is ever off-page and there is nothing to remember — while\n * narrowing the selection as the FILTER narrows is the behaviour a client-mode\n * grid should keep. Remembering there would mean a bulk action reaching rows\n * the operator has just filtered away.\n */\nexport interface SelectionOptions {\n /**\n * Keep rows the current page no longer renders.\n *\n * True in server mode, where `matched` is a page rather than the result.\n */\n rememberOffPage?: boolean;\n}\n\nexport function useSelection<T>(\n matched: T[],\n getRowId: (row: T) => string | number,\n options: SelectionOptions = {},\n): DataViewsSelection<T> {\n const [selectedIds, setSelectedIds] = useState<Set<string | number>>(new Set());\n // Rows seen while selected, so a selection outlives the page that made it.\n // A ref rather than state: it is a CACHE derived from what has been rendered,\n // and holding it in state would re-render on every page load to store rows\n // nothing is waiting for.\n const remembered = useRef(new Map<string | number, T>());\n\n const selectedRows = useMemo(() => {\n const onPage = matched.filter((row) => selectedIds.has(getRowId(row)));\n if (!options.rememberOffPage) return onPage;\n\n const cache = remembered.current;\n // Refresh from what is on screen NOW: a row edited elsewhere and re-fetched\n // must not be acted on through a stale snapshot from three pages ago.\n for (const row of onPage) cache.set(getRowId(row), row);\n // …and forget anything no longer selected, so the map cannot outgrow the\n // selection it exists to describe.\n for (const id of cache.keys()) if (!selectedIds.has(id)) cache.delete(id);\n\n // On-page rows first, in the page's own order — unchanged from before this\n // — then the remembered tail. Appending rather than interleaving keeps the\n // familiar case byte-identical and makes the addition exactly the addition.\n const onPageIds = new Set(onPage.map(getRowId));\n const offPage = [...cache.entries()].flatMap(([id, row]) =>\n onPageIds.has(id) ? [] : [row],\n );\n return [...onPage, ...offPage];\n }, [matched, selectedIds, getRowId, options.rememberOffPage]);\n\n return {\n selectedIds,\n setSelectedIds,\n toggleId: (id) =>\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n }),\n selectedRows,\n clearSelection: () => setSelectedIds(new Set()),\n selectAll: () => setSelectedIds(new Set(matched.map((row) => getRowId(row)))),\n };\n}\n"],"mappings":";AAEA,SAAS,SAAS,QAAQ,gBAAgB;AAsDnC,SAAS,aACd,SACA,UACA,UAA4B,CAAC,GACN;AACvB,QAAM,CAAC,aAAa,cAAc,IAAI,SAA+B,oBAAI,IAAI,CAAC;AAK9E,QAAM,aAAa,OAAO,oBAAI,IAAwB,CAAC;AAEvD,QAAM,eAAe,QAAQ,MAAM;AACjC,UAAM,SAAS,QAAQ,OAAO,CAAC,QAAQ,YAAY,IAAI,SAAS,GAAG,CAAC,CAAC;AACrE,QAAI,CAAC,QAAQ,gBAAiB,QAAO;AAErC,UAAM,QAAQ,WAAW;AAGzB,eAAW,OAAO,OAAQ,OAAM,IAAI,SAAS,GAAG,GAAG,GAAG;AAGtD,eAAW,MAAM,MAAM,KAAK,EAAG,KAAI,CAAC,YAAY,IAAI,EAAE,EAAG,OAAM,OAAO,EAAE;AAKxE,UAAM,YAAY,IAAI,IAAI,OAAO,IAAI,QAAQ,CAAC;AAC9C,UAAM,UAAU,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE;AAAA,MAAQ,CAAC,CAAC,IAAI,GAAG,MACpD,UAAU,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;AAAA,IAC/B;AACA,WAAO,CAAC,GAAG,QAAQ,GAAG,OAAO;AAAA,EAC/B,GAAG,CAAC,SAAS,aAAa,UAAU,QAAQ,eAAe,CAAC;AAE5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,CAAC,OACT,eAAe,CAAC,SAAS;AACvB,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,UAAI,KAAK,IAAI,EAAE,EAAG,MAAK,OAAO,EAAE;AAAA,UAC3B,MAAK,IAAI,EAAE;AAChB,aAAO;AAAA,IACT,CAAC;AAAA,IACH;AAAA,IACA,gBAAgB,MAAM,eAAe,oBAAI,IAAI,CAAC;AAAA,IAC9C,WAAW,MAAM,eAAe,IAAI,IAAI,QAAQ,IAAI,CAAC,QAAQ,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC9E;AACF;","names":[]}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GridMain
|
|
3
|
+
} from "./chunk-M6365FGG.js";
|
|
1
4
|
import {
|
|
2
5
|
FilterDialog,
|
|
3
6
|
GridFilterPanel
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PHA3NFZM.js";
|
|
5
8
|
import {
|
|
6
9
|
DataViewsEmpty
|
|
7
10
|
} from "./chunk-S7CAXRRP.js";
|
|
8
11
|
import {
|
|
9
12
|
InlineFilterControls
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LPNF4YJ7.js";
|
|
11
14
|
import {
|
|
12
|
-
|
|
13
|
-
} from "./chunk-
|
|
15
|
+
GridHeaderRow
|
|
16
|
+
} from "./chunk-A4YWFX5C.js";
|
|
14
17
|
import {
|
|
15
18
|
DataViewsPagination
|
|
16
19
|
} from "./chunk-VR5HDUBK.js";
|
|
@@ -18,12 +21,15 @@ import {
|
|
|
18
21
|
toOverflowFields,
|
|
19
22
|
useFilterOverflow
|
|
20
23
|
} from "./chunk-TQ6FPOPD.js";
|
|
24
|
+
import {
|
|
25
|
+
ShellToolbar
|
|
26
|
+
} from "./chunk-GNAAHDCN.js";
|
|
27
|
+
import {
|
|
28
|
+
resolveSelectionExtra
|
|
29
|
+
} from "./chunk-KX75HM5U.js";
|
|
21
30
|
import {
|
|
22
31
|
ScopeTabsSlot
|
|
23
32
|
} from "./chunk-OGGHD64H.js";
|
|
24
|
-
import {
|
|
25
|
-
ShellToolbar
|
|
26
|
-
} from "./chunk-AWTERXCW.js";
|
|
27
33
|
import {
|
|
28
34
|
DataViewsLayoutProvider,
|
|
29
35
|
useDataViewsLayout
|
|
@@ -39,42 +45,11 @@ import {
|
|
|
39
45
|
} from "./chunk-J3JGO6Y6.js";
|
|
40
46
|
import {
|
|
41
47
|
default as default2
|
|
42
|
-
} from "./chunk-6DPAWXZ3.js";
|
|
43
|
-
import {
|
|
44
|
-
default as default3
|
|
45
48
|
} from "./chunk-WEBEOBN5.js";
|
|
46
|
-
import {
|
|
47
|
-
Text
|
|
48
|
-
} from "./chunk-VRHBJXZ7.js";
|
|
49
49
|
|
|
50
50
|
// src/components/data-display/DataViews/data-views-grid-parts.tsx
|
|
51
51
|
import { useEffect, useState } from "react";
|
|
52
52
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
53
|
-
function GridHeaderRow({
|
|
54
|
-
title,
|
|
55
|
-
headerActions,
|
|
56
|
-
testIdPrefix
|
|
57
|
-
}) {
|
|
58
|
-
if (!title && !headerActions) return null;
|
|
59
|
-
return /* @__PURE__ */ jsxs(
|
|
60
|
-
default2,
|
|
61
|
-
{
|
|
62
|
-
"data-testid": `${testIdPrefix}-header`,
|
|
63
|
-
sx: {
|
|
64
|
-
display: "flex",
|
|
65
|
-
alignItems: "center",
|
|
66
|
-
justifyContent: "space-between",
|
|
67
|
-
gap: 2,
|
|
68
|
-
flexWrap: "wrap",
|
|
69
|
-
pb: 1.5
|
|
70
|
-
},
|
|
71
|
-
children: [
|
|
72
|
-
title ? /* @__PURE__ */ jsx(Text, { variant: "heading", size: "lg", as: "h2", children: title }) : /* @__PURE__ */ jsx(default2, {}),
|
|
73
|
-
headerActions && /* @__PURE__ */ jsx(default2, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: headerActions })
|
|
74
|
-
]
|
|
75
|
-
}
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
53
|
function LayoutStateSync({
|
|
79
54
|
c
|
|
80
55
|
}) {
|
|
@@ -152,7 +127,7 @@ function ShellStack({
|
|
|
152
127
|
open: c.filterOpen,
|
|
153
128
|
onOpenChange: c.setFilterOpen,
|
|
154
129
|
hasActiveFilters: c.activeFilterCount > 0,
|
|
155
|
-
children: /* @__PURE__ */ jsxs(
|
|
130
|
+
children: /* @__PURE__ */ jsxs(default2, { spacing: 0, "data-testid": dataTestId ? `${dataTestId}-container` : void 0, children: [
|
|
156
131
|
/* @__PURE__ */ jsx(GridHeaderRow, { title: props.title, headerActions: props.headerActions, testIdPrefix }),
|
|
157
132
|
/* @__PURE__ */ jsx(
|
|
158
133
|
ShellToolbar,
|
|
@@ -175,6 +150,7 @@ function ShellStack({
|
|
|
175
150
|
testIdPrefix,
|
|
176
151
|
rowActions: props.rowActions,
|
|
177
152
|
bulkActions: props.bulkActions,
|
|
153
|
+
selectionExtra: resolveSelectionExtra(props),
|
|
178
154
|
toolbarRightSlot: props.toolbarRightSlot,
|
|
179
155
|
compactControls: showInline && split.compactControls,
|
|
180
156
|
counterHidden: showInline && split.counterHidden,
|
|
@@ -261,4 +237,4 @@ function GridShell(props) {
|
|
|
261
237
|
export {
|
|
262
238
|
GridShell
|
|
263
239
|
};
|
|
264
|
-
//# sourceMappingURL=chunk-
|
|
240
|
+
//# sourceMappingURL=chunk-LNIVT62P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-grid-parts.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { TableFilter } from \"../../layout/TableFilter\";\nimport { Stack } from \"../../../mui/Stack\";\n\nimport {\n DataViewsLayoutProvider,\n useDataViewsLayout,\n type DataViewsLayout,\n} from \"./data-views-layout-context\";\nimport { FilterDialog, GridFilterPanel } from \"./data-views-filter-panel\";\nimport { GridMain } from \"./data-views-grid-bodies\";\nimport type { ListGroupConfig } from \"./list-card-rails\";\nimport { InlineFilterControls } from \"./data-views-inline-bar\";\nimport { toOverflowFields, useFilterOverflow, type OverflowSplit } from \"./data-views-overflow\";\nimport { GridHeaderRow } from \"./data-views-header-row\";\nimport { resolveSelectionExtra, type SelectionExtraRender } from \"./data-views-selection-extra\";\nimport { ShellToolbar } from \"./data-views-shell-toolbar\";\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { DataViewsEmpty } from \"./data-views-empty\";\nimport { DataViewsPagination } from \"./data-views-pagination\";\nimport type { BoardConfig } from \"./DataViewsBoard\";\nimport { type ScopeConfig } from \"./data-views-scopes\";\nimport { ScopeTabsSlot } from \"./data-views-scope-tabs\";\nimport { togglePillValues } from \"./data-views-grid-helpers\";\nimport type {\n DataViewCardSelection,\n FilterFieldConfig,\n RangeFieldConfig,\n RangeValue,\n RowAction,\n} from \"./data-views-types\";\nimport type { DataViewsController } from \"./use-data-views-state\";\n\n/* ── Layout ⇄ view-state mirror ──────────────────────────────────────────── */\n\n/**\n * Mirrors the LIVE layout back into the view state, so saving a view captures\n * the layout the user is actually looking at.\n *\n * A component rather than a callback prop because only something INSIDE the\n * provider can read the layout, and only the controller can write the state.\n * The `stored !== layout` guard is what makes it idempotent: `c` is rebuilt on\n * every render, so an unguarded effect here would patch → re-render → patch.\n *\n * It re-fires when `stored` changes too, which is the case that matters after\n * applying a saved view: `appliedState` REPLACES the state, so a view saved\n * before layouts were captured clears `state.layout`, and the mirror puts the\n * current one back rather than leaving the next save with nothing to store.\n */\nfunction LayoutStateSync<T extends Record<string, unknown>>({\n c,\n}: {\n c: DataViewsController<T>;\n}): null {\n const { layout } = useDataViewsLayout();\n const stored = c.state.layout;\n useEffect(() => {\n if (stored !== layout) c.patch({ layout });\n // `c` is intentionally out of the deps — see the guard above.\n }, [layout, stored]);\n return null;\n}\n\n/* ── Shell (composes toolbar + body + panel) ─────────────────────────────── */\n\n/** The shared filter-surface props consumed by the inline bar, panel, and modal. */\ninterface FilterSurfaceProps<T extends Record<string, unknown>> {\n testIdPrefix: string;\n search: string;\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n pills: Record<string, string[]>;\n ranges: Record<string, RangeValue>;\n onSearchChange: (value: string) => void;\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onChangeRange: (fieldId: string, range: RangeValue) => void;\n onClearField: (fieldId: string) => void;\n onClearAll: () => void;\n}\n\n/**\n * Derives the responsive filter state (which surface to show at this width) and\n * the filter-mutation handlers from the controller — pulled out of `GridShell`\n * so the component body stays under the size/complexity budget.\n */\n/** Grouped rather than positional: the list had grown past readability. */\ninterface GridShellFiltersArgs<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n inlineFilters: boolean;\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n testIdPrefix: string;\n alwaysShowSearch: boolean;\n /** Is \"Exportar\" on the bar? Half the right cluster's cost when it is not. */\n hasExport: boolean;\n}\n\nfunction useGridShellFilters<T extends Record<string, unknown>>({\n c,\n inlineFilters,\n fields,\n rangeFields,\n testIdPrefix,\n alwaysShowSearch,\n hasExport,\n}: GridShellFiltersArgs<T>): {\n showInline: boolean;\n useModal: boolean;\n inlineVisible: boolean;\n filterProps: FilterSurfaceProps<T>;\n split: OverflowSplit<T>;\n onControlOpenChange: (open: boolean) => void;\n} {\n const { state } = c;\n // How many filter controls are open. A COUNT, not a flag: closing one popover\n // by opening another overlaps, and a boolean would unfreeze mid-handover.\n const [openControls, setOpenControls] = useState(0);\n // ONE measurement for the whole shell: the filter row decides which controls\n // it can keep, and the TOOLBAR needs the same answer to drop its labels.\n // Measuring twice would let the two disagree at the crossover width.\n const split = useFilterOverflow(\n toOverflowFields(fields, rangeFields),\n state.pills,\n c.ranges,\n openControls > 0,\n hasExport,\n );\n // THE BAR RENDERS AT EVERY WIDTH. It used to be swapped for a full-screen\n // filter MODAL below `lg`, which was the responsive strategy before the\n // measured ladder existed — and the two now do the same job, badly together:\n // the modal took the bar away at 1199px, and with it the very degradation\n // (labels off, search collapsed, filters into \"Mais\") that exists to make a\n // narrow bar work. So a 900px window got no bar and no ladder, and the\n // operator lost the search entirely rather than gaining a compact one.\n //\n // The ladder is measured, so it already covers every width the modal did.\n const showInline = inlineFilters;\n const useModal = false;\n const inlineVisible =\n showInline &&\n (alwaysShowSearch || fields.length > 0 || rangeFields.length > 0 || state.search !== \"\");\n const filterProps: FilterSurfaceProps<T> = {\n testIdPrefix,\n search: state.search,\n fields,\n rangeFields,\n pills: state.pills,\n ranges: c.ranges,\n onSearchChange: (value) => c.patch({ search: value }),\n // Updater, never the render's `state` — see {@link DataViewStatePatch}.\n onTogglePill: (fieldId, value, checked) =>\n c.patch(({ pills }) => ({ pills: { ...pills, [fieldId]: togglePillValues(pills[fieldId], value, checked) } })),\n onChangeRange: (fieldId, range) => c.patch({ ranges: { ...c.ranges, [fieldId]: range } }),\n onClearField: (fieldId) => c.patch({ pills: { ...state.pills, [fieldId]: [] } }),\n onClearAll: () => c.patch({ search: \"\", pills: {}, ranges: {} }),\n };\n return {\n showInline,\n useModal,\n inlineVisible,\n filterProps,\n split,\n onControlOpenChange: (open) =>\n setOpenControls((count) => Math.max(0, count + (open ? 1 : -1))),\n };\n}\n\ninterface GridShellProps<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n rows: T[];\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n testIdPrefix: string;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n toolbarRightSlot?: React.ReactNode;\n rowActions?: RowAction<T>[];\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /** A widening control beside the selection count — see `resolveSelectionExtra`. */\n selectionExtra?: SelectionExtraRender<T>;\n /** Opt-in \"Grade\" (cards) layout: renders each row as an entity-supplied card.\n * Omit ⇒ table only (no layout toggle). */\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /**\n * Opt-in \"Quadro\" (board) layout. Needs `renderCard` too — the board reuses\n * the entity's card, so a board config without one simply offers no board\n * rather than failing: that is a config gap, not a runtime error.\n */\n board?: BoardConfig<T>;\n /** Opt-in \"Lista\" layout: one full-width, entity-rendered row per record. */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns, so its rows line up by construction. */\n listGroup?: ListGroupConfig<T>;\n /** The page-level partition rendered as tabs under the toolbar. */\n scopes?: ScopeConfig[];\n /**\n * The row field the scopes partition by. Compared against the board's\n * `groupBy` so the two are not shown as the same partition twice.\n */\n scopeFieldId?: string;\n /** Per-sort-field value kind, so directions read in the column's own terms. */\n sortKinds?: Record<string, string>;\n /** The saved-view chrome bracketing the Exibir panel. */\n displayView?: DisplayPanelView;\n /** Injected export — the host re-queries; the grid never fetches. */\n exportConfig?: DataViewExport;\n /** Page title in the grid's own header row, above the scopes + toolbar. */\n title?: string;\n /** Primary page actions rendered at the header row's right. */\n headerActions?: React.ReactNode;\n /** Which layout to show first when the user has expressed no preference (default \"table\"). */\n defaultLayout?: DataViewsLayout;\n /** Pin to `defaultLayout`, ignoring the remembered preference (stories/docs). */\n ignoreStoredLayout?: boolean;\n /**\n * Opt into the responsive inline filter UX: a collapsible filter row below the\n * toolbar on wide screens and a modal on narrow ones. When false (default),\n * keep the classic slide-in filter panel opened by the \"Filtros\" button.\n */\n inlineFilters?: boolean;\n /**\n * Keep the inline search box on screen even with no filter fields and no\n * active search. Without it a grid whose only filter IS the search (`fields`\n * empty) can never OFFER one: the row renders only once a search exists, so\n * the operator would have to hand-edit the URL to start one. Default false —\n * every grid that ships filter fields already shows the row.\n */\n alwaysShowSearch?: boolean;\n}\n\n/** The scrollable content region: scope tabs, toolbar, filter bar, body, pager. */\nfunction ShellStack<T extends Record<string, unknown>>({\n props,\n filters,\n}: {\n props: GridShellProps<T>;\n filters: ReturnType<typeof useGridShellFilters<T>>;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n const { c, testIdPrefix, dataTestId, scopes = [], emptyState, inlineFilters = false } = props;\n const { showInline, useModal, inlineVisible, filterProps, split, onControlOpenChange } = filters;\n // The grid renders the FILTERED empty state itself — it is the only party\n // that knows a filter is applied. See {@link DataViewsEmpty}.\n const body = (\n <DataViewsEmpty\n filtered={c.activeFilterCount > 0 || c.state.search !== \"\"}\n onClearFilters={() => c.patch({ search: \"\", pills: {}, ranges: {} })}\n emptyState={emptyState}\n testIdPrefix={testIdPrefix}\n />\n );\n return (\n <TableFilter\n copy={copy.tableFilter} open={c.filterOpen} onOpenChange={c.setFilterOpen}\n hasActiveFilters={c.activeFilterCount > 0}\n >\n <Stack spacing={0} data-testid={dataTestId ? `${dataTestId}-container` : undefined}>\n <GridHeaderRow title={props.title} headerActions={props.headerActions} testIdPrefix={testIdPrefix} />\n <ShellToolbar\n c={c}\n rows={props.rows}\n sortKinds={props.sortKinds}\n displayView={props.displayView}\n exportConfig={props.exportConfig}\n filterControls={\n inlineVisible ? (\n <InlineFilterControls\n {...filterProps} split={split} activeFilterCount={c.activeFilterCount}\n onControlOpenChange={onControlOpenChange}\n />\n ) : undefined\n }\n barRef={split.barRef}\n testIdPrefix={testIdPrefix}\n rowActions={props.rowActions}\n bulkActions={props.bulkActions}\n selectionExtra={resolveSelectionExtra(props)}\n toolbarRightSlot={props.toolbarRightSlot}\n compactControls={showInline && split.compactControls}\n counterHidden={showInline && split.counterHidden}\n showInline={showInline}\n />\n <ScopeTabsSlot\n scopes={scopes} scopeFieldId={props.scopeFieldId} board={props.board}\n value={c.scope} onChange={c.setScope} counts={c.scopeCounts}\n testIdPrefix={testIdPrefix}\n />\n <TableFilter.Layout>\n <TableFilter.Main>\n <GridMain\n c={c}\n getRowId={props.getRowId}\n renderCard={props.renderCard}\n renderListRow={props.renderListRow}\n listGroup={props.listGroup}\n board={props.board}\n dataTestId={dataTestId}\n testIdPrefix={testIdPrefix}\n emptyState={body}\n />\n <DataViewsPagination c={c} testIdPrefix={testIdPrefix} />\n </TableFilter.Main>\n {inlineFilters ? null : <GridFilterPanel {...filterProps} />}\n </TableFilter.Layout>\n {useModal && <FilterDialog open={c.filterOpen} onClose={() => c.setFilterOpen(false)} {...filterProps} />}\n </Stack>\n </TableFilter>\n );\n}\n\nexport function GridShell<T extends Record<string, unknown>>(props: GridShellProps<T>): React.JSX.Element {\n const {\n c,\n fields,\n rangeFields,\n testIdPrefix,\n renderCard,\n renderListRow,\n board,\n defaultLayout,\n ignoreStoredLayout,\n inlineFilters = false,\n alwaysShowSearch = false,\n } = props;\n const filters = useGridShellFilters({\n c,\n inlineFilters,\n fields,\n rangeFields,\n testIdPrefix,\n alwaysShowSearch,\n hasExport: props.exportConfig !== undefined,\n });\n return (\n <DataViewsLayoutProvider\n canUseCards={Boolean(renderCard)}\n canUseList={Boolean(renderListRow)}\n // The board reuses the entity's card, so it needs BOTH — a `board` with no\n // `renderCard` offers no board rather than throwing.\n canUseBoard={Boolean(board && renderCard)}\n defaultLayout={defaultLayout}\n ignoreStoredLayout={ignoreStoredLayout}\n viewLayout={c.state.layout}\n >\n <LayoutStateSync c={c} />\n <ShellStack props={props} filters={filters} />\n </DataViewsLayoutProvider>\n );\n}\n"],"mappings":"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","names":["default"]}
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-ECIGNYSI.js";
|
|
8
8
|
import {
|
|
9
9
|
MoreFilters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UENDC45F.js";
|
|
11
11
|
import {
|
|
12
12
|
RangePill
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DFLTUI7W.js";
|
|
14
14
|
import {
|
|
15
15
|
CollapsedSearch,
|
|
16
16
|
InlineKeyword
|
|
@@ -220,4 +220,4 @@ function FilterSlots({
|
|
|
220
220
|
export {
|
|
221
221
|
InlineFilterControls
|
|
222
222
|
};
|
|
223
|
-
//# sourceMappingURL=chunk-
|
|
223
|
+
//# sourceMappingURL=chunk-LPNF4YJ7.js.map
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "./chunk-KHG57NAE.js";
|
|
23
23
|
import {
|
|
24
24
|
DataGrid
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-RPWEXIAW.js";
|
|
26
26
|
import {
|
|
27
27
|
default as default2
|
|
28
28
|
} from "./chunk-6DPAWXZ3.js";
|
|
@@ -264,4 +264,4 @@ function GridMain(props) {
|
|
|
264
264
|
export {
|
|
265
265
|
GridMain
|
|
266
266
|
};
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-M6365FGG.js.map
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
metaShape,
|
|
9
9
|
rowStyles,
|
|
10
10
|
useRowShell
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-O6V7KKW7.js";
|
|
12
12
|
import {
|
|
13
13
|
ListCardActions,
|
|
14
14
|
ListCardCaption,
|
|
@@ -179,4 +179,4 @@ function BaseListCard(props) {
|
|
|
179
179
|
export {
|
|
180
180
|
BaseListCard
|
|
181
181
|
};
|
|
182
|
-
//# sourceMappingURL=chunk-
|
|
182
|
+
//# sourceMappingURL=chunk-O6MZPB64.js.map
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
STACK_BREAK
|
|
3
|
-
} from "./chunk-EICVL6GS.js";
|
|
4
1
|
import {
|
|
5
2
|
CARD_RADIUS,
|
|
6
3
|
cardSurfaceStyles,
|
|
@@ -8,6 +5,9 @@ import {
|
|
|
8
5
|
isSelectable,
|
|
9
6
|
slotTestIds
|
|
10
7
|
} from "./chunk-MQUU2XZB.js";
|
|
8
|
+
import {
|
|
9
|
+
STACK_BREAK
|
|
10
|
+
} from "./chunk-EICVL6GS.js";
|
|
11
11
|
import {
|
|
12
12
|
useDragItem
|
|
13
13
|
} from "./chunk-JCJGJX7V.js";
|
|
@@ -181,4 +181,4 @@ export {
|
|
|
181
181
|
actionProps,
|
|
182
182
|
rowStyles
|
|
183
183
|
};
|
|
184
|
-
//# sourceMappingURL=chunk-
|
|
184
|
+
//# sourceMappingURL=chunk-O6V7KKW7.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Chart
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AP3PVR3T.js";
|
|
4
4
|
import {
|
|
5
5
|
CHART_SEMANTIC_COLORS,
|
|
6
6
|
specToChartProps
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R6SBP5M5.js";
|
|
8
8
|
import {
|
|
9
9
|
accentFor
|
|
10
10
|
} from "./chunk-I6PZVHIT.js";
|
|
@@ -46,4 +46,4 @@ var SpecChart = ({
|
|
|
46
46
|
export {
|
|
47
47
|
SpecChart
|
|
48
48
|
};
|
|
49
|
-
//# sourceMappingURL=chunk-
|
|
49
|
+
//# sourceMappingURL=chunk-PDGAFQ6Z.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-ECIGNYSI.js";
|
|
4
4
|
import {
|
|
5
5
|
PanelRangeField
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DFLTUI7W.js";
|
|
7
7
|
import {
|
|
8
8
|
useDataViewsCopy
|
|
9
9
|
} from "./chunk-KHG57NAE.js";
|
|
@@ -154,4 +154,4 @@ export {
|
|
|
154
154
|
GridFilterPanel,
|
|
155
155
|
FilterDialog
|
|
156
156
|
};
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-PHA3NFZM.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RangeBounds
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DFLTUI7W.js";
|
|
4
4
|
import {
|
|
5
5
|
isRangeSet
|
|
6
6
|
} from "./chunk-GCZJH4XL.js";
|
|
@@ -188,4 +188,4 @@ export {
|
|
|
188
188
|
fieldClearing,
|
|
189
189
|
MoreGroup
|
|
190
190
|
};
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
191
|
+
//# sourceMappingURL=chunk-QIKTIKO6.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
chartValueFormatter
|
|
3
|
-
} from "./chunk-QVWNK4JO.js";
|
|
4
1
|
import {
|
|
5
2
|
getChartSpecRenderer,
|
|
6
3
|
getRegisteredChartSpecTypes
|
|
7
4
|
} from "./chunk-WKUA6P3W.js";
|
|
5
|
+
import {
|
|
6
|
+
chartValueFormatter
|
|
7
|
+
} from "./chunk-QVWNK4JO.js";
|
|
8
8
|
|
|
9
9
|
// src/components/data-display/Chart/chart-spec.ts
|
|
10
10
|
var CHART_SEMANTIC_COLORS = [
|
|
@@ -149,4 +149,4 @@ export {
|
|
|
149
149
|
parseChartSpec,
|
|
150
150
|
specToChartProps
|
|
151
151
|
};
|
|
152
|
-
//# sourceMappingURL=chunk-
|
|
152
|
+
//# sourceMappingURL=chunk-R6SBP5M5.js.map
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataGridEmpty,
|
|
3
|
+
DataGridError,
|
|
4
|
+
DataGridLoading
|
|
5
|
+
} from "./chunk-5E3XZAED.js";
|
|
1
6
|
import {
|
|
2
7
|
useDataGridModel
|
|
3
8
|
} from "./chunk-DLJGBJZW.js";
|
|
@@ -5,11 +10,6 @@ import {
|
|
|
5
10
|
GridBody,
|
|
6
11
|
GridHeader
|
|
7
12
|
} from "./chunk-KZLLTOB2.js";
|
|
8
|
-
import {
|
|
9
|
-
DataGridEmpty,
|
|
10
|
-
DataGridError,
|
|
11
|
-
DataGridLoading
|
|
12
|
-
} from "./chunk-5E3XZAED.js";
|
|
13
13
|
|
|
14
14
|
// src/components/data-display/DataGrid/DataGrid.tsx
|
|
15
15
|
import Paper from "@mui/material/Paper/index.js";
|
|
@@ -115,4 +115,4 @@ DataGrid.displayName = "DataGrid";
|
|
|
115
115
|
export {
|
|
116
116
|
DataGrid
|
|
117
117
|
};
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
118
|
+
//# sourceMappingURL=chunk-RPWEXIAW.js.map
|
|
@@ -22,6 +22,7 @@ function SelectionCluster({
|
|
|
22
22
|
selectAll,
|
|
23
23
|
clearSelection,
|
|
24
24
|
actions,
|
|
25
|
+
selectionExtra,
|
|
25
26
|
selectAllTestId,
|
|
26
27
|
clearAllTestId,
|
|
27
28
|
edgeAlign = false,
|
|
@@ -95,6 +96,7 @@ function SelectionCluster({
|
|
|
95
96
|
]
|
|
96
97
|
}
|
|
97
98
|
),
|
|
99
|
+
selectionExtra,
|
|
98
100
|
actionsSlot
|
|
99
101
|
] }) : actionsSlot
|
|
100
102
|
]
|
|
@@ -159,6 +161,7 @@ function ContentToolbar({
|
|
|
159
161
|
rightControls,
|
|
160
162
|
leadingControls,
|
|
161
163
|
actions,
|
|
164
|
+
selectionExtra,
|
|
162
165
|
selectAllTestId,
|
|
163
166
|
clearAllTestId,
|
|
164
167
|
edgeAlign = false,
|
|
@@ -198,6 +201,7 @@ function ContentToolbar({
|
|
|
198
201
|
selectAll,
|
|
199
202
|
clearSelection,
|
|
200
203
|
actions,
|
|
204
|
+
selectionExtra,
|
|
201
205
|
selectAllTestId,
|
|
202
206
|
clearAllTestId,
|
|
203
207
|
selectAllLabel,
|
|
@@ -222,4 +226,4 @@ function ContentToolbar({
|
|
|
222
226
|
export {
|
|
223
227
|
ContentToolbar
|
|
224
228
|
};
|
|
225
|
-
//# sourceMappingURL=chunk-
|
|
229
|
+
//# sourceMappingURL=chunk-TSPHRZ4U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/ContentToolbar/ContentToolbar.tsx"],"sourcesContent":["'use client';\n\nimport Box from '@mui/material/Box/index.js';\nimport Button from '@mui/material/Button/index.js';\nimport Checkbox from '@mui/material/Checkbox/index.js';\nimport Divider from '@mui/material/Divider/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport React from 'react';\n\nimport type { ContentToolbarProps } from './ContentToolbar.types';\n\nconst selectionButtonSx = {\n minWidth: 0,\n height: 'auto',\n borderRadius: 0.5,\n fontWeight: 600,\n py: 0.5,\n px: 1.5,\n fontSize: '0.75rem',\n textTransform: 'none',\n color: 'text.primary',\n} as const;\n\ntype SelectionClusterProps = Pick<\n ContentToolbarProps,\n | 'hasSelection'\n | 'selectedCount'\n | 'selectAll'\n | 'clearSelection'\n | 'actions'\n | 'selectionExtra'\n | 'selectAllTestId'\n | 'clearAllTestId'\n | 'edgeAlign'\n | 'selectAllLabel'\n | 'selectAllText'\n | 'clearAllText'\n>;\n\n/** The left cluster: Select All + (when selecting) Clear All / count / actions. */\nfunction SelectionCluster({\n hasSelection,\n selectedCount,\n selectAll,\n clearSelection,\n actions,\n selectionExtra,\n selectAllTestId,\n clearAllTestId,\n edgeAlign = false,\n selectAllLabel,\n selectAllText,\n clearAllText,\n}: SelectionClusterProps): React.JSX.Element {\n const actionsSlot = actions !== undefined && (\n <Box sx={{ ml: 0.5, display: 'flex', flexShrink: 0, alignItems: 'center' }}>{actions}</Box>\n );\n return (\n <Box\n sx={{\n display: 'flex',\n minWidth: 0,\n // Mobile: don't grow, so the controls sit on the SAME line as the checkbox\n // (no orphaned selection row). Desktop: grow to push controls right.\n flex: { xs: '0 0 auto', md: 1 },\n alignItems: 'center',\n gap: 1.5,\n ml: edgeAlign ? -1.5 : 0,\n }}\n >\n {/* Desktop: a \"Select All\" text button (md+). Mobile: a compact checkbox\n that toggles select-all/clear — the text would eat the tight row. */}\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={selectAll}\n data-testid={selectAllTestId}\n sx={{ ...selectionButtonSx, display: { xs: 'none', md: 'inline-flex' } }}\n >\n {selectAllText}\n </Button>\n <Checkbox\n size=\"small\"\n checked={hasSelection}\n onChange={(event) => (event.target.checked ? selectAll() : clearSelection())}\n data-testid={`${selectAllTestId}-checkbox`}\n inputProps={{ 'aria-label': selectAllLabel }}\n sx={{ p: 0.5, display: { xs: 'inline-flex', md: 'none' } }}\n />\n {hasSelection ? (\n <>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={clearSelection}\n data-testid={clearAllTestId}\n sx={selectionButtonSx}\n >\n {clearAllText}\n </Button>\n <Divider orientation=\"vertical\" flexItem sx={{ height: 16, alignSelf: 'center' }} />\n <Typography\n component=\"span\"\n data-testid=\"selected-count-indicator\"\n sx={{ fontSize: '0.875rem', color: 'text.secondary', whiteSpace: 'nowrap', flexShrink: 0 }}\n >\n {selectedCount} {selectedCount === 1 ? 'item' : 'items'} selected\n </Typography>\n {selectionExtra}\n {actionsSlot}\n </>\n ) : (\n actionsSlot\n )}\n </Box>\n );\n}\n\n/**\n * The BROWSING half of the toolbar: search + filters on the left, the page's\n * own controls on the right. Split out of {@link ContentToolbar} so that\n * function stays inside the complexity gate — it is layout only, and the\n * decision of whether to show it at all is made by the caller.\n */\nfunction BrowsingClusters({\n leadingControls,\n rightControls,\n hasSelection,\n edgeAlign,\n}: {\n leadingControls?: React.ReactNode;\n rightControls: React.ReactNode;\n hasSelection: boolean;\n edgeAlign: boolean;\n}): React.JSX.Element {\n return (\n <>\n {/* minWidth:0 lets this cluster be the one that gives up width as the row\n * tightens, which is what the filter overflow measures against. */}\n {leadingControls !== undefined && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n flexGrow: 1,\n minWidth: 0,\n // The collapse ladder has a FLOOR — below roughly 400px even the\n // fully-collapsed row does not fit, and its controls cannot shrink\n // (they are flexShrink:0 so an over-packed row sheds instead of\n // squeezing). Past that point this scrolls rather than letting them\n // paint outside the toolbar, which is what a narrow phone did.\n overflowX: 'auto',\n // No scrollbar gutter stealing height on the common case.\n scrollbarWidth: 'thin',\n }}\n >\n {leadingControls}\n </Box>\n )}\n {/* ml:auto keeps the controls right-aligned even when the cluster wraps to\n * its own row (where justify-content:space-between would otherwise snap a\n * lone item to the left); it's a no-op on a shared row. */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n // Same single-line rule as the row itself: this cluster wrapping\n // INTERNALLY buys a second line just as surely as the row wrapping\n // does. It bit at exactly 900px, the `md` breakpoint where the \"N de\n // N\" counter appears and pushes Exibir/Exportar over the edge.\n flexWrap: leadingControls === undefined ? 'wrap' : 'nowrap',\n // Tight (5px) when browsing so the controls fit one line beside the\n // checkbox; roomier (14px) in selection mode where they get their own row.\n gap: hasSelection ? '14px' : '5px',\n ml: 'auto',\n mr: edgeAlign ? -1.5 : 0,\n '& > *': { flexShrink: 0 },\n }}\n >\n {rightControls}\n </Box>\n </>\n );\n}\n\n/**\n * Shared toolbar for content pages (Favorites, Personal Space, Recents, …). The\n * left cluster owns selection chrome — **Select All**, and once items are\n * selected, **Clear All** + an \"N items selected\" count + an optional `actions`\n * slot. The right cluster is a free `rightControls` slot for page-specific\n * controls (ViewSelector, SortByDropdown, MultiSelectDropdown, FilterTrigger).\n *\n * Faithful, generic MUI port of the reference `ContentPageToolbar` — the\n * domain-specific default actions are intentionally left to the consumer via\n * the `actions` slot so this stays agnostic and reusable across projects.\n *\n * @example\n * ```tsx\n * <ContentToolbar\n * hasSelection={selected.size > 0}\n * selectedCount={selected.size}\n * selectAll={selectAll}\n * clearSelection={clear}\n * rightControls={\n * <>\n * <ViewSelector viewMode={view} onViewModeChange={setView} zoom={zoom} onZoomChange={setZoom} />\n * <SortByDropdown fields={FIELDS} activeField={field} onFieldChange={setField} />\n * <MultiSelectDropdown label=\"Content Type\" options={types} selected={typeSet} onToggle={toggle} onClear={clear} />\n * <FilterTrigger open={panelOpen} onOpenChange={setPanelOpen} hasActiveFilters={hasFilters} />\n * </>\n * }\n * />\n * ```\n */\nexport function ContentToolbar({\n hasSelection,\n selectedCount,\n selectAll,\n clearSelection,\n rightControls,\n leadingControls,\n actions,\n selectionExtra,\n selectAllTestId,\n clearAllTestId,\n edgeAlign = false,\n exclusiveSelection = false,\n selectAllLabel,\n selectAllText,\n clearAllText,\n}: ContentToolbarProps): React.JSX.Element {\n // Under `exclusiveSelection` the two states are alternatives, not neighbours:\n // browsing shows the controls and no checkbox, selecting shows the checkbox\n // and no controls. Anything else double-books the row.\n const showSelection = !exclusiveSelection || hasSelection;\n const showControls = !exclusiveSelection || !hasSelection;\n return (\n // Two clusters on one line. They may wrap onto separate rows ONLY for a\n // toolbar without `leadingControls` — one carrying search + filters is\n // driven by a measured collapse ladder (see `useFilterOverflow`), and a\n // wrap there is the ladder having failed: it would silently buy a second\n // row instead of shedding a control into \"Mais\", which is the one outcome\n // the ladder exists to prevent.\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: leadingControls === undefined ? 'wrap' : 'nowrap',\n rowGap: 1,\n }}\n >\n {showSelection && (\n <SelectionCluster\n selectAllText={selectAllText}\n clearAllText={clearAllText}\n hasSelection={hasSelection}\n selectedCount={selectedCount}\n selectAll={selectAll}\n clearSelection={clearSelection}\n actions={actions}\n selectionExtra={selectionExtra}\n selectAllTestId={selectAllTestId}\n clearAllTestId={clearAllTestId}\n selectAllLabel={selectAllLabel}\n edgeAlign={edgeAlign}\n />\n )}\n\n {showControls && (\n <BrowsingClusters\n leadingControls={leadingControls}\n rightControls={rightControls}\n hasSelection={hasSelection}\n edgeAlign={edgeAlign}\n />\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/components/data-display/DataViews/data-views-writers.ts
|
|
2
|
+
function nextVisibleColumns(current, id, visible) {
|
|
3
|
+
const without = current.filter((colId) => colId !== id);
|
|
4
|
+
return visible ? [...without, id] : without;
|
|
5
|
+
}
|
|
6
|
+
function useStateWriters(setState) {
|
|
7
|
+
return {
|
|
8
|
+
patch: (next) => setState((prev) => ({ ...prev, ...typeof next === "function" ? next(prev) : next })),
|
|
9
|
+
toggleColumn: (id, visible) => setState((prev) => ({
|
|
10
|
+
...prev,
|
|
11
|
+
visibleColumns: nextVisibleColumns(prev.visibleColumns, id, visible)
|
|
12
|
+
}))
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
useStateWriters
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=chunk-U5FOJBLG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-writers.ts"],"sourcesContent":["\"use client\";\n\nimport { type Dispatch, type SetStateAction } from \"react\";\n\nimport { type DataViewState, type DataViewStatePatch } from \"./data-views-types\";\n\n/**\n * Add or remove one column id from the visible-columns list.\n *\n * Moved here with its only caller. A visible column is APPENDED rather than\n * restored to its original index, which is what makes re-showing a column put\n * it last — the behaviour the Exibir panel has always had.\n */\nfunction nextVisibleColumns(current: string[], id: string, visible: boolean): string[] {\n const without = current.filter((colId) => colId !== id);\n return visible ? [...without, id] : without;\n}\n\n/**\n * The two ways a DataViews state is WRITTEN, spelled once.\n *\n * Both are `setState` with a shape — a whole-state patch, and the one column\n * toggle that has to merge into a list rather than replace a field. They sat\n * inline in `useDataViewsState`, which is permanently at the size gate's\n * ceiling; here they sit next to each other, where the fact that\n * `toggleColumn` is just a `patch` with a merge rule is visible.\n *\n * Extracted for the same reason `useSelection` was: that hook is a COMPOSITION\n * of the pieces below it, and every piece that can be named on its own leaves\n * it reading as what it assembles rather than as how each part works.\n */\nexport function useStateWriters(setState: Dispatch<SetStateAction<DataViewState>>): {\n patch: (next: DataViewStatePatch) => void;\n toggleColumn: (id: string, visible: boolean) => void;\n} {\n return {\n patch: (next) =>\n setState((prev) => ({ ...prev, ...(typeof next === \"function\" ? next(prev) : next) })),\n toggleColumn: (id, visible) =>\n setState((prev) => ({\n ...prev,\n visibleColumns: nextVisibleColumns(prev.visibleColumns, id, visible),\n })),\n };\n}\n"],"mappings":";AAaA,SAAS,mBAAmB,SAAmB,IAAY,SAA4B;AACrF,QAAM,UAAU,QAAQ,OAAO,CAAC,UAAU,UAAU,EAAE;AACtD,SAAO,UAAU,CAAC,GAAG,SAAS,EAAE,IAAI;AACtC;AAeO,SAAS,gBAAgB,UAG9B;AACA,SAAO;AAAA,IACL,OAAO,CAAC,SACN,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAI,OAAO,SAAS,aAAa,KAAK,IAAI,IAAI,KAAM,EAAE;AAAA,IACvF,cAAc,CAAC,IAAI,YACjB,SAAS,CAAC,UAAU;AAAA,MAClB,GAAG;AAAA,MACH,gBAAgB,mBAAmB,KAAK,gBAAgB,IAAI,OAAO;AAAA,IACrE,EAAE;AAAA,EACN;AACF;","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-LS42VJAI.js";
|
|
4
4
|
import {
|
|
5
5
|
DataViewsGrid
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-62WEMJV3.js";
|
|
7
7
|
import {
|
|
8
8
|
viewStateKey
|
|
9
9
|
} from "./chunk-ZOLAYP2D.js";
|
|
@@ -178,4 +178,4 @@ function renderViewDialogs(ctl, fields, columns, views, testIdPrefix, onSaved) {
|
|
|
178
178
|
export {
|
|
179
179
|
DataViewsTableBase
|
|
180
180
|
};
|
|
181
|
-
//# sourceMappingURL=chunk-
|
|
181
|
+
//# sourceMappingURL=chunk-U5RIDMMV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/DataViewsTableBase.tsx"],"sourcesContent":["\"use client\";\n\nimport type { SortFieldDefinition } from \"../../layout/ContentToolbar\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { DataViewsGrid } from \"./DataViewsGrid\";\nimport type { SelectionExtraRender } from \"./data-views-selection-extra\";\nimport type { ListGroupConfig } from \"./list-card-rails\";\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport { viewStateKey } from \"./data-views-dirty\";\nimport { DeleteViewDialog } from \"./DeleteViewDialog\";\nimport type { BoardConfig } from \"./DataViewsBoard\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport type { ScopeConfig } from \"./data-views-scopes\";\nimport { ViewDialogs, ViewMutationErrorAlert } from \"./data-views-table-parts\";\nimport {\n useSavedViewsController,\n type SavedViewsController,\n} from \"./use-saved-views-controller\";\nimport {\n type DataViewColumn,\n type DataViewsLayout,\n type DataViewServer,\n type DataViewState,\n type DataViewSyncState,\n type DataViewPersistence,\n type DataViewRouter,\n type FilterFieldConfig,\n type RangeFieldConfig,\n type DataViewCardSelection,\n type RowAction,\n type SavedViewSummary,\n} from \"./data-views-types\";\n\nexport interface DataViewsTableBaseProps<T extends Record<string, unknown>> {\n /** The applied-view id read from the URL (`?view=`) on load, or null. */\n initialViewId?: string | null;\n /** Injected saved-view persistence (create/update/delete). */\n persistence: DataViewPersistence;\n /** Injected router side-effects (URL sync + refresh). */\n router: DataViewRouter;\n rows: T[];\n columns: DataViewColumn<T>[];\n fields: FilterFieldConfig<T>[];\n /** Optional numeric min/max range filters (advanced \"filter by amount\"). */\n rangeFields?: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n onRowClick?: (row: T) => void;\n emptyState?: React.ReactNode;\n dataTestId?: string;\n testIdPrefix?: string;\n /** The user's + shared views for this table (from the server). */\n views: SavedViewSummary[];\n /** Big page title in the table header, beside the funnel + gear (GTA layout). */\n title?: string;\n /** Primary page actions (e.g. \"Novo produto\") rendered at the header's right. */\n headerActions?: React.ReactNode;\n /** Sort options for the toolbar's \"Sort By\" dropdown (defaults to sortable columns). */\n sortFields?: SortFieldDefinition[];\n /**\n * Per-sort-field VALUE KIND (`\"currency\" | \"number\" | \"date\" | \"text\"`), so the\n * Exibir panel phrases the direction in that column's own terms. \"Crescente\"\n * on a currency column is a puzzle; \"Menor → maior\" is not. Defaults to text.\n */\n sortKinds?: Record<string, string>;\n /**\n * Opt-in \"Exportar\" control. The grid hands the host the current query,\n * UNPAGINATED, and the host re-queries — the grid never fetches, and an\n * export therefore follows the filters rather than the loaded page.\n */\n exportConfig?: DataViewExport;\n /** Notified with the currently-visible (filtered) rows, so Export matches the view. */\n onVisibleRowsChange?: (rows: T[]) => void;\n /** Reusable row actions driving both the row \"⋮\" kebab and the bulk menu. */\n rowActions?: RowAction<T>[];\n /** Leading control in the auto kebab column (e.g. a favourite star). */\n rowActionsLeading?: (row: T) => React.ReactNode;\n /** Low-level bulk-action override; prefer `rowActions`. */\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /** A selection-widening control beside the count (e.g. \"select all matching\"). */\n selectionExtra?: SelectionExtraRender<T>;\n /** Bespoke per-row menu (an entity's self-contained 3-dots menu) instead of the auto kebab. */\n renderRowMenu?: (row: T) => React.ReactNode;\n /** Opt-in \"Grade\" (cards) layout — a card renderer per row; adds a Grade/Tabela toggle. */\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** Opt-in \"Quadro\" (board) layout — the loaded page as columns of one field. Needs `renderCard`. */\n board?: BoardConfig<T>;\n /** Opt-in \"Lista\" layout — one full-width, entity-rendered row per record (FUT-733). */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns, so its rows line up by construction not convention. */\n listGroup?: ListGroupConfig<T>;\n /** The page-level partition rendered as tabs under the toolbar (server mode only). */\n scopes?: ScopeConfig[];\n /** The row field the scopes partition by — used only to reject a pill over the same field. */\n scopeFieldId?: string;\n /** Which layout to show first when the user has expressed no preference (default \"table\"). */\n defaultLayout?: DataViewsLayout;\n /**\n * Ignore the remembered cross-screen layout preference and pin to\n * `defaultLayout`. For tables that exist to SHOW a layout — stories, docs,\n * screenshots — not for real screens.\n */\n ignoreStoredLayout?: boolean;\n /** Opt into the responsive inline filter UX (collapsible row / modal). Default keeps the panel. */\n inlineFilters?: boolean;\n /** Keep the inline search visible with no filter fields and no active search. */\n alwaysShowSearch?: boolean;\n /** Server-mode wiring (FUT-180): backend-driven rows/total + re-fetch. Omit for client mode. */\n server?: DataViewServer;\n /** Seed the initial view state (search/pills/ranges/sort) from the URL when no saved view applies. */\n initialState?: DataViewState;\n}\n\n/**\n * Derive the grid's reactive `syncState` from the URL-seeded `initialState` in\n * server mode so browser back/forward RE-APPLIES the search/pills/sort controls\n * (merging over live state, preserving hidden columns — see {@link DataViewSyncState}).\n * Client-mode tables (no `server`) get `undefined`. Callers memoize `initialState`\n * on the URL, so this reference only changes on genuine navigations.\n */\nfunction useUrlSyncState(\n server: DataViewServer | undefined,\n initialState: DataViewState | undefined,\n): DataViewSyncState | undefined {\n const isServerMode = server !== undefined;\n return useMemo<DataViewSyncState | undefined>(\n () =>\n isServerMode && initialState\n ? {\n search: initialState.search,\n pills: initialState.pills,\n ranges: initialState.ranges,\n sortBy: initialState.sortBy,\n // The scope belongs in the URL-driven slice alongside them: a\n // `?view=recusados`-style deep link and browser back/forward must\n // move the tab strip, and they must do it WITHOUT resetting the\n // user's hidden columns — which is the whole reason this is a\n // merging `syncState` and not a replacing `appliedState`.\n scope: initialState.scope,\n }\n : undefined,\n [isServerMode, initialState],\n );\n}\n\n/**\n * Resolve the initial applied view: a `?view=<id>` shortcut (FUT-90) wins, else\n * the user's default view, else none. Drives the seed state + trigger label.\n */\nfunction resolveInitialView(\n views: SavedViewSummary[],\n requestedId: string | null,\n): SavedViewSummary | undefined {\n const requested = requestedId ? views.find((view) => view.id === requestedId) : undefined;\n return requested ?? views.find((view) => view.isDefault);\n}\n\n/**\n * The Exibir panel's view chrome, assembled from the saved-views controller.\n * Extracted so {@link DataViewsTableBase} stays inside its size budget.\n */\nfunction buildDisplayView({\n ctl,\n views,\n activeView,\n dirty,\n onRequestDelete,\n}: {\n ctl: SavedViewsController;\n views: SavedViewSummary[];\n activeView: SavedViewSummary | undefined;\n dirty: boolean;\n /** Opens the confirmation; the delete itself happens on confirm. */\n onRequestDelete: (view: SavedViewSummary) => void;\n}): DisplayPanelView {\n return {\n activeViewName: ctl.activeViewName,\n dirty,\n onReset: () => (activeView ? ctl.applyView(activeView) : ctl.selectMain()),\n // Only offer \"Atualizar\" when there IS a view to update — otherwise the\n // single footer button is a plain \"Salvar visão\".\n onUpdate: activeView ? () => ctl.openEdit(activeView) : undefined,\n onSaveAs: ctl.openCreate,\n // The views themselves, not a dropdown: the panel renders them in its own\n // body (see `data-views-view-nav`), so there is no second popover to clip\n // the row actions.\n nav: {\n views,\n activeViewId: activeView?.id ?? null,\n onSelectView: (id) => {\n const next = id === null ? null : views.find((view) => view.id === id);\n if (next) ctl.applyView(next);\n else ctl.selectMain();\n },\n onEditView: ctl.openEdit,\n onPatchView: (view, changes) => void ctl.patchView(view, changes),\n onDeleteView: onRequestDelete,\n },\n };\n}\n\n/**\n * \"Are there unsaved changes?\" — the dot on Exibir, and whether Redefinir and\n * Salvar visão are live.\n *\n * Two things it gets right that the inline version did not. It compares\n * NORMALISED states (`viewStateKey`), so a filter applied and then removed is\n * clean again rather than clean-looking but flagged; and it re-baselines after\n * a SAVE, because the state just written is the clean one from that point.\n *\n * The baseline is the first state the grid emits for a view, not the view\n * itself: the grid normalises what it is handed — resolving visible columns,\n * filling in layout — so the applied view is never byte-identical to the state\n * it produces.\n */\nfunction useDirtyTracking(ctl: SavedViewsController): {\n dirty: boolean;\n noteState: (state: DataViewState) => void;\n markSaved: () => void;\n} {\n const [dirty, setDirty] = useState(false);\n const [savedAt, setSavedAt] = useState(0);\n const baseline = useRef<string | null>(null);\n const appliedKey = JSON.stringify(ctl.applied ?? null);\n\n useEffect(() => {\n baseline.current = null;\n setDirty(false);\n }, [appliedKey, savedAt]);\n\n return {\n dirty,\n noteState: (state) => {\n ctl.currentRef.current = state;\n const key = viewStateKey(state);\n if (baseline.current === null) {\n baseline.current = key;\n setDirty(false);\n return;\n }\n const next = key !== baseline.current;\n setDirty((prev) => (prev === next ? prev : next));\n },\n markSaved: () => setSavedAt((tick) => tick + 1),\n };\n}\n\n/**\n * The reusable admin table (FUT-89): the DataViews grid plus the full saved-views\n * experience — a views dropdown, a save/edit modal (with preview), and a manage\n * dialog. Framework-agnostic: saved-view persistence and router side-effects are\n * INJECTED (`persistence`, `router`, `initialViewId`) so the host app wires them\n * to its backend + framework router. A default view auto-applies on load; applying\n * a view restores its filters + columns + sort. Each table supplies its own columns\n * + filter fields; everything else is shared.\n */\nexport function DataViewsTableBase<T extends Record<string, unknown>>(\n props: DataViewsTableBaseProps<T>,\n): React.JSX.Element {\n // Forwarded as a whole rather than restated name-by-name twice (as in\n // DataViewsGrid): this component only ADDS the saved-views chrome, and a\n // 30-name destructure repeated in the JSX is exactly where a newly added prop\n // silently stops being passed on.\n const {\n initialViewId = null,\n persistence,\n router,\n columns,\n fields,\n testIdPrefix = \"table\",\n views,\n server,\n initialState,\n } = props;\n const initialView = resolveInitialView(views, initialViewId);\n const columnIds = columns.map((col) => col.id);\n const ctl = useSavedViewsController(persistence, router, columnIds, views, initialView, initialState);\n // Unsaved-changes flag for the Exibir panel. Set from `onStateChange` rather\n // than derived in render because the live state lives in a REF (the grid owns\n // it); the equality bail-out in `setDirty` is what stops the update loop.\n const { dirty, noteState, markSaved } = useDirtyTracking(ctl);\n // Deleting a saved view is confirmed, not immediate — see `DeleteViewDialog`.\n const [pendingDelete, setPendingDelete] = useState<SavedViewSummary | null>(null);\n // The view the panel's \"Redefinir\" restores: the applied one, or the built-in\n // \"Visão principal\" when none is.\n const activeView = views.find((view) => view.name === ctl.activeViewName);\n const displayView = buildDisplayView({\n ctl,\n views,\n activeView,\n dirty,\n onRequestDelete: setPendingDelete,\n });\n // Server-mode lists re-apply URL-derived controls on back/forward (not just the mount seed).\n const syncState = useUrlSyncState(server, initialState);\n\n return (\n <>\n <ViewMutationErrorAlert error={ctl.mutationError} onClose={ctl.clearMutationError} testIdPrefix={testIdPrefix} />\n <DataViewsGrid<T>\n {...props}\n testIdPrefix={testIdPrefix}\n appliedState={ctl.applied}\n syncState={syncState}\n onStateChange={noteState}\n // The saved-views menu is NOT a toolbar control any more: it lives in\n // the Exibir panel's VISÃO header, passed through `displayView`.\n displayView={displayView}\n />\n {renderViewDialogs(ctl, fields, columns, views, testIdPrefix, markSaved)}\n <DeleteViewDialog\n view={pendingDelete}\n onClose={() => setPendingDelete(null)}\n onConfirm={(view) => {\n void ctl.handleDelete(view);\n setPendingDelete(null);\n }}\n testIdPrefix={testIdPrefix}\n />\n </>\n );\n}\n\n/** The save + manage saved-view dialogs, split out to keep the base thin. */\nfunction renderViewDialogs<T extends Record<string, unknown>>(\n ctl: SavedViewsController,\n fields: DataViewsTableBaseProps<T>[\"fields\"],\n columns: DataViewsTableBaseProps<T>[\"columns\"],\n views: SavedViewSummary[],\n testIdPrefix: string,\n onSaved: () => void,\n): React.JSX.Element {\n return (\n <ViewDialogs<T>\n saveOpen={ctl.saveOpen}\n onCloseSave={ctl.closeSave}\n currentState={ctl.editing ? ctl.editing.state : ctl.currentRef.current}\n fields={fields}\n columns={columns}\n editing={ctl.editing}\n onSave={async (payload) => {\n await ctl.handleSave(payload);\n // The saved state is the clean one from here on.\n onSaved();\n }}\n manageOpen={ctl.manageOpen}\n onCloseManage={() => ctl.setManageOpen(false)}\n views={views}\n onEditFromManage={ctl.editFromManage}\n onDelete={(view) => void ctl.handleDelete(view)}\n testIdPrefix={testIdPrefix}\n />\n );\n}\n"],"mappings":"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","names":[]}
|