@12-apps/ui 6.1.0 → 6.3.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/components-catalog.md +8 -0
- package/dist/{chunk-35VGGLOC.js → chunk-CEKPLUQV.js} +2 -2
- package/dist/{chunk-35VGGLOC.js.map → chunk-CEKPLUQV.js.map} +1 -1
- package/dist/{chunk-62XQWGXU.js → chunk-MXPXKORR.js} +19 -17
- package/dist/chunk-MXPXKORR.js.map +1 -0
- package/dist/{chunk-7XLEWBKL.js → chunk-N554AFDB.js} +7 -10
- package/dist/chunk-N554AFDB.js.map +1 -0
- package/dist/{chunk-JDO7W4D4.js → chunk-R5ZQZSEQ.js} +2 -20
- package/dist/{chunk-JDO7W4D4.js.map → chunk-R5ZQZSEQ.js.map} +1 -1
- package/dist/{chunk-R4TYXKDD.js → chunk-TPQRIPCN.js} +52 -48
- package/dist/chunk-TPQRIPCN.js.map +1 -0
- package/dist/copy.js +1 -0
- package/dist/copy.js.map +1 -0
- package/dist/data-display/CardKit.js +277 -0
- package/dist/data-display/CardKit.js.map +1 -0
- package/dist/data-display/DataViews.js +664 -616
- package/dist/data-display/DataViews.js.map +1 -1
- package/dist/data-display/SectionOnboarding.js +3 -3
- package/dist/data-display/SectionOnboarding.js.map +1 -1
- package/dist/feedback/ConfirmAction.js +3 -5
- package/dist/form/CategorySelect.js +1 -1
- package/dist/form/CepField.js +1 -1
- package/dist/form/total-form.js +8 -4
- package/dist/form/total-form.js.map +1 -1
- package/dist/layout/ContentToolbar.js +1 -1
- package/dist/layout/TableFilter.js +1 -1
- package/dist/pt-BR.js +222 -0
- package/dist/pt-BR.js.map +1 -0
- package/dist/types/components/data-display/CardKit/CardKebab.d.ts +23 -0
- package/dist/types/components/data-display/CardKit/CardKebab.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/CardKit.types.d.ts +55 -0
- package/dist/types/components/data-display/CardKit/CardKit.types.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/card-actions-context.d.ts +51 -0
- package/dist/types/components/data-display/CardKit/card-actions-context.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/index.d.ts +15 -0
- package/dist/types/components/data-display/CardKit/index.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/list-card-parts.d.ts +60 -0
- package/dist/types/components/data-display/CardKit/list-card-parts.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/row-actions-to-menu.d.ts +17 -0
- package/dist/types/components/data-display/CardKit/row-actions-to-menu.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts +65 -0
- package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts +60 -0
- package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/DataViewsBoard.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/DeleteViewDialog.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts +4 -1
- package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts +0 -5
- package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/base-card.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/base-list-card-gutters.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-columns-tab.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts +17 -0
- package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +205 -0
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-display-panel.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-display-tabs.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-export.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts +3 -2
- package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-scopes.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-search.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-select-all-strip.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-table-parts.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts +1 -1
- package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/index.d.ts +2 -0
- package/dist/types/components/data-display/DataViews/index.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/save-view-preview.d.ts +10 -0
- package/dist/types/components/data-display/DataViews/save-view-preview.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/use-saved-views-controller.d.ts.map +1 -1
- package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts +6 -5
- package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts +1 -3
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts +4 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts +9 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts +2 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/index.d.ts +2 -2
- package/dist/types/components/feedback/ConfirmAction/index.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts +5 -1
- package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts +4 -1
- package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts +5 -2
- package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts +5 -2
- package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts +3 -0
- package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts +5 -0
- package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts +4 -1
- package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.types.d.ts +3 -0
- package/dist/types/components/form/CepField/CepField.types.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/CategoryField.d.ts +4 -1
- package/dist/types/components/form/total-form/Fields/CategoryField.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/CepField.d.ts +4 -1
- package/dist/types/components/form/total-form/Fields/CepField.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +6 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/SavedViewsMenu.d.ts.map +1 -1
- package/dist/types/copy.d.ts +99 -0
- package/dist/types/copy.d.ts.map +1 -0
- package/dist/types/pt-BR.d.ts +28 -0
- package/dist/types/pt-BR.d.ts.map +1 -0
- package/dist/types/utils/export-rows.d.ts +31 -0
- package/dist/types/utils/export-rows.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/utils.js +50 -0
- package/dist/utils.js.map +1 -1
- package/package.json +14 -2
- package/src/components/data-display/CardKit/CardKebab.tsx +43 -0
- package/src/components/data-display/CardKit/CardKit.md +87 -0
- package/src/components/data-display/CardKit/CardKit.types.ts +60 -0
- package/src/components/data-display/CardKit/card-actions-context.tsx +98 -0
- package/src/components/data-display/CardKit/index.ts +19 -0
- package/src/components/data-display/CardKit/list-card-parts.tsx +163 -0
- package/src/components/data-display/CardKit/row-actions-to-menu.ts +29 -0
- package/src/components/data-display/CardKit/use-remove-confirm.tsx +111 -0
- package/src/components/data-display/CardKit/use-row-confirm.tsx +96 -0
- package/src/components/data-display/DataViews/DataViewsBoard.tsx +7 -4
- package/src/components/data-display/DataViews/DeleteViewDialog.tsx +6 -4
- package/src/components/data-display/DataViews/ManageViewsDialog.tsx +26 -10
- package/src/components/data-display/DataViews/SaveViewModal.tsx +56 -90
- package/src/components/data-display/DataViews/base-card.tsx +3 -1
- package/src/components/data-display/DataViews/base-list-card-gutters.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-bar-controls.tsx +8 -5
- package/src/components/data-display/DataViews/data-views-category-pill.tsx +6 -3
- package/src/components/data-display/DataViews/data-views-columns-tab.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-copy-context.tsx +43 -0
- package/src/components/data-display/DataViews/data-views-copy.ts +214 -0
- package/src/components/data-display/DataViews/data-views-display-panel.tsx +15 -9
- package/src/components/data-display/DataViews/data-views-display-tabs.tsx +19 -29
- package/src/components/data-display/DataViews/data-views-export.tsx +9 -10
- package/src/components/data-display/DataViews/data-views-filter-panel.tsx +9 -5
- package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +5 -2
- package/src/components/data-display/DataViews/data-views-more-fields.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-more-filters.tsx +6 -3
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +9 -5
- package/src/components/data-display/DataViews/data-views-range-presets.ts +7 -8
- package/src/components/data-display/DataViews/data-views-scopes.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-search.tsx +7 -4
- package/src/components/data-display/DataViews/data-views-select-all-strip.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-table-parts.tsx +7 -2
- package/src/components/data-display/DataViews/data-views-view-nav.tsx +22 -16
- package/src/components/data-display/DataViews/index.ts +20 -0
- package/src/components/data-display/DataViews/save-view-preview.tsx +78 -0
- package/src/components/data-display/DataViews/use-saved-views-controller.ts +3 -1
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +3 -3
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +8 -7
- package/src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts +2 -2
- package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +12 -5
- package/src/components/feedback/ConfirmAction/ConfirmAction.types.ts +9 -1
- package/src/components/feedback/ConfirmAction/ConfirmButton.tsx +12 -4
- package/src/components/feedback/ConfirmAction/index.ts +2 -2
- package/src/components/feedback/ConfirmAction/with-confirmation.tsx +4 -3
- package/src/components/form/CategorySelect/CategoryPanel.tsx +18 -6
- package/src/components/form/CategorySelect/CategoryPanelFoot.tsx +10 -5
- package/src/components/form/CategorySelect/CategoryPanelHead.tsx +8 -3
- package/src/components/form/CategorySelect/CategoryPanelList.tsx +17 -10
- package/src/components/form/CategorySelect/CategorySelect.tsx +3 -3
- package/src/components/form/CategorySelect/CategorySelect.types.ts +5 -0
- package/src/components/form/CategorySelect/CategoryTrigger.tsx +5 -1
- package/src/components/form/CepField/CepField.tsx +6 -9
- package/src/components/form/CepField/CepField.types.ts +3 -0
- package/src/components/form/total-form/Fields/CategoryField.tsx +5 -0
- package/src/components/form/total-form/Fields/CepField.tsx +5 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +6 -1
- package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +1 -21
- package/src/components/layout/TableFilter/TableFilter.tsx +1 -1
- package/src/copy.ts +103 -0
- package/src/pt-BR.ts +247 -0
- package/src/utils/export-rows.ts +95 -0
- package/src/utils/index.ts +1 -0
- package/dist/chunk-62XQWGXU.js.map +0 -1
- package/dist/chunk-7XLEWBKL.js.map +0 -1
- package/dist/chunk-R4TYXKDD.js.map +0 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState, type JSX } from 'react';
|
|
4
|
+
|
|
5
|
+
import type { ConfirmActionCopy } from '../../../copy';
|
|
6
|
+
import { ConfirmActionDialog, useConfirmAction } from '../../feedback/ConfirmAction';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* How the popup should read for the rows about to be acted on.
|
|
10
|
+
*
|
|
11
|
+
* Built from the SELECTION rather than from a single row, because the same
|
|
12
|
+
* guard covers a bulk action: "Delete 4 categories?" and "Delete the category
|
|
13
|
+
* Drinks?" are the same question asked of a different-sized selection — and an
|
|
14
|
+
* operator who multi-selected by mistake is exactly who this popup is for.
|
|
15
|
+
*/
|
|
16
|
+
export interface RowConfirmCopy {
|
|
17
|
+
title: string;
|
|
18
|
+
description: string;
|
|
19
|
+
/** Echoed into the popup; omit for a multi-row selection the title covers. */
|
|
20
|
+
entityName?: string;
|
|
21
|
+
/** The VERB. Required, never defaulted — see {@link useRowConfirm}. */
|
|
22
|
+
confirmText: string;
|
|
23
|
+
/** Override where the word "cancel" would mean the ACTION itself. */
|
|
24
|
+
cancelText?: string;
|
|
25
|
+
/** Require typing this before the confirm enables — for the unrecoverable few. */
|
|
26
|
+
typeToConfirm?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface RowConfirmOptions<T> {
|
|
30
|
+
/**
|
|
31
|
+
* The destructive write, over the whole selection. Called ONLY after the
|
|
32
|
+
* operator confirms; throw (or reject) to keep the popup open carrying the
|
|
33
|
+
* message.
|
|
34
|
+
*/
|
|
35
|
+
write: (rows: T[]) => Promise<unknown>;
|
|
36
|
+
/** The wording, given the selection. */
|
|
37
|
+
describe: (rows: T[]) => RowConfirmCopy;
|
|
38
|
+
dataTestId: string;
|
|
39
|
+
/** Shown when `write` fails without a message of its own. */
|
|
40
|
+
errorText: string;
|
|
41
|
+
/** The dialog's own words. REQUIRED — this package ships no default copy. */
|
|
42
|
+
copy: ConfirmActionCopy;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface RowConfirm<T> {
|
|
46
|
+
/** Hand this a grid action's `rows`: it opens the popup and writes nothing. */
|
|
47
|
+
request: (rows: T[]) => void;
|
|
48
|
+
/** Render next to the grid. */
|
|
49
|
+
dialog: JSX.Element | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Confirmation for a grid's `RowAction` — the per-row kebab entry and the
|
|
54
|
+
* multi-select actions menu both, since they run the same handler.
|
|
55
|
+
*
|
|
56
|
+
* The SELECTION is held while the popup is open, so the write sees exactly the
|
|
57
|
+
* rows the operator was looking at when they were asked. Re-reading the grid's
|
|
58
|
+
* live selection at confirm time is the bug this shape avoids: the list can
|
|
59
|
+
* refresh underneath an open dialog.
|
|
60
|
+
*
|
|
61
|
+
* `confirmText` is required and comes from `describe`, with no default. A verb
|
|
62
|
+
* defaulted in the origin's language reads as finished to the next adopter
|
|
63
|
+
* right up until an operator sees it — and `ConfirmOptions` already refuses to
|
|
64
|
+
* default one for the same reason.
|
|
65
|
+
*/
|
|
66
|
+
export function useRowConfirm<T>({
|
|
67
|
+
write,
|
|
68
|
+
describe,
|
|
69
|
+
dataTestId,
|
|
70
|
+
errorText,
|
|
71
|
+
copy,
|
|
72
|
+
}: RowConfirmOptions<T>): RowConfirm<T> {
|
|
73
|
+
const [target, setTarget] = useState<T[] | null>(null);
|
|
74
|
+
|
|
75
|
+
const state = useConfirmAction(async () => {
|
|
76
|
+
if (!target) return;
|
|
77
|
+
await write(target);
|
|
78
|
+
setTarget(null);
|
|
79
|
+
}, errorText);
|
|
80
|
+
|
|
81
|
+
const request = (rows: T[]): void => {
|
|
82
|
+
// An empty selection has nothing to confirm — asking would be a popup about
|
|
83
|
+
// nothing, and confirming it would write nothing.
|
|
84
|
+
if (rows.length === 0) return;
|
|
85
|
+
setTarget(rows);
|
|
86
|
+
state.request();
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
request,
|
|
91
|
+
dialog: target ? (
|
|
92
|
+
<ConfirmActionDialog state={state}
|
|
93
|
+
copy={copy} {...describe(target)} dataTestId={dataTestId} />
|
|
94
|
+
) : null,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
3
4
|
import { Box } from "../../../mui/Box";
|
|
4
5
|
import { Text } from "../../typography/Text";
|
|
5
6
|
|
|
@@ -134,6 +135,7 @@ function BoardColumnHeader({
|
|
|
134
135
|
sum: string | null;
|
|
135
136
|
testId: string;
|
|
136
137
|
}): React.JSX.Element {
|
|
138
|
+
const copy = useDataViewsCopy();
|
|
137
139
|
return (
|
|
138
140
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 0.25 }}>
|
|
139
141
|
<Box sx={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: 1 }}>
|
|
@@ -146,10 +148,10 @@ function BoardColumnHeader({
|
|
|
146
148
|
<Box
|
|
147
149
|
component="span"
|
|
148
150
|
data-testid={`${testId}-count`}
|
|
149
|
-
aria-label={
|
|
151
|
+
aria-label={copy.board.countOnPage(label, count)}
|
|
150
152
|
sx={{ color: "text.secondary", whiteSpace: "nowrap" }}
|
|
151
153
|
>
|
|
152
|
-
{count}
|
|
154
|
+
{copy.board.onThisPage(count)}
|
|
153
155
|
</Box>
|
|
154
156
|
</Text>
|
|
155
157
|
</Box>
|
|
@@ -158,7 +160,7 @@ function BoardColumnHeader({
|
|
|
158
160
|
<Box
|
|
159
161
|
component="span"
|
|
160
162
|
data-testid={`${testId}-sum`}
|
|
161
|
-
aria-label={
|
|
163
|
+
aria-label={copy.board.pageSum(sum)}
|
|
162
164
|
sx={{ color: "text.secondary" }}
|
|
163
165
|
>
|
|
164
166
|
{sum}
|
|
@@ -283,6 +285,7 @@ export function DataViewsBoard<T extends Record<string, unknown>>({
|
|
|
283
285
|
cardScale,
|
|
284
286
|
dataTestId,
|
|
285
287
|
}: DataViewsBoardProps<T>): React.JSX.Element {
|
|
288
|
+
const copy = useDataViewsCopy();
|
|
286
289
|
const columns = groupRows(rows, board);
|
|
287
290
|
const width = Math.max(MIN_COLUMN_WIDTH, Math.round(BASE_COLUMN_WIDTH * cardScale));
|
|
288
291
|
const testId = dataTestId ? `${dataTestId}-board` : "data-views-board";
|
|
@@ -290,7 +293,7 @@ export function DataViewsBoard<T extends Record<string, unknown>>({
|
|
|
290
293
|
<Box sx={{ mt: 1.5 }}>
|
|
291
294
|
<Text variant="caption" as="p">
|
|
292
295
|
<Box component="span" data-testid={`${testId}-scale-note`} sx={{ color: "text.secondary" }}>
|
|
293
|
-
|
|
296
|
+
{copy.board.pageScopeNote}
|
|
294
297
|
</Box>
|
|
295
298
|
</Text>
|
|
296
299
|
<Box
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* records are untouched, and warns separately when the view is SHARED, because
|
|
13
13
|
* that deletion takes it from everyone rather than from one person.
|
|
14
14
|
*/
|
|
15
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
15
16
|
import { Dialog, DialogContent } from "../../feedback/Dialog";
|
|
16
17
|
import { Button } from "../../form/Button";
|
|
17
18
|
import { Stack } from "../../../mui/Stack";
|
|
@@ -33,12 +34,13 @@ export function DeleteViewDialog({
|
|
|
33
34
|
entityLabel?: string;
|
|
34
35
|
testIdPrefix?: string;
|
|
35
36
|
}): React.JSX.Element | null {
|
|
37
|
+
const copy = useDataViewsCopy();
|
|
36
38
|
if (!view) return null;
|
|
37
39
|
return (
|
|
38
40
|
<Dialog
|
|
39
41
|
open
|
|
40
42
|
onClose={onClose}
|
|
41
|
-
title=
|
|
43
|
+
title={copy.deleteView.title}
|
|
42
44
|
size="sm"
|
|
43
45
|
showCloseButton
|
|
44
46
|
dataTestId={`${testIdPrefix}-delete-modal`}
|
|
@@ -51,12 +53,12 @@ export function DeleteViewDialog({
|
|
|
51
53
|
|
|
52
54
|
{view.shared && (
|
|
53
55
|
<Text variant="body" color="warning" as="p" data-testid={`${testIdPrefix}-delete-shared`}>
|
|
54
|
-
|
|
56
|
+
{copy.deleteView.sharedWarning}
|
|
55
57
|
</Text>
|
|
56
58
|
)}
|
|
57
59
|
|
|
58
60
|
<Text variant="body" color="secondary" as="p">
|
|
59
|
-
{entityLabel}
|
|
61
|
+
{copy.deleteView.rowsUnaffected(entityLabel)}
|
|
60
62
|
</Text>
|
|
61
63
|
|
|
62
64
|
<Stack direction="row" spacing={1.5} sx={{ justifyContent: "flex-end", pt: 0.5 }}>
|
|
@@ -73,7 +75,7 @@ export function DeleteViewDialog({
|
|
|
73
75
|
onClick={() => onConfirm(view)}
|
|
74
76
|
dataTestId={`${testIdPrefix}-delete-confirm`}
|
|
75
77
|
>
|
|
76
|
-
|
|
78
|
+
{copy.deleteView.confirm}
|
|
77
79
|
</Button>
|
|
78
80
|
</Stack>
|
|
79
81
|
</Stack>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
import type { ConfirmActionCopy } from "../../../copy";
|
|
6
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
7
|
+
import { createConfirmButton } from "../../feedback/ConfirmAction";
|
|
4
8
|
import { Dialog, DialogContent } from "../../feedback/Dialog";
|
|
5
9
|
import { Button } from "../../form/Button";
|
|
6
10
|
import { Box } from "../../../mui/Box";
|
|
@@ -10,6 +14,8 @@ import { Text } from "../../typography/Text";
|
|
|
10
14
|
import type { SavedViewSummary } from "./data-views-types";
|
|
11
15
|
|
|
12
16
|
interface ManageViewsDialogProps {
|
|
17
|
+
/** The confirm dialog's words. REQUIRED — this package ships no default copy. */
|
|
18
|
+
confirmCopy: ConfirmActionCopy;
|
|
13
19
|
open: boolean;
|
|
14
20
|
onClose: () => void;
|
|
15
21
|
views: SavedViewSummary[];
|
|
@@ -19,11 +25,12 @@ interface ManageViewsDialogProps {
|
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
function tags(view: SavedViewSummary): string[] {
|
|
28
|
+
const copy = useDataViewsCopy();
|
|
22
29
|
const list: string[] = [];
|
|
23
|
-
if (view.isDefault) list.push(
|
|
30
|
+
if (view.isDefault) list.push(copy.manageViews.defaultTag);
|
|
24
31
|
if (view.pinned) list.push("Fixada");
|
|
25
32
|
if (view.shared) list.push("Compartilhada");
|
|
26
|
-
if (!view.isOwner) list.push(
|
|
33
|
+
if (!view.isOwner) list.push(copy.manageViews.otherUserTag);
|
|
27
34
|
return list;
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -37,12 +44,19 @@ function ManageViewRow({
|
|
|
37
44
|
onEdit,
|
|
38
45
|
onDelete,
|
|
39
46
|
testIdPrefix,
|
|
47
|
+
confirmCopy,
|
|
40
48
|
}: {
|
|
41
49
|
view: SavedViewSummary;
|
|
42
50
|
onEdit: (view: SavedViewSummary) => void;
|
|
43
51
|
onDelete: (view: SavedViewSummary) => void;
|
|
44
52
|
testIdPrefix: string;
|
|
53
|
+
confirmCopy: ConfirmActionCopy;
|
|
45
54
|
}): React.JSX.Element {
|
|
55
|
+
const ConfirmButton = useMemo(
|
|
56
|
+
() => createConfirmButton(confirmCopy, confirmCopy.defaultError),
|
|
57
|
+
[confirmCopy],
|
|
58
|
+
);
|
|
59
|
+
const copy = useDataViewsCopy();
|
|
46
60
|
return (
|
|
47
61
|
<Stack
|
|
48
62
|
direction="row"
|
|
@@ -83,15 +97,15 @@ function ManageViewRow({
|
|
|
83
97
|
color="danger"
|
|
84
98
|
onClick={() => onDelete(view)}
|
|
85
99
|
confirm={{
|
|
86
|
-
title:
|
|
100
|
+
title: copy.manageViews.deleteTitle,
|
|
87
101
|
entityName: view.name,
|
|
88
102
|
description:
|
|
89
|
-
|
|
90
|
-
confirmText:
|
|
103
|
+
copy.manageViews.deleteBody,
|
|
104
|
+
confirmText: copy.manageViews.deleteConfirm,
|
|
91
105
|
}}
|
|
92
106
|
dataTestId={`${testIdPrefix}-manage-delete-${view.id}`}
|
|
93
107
|
>
|
|
94
|
-
|
|
108
|
+
{copy.manageViews.deleteConfirm}
|
|
95
109
|
</ConfirmButton>
|
|
96
110
|
</Stack>
|
|
97
111
|
)}
|
|
@@ -106,12 +120,14 @@ export function ManageViewsDialog({
|
|
|
106
120
|
onEdit,
|
|
107
121
|
onDelete,
|
|
108
122
|
testIdPrefix = "views",
|
|
123
|
+
confirmCopy,
|
|
109
124
|
}: ManageViewsDialogProps): React.JSX.Element {
|
|
125
|
+
const copy = useDataViewsCopy();
|
|
110
126
|
return (
|
|
111
127
|
<Dialog
|
|
112
128
|
open={open}
|
|
113
129
|
onClose={onClose}
|
|
114
|
-
title=
|
|
130
|
+
title={copy.manageViews.title}
|
|
115
131
|
size="md"
|
|
116
132
|
showCloseButton
|
|
117
133
|
dataTestId={`${testIdPrefix}-manage-dialog`}
|
|
@@ -120,11 +136,11 @@ export function ManageViewsDialog({
|
|
|
120
136
|
<Stack spacing={1.5} data-testid={`${testIdPrefix}-manage-list`}>
|
|
121
137
|
{views.length === 0 ? (
|
|
122
138
|
<Text variant="body" as="p">
|
|
123
|
-
|
|
139
|
+
{copy.manageViews.empty}
|
|
124
140
|
</Text>
|
|
125
141
|
) : (
|
|
126
142
|
views.map((view) => (
|
|
127
|
-
<ManageViewRow
|
|
143
|
+
<ManageViewRow confirmCopy={confirmCopy}
|
|
128
144
|
key={view.id}
|
|
129
145
|
view={view}
|
|
130
146
|
onEdit={onEdit}
|
|
@@ -5,6 +5,7 @@ import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined";
|
|
|
5
5
|
import StarOutlineRoundedIcon from "@mui/icons-material/StarOutlineRounded";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
|
|
8
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
8
9
|
import { Dialog, DialogContent } from "../../feedback/Dialog";
|
|
9
10
|
import { Button } from "../../form/Button";
|
|
10
11
|
import { Input } from "../../form/Input";
|
|
@@ -14,6 +15,7 @@ import { Stack } from "../../../mui/Stack";
|
|
|
14
15
|
import { Text } from "../../typography/Text";
|
|
15
16
|
|
|
16
17
|
import { describeViewState } from "./data-views-preview";
|
|
18
|
+
import { PreviewBox } from "./save-view-preview";
|
|
17
19
|
import type {
|
|
18
20
|
DataViewColumn,
|
|
19
21
|
DataViewState,
|
|
@@ -119,28 +121,29 @@ function FlagsSwitches({
|
|
|
119
121
|
setIsDefault,
|
|
120
122
|
testIdPrefix,
|
|
121
123
|
}: FlagsSwitchesProps): React.JSX.Element {
|
|
124
|
+
const copy = useDataViewsCopy();
|
|
122
125
|
return (
|
|
123
126
|
<Stack spacing={0}>
|
|
124
127
|
<FlagRow
|
|
125
128
|
icon={<PushPinOutlinedIcon fontSize="small" />}
|
|
126
|
-
title=
|
|
127
|
-
description=
|
|
129
|
+
title={copy.saveView.pinnedTitle}
|
|
130
|
+
description={copy.saveView.pinnedDescription}
|
|
128
131
|
checked={pinned}
|
|
129
132
|
onChange={setPinned}
|
|
130
133
|
testId={`${testIdPrefix}-save-pinned`}
|
|
131
134
|
/>
|
|
132
135
|
<FlagRow
|
|
133
136
|
icon={<GroupOutlinedIcon fontSize="small" />}
|
|
134
|
-
title=
|
|
135
|
-
description=
|
|
137
|
+
title={copy.saveView.sharedTitle}
|
|
138
|
+
description={copy.saveView.sharedDescription}
|
|
136
139
|
checked={shared}
|
|
137
140
|
onChange={setShared}
|
|
138
141
|
testId={`${testIdPrefix}-save-shared`}
|
|
139
142
|
/>
|
|
140
143
|
<FlagRow
|
|
141
144
|
icon={<StarOutlineRoundedIcon fontSize="small" />}
|
|
142
|
-
title=
|
|
143
|
-
description=
|
|
145
|
+
title={copy.saveView.setDefaultTitle}
|
|
146
|
+
description={copy.saveView.setDefaultDescription}
|
|
144
147
|
checked={isDefault}
|
|
145
148
|
onChange={setIsDefault}
|
|
146
149
|
testId={`${testIdPrefix}-save-default`}
|
|
@@ -149,70 +152,6 @@ function FlagsSwitches({
|
|
|
149
152
|
);
|
|
150
153
|
}
|
|
151
154
|
|
|
152
|
-
interface PreviewBoxProps {
|
|
153
|
-
preview: { filters: string[]; columns: string[]; sort: string[] };
|
|
154
|
-
testIdPrefix: string;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/** One "label — value" line of the summary. */
|
|
158
|
-
function SummaryRow({
|
|
159
|
-
label,
|
|
160
|
-
items,
|
|
161
|
-
testId,
|
|
162
|
-
}: {
|
|
163
|
-
label: string;
|
|
164
|
-
items: string[];
|
|
165
|
-
testId: string;
|
|
166
|
-
}): React.JSX.Element | null {
|
|
167
|
-
if (items.length === 0) return null;
|
|
168
|
-
return (
|
|
169
|
-
<Box sx={{ display: "flex", gap: 1.5 }} data-testid={testId}>
|
|
170
|
-
<Text variant="caption" as="span">
|
|
171
|
-
<Box component="span" sx={{ width: 116, flexShrink: 0, color: "text.secondary" }}>
|
|
172
|
-
{label}
|
|
173
|
-
</Box>
|
|
174
|
-
</Text>
|
|
175
|
-
<Text variant="caption" as="span">
|
|
176
|
-
<Box component="span" sx={{ minWidth: 0, flex: 1 }}>
|
|
177
|
-
{items.join(", ")}
|
|
178
|
-
</Box>
|
|
179
|
-
</Text>
|
|
180
|
-
</Box>
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function PreviewBox({ preview, testIdPrefix }: PreviewBoxProps): React.JSX.Element {
|
|
185
|
-
const empty =
|
|
186
|
-
preview.filters.length === 0 && preview.columns.length === 0 && preview.sort.length === 0;
|
|
187
|
-
return (
|
|
188
|
-
<Box sx={{ p: 1.5, borderRadius: 1.5, bgcolor: "action.hover", border: (theme) => `1px solid ${theme.palette.divider}` }}>
|
|
189
|
-
<Text variant="caption" as="p">
|
|
190
|
-
<Box
|
|
191
|
-
component="span"
|
|
192
|
-
sx={{ display: "block", mb: 1, textTransform: "uppercase", letterSpacing: 0.6, fontWeight: 600, color: "text.disabled" }}
|
|
193
|
-
>
|
|
194
|
-
O que esta visão guarda
|
|
195
|
-
</Box>
|
|
196
|
-
</Text>
|
|
197
|
-
{empty ? (
|
|
198
|
-
// Saving is still allowed — an operator may be naming the default on
|
|
199
|
-
// purpose — but it should not be a surprise afterwards.
|
|
200
|
-
<Text variant="caption" as="p">
|
|
201
|
-
<Box component="span" sx={{ color: "warning.main", lineHeight: 1.6 }} data-testid={`${testIdPrefix}-preview-empty`}>
|
|
202
|
-
Nada foi alterado — esta visão ficará igual à Visão principal.
|
|
203
|
-
</Box>
|
|
204
|
-
</Text>
|
|
205
|
-
) : (
|
|
206
|
-
<Stack spacing={0.75}>
|
|
207
|
-
<SummaryRow label="Filtros" items={preview.filters} testId={`${testIdPrefix}-preview-filters`} />
|
|
208
|
-
<SummaryRow label="Colunas ocultas" items={preview.columns} testId={`${testIdPrefix}-preview-columns`} />
|
|
209
|
-
<SummaryRow label="Ordenação" items={preview.sort} testId={`${testIdPrefix}-preview-sort`} />
|
|
210
|
-
</Stack>
|
|
211
|
-
)}
|
|
212
|
-
</Box>
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
155
|
interface SaveViewFormState {
|
|
217
156
|
name: string;
|
|
218
157
|
description: string;
|
|
@@ -248,6 +187,7 @@ function useSaveViewForm(
|
|
|
248
187
|
editing: SavedViewSummary | null | undefined,
|
|
249
188
|
onSave: (payload: SaveViewPayload) => Promise<void> | void,
|
|
250
189
|
): SaveViewFormState {
|
|
190
|
+
const copy = useDataViewsCopy();
|
|
251
191
|
const initial = seedForm(editing);
|
|
252
192
|
const [name, setName] = useState(initial.name);
|
|
253
193
|
const [description, setDescription] = useState(initial.description);
|
|
@@ -267,7 +207,7 @@ function useSaveViewForm(
|
|
|
267
207
|
try {
|
|
268
208
|
await onSave({ name: name.trim(), description: description.trim(), shared, pinned, isDefault });
|
|
269
209
|
} catch (cause) {
|
|
270
|
-
setError(cause instanceof Error ? cause.message :
|
|
210
|
+
setError(cause instanceof Error ? cause.message : copy.saveView.saveFailed);
|
|
271
211
|
} finally {
|
|
272
212
|
setSaving(false);
|
|
273
213
|
}
|
|
@@ -295,6 +235,38 @@ function useSaveViewForm(
|
|
|
295
235
|
* share / default flags, and previews the filters, visible columns, and sort the
|
|
296
236
|
* view will store. Used for both create and edit.
|
|
297
237
|
*/
|
|
238
|
+
/**
|
|
239
|
+
* The dialog's two buttons.
|
|
240
|
+
*
|
|
241
|
+
* Cancel first, primary last: the confirming action sits where the eye lands
|
|
242
|
+
* at the end of the dialog, not before the way out.
|
|
243
|
+
*/
|
|
244
|
+
function FormFooter({
|
|
245
|
+
editing,
|
|
246
|
+
canSave,
|
|
247
|
+
onSubmit,
|
|
248
|
+
onClose,
|
|
249
|
+
testIdPrefix,
|
|
250
|
+
}: {
|
|
251
|
+
editing: SaveViewModalProps<never>["editing"];
|
|
252
|
+
canSave: boolean;
|
|
253
|
+
onSubmit: () => void;
|
|
254
|
+
onClose: () => void;
|
|
255
|
+
testIdPrefix: string;
|
|
256
|
+
}): React.JSX.Element {
|
|
257
|
+
const copy = useDataViewsCopy();
|
|
258
|
+
return (
|
|
259
|
+
<Stack direction="row" spacing={1.5} sx={{ justifyContent: "flex-end" }}>
|
|
260
|
+
<Button variant="text" color="neutral" onClick={onClose} dataTestId={`${testIdPrefix}-save-cancel`}>
|
|
261
|
+
{copy.saveView.cancel}
|
|
262
|
+
</Button>
|
|
263
|
+
<Button onClick={onSubmit} disabled={!canSave} dataTestId={`${testIdPrefix}-save-submit`}>
|
|
264
|
+
{editing ? copy.saveView.submitEditing : copy.saveView.submitCreating}
|
|
265
|
+
</Button>
|
|
266
|
+
</Stack>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
298
270
|
export function SaveViewModal<T extends Record<string, unknown>>({
|
|
299
271
|
open,
|
|
300
272
|
onClose,
|
|
@@ -305,6 +277,7 @@ export function SaveViewModal<T extends Record<string, unknown>>({
|
|
|
305
277
|
onSave,
|
|
306
278
|
testIdPrefix = "view",
|
|
307
279
|
}: SaveViewModalProps<T>): React.JSX.Element {
|
|
280
|
+
const copy = useDataViewsCopy();
|
|
308
281
|
const form = useSaveViewForm(editing, onSave);
|
|
309
282
|
const preview = describeViewState(currentState, fields, columns);
|
|
310
283
|
|
|
@@ -312,7 +285,7 @@ export function SaveViewModal<T extends Record<string, unknown>>({
|
|
|
312
285
|
<Dialog
|
|
313
286
|
open={open}
|
|
314
287
|
onClose={onClose}
|
|
315
|
-
title={editing ?
|
|
288
|
+
title={editing ? copy.saveView.titleEditing : copy.saveView.titleCreating}
|
|
316
289
|
size="sm"
|
|
317
290
|
showCloseButton
|
|
318
291
|
dataTestId={`${testIdPrefix}-save-modal`}
|
|
@@ -322,8 +295,8 @@ export function SaveViewModal<T extends Record<string, unknown>>({
|
|
|
322
295
|
<Input
|
|
323
296
|
size="sm"
|
|
324
297
|
fullWidth
|
|
325
|
-
label=
|
|
326
|
-
placeholder=
|
|
298
|
+
label={copy.saveView.nameLabel}
|
|
299
|
+
placeholder={copy.saveView.namePlaceholder}
|
|
327
300
|
value={form.name}
|
|
328
301
|
onChange={(event) => form.setName(event.target.value)}
|
|
329
302
|
data-testid={`${testIdPrefix}-save-name`}
|
|
@@ -331,8 +304,8 @@ export function SaveViewModal<T extends Record<string, unknown>>({
|
|
|
331
304
|
<Input
|
|
332
305
|
size="sm"
|
|
333
306
|
fullWidth
|
|
334
|
-
label=
|
|
335
|
-
placeholder=
|
|
307
|
+
label={copy.saveView.descriptionLabel}
|
|
308
|
+
placeholder={copy.saveView.descriptionPlaceholder}
|
|
336
309
|
value={form.description}
|
|
337
310
|
onChange={(event) => form.setDescription(event.target.value)}
|
|
338
311
|
data-testid={`${testIdPrefix}-save-description`}
|
|
@@ -356,20 +329,13 @@ export function SaveViewModal<T extends Record<string, unknown>>({
|
|
|
356
329
|
</Text>
|
|
357
330
|
)}
|
|
358
331
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
onClick={() => void form.submit()}
|
|
367
|
-
disabled={!form.canSave}
|
|
368
|
-
dataTestId={`${testIdPrefix}-save-submit`}
|
|
369
|
-
>
|
|
370
|
-
{editing ? "Salvar alterações" : "Salvar visão"}
|
|
371
|
-
</Button>
|
|
372
|
-
</Stack>
|
|
332
|
+
<FormFooter
|
|
333
|
+
editing={editing}
|
|
334
|
+
canSave={form.canSave}
|
|
335
|
+
onSubmit={() => void form.submit()}
|
|
336
|
+
onClose={onClose}
|
|
337
|
+
testIdPrefix={testIdPrefix}
|
|
338
|
+
/>
|
|
373
339
|
</Stack>
|
|
374
340
|
</DialogContent>
|
|
375
341
|
</Dialog>
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type CardSurfaceProps,
|
|
23
23
|
} from "./card-surface";
|
|
24
24
|
import { CARD_ASPECT_RATIOS, type CardAspectRatio } from "./data-views-types";
|
|
25
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
25
26
|
|
|
26
27
|
export interface BaseCardProps extends CardSurfaceProps {
|
|
27
28
|
/** Extra body content below the caption (chips, meta). Optional. */
|
|
@@ -127,6 +128,7 @@ function CardOverlays({
|
|
|
127
128
|
checkboxTestId,
|
|
128
129
|
menu,
|
|
129
130
|
}: Pick<BaseCardProps, "selected" | "onToggleSelect" | "checkboxTestId" | "menu">): React.JSX.Element {
|
|
131
|
+
const copy = useDataViewsCopy();
|
|
130
132
|
return (
|
|
131
133
|
<>
|
|
132
134
|
{onToggleSelect && (
|
|
@@ -138,7 +140,7 @@ function CardOverlays({
|
|
|
138
140
|
onClick={(event) => event.stopPropagation()}
|
|
139
141
|
size="small"
|
|
140
142
|
data-testid={checkboxTestId}
|
|
141
|
-
aria-label=
|
|
143
|
+
aria-label={copy.selection.selectRow}
|
|
142
144
|
/>
|
|
143
145
|
</Box>
|
|
144
146
|
)}
|
|
@@ -7,6 +7,7 @@ import { Checkbox } from "../../form/Checkbox";
|
|
|
7
7
|
import { Box } from "../../../mui/Box";
|
|
8
8
|
|
|
9
9
|
import { DragHandle, useDragItem } from "./data-views-drag";
|
|
10
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* THE THREE GUTTERS AT THE HEAD OF A ROW — the disclosure chevron, the drag grip
|
|
@@ -72,6 +73,7 @@ export function SelectSlot({
|
|
|
72
73
|
onToggleSelect?: (event?: React.MouseEvent) => void;
|
|
73
74
|
testId?: string;
|
|
74
75
|
}): React.JSX.Element | null {
|
|
76
|
+
const copy = useDataViewsCopy();
|
|
75
77
|
if (!selectable) return reserve ? <Box data-slot="select" /> : null;
|
|
76
78
|
return (
|
|
77
79
|
// z-index 1: above the stretched link, or the anchor swallows the click.
|
|
@@ -88,7 +90,7 @@ export function SelectSlot({
|
|
|
88
90
|
}}
|
|
89
91
|
size="small"
|
|
90
92
|
data-testid={testId}
|
|
91
|
-
aria-label=
|
|
93
|
+
aria-label={copy.selection.selectRow}
|
|
92
94
|
/>
|
|
93
95
|
</Box>
|
|
94
96
|
);
|
|
@@ -15,6 +15,7 @@ import FilterAltOffRoundedIcon from "@mui/icons-material/FilterAltOffRounded";
|
|
|
15
15
|
import { Tooltip } from "@mui/material";
|
|
16
16
|
|
|
17
17
|
import { Box } from "../../../mui/Box";
|
|
18
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* "Limpar" — one gesture back to the unfiltered list.
|
|
@@ -38,6 +39,7 @@ export function ClearAllControl({
|
|
|
38
39
|
compact: boolean;
|
|
39
40
|
testIdPrefix: string;
|
|
40
41
|
}): React.JSX.Element {
|
|
42
|
+
const copy = useDataViewsCopy();
|
|
41
43
|
// No border, no fill. Every other control on this row is an outlined pill
|
|
42
44
|
// because it OPENS something; this one is an escape hatch, and giving it the
|
|
43
45
|
// same weight made it read as a sixth filter. Quiet until hovered.
|
|
@@ -47,7 +49,7 @@ export function ClearAllControl({
|
|
|
47
49
|
type="button"
|
|
48
50
|
onClick={onClearAll}
|
|
49
51
|
data-testid={`${testIdPrefix}-clear-all`}
|
|
50
|
-
aria-label=
|
|
52
|
+
aria-label={copy.filters.clearAll}
|
|
51
53
|
sx={{
|
|
52
54
|
display: "inline-flex",
|
|
53
55
|
alignItems: "center",
|
|
@@ -66,10 +68,10 @@ export function ClearAllControl({
|
|
|
66
68
|
}}
|
|
67
69
|
>
|
|
68
70
|
<FilterAltOffRoundedIcon sx={{ fontSize: 16 }} />
|
|
69
|
-
{!compact && <Box component="span">
|
|
71
|
+
{!compact && <Box component="span">{copy.filters.clear}</Box>}
|
|
70
72
|
</Box>
|
|
71
73
|
);
|
|
72
|
-
return compact ? <Tooltip title=
|
|
74
|
+
return compact ? <Tooltip title={copy.filters.clearAll}>{button}</Tooltip> : button;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
/**
|
|
@@ -91,13 +93,14 @@ export function CloseSearchControl({
|
|
|
91
93
|
onClose: () => void;
|
|
92
94
|
testIdPrefix: string;
|
|
93
95
|
}): React.JSX.Element {
|
|
96
|
+
const copy = useDataViewsCopy();
|
|
94
97
|
return (
|
|
95
|
-
<Tooltip title=
|
|
98
|
+
<Tooltip title={copy.search.close}>
|
|
96
99
|
<Box
|
|
97
100
|
component="button"
|
|
98
101
|
type="button"
|
|
99
102
|
onClick={onClose}
|
|
100
|
-
aria-label=
|
|
103
|
+
aria-label={copy.search.close}
|
|
101
104
|
data-testid={`${testIdPrefix}-search-close`}
|
|
102
105
|
sx={{
|
|
103
106
|
display: "inline-flex",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
3
4
|
import { CategorySelect } from "../../form/CategorySelect";
|
|
4
5
|
import { MultiSelectDropdown } from "../../layout/ContentToolbar";
|
|
5
6
|
|
|
@@ -65,10 +66,12 @@ export function PillControl<T extends Record<string, unknown>>({
|
|
|
65
66
|
testIdPrefix,
|
|
66
67
|
layout = "pill",
|
|
67
68
|
}: PillControlProps<T>): React.JSX.Element {
|
|
69
|
+
const copy = useDataViewsCopy();
|
|
68
70
|
const testId = `${testIdPrefix}-filter-${fieldId}`;
|
|
69
71
|
if (pill.control === "category") {
|
|
70
72
|
return (
|
|
71
73
|
<CategorySelect
|
|
74
|
+
copy={copy.categorySelect}
|
|
72
75
|
placeholder={pill.label}
|
|
73
76
|
label={layout === "stacked" ? pill.label : undefined}
|
|
74
77
|
fullWidth={layout === "stacked"}
|
|
@@ -86,10 +89,10 @@ export function PillControl<T extends Record<string, unknown>>({
|
|
|
86
89
|
selected={new Set(selected)}
|
|
87
90
|
onToggle={(value, checked) => onTogglePill(fieldId, value, checked)}
|
|
88
91
|
onClear={() => onClearField(fieldId)}
|
|
89
|
-
allLabel=
|
|
92
|
+
allLabel={copy.filters.allOption}
|
|
90
93
|
searchable={pill.searchEnabled ? true : undefined}
|
|
91
|
-
searchPlaceholder=
|
|
92
|
-
noResultsLabel=
|
|
94
|
+
searchPlaceholder={copy.filters.optionSearchPlaceholder}
|
|
95
|
+
noResultsLabel={copy.filters.optionsEmpty}
|
|
93
96
|
layout={layout}
|
|
94
97
|
onOpenChange={onOpenChange}
|
|
95
98
|
data-testid={testId}
|