@12-apps/ui 6.2.0 → 6.3.1
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/{chunk-35VGGLOC.js → chunk-CEKPLUQV.js} +2 -2
- package/dist/{chunk-35VGGLOC.js.map → chunk-CEKPLUQV.js.map} +1 -1
- 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/{chunk-62XQWGXU.js → chunk-WFPXRSIZ.js} +20 -18
- package/dist/chunk-WFPXRSIZ.js.map +1 -0
- package/dist/copy.js +1 -0
- package/dist/copy.js.map +1 -0
- package/dist/data-display/CardKit.js +15 -4
- package/dist/data-display/CardKit.js.map +1 -1
- 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/use-remove-confirm.d.ts +4 -1
- package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts.map +1 -1
- package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts +5 -2
- package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts.map +1 -1
- 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/package.json +10 -2
- package/src/components/data-display/CardKit/use-remove-confirm.tsx +5 -0
- package/src/components/data-display/CardKit/use-row-confirm.tsx +7 -2
- 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 +20 -6
- 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/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,78 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What a saved view actually GUARDS, listed before it is saved.
|
|
5
|
+
*
|
|
6
|
+
* Split out of `SaveViewModal.tsx` when that file crossed the size gate: this
|
|
7
|
+
* is the one self-contained piece of it — a read-only summary of the view
|
|
8
|
+
* state, with no form and no dialog around it.
|
|
9
|
+
*/
|
|
10
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
11
|
+
import { Box } from "../../../mui/Box";
|
|
12
|
+
import { Stack } from "../../../mui/Stack";
|
|
13
|
+
import { Text } from "../../typography/Text";
|
|
14
|
+
|
|
15
|
+
export interface PreviewBoxProps {
|
|
16
|
+
preview: { filters: string[]; columns: string[]; sort: string[] };
|
|
17
|
+
testIdPrefix: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** One "label — value" line of the summary. */
|
|
21
|
+
function SummaryRow({
|
|
22
|
+
label,
|
|
23
|
+
items,
|
|
24
|
+
testId,
|
|
25
|
+
}: {
|
|
26
|
+
label: string;
|
|
27
|
+
items: string[];
|
|
28
|
+
testId: string;
|
|
29
|
+
}): React.JSX.Element | null {
|
|
30
|
+
if (items.length === 0) return null;
|
|
31
|
+
return (
|
|
32
|
+
<Box sx={{ display: "flex", gap: 1.5 }} data-testid={testId}>
|
|
33
|
+
<Text variant="caption" as="span">
|
|
34
|
+
<Box component="span" sx={{ width: 116, flexShrink: 0, color: "text.secondary" }}>
|
|
35
|
+
{label}
|
|
36
|
+
</Box>
|
|
37
|
+
</Text>
|
|
38
|
+
<Text variant="caption" as="span">
|
|
39
|
+
<Box component="span" sx={{ minWidth: 0, flex: 1 }}>
|
|
40
|
+
{items.join(", ")}
|
|
41
|
+
</Box>
|
|
42
|
+
</Text>
|
|
43
|
+
</Box>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function PreviewBox({ preview, testIdPrefix }: PreviewBoxProps): React.JSX.Element {
|
|
48
|
+
const copy = useDataViewsCopy();
|
|
49
|
+
const empty =
|
|
50
|
+
preview.filters.length === 0 && preview.columns.length === 0 && preview.sort.length === 0;
|
|
51
|
+
return (
|
|
52
|
+
<Box sx={{ p: 1.5, borderRadius: 1.5, bgcolor: "action.hover", border: (theme) => `1px solid ${theme.palette.divider}` }}>
|
|
53
|
+
<Text variant="caption" as="p">
|
|
54
|
+
<Box
|
|
55
|
+
component="span"
|
|
56
|
+
sx={{ display: "block", mb: 1, textTransform: "uppercase", letterSpacing: 0.6, fontWeight: 600, color: "text.disabled" }}
|
|
57
|
+
>
|
|
58
|
+
{copy.saveView.previewHeading}
|
|
59
|
+
</Box>
|
|
60
|
+
</Text>
|
|
61
|
+
{empty ? (
|
|
62
|
+
// Saving is still allowed — an operator may be naming the default on
|
|
63
|
+
// purpose — but it should not be a surprise afterwards.
|
|
64
|
+
<Text variant="caption" as="p">
|
|
65
|
+
<Box component="span" sx={{ color: "warning.main", lineHeight: 1.6 }} data-testid={`${testIdPrefix}-preview-empty`}>
|
|
66
|
+
{copy.saveView.previewUnchanged}
|
|
67
|
+
</Box>
|
|
68
|
+
</Text>
|
|
69
|
+
) : (
|
|
70
|
+
<Stack spacing={0.75}>
|
|
71
|
+
<SummaryRow label={copy.saveView.previewFilters} items={preview.filters} testId={`${testIdPrefix}-preview-filters`} />
|
|
72
|
+
<SummaryRow label={copy.saveView.previewHiddenColumns} items={preview.columns} testId={`${testIdPrefix}-preview-columns`} />
|
|
73
|
+
<SummaryRow label={copy.saveView.sortRowLabel} items={preview.sort} testId={`${testIdPrefix}-preview-sort`} />
|
|
74
|
+
</Stack>
|
|
75
|
+
)}
|
|
76
|
+
</Box>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useRef, useState } from "react";
|
|
4
4
|
|
|
5
|
+
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
5
6
|
import { useViewMutations, type ViewMutations } from "./data-views-view-mutations";
|
|
6
7
|
import {
|
|
7
8
|
coerceViewState,
|
|
@@ -99,6 +100,7 @@ export function useSavedViewsController(
|
|
|
99
100
|
initialView: SavedViewSummary | undefined,
|
|
100
101
|
initialState: DataViewState | undefined,
|
|
101
102
|
): SavedViewsController {
|
|
103
|
+
const copy = useDataViewsCopy();
|
|
102
104
|
const { applied, currentRef, activeViewName, applyView, selectMain } =
|
|
103
105
|
useAppliedView(router, columnIds, views, initialView, initialState);
|
|
104
106
|
const [saveOpen, setSaveOpen] = useState(false);
|
|
@@ -122,7 +124,7 @@ export function useSavedViewsController(
|
|
|
122
124
|
} else {
|
|
123
125
|
// A rejected pin/share/default/delete must be visible (FUT-100) — the
|
|
124
126
|
// menus close on click, so an inline Alert is the only surviving signal.
|
|
125
|
-
setMutationError(error ??
|
|
127
|
+
setMutationError(error ?? copy.nav.saveFailed);
|
|
126
128
|
}
|
|
127
129
|
};
|
|
128
130
|
|
|
@@ -100,8 +100,8 @@ const ConfiguredView: React.FC<SectionOnboardingProps> = ({
|
|
|
100
100
|
title,
|
|
101
101
|
configuredTitle,
|
|
102
102
|
configuredSummary,
|
|
103
|
-
editLabel
|
|
104
|
-
collapseLabel
|
|
103
|
+
editLabel,
|
|
104
|
+
collapseLabel,
|
|
105
105
|
defaultExpanded = false,
|
|
106
106
|
children,
|
|
107
107
|
className,
|
|
@@ -167,7 +167,7 @@ const HeroView: React.FC<SectionOnboardingProps & { onStart: () => void }> = ({
|
|
|
167
167
|
activeStepId,
|
|
168
168
|
completedStepIds,
|
|
169
169
|
primaryAction,
|
|
170
|
-
startLabel
|
|
170
|
+
startLabel,
|
|
171
171
|
secondaryAction,
|
|
172
172
|
helpLink,
|
|
173
173
|
children,
|
|
@@ -64,7 +64,14 @@ export interface SectionOnboardingProps {
|
|
|
64
64
|
* and `children` exist. Clicking it advances the hero to the in-progress view
|
|
65
65
|
* (steps + form) without the parent managing state. @default 'Começar'
|
|
66
66
|
*/
|
|
67
|
-
|
|
67
|
+
/** The button that begins the section. REQUIRED since FUT-760. */
|
|
68
|
+
startLabel: string;
|
|
69
|
+
|
|
70
|
+
/** Label of the reveal toggle in the configured state. */
|
|
71
|
+
editLabel: string;
|
|
72
|
+
|
|
73
|
+
/** Label of that toggle while the form is revealed. */
|
|
74
|
+
collapseLabel: string;
|
|
68
75
|
|
|
69
76
|
/** Optional secondary CTA of the hero — e.g. "Ver como funciona". */
|
|
70
77
|
secondaryAction?: SectionOnboardingAction;
|
|
@@ -81,12 +88,6 @@ export interface SectionOnboardingProps {
|
|
|
81
88
|
*/
|
|
82
89
|
configuredSummary?: ReactNode;
|
|
83
90
|
|
|
84
|
-
/** Label of the reveal toggle in the configured state. @default 'Editar' */
|
|
85
|
-
editLabel?: string;
|
|
86
|
-
|
|
87
|
-
/** Label of the reveal toggle while expanded. @default 'Ocultar' */
|
|
88
|
-
collapseLabel?: string;
|
|
89
|
-
|
|
90
91
|
/** Start the configured state with the form already revealed. @default false */
|
|
91
92
|
defaultExpanded?: boolean;
|
|
92
93
|
|
|
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
3
3
|
import type { ConfirmHandler, UseConfirmActionResult } from './ConfirmAction.types';
|
|
4
4
|
|
|
5
5
|
/** Used when the guarded action rejects and the caller supplied no wording. */
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* What the popup says after a failed attempt.
|
|
@@ -29,7 +29,7 @@ function failureMessage(cause: unknown, errorText: string): string {
|
|
|
29
29
|
*/
|
|
30
30
|
export function useConfirmAction(
|
|
31
31
|
onConfirm: ConfirmHandler,
|
|
32
|
-
errorText: string
|
|
32
|
+
errorText: string,
|
|
33
33
|
): UseConfirmActionResult {
|
|
34
34
|
const [open, setOpen] = useState(false);
|
|
35
35
|
const [pending, setPending] = useState(false);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from "../../../copy";
|
|
1
2
|
import { Alert, Stack, TextField, Typography } from '@mui/material';
|
|
2
3
|
import React, { type ReactNode } from 'react';
|
|
3
4
|
|
|
@@ -10,7 +11,6 @@ import type {
|
|
|
10
11
|
UseConfirmActionResult,
|
|
11
12
|
} from './ConfirmAction.types';
|
|
12
13
|
|
|
13
|
-
const DEFAULT_CANCEL_TEXT = 'Cancelar';
|
|
14
14
|
const DEFAULT_TEST_ID = 'confirm-action';
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -22,8 +22,12 @@ const DEFAULT_TEST_ID = 'confirm-action';
|
|
|
22
22
|
* mention it. A body with neither a name nor a description would leave the
|
|
23
23
|
* operator with only the title to decide on, so a neutral fallback covers that.
|
|
24
24
|
*/
|
|
25
|
-
function confirmBody(
|
|
26
|
-
|
|
25
|
+
function confirmBody(
|
|
26
|
+
description: ReactNode,
|
|
27
|
+
copy: ConfirmActionCopy,
|
|
28
|
+
entityName?: string,
|
|
29
|
+
): ReactNode {
|
|
30
|
+
if (!entityName) return description ?? copy.irreversible;
|
|
27
31
|
return (
|
|
28
32
|
<>
|
|
29
33
|
<Typography component="span" sx={{ fontWeight: 600, display: "block" }}>
|
|
@@ -86,6 +90,8 @@ function TypeToConfirmField({
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
export interface ConfirmActionDialogProps extends ConfirmOptions {
|
|
93
|
+
/** The fallback body when no entity is named. REQUIRED — no default copy. */
|
|
94
|
+
copy: ConfirmActionCopy;
|
|
89
95
|
state: UseConfirmActionResult;
|
|
90
96
|
}
|
|
91
97
|
|
|
@@ -101,12 +107,13 @@ export function ConfirmActionDialog({
|
|
|
101
107
|
description,
|
|
102
108
|
entityName,
|
|
103
109
|
confirmText,
|
|
104
|
-
cancelText
|
|
110
|
+
cancelText,
|
|
105
111
|
typeToConfirm,
|
|
106
112
|
typeToConfirmLabel,
|
|
107
113
|
tone = 'destructive',
|
|
108
114
|
initialFocus,
|
|
109
115
|
dataTestId = DEFAULT_TEST_ID,
|
|
116
|
+
copy,
|
|
110
117
|
}: ConfirmActionDialogProps): React.ReactElement {
|
|
111
118
|
const [typed, setTyped] = React.useState('');
|
|
112
119
|
|
|
@@ -123,9 +130,16 @@ export function ConfirmActionDialog({
|
|
|
123
130
|
open={state.open}
|
|
124
131
|
variant={tone === 'destructive' ? 'destructive' : 'default'}
|
|
125
132
|
title={title}
|
|
126
|
-
description={confirmBody(description, entityName)}
|
|
133
|
+
description={confirmBody(description, copy, entityName)}
|
|
127
134
|
confirmText={confirmText}
|
|
128
|
-
|
|
135
|
+
// `copy.cancel` is the fallback, NOT `AlertDialog`'s own. The 6.3.0 copy
|
|
136
|
+
// sweep deleted this component's `cancelText = 'Cancelar'` default and
|
|
137
|
+
// put the word in `ConfirmActionCopy` — where nothing then read it, so
|
|
138
|
+
// every confirmation that names no `cancelText` of its own fell through
|
|
139
|
+
// to `AlertDialog`'s English `'Cancel'`, in a pt-BR dialog. That is the
|
|
140
|
+
// precise failure the sweep exists to prevent, one layer down: a port
|
|
141
|
+
// that is required, supplied, and ignored.
|
|
142
|
+
cancelText={cancelText ?? copy.cancel}
|
|
129
143
|
loading={state.pending}
|
|
130
144
|
confirmDisabled={gateUnmet}
|
|
131
145
|
initialFocus={resolveInitialFocus(tone, initialFocus)}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from "../../../copy";
|
|
1
2
|
import type { ComponentType, ReactNode } from 'react';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -43,7 +44,6 @@ export interface ConfirmOptions {
|
|
|
43
44
|
/** Defaults to `cancel` for the destructive tone, `confirm` otherwise. */
|
|
44
45
|
initialFocus?: ConfirmInitialFocus;
|
|
45
46
|
/** Shown inside the dialog when the action rejects; the dialog stays open. */
|
|
46
|
-
errorText?: string;
|
|
47
47
|
/** Root test id; the dialog's parts derive theirs from it. */
|
|
48
48
|
dataTestId?: string;
|
|
49
49
|
}
|
|
@@ -82,6 +82,14 @@ export interface UseConfirmActionResult {
|
|
|
82
82
|
* the trigger — a button, a menu item, an icon.
|
|
83
83
|
*/
|
|
84
84
|
export interface ConfirmActionProps extends ConfirmOptions {
|
|
85
|
+
/**
|
|
86
|
+
* What the operator is told when the action fails and the cause carries no
|
|
87
|
+
* message. REQUIRED since FUT-760 — it used to default to this package's own
|
|
88
|
+
* pt-BR, so a host that passed nothing shipped one product's Portuguese.
|
|
89
|
+
*/
|
|
90
|
+
errorText: string;
|
|
91
|
+
/** The fallback body when no entity is named. REQUIRED — see `errorText`. */
|
|
92
|
+
copy: ConfirmActionCopy;
|
|
85
93
|
onConfirm: ConfirmHandler;
|
|
86
94
|
children: (request: () => void, state: { pending: boolean }) => ReactNode;
|
|
87
95
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from '../../../copy';
|
|
1
2
|
import { Button } from '../../form/Button';
|
|
2
3
|
import type { ButtonProps } from '../../form/Button/Button.types';
|
|
3
4
|
|
|
@@ -12,7 +13,14 @@ import type { ConfirmableComponent } from './ConfirmAction.types';
|
|
|
12
13
|
* The baked-in defaults are only the wording and tone every destructive
|
|
13
14
|
* confirmation shares, and each instance can still override them.
|
|
14
15
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
)
|
|
16
|
+
export function createConfirmButton(
|
|
17
|
+
copy: ConfirmActionCopy,
|
|
18
|
+
errorText: string,
|
|
19
|
+
): ConfirmableComponent<ButtonProps> {
|
|
20
|
+
return withConfirmation<ButtonProps>(Button, {
|
|
21
|
+
cancelText: copy.cancel,
|
|
22
|
+
tone: 'destructive',
|
|
23
|
+
errorText,
|
|
24
|
+
copy,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ConfirmAction } from './ConfirmAction';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
2
|
+
export { createConfirmButton } from './ConfirmButton';
|
|
3
|
+
export { useConfirmAction } from './ConfirmAction.hooks';
|
|
4
4
|
export { ConfirmActionDialog } from './ConfirmAction.parts';
|
|
5
5
|
export { withConfirmation } from './with-confirmation';
|
|
6
6
|
export type {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from '../../../copy';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import type { ComponentType } from 'react';
|
|
3
4
|
|
|
@@ -81,12 +82,12 @@ function useGuardedHandler(onClick: ConfirmableProps['onClick']): ConfirmHandler
|
|
|
81
82
|
*/
|
|
82
83
|
export function withConfirmation<P extends ConfirmableProps>(
|
|
83
84
|
Wrapped: ComponentType<P>,
|
|
84
|
-
defaults
|
|
85
|
+
defaults: Partial<ConfirmOptions> & { errorText: string; copy: ConfirmActionCopy },
|
|
85
86
|
): ConfirmableComponent<P> {
|
|
86
87
|
function WithConfirmation(props: P & WithConfirmationProps): React.ReactElement {
|
|
87
88
|
const { confirm, onClick } = props;
|
|
88
89
|
const options = resolveOptions(defaults, confirm);
|
|
89
|
-
const state = useConfirmAction(useGuardedHandler(onClick),
|
|
90
|
+
const state = useConfirmAction(useGuardedHandler(onClick), defaults.errorText);
|
|
90
91
|
|
|
91
92
|
// `confirm` is ours and must not reach the DOM — an unknown attribute on a
|
|
92
93
|
// <button> is a React warning at every render. The cast is the standard HOC
|
|
@@ -99,7 +100,7 @@ export function withConfirmation<P extends ConfirmableProps>(
|
|
|
99
100
|
return (
|
|
100
101
|
<>
|
|
101
102
|
<Wrapped {...forwarded} onClick={state.request} />
|
|
102
|
-
<ConfirmActionDialog state={state} {...options} />
|
|
103
|
+
<ConfirmActionDialog state={state} {...options} copy={defaults.copy} />
|
|
103
104
|
</>
|
|
104
105
|
);
|
|
105
106
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from "../../../copy";
|
|
3
4
|
import { Box } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { removeChip } from './category-tree';
|
|
@@ -12,6 +13,8 @@ import type { CategoryGroup, CategorySelectionChip } from './CategorySelect.type
|
|
|
12
13
|
import type { CategorySelectState } from './useCategorySelect';
|
|
13
14
|
|
|
14
15
|
export interface CategoryPanelProps {
|
|
16
|
+
/** The words this panel renders. REQUIRED — no default copy. */
|
|
17
|
+
copy: CategorySelectCopy;
|
|
15
18
|
state: CategorySelectState;
|
|
16
19
|
chips: CategorySelectionChip[];
|
|
17
20
|
rowIds: string[];
|
|
@@ -55,6 +58,7 @@ export function CategoryPanel({
|
|
|
55
58
|
searchInputRef,
|
|
56
59
|
listRef,
|
|
57
60
|
dataTestId,
|
|
61
|
+
copy,
|
|
58
62
|
}: CategoryPanelProps): React.JSX.Element {
|
|
59
63
|
return (
|
|
60
64
|
<Box
|
|
@@ -65,8 +69,9 @@ export function CategoryPanel({
|
|
|
65
69
|
sx={(theme) => ({ ...panelSx(theme), ...(sheet ? sheetSx(theme) : {}) })}
|
|
66
70
|
>
|
|
67
71
|
<CategoryPanelHead
|
|
72
|
+
copy={copy}
|
|
68
73
|
query={state.query}
|
|
69
|
-
placeholder={single ?
|
|
74
|
+
placeholder={single ? copy.search.placeholderSingle : copy.search.placeholderMulti}
|
|
70
75
|
sheet={sheet}
|
|
71
76
|
quickActions={
|
|
72
77
|
single ? undefined : <CategoryQuickActions state={state} dataTestId={dataTestId} />
|
|
@@ -76,9 +81,9 @@ export function CategoryPanel({
|
|
|
76
81
|
dataTestId={dataTestId}
|
|
77
82
|
/>
|
|
78
83
|
{!single && !loading && (
|
|
79
|
-
<PinnedTray state={state} chips={chips} dataTestId={dataTestId} />
|
|
84
|
+
<PinnedTray state={state} chips={chips} dataTestId={dataTestId} copy={copy} />
|
|
80
85
|
)}
|
|
81
|
-
<CategoryPanelList
|
|
86
|
+
<CategoryPanelList copy={copy}
|
|
82
87
|
groups={state.visibleGroups}
|
|
83
88
|
query={state.query}
|
|
84
89
|
draft={state.draft}
|
|
@@ -103,6 +108,7 @@ export function CategoryPanel({
|
|
|
103
108
|
changed={changed}
|
|
104
109
|
single={single}
|
|
105
110
|
sheet={sheet}
|
|
111
|
+
copy={copy}
|
|
106
112
|
onApply={onApply}
|
|
107
113
|
onCancel={onCancel}
|
|
108
114
|
dataTestId={dataTestId}
|
|
@@ -116,9 +122,11 @@ function PinnedTray({
|
|
|
116
122
|
state,
|
|
117
123
|
chips,
|
|
118
124
|
dataTestId,
|
|
119
|
-
|
|
125
|
+
copy,
|
|
126
|
+
}: Pick<CategoryPanelProps, 'state' | 'chips' | 'dataTestId' | 'copy'>): React.JSX.Element {
|
|
120
127
|
return (
|
|
121
128
|
<CategoryPinnedTray
|
|
129
|
+
copy={copy}
|
|
122
130
|
chips={chips}
|
|
123
131
|
onRemove={(chipId) => state.setDraft(removeChip(state.allGroups, chipId, state.draft))}
|
|
124
132
|
dataTestId={dataTestId}
|
|
@@ -135,18 +143,22 @@ function PanelFooter({
|
|
|
135
143
|
onApply,
|
|
136
144
|
onCancel,
|
|
137
145
|
dataTestId,
|
|
146
|
+
copy,
|
|
138
147
|
}: Pick<
|
|
139
148
|
CategoryPanelProps,
|
|
140
|
-
'state' | 'changed' | 'single' | 'sheet' | 'onApply' | 'onCancel' | 'dataTestId'
|
|
149
|
+
'state' | 'changed' | 'single' | 'sheet' | 'onApply' | 'onCancel' | 'dataTestId' | 'copy'
|
|
141
150
|
>): React.JSX.Element {
|
|
142
151
|
if (single) {
|
|
143
|
-
return
|
|
152
|
+
return (
|
|
153
|
+
<CategorySingleFoot sheet={sheet} onCancel={onCancel} dataTestId={dataTestId} copy={copy} />
|
|
154
|
+
);
|
|
144
155
|
}
|
|
145
156
|
return (
|
|
146
157
|
<CategoryMultiFoot
|
|
147
158
|
count={state.draft.size}
|
|
148
159
|
changed={changed}
|
|
149
160
|
sheet={sheet}
|
|
161
|
+
copy={copy}
|
|
150
162
|
onClear={() => state.setDraft(new Set())}
|
|
151
163
|
onApply={onApply}
|
|
152
164
|
dataTestId={dataTestId}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Box, Button } from '@mui/material';
|
|
4
4
|
|
|
5
|
+
import type { CategorySelectCopy } from '../../../copy';
|
|
5
6
|
import { footerSx, METRICS } from './CategorySelect.styles';
|
|
6
7
|
|
|
7
8
|
const buttonSx = (sheet: boolean) =>
|
|
@@ -23,6 +24,7 @@ interface MultiFootProps {
|
|
|
23
24
|
onClear: () => void;
|
|
24
25
|
onApply: () => void;
|
|
25
26
|
dataTestId: string;
|
|
27
|
+
copy: CategorySelectCopy;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -37,11 +39,12 @@ export function CategoryMultiFoot({
|
|
|
37
39
|
onClear,
|
|
38
40
|
onApply,
|
|
39
41
|
dataTestId,
|
|
42
|
+
copy,
|
|
40
43
|
}: MultiFootProps): React.JSX.Element {
|
|
41
44
|
return (
|
|
42
45
|
<Box sx={footerSx} data-testid={`${dataTestId}-footer`}>
|
|
43
46
|
<Box component="span" sx={{ fontSize: 12, color: 'text.secondary' }}>
|
|
44
|
-
|
|
47
|
+
{copy.footer.selectedCount(count)}
|
|
45
48
|
</Box>
|
|
46
49
|
<Box sx={{ display: 'flex', gap: '6px' }}>
|
|
47
50
|
<Button
|
|
@@ -51,7 +54,7 @@ export function CategoryMultiFoot({
|
|
|
51
54
|
onClick={onClear}
|
|
52
55
|
data-testid={`${dataTestId}-clear`}
|
|
53
56
|
>
|
|
54
|
-
|
|
57
|
+
{copy.footer.clear}
|
|
55
58
|
</Button>
|
|
56
59
|
<Button
|
|
57
60
|
variant="contained"
|
|
@@ -59,7 +62,7 @@ export function CategoryMultiFoot({
|
|
|
59
62
|
onClick={onApply}
|
|
60
63
|
data-testid={`${dataTestId}-apply`}
|
|
61
64
|
>
|
|
62
|
-
{changed ?
|
|
65
|
+
{changed ? copy.footer.apply : copy.footer.close}
|
|
63
66
|
</Button>
|
|
64
67
|
</Box>
|
|
65
68
|
</Box>
|
|
@@ -71,15 +74,17 @@ export function CategorySingleFoot({
|
|
|
71
74
|
sheet,
|
|
72
75
|
onCancel,
|
|
73
76
|
dataTestId,
|
|
77
|
+
copy,
|
|
74
78
|
}: {
|
|
75
79
|
sheet: boolean;
|
|
76
80
|
onCancel: () => void;
|
|
77
81
|
dataTestId: string;
|
|
82
|
+
copy: CategorySelectCopy;
|
|
78
83
|
}): React.JSX.Element {
|
|
79
84
|
return (
|
|
80
85
|
<Box sx={footerSx} data-testid={`${dataTestId}-footer`}>
|
|
81
86
|
<Box component="span" sx={{ fontSize: 12, color: 'text.secondary' }}>
|
|
82
|
-
|
|
87
|
+
{copy.footer.singleHint}
|
|
83
88
|
</Box>
|
|
84
89
|
<Button
|
|
85
90
|
variant="outlined"
|
|
@@ -87,7 +92,7 @@ export function CategorySingleFoot({
|
|
|
87
92
|
onClick={onCancel}
|
|
88
93
|
data-testid={`${dataTestId}-cancel`}
|
|
89
94
|
>
|
|
90
|
-
|
|
95
|
+
{copy.footer.cancel}
|
|
91
96
|
</Button>
|
|
92
97
|
</Box>
|
|
93
98
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from '../../../copy';
|
|
3
4
|
import { Box, InputBase } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { SearchGlyph } from './CategoryIcons';
|
|
@@ -21,6 +22,7 @@ interface PanelHeadProps {
|
|
|
21
22
|
onQueryChange: (next: string) => void;
|
|
22
23
|
searchInputRef: React.RefObject<HTMLInputElement | null>;
|
|
23
24
|
dataTestId: string;
|
|
25
|
+
copy: CategorySelectCopy;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
const searchFieldSx = {
|
|
@@ -72,6 +74,7 @@ export function CategoryPanelHead({
|
|
|
72
74
|
onQueryChange,
|
|
73
75
|
searchInputRef,
|
|
74
76
|
dataTestId,
|
|
77
|
+
copy,
|
|
75
78
|
}: PanelHeadProps): React.JSX.Element {
|
|
76
79
|
return (
|
|
77
80
|
<Box sx={(theme) => panelHeadSx(theme, sheet)}>
|
|
@@ -99,7 +102,7 @@ export function CategoryPanelHead({
|
|
|
99
102
|
<Box
|
|
100
103
|
component="button"
|
|
101
104
|
type="button"
|
|
102
|
-
aria-label=
|
|
105
|
+
aria-label={copy.search.clear}
|
|
103
106
|
data-testid={`${dataTestId}-search-clear`}
|
|
104
107
|
sx={clearButtonSx}
|
|
105
108
|
onClick={() => onQueryChange('')}
|
|
@@ -129,6 +132,7 @@ interface PinnedTrayProps {
|
|
|
129
132
|
chips: CategorySelectionChip[];
|
|
130
133
|
onRemove: (chipId: string) => void;
|
|
131
134
|
dataTestId: string;
|
|
135
|
+
copy: CategorySelectCopy;
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
/**
|
|
@@ -142,18 +146,19 @@ export function CategoryPinnedTray({
|
|
|
142
146
|
chips,
|
|
143
147
|
onRemove,
|
|
144
148
|
dataTestId,
|
|
149
|
+
copy,
|
|
145
150
|
}: PinnedTrayProps): React.JSX.Element | null {
|
|
146
151
|
if (chips.length === 0) return null;
|
|
147
152
|
return (
|
|
148
153
|
<Box sx={pinnedSx} data-testid={`${dataTestId}-pinned`}>
|
|
149
|
-
<Box sx={pinnedLabelSx}>
|
|
154
|
+
<Box sx={pinnedLabelSx}>{copy.search.pinnedLabel(chips.length)}</Box>
|
|
150
155
|
<Box sx={chipWrapSx}>
|
|
151
156
|
{chips.map((chip) => (
|
|
152
157
|
<Box component="span" key={chip.id} sx={chipSx}>
|
|
153
158
|
{chip.label}
|
|
154
159
|
<button
|
|
155
160
|
type="button"
|
|
156
|
-
aria-label={
|
|
161
|
+
aria-label={copy.search.removeChip(chip.label)}
|
|
157
162
|
data-testid={`${dataTestId}-unpin-${chip.id}`}
|
|
158
163
|
onClick={() => onRemove(chip.id)}
|
|
159
164
|
>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from "../../../copy";
|
|
3
4
|
import { Box, Button, Skeleton } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { categoryCheckState } from './category-tree';
|
|
@@ -18,6 +19,8 @@ const SENTENCE_CASE = { textTransform: 'none' } as const;
|
|
|
18
19
|
const SKELETON_ROWS = 6;
|
|
19
20
|
|
|
20
21
|
interface PanelListProps {
|
|
22
|
+
/** The words this panel renders. REQUIRED — no default copy. */
|
|
23
|
+
copy: CategorySelectCopy;
|
|
21
24
|
groups: CategoryGroup[];
|
|
22
25
|
query: string;
|
|
23
26
|
draft: ReadonlySet<string>;
|
|
@@ -52,17 +55,19 @@ function LoadingRows(): React.JSX.Element {
|
|
|
52
55
|
function EmptyCatalogue({
|
|
53
56
|
onCreateCategory,
|
|
54
57
|
dataTestId,
|
|
58
|
+
copy,
|
|
55
59
|
}: {
|
|
56
60
|
onCreateCategory?: (name?: string) => void;
|
|
57
61
|
dataTestId: string;
|
|
62
|
+
copy: CategorySelectCopy;
|
|
58
63
|
}): React.JSX.Element {
|
|
59
64
|
return (
|
|
60
65
|
<Box sx={emptySx} data-testid={`${dataTestId}-empty-catalogue`}>
|
|
61
|
-
<strong>
|
|
62
|
-
<p>
|
|
66
|
+
<strong>{copy.emptyTitle}</strong>
|
|
67
|
+
<p>{copy.purpose}</p>
|
|
63
68
|
{onCreateCategory && (
|
|
64
69
|
<Button variant="contained" size="small" sx={SENTENCE_CASE} onClick={() => onCreateCategory()}>
|
|
65
|
-
|
|
70
|
+
{copy.createCategory}
|
|
66
71
|
</Button>
|
|
67
72
|
)}
|
|
68
73
|
</Box>
|
|
@@ -75,19 +80,21 @@ function NoResults({
|
|
|
75
80
|
onClearQuery,
|
|
76
81
|
onCreateCategory,
|
|
77
82
|
dataTestId,
|
|
83
|
+
copy,
|
|
78
84
|
}: {
|
|
79
85
|
query: string;
|
|
80
86
|
onClearQuery: () => void;
|
|
81
87
|
onCreateCategory?: (name?: string) => void;
|
|
82
88
|
dataTestId: string;
|
|
89
|
+
copy: CategorySelectCopy;
|
|
83
90
|
}): React.JSX.Element {
|
|
84
91
|
return (
|
|
85
92
|
<Box sx={emptySx} data-testid={`${dataTestId}-no-results`}>
|
|
86
|
-
<strong>
|
|
87
|
-
<p>
|
|
93
|
+
<strong>{copy.noResults.title(query)}</strong>
|
|
94
|
+
<p>{copy.noResults.hint}</p>
|
|
88
95
|
<Box sx={{ display: 'flex', gap: '6px', justifyContent: 'center' }}>
|
|
89
96
|
<Button variant="outlined" size="small" sx={SENTENCE_CASE} onClick={onClearQuery}>
|
|
90
|
-
|
|
97
|
+
{copy.noResults.clearSearch}
|
|
91
98
|
</Button>
|
|
92
99
|
{onCreateCategory && (
|
|
93
100
|
<Button
|
|
@@ -97,7 +104,7 @@ function NoResults({
|
|
|
97
104
|
data-testid={`${dataTestId}-create`}
|
|
98
105
|
onClick={() => onCreateCategory(query.trim())}
|
|
99
106
|
>
|
|
100
|
-
|
|
107
|
+
{copy.noResults.create(query.trim())}
|
|
101
108
|
</Button>
|
|
102
109
|
)}
|
|
103
110
|
</Box>
|
|
@@ -161,13 +168,13 @@ function CategoryGroupRows({
|
|
|
161
168
|
|
|
162
169
|
/** The scrolling body of the panel, including its three non-list states. */
|
|
163
170
|
export function CategoryPanelList(props: PanelListProps): React.JSX.Element {
|
|
164
|
-
const { groups, loading, query, listRef, sheet, dataTestId } = props;
|
|
171
|
+
const { groups, loading, query, listRef, sheet, dataTestId, copy } = props;
|
|
165
172
|
|
|
166
173
|
const body = (): React.JSX.Element => {
|
|
167
174
|
if (loading) return <LoadingRows />;
|
|
168
175
|
if (groups.length === 0 && query.trim().length > 0) {
|
|
169
176
|
return (
|
|
170
|
-
<NoResults
|
|
177
|
+
<NoResults copy={copy}
|
|
171
178
|
query={query}
|
|
172
179
|
onClearQuery={props.onClearQuery}
|
|
173
180
|
onCreateCategory={props.onCreateCategory}
|
|
@@ -177,7 +184,7 @@ export function CategoryPanelList(props: PanelListProps): React.JSX.Element {
|
|
|
177
184
|
}
|
|
178
185
|
if (groups.length === 0) {
|
|
179
186
|
return (
|
|
180
|
-
<EmptyCatalogue
|
|
187
|
+
<EmptyCatalogue copy={copy}
|
|
181
188
|
onCreateCategory={props.onCreateCategory}
|
|
182
189
|
dataTestId={dataTestId}
|
|
183
190
|
/>
|