@12-apps/ui 1.5.1 → 1.6.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/package.json +5 -5
- package/src/components/data-display/DataViews/DataViewsBoard.tsx +327 -0
- package/src/components/data-display/DataViews/DataViewsGrid.tsx +80 -77
- package/src/components/data-display/DataViews/DataViewsTableBase.tsx +178 -230
- package/src/components/data-display/DataViews/DeleteViewDialog.tsx +83 -0
- package/src/components/data-display/DataViews/SaveViewModal.tsx +140 -52
- package/src/components/data-display/DataViews/data-views-columns-tab.tsx +240 -0
- package/src/components/data-display/DataViews/data-views-columns.ts +129 -0
- package/src/components/data-display/DataViews/data-views-dirty.ts +62 -0
- package/src/components/data-display/DataViews/data-views-display-panel.tsx +328 -0
- package/src/components/data-display/DataViews/data-views-display-tabs.tsx +328 -0
- package/src/components/data-display/DataViews/data-views-empty.tsx +91 -0
- package/src/components/data-display/DataViews/data-views-export.tsx +260 -0
- package/src/components/data-display/DataViews/data-views-glyphs.tsx +103 -0
- package/src/components/data-display/DataViews/data-views-grid-bodies.tsx +340 -0
- package/src/components/data-display/DataViews/data-views-grid-parts.tsx +220 -242
- package/src/components/data-display/DataViews/data-views-inline-bar.tsx +187 -81
- package/src/components/data-display/DataViews/data-views-layout-context.tsx +215 -79
- package/src/components/data-display/DataViews/data-views-more-filters.tsx +300 -0
- package/src/components/data-display/DataViews/data-views-overflow.ts +302 -0
- package/src/components/data-display/DataViews/data-views-preview.ts +11 -3
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +162 -92
- package/src/components/data-display/DataViews/data-views-range-values.ts +69 -0
- package/src/components/data-display/DataViews/data-views-scopes.tsx +356 -0
- package/src/components/data-display/DataViews/data-views-search.tsx +156 -0
- package/src/components/data-display/DataViews/data-views-select-all-strip.tsx +105 -0
- package/src/components/data-display/DataViews/data-views-selection.ts +50 -0
- package/src/components/data-display/DataViews/data-views-server-query.ts +75 -0
- package/src/components/data-display/DataViews/data-views-shell-toolbar.tsx +87 -0
- package/src/components/data-display/DataViews/data-views-table-parts.tsx +5 -0
- package/src/components/data-display/DataViews/data-views-toolbar.tsx +63 -48
- package/src/components/data-display/DataViews/data-views-types.ts +88 -9
- package/src/components/data-display/DataViews/data-views-view-nav.tsx +378 -0
- package/src/components/data-display/DataViews/index.ts +14 -1
- package/src/components/data-display/DataViews/use-data-views-state.ts +158 -134
- package/src/components/data-display/DataViews/use-saved-views-controller.ts +171 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.tsx +86 -30
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +25 -0
- package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +6 -1
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The saved views, rendered INSIDE the Exibir panel rather than in a dropdown
|
|
5
|
+
* of their own.
|
|
6
|
+
*
|
|
7
|
+
* Two levels, both of them replacing the panel's BODY (the tabs stay put):
|
|
8
|
+
* the list of views, and one view's actions. It is a drill-down and not a
|
|
9
|
+
* nested menu on purpose — an absolutely positioned popover inside the panel's
|
|
10
|
+
* own scroll container gets clipped by it, which is how "Excluir visão" ends
|
|
11
|
+
* up unreachable. One level, no clipping, and it works on touch.
|
|
12
|
+
*/
|
|
13
|
+
import ChevronLeftRoundedIcon from "@mui/icons-material/ChevronLeftRounded";
|
|
14
|
+
import CheckRoundedIcon from "@mui/icons-material/CheckRounded";
|
|
15
|
+
import DeleteOutlineRoundedIcon from "@mui/icons-material/DeleteOutlineRounded";
|
|
16
|
+
import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
|
|
17
|
+
import GroupOutlinedIcon from "@mui/icons-material/GroupOutlined";
|
|
18
|
+
import MoreVertRoundedIcon from "@mui/icons-material/MoreVertRounded";
|
|
19
|
+
import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined";
|
|
20
|
+
import StarOutlineRoundedIcon from "@mui/icons-material/StarOutlined";
|
|
21
|
+
import StarOutlineRoundedIcon2 from "@mui/icons-material/StarOutlineRounded";
|
|
22
|
+
import { IconButton } from "@mui/material";
|
|
23
|
+
|
|
24
|
+
import KeyboardArrowDownRoundedIcon from "@mui/icons-material/KeyboardArrowDownRounded";
|
|
25
|
+
import RestartAltRoundedIcon from "@mui/icons-material/RestartAltRounded";
|
|
26
|
+
import SaveOutlinedIcon from "@mui/icons-material/SaveOutlined";
|
|
27
|
+
|
|
28
|
+
import { Button } from "../../form/Button";
|
|
29
|
+
import { Box } from "../../../mui/Box";
|
|
30
|
+
import { Text } from "../../typography/Text";
|
|
31
|
+
|
|
32
|
+
import type { DisplayPanelView } from "./data-views-display-panel";
|
|
33
|
+
import type { SavedViewSummary } from "./data-views-types";
|
|
34
|
+
|
|
35
|
+
/** What the panel needs to drive the views without owning any of them. */
|
|
36
|
+
export interface ViewNavHandlers {
|
|
37
|
+
views: SavedViewSummary[];
|
|
38
|
+
activeViewId?: string | null;
|
|
39
|
+
/** `null` selects the built-in "Visão principal". */
|
|
40
|
+
onSelectView: (id: string | null) => void;
|
|
41
|
+
onEditView: (view: SavedViewSummary) => void;
|
|
42
|
+
onPatchView: (
|
|
43
|
+
view: SavedViewSummary,
|
|
44
|
+
changes: Partial<Pick<SavedViewSummary, "isDefault" | "pinned" | "shared">>,
|
|
45
|
+
) => void;
|
|
46
|
+
onDeleteView: (view: SavedViewSummary) => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const rowSx = {
|
|
50
|
+
display: "flex",
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
gap: 1,
|
|
53
|
+
width: "100%",
|
|
54
|
+
px: 1.25,
|
|
55
|
+
py: 1,
|
|
56
|
+
border: 0,
|
|
57
|
+
borderRadius: 1,
|
|
58
|
+
bgcolor: "transparent",
|
|
59
|
+
cursor: "pointer",
|
|
60
|
+
font: "inherit",
|
|
61
|
+
fontSize: "0.8125rem",
|
|
62
|
+
textAlign: "left",
|
|
63
|
+
color: "text.primary",
|
|
64
|
+
"&:hover": { bgcolor: "action.hover" },
|
|
65
|
+
} as const;
|
|
66
|
+
|
|
67
|
+
/** The list: the built-in view, then each saved one with its own "⋮". */
|
|
68
|
+
export function ViewsList({
|
|
69
|
+
handlers,
|
|
70
|
+
onOpenActions,
|
|
71
|
+
testIdPrefix,
|
|
72
|
+
}: {
|
|
73
|
+
handlers: ViewNavHandlers;
|
|
74
|
+
onOpenActions: (view: SavedViewSummary) => void;
|
|
75
|
+
testIdPrefix: string;
|
|
76
|
+
}): React.JSX.Element {
|
|
77
|
+
const { views, activeViewId, onSelectView } = handlers;
|
|
78
|
+
const onMain = !activeViewId;
|
|
79
|
+
return (
|
|
80
|
+
<Box sx={{ p: 0.75 }} data-testid={`${testIdPrefix}-views-list`}>
|
|
81
|
+
<Box
|
|
82
|
+
component="button"
|
|
83
|
+
type="button"
|
|
84
|
+
onClick={() => onSelectView(null)}
|
|
85
|
+
data-testid={`${testIdPrefix}-view-main`}
|
|
86
|
+
sx={{ ...rowSx, color: onMain ? "primary.main" : "text.primary", fontWeight: onMain ? 600 : 400 }}
|
|
87
|
+
>
|
|
88
|
+
<Box component="span" sx={{ flex: 1 }}>
|
|
89
|
+
Visão principal
|
|
90
|
+
</Box>
|
|
91
|
+
{onMain && <CheckRoundedIcon fontSize="small" />}
|
|
92
|
+
</Box>
|
|
93
|
+
|
|
94
|
+
{views.map((view) => {
|
|
95
|
+
const active = view.id === activeViewId;
|
|
96
|
+
return (
|
|
97
|
+
<Box key={view.id} sx={{ display: "flex", alignItems: "center" }}>
|
|
98
|
+
<Box
|
|
99
|
+
component="button"
|
|
100
|
+
type="button"
|
|
101
|
+
onClick={() => onSelectView(view.id)}
|
|
102
|
+
data-testid={`${testIdPrefix}-view-${view.id}`}
|
|
103
|
+
sx={{ ...rowSx, minWidth: 0, color: active ? "primary.main" : "text.primary", fontWeight: active ? 600 : 400 }}
|
|
104
|
+
>
|
|
105
|
+
<Box component="span" sx={{ flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
|
|
106
|
+
{view.name}
|
|
107
|
+
</Box>
|
|
108
|
+
{/* What the row-menu toggles DID, readable without opening it:
|
|
109
|
+
a view set as default, pinned or shared says so here. */}
|
|
110
|
+
{view.isDefault && (
|
|
111
|
+
<StarOutlineRoundedIcon fontSize="small" sx={{ color: "warning.main" }} titleAccess="Padrão" />
|
|
112
|
+
)}
|
|
113
|
+
{view.pinned && (
|
|
114
|
+
<PushPinOutlinedIcon fontSize="small" sx={{ color: "text.disabled" }} titleAccess="Fixada" />
|
|
115
|
+
)}
|
|
116
|
+
{view.shared && (
|
|
117
|
+
<GroupOutlinedIcon fontSize="small" sx={{ color: "text.disabled" }} titleAccess="Compartilhada" />
|
|
118
|
+
)}
|
|
119
|
+
{active && <CheckRoundedIcon fontSize="small" />}
|
|
120
|
+
</Box>
|
|
121
|
+
<IconButton
|
|
122
|
+
size="small"
|
|
123
|
+
onClick={() => onOpenActions(view)}
|
|
124
|
+
aria-label={`Opções de ${view.name}`}
|
|
125
|
+
data-testid={`${testIdPrefix}-view-${view.id}-menu`}
|
|
126
|
+
>
|
|
127
|
+
<MoreVertRoundedIcon fontSize="small" />
|
|
128
|
+
</IconButton>
|
|
129
|
+
</Box>
|
|
130
|
+
);
|
|
131
|
+
})}
|
|
132
|
+
|
|
133
|
+
{views.length === 0 && (
|
|
134
|
+
<Text variant="caption" as="p">
|
|
135
|
+
<Box component="span" sx={{ display: "block", px: 1.25, py: 1.5, color: "text.secondary", lineHeight: 1.6 }}>
|
|
136
|
+
Nenhuma visão salva. Ajuste filtros, colunas ou ordenação e salve abaixo.
|
|
137
|
+
</Box>
|
|
138
|
+
</Text>
|
|
139
|
+
)}
|
|
140
|
+
</Box>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** One view's actions, reached from its "⋮" and left by the back row. */
|
|
145
|
+
export function ViewActions({
|
|
146
|
+
view,
|
|
147
|
+
handlers,
|
|
148
|
+
onBack,
|
|
149
|
+
testIdPrefix,
|
|
150
|
+
}: {
|
|
151
|
+
view: SavedViewSummary;
|
|
152
|
+
handlers: ViewNavHandlers;
|
|
153
|
+
onBack: () => void;
|
|
154
|
+
testIdPrefix: string;
|
|
155
|
+
}): React.JSX.Element {
|
|
156
|
+
const { onEditView, onPatchView, onDeleteView } = handlers;
|
|
157
|
+
const action = (
|
|
158
|
+
key: string,
|
|
159
|
+
Icon: typeof StarOutlineRoundedIcon2,
|
|
160
|
+
label: string,
|
|
161
|
+
onClick: () => void,
|
|
162
|
+
opts: { on?: boolean; danger?: boolean } = {},
|
|
163
|
+
): React.JSX.Element => (
|
|
164
|
+
<Box
|
|
165
|
+
component="button"
|
|
166
|
+
type="button"
|
|
167
|
+
onClick={onClick}
|
|
168
|
+
data-testid={`${testIdPrefix}-view-action-${key}`}
|
|
169
|
+
sx={{
|
|
170
|
+
...rowSx,
|
|
171
|
+
color: opts.danger ? "error.main" : "text.primary",
|
|
172
|
+
"&:hover": { bgcolor: opts.danger ? "error.lighter" : "action.hover" },
|
|
173
|
+
}}
|
|
174
|
+
>
|
|
175
|
+
<Icon fontSize="small" sx={{ color: opts.danger ? "inherit" : "text.disabled" }} />
|
|
176
|
+
<Box component="span" sx={{ flex: 1 }}>
|
|
177
|
+
{label}
|
|
178
|
+
</Box>
|
|
179
|
+
{opts.on && <CheckRoundedIcon fontSize="small" color="primary" />}
|
|
180
|
+
</Box>
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<Box sx={{ p: 0.75 }} data-testid={`${testIdPrefix}-view-actions`}>
|
|
185
|
+
<Box
|
|
186
|
+
component="button"
|
|
187
|
+
type="button"
|
|
188
|
+
onClick={onBack}
|
|
189
|
+
data-testid={`${testIdPrefix}-view-actions-back`}
|
|
190
|
+
sx={{ ...rowSx, color: "text.secondary", fontSize: "0.75rem" }}
|
|
191
|
+
>
|
|
192
|
+
<ChevronLeftRoundedIcon fontSize="small" />
|
|
193
|
+
<Box component="span" sx={{ flex: 1, fontWeight: 600, color: "text.primary" }}>
|
|
194
|
+
{view.name}
|
|
195
|
+
</Box>
|
|
196
|
+
</Box>
|
|
197
|
+
<Box sx={{ my: 0.5, borderTop: 1, borderColor: "divider" }} />
|
|
198
|
+
{action("edit", EditOutlinedIcon, "Renomear e editar", () => onEditView(view))}
|
|
199
|
+
{action("default", StarOutlineRoundedIcon2, "Definir como padrão", () => onPatchView(view, { isDefault: !view.isDefault }), { on: view.isDefault })}
|
|
200
|
+
{action("pin", PushPinOutlinedIcon, "Fixar na barra lateral", () => onPatchView(view, { pinned: !view.pinned }), { on: view.pinned })}
|
|
201
|
+
{action("share", GroupOutlinedIcon, "Compartilhar com a equipe", () => onPatchView(view, { shared: !view.shared }), { on: view.shared })}
|
|
202
|
+
<Box sx={{ my: 0.5, borderTop: 1, borderColor: "divider" }} />
|
|
203
|
+
{action("delete", DeleteOutlineRoundedIcon, "Excluir visão", () => onDeleteView(view), { danger: true })}
|
|
204
|
+
</Box>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Name, unsaved dot, chevron — the parts, so the toggle has one decision. */
|
|
209
|
+
function ToggleContents({
|
|
210
|
+
view,
|
|
211
|
+
open,
|
|
212
|
+
interactive,
|
|
213
|
+
testIdPrefix,
|
|
214
|
+
}: {
|
|
215
|
+
view: DisplayPanelView;
|
|
216
|
+
open: boolean;
|
|
217
|
+
interactive: boolean;
|
|
218
|
+
testIdPrefix: string;
|
|
219
|
+
}): React.JSX.Element {
|
|
220
|
+
return (
|
|
221
|
+
<>
|
|
222
|
+
<Box component="span" sx={{ fontWeight: 600 }} data-testid={`${testIdPrefix}-display-view-name`}>
|
|
223
|
+
{view.activeViewName ?? "Visão principal"}
|
|
224
|
+
</Box>
|
|
225
|
+
{view.dirty && (
|
|
226
|
+
<Box
|
|
227
|
+
component="span"
|
|
228
|
+
aria-label="Alterações não salvas"
|
|
229
|
+
data-testid={`${testIdPrefix}-display-dirty`}
|
|
230
|
+
sx={{ height: 6, width: 6, borderRadius: "50%", bgcolor: "primary.main" }}
|
|
231
|
+
/>
|
|
232
|
+
)}
|
|
233
|
+
{interactive && (
|
|
234
|
+
<KeyboardArrowDownRoundedIcon
|
|
235
|
+
fontSize="small"
|
|
236
|
+
sx={{ color: "text.disabled", transform: open ? "rotate(180deg)" : "none" }}
|
|
237
|
+
/>
|
|
238
|
+
)}
|
|
239
|
+
</>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** The name + unsaved dot; a button only when there are views to open. */
|
|
244
|
+
function ViewToggle({
|
|
245
|
+
view,
|
|
246
|
+
open,
|
|
247
|
+
onToggle,
|
|
248
|
+
testIdPrefix,
|
|
249
|
+
}: {
|
|
250
|
+
view: DisplayPanelView;
|
|
251
|
+
open: boolean;
|
|
252
|
+
onToggle: () => void;
|
|
253
|
+
testIdPrefix: string;
|
|
254
|
+
}): React.JSX.Element {
|
|
255
|
+
const interactive = Boolean(view.nav);
|
|
256
|
+
// One decision, not eight: a panel with no views renders the same row as
|
|
257
|
+
// plain text rather than as a button that opens nothing.
|
|
258
|
+
const affordance = interactive
|
|
259
|
+
? { px: 0.75, py: 0.25, cursor: "pointer", "&:hover": { bgcolor: "action.hover" } }
|
|
260
|
+
: { px: 0, py: 0, cursor: "default" };
|
|
261
|
+
return (
|
|
262
|
+
<Box
|
|
263
|
+
component={interactive ? "button" : "div"}
|
|
264
|
+
type={interactive ? "button" : undefined}
|
|
265
|
+
onClick={interactive ? onToggle : undefined}
|
|
266
|
+
aria-expanded={interactive ? open : undefined}
|
|
267
|
+
data-testid={`${testIdPrefix}-display-view-toggle`}
|
|
268
|
+
sx={{
|
|
269
|
+
ml: "auto",
|
|
270
|
+
display: "flex",
|
|
271
|
+
alignItems: "center",
|
|
272
|
+
gap: 0.75,
|
|
273
|
+
minWidth: 0,
|
|
274
|
+
border: 0,
|
|
275
|
+
borderRadius: 1,
|
|
276
|
+
font: "inherit",
|
|
277
|
+
fontSize: "0.75rem",
|
|
278
|
+
bgcolor: open ? "action.selected" : "transparent",
|
|
279
|
+
...affordance,
|
|
280
|
+
}}
|
|
281
|
+
>
|
|
282
|
+
<ToggleContents view={view} open={open} interactive={interactive} testIdPrefix={testIdPrefix} />
|
|
283
|
+
</Box>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** The VISÃO row above the tabs. */
|
|
288
|
+
export function ViewHeader(props: {
|
|
289
|
+
view: DisplayPanelView;
|
|
290
|
+
open: boolean;
|
|
291
|
+
onToggle: () => void;
|
|
292
|
+
testIdPrefix: string;
|
|
293
|
+
}): React.JSX.Element {
|
|
294
|
+
return (
|
|
295
|
+
<Box sx={{ display: "flex", alignItems: "center", gap: 1, px: 1.5, py: 1, borderBottom: 1, borderColor: "divider" }}>
|
|
296
|
+
<Text variant="caption" as="span">
|
|
297
|
+
<Box component="span" sx={{ textTransform: "uppercase", letterSpacing: 0.5, color: "text.disabled" }}>
|
|
298
|
+
Visão
|
|
299
|
+
</Box>
|
|
300
|
+
</Text>
|
|
301
|
+
<ViewToggle {...props} />
|
|
302
|
+
</Box>
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Redefinir / Salvar como nova / Atualizar, pinned below the tabs. */
|
|
307
|
+
export function ViewFooter({
|
|
308
|
+
view,
|
|
309
|
+
onDone,
|
|
310
|
+
testIdPrefix,
|
|
311
|
+
}: {
|
|
312
|
+
view: DisplayPanelView;
|
|
313
|
+
onDone: () => void;
|
|
314
|
+
testIdPrefix: string;
|
|
315
|
+
}): React.JSX.Element {
|
|
316
|
+
return (
|
|
317
|
+
<Box
|
|
318
|
+
sx={{
|
|
319
|
+
display: "flex",
|
|
320
|
+
alignItems: "center",
|
|
321
|
+
justifyContent: "space-between",
|
|
322
|
+
gap: 1,
|
|
323
|
+
px: 1.5,
|
|
324
|
+
py: 1,
|
|
325
|
+
borderTop: 1,
|
|
326
|
+
borderColor: "divider",
|
|
327
|
+
bgcolor: "action.hover",
|
|
328
|
+
}}
|
|
329
|
+
>
|
|
330
|
+
<Button
|
|
331
|
+
variant="text"
|
|
332
|
+
size="sm"
|
|
333
|
+
color="neutral"
|
|
334
|
+
disabled={!view.dirty}
|
|
335
|
+
startIcon={<RestartAltRoundedIcon fontSize="small" />}
|
|
336
|
+
onClick={view.onReset}
|
|
337
|
+
dataTestId={`${testIdPrefix}-display-reset`}
|
|
338
|
+
>
|
|
339
|
+
Redefinir
|
|
340
|
+
</Button>
|
|
341
|
+
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
|
342
|
+
{/* Only meaningful with a view APPLIED: on Visão principal the single
|
|
343
|
+
"Salvar visão" already is "save as new". */}
|
|
344
|
+
{view.onUpdate && (
|
|
345
|
+
<Button
|
|
346
|
+
variant="text"
|
|
347
|
+
size="sm"
|
|
348
|
+
color="neutral"
|
|
349
|
+
onClick={() => {
|
|
350
|
+
view.onSaveAs();
|
|
351
|
+
onDone();
|
|
352
|
+
}}
|
|
353
|
+
dataTestId={`${testIdPrefix}-display-save-as`}
|
|
354
|
+
>
|
|
355
|
+
Salvar como nova
|
|
356
|
+
</Button>
|
|
357
|
+
)}
|
|
358
|
+
{/* Enabled only when something in Ordenar / Colunas / Exibição (or the
|
|
359
|
+
filters the view also stores) differs from the applied view: the
|
|
360
|
+
filled button is a STATE — "there is something to save" — not a
|
|
361
|
+
permanent fixture. */}
|
|
362
|
+
<Button
|
|
363
|
+
size="sm"
|
|
364
|
+
disabled={!view.dirty}
|
|
365
|
+
startIcon={<SaveOutlinedIcon fontSize="small" />}
|
|
366
|
+
onClick={() => {
|
|
367
|
+
(view.onUpdate ?? view.onSaveAs)();
|
|
368
|
+
onDone();
|
|
369
|
+
}}
|
|
370
|
+
dataTestId={`${testIdPrefix}-display-save`}
|
|
371
|
+
>
|
|
372
|
+
{view.onUpdate ? "Atualizar visão" : "Salvar visão"}
|
|
373
|
+
</Button>
|
|
374
|
+
</Box>
|
|
375
|
+
</Box>
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
@@ -8,8 +8,20 @@
|
|
|
8
8
|
export { BaseCard } from "./base-card";
|
|
9
9
|
export { DataViewsGrid } from "./DataViewsGrid";
|
|
10
10
|
export { DataViewsTableBase, type DataViewsTableBaseProps } from "./DataViewsTableBase";
|
|
11
|
-
export { toSavedViewSummary, CARD_ASPECT_RATIOS } from "./data-views-types";
|
|
11
|
+
export { toSavedViewSummary, CARD_ASPECT_RATIOS, DATA_VIEWS_LAYOUTS } from "./data-views-types";
|
|
12
12
|
export { cardScaleForZoom, cardMinWidthForZoom } from "./data-views-layout-context";
|
|
13
|
+
export { DataViewsBoard, type BoardConfig, type BoardGroup } from "./DataViewsBoard";
|
|
14
|
+
export type {
|
|
15
|
+
DataViewExport,
|
|
16
|
+
DataViewExportFormat,
|
|
17
|
+
DataViewExportRequest,
|
|
18
|
+
} from "./data-views-export";
|
|
19
|
+
export {
|
|
20
|
+
DataViewsScopeTabs,
|
|
21
|
+
resolveScope,
|
|
22
|
+
assertNoScopePillOverlap,
|
|
23
|
+
type ScopeConfig,
|
|
24
|
+
} from "./data-views-scopes";
|
|
13
25
|
export type {
|
|
14
26
|
RowAction,
|
|
15
27
|
DataViewCardSelection,
|
|
@@ -17,6 +29,7 @@ export type {
|
|
|
17
29
|
SavedViewSummary,
|
|
18
30
|
DataViewState,
|
|
19
31
|
DataViewSyncState,
|
|
32
|
+
DataViewsLayout,
|
|
20
33
|
DataViewColumn,
|
|
21
34
|
FilterFieldConfig,
|
|
22
35
|
RangeFieldConfig,
|