@nextelco/common-ui 2.1.105 → 2.1.107
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/esm/index.js +201 -145
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/legacy/components/atoms/InputData/InputData.js +2 -13
- package/dist/esm/legacy/components/atoms/InputData/InputData.js.map +1 -1
- package/dist/esm/legacy/components/charts/Charts.js +147 -57
- package/dist/esm/legacy/components/charts/Charts.js.map +1 -1
- package/dist/esm/legacy/components/layout/Layout/Layout.js +21 -82
- package/dist/esm/legacy/components/layout/Layout/Layout.js.map +1 -1
- package/dist/esm/legacy/components/layout/Sidebar/Sidebar.js +29 -218
- package/dist/esm/legacy/components/layout/Sidebar/Sidebar.js.map +1 -1
- package/dist/esm/legacy/components/molecules/ColumnPicker/ColumnPicker.js +77 -10
- package/dist/esm/legacy/components/molecules/ColumnPicker/ColumnPicker.js.map +1 -1
- package/dist/esm/legacy/components/molecules/DataTable/DataTable.js +445 -337
- package/dist/esm/legacy/components/molecules/DataTable/DataTable.js.map +1 -1
- package/dist/esm/legacy/components/molecules/UserAvatar/UserAvatar.js +15 -97
- package/dist/esm/legacy/components/molecules/UserAvatar/UserAvatar.js.map +1 -1
- package/dist/esm/legacy/components/organisms/MapaPontos/MapaPontos.js +3 -3
- package/dist/esm/legacy/components/organisms/MapaPontos/MapaPontos.js.map +1 -1
- package/dist/esm/legacy/components/organisms/PainelFiltros/PainelFiltros.js +15 -3
- package/dist/esm/legacy/components/organisms/PainelFiltros/PainelFiltros.js.map +1 -1
- package/dist/esm/legacy/components/organisms/Selector/Selector.js +4 -4
- package/dist/esm/legacy/components/organisms/Selector/Selector.js.map +1 -1
- package/dist/esm/legacy/components/ui/Avisos.js +23 -76
- package/dist/esm/legacy/components/ui/Avisos.js.map +1 -1
- package/dist/esm/legacy/components/ui/CabecalhoPagina.js +14 -27
- package/dist/esm/legacy/components/ui/CabecalhoPagina.js.map +1 -1
- package/dist/esm/legacy/components/ui/CaixaPesquisa.js +3 -51
- package/dist/esm/legacy/components/ui/CaixaPesquisa.js.map +1 -1
- package/dist/esm/legacy/components/ui/Confirmacao.js +13 -31
- package/dist/esm/legacy/components/ui/Confirmacao.js.map +1 -1
- package/dist/esm/legacy/components/ui/Escolha.js +21 -137
- package/dist/esm/legacy/components/ui/Escolha.js.map +1 -1
- package/dist/esm/legacy/components/ui/FaixaAviso.js +13 -11
- package/dist/esm/legacy/components/ui/FaixaAviso.js.map +1 -1
- package/dist/esm/legacy/components/ui/Separadores.js +11 -46
- package/dist/esm/legacy/components/ui/Separadores.js.map +1 -1
- package/dist/esm/legacy/components/ui/Ui.js +18 -115
- package/dist/esm/legacy/components/ui/Ui.js.map +1 -1
- package/dist/esm/legacy/components/ui/painelFlutuante.js +5 -44
- package/dist/esm/legacy/components/ui/painelFlutuante.js.map +1 -1
- package/dist/esm/v1/capabilities/overlay/useFloatingPanel.js +52 -0
- package/dist/esm/v1/capabilities/overlay/useFloatingPanel.js.map +1 -0
- package/dist/esm/v1/capabilities/theme/useIsDark.js +15 -0
- package/dist/esm/v1/capabilities/theme/useIsDark.js.map +1 -0
- package/dist/esm/v1/capabilities/theme/useTheme.js +66 -0
- package/dist/esm/v1/capabilities/theme/useTheme.js.map +1 -0
- package/dist/esm/v1/components/data/Pagination/Pagination.js +66 -0
- package/dist/esm/v1/components/data/Pagination/Pagination.js.map +1 -0
- package/dist/esm/v1/components/feedback/Toast/Toast.js +105 -0
- package/dist/esm/v1/components/feedback/Toast/Toast.js.map +1 -0
- package/dist/esm/v1/components/forms/FormField/FormField.js.map +1 -1
- package/dist/esm/v1/components/forms/FormGrid/FormGrid.js.map +1 -1
- package/dist/esm/v1/components/layout/AppShell/AppShell.js +89 -0
- package/dist/esm/v1/components/layout/AppShell/AppShell.js.map +1 -0
- package/dist/esm/v1/components/layout/Page/Page.js +16 -0
- package/dist/esm/v1/components/layout/Page/Page.js.map +1 -0
- package/dist/esm/v1/components/layout/PageHeader/PageHeader.js +26 -0
- package/dist/esm/v1/components/layout/PageHeader/PageHeader.js.map +1 -0
- package/dist/esm/v1/components/layout/SideNav/SideNav.js +277 -0
- package/dist/esm/v1/components/layout/SideNav/SideNav.js.map +1 -0
- package/dist/esm/v1/components/layout/navTrail.js +19 -0
- package/dist/esm/v1/components/layout/navTrail.js.map +1 -0
- package/dist/esm/v1/components/lists/ListFinder/ListFinder.js +4 -4
- package/dist/esm/v1/components/lists/ListFinder/ListFinder.js.map +1 -1
- package/dist/esm/v1/components/overlays/ConfirmDialog/ConfirmDialog.js +95 -0
- package/dist/esm/v1/components/overlays/ConfirmDialog/ConfirmDialog.js.map +1 -0
- package/dist/esm/v1/components/overlays/Dialog/Dialog.js.map +1 -1
- package/dist/esm/v1/components/overlays/Tooltip/Tooltip.js +98 -0
- package/dist/esm/v1/components/overlays/Tooltip/Tooltip.js.map +1 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipLayer.js +84 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipLayer.js.map +1 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipPanel.js +33 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipPanel.js.map +1 -0
- package/dist/esm/v1/components/overlays/topLayer.js +28 -0
- package/dist/esm/v1/components/overlays/topLayer.js.map +1 -0
- package/dist/esm/v1/components/tables/PaginatedTable/PaginatedTable.js.map +1 -1
- package/dist/esm/v1/components/tables/Table/Table.js.map +1 -1
- package/dist/esm/v1/foundations/icons/icons.js +61 -2
- package/dist/esm/v1/foundations/icons/icons.js.map +1 -1
- package/dist/esm/v1/primitives/buttons/Button/Button.js +18 -4
- package/dist/esm/v1/primitives/buttons/Button/Button.js.map +1 -1
- package/dist/esm/v1/primitives/buttons/SegmentedControl/SegmentedControl.js +65 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/SegmentedControl.js.map +1 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/segmentedStyles.js +10 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/segmentedStyles.js.map +1 -0
- package/dist/esm/v1/primitives/display/Avatar/Avatar.js +120 -0
- package/dist/esm/v1/primitives/display/Avatar/Avatar.js.map +1 -0
- package/dist/esm/v1/primitives/display/Badge/Badge.js +23 -0
- package/dist/esm/v1/primitives/display/Badge/Badge.js.map +1 -0
- package/dist/esm/v1/primitives/display/Card/Card.js +22 -0
- package/dist/esm/v1/primitives/display/Card/Card.js.map +1 -0
- package/dist/esm/v1/primitives/display/FilterChips/FilterChips.js +45 -0
- package/dist/esm/v1/primitives/display/FilterChips/FilterChips.js.map +1 -0
- package/dist/esm/v1/primitives/display/Kpi/Kpi.js +103 -0
- package/dist/esm/v1/primitives/display/Kpi/Kpi.js.map +1 -0
- package/dist/esm/v1/primitives/display/Notice/Notice.js +71 -0
- package/dist/esm/v1/primitives/display/Notice/Notice.js.map +1 -0
- package/dist/esm/v1/primitives/display/Person/Person.js +14 -0
- package/dist/esm/v1/primitives/display/Person/Person.js.map +1 -0
- package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js +10 -5
- package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js.map +1 -1
- package/dist/esm/v1/primitives/forms/DateInput/DateInput.js +150 -0
- package/dist/esm/v1/primitives/forms/DateInput/DateInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/LookupInput/LookupInput.js.map +1 -1
- package/dist/esm/v1/primitives/forms/SearchInput/SearchInput.js +43 -0
- package/dist/esm/v1/primitives/forms/SearchInput/SearchInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/SelectInput/SelectInput.js +190 -12
- package/dist/esm/v1/primitives/forms/SelectInput/SelectInput.js.map +1 -1
- package/dist/esm/v1/primitives/forms/TextArea/TextArea.js.map +1 -1
- package/dist/esm/v1/primitives/forms/field.js +4 -2
- package/dist/esm/v1/primitives/forms/field.js.map +1 -1
- package/dist/esm/v1/primitives/lists/ListItem/ListItem.js +2 -2
- package/dist/esm/v1/primitives/lists/ListItem/ListItem.js.map +1 -1
- package/dist/esm/v1/primitives/navigation/Tabs/Tabs.js +96 -0
- package/dist/esm/v1/primitives/navigation/Tabs/Tabs.js.map +1 -0
- package/dist/style.components.css +1 -1
- package/dist/style.css +1 -1
- package/dist/style.layered.css +1 -1
- package/dist/tailwind.css +24 -0
- package/dist/theme-boot.js +1 -0
- package/dist/theme.css +10 -3
- package/dist/tokens.css +119 -0
- package/dist/types/legacy/components/atoms/InputData/InputData.d.ts +4 -1
- package/dist/types/legacy/components/charts/Charts.d.ts +58 -5
- package/dist/types/legacy/components/layout/Layout/Layout.d.ts +7 -20
- package/dist/types/legacy/components/layout/Sidebar/Sidebar.d.ts +13 -26
- package/dist/types/legacy/components/molecules/ColumnPicker/ColumnPicker.d.ts +56 -3
- package/dist/types/legacy/components/molecules/DataTable/DataTable.d.ts +72 -7
- package/dist/types/legacy/components/molecules/UserAvatar/UserAvatar.d.ts +4 -5
- package/dist/types/legacy/components/ui/Avisos.d.ts +6 -16
- package/dist/types/legacy/components/ui/CabecalhoPagina.d.ts +6 -20
- package/dist/types/legacy/components/ui/CaixaPesquisa.d.ts +2 -4
- package/dist/types/legacy/components/ui/Confirmacao.d.ts +3 -10
- package/dist/types/legacy/components/ui/Escolha.d.ts +5 -15
- package/dist/types/legacy/components/ui/FaixaAviso.d.ts +2 -6
- package/dist/types/legacy/components/ui/Separadores.d.ts +3 -10
- package/dist/types/legacy/components/ui/Ui.d.ts +12 -54
- package/dist/types/legacy/components/ui/painelFlutuante.d.ts +6 -10
- package/dist/types/legacy/exports/atoms.d.ts +1 -1
- package/dist/types/legacy/exports/charts.d.ts +2 -2
- package/dist/types/legacy/exports/hooks.d.ts +2 -2
- package/dist/types/legacy/exports/molecules.d.ts +2 -2
- package/dist/types/v1/capabilities/overlay/useFloatingPanel.d.ts +20 -0
- package/dist/types/v1/capabilities/theme/useIsDark.d.ts +10 -0
- package/dist/types/v1/capabilities/theme/useTheme.d.ts +29 -0
- package/dist/types/v1/components/data/Pagination/Pagination.d.ts +33 -0
- package/dist/types/v1/components/feedback/Toast/Toast.d.ts +51 -0
- package/dist/types/v1/components/forms/FormField/FormField.d.ts +3 -3
- package/dist/types/v1/components/forms/FormGrid/FormGrid.d.ts +2 -0
- package/dist/types/v1/components/layout/AppShell/AppShell.d.ts +35 -0
- package/dist/types/v1/components/layout/Page/Page.d.ts +23 -0
- package/dist/types/v1/components/layout/PageHeader/PageHeader.d.ts +35 -0
- package/dist/types/v1/components/layout/SideNav/SideNav.d.ts +92 -0
- package/dist/types/v1/components/layout/navTrail.d.ts +15 -0
- package/dist/types/v1/components/lists/ListFinder/ListFinder.d.ts +1 -1
- package/dist/types/v1/components/overlays/ConfirmDialog/ConfirmDialog.d.ts +59 -0
- package/dist/types/v1/components/overlays/Dialog/Dialog.d.ts +6 -3
- package/dist/types/v1/components/overlays/Tooltip/Tooltip.d.ts +34 -0
- package/dist/types/v1/components/overlays/Tooltip/TooltipLayer.d.ts +18 -0
- package/dist/types/v1/components/overlays/Tooltip/TooltipPanel.d.ts +23 -0
- package/dist/types/v1/components/overlays/topLayer.d.ts +23 -0
- package/dist/types/v1/components/tables/PaginatedTable/PaginatedTable.d.ts +1 -1
- package/dist/types/v1/components/tables/Table/Table.d.ts +1 -1
- package/dist/types/v1/foundations/icons/icons.d.ts +20 -0
- package/dist/types/v1/index.d.ts +43 -1
- package/dist/types/v1/primitives/buttons/Button/Button.d.ts +22 -5
- package/dist/types/v1/primitives/buttons/SegmentedControl/SegmentedControl.d.ts +28 -0
- package/dist/types/v1/primitives/buttons/SegmentedControl/segmentedStyles.d.ts +16 -0
- package/dist/types/v1/primitives/display/Avatar/Avatar.d.ts +30 -0
- package/dist/types/v1/primitives/display/Badge/Badge.d.ts +25 -0
- package/dist/types/v1/primitives/display/Card/Card.d.ts +22 -0
- package/dist/types/v1/primitives/display/FilterChips/FilterChips.d.ts +33 -0
- package/dist/types/v1/primitives/display/Kpi/Kpi.d.ts +68 -0
- package/dist/types/v1/primitives/display/Notice/Notice.d.ts +29 -0
- package/dist/types/v1/primitives/display/Person/Person.d.ts +15 -0
- package/dist/types/v1/primitives/forms/Checkbox/Checkbox.d.ts +7 -0
- package/dist/types/v1/primitives/forms/DateInput/DateInput.d.ts +43 -0
- package/dist/types/v1/primitives/forms/LookupInput/LookupInput.d.ts +3 -0
- package/dist/types/v1/primitives/forms/SearchInput/SearchInput.d.ts +23 -0
- package/dist/types/v1/primitives/forms/SelectInput/SelectInput.d.ts +61 -10
- package/dist/types/v1/primitives/forms/TextArea/TextArea.d.ts +3 -0
- package/dist/types/v1/primitives/forms/field.d.ts +2 -0
- package/dist/types/v1/primitives/lists/ListItem/ListItem.d.ts +2 -1
- package/dist/types/v1/primitives/navigation/Tabs/Tabs.d.ts +58 -0
- package/package.json +3 -3
- package/dist/esm/legacy/components/atoms/Tooltip/Tooltip.css +0 -17
- package/dist/esm/legacy/components/atoms/Tooltip/Tooltip.js +0 -41
- package/dist/esm/legacy/components/atoms/Tooltip/Tooltip.js.map +0 -1
- package/dist/esm/legacy/components/molecules/Search/Search.css +0 -18
- package/dist/esm/legacy/components/molecules/Search/Search.js +0 -30
- package/dist/esm/legacy/components/molecules/Search/Search.js.map +0 -1
- package/dist/esm/legacy/hooks/useTheme.js +0 -39
- package/dist/esm/legacy/hooks/useTheme.js.map +0 -1
- package/dist/esm/v1/primitives/lists/ListItem/ListCheckbox.js +0 -28
- package/dist/esm/v1/primitives/lists/ListItem/ListCheckbox.js.map +0 -1
- package/dist/types/legacy/components/atoms/Tooltip/Tooltip.d.ts +0 -13
- package/dist/types/legacy/components/molecules/Search/Search.d.ts +0 -7
- package/dist/types/legacy/hooks/useTheme.d.ts +0 -17
- package/dist/types/v1/primitives/lists/ListItem/ListCheckbox.d.ts +0 -14
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect, useRef, useLayoutEffect,
|
|
3
|
-
import
|
|
2
|
+
import { useState, useEffect, useMemo, useRef, useLayoutEffect, Fragment } from "react";
|
|
3
|
+
import { FilterChips } from "../../../../v1/primitives/display/FilterChips/FilterChips.js";
|
|
4
|
+
import { Pagination } from "../../../../v1/components/data/Pagination/Pagination.js";
|
|
4
5
|
import { createPortal } from "react-dom";
|
|
5
6
|
const DEFAULT_LABELS = {
|
|
6
7
|
total: "Total",
|
|
8
|
+
scrollRegion: "Tabela (deslizar na horizontal)",
|
|
7
9
|
results: "{count} results",
|
|
8
10
|
resizeColumn: "Drag to resize · double-click to reset",
|
|
9
11
|
export: "Export",
|
|
@@ -19,11 +21,17 @@ const DEFAULT_LABELS = {
|
|
|
19
21
|
loadingOptions: "Loading options from all pages…",
|
|
20
22
|
min: "From",
|
|
21
23
|
max: "To",
|
|
24
|
+
from: "From",
|
|
25
|
+
to: "To",
|
|
22
26
|
page: "Page {page}/{pages}",
|
|
23
27
|
prev: "Prev",
|
|
24
28
|
next: "Next",
|
|
25
29
|
sortAsc: "Sort ascending",
|
|
26
30
|
sortDesc: "Sort descending",
|
|
31
|
+
sortOldest: "Oldest first",
|
|
32
|
+
sortNewest: "Newest first",
|
|
33
|
+
sortSmallest: "Smallest first",
|
|
34
|
+
sortLargest: "Largest first",
|
|
27
35
|
groupBy: "Group by {label}",
|
|
28
36
|
ungroup: "Remove grouping by {label}",
|
|
29
37
|
clearGroups: "Clear grouping",
|
|
@@ -37,6 +45,7 @@ const Layers = ({ size = 11, className }) => /* @__PURE__ */ jsxs("svg", { xmlns
|
|
|
37
45
|
/* @__PURE__ */ jsx("path", { d: "m3 17 9 5 9-5M3 12l9 5 9-5" })
|
|
38
46
|
] });
|
|
39
47
|
const Caret = ({ size = 11, className }) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", className, children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
|
|
48
|
+
const Spinner = ({ size = 16, className }) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className: `animate-spin ${className ?? ""}`, "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
|
|
40
49
|
const EMPTY = "—";
|
|
41
50
|
const MAX_OPCOES_FILTRO = 50;
|
|
42
51
|
const DEFAULT_STICKY_WIDTH = 160;
|
|
@@ -51,19 +60,70 @@ function rawValue(row, col) {
|
|
|
51
60
|
if (typeof v === "number" || typeof v === "string") return v;
|
|
52
61
|
return String(v);
|
|
53
62
|
}
|
|
63
|
+
const normalizarRotulo = (v) => v == null || v === "" ? EMPTY : String(v);
|
|
54
64
|
function filterKey(row, col) {
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
return normalizarRotulo(rawValue(row, col));
|
|
66
|
+
}
|
|
67
|
+
function temValor(row, col) {
|
|
68
|
+
if (col.filterValues) return col.filterValues(row).some((v) => v != null && v !== "");
|
|
69
|
+
return rawValue(row, col) !== null;
|
|
70
|
+
}
|
|
71
|
+
function lerFiltrosGuardados(columns, f) {
|
|
72
|
+
return Object.fromEntries(
|
|
73
|
+
Object.entries(f).map(([k, v]) => {
|
|
74
|
+
const data = columns.find((c) => c.key === k)?.sortType === "date";
|
|
75
|
+
return [k, new Set(data ? v.map(rotuloDeData) : v)];
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
function chaveDosFiltros(f) {
|
|
80
|
+
return JSON.stringify(
|
|
81
|
+
Object.entries(f).map(([k, v]) => [k, [...v].sort()]).sort()
|
|
82
|
+
);
|
|
57
83
|
}
|
|
58
84
|
function timestampDeData(v) {
|
|
59
85
|
if (v == null || v === "") return NaN;
|
|
60
86
|
if (v instanceof Date) return v.getTime();
|
|
87
|
+
if (typeof v === "number") return Number.isFinite(v) ? v : NaN;
|
|
61
88
|
const s = String(v).trim();
|
|
62
89
|
const m = /^(\d{1,2})[/-](\d{1,2})[/-](\d{4})/.exec(s);
|
|
63
90
|
if (m) return Date.UTC(Number(m[3]), Number(m[2]) - 1, Number(m[1]));
|
|
64
91
|
const t = new Date(s).getTime();
|
|
65
92
|
return Number.isNaN(t) ? NaN : t;
|
|
66
93
|
}
|
|
94
|
+
const doisDigitos = (n) => String(n).padStart(2, "0");
|
|
95
|
+
const RX_CHAVE_DIA = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
96
|
+
function chaveDia(v) {
|
|
97
|
+
if (v == null || v === "") return null;
|
|
98
|
+
if (typeof v === "string") {
|
|
99
|
+
const s = v.trim();
|
|
100
|
+
const pt = /^(\d{1,2})[/-](\d{1,2})[/-](\d{4})/.exec(s);
|
|
101
|
+
if (pt) return `${pt[3]}-${doisDigitos(pt[2])}-${doisDigitos(pt[1])}`;
|
|
102
|
+
if (RX_CHAVE_DIA.test(s)) return s;
|
|
103
|
+
}
|
|
104
|
+
const t = timestampDeData(v);
|
|
105
|
+
if (!Number.isFinite(t)) return null;
|
|
106
|
+
const d = new Date(t);
|
|
107
|
+
return `${d.getFullYear()}-${doisDigitos(d.getMonth() + 1)}-${doisDigitos(d.getDate())}`;
|
|
108
|
+
}
|
|
109
|
+
function rotuloDeData(v) {
|
|
110
|
+
if (v == null || v === "") return EMPTY;
|
|
111
|
+
return chaveDia(v) ?? String(v);
|
|
112
|
+
}
|
|
113
|
+
function diaVisivel(v) {
|
|
114
|
+
const m = RX_CHAVE_DIA.exec(v);
|
|
115
|
+
return m ? `${m[3]}/${m[2]}/${m[1]}` : v;
|
|
116
|
+
}
|
|
117
|
+
function ordenarDias(a, b) {
|
|
118
|
+
if (a === EMPTY) return 1;
|
|
119
|
+
if (b === EMPTY) return -1;
|
|
120
|
+
const da = RX_CHAVE_DIA.test(a);
|
|
121
|
+
const db = RX_CHAVE_DIA.test(b);
|
|
122
|
+
if (da && db) return a < b ? 1 : a > b ? -1 : 0;
|
|
123
|
+
if (da) return -1;
|
|
124
|
+
if (db) return 1;
|
|
125
|
+
return COLLATOR.compare(a, b);
|
|
126
|
+
}
|
|
67
127
|
function compare(a, b, type) {
|
|
68
128
|
if (a == null && b == null) return 0;
|
|
69
129
|
if (a == null) return 1;
|
|
@@ -122,6 +182,7 @@ function DataTable({
|
|
|
122
182
|
onDataNeeded,
|
|
123
183
|
isAllDataLoading,
|
|
124
184
|
alwaysClient,
|
|
185
|
+
totalCount,
|
|
125
186
|
onClientModeChange,
|
|
126
187
|
rowKey,
|
|
127
188
|
onRowClick,
|
|
@@ -135,6 +196,8 @@ function DataTable({
|
|
|
135
196
|
pageSizeOptions,
|
|
136
197
|
selectable,
|
|
137
198
|
onSelectionChange,
|
|
199
|
+
isRowSelectable,
|
|
200
|
+
initialSelectedKeys,
|
|
138
201
|
clearSelectionTrigger,
|
|
139
202
|
storageKey,
|
|
140
203
|
defaultMaxColumnWidth = 360,
|
|
@@ -151,7 +214,12 @@ function DataTable({
|
|
|
151
214
|
emptyIcon,
|
|
152
215
|
labels,
|
|
153
216
|
totalRow = false,
|
|
154
|
-
defaultGroupBy
|
|
217
|
+
defaultGroupBy,
|
|
218
|
+
groupBy,
|
|
219
|
+
onGroupByChange,
|
|
220
|
+
onSortChange,
|
|
221
|
+
onColumnFiltersChange,
|
|
222
|
+
scrollAffordance = false
|
|
155
223
|
}) {
|
|
156
224
|
const L = { ...DEFAULT_LABELS, ...labels };
|
|
157
225
|
const [larguras, setLarguras] = useState(() => {
|
|
@@ -210,8 +278,7 @@ function DataTable({
|
|
|
210
278
|
try {
|
|
211
279
|
const raw = sessionStorage.getItem(`dt_filters_${storageKey}`);
|
|
212
280
|
if (!raw) return {};
|
|
213
|
-
|
|
214
|
-
return Object.fromEntries(Object.entries(parsed).map(([k, v]) => [k, new Set(v)]));
|
|
281
|
+
return lerFiltrosGuardados(columns, JSON.parse(raw));
|
|
215
282
|
} catch {
|
|
216
283
|
return {};
|
|
217
284
|
}
|
|
@@ -225,17 +292,27 @@ function DataTable({
|
|
|
225
292
|
return {};
|
|
226
293
|
}
|
|
227
294
|
});
|
|
228
|
-
const [
|
|
295
|
+
const [groupByInterno, setGroupByInterno] = useState(
|
|
229
296
|
() => (lerSessao("group") ?? defaultGroupBy ?? []).filter((k) => columns.some((c) => c.key === k))
|
|
230
297
|
);
|
|
298
|
+
const grupoControlado = groupBy !== void 0;
|
|
299
|
+
const chaveGrupoExterno = groupBy?.join("\0");
|
|
300
|
+
const chaveColunas = columns.map((c) => c.key).join("\0");
|
|
301
|
+
const groupByKeys = useMemo(
|
|
302
|
+
() => grupoControlado ? groupBy.filter((k) => columns.some((c) => c.key === k)) : groupByInterno,
|
|
303
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
304
|
+
[grupoControlado, chaveGrupoExterno, groupByInterno, chaveColunas]
|
|
305
|
+
);
|
|
231
306
|
const [collapsedGroups, setCollapsedGroups] = useState(/* @__PURE__ */ new Set());
|
|
232
|
-
const
|
|
307
|
+
const selecaoInicial = initialSelectedKeys ? Array.from(initialSelectedKeys, String) : null;
|
|
308
|
+
const [selectedKeys, setSelectedKeys] = useState(() => new Set(selecaoInicial ?? []));
|
|
233
309
|
const [openFilter, setOpenFilter] = useState(null);
|
|
234
310
|
const [filterSearch, setFilterSearch] = useState("");
|
|
235
311
|
const filterRefs = useRef(/* @__PURE__ */ new Map());
|
|
236
312
|
const popupRef = useRef(null);
|
|
237
313
|
const [popupPos, setPopupPos] = useState(null);
|
|
238
314
|
const isGrouped = groupByKeys.length > 0;
|
|
315
|
+
const funilAberto = openFilter ? columns.find((c) => c.key === openFilter || c.extraFilters?.some((f) => f.key === openFilter))?.key ?? openFilter : null;
|
|
239
316
|
useEffect(() => {
|
|
240
317
|
if (!storageKey) return;
|
|
241
318
|
const serializavel = Object.fromEntries(Object.entries(columnFilters).map(([k, v]) => [k, Array.from(v)]));
|
|
@@ -243,17 +320,17 @@ function DataTable({
|
|
|
243
320
|
sessionStorage.setItem(`dt_filters_${storageKey}`, JSON.stringify(serializavel));
|
|
244
321
|
sessionStorage.setItem(`dt_ranges_${storageKey}`, JSON.stringify(rangeFilters));
|
|
245
322
|
sessionStorage.setItem(`dt_sort_${storageKey}`, JSON.stringify(sort));
|
|
246
|
-
sessionStorage.setItem(`dt_group_${storageKey}`, JSON.stringify(groupByKeys));
|
|
323
|
+
if (!grupoControlado) sessionStorage.setItem(`dt_group_${storageKey}`, JSON.stringify(groupByKeys));
|
|
247
324
|
} catch {
|
|
248
325
|
}
|
|
249
|
-
}, [columnFilters, rangeFilters, sort, groupByKeys, storageKey]);
|
|
326
|
+
}, [columnFilters, rangeFilters, sort, groupByKeys, grupoControlado, storageKey]);
|
|
250
327
|
useLayoutEffect(() => {
|
|
251
|
-
if (!
|
|
328
|
+
if (!funilAberto) {
|
|
252
329
|
setPopupPos(null);
|
|
253
330
|
return;
|
|
254
331
|
}
|
|
255
332
|
const recalcular = () => {
|
|
256
|
-
const el = filterRefs.current.get(
|
|
333
|
+
const el = filterRefs.current.get(funilAberto);
|
|
257
334
|
if (!el) return;
|
|
258
335
|
const r = el.getBoundingClientRect();
|
|
259
336
|
const largura = Math.min(288, window.innerWidth * 0.8);
|
|
@@ -267,19 +344,19 @@ function DataTable({
|
|
|
267
344
|
window.removeEventListener("scroll", recalcular, true);
|
|
268
345
|
window.removeEventListener("resize", recalcular);
|
|
269
346
|
};
|
|
270
|
-
}, [
|
|
347
|
+
}, [funilAberto]);
|
|
271
348
|
useEffect(() => {
|
|
272
349
|
const onDown = (e) => {
|
|
273
|
-
if (!
|
|
350
|
+
if (!funilAberto) return;
|
|
274
351
|
const alvo = e.target;
|
|
275
|
-
const botao = filterRefs.current.get(
|
|
352
|
+
const botao = filterRefs.current.get(funilAberto);
|
|
276
353
|
if (botao?.contains(alvo) || popupRef.current?.contains(alvo)) return;
|
|
277
354
|
setOpenFilter(null);
|
|
278
355
|
setFilterSearch("");
|
|
279
356
|
};
|
|
280
357
|
document.addEventListener("mousedown", onDown);
|
|
281
358
|
return () => document.removeEventListener("mousedown", onDown);
|
|
282
|
-
}, [
|
|
359
|
+
}, [funilAberto]);
|
|
283
360
|
const resolverValor = (key) => {
|
|
284
361
|
const col = columns.find((c) => c.key === key);
|
|
285
362
|
if (col) return (row) => rawValue(row, col);
|
|
@@ -289,9 +366,34 @@ function DataTable({
|
|
|
289
366
|
}
|
|
290
367
|
return void 0;
|
|
291
368
|
};
|
|
292
|
-
const rotuloDe = (fn, row) =>
|
|
293
|
-
|
|
294
|
-
|
|
369
|
+
const rotuloDe = (fn, row) => normalizarRotulo(fn(row));
|
|
370
|
+
const eColunaData = (key) => columns.find((c) => c.key === key)?.sortType === "date";
|
|
371
|
+
const resolverRotulos = (key) => {
|
|
372
|
+
const col = columns.find((c) => c.key === key);
|
|
373
|
+
const normalizar = col?.sortType === "date" ? rotuloDeData : (v) => normalizarRotulo(v);
|
|
374
|
+
if (col?.filterValues) {
|
|
375
|
+
const fv = col.filterValues;
|
|
376
|
+
return (row) => {
|
|
377
|
+
const vs = Array.from(new Set(fv(row).map(normalizar)));
|
|
378
|
+
return vs.length > 0 ? vs : [EMPTY];
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
if (col?.sortType === "date") {
|
|
382
|
+
const ler = col.value ?? ((row) => row[col.key]);
|
|
383
|
+
return (row) => [rotuloDeData(ler(row))];
|
|
384
|
+
}
|
|
385
|
+
const fn = resolverValor(key);
|
|
386
|
+
return fn ? (row) => [rotuloDe(fn, row)] : void 0;
|
|
387
|
+
};
|
|
388
|
+
const rotuloVisivel = (key, v) => eColunaData(key) ? diaVisivel(v) : v;
|
|
389
|
+
const passaFiltro = (key, sel) => {
|
|
390
|
+
const col = columns.find((c) => c.key === key);
|
|
391
|
+
if (col?.filterValues || col?.sortType === "date") {
|
|
392
|
+
const rotulos = resolverRotulos(key);
|
|
393
|
+
return (row) => rotulos(row).some((v) => sel.has(v));
|
|
394
|
+
}
|
|
395
|
+
const fn = resolverValor(key);
|
|
396
|
+
return fn ? (row) => sel.has(rotuloDe(fn, row)) : void 0;
|
|
295
397
|
};
|
|
296
398
|
const modoExcel = filterMode === "excel";
|
|
297
399
|
const activeFilters = useMemo(
|
|
@@ -315,25 +417,51 @@ function DataTable({
|
|
|
315
417
|
if (clearSelectionTrigger === void 0) return;
|
|
316
418
|
setSelectedKeys(/* @__PURE__ */ new Set());
|
|
317
419
|
}, [clearSelectionTrigger]);
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
);
|
|
420
|
+
const chaveSelecaoInicial = selecaoInicial ? JSON.stringify([...selecaoInicial].sort()) : null;
|
|
421
|
+
const selecaoInicialAnterior = useRef(chaveSelecaoInicial);
|
|
321
422
|
useEffect(() => {
|
|
423
|
+
if (chaveSelecaoInicial === selecaoInicialAnterior.current) return;
|
|
424
|
+
selecaoInicialAnterior.current = chaveSelecaoInicial;
|
|
425
|
+
if (chaveSelecaoInicial !== null) setSelectedKeys(new Set(JSON.parse(chaveSelecaoInicial)));
|
|
426
|
+
}, [chaveSelecaoInicial]);
|
|
427
|
+
const mudarFiltrosCol = (proximo) => {
|
|
428
|
+
const next = proximo(columnFilters);
|
|
429
|
+
if (chaveDosFiltros(next) === chaveDosFiltros(columnFilters)) return;
|
|
430
|
+
setColumnFilters(next);
|
|
322
431
|
if (!selectable) return;
|
|
323
432
|
setSelectedKeys(/* @__PURE__ */ new Set());
|
|
324
433
|
onSelectionChange?.(/* @__PURE__ */ new Set());
|
|
325
|
-
}
|
|
434
|
+
};
|
|
435
|
+
const avisarOrdenacao = useRef(onSortChange);
|
|
436
|
+
avisarOrdenacao.current = onSortChange;
|
|
437
|
+
const ordenacaoAvisada = useRef("null");
|
|
438
|
+
useEffect(() => {
|
|
439
|
+
const s = sort ? { key: sort.key, dir: sort.dir === 1 ? "asc" : "desc" } : null;
|
|
440
|
+
const chave = JSON.stringify(s);
|
|
441
|
+
if (chave === ordenacaoAvisada.current) return;
|
|
442
|
+
ordenacaoAvisada.current = chave;
|
|
443
|
+
avisarOrdenacao.current?.(s);
|
|
444
|
+
}, [sort]);
|
|
445
|
+
const avisarFiltros = useRef(onColumnFiltersChange);
|
|
446
|
+
avisarFiltros.current = onColumnFiltersChange;
|
|
447
|
+
const filtrosAvisados = useRef(chaveDosFiltros({}));
|
|
448
|
+
const chaveFiltrosAtivos = chaveDosFiltros(Object.fromEntries(activeFilters));
|
|
449
|
+
useEffect(() => {
|
|
450
|
+
if (chaveFiltrosAtivos === filtrosAvisados.current) return;
|
|
451
|
+
filtrosAvisados.current = chaveFiltrosAtivos;
|
|
452
|
+
avisarFiltros.current?.(Object.fromEntries(JSON.parse(chaveFiltrosAtivos)));
|
|
453
|
+
}, [chaveFiltrosAtivos]);
|
|
326
454
|
const cruzFiltros = modoExcel ? SEM_CRUZAMENTO : activeFilters;
|
|
327
455
|
const cruzRanges = modoExcel ? SEM_CRUZAMENTO : activeRanges;
|
|
328
456
|
const distinctValues = (key) => {
|
|
329
|
-
const
|
|
330
|
-
if (!
|
|
457
|
+
const rotulosFn = resolverRotulos(key);
|
|
458
|
+
if (!rotulosFn) return [];
|
|
331
459
|
let fonte = allData ?? data;
|
|
332
460
|
for (const [outraKey, escolhidos] of cruzFiltros) {
|
|
333
461
|
if (outraKey === key) continue;
|
|
334
|
-
const
|
|
335
|
-
if (!
|
|
336
|
-
fonte = fonte.filter(
|
|
462
|
+
const passa = passaFiltro(outraKey, escolhidos);
|
|
463
|
+
if (!passa) continue;
|
|
464
|
+
fonte = fonte.filter(passa);
|
|
337
465
|
}
|
|
338
466
|
for (const [outraKey, r] of cruzRanges) {
|
|
339
467
|
if (outraKey === key) continue;
|
|
@@ -348,14 +476,18 @@ function DataTable({
|
|
|
348
476
|
});
|
|
349
477
|
}
|
|
350
478
|
const set = /* @__PURE__ */ new Set();
|
|
351
|
-
fonte.forEach((row) => set.add(
|
|
352
|
-
return Array.from(set).sort(ordenarRotulos);
|
|
479
|
+
fonte.forEach((row) => rotulosFn(row).forEach((v) => set.add(v)));
|
|
480
|
+
return Array.from(set).sort(eColunaData(key) ? ordenarDias : ordenarRotulos);
|
|
353
481
|
};
|
|
354
482
|
const openFilterOptions = useMemo(() => {
|
|
355
483
|
if (!openFilter) return [];
|
|
356
484
|
return distinctValues(openFilter);
|
|
357
485
|
}, [openFilter, data, allData, columns, cruzFiltros, cruzRanges]);
|
|
358
|
-
const openFilterOptionsLower = useMemo(
|
|
486
|
+
const openFilterOptionsLower = useMemo(
|
|
487
|
+
() => openFilterOptions.map((v) => (openFilter ? rotuloVisivel(openFilter, v) : v).toLowerCase()),
|
|
488
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
489
|
+
[openFilterOptions]
|
|
490
|
+
);
|
|
359
491
|
const opcoesVisiveis = useMemo(() => {
|
|
360
492
|
const q = filterSearch.toLowerCase();
|
|
361
493
|
const corresponde = q ? modoExcel ? pesquisaCuringa(q) : (v) => v.includes(q) : null;
|
|
@@ -370,11 +502,9 @@ function DataTable({
|
|
|
370
502
|
}, [openFilterOptions, openFilterOptionsLower, filterSearch, modoExcel]);
|
|
371
503
|
const filtrar = (rows) => {
|
|
372
504
|
if (activeFilters.length === 0 && activeRanges.length === 0) return rows;
|
|
505
|
+
const predicados = activeFilters.flatMap(([key, sel]) => passaFiltro(key, sel) ?? []);
|
|
373
506
|
return rows.filter(
|
|
374
|
-
(row) =>
|
|
375
|
-
const fn = resolverValor(key);
|
|
376
|
-
return fn ? sel.has(rotuloDe(fn, row)) : true;
|
|
377
|
-
}) && activeRanges.every(([key, r]) => {
|
|
507
|
+
(row) => predicados.every((passa) => passa(row)) && activeRanges.every(([key, r]) => {
|
|
378
508
|
const col = columns.find((c) => c.key === key);
|
|
379
509
|
if (!col) return true;
|
|
380
510
|
const n = valorParaIntervalo(row, col);
|
|
@@ -406,19 +536,17 @@ function DataTable({
|
|
|
406
536
|
useEffect(() => {
|
|
407
537
|
avisarVisiveis.current?.(sorted);
|
|
408
538
|
}, [sorted]);
|
|
409
|
-
const
|
|
410
|
-
if (!
|
|
411
|
-
|
|
412
|
-
setCollapsedGroups(/* @__PURE__ */ new Set());
|
|
413
|
-
};
|
|
414
|
-
const removerGrupo = (key) => {
|
|
415
|
-
setGroupByKeys((prev) => prev.filter((k) => k !== key));
|
|
539
|
+
const mudarGrupos = (proximo) => {
|
|
540
|
+
if (!grupoControlado) setGroupByInterno(proximo);
|
|
541
|
+
onGroupByChange?.(proximo);
|
|
416
542
|
setCollapsedGroups(/* @__PURE__ */ new Set());
|
|
417
543
|
};
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
544
|
+
const alternarGrupo = (key) => {
|
|
545
|
+
if (!allData) onDataNeeded?.();
|
|
546
|
+
mudarGrupos(groupByKeys.includes(key) ? groupByKeys.filter((k) => k !== key) : [...groupByKeys, key]);
|
|
421
547
|
};
|
|
548
|
+
const removerGrupo = (key) => mudarGrupos(groupByKeys.filter((k) => k !== key));
|
|
549
|
+
const limparGrupos = () => mudarGrupos([]);
|
|
422
550
|
const alternarColapso = (path) => setCollapsedGroups((prev) => {
|
|
423
551
|
const n = new Set(prev);
|
|
424
552
|
if (n.has(path)) n.delete(path);
|
|
@@ -450,12 +578,34 @@ function DataTable({
|
|
|
450
578
|
[sorted, groupByKeys, isGrouped, columns]
|
|
451
579
|
);
|
|
452
580
|
const [page, setPage] = useState(1);
|
|
453
|
-
const
|
|
454
|
-
|
|
581
|
+
const chavePageSize = storageKey ? `dt_pagesize_${storageKey}` : null;
|
|
582
|
+
const [pageSizeAtual, setPageSizeAtual] = useState(() => {
|
|
583
|
+
if (!pageSize || !chavePageSize) return pageSize;
|
|
584
|
+
try {
|
|
585
|
+
const guardado = Number(sessionStorage.getItem(chavePageSize));
|
|
586
|
+
return Number.isFinite(guardado) && guardado > 0 ? guardado : pageSize;
|
|
587
|
+
} catch {
|
|
588
|
+
return pageSize;
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
const pageSizeProp = useRef(pageSize);
|
|
592
|
+
useEffect(() => {
|
|
593
|
+
if (pageSizeProp.current === pageSize) return;
|
|
594
|
+
pageSizeProp.current = pageSize;
|
|
595
|
+
setPageSizeAtual(pageSize);
|
|
596
|
+
}, [pageSize]);
|
|
597
|
+
const escolherPageSize = (n) => {
|
|
598
|
+
setPageSizeAtual(n);
|
|
599
|
+
if (!chavePageSize) return;
|
|
600
|
+
try {
|
|
601
|
+
sessionStorage.setItem(chavePageSize, String(n));
|
|
602
|
+
} catch {
|
|
603
|
+
}
|
|
604
|
+
};
|
|
455
605
|
useEffect(() => {
|
|
456
606
|
setPage(1);
|
|
457
|
-
}, [columnFilters, rangeFilters, sort, groupByKeys, pageSizeAtual]);
|
|
458
|
-
const paginando = !!pageSizeAtual && !isGrouped;
|
|
607
|
+
}, [columnFilters, rangeFilters, sort, groupByKeys, pageSizeAtual, isClientMode]);
|
|
608
|
+
const paginando = !!pageSizeAtual && !isGrouped && (!allData || isClientMode);
|
|
459
609
|
const totalPages = paginando ? Math.max(1, Math.ceil(sorted.length / pageSizeAtual)) : 1;
|
|
460
610
|
const currentPage = Math.min(page, totalPages);
|
|
461
611
|
const pageData = paginando ? sorted.slice((currentPage - 1) * pageSizeAtual, currentPage * pageSizeAtual) : sorted;
|
|
@@ -465,10 +615,11 @@ function DataTable({
|
|
|
465
615
|
sorted.forEach((r, i) => m.set(r, i));
|
|
466
616
|
return m;
|
|
467
617
|
}, [sorted]);
|
|
618
|
+
const podeSelecionar = (row) => !isRowSelectable || isRowSelectable(row);
|
|
468
619
|
const visibleKeys = useMemo(
|
|
469
|
-
() => pageData.
|
|
620
|
+
() => pageData.flatMap((row, i) => podeSelecionar(row) ? [chaveDe(row, i)] : []),
|
|
470
621
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
471
|
-
[pageData, rowKey]
|
|
622
|
+
[pageData, rowKey, isRowSelectable]
|
|
472
623
|
);
|
|
473
624
|
const alternarLinha = (key) => setSelectedKeys((prev) => {
|
|
474
625
|
const next = new Set(prev);
|
|
@@ -502,11 +653,10 @@ function DataTable({
|
|
|
502
653
|
groupBy: groupByKeys
|
|
503
654
|
}),
|
|
504
655
|
repor: (e) => {
|
|
505
|
-
setColumnFilters(
|
|
656
|
+
setColumnFilters(lerFiltrosGuardados(columns, e?.columnFilters ?? {}));
|
|
506
657
|
setRangeFilters(e?.rangeFilters ?? {});
|
|
507
658
|
setSort(e?.sortKey ? { key: e.sortKey, dir: e.sortDir === "desc" ? -1 : 1 } : null);
|
|
508
|
-
|
|
509
|
-
setCollapsedGroups(/* @__PURE__ */ new Set());
|
|
659
|
+
mudarGrupos(e?.groupBy ?? []);
|
|
510
660
|
const precisaTudo = !!e?.sortKey || !!e?.groupBy?.length || Object.keys(e?.columnFilters ?? {}).length > 0 || Object.keys(e?.rangeFilters ?? {}).length > 0;
|
|
511
661
|
if (precisaTudo && !allData) onDataNeeded?.();
|
|
512
662
|
}
|
|
@@ -517,7 +667,7 @@ function DataTable({
|
|
|
517
667
|
setSort((s) => s?.key === key ? s.dir === 1 ? { key, dir: -1 } : null : { key, dir: 1 });
|
|
518
668
|
};
|
|
519
669
|
const selecaoDaColuna = (key) => new Set(columnFilters[key] ?? (modoExcel ? openFilterOptions : []));
|
|
520
|
-
const aplicarSelecao = (key, sel) =>
|
|
670
|
+
const aplicarSelecao = (key, sel) => mudarFiltrosCol((prev) => {
|
|
521
671
|
const proximo = { ...prev };
|
|
522
672
|
if (modoExcel && sel.size === openFilterOptions.length) delete proximo[key];
|
|
523
673
|
else proximo[key] = sel;
|
|
@@ -553,7 +703,7 @@ function DataTable({
|
|
|
553
703
|
});
|
|
554
704
|
};
|
|
555
705
|
const clearColumnFilter = (key) => {
|
|
556
|
-
|
|
706
|
+
mudarFiltrosCol((prev) => {
|
|
557
707
|
const n = { ...prev };
|
|
558
708
|
delete n[key];
|
|
559
709
|
return n;
|
|
@@ -565,7 +715,7 @@ function DataTable({
|
|
|
565
715
|
});
|
|
566
716
|
};
|
|
567
717
|
const clearAllFilters = () => {
|
|
568
|
-
|
|
718
|
+
mudarFiltrosCol(() => ({}));
|
|
569
719
|
setRangeFilters({});
|
|
570
720
|
};
|
|
571
721
|
const temIntervalo = (key) => {
|
|
@@ -613,26 +763,41 @@ function DataTable({
|
|
|
613
763
|
return void 0;
|
|
614
764
|
};
|
|
615
765
|
const nColunas = columns.length + (selectable ? 1 : 0);
|
|
616
|
-
const
|
|
766
|
+
const totalResultados = totalCount != null && !isClientMode && !hasActiveFilters ? totalCount : sorted.length;
|
|
767
|
+
const aEsperarDataset = !allData && (!!isAllDataLoading || !!onDataNeeded) && (hasActiveFilters || !!sort || isGrouped);
|
|
617
768
|
const linhasBase = allData ?? data;
|
|
618
769
|
const semDados = useMemo(
|
|
619
|
-
() => new Set(columns.filter((c) => !linhasBase.some((r) =>
|
|
770
|
+
() => new Set(columns.filter((c) => !linhasBase.some((r) => temValor(r, c))).map((c) => c.key)),
|
|
620
771
|
[columns, linhasBase]
|
|
621
772
|
);
|
|
622
773
|
const filtravel = (c) => c.filterable ?? !semDados.has(c.key);
|
|
623
774
|
const agrupavel = (c) => c.groupable ?? (!semDados.has(c.key) && !c.groupAggregate && (!c.sortType || c.sortType === "text"));
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
775
|
+
const rolarComTeclado = (e) => {
|
|
776
|
+
if (e.target !== e.currentTarget) return;
|
|
777
|
+
const el = e.currentTarget;
|
|
778
|
+
const passo = Math.max(40, Math.round(el.clientWidth * 0.2));
|
|
779
|
+
if (e.key === "ArrowRight") el.scrollLeft += passo;
|
|
780
|
+
else if (e.key === "ArrowLeft") el.scrollLeft -= passo;
|
|
781
|
+
else if (e.key === "Home") el.scrollLeft = 0;
|
|
782
|
+
else if (e.key === "End") el.scrollLeft = el.scrollWidth;
|
|
783
|
+
else return;
|
|
784
|
+
e.preventDefault();
|
|
785
|
+
};
|
|
627
786
|
if (isError) {
|
|
628
787
|
return /* @__PURE__ */ jsx("div", { className: "py-16 text-center text-sm font-bold uppercase tracking-widest text-red-400", children: L.error });
|
|
629
788
|
}
|
|
630
|
-
const renderPopup = (
|
|
789
|
+
const renderPopup = (coluna, key, listas) => {
|
|
790
|
+
const col = key === coluna.key ? coluna : void 0;
|
|
631
791
|
const { opts, total: totalOpcoes } = opcoesVisiveis;
|
|
632
792
|
const sel = columnFilters[key];
|
|
633
793
|
const isFiltered = temFiltro(key);
|
|
634
794
|
const podeOrdenar = !!sortFromFilter && !!col && col.sortable !== false;
|
|
635
|
-
const
|
|
795
|
+
const eData = col?.sortType === "date";
|
|
796
|
+
const temRange = !!col && (col.sortType === "number" || eData);
|
|
797
|
+
const [rotuloAsc, rotuloDesc] = eData ? [L.sortOldest, L.sortNewest] : col?.sortType === "number" ? [L.sortSmallest, L.sortLargest] : [L.sortAsc, L.sortDesc];
|
|
798
|
+
const [rotuloMin, rotuloMax] = eData ? [L.from, L.to] : [L.min, L.max];
|
|
799
|
+
const intervalo = rangeFilters[key];
|
|
800
|
+
const valorCampo = (n, campo) => n == null ? "" : eData ? new Date(campo === "max" ? n - 86399999 : n).toISOString().slice(0, 10) : String(n);
|
|
636
801
|
return createPortal(
|
|
637
802
|
/* @__PURE__ */ jsxs(
|
|
638
803
|
"div",
|
|
@@ -641,7 +806,28 @@ function DataTable({
|
|
|
641
806
|
style: { position: "fixed", top: popupPos.top, left: popupPos.left },
|
|
642
807
|
className: "z-[100] w-72 max-w-[80vw] bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 shadow-2xl rounded-xl overflow-hidden",
|
|
643
808
|
children: [
|
|
644
|
-
|
|
809
|
+
listas.length > 1 && // Seletor da lista a filtrar: a coluna e cada filtro extra partilham o mesmo funil.
|
|
810
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 pt-2 pb-2 border-b border-slate-100 dark:border-slate-800", children: /* @__PURE__ */ jsx("div", { role: "group", "aria-label": coluna.label, className: "flex flex-wrap gap-0.5 p-0.5 rounded-lg bg-slate-100 dark:bg-slate-800", children: listas.map((l) => {
|
|
811
|
+
const ativa = l.key === key;
|
|
812
|
+
return /* @__PURE__ */ jsxs(
|
|
813
|
+
"button",
|
|
814
|
+
{
|
|
815
|
+
type: "button",
|
|
816
|
+
"aria-pressed": ativa,
|
|
817
|
+
onClick: () => {
|
|
818
|
+
if (ativa) return;
|
|
819
|
+
setOpenFilter(l.key);
|
|
820
|
+
setFilterSearch("");
|
|
821
|
+
},
|
|
822
|
+
className: `appearance-none border-0 cursor-pointer flex-1 min-w-0 inline-flex items-center justify-center gap-1 px-2 py-1 rounded-md text-[10px] font-black uppercase tracking-wider truncate transition-colors ${ativa ? "bg-white dark:bg-slate-900 text-proef-blue dark:text-proef-turquoise shadow-sm" : "bg-transparent text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
|
|
823
|
+
children: [
|
|
824
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: l.label }),
|
|
825
|
+
temFiltro(l.key) && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "w-1.5 h-1.5 rounded-full bg-proef-turquoise shrink-0" })
|
|
826
|
+
]
|
|
827
|
+
},
|
|
828
|
+
l.key
|
|
829
|
+
);
|
|
830
|
+
}) }) }),
|
|
645
831
|
!allData && isAllDataLoading && // As opções à vista ainda são só as de `data`. Dizê-lo é melhor do que deixar
|
|
646
832
|
// escolher de uma lista incompleta.
|
|
647
833
|
/* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 bg-amber-50 dark:bg-amber-500/10 border-b border-amber-100 dark:border-amber-500/20 text-[10px] text-amber-700 dark:text-amber-300", children: L.loadingOptions }),
|
|
@@ -656,7 +842,7 @@ function DataTable({
|
|
|
656
842
|
className: `appearance-none bg-transparent border-0 cursor-pointer w-full flex items-center gap-2 px-2.5 py-1.5 text-[11px] font-semibold text-left hover:bg-slate-50 dark:hover:bg-slate-800 ${sort?.key === key && sort.dir === 1 ? "text-proef-blue dark:text-proef-turquoise bg-slate-50 dark:bg-slate-800" : "text-slate-600 dark:text-slate-300"}`,
|
|
657
843
|
children: [
|
|
658
844
|
"▲ ",
|
|
659
|
-
|
|
845
|
+
rotuloAsc
|
|
660
846
|
]
|
|
661
847
|
}
|
|
662
848
|
),
|
|
@@ -670,7 +856,7 @@ function DataTable({
|
|
|
670
856
|
className: `appearance-none bg-transparent border-0 cursor-pointer w-full flex items-center gap-2 px-2.5 py-1.5 text-[11px] font-semibold text-left hover:bg-slate-50 dark:hover:bg-slate-800 ${sort?.key === key && sort.dir === -1 ? "text-proef-blue dark:text-proef-turquoise bg-slate-50 dark:bg-slate-800" : "text-slate-600 dark:text-slate-300"}`,
|
|
671
857
|
children: [
|
|
672
858
|
"▼ ",
|
|
673
|
-
|
|
859
|
+
rotuloDesc
|
|
674
860
|
]
|
|
675
861
|
}
|
|
676
862
|
)
|
|
@@ -682,24 +868,28 @@ function DataTable({
|
|
|
682
868
|
/* @__PURE__ */ jsx(
|
|
683
869
|
"input",
|
|
684
870
|
{
|
|
685
|
-
type:
|
|
686
|
-
defaultValue: "",
|
|
871
|
+
type: eData ? "date" : "number",
|
|
872
|
+
defaultValue: valorCampo(intervalo?.min, "min"),
|
|
687
873
|
onChange: (e) => setRange(key, "min", e.target.value, col.sortType),
|
|
688
|
-
placeholder:
|
|
689
|
-
title:
|
|
874
|
+
placeholder: rotuloMin,
|
|
875
|
+
title: rotuloMin,
|
|
876
|
+
"aria-label": rotuloMin,
|
|
690
877
|
className: "w-1/2 bg-slate-50 dark:bg-slate-800 dark:text-slate-100 dark:[color-scheme:dark] border border-slate-200 dark:border-slate-700 rounded-lg px-2 py-1.5 text-xs outline-none focus:border-proef-blue dark:focus:border-proef-turquoise"
|
|
691
|
-
}
|
|
878
|
+
},
|
|
879
|
+
`${key}-min`
|
|
692
880
|
),
|
|
693
881
|
/* @__PURE__ */ jsx(
|
|
694
882
|
"input",
|
|
695
883
|
{
|
|
696
|
-
type:
|
|
697
|
-
defaultValue: "",
|
|
884
|
+
type: eData ? "date" : "number",
|
|
885
|
+
defaultValue: valorCampo(intervalo?.max, "max"),
|
|
698
886
|
onChange: (e) => setRange(key, "max", e.target.value, col.sortType),
|
|
699
|
-
placeholder:
|
|
700
|
-
title:
|
|
887
|
+
placeholder: rotuloMax,
|
|
888
|
+
title: rotuloMax,
|
|
889
|
+
"aria-label": rotuloMax,
|
|
701
890
|
className: "w-1/2 bg-slate-50 dark:bg-slate-800 dark:text-slate-100 dark:[color-scheme:dark] border border-slate-200 dark:border-slate-700 rounded-lg px-2 py-1.5 text-xs outline-none focus:border-proef-blue dark:focus:border-proef-turquoise"
|
|
702
|
-
}
|
|
891
|
+
},
|
|
892
|
+
`${key}-max`
|
|
703
893
|
)
|
|
704
894
|
] }),
|
|
705
895
|
/* @__PURE__ */ jsx(
|
|
@@ -753,7 +943,7 @@ function DataTable({
|
|
|
753
943
|
children: checked && /* @__PURE__ */ jsx("span", { className: "text-[9px] leading-none", children: "✓" })
|
|
754
944
|
}
|
|
755
945
|
),
|
|
756
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-slate-700 dark:text-slate-200 font-normal break-words", children: v })
|
|
946
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-slate-700 dark:text-slate-200 font-normal break-words", children: rotuloVisivel(key, v) })
|
|
757
947
|
]
|
|
758
948
|
},
|
|
759
949
|
v
|
|
@@ -776,16 +966,18 @@ function DataTable({
|
|
|
776
966
|
document.body
|
|
777
967
|
);
|
|
778
968
|
};
|
|
779
|
-
const botaoFunil = (
|
|
780
|
-
const
|
|
781
|
-
|
|
969
|
+
const botaoFunil = (c) => {
|
|
970
|
+
const listas = [...filtravel(c) ? [{ key: c.key, label: c.label }] : [], ...(c.extraFilters ?? []).map((f) => ({ key: f.key, label: f.label }))];
|
|
971
|
+
if (listas.length === 0) return null;
|
|
972
|
+
const isOpen = funilAberto === c.key;
|
|
973
|
+
const isFiltered = listas.some((l) => temFiltro(l.key));
|
|
782
974
|
return /* @__PURE__ */ jsxs(
|
|
783
975
|
"div",
|
|
784
976
|
{
|
|
785
977
|
className: "relative",
|
|
786
978
|
ref: (el) => {
|
|
787
|
-
if (el) filterRefs.current.set(key, el);
|
|
788
|
-
else filterRefs.current.delete(key);
|
|
979
|
+
if (el) filterRefs.current.set(c.key, el);
|
|
980
|
+
else filterRefs.current.delete(c.key);
|
|
789
981
|
},
|
|
790
982
|
children: [
|
|
791
983
|
/* @__PURE__ */ jsx(
|
|
@@ -793,23 +985,26 @@ function DataTable({
|
|
|
793
985
|
{
|
|
794
986
|
onClick: () => {
|
|
795
987
|
if (!isOpen && !allData) onDataNeeded?.();
|
|
796
|
-
setOpenFilter(isOpen ? null : key);
|
|
988
|
+
setOpenFilter(isOpen ? null : listas[0].key);
|
|
797
989
|
setFilterSearch("");
|
|
798
990
|
},
|
|
799
|
-
className: `appearance-none border-0 bg-transparent cursor-pointer p-0.5 transition-colors ${
|
|
800
|
-
title:
|
|
801
|
-
|
|
991
|
+
className: `appearance-none border-0 bg-transparent cursor-pointer p-0.5 transition-colors ${isFiltered || isOpen ? "text-proef-turquoise" : "text-slate-300 dark:text-slate-600 hover:text-slate-500 dark:hover:text-slate-300"}`,
|
|
992
|
+
title: c.label,
|
|
993
|
+
"aria-label": c.label,
|
|
994
|
+
"aria-expanded": isOpen,
|
|
995
|
+
children: /* @__PURE__ */ jsx(Funnel, { size: 11, className: isFiltered ? "fill-current" : "" })
|
|
802
996
|
}
|
|
803
997
|
),
|
|
804
|
-
isOpen && popupPos && renderPopup(
|
|
998
|
+
isOpen && popupPos && openFilter && renderPopup(c, openFilter, listas)
|
|
805
999
|
]
|
|
806
1000
|
},
|
|
807
|
-
key
|
|
1001
|
+
c.key
|
|
808
1002
|
);
|
|
809
1003
|
};
|
|
810
1004
|
const renderLinha = (row, i) => {
|
|
811
1005
|
const k = chaveDe(row, i);
|
|
812
1006
|
const marcada = selectable && selectedKeys.has(k);
|
|
1007
|
+
const selecionavel = !!selectable && podeSelecionar(row);
|
|
813
1008
|
return /* @__PURE__ */ jsxs(
|
|
814
1009
|
"tr",
|
|
815
1010
|
{
|
|
@@ -823,12 +1018,15 @@ function DataTable({
|
|
|
823
1018
|
className: "px-3 py-2.5 border-b border-slate-100 dark:border-slate-800 w-10",
|
|
824
1019
|
onClick: (e) => {
|
|
825
1020
|
e.stopPropagation();
|
|
826
|
-
alternarLinha(k);
|
|
1021
|
+
if (selecionavel) alternarLinha(k);
|
|
827
1022
|
},
|
|
828
1023
|
children: /* @__PURE__ */ jsx(
|
|
829
1024
|
"span",
|
|
830
1025
|
{
|
|
831
|
-
|
|
1026
|
+
role: "checkbox",
|
|
1027
|
+
"aria-checked": !!marcada,
|
|
1028
|
+
"aria-disabled": !selecionavel || void 0,
|
|
1029
|
+
className: `w-4 h-4 flex items-center justify-center border transition-colors rounded ${marcada ? "bg-proef-navy dark:bg-proef-turquoise border-proef-navy dark:border-proef-turquoise text-white dark:text-proef-navy" : "border-slate-300 dark:border-slate-600 hover:border-slate-400 dark:hover:border-slate-500"} ${selecionavel ? "" : "opacity-40 cursor-not-allowed bg-slate-100 dark:bg-slate-800"}`,
|
|
832
1030
|
children: marcada && /* @__PURE__ */ jsx("span", { className: "text-[9px] leading-none", children: "✓" })
|
|
833
1031
|
}
|
|
834
1032
|
)
|
|
@@ -844,7 +1042,8 @@ function DataTable({
|
|
|
844
1042
|
const max = larguraMax(c);
|
|
845
1043
|
if (!max) return conteudo;
|
|
846
1044
|
const v = rawValue(row, c);
|
|
847
|
-
|
|
1045
|
+
const dica = typeof conteudo === "string" || typeof conteudo === "number" ? String(conteudo) : c.sortType !== "date" && v !== null && v !== void 0 ? String(v) : void 0;
|
|
1046
|
+
return /* @__PURE__ */ jsx("div", { className: "overflow-hidden text-ellipsis", style: { maxWidth: max, width: larguras[c.key] }, title: dica, children: conteudo });
|
|
848
1047
|
})()
|
|
849
1048
|
},
|
|
850
1049
|
c.key
|
|
@@ -882,9 +1081,9 @@ function DataTable({
|
|
|
882
1081
|
] }, no.path);
|
|
883
1082
|
});
|
|
884
1083
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
885
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2.5", children: [
|
|
886
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400", children: L.results.replace("{count}", String(
|
|
887
|
-
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
1084
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2.5", children: [
|
|
1085
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400", children: isLoading ? "" : L.results.replace("{count}", String(totalResultados)) }),
|
|
1086
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-2", children: [
|
|
888
1087
|
extraToolbar,
|
|
889
1088
|
exportFileName && sorted.length > 0 && /* @__PURE__ */ jsxs(
|
|
890
1089
|
"button",
|
|
@@ -899,248 +1098,157 @@ function DataTable({
|
|
|
899
1098
|
)
|
|
900
1099
|
] })
|
|
901
1100
|
] }),
|
|
902
|
-
isGrouped && /* @__PURE__ */
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
key
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
{
|
|
942
|
-
className: "flex items-center gap-1.5 bg-proef-turquoise/15 text-proef-navy dark:text-proef-turquoise px-2.5 py-1 text-[10px] font-black uppercase tracking-wider",
|
|
943
|
-
children: [
|
|
944
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
945
|
-
col?.label ?? key,
|
|
946
|
-
": ",
|
|
947
|
-
txt
|
|
948
|
-
] }),
|
|
949
|
-
/* @__PURE__ */ jsx(
|
|
950
|
-
"button",
|
|
951
|
-
{
|
|
952
|
-
onClick: () => clearColumnFilter(key),
|
|
953
|
-
className: "appearance-none bg-transparent border-0 cursor-pointer ml-0.5 hover:text-proef-blue dark:hover:text-proef-turquoise",
|
|
954
|
-
children: "✕"
|
|
955
|
-
}
|
|
956
|
-
)
|
|
957
|
-
]
|
|
958
|
-
},
|
|
959
|
-
`r-${key}`
|
|
960
|
-
);
|
|
961
|
-
}),
|
|
962
|
-
activeFilters.flatMap(([key, sel]) => {
|
|
963
|
-
const col = columns.find((c) => c.key === key);
|
|
964
|
-
const extra = !col ? columns.flatMap((c) => c.extraFilters ?? []).find((f) => f.key === key) : void 0;
|
|
965
|
-
const chipLabel = col?.label ?? extra?.label ?? key;
|
|
966
|
-
const arr = Array.from(sel);
|
|
967
|
-
if (col?.valueChipColors) {
|
|
968
|
-
const cores = col.valueChipColors;
|
|
969
|
-
return arr.map((v) => /* @__PURE__ */ jsxs(
|
|
970
|
-
"div",
|
|
971
|
-
{
|
|
972
|
-
className: `flex items-center gap-1.5 px-2.5 py-1 text-[10px] font-black uppercase tracking-wider ${cores[v] ?? "bg-proef-turquoise/15 text-proef-navy dark:text-proef-turquoise"}`,
|
|
973
|
-
children: [
|
|
974
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
975
|
-
chipLabel,
|
|
976
|
-
": ",
|
|
977
|
-
v
|
|
978
|
-
] }),
|
|
979
|
-
/* @__PURE__ */ jsx(
|
|
980
|
-
"button",
|
|
981
|
-
{
|
|
982
|
-
onClick: () => toggleFilterValue(key, v),
|
|
983
|
-
className: "appearance-none bg-transparent border-0 cursor-pointer ml-0.5 hover:opacity-70",
|
|
984
|
-
children: "✕"
|
|
985
|
-
}
|
|
986
|
-
)
|
|
987
|
-
]
|
|
988
|
-
},
|
|
989
|
-
`${key}:${v}`
|
|
990
|
-
));
|
|
991
|
-
}
|
|
992
|
-
const txt = arr.length > 2 || arr.length === 0 ? L.selected.replace("{count}", String(arr.length)) : arr.join(", ");
|
|
993
|
-
return [
|
|
994
|
-
/* @__PURE__ */ jsxs(
|
|
995
|
-
"div",
|
|
996
|
-
{
|
|
997
|
-
className: "flex items-center gap-1.5 bg-proef-turquoise/15 text-proef-navy dark:text-proef-turquoise px-2.5 py-1 text-[10px] font-black uppercase tracking-wider",
|
|
998
|
-
children: [
|
|
999
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
1000
|
-
chipLabel,
|
|
1001
|
-
": ",
|
|
1002
|
-
txt
|
|
1003
|
-
] }),
|
|
1004
|
-
/* @__PURE__ */ jsx(
|
|
1005
|
-
"button",
|
|
1006
|
-
{
|
|
1007
|
-
onClick: () => clearColumnFilter(key),
|
|
1008
|
-
className: "appearance-none bg-transparent border-0 cursor-pointer ml-0.5 hover:text-proef-blue dark:hover:text-proef-turquoise",
|
|
1009
|
-
children: "✕"
|
|
1010
|
-
}
|
|
1011
|
-
)
|
|
1012
|
-
]
|
|
1013
|
-
},
|
|
1014
|
-
key
|
|
1015
|
-
)
|
|
1016
|
-
];
|
|
1017
|
-
}),
|
|
1018
|
-
/* @__PURE__ */ jsx(
|
|
1019
|
-
"button",
|
|
1020
|
-
{
|
|
1021
|
-
onClick: clearAllFilters,
|
|
1022
|
-
className: "appearance-none bg-transparent border-0 cursor-pointer text-[10px] font-black uppercase tracking-wider text-slate-400 hover:text-red-500 transition-colors",
|
|
1023
|
-
children: L.clearAll
|
|
1024
|
-
}
|
|
1025
|
-
)
|
|
1026
|
-
] }),
|
|
1027
|
-
/* @__PURE__ */ jsx("div", { className: "overflow-auto rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900", style: { maxHeight }, children: /* @__PURE__ */ jsxs("table", { className: "w-full text-[13px] border-collapse dark:text-slate-200", children: [
|
|
1028
|
-
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-[2]", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1029
|
-
selectable && /* @__PURE__ */ jsx("th", { className: "bg-slate-50 dark:bg-slate-800 px-3 py-2.5 border-b border-slate-200 dark:border-slate-700 w-10 sticky left-0 z-[3]", children: /* @__PURE__ */ jsx(
|
|
1030
|
-
"button",
|
|
1031
|
-
{
|
|
1032
|
-
onClick: alternarTodas,
|
|
1033
|
-
className: `appearance-none cursor-pointer w-4 h-4 flex items-center justify-center border transition-colors rounded ${todasVisiveisMarcadas ? "bg-proef-navy dark:bg-proef-turquoise border-proef-navy dark:border-proef-turquoise text-white dark:text-proef-navy" : algumaVisivelMarcada ? "bg-slate-300 dark:bg-slate-600 border-slate-300 dark:border-slate-600 text-white" : "bg-white dark:bg-slate-900 border-slate-300 dark:border-slate-600 hover:border-slate-400 dark:hover:border-slate-500"}`,
|
|
1034
|
-
children: (todasVisiveisMarcadas || algumaVisivelMarcada) && /* @__PURE__ */ jsx("span", { className: "text-[9px] leading-none", children: "✓" })
|
|
1035
|
-
}
|
|
1036
|
-
) }),
|
|
1037
|
-
columns.map((c) => {
|
|
1038
|
-
temFiltro(c.key);
|
|
1039
|
-
const podeOrdenar = c.sortable !== false;
|
|
1040
|
-
const podeAgrupar = agrupavel(c);
|
|
1041
|
-
const agrupada = groupByKeys.includes(c.key);
|
|
1042
|
-
return /* @__PURE__ */ jsxs(
|
|
1043
|
-
"th",
|
|
1044
|
-
{
|
|
1045
|
-
style: {
|
|
1046
|
-
...c.width ? { minWidth: c.width } : {},
|
|
1047
|
-
...larguras[c.key] ? { width: larguras[c.key], minWidth: larguras[c.key], maxWidth: larguras[c.key] } : {},
|
|
1048
|
-
...estiloPreso(c) ?? {}
|
|
1049
|
-
},
|
|
1050
|
-
className: `group/th relative bg-slate-50 dark:bg-slate-800 text-[11.5px] uppercase tracking-wide text-slate-500 dark:text-slate-400 font-semibold px-3 py-2.5 border-b border-slate-200 dark:border-slate-700 whitespace-nowrap select-none ${alignClass(
|
|
1051
|
-
c.align
|
|
1052
|
-
)} ${c.sticky ? `sticky z-[3] bg-slate-50 dark:bg-slate-800 ${c.sticky === "right" ? "border-l border-slate-200 dark:border-slate-700" : ""}` : ""} ${c.headerClassName ?? ""}`,
|
|
1053
|
-
children: [
|
|
1054
|
-
resizableColumns && // Pega no limite direito: arrastar redimensiona; duplo clique repõe a largura automática
|
|
1055
|
-
/* @__PURE__ */ jsx(
|
|
1056
|
-
"span",
|
|
1057
|
-
{
|
|
1058
|
-
role: "separator",
|
|
1059
|
-
"aria-orientation": "vertical",
|
|
1060
|
-
title: L.resizeColumn,
|
|
1061
|
-
onMouseDown: (e) => iniciarResize(e, c.key),
|
|
1062
|
-
onDoubleClick: () => reporLargura(c.key),
|
|
1063
|
-
onClick: (e) => e.stopPropagation(),
|
|
1064
|
-
className: "absolute right-0 top-0 z-[4] h-full w-1.5 cursor-col-resize bg-transparent hover:bg-proef-blue/40 group-hover/th:bg-slate-300/60 dark:group-hover/th:bg-slate-600/60"
|
|
1065
|
-
}
|
|
1066
|
-
),
|
|
1067
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1068
|
-
podeOrdenar ? /* @__PURE__ */ jsxs(
|
|
1069
|
-
"button",
|
|
1070
|
-
{
|
|
1071
|
-
onClick: () => toggleSort(c.key),
|
|
1072
|
-
className: "appearance-none bg-transparent border-0 cursor-pointer p-0 uppercase tracking-wide text-slate-500 dark:text-slate-400 hover:text-proef-blue dark:hover:text-proef-turquoise font-semibold",
|
|
1073
|
-
children: [
|
|
1074
|
-
c.label,
|
|
1075
|
-
sort?.key === c.key && /* @__PURE__ */ jsx("span", { className: "ml-1", children: sort.dir === 1 ? "▲" : "▼" })
|
|
1076
|
-
]
|
|
1077
|
-
}
|
|
1078
|
-
) : /* @__PURE__ */ jsx("span", { children: c.label }),
|
|
1079
|
-
podeAgrupar && /* @__PURE__ */ jsx(
|
|
1080
|
-
"button",
|
|
1081
|
-
{
|
|
1082
|
-
onClick: () => alternarGrupo(c.key),
|
|
1083
|
-
title: (agrupada ? L.ungroup : L.groupBy).replace("{label}", c.label),
|
|
1084
|
-
className: `appearance-none bg-transparent border-0 cursor-pointer p-0.5 transition-colors ${agrupada ? "text-violet-600 dark:text-violet-300" : "text-slate-300 dark:text-slate-600 hover:text-slate-500 dark:hover:text-slate-300"}`,
|
|
1085
|
-
children: /* @__PURE__ */ jsx(Layers, { size: 10 })
|
|
1086
|
-
}
|
|
1087
|
-
),
|
|
1088
|
-
filtravel(c) && botaoFunil(c.key, c),
|
|
1089
|
-
c.extraFilters?.map((ef) => botaoFunil(ef.key, void 0, { label: ef.label }))
|
|
1090
|
-
] }),
|
|
1091
|
-
c.headerExtra && /* @__PURE__ */ jsx("div", { className: "mt-0.5 normal-case font-normal tracking-normal", children: c.headerExtra(filtered) })
|
|
1092
|
-
]
|
|
1093
|
-
},
|
|
1094
|
-
c.key
|
|
1095
|
-
);
|
|
1096
|
-
})
|
|
1097
|
-
] }) }),
|
|
1098
|
-
/* @__PURE__ */ jsx("tbody", { children: aEsperarDataset ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: nColunas, className: "py-16 text-center text-sm font-bold uppercase tracking-widest text-slate-400", children: L.loading }) }) : isGrouped ? grupos.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: nColunas, className: "py-16 text-center text-sm text-slate-400", children: L.empty }) }) : renderGrupos(grupos, 0) : sorted.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", { colSpan: nColunas, className: "py-16 text-center", children: [
|
|
1099
|
-
emptyIcon && /* @__PURE__ */ jsx("div", { className: "flex justify-center mb-2", children: emptyIcon }),
|
|
1100
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-slate-400", children: L.empty }),
|
|
1101
|
-
emptySubLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-400 mt-1", children: emptySubLabel })
|
|
1102
|
-
] }) }) : pageData.map((row, i) => renderLinha(row, i)) }),
|
|
1103
|
-
totalRow && !aEsperarDataset && sorted.length > 0 && /* @__PURE__ */ jsx("tfoot", { className: "sticky bottom-0 z-[2]", children: /* @__PURE__ */ jsxs("tr", { className: "bg-slate-100 dark:bg-slate-800 font-black text-slate-800 dark:text-slate-100", children: [
|
|
1104
|
-
/* @__PURE__ */ jsx("td", { colSpan: colunasRotuloGrupo, className: "px-3 py-2 border-t-2 border-slate-200 dark:border-slate-700 text-[10px] uppercase tracking-widest", children: L.total }),
|
|
1105
|
-
colunasComValor.map((c) => /* @__PURE__ */ jsx("td", { className: `px-3 py-2 border-t-2 border-slate-200 dark:border-slate-700 whitespace-nowrap text-xs ${alignClass(c.align)}`, children: c.groupAggregate?.(sorted) }, c.key))
|
|
1106
|
-
] }) })
|
|
1107
|
-
] }) }),
|
|
1108
|
-
paginando && (totalPages > 1 || (pageSizeOptions?.length ?? 0) > 0) && /* @__PURE__ */ jsxs("div", { className: "mt-2.5 flex items-center justify-between gap-2", children: [
|
|
1109
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-black uppercase tracking-widest text-slate-400", children: L.page.replace("{page}", String(currentPage)).replace("{pages}", String(totalPages)) }),
|
|
1110
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1111
|
-
(pageSizeOptions?.length ?? 0) > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 mr-2 text-[10px] font-black uppercase tracking-widest text-slate-400", children: [
|
|
1112
|
-
L.perPage,
|
|
1113
|
-
/* @__PURE__ */ jsx(
|
|
1114
|
-
Escolha,
|
|
1115
|
-
{
|
|
1116
|
-
rotulo: L.perPage,
|
|
1117
|
-
valor: String(pageSizeAtual),
|
|
1118
|
-
onMudar: (v) => setPageSizeAtual(Number(v)),
|
|
1119
|
-
className: "w-20 normal-case tracking-normal font-normal",
|
|
1120
|
-
opcoes: [.../* @__PURE__ */ new Set([...pageSizeOptions ?? [], pageSizeAtual])].sort((a, b) => a - b).map(String)
|
|
1101
|
+
isGrouped && /* @__PURE__ */ jsx(
|
|
1102
|
+
FilterChips,
|
|
1103
|
+
{
|
|
1104
|
+
className: "mb-2",
|
|
1105
|
+
items: groupByKeys.map((key) => ({
|
|
1106
|
+
key,
|
|
1107
|
+
tone: "group",
|
|
1108
|
+
icon: /* @__PURE__ */ jsx(Layers, { size: 9 }),
|
|
1109
|
+
label: columns.find((c) => c.key === key)?.label ?? key,
|
|
1110
|
+
onRemove: () => removerGrupo(key)
|
|
1111
|
+
})),
|
|
1112
|
+
onClearAll: limparGrupos,
|
|
1113
|
+
clearAllLabel: L.clearGroups
|
|
1114
|
+
}
|
|
1115
|
+
),
|
|
1116
|
+
(activeFilters.length > 0 || activeRanges.length > 0) && /* @__PURE__ */ jsx(
|
|
1117
|
+
FilterChips,
|
|
1118
|
+
{
|
|
1119
|
+
className: "mb-2",
|
|
1120
|
+
items: [
|
|
1121
|
+
...activeRanges.map(([key, r]) => {
|
|
1122
|
+
const col = columns.find((c) => c.key === key);
|
|
1123
|
+
const fmt = (v) => v == null ? "" : col?.sortType === "date" ? new Date(v).toLocaleDateString() : String(v);
|
|
1124
|
+
const txt = r.min != null && r.max != null ? `${fmt(r.min)} – ${fmt(r.max)}` : r.min != null ? `≥ ${fmt(r.min)}` : `≤ ${fmt(r.max)}`;
|
|
1125
|
+
return { key: `r-${key}`, label: `${col?.label ?? key}: ${txt}`, onRemove: () => clearColumnFilter(key) };
|
|
1126
|
+
}),
|
|
1127
|
+
...activeFilters.flatMap(([key, sel]) => {
|
|
1128
|
+
const col = columns.find((c) => c.key === key);
|
|
1129
|
+
const extra = !col ? columns.flatMap((c) => c.extraFilters ?? []).find((f) => f.key === key) : void 0;
|
|
1130
|
+
const chipLabel = col?.label ?? extra?.label ?? key;
|
|
1131
|
+
const arr = Array.from(sel);
|
|
1132
|
+
if (col?.valueChipColors) {
|
|
1133
|
+
const cores = col.valueChipColors;
|
|
1134
|
+
return arr.map((v) => ({
|
|
1135
|
+
key: `${key}:${v}`,
|
|
1136
|
+
label: `${chipLabel}: ${rotuloVisivel(key, v)}`,
|
|
1137
|
+
colorClassName: cores[v],
|
|
1138
|
+
onRemove: () => toggleFilterValue(key, v)
|
|
1139
|
+
}));
|
|
1121
1140
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1141
|
+
const txt = arr.length > 2 || arr.length === 0 ? L.selected.replace("{count}", String(arr.length)) : arr.map((v) => rotuloVisivel(key, v)).join(", ");
|
|
1142
|
+
return [{ key, label: `${chipLabel}: ${txt}`, onRemove: () => clearColumnFilter(key) }];
|
|
1143
|
+
})
|
|
1144
|
+
],
|
|
1145
|
+
onClearAll: clearAllFilters,
|
|
1146
|
+
clearAllLabel: L.clearAll
|
|
1147
|
+
}
|
|
1148
|
+
),
|
|
1149
|
+
/* @__PURE__ */ jsx(
|
|
1150
|
+
"div",
|
|
1151
|
+
{
|
|
1152
|
+
className: `overflow-auto rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 ${scrollAffordance ? "outline-none focus-visible:ring-2 focus-visible:ring-proef-blue dark:focus-visible:ring-proef-turquoise" : ""}`,
|
|
1153
|
+
style: { maxHeight },
|
|
1154
|
+
...scrollAffordance ? { tabIndex: 0, role: "region", "aria-label": L.scrollRegion ?? DEFAULT_LABELS.scrollRegion, onKeyDown: rolarComTeclado } : {},
|
|
1155
|
+
children: /* @__PURE__ */ jsxs("table", { className: "w-full text-[13px] border-collapse dark:text-slate-200", children: [
|
|
1156
|
+
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-[2]", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1157
|
+
selectable && /* @__PURE__ */ jsx("th", { className: "bg-slate-50 dark:bg-slate-800 px-3 py-2.5 border-b border-slate-200 dark:border-slate-700 w-10 sticky left-0 z-[3]", children: /* @__PURE__ */ jsx(
|
|
1158
|
+
"button",
|
|
1159
|
+
{
|
|
1160
|
+
onClick: alternarTodas,
|
|
1161
|
+
className: `appearance-none cursor-pointer w-4 h-4 flex items-center justify-center border transition-colors rounded ${todasVisiveisMarcadas ? "bg-proef-navy dark:bg-proef-turquoise border-proef-navy dark:border-proef-turquoise text-white dark:text-proef-navy" : algumaVisivelMarcada ? "bg-slate-300 dark:bg-slate-600 border-slate-300 dark:border-slate-600 text-white" : "bg-white dark:bg-slate-900 border-slate-300 dark:border-slate-600 hover:border-slate-400 dark:hover:border-slate-500"}`,
|
|
1162
|
+
children: (todasVisiveisMarcadas || algumaVisivelMarcada) && /* @__PURE__ */ jsx("span", { className: "text-[9px] leading-none", children: "✓" })
|
|
1163
|
+
}
|
|
1164
|
+
) }),
|
|
1165
|
+
columns.map((c) => {
|
|
1166
|
+
const podeOrdenar = c.sortable !== false;
|
|
1167
|
+
const podeAgrupar = agrupavel(c);
|
|
1168
|
+
const agrupada = groupByKeys.includes(c.key);
|
|
1169
|
+
return /* @__PURE__ */ jsxs(
|
|
1170
|
+
"th",
|
|
1171
|
+
{
|
|
1172
|
+
style: {
|
|
1173
|
+
...c.width ? { minWidth: c.width } : {},
|
|
1174
|
+
...larguras[c.key] ? { width: larguras[c.key], minWidth: larguras[c.key], maxWidth: larguras[c.key] } : {},
|
|
1175
|
+
...estiloPreso(c) ?? {}
|
|
1176
|
+
},
|
|
1177
|
+
className: `group/th relative bg-slate-50 dark:bg-slate-800 text-[11.5px] uppercase tracking-wide text-slate-500 dark:text-slate-400 font-semibold px-3 py-2.5 border-b border-slate-200 dark:border-slate-700 whitespace-nowrap select-none ${alignClass(
|
|
1178
|
+
c.align
|
|
1179
|
+
)} ${c.sticky ? `sticky z-[3] bg-slate-50 dark:bg-slate-800 ${c.sticky === "right" ? "border-l border-slate-200 dark:border-slate-700" : ""}` : ""} ${c.headerClassName ?? ""}`,
|
|
1180
|
+
children: [
|
|
1181
|
+
resizableColumns && // Pega no limite direito: arrastar redimensiona; duplo clique repõe a largura automática
|
|
1182
|
+
/* @__PURE__ */ jsx(
|
|
1183
|
+
"span",
|
|
1184
|
+
{
|
|
1185
|
+
role: "separator",
|
|
1186
|
+
"aria-orientation": "vertical",
|
|
1187
|
+
title: L.resizeColumn,
|
|
1188
|
+
onMouseDown: (e) => iniciarResize(e, c.key),
|
|
1189
|
+
onDoubleClick: () => reporLargura(c.key),
|
|
1190
|
+
onClick: (e) => e.stopPropagation(),
|
|
1191
|
+
className: "absolute right-0 top-0 z-[4] h-full w-1.5 cursor-col-resize bg-transparent hover:bg-proef-blue/40 group-hover/th:bg-slate-300/60 dark:group-hover/th:bg-slate-600/60"
|
|
1192
|
+
}
|
|
1193
|
+
),
|
|
1194
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1195
|
+
podeOrdenar ? /* @__PURE__ */ jsxs(
|
|
1196
|
+
"button",
|
|
1197
|
+
{
|
|
1198
|
+
onClick: () => toggleSort(c.key),
|
|
1199
|
+
className: "appearance-none bg-transparent border-0 cursor-pointer p-0 uppercase tracking-wide text-slate-500 dark:text-slate-400 hover:text-proef-blue dark:hover:text-proef-turquoise font-semibold",
|
|
1200
|
+
children: [
|
|
1201
|
+
c.label,
|
|
1202
|
+
sort?.key === c.key && /* @__PURE__ */ jsx("span", { className: "ml-1", children: sort.dir === 1 ? "▲" : "▼" })
|
|
1203
|
+
]
|
|
1204
|
+
}
|
|
1205
|
+
) : /* @__PURE__ */ jsx("span", { children: c.label }),
|
|
1206
|
+
podeAgrupar && /* @__PURE__ */ jsx(
|
|
1207
|
+
"button",
|
|
1208
|
+
{
|
|
1209
|
+
onClick: () => alternarGrupo(c.key),
|
|
1210
|
+
title: (agrupada ? L.ungroup : L.groupBy).replace("{label}", c.label),
|
|
1211
|
+
className: `appearance-none bg-transparent border-0 cursor-pointer p-0.5 transition-colors ${agrupada ? "text-violet-600 dark:text-violet-300" : "text-slate-300 dark:text-slate-600 hover:text-slate-500 dark:hover:text-slate-300"}`,
|
|
1212
|
+
children: /* @__PURE__ */ jsx(Layers, { size: 10 })
|
|
1213
|
+
}
|
|
1214
|
+
),
|
|
1215
|
+
botaoFunil(c)
|
|
1216
|
+
] }),
|
|
1217
|
+
c.headerExtra && /* @__PURE__ */ jsx("div", { className: "mt-0.5 normal-case font-normal tracking-normal", children: c.headerExtra(filtered) })
|
|
1218
|
+
]
|
|
1219
|
+
},
|
|
1220
|
+
c.key
|
|
1221
|
+
);
|
|
1222
|
+
})
|
|
1223
|
+
] }) }),
|
|
1224
|
+
/* @__PURE__ */ jsx("tbody", { children: isLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: nColunas, className: "py-16 text-center text-sm font-bold uppercase tracking-widest text-slate-400", children: /* @__PURE__ */ jsxs("div", { role: "status", "aria-live": "polite", className: "inline-flex items-center gap-2", children: [
|
|
1225
|
+
/* @__PURE__ */ jsx(Spinner, { size: 16, className: "text-proef-blue dark:text-proef-turquoise" }),
|
|
1226
|
+
/* @__PURE__ */ jsx("span", { children: L.loading })
|
|
1227
|
+
] }) }) }) : aEsperarDataset ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: nColunas, className: "py-16 text-center text-sm font-bold uppercase tracking-widest text-slate-400", children: L.loading }) }) : isGrouped ? grupos.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: nColunas, className: "py-16 text-center text-sm text-slate-400", children: L.empty }) }) : renderGrupos(grupos, 0) : sorted.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", { colSpan: nColunas, className: "py-16 text-center", children: [
|
|
1228
|
+
emptyIcon && /* @__PURE__ */ jsx("div", { className: "flex justify-center mb-2", children: emptyIcon }),
|
|
1229
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-slate-400", children: L.empty }),
|
|
1230
|
+
emptySubLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-400 mt-1", children: emptySubLabel })
|
|
1231
|
+
] }) }) : pageData.map((row, i) => renderLinha(row, i)) }),
|
|
1232
|
+
totalRow && !isLoading && !aEsperarDataset && sorted.length > 0 && /* @__PURE__ */ jsx("tfoot", { className: "sticky bottom-0 z-[2]", children: /* @__PURE__ */ jsxs("tr", { className: "bg-slate-100 dark:bg-slate-800 font-black text-slate-800 dark:text-slate-100", children: [
|
|
1233
|
+
/* @__PURE__ */ jsx("td", { colSpan: colunasRotuloGrupo, className: "px-3 py-2 border-t-2 border-slate-200 dark:border-slate-700 text-[10px] uppercase tracking-widest", children: L.total }),
|
|
1234
|
+
colunasComValor.map((c) => /* @__PURE__ */ jsx("td", { className: `px-3 py-2 border-t-2 border-slate-200 dark:border-slate-700 whitespace-nowrap text-xs ${alignClass(c.align)}`, children: c.groupAggregate?.(sorted) }, c.key))
|
|
1235
|
+
] }) })
|
|
1236
|
+
] })
|
|
1237
|
+
}
|
|
1238
|
+
),
|
|
1239
|
+
!isLoading && paginando && (totalPages > 1 || (pageSizeOptions?.length ?? 0) > 0) && /* @__PURE__ */ jsx(
|
|
1240
|
+
Pagination,
|
|
1241
|
+
{
|
|
1242
|
+
className: "mt-2.5",
|
|
1243
|
+
page: currentPage,
|
|
1244
|
+
pages: totalPages,
|
|
1245
|
+
onPageChange: (p) => setPage(Math.min(totalPages, Math.max(1, p))),
|
|
1246
|
+
pageSize: pageSizeAtual,
|
|
1247
|
+
pageSizeOptions,
|
|
1248
|
+
onPageSizeChange: escolherPageSize,
|
|
1249
|
+
labels: { page: L.page, perPage: L.perPage, prev: L.prev, next: L.next }
|
|
1250
|
+
}
|
|
1251
|
+
)
|
|
1144
1252
|
] });
|
|
1145
1253
|
}
|
|
1146
1254
|
export {
|