@astryxdesign/core 0.7.8-canary.c239daf → 0.7.8-canary.cc034ed
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/PowerSearch/PowerSearch.d.ts +4 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +24 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.js +172 -50
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +5 -2
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +5 -2
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +5 -2
- package/locales/en.json +21 -9
- package/locales/pseudo.json +15 -6
- package/package.json +4 -4
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/PowerSearch/PowerSearch.tsx +4 -2
- package/src/PowerSearch/PowerSearchBottomSheet.tsx +237 -62
- package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +5 -2
- package/src/i18n/generated-locales/en.generated.ts +6 -4
- package/src/i18n/generated-locales/pseudo.generated.ts +6 -4
|
@@ -133,8 +133,10 @@ export interface PowerSearchProps extends Omit<BaseProps<HTMLElement>, 'onChange
|
|
|
133
133
|
* above it with the fields (or the content search with inline
|
|
134
134
|
* suggestions), and a value step opens above that, stages operator →
|
|
135
135
|
* value, and confirms from its footer. Dismissing a step reveals the
|
|
136
|
-
* one beneath.
|
|
137
|
-
*
|
|
136
|
+
* one beneath. The flow edits a draft: `onChange` is called when Done
|
|
137
|
+
* applies it, once per edit in order, and a dismissal with a changed
|
|
138
|
+
* draft asks before discarding it. Suited to compact touch screens,
|
|
139
|
+
* where the editor popover competes with the software keyboard.
|
|
138
140
|
* - `'adaptive'`: the bottom sheet on compact coarse-pointer screens,
|
|
139
141
|
* otherwise the popover — the same resolution Selector uses. The server
|
|
140
142
|
* render and the hydrating render are the popover.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PowerSearch.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearch.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"PowerSearch.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearch.tsx"],"names":[],"mappings":"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"}
|
|
@@ -72,7 +72,14 @@ export interface PowerSearchBottomSheetProps {
|
|
|
72
72
|
config: InternalConfig;
|
|
73
73
|
/** The caller's config, handed to Editor overrides as they expect it. */
|
|
74
74
|
configProp: PowerSearchConfig;
|
|
75
|
+
/** The committed filters; the draft the sheet edits starts from them. */
|
|
75
76
|
filters: ReadonlyArray<PowerSearchFilter>;
|
|
77
|
+
/**
|
|
78
|
+
* The field's `onChange`. Done replays the draft's edits through it, in
|
|
79
|
+
* order, onto the field's latest filters, each call carrying that list
|
|
80
|
+
* with the edit applied; nothing is reported before Done, and nothing when
|
|
81
|
+
* the field is read-only or disabled at Done.
|
|
82
|
+
*/
|
|
76
83
|
onChange: (filters: ReadonlyArray<PowerSearchFilter>, changeType: PowerSearchChangeType, index: number) => void;
|
|
77
84
|
/** The field typeahead source; the content search lists its suggestions. */
|
|
78
85
|
searchSource: SearchSource<PowerSearchItem>;
|
|
@@ -90,13 +97,29 @@ export interface PowerSearchBottomSheetProps {
|
|
|
90
97
|
components?: PowerSearchComponents;
|
|
91
98
|
editors: PowerSearchSheetEditors;
|
|
92
99
|
}
|
|
100
|
+
/** One edit of the draft: the draft before and after it, and its type and index in the draft; Done replays it onto the field's latest filters. */
|
|
101
|
+
interface DraftEdit {
|
|
102
|
+
before: ReadonlyArray<PowerSearchFilter>;
|
|
103
|
+
after: ReadonlyArray<PowerSearchFilter>;
|
|
104
|
+
changeType: PowerSearchChangeType;
|
|
105
|
+
index: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Replays the draft's edits onto `base`, the field's latest filters, and
|
|
109
|
+
* reports each through `report` with the list after it. An add appends; an
|
|
110
|
+
* edit replaces the first filter matching the one it edited; a removal drops
|
|
111
|
+
* the filters it removed, by signature. An edit or removal whose target is
|
|
112
|
+
* not in the base list is skipped: the parent removed it meanwhile.
|
|
113
|
+
*/
|
|
114
|
+
export declare function replayDraftEdits(base: ReadonlyArray<PowerSearchFilter>, edits: ReadonlyArray<DraftEdit>, report: (filters: ReadonlyArray<PowerSearchFilter>, changeType: PowerSearchChangeType, index: number) => void): ReadonlyArray<PowerSearchFilter>;
|
|
93
115
|
/**
|
|
94
116
|
* The sheet flow of PowerSearch's touch presentation: Filters, Add filter,
|
|
95
117
|
* and the value step, as standalone sheets that stack, each open beneath the
|
|
96
118
|
* step it led to.
|
|
97
119
|
*/
|
|
98
|
-
export declare function PowerSearchBottomSheet({ isOpen, onOpenChange, finalFocusRef, resultCountText, config, configProp, filters, onChange, searchSource, placeholder, isReadOnly, isDisabled, hasClear, maxOperatorMenuItems, timezoneID, maxSearchResults, saveButtonLabel: saveButtonLabelFromProps, components: componentOverrides, editors, }: PowerSearchBottomSheetProps): React.JSX.Element;
|
|
120
|
+
export declare function PowerSearchBottomSheet({ isOpen, onOpenChange, finalFocusRef, resultCountText, config, configProp, filters: committedFilters, onChange: onCommit, searchSource, placeholder, isReadOnly, isDisabled, hasClear, maxOperatorMenuItems, timezoneID, maxSearchResults, saveButtonLabel: saveButtonLabelFromProps, components: componentOverrides, editors, }: PowerSearchBottomSheetProps): React.JSX.Element;
|
|
99
121
|
export declare namespace PowerSearchBottomSheet {
|
|
100
122
|
var displayName: string;
|
|
101
123
|
}
|
|
124
|
+
export {};
|
|
102
125
|
//# sourceMappingURL=PowerSearchBottomSheet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PowerSearchBottomSheet.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearchBottomSheet.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,EASZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAoBf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAkCrD,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAe3D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAIV,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EAEjB,iBAAiB,EACjB,eAAe,EAEhB,MAAM,SAAS,CAAC;AAajB;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,wBAAwB,EAAE,OAAO,wBAAwB,CAAC;CAC3D;AAED,MAAM,WAAW,2BAA2B;IAC1C,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,aAAa,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC7C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,yEAAyE;IACzE,UAAU,EAAE,iBAAiB,CAAC;IAC9B,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC1C,QAAQ,EAAE,CACR,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,UAAU,EAAE,qBAAqB,EACjC,KAAK,EAAE,MAAM,KACV,IAAI,CAAC;IACV,4EAA4E;IAC5E,YAAY,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAC5C,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,OAAO,EAAE,uBAAuB,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"PowerSearchBottomSheet.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearchBottomSheet.tsx"],"names":[],"mappings":"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"}
|
|
@@ -104,6 +104,82 @@ registerEnglishFallback(english);
|
|
|
104
104
|
// Styles
|
|
105
105
|
// =============================================================================
|
|
106
106
|
|
|
107
|
+
/** One edit of the draft: the draft before and after it, and its type and index in the draft; Done replays it onto the field's latest filters. */
|
|
108
|
+
|
|
109
|
+
// Whether two filter lists hold the same filters in the same order, by the
|
|
110
|
+
// key-order-insensitive signature the sheet matches filters with.
|
|
111
|
+
function hasSameFilters(a, b) {
|
|
112
|
+
return a.length === b.length && a.every((filter, index) => b[index] != null && filterSignature(filter) === filterSignature(b[index]));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// The filters `before` holds that `after` does not, as a multiset by
|
|
116
|
+
// signature, in `before` order.
|
|
117
|
+
function removedFilters(before, after) {
|
|
118
|
+
const remaining = new Map();
|
|
119
|
+
for (const filter of after) {
|
|
120
|
+
const signature = filterSignature(filter);
|
|
121
|
+
remaining.set(signature, (remaining.get(signature) ?? 0) + 1);
|
|
122
|
+
}
|
|
123
|
+
return before.filter(filter => {
|
|
124
|
+
const signature = filterSignature(filter);
|
|
125
|
+
const count = remaining.get(signature) ?? 0;
|
|
126
|
+
if (count > 0) {
|
|
127
|
+
remaining.set(signature, count - 1);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Replays the draft's edits onto `base`, the field's latest filters, and
|
|
136
|
+
* reports each through `report` with the list after it. An add appends; an
|
|
137
|
+
* edit replaces the first filter matching the one it edited; a removal drops
|
|
138
|
+
* the filters it removed, by signature. An edit or removal whose target is
|
|
139
|
+
* not in the base list is skipped: the parent removed it meanwhile.
|
|
140
|
+
*/
|
|
141
|
+
export function replayDraftEdits(base, edits, report) {
|
|
142
|
+
let current = base;
|
|
143
|
+
for (const edit of edits) {
|
|
144
|
+
if (edit.changeType === 'add') {
|
|
145
|
+
const added = edit.after[edit.index];
|
|
146
|
+
if (added == null) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
current = [...current, added];
|
|
150
|
+
report(current, 'add', current.length - 1);
|
|
151
|
+
} else if (edit.changeType === 'edit') {
|
|
152
|
+
const original = edit.before[edit.index];
|
|
153
|
+
const updated = edit.after[edit.index];
|
|
154
|
+
if (original == null || updated == null) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const signature = filterSignature(original);
|
|
158
|
+
const index = current.findIndex(filter => filterSignature(filter) === signature);
|
|
159
|
+
if (index === -1) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
current = current.map((filter, i) => i === index ? updated : filter);
|
|
163
|
+
report(current, 'edit', index);
|
|
164
|
+
} else {
|
|
165
|
+
const removed = removedFilters(edit.before, edit.after).map(filterSignature);
|
|
166
|
+
const indexes = [];
|
|
167
|
+
for (const signature of removed) {
|
|
168
|
+
const index = current.findIndex((filter, i) => !indexes.includes(i) && filterSignature(filter) === signature);
|
|
169
|
+
if (index !== -1) {
|
|
170
|
+
indexes.push(index);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (indexes.length === 0) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
current = current.filter((_, i) => !indexes.includes(i));
|
|
177
|
+
report(current, 'remove', Math.min(...indexes));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return current;
|
|
181
|
+
}
|
|
182
|
+
|
|
107
183
|
// The trailing plus a field row shows when choosing it adds the filter at
|
|
108
184
|
// once, and the Add filter actions' glyph. Core's default icon set has no plus.
|
|
109
185
|
function PlusIcon(props) {
|
|
@@ -514,8 +590,8 @@ export function PowerSearchBottomSheet({
|
|
|
514
590
|
resultCountText,
|
|
515
591
|
config,
|
|
516
592
|
configProp,
|
|
517
|
-
filters,
|
|
518
|
-
onChange,
|
|
593
|
+
filters: committedFilters,
|
|
594
|
+
onChange: onCommit,
|
|
519
595
|
searchSource,
|
|
520
596
|
placeholder,
|
|
521
597
|
isReadOnly,
|
|
@@ -535,6 +611,27 @@ export function PowerSearchBottomSheet({
|
|
|
535
611
|
const locale = useLocale();
|
|
536
612
|
const formatList = useListFormatter();
|
|
537
613
|
const isInteractive = !isDisabled && !isReadOnly;
|
|
614
|
+
|
|
615
|
+
// ---- draft ----
|
|
616
|
+
// One open flow edits one draft of the filter list; `onChange` waits for
|
|
617
|
+
// Done, and a dismissal with a changed draft asks first.
|
|
618
|
+
const [filtersAtOpen, setFiltersAtOpen] = useState(() => committedFilters);
|
|
619
|
+
const [filters, setFilters] = useState(() => committedFilters);
|
|
620
|
+
// The draft as of the last edit, for the edit log's `before` lists.
|
|
621
|
+
const draftRef = useRef(filters);
|
|
622
|
+
const draftEditsRef = useRef([]);
|
|
623
|
+
const onChange = useCallback((next, changeType, index) => {
|
|
624
|
+
draftEditsRef.current.push({
|
|
625
|
+
before: draftRef.current,
|
|
626
|
+
after: next,
|
|
627
|
+
changeType,
|
|
628
|
+
index
|
|
629
|
+
});
|
|
630
|
+
draftRef.current = next;
|
|
631
|
+
setFilters(next);
|
|
632
|
+
}, []);
|
|
633
|
+
const isDraftDirty = !hasSameFilters(filtersAtOpen, filters);
|
|
634
|
+
const [isDiscardConfirmationOpen, setIsDiscardConfirmationOpen] = useState(false);
|
|
538
635
|
const contentSearchFieldKey = config.config.contentSearchFieldKey;
|
|
539
636
|
const contentSearchOperator = contentSearchFieldKey == null ? undefined : config.getDefaultOperator(contentSearchFieldKey);
|
|
540
637
|
const hasContentSearch = contentSearchOperator?.value.type === 'string';
|
|
@@ -616,9 +713,6 @@ export function PowerSearchBottomSheet({
|
|
|
616
713
|
const [contentQuery, setContentQuery] = useState('');
|
|
617
714
|
const [isClearConfirmationOpen, setIsClearConfirmationOpen] = useState(false);
|
|
618
715
|
const clearAllButtonRef = useRef(null);
|
|
619
|
-
// Set while Clear all commits, so the result count that changes in that
|
|
620
|
-
// commit is spoken with Clear all's outcome, as one message.
|
|
621
|
-
const isClearingRef = useRef(false);
|
|
622
716
|
|
|
623
717
|
// `useAnnounce` delivers inside the open Astryx modal that encloses its
|
|
624
718
|
// caller, and this component renders above the
|
|
@@ -645,13 +739,21 @@ export function PowerSearchBottomSheet({
|
|
|
645
739
|
if (isOpen !== wasOpen) {
|
|
646
740
|
setWasOpen(isOpen);
|
|
647
741
|
if (isOpen) {
|
|
742
|
+
// A fresh draft from the committed filters; the entry step is judged
|
|
743
|
+
// against them, not the previous session's draft.
|
|
744
|
+
setFiltersAtOpen(committedFilters);
|
|
745
|
+
setFilters(committedFilters);
|
|
746
|
+
draftRef.current = committedFilters;
|
|
747
|
+
draftEditsRef.current = [];
|
|
748
|
+
const startsOnAddFilter = committedFilters.length === 0 && isInteractive;
|
|
648
749
|
setFieldQuery('');
|
|
649
750
|
setContentQuery('');
|
|
650
|
-
setStep(
|
|
651
|
-
setFieldPickerOrigin(
|
|
751
|
+
setStep(startsOnAddFilter ? 'fields' : 'manage');
|
|
752
|
+
setFieldPickerOrigin(startsOnAddFilter ? 'trigger' : 'manage');
|
|
652
753
|
} else {
|
|
653
754
|
setStep(null);
|
|
654
755
|
setIsClearConfirmationOpen(false);
|
|
756
|
+
setIsDiscardConfirmationOpen(false);
|
|
655
757
|
}
|
|
656
758
|
}
|
|
657
759
|
const closeFlow = useCallback(() => {
|
|
@@ -659,6 +761,32 @@ export function PowerSearchBottomSheet({
|
|
|
659
761
|
setStep(null);
|
|
660
762
|
onOpenChange(false);
|
|
661
763
|
}, [onOpenChange]);
|
|
764
|
+
// Done replays each edit in order onto the field's latest filters, so a
|
|
765
|
+
// consumer gets the calls a popover session makes and keeps a filter it
|
|
766
|
+
// added meanwhile.
|
|
767
|
+
const commitAndClose = useCallback(() => {
|
|
768
|
+
// A field that became read-only while the flow was open reports nothing.
|
|
769
|
+
if (isDraftDirty && isInteractive) {
|
|
770
|
+
replayDraftEdits(committedFilters, draftEditsRef.current, onCommit);
|
|
771
|
+
}
|
|
772
|
+
draftEditsRef.current = [];
|
|
773
|
+
closeFlow();
|
|
774
|
+
}, [closeFlow, committedFilters, isDraftDirty, isInteractive, onCommit]);
|
|
775
|
+
const requestDismiss = useCallback(() => {
|
|
776
|
+
if (isDraftDirty) {
|
|
777
|
+
setIsDiscardConfirmationOpen(true);
|
|
778
|
+
} else {
|
|
779
|
+
closeFlow();
|
|
780
|
+
}
|
|
781
|
+
}, [closeFlow, isDraftDirty]);
|
|
782
|
+
const closeDiscardConfirmation = () => {
|
|
783
|
+
// eslint-disable-next-line @eslint-react/dom-no-flush-sync -- the confirmation must be gone before focus moves back into the sheet
|
|
784
|
+
flushSync(() => setIsDiscardConfirmationOpen(false));
|
|
785
|
+
const target = stepRef.current === 'manage' ? managerAddButtonRef.current ?? manageSheetRef.current?.closest('[tabindex="-1"]') : fieldsSheetRef.current?.closest('[tabindex="-1"]');
|
|
786
|
+
target?.focus({
|
|
787
|
+
preventScroll: true
|
|
788
|
+
});
|
|
789
|
+
};
|
|
662
790
|
|
|
663
791
|
// Whether a Filters row is a button: the field interactive and the
|
|
664
792
|
// filter not read-only. The row opens the value step — the editor for its
|
|
@@ -864,14 +992,8 @@ export function PowerSearchBottomSheet({
|
|
|
864
992
|
// is quiet then, so the change is spoken here, inside the dialog. Only a
|
|
865
993
|
// change after the flow opened is spoken.
|
|
866
994
|
const announcedResultCountRef = useRef(resultCountText);
|
|
867
|
-
// The latest result count, for Clear all's handler to read after its
|
|
868
|
-
// commit has flushed.
|
|
869
|
-
const latestResultCountRef = useRef(resultCountText);
|
|
870
|
-
useLayoutEffect(() => {
|
|
871
|
-
latestResultCountRef.current = resultCountText;
|
|
872
|
-
}, [resultCountText]);
|
|
873
995
|
useEffect(() => {
|
|
874
|
-
if (
|
|
996
|
+
if (resultCountText === announcedResultCountRef.current) {
|
|
875
997
|
return;
|
|
876
998
|
}
|
|
877
999
|
announcedResultCountRef.current = resultCountText;
|
|
@@ -1138,26 +1260,21 @@ export function PowerSearchBottomSheet({
|
|
|
1138
1260
|
// confirmation must be gone before focus moves into the sheet and the
|
|
1139
1261
|
// outcome is routed into the sheet's region, so its close is flushed
|
|
1140
1262
|
// first. The outcome is "Editable filters removed" while a read-only filter
|
|
1141
|
-
// remains, otherwise "All filters removed"
|
|
1142
|
-
//
|
|
1143
|
-
// sheet's first remaining control: a kept read-only row has none,
|
|
1144
|
-
// filter.
|
|
1263
|
+
// remains, otherwise "All filters removed"; the result count follows the
|
|
1264
|
+
// applied filters, which change on Done, so none changes here. Focus moves
|
|
1265
|
+
// to the sheet's first remaining control: a kept read-only row has none,
|
|
1266
|
+
// so Add filter.
|
|
1145
1267
|
const closeClearConfirmation = confirmed => {
|
|
1146
1268
|
const kept = filters.filter(filter => filter.isReadOnly);
|
|
1147
1269
|
const firstRemovedIndex = filters.findIndex(filter => !filter.isReadOnly);
|
|
1148
1270
|
const isClearing = confirmed && isInteractive && firstRemovedIndex >= 0;
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
}
|
|
1157
|
-
});
|
|
1158
|
-
} finally {
|
|
1159
|
-
isClearingRef.current = false;
|
|
1160
|
-
}
|
|
1271
|
+
// eslint-disable-next-line @eslint-react/dom-no-flush-sync -- the confirmation must be gone before focus moves into the sheet and the words are routed into it
|
|
1272
|
+
flushSync(() => {
|
|
1273
|
+
setIsClearConfirmationOpen(false);
|
|
1274
|
+
if (isClearing) {
|
|
1275
|
+
onChange(kept, 'remove', firstRemovedIndex);
|
|
1276
|
+
}
|
|
1277
|
+
});
|
|
1161
1278
|
if (!isClearing) {
|
|
1162
1279
|
clearAllButtonRef.current?.focus();
|
|
1163
1280
|
return;
|
|
@@ -1165,18 +1282,7 @@ export function PowerSearchBottomSheet({
|
|
|
1165
1282
|
managerAddButtonRef.current?.focus({
|
|
1166
1283
|
preventScroll: true
|
|
1167
1284
|
});
|
|
1168
|
-
|
|
1169
|
-
const changedCount = resultCount !== announcedResultCountRef.current ? resultCount : null;
|
|
1170
|
-
announcedResultCountRef.current = resultCount;
|
|
1171
|
-
if (kept.length > 0) {
|
|
1172
|
-
announce(changedCount == null ? t('@astryx.powersearch.editableFiltersRemoved') : t('@astryx.powersearch.sheet.editableFiltersClearedWithCount', {
|
|
1173
|
-
resultCount: changedCount
|
|
1174
|
-
}));
|
|
1175
|
-
} else {
|
|
1176
|
-
announce(changedCount == null ? t('@astryx.powersearch.allFiltersRemoved') : t('@astryx.powersearch.sheet.filtersClearedWithCount', {
|
|
1177
|
-
resultCount: changedCount
|
|
1178
|
-
}));
|
|
1179
|
-
}
|
|
1285
|
+
announce(kept.length > 0 ? t('@astryx.powersearch.editableFiltersRemoved') : t('@astryx.powersearch.allFiltersRemoved'));
|
|
1180
1286
|
};
|
|
1181
1287
|
const handleOperatorSelect = useCallback(operator => {
|
|
1182
1288
|
setDraft(current => {
|
|
@@ -1270,20 +1376,20 @@ export function PowerSearchBottomSheet({
|
|
|
1270
1376
|
// Every step change goes through the handlers above.
|
|
1271
1377
|
const handleManageOpenChange = useCallback(isSheetOpen => {
|
|
1272
1378
|
if (!isSheetOpen && stepRef.current === 'manage') {
|
|
1273
|
-
|
|
1379
|
+
requestDismiss();
|
|
1274
1380
|
}
|
|
1275
|
-
}, [
|
|
1381
|
+
}, [requestDismiss]);
|
|
1276
1382
|
const handleFieldsOpenChange = useCallback(isSheetOpen => {
|
|
1277
1383
|
if (isSheetOpen || stepRef.current !== 'fields') {
|
|
1278
1384
|
return;
|
|
1279
1385
|
}
|
|
1280
1386
|
if (fieldPickerOrigin === 'trigger') {
|
|
1281
|
-
|
|
1387
|
+
requestDismiss();
|
|
1282
1388
|
return;
|
|
1283
1389
|
}
|
|
1284
1390
|
queueManagerAddFocus();
|
|
1285
1391
|
setStep('manage');
|
|
1286
|
-
}, [
|
|
1392
|
+
}, [fieldPickerOrigin, queueManagerAddFocus, requestDismiss]);
|
|
1287
1393
|
const handleValueOpenChange = useCallback(isSheetOpen => {
|
|
1288
1394
|
if (!isSheetOpen && stepRef.current === 'value') {
|
|
1289
1395
|
returnFromValue();
|
|
@@ -1510,7 +1616,7 @@ export function PowerSearchBottomSheet({
|
|
|
1510
1616
|
// action. Mounted only while the sheet is open, so its text
|
|
1511
1617
|
// is spoken in this sheet when it appears.
|
|
1512
1618
|
isManageSheetOpen && /*#__PURE__*/_jsx(EmptyState, {
|
|
1513
|
-
title: t('@astryx.powersearch.sheet.noFilters'),
|
|
1619
|
+
title: t(isDraftDirty ? '@astryx.powersearch.sheet.noFiltersInDraft' : '@astryx.powersearch.sheet.noFilters'),
|
|
1514
1620
|
description: t('@astryx.powersearch.sheet.noFiltersDescription'),
|
|
1515
1621
|
headingLevel: 4,
|
|
1516
1622
|
icon: /*#__PURE__*/_jsx(Icon, {
|
|
@@ -1574,7 +1680,7 @@ export function PowerSearchBottomSheet({
|
|
|
1574
1680
|
})
|
|
1575
1681
|
})
|
|
1576
1682
|
})
|
|
1577
|
-
}), filterRows.length > 0 && /*#__PURE__*/_jsxs("div", {
|
|
1683
|
+
}), (filterRows.length > 0 || isDraftDirty) && /*#__PURE__*/_jsxs("div", {
|
|
1578
1684
|
...{
|
|
1579
1685
|
className: "x1vjfegm x78zum5 x6s0dn4 x1qughib x1txdalj x8o8v82 x1pzlopt x10xzikg x1n2onr6 xdd4er5 x2lah0s"
|
|
1580
1686
|
},
|
|
@@ -1590,7 +1696,7 @@ export function PowerSearchBottomSheet({
|
|
|
1590
1696
|
variant: "primary",
|
|
1591
1697
|
size: "lg",
|
|
1592
1698
|
xstyle: isClearAllShown ? styles.footerEqualAction : [styles.footerSoleAction, styles.touchHitArea],
|
|
1593
|
-
onClick:
|
|
1699
|
+
onClick: commitAndClose,
|
|
1594
1700
|
width: isClearAllShown ? undefined : '100%'
|
|
1595
1701
|
})]
|
|
1596
1702
|
})]
|
|
@@ -1776,7 +1882,7 @@ export function PowerSearchBottomSheet({
|
|
|
1776
1882
|
variant: "primary",
|
|
1777
1883
|
width: "100%",
|
|
1778
1884
|
xstyle: styles.touchAction,
|
|
1779
|
-
onClick:
|
|
1885
|
+
onClick: commitAndClose
|
|
1780
1886
|
})
|
|
1781
1887
|
})]
|
|
1782
1888
|
})
|
|
@@ -1913,6 +2019,22 @@ export function PowerSearchBottomSheet({
|
|
|
1913
2019
|
actionLabel: t('@astryx.powersearch.sheet.clearAllConfirm'),
|
|
1914
2020
|
cancelLabel: t('@astryx.powersearch.sheet.clearAllCancel'),
|
|
1915
2021
|
onAction: () => closeClearConfirmation(true)
|
|
2022
|
+
}), isDiscardConfirmationOpen && /*#__PURE__*/_jsx(SheetConfirmation, {
|
|
2023
|
+
isOpen: true,
|
|
2024
|
+
onOpenChange: isConfirmationOpen => {
|
|
2025
|
+
if (!isConfirmationOpen) {
|
|
2026
|
+
closeDiscardConfirmation();
|
|
2027
|
+
}
|
|
2028
|
+
},
|
|
2029
|
+
title: t('@astryx.powersearch.sheet.discardTitle'),
|
|
2030
|
+
description: t('@astryx.powersearch.sheet.discardDescription'),
|
|
2031
|
+
actionLabel: t('@astryx.powersearch.sheet.discardConfirm'),
|
|
2032
|
+
cancelLabel: t('@astryx.powersearch.sheet.keepEditing'),
|
|
2033
|
+
onAction: () => {
|
|
2034
|
+
setIsDiscardConfirmationOpen(false);
|
|
2035
|
+
draftEditsRef.current = [];
|
|
2036
|
+
closeFlow();
|
|
2037
|
+
}
|
|
1916
2038
|
})]
|
|
1917
2039
|
});
|
|
1918
2040
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PowerSearchBottomSheet.generated.d.ts","sourceRoot":"","sources":["../../../../src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,QAAA,MAAM,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"PowerSearchBottomSheet.generated.d.ts","sourceRoot":"","sources":["../../../../src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,QAAA,MAAM,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmC7C,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -18,15 +18,18 @@ const english = {
|
|
|
18
18
|
"@astryx.powersearch.sheet.clearAllConfirm": "Clear filters",
|
|
19
19
|
"@astryx.powersearch.sheet.clearAllDescription": "This removes all editable filters from this search.",
|
|
20
20
|
"@astryx.powersearch.sheet.clearAllTitle": "Clear all filters?",
|
|
21
|
+
"@astryx.powersearch.sheet.discardConfirm": "Discard changes",
|
|
22
|
+
"@astryx.powersearch.sheet.discardDescription": "Your changes to the filters haven't been applied.",
|
|
23
|
+
"@astryx.powersearch.sheet.discardTitle": "Discard changes?",
|
|
21
24
|
"@astryx.powersearch.sheet.done": "Done",
|
|
22
|
-
"@astryx.powersearch.sheet.editableFiltersClearedWithCount": "Editable filters removed. {resultCount}",
|
|
23
25
|
"@astryx.powersearch.sheet.fieldOperator": "{field} {operator}",
|
|
24
26
|
"@astryx.powersearch.sheet.filterUnavailable": "This filter is no longer available",
|
|
25
|
-
"@astryx.powersearch.sheet.filtersClearedWithCount": "All filters removed. {resultCount}",
|
|
26
27
|
"@astryx.powersearch.sheet.filtersTitle": "Filters",
|
|
28
|
+
"@astryx.powersearch.sheet.keepEditing": "Keep editing",
|
|
27
29
|
"@astryx.powersearch.sheet.labelValue": "{label} {value}",
|
|
28
30
|
"@astryx.powersearch.sheet.noFilters": "No filters applied",
|
|
29
31
|
"@astryx.powersearch.sheet.noFiltersDescription": "Add a filter to narrow your results and find what you need faster.",
|
|
32
|
+
"@astryx.powersearch.sheet.noFiltersInDraft": "No filters",
|
|
30
33
|
"@astryx.powersearch.sheet.noMatchingFields": "No filters match your search",
|
|
31
34
|
"@astryx.powersearch.sheet.noResults": "No results found",
|
|
32
35
|
"@astryx.powersearch.sheet.removeFilter": "Remove {field} filter",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.generated.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated-locales/en.generated.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,QAAA,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"en.generated.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated-locales/en.generated.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,QAAA,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmqBpD,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -74,6 +74,7 @@ const runtimeCatalog = {
|
|
|
74
74
|
'@astryx.powersearch.sheet.filtersTitle': 'Filters',
|
|
75
75
|
'@astryx.powersearch.sheet.addFilter': 'Add filter',
|
|
76
76
|
'@astryx.powersearch.sheet.noFilters': 'No filters applied',
|
|
77
|
+
'@astryx.powersearch.sheet.noFiltersInDraft': 'No filters',
|
|
77
78
|
'@astryx.powersearch.sheet.noFiltersDescription': 'Add a filter to narrow your results and find what you need faster.',
|
|
78
79
|
'@astryx.powersearch.sheet.clearAll': 'Clear all',
|
|
79
80
|
'@astryx.powersearch.sheet.clearAllTitle': 'Clear all filters?',
|
|
@@ -81,6 +82,10 @@ const runtimeCatalog = {
|
|
|
81
82
|
'@astryx.powersearch.sheet.clearAllConfirm': 'Clear filters',
|
|
82
83
|
'@astryx.powersearch.sheet.clearAllCancel': 'Keep filters',
|
|
83
84
|
'@astryx.powersearch.sheet.done': 'Done',
|
|
85
|
+
'@astryx.powersearch.sheet.discardTitle': 'Discard changes?',
|
|
86
|
+
'@astryx.powersearch.sheet.discardDescription': "Your changes to the filters haven't been applied.",
|
|
87
|
+
'@astryx.powersearch.sheet.keepEditing': 'Keep editing',
|
|
88
|
+
'@astryx.powersearch.sheet.discardConfirm': 'Discard changes',
|
|
84
89
|
'@astryx.powersearch.sheet.search': 'Search',
|
|
85
90
|
'@astryx.powersearch.sheet.searchResults': 'Search results',
|
|
86
91
|
'@astryx.powersearch.sheet.searchFields': 'Search filters',
|
|
@@ -99,8 +104,6 @@ const runtimeCatalog = {
|
|
|
99
104
|
'@astryx.powersearch.sheet.relativeMonthsFromNow': '{count, number} {count, plural, one {month} other {months}} from now',
|
|
100
105
|
'@astryx.powersearch.sheet.fieldOperator': '{field} {operator}',
|
|
101
106
|
'@astryx.powersearch.sheet.labelValue': '{label} {value}',
|
|
102
|
-
'@astryx.powersearch.sheet.filtersClearedWithCount': 'All filters removed. {resultCount}',
|
|
103
|
-
'@astryx.powersearch.sheet.editableFiltersClearedWithCount': 'Editable filters removed. {resultCount}',
|
|
104
107
|
'@astryx.alertDialog.cancel': 'Cancel',
|
|
105
108
|
'@astryx.appShell.mobileNavigation': 'Mobile navigation',
|
|
106
109
|
'@astryx.appShell.skipToContent': 'Skip to content',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pseudo.generated.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated-locales/pseudo.generated.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,QAAA,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"pseudo.generated.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated-locales/pseudo.generated.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,QAAA,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA+qBpD,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -74,6 +74,7 @@ const runtimeCatalog = {
|
|
|
74
74
|
'@astryx.powersearch.sheet.filtersTitle': '⟦Ƒíłţéřš⟧',
|
|
75
75
|
'@astryx.powersearch.sheet.addFilter': '⟦Àðð ƒíłţéř⟧',
|
|
76
76
|
'@astryx.powersearch.sheet.noFilters': '⟦Ñó ƒíłţéřš àþþłíéð⟧',
|
|
77
|
+
'@astryx.powersearch.sheet.noFiltersInDraft': '⟦Ñó ƒíłţéřš⟧',
|
|
77
78
|
'@astryx.powersearch.sheet.noFiltersDescription': '⟦Àðð à ƒíłţéř ţó ñàřřóŵ ýóúř řéšúłţš àñð ƒíñð ŵĥàţ ýóú ñééð ƒàšţéř.⟧',
|
|
78
79
|
'@astryx.powersearch.sheet.clearAll': '⟦Çłéàř àłł⟧',
|
|
79
80
|
'@astryx.powersearch.sheet.clearAllTitle': '⟦Çłéàř àłł ƒíłţéřš?⟧',
|
|
@@ -81,6 +82,10 @@ const runtimeCatalog = {
|
|
|
81
82
|
'@astryx.powersearch.sheet.clearAllConfirm': '⟦Çłéàř ƒíłţéřš⟧',
|
|
82
83
|
'@astryx.powersearch.sheet.clearAllCancel': '⟦Ķééþ ƒíłţéřš⟧',
|
|
83
84
|
'@astryx.powersearch.sheet.done': '⟦Ðóñé⟧',
|
|
85
|
+
'@astryx.powersearch.sheet.discardTitle': '⟦Ðíšçàřð çĥàñĝéš?⟧',
|
|
86
|
+
'@astryx.powersearch.sheet.discardDescription': "⟦Ýóúř çĥàñĝéš ţó ţĥé ƒíłţéřš ĥàṽéñ'ţ ƀééñ àþþłíéð.⟧",
|
|
87
|
+
'@astryx.powersearch.sheet.keepEditing': '⟦Ķééþ éðíţíñĝ⟧',
|
|
88
|
+
'@astryx.powersearch.sheet.discardConfirm': '⟦Ðíšçàřð çĥàñĝéš⟧',
|
|
84
89
|
'@astryx.powersearch.sheet.search': '⟦Šéàřçĥ⟧',
|
|
85
90
|
'@astryx.powersearch.sheet.searchResults': '⟦Šéàřçĥ řéšúłţš⟧',
|
|
86
91
|
'@astryx.powersearch.sheet.searchFields': '⟦Šéàřçĥ ƒíłţéřš⟧',
|
|
@@ -99,8 +104,6 @@ const runtimeCatalog = {
|
|
|
99
104
|
'@astryx.powersearch.sheet.relativeMonthsFromNow': '⟦{count, number} {count, plural, one {month} other {months}} ƒřóɱ ñóŵ⟧',
|
|
100
105
|
'@astryx.powersearch.sheet.fieldOperator': '⟦{field} {operator}⟧',
|
|
101
106
|
'@astryx.powersearch.sheet.labelValue': '⟦{label} {value}⟧',
|
|
102
|
-
'@astryx.powersearch.sheet.filtersClearedWithCount': '⟦Àłł ƒíłţéřš řéɱóṽéð. {resultCount}⟧',
|
|
103
|
-
'@astryx.powersearch.sheet.editableFiltersClearedWithCount': '⟦Éðíţàƀłé ƒíłţéřš řéɱóṽéð. {resultCount}⟧',
|
|
104
107
|
'@astryx.alertDialog.cancel': '⟦Çàñçéł⟧',
|
|
105
108
|
'@astryx.appShell.mobileNavigation': '⟦Ṁóƀíłé ñàṽíĝàţíóñ⟧',
|
|
106
109
|
'@astryx.appShell.skipToContent': '⟦Šķíþ ţó çóñţéñţ⟧',
|
package/locales/en.json
CHANGED
|
@@ -267,6 +267,10 @@
|
|
|
267
267
|
"defaultMessage": "No filters applied",
|
|
268
268
|
"description": "Heading of the PowerSearch Filters sheet empty state when no filter is active (experimental bottom-sheet presentation). Neutral tone."
|
|
269
269
|
},
|
|
270
|
+
"@astryx.powersearch.sheet.noFiltersInDraft": {
|
|
271
|
+
"defaultMessage": "No filters",
|
|
272
|
+
"description": "Heading of the PowerSearch Filters sheet empty state while the sheet's draft is empty but the field still has applied filters, which Done replaces. Must not say the filters are applied or removed yet. Neutral tone."
|
|
273
|
+
},
|
|
270
274
|
"@astryx.powersearch.sheet.noFiltersDescription": {
|
|
271
275
|
"defaultMessage": "Add a filter to narrow your results and find what you need faster.",
|
|
272
276
|
"description": "Guidance line under the PowerSearch Filters sheet empty state, above its Add filter action. One short sentence."
|
|
@@ -293,7 +297,23 @@
|
|
|
293
297
|
},
|
|
294
298
|
"@astryx.powersearch.sheet.done": {
|
|
295
299
|
"defaultMessage": "Done",
|
|
296
|
-
"description": "Primary button label in the PowerSearch Filters sheet footer that closes the sheet. Short; marks the end of the filtering task."
|
|
300
|
+
"description": "Primary button label in the PowerSearch Filters sheet footer that commits the sheet's filter draft and closes the sheet. Short; marks the end of the filtering task."
|
|
301
|
+
},
|
|
302
|
+
"@astryx.powersearch.sheet.discardTitle": {
|
|
303
|
+
"defaultMessage": "Discard changes?",
|
|
304
|
+
"description": "Title of the confirmation dialog shown when someone tries to dismiss the PowerSearch filter sheet after changing its filter draft. A question."
|
|
305
|
+
},
|
|
306
|
+
"@astryx.powersearch.sheet.discardDescription": {
|
|
307
|
+
"defaultMessage": "Your changes to the filters haven't been applied.",
|
|
308
|
+
"description": "Body of the dirty-dismiss confirmation inside the PowerSearch filter sheet. Done applies the draft; a dismissal would drop it."
|
|
309
|
+
},
|
|
310
|
+
"@astryx.powersearch.sheet.keepEditing": {
|
|
311
|
+
"defaultMessage": "Keep editing",
|
|
312
|
+
"description": "Label of the safe cancel action in the PowerSearch dirty-dismiss confirmation. It closes the confirmation and returns to the unchanged draft."
|
|
313
|
+
},
|
|
314
|
+
"@astryx.powersearch.sheet.discardConfirm": {
|
|
315
|
+
"defaultMessage": "Discard changes",
|
|
316
|
+
"description": "Label of the destructive action in the PowerSearch dirty-dismiss confirmation. It closes the sheet without applying its filter draft."
|
|
297
317
|
},
|
|
298
318
|
"@astryx.powersearch.sheet.search": {
|
|
299
319
|
"defaultMessage": "Search",
|
|
@@ -367,14 +387,6 @@
|
|
|
367
387
|
"defaultMessage": "{label} {value}",
|
|
368
388
|
"description": "A Filters row's \"field operator\" text joined with its value, as the removal announcement reads it (for example \"Status is Open\"). Translators may reorder the two parts."
|
|
369
389
|
},
|
|
370
|
-
"@astryx.powersearch.sheet.filtersClearedWithCount": {
|
|
371
|
-
"defaultMessage": "All filters removed. {resultCount}",
|
|
372
|
-
"description": "Polite screen-reader announcement after Clear all in the PowerSearch touch sheet when the result count changed with it; resultCount is the field's already formatted result count (for example \"240 results\"). Live-region text, never shown on screen."
|
|
373
|
-
},
|
|
374
|
-
"@astryx.powersearch.sheet.editableFiltersClearedWithCount": {
|
|
375
|
-
"defaultMessage": "Editable filters removed. {resultCount}",
|
|
376
|
-
"description": "Polite screen-reader announcement after Clear all in the PowerSearch touch sheet removes the editable filters, keeps read-only ones, and the result count changed with it; resultCount is the field's already formatted result count (for example \"240 results\"). Live-region text, never shown on screen."
|
|
377
|
-
},
|
|
378
390
|
"@astryx.alertDialog.cancel": {
|
|
379
391
|
"defaultMessage": "Cancel",
|
|
380
392
|
"description": "Button label on the secondary/dismiss button of an AlertDialog (modal confirmation). Imperative verb; consumers usually override with task-specific text."
|
package/locales/pseudo.json
CHANGED
|
@@ -200,6 +200,9 @@
|
|
|
200
200
|
"@astryx.powersearch.sheet.noFilters": {
|
|
201
201
|
"defaultMessage": "⟦Ñó ƒíłţéřš àþþłíéð⟧"
|
|
202
202
|
},
|
|
203
|
+
"@astryx.powersearch.sheet.noFiltersInDraft": {
|
|
204
|
+
"defaultMessage": "⟦Ñó ƒíłţéřš⟧"
|
|
205
|
+
},
|
|
203
206
|
"@astryx.powersearch.sheet.noFiltersDescription": {
|
|
204
207
|
"defaultMessage": "⟦Àðð à ƒíłţéř ţó ñàřřóŵ ýóúř řéšúłţš àñð ƒíñð ŵĥàţ ýóú ñééð ƒàšţéř.⟧"
|
|
205
208
|
},
|
|
@@ -221,6 +224,18 @@
|
|
|
221
224
|
"@astryx.powersearch.sheet.done": {
|
|
222
225
|
"defaultMessage": "⟦Ðóñé⟧"
|
|
223
226
|
},
|
|
227
|
+
"@astryx.powersearch.sheet.discardTitle": {
|
|
228
|
+
"defaultMessage": "⟦Ðíšçàřð çĥàñĝéš?⟧"
|
|
229
|
+
},
|
|
230
|
+
"@astryx.powersearch.sheet.discardDescription": {
|
|
231
|
+
"defaultMessage": "⟦Ýóúř çĥàñĝéš ţó ţĥé ƒíłţéřš ĥàṽéñ'ţ ƀééñ àþþłíéð.⟧"
|
|
232
|
+
},
|
|
233
|
+
"@astryx.powersearch.sheet.keepEditing": {
|
|
234
|
+
"defaultMessage": "⟦Ķééþ éðíţíñĝ⟧"
|
|
235
|
+
},
|
|
236
|
+
"@astryx.powersearch.sheet.discardConfirm": {
|
|
237
|
+
"defaultMessage": "⟦Ðíšçàřð çĥàñĝéš⟧"
|
|
238
|
+
},
|
|
224
239
|
"@astryx.powersearch.sheet.search": {
|
|
225
240
|
"defaultMessage": "⟦Šéàřçĥ⟧"
|
|
226
241
|
},
|
|
@@ -275,12 +290,6 @@
|
|
|
275
290
|
"@astryx.powersearch.sheet.labelValue": {
|
|
276
291
|
"defaultMessage": "⟦{label} {value}⟧"
|
|
277
292
|
},
|
|
278
|
-
"@astryx.powersearch.sheet.filtersClearedWithCount": {
|
|
279
|
-
"defaultMessage": "⟦Àłł ƒíłţéřš řéɱóṽéð. {resultCount}⟧"
|
|
280
|
-
},
|
|
281
|
-
"@astryx.powersearch.sheet.editableFiltersClearedWithCount": {
|
|
282
|
-
"defaultMessage": "⟦Éðíţàƀłé ƒíłţéřš řéɱóṽéð. {resultCount}⟧"
|
|
283
|
-
},
|
|
284
293
|
"@astryx.alertDialog.cancel": {
|
|
285
294
|
"defaultMessage": "⟦Çàñçéł⟧"
|
|
286
295
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/core",
|
|
3
|
-
"version": "0.7.8-canary.
|
|
3
|
+
"version": "0.7.8-canary.cc034ed",
|
|
4
4
|
"displayName": "Astryx Core",
|
|
5
5
|
"description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -870,9 +870,9 @@
|
|
|
870
870
|
"react-dom": ">=19.0.0"
|
|
871
871
|
},
|
|
872
872
|
"devDependencies": {
|
|
873
|
-
"@astryxdesign/a11y-spec": "0.7.8-canary.
|
|
874
|
-
"@astryxdesign/cli": "0.7.8-canary.
|
|
875
|
-
"@astryxdesign/interaction-harness": "0.7.8-canary.
|
|
873
|
+
"@astryxdesign/a11y-spec": "0.7.8-canary.cc034ed",
|
|
874
|
+
"@astryxdesign/cli": "0.7.8-canary.cc034ed",
|
|
875
|
+
"@astryxdesign/interaction-harness": "0.7.8-canary.cc034ed",
|
|
876
876
|
"@babel/cli": "^7.29.7",
|
|
877
877
|
"@babel/core": "^7.29.7",
|
|
878
878
|
"@babel/preset-react": "^7.29.7",
|
|
@@ -211,7 +211,7 @@ export const docs = {
|
|
|
211
211
|
name: 'presentation',
|
|
212
212
|
type: "'popover' | 'bottom-sheet' | 'adaptive'",
|
|
213
213
|
description:
|
|
214
|
-
'How the field presents filter editing. adaptive (the default) uses the bottom sheet on compact touch screens and the popover otherwise, resolved the same way Selector resolves it; the server render and the hydrating render are the popover. popover is the tokenizer field with its typeahead and the editor popover on every device. bottom-sheet makes the whole field, on every device, one trigger showing display-only filter tokens: it opens a Filters sheet listing the filters as rows that edit or remove a filter, with Add filter, Done, and Clear all (which asks first and keeps read-only filters); an Add filter sheet with the fields (or the content search with inline suggestions) opens above it, and a value step that stages operator → value and confirms from its footer opens above that. Dismissing a step reveals the one beneath. List values edit through the Tokenizer\'s own sheet. In the sheet presentation menuWidth and tokenOverflowBehavior have no surface to act on and warn in development. Pass presentation="popover" to keep the tokenizer field and the editor popover on every device.',
|
|
214
|
+
'How the field presents filter editing. adaptive (the default) uses the bottom sheet on compact touch screens and the popover otherwise, resolved the same way Selector resolves it; the server render and the hydrating render are the popover. popover is the tokenizer field with its typeahead and the editor popover on every device. bottom-sheet makes the whole field, on every device, one trigger showing display-only filter tokens: it opens a Filters sheet listing the filters as rows that edit or remove a filter, with Add filter, Done, and Clear all (which asks first and keeps read-only filters); an Add filter sheet with the fields (or the content search with inline suggestions) opens above it, and a value step that stages operator → value and confirms from its footer opens above that. Dismissing a step reveals the one beneath. The flow edits a draft: adding, editing and removing filters and Clear all change the draft, and onChange is called when Done applies it, once per edit in order; dismissing the flow with a changed draft asks before discarding it. List values edit through the Tokenizer\'s own sheet. In the sheet presentation menuWidth and tokenOverflowBehavior have no surface to act on and warn in development. Pass presentation="popover" to keep the tokenizer field and the editor popover on every device.',
|
|
215
215
|
default: "'adaptive'",
|
|
216
216
|
},
|
|
217
217
|
],
|
|
@@ -484,7 +484,7 @@ export const docsZh = {
|
|
|
484
484
|
name: 'presentation',
|
|
485
485
|
type: "'popover' | 'bottom-sheet' | 'adaptive'",
|
|
486
486
|
description:
|
|
487
|
-
'字段如何呈现筛选编辑。adaptive(默认)在紧凑触摸屏上使用底部面板,其他情况使用 popover,解析方式与 Selector 相同;服务端渲染和水合期间的渲染均为 popover。popover 在所有设备上为带有预输入和编辑弹出层的标记字段。bottom-sheet 在所有设备上将整个字段变为一个显示只读筛选标记的触发按钮——点按后打开列出筛选项的「筛选」面板,每行可编辑或移除筛选(含添加筛选、完成、全部清除;全部清除会先确认,并保留只读筛选);列出字段(或带内联建议的内容搜索)的「添加筛选」面板在其上方打开,按运算符 →
|
|
487
|
+
'字段如何呈现筛选编辑。adaptive(默认)在紧凑触摸屏上使用底部面板,其他情况使用 popover,解析方式与 Selector 相同;服务端渲染和水合期间的渲染均为 popover。popover 在所有设备上为带有预输入和编辑弹出层的标记字段。bottom-sheet 在所有设备上将整个字段变为一个显示只读筛选标记的触发按钮——点按后打开列出筛选项的「筛选」面板,每行可编辑或移除筛选(含添加筛选、完成、全部清除;全部清除会先确认,并保留只读筛选);列出字段(或带内联建议的内容搜索)的「添加筛选」面板在其上方打开,按运算符 → 值暂存并在底部确认的取值步骤再在其上方打开。关闭某一步会露出下方的那一步。整个流程编辑的是草稿:添加、编辑、移除筛选和全部清除都只改动草稿,点按「完成」应用草稿时才按编辑顺序逐次触发 onChange;草稿有改动时关闭流程会先询问是否放弃。列表值通过 Tokenizer 自身的面板编辑。在底部面板呈现中,menuWidth 和 tokenOverflowBehavior 没有作用对象,并会在开发环境中发出警告。传入 presentation="popover" 可在所有设备上保留标记字段和编辑弹出层。',
|
|
488
488
|
default: "'adaptive'",
|
|
489
489
|
},
|
|
490
490
|
],
|
|
@@ -430,8 +430,10 @@ export interface PowerSearchProps extends Omit<
|
|
|
430
430
|
* above it with the fields (or the content search with inline
|
|
431
431
|
* suggestions), and a value step opens above that, stages operator →
|
|
432
432
|
* value, and confirms from its footer. Dismissing a step reveals the
|
|
433
|
-
* one beneath.
|
|
434
|
-
*
|
|
433
|
+
* one beneath. The flow edits a draft: `onChange` is called when Done
|
|
434
|
+
* applies it, once per edit in order, and a dismissal with a changed
|
|
435
|
+
* draft asks before discarding it. Suited to compact touch screens,
|
|
436
|
+
* where the editor popover competes with the software keyboard.
|
|
435
437
|
* - `'adaptive'`: the bottom sheet on compact coarse-pointer screens,
|
|
436
438
|
* otherwise the popover — the same resolution Selector uses. The server
|
|
437
439
|
* render and the hydrating render are the popover.
|
|
@@ -181,7 +181,14 @@ export interface PowerSearchBottomSheetProps {
|
|
|
181
181
|
config: InternalConfig;
|
|
182
182
|
/** The caller's config, handed to Editor overrides as they expect it. */
|
|
183
183
|
configProp: PowerSearchConfig;
|
|
184
|
+
/** The committed filters; the draft the sheet edits starts from them. */
|
|
184
185
|
filters: ReadonlyArray<PowerSearchFilter>;
|
|
186
|
+
/**
|
|
187
|
+
* The field's `onChange`. Done replays the draft's edits through it, in
|
|
188
|
+
* order, onto the field's latest filters, each call carrying that list
|
|
189
|
+
* with the edit applied; nothing is reported before Done, and nothing when
|
|
190
|
+
* the field is read-only or disabled at Done.
|
|
191
|
+
*/
|
|
185
192
|
onChange: (
|
|
186
193
|
filters: ReadonlyArray<PowerSearchFilter>,
|
|
187
194
|
changeType: PowerSearchChangeType,
|
|
@@ -208,6 +215,116 @@ export interface PowerSearchBottomSheetProps {
|
|
|
208
215
|
// Styles
|
|
209
216
|
// =============================================================================
|
|
210
217
|
|
|
218
|
+
/** One edit of the draft: the draft before and after it, and its type and index in the draft; Done replays it onto the field's latest filters. */
|
|
219
|
+
interface DraftEdit {
|
|
220
|
+
before: ReadonlyArray<PowerSearchFilter>;
|
|
221
|
+
after: ReadonlyArray<PowerSearchFilter>;
|
|
222
|
+
changeType: PowerSearchChangeType;
|
|
223
|
+
index: number;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Whether two filter lists hold the same filters in the same order, by the
|
|
227
|
+
// key-order-insensitive signature the sheet matches filters with.
|
|
228
|
+
function hasSameFilters(
|
|
229
|
+
a: ReadonlyArray<PowerSearchFilter>,
|
|
230
|
+
b: ReadonlyArray<PowerSearchFilter>,
|
|
231
|
+
): boolean {
|
|
232
|
+
return (
|
|
233
|
+
a.length === b.length &&
|
|
234
|
+
a.every(
|
|
235
|
+
(filter, index) =>
|
|
236
|
+
b[index] != null &&
|
|
237
|
+
filterSignature(filter) === filterSignature(b[index]),
|
|
238
|
+
)
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// The filters `before` holds that `after` does not, as a multiset by
|
|
243
|
+
// signature, in `before` order.
|
|
244
|
+
function removedFilters(
|
|
245
|
+
before: ReadonlyArray<PowerSearchFilter>,
|
|
246
|
+
after: ReadonlyArray<PowerSearchFilter>,
|
|
247
|
+
): PowerSearchFilter[] {
|
|
248
|
+
const remaining = new Map<string, number>();
|
|
249
|
+
for (const filter of after) {
|
|
250
|
+
const signature = filterSignature(filter);
|
|
251
|
+
remaining.set(signature, (remaining.get(signature) ?? 0) + 1);
|
|
252
|
+
}
|
|
253
|
+
return before.filter(filter => {
|
|
254
|
+
const signature = filterSignature(filter);
|
|
255
|
+
const count = remaining.get(signature) ?? 0;
|
|
256
|
+
if (count > 0) {
|
|
257
|
+
remaining.set(signature, count - 1);
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
return true;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Replays the draft's edits onto `base`, the field's latest filters, and
|
|
266
|
+
* reports each through `report` with the list after it. An add appends; an
|
|
267
|
+
* edit replaces the first filter matching the one it edited; a removal drops
|
|
268
|
+
* the filters it removed, by signature. An edit or removal whose target is
|
|
269
|
+
* not in the base list is skipped: the parent removed it meanwhile.
|
|
270
|
+
*/
|
|
271
|
+
export function replayDraftEdits(
|
|
272
|
+
base: ReadonlyArray<PowerSearchFilter>,
|
|
273
|
+
edits: ReadonlyArray<DraftEdit>,
|
|
274
|
+
report: (
|
|
275
|
+
filters: ReadonlyArray<PowerSearchFilter>,
|
|
276
|
+
changeType: PowerSearchChangeType,
|
|
277
|
+
index: number,
|
|
278
|
+
) => void,
|
|
279
|
+
): ReadonlyArray<PowerSearchFilter> {
|
|
280
|
+
let current = base;
|
|
281
|
+
for (const edit of edits) {
|
|
282
|
+
if (edit.changeType === 'add') {
|
|
283
|
+
const added = edit.after[edit.index];
|
|
284
|
+
if (added == null) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
current = [...current, added];
|
|
288
|
+
report(current, 'add', current.length - 1);
|
|
289
|
+
} else if (edit.changeType === 'edit') {
|
|
290
|
+
const original = edit.before[edit.index];
|
|
291
|
+
const updated = edit.after[edit.index];
|
|
292
|
+
if (original == null || updated == null) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const signature = filterSignature(original);
|
|
296
|
+
const index = current.findIndex(
|
|
297
|
+
filter => filterSignature(filter) === signature,
|
|
298
|
+
);
|
|
299
|
+
if (index === -1) {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
current = current.map((filter, i) => (i === index ? updated : filter));
|
|
303
|
+
report(current, 'edit', index);
|
|
304
|
+
} else {
|
|
305
|
+
const removed = removedFilters(edit.before, edit.after).map(
|
|
306
|
+
filterSignature,
|
|
307
|
+
);
|
|
308
|
+
const indexes: number[] = [];
|
|
309
|
+
for (const signature of removed) {
|
|
310
|
+
const index = current.findIndex(
|
|
311
|
+
(filter, i) =>
|
|
312
|
+
!indexes.includes(i) && filterSignature(filter) === signature,
|
|
313
|
+
);
|
|
314
|
+
if (index !== -1) {
|
|
315
|
+
indexes.push(index);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (indexes.length === 0) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
current = current.filter((_, i) => !indexes.includes(i));
|
|
322
|
+
report(current, 'remove', Math.min(...indexes));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return current;
|
|
326
|
+
}
|
|
327
|
+
|
|
211
328
|
// The trailing plus a field row shows when choosing it adds the filter at
|
|
212
329
|
// once, and the Add filter actions' glyph. Core's default icon set has no plus.
|
|
213
330
|
function PlusIcon(props: SVGProps<SVGSVGElement>) {
|
|
@@ -834,8 +951,8 @@ export function PowerSearchBottomSheet({
|
|
|
834
951
|
resultCountText,
|
|
835
952
|
config,
|
|
836
953
|
configProp,
|
|
837
|
-
filters,
|
|
838
|
-
onChange,
|
|
954
|
+
filters: committedFilters,
|
|
955
|
+
onChange: onCommit,
|
|
839
956
|
searchSource,
|
|
840
957
|
placeholder,
|
|
841
958
|
isReadOnly,
|
|
@@ -854,6 +971,35 @@ export function PowerSearchBottomSheet({
|
|
|
854
971
|
const formatList = useListFormatter();
|
|
855
972
|
const isInteractive = !isDisabled && !isReadOnly;
|
|
856
973
|
|
|
974
|
+
// ---- draft ----
|
|
975
|
+
// One open flow edits one draft of the filter list; `onChange` waits for
|
|
976
|
+
// Done, and a dismissal with a changed draft asks first.
|
|
977
|
+
const [filtersAtOpen, setFiltersAtOpen] = useState(() => committedFilters);
|
|
978
|
+
const [filters, setFilters] = useState(() => committedFilters);
|
|
979
|
+
// The draft as of the last edit, for the edit log's `before` lists.
|
|
980
|
+
const draftRef = useRef(filters);
|
|
981
|
+
const draftEditsRef = useRef<DraftEdit[]>([]);
|
|
982
|
+
const onChange = useCallback(
|
|
983
|
+
(
|
|
984
|
+
next: ReadonlyArray<PowerSearchFilter>,
|
|
985
|
+
changeType: PowerSearchChangeType,
|
|
986
|
+
index: number,
|
|
987
|
+
) => {
|
|
988
|
+
draftEditsRef.current.push({
|
|
989
|
+
before: draftRef.current,
|
|
990
|
+
after: next,
|
|
991
|
+
changeType,
|
|
992
|
+
index,
|
|
993
|
+
});
|
|
994
|
+
draftRef.current = next;
|
|
995
|
+
setFilters(next);
|
|
996
|
+
},
|
|
997
|
+
[],
|
|
998
|
+
);
|
|
999
|
+
const isDraftDirty = !hasSameFilters(filtersAtOpen, filters);
|
|
1000
|
+
const [isDiscardConfirmationOpen, setIsDiscardConfirmationOpen] =
|
|
1001
|
+
useState(false);
|
|
1002
|
+
|
|
857
1003
|
const contentSearchFieldKey = config.config.contentSearchFieldKey;
|
|
858
1004
|
const contentSearchOperator =
|
|
859
1005
|
contentSearchFieldKey == null
|
|
@@ -961,9 +1107,6 @@ export function PowerSearchBottomSheet({
|
|
|
961
1107
|
const [contentQuery, setContentQuery] = useState('');
|
|
962
1108
|
const [isClearConfirmationOpen, setIsClearConfirmationOpen] = useState(false);
|
|
963
1109
|
const clearAllButtonRef = useRef<HTMLButtonElement>(null);
|
|
964
|
-
// Set while Clear all commits, so the result count that changes in that
|
|
965
|
-
// commit is spoken with Clear all's outcome, as one message.
|
|
966
|
-
const isClearingRef = useRef(false);
|
|
967
1110
|
|
|
968
1111
|
// `useAnnounce` delivers inside the open Astryx modal that encloses its
|
|
969
1112
|
// caller, and this component renders above the
|
|
@@ -990,13 +1133,21 @@ export function PowerSearchBottomSheet({
|
|
|
990
1133
|
if (isOpen !== wasOpen) {
|
|
991
1134
|
setWasOpen(isOpen);
|
|
992
1135
|
if (isOpen) {
|
|
1136
|
+
// A fresh draft from the committed filters; the entry step is judged
|
|
1137
|
+
// against them, not the previous session's draft.
|
|
1138
|
+
setFiltersAtOpen(committedFilters);
|
|
1139
|
+
setFilters(committedFilters);
|
|
1140
|
+
draftRef.current = committedFilters;
|
|
1141
|
+
draftEditsRef.current = [];
|
|
1142
|
+
const startsOnAddFilter = committedFilters.length === 0 && isInteractive;
|
|
993
1143
|
setFieldQuery('');
|
|
994
1144
|
setContentQuery('');
|
|
995
|
-
setStep(
|
|
996
|
-
setFieldPickerOrigin(
|
|
1145
|
+
setStep(startsOnAddFilter ? 'fields' : 'manage');
|
|
1146
|
+
setFieldPickerOrigin(startsOnAddFilter ? 'trigger' : 'manage');
|
|
997
1147
|
} else {
|
|
998
1148
|
setStep(null);
|
|
999
1149
|
setIsClearConfirmationOpen(false);
|
|
1150
|
+
setIsDiscardConfirmationOpen(false);
|
|
1000
1151
|
}
|
|
1001
1152
|
}
|
|
1002
1153
|
|
|
@@ -1005,6 +1156,34 @@ export function PowerSearchBottomSheet({
|
|
|
1005
1156
|
setStep(null);
|
|
1006
1157
|
onOpenChange(false);
|
|
1007
1158
|
}, [onOpenChange]);
|
|
1159
|
+
// Done replays each edit in order onto the field's latest filters, so a
|
|
1160
|
+
// consumer gets the calls a popover session makes and keeps a filter it
|
|
1161
|
+
// added meanwhile.
|
|
1162
|
+
const commitAndClose = useCallback(() => {
|
|
1163
|
+
// A field that became read-only while the flow was open reports nothing.
|
|
1164
|
+
if (isDraftDirty && isInteractive) {
|
|
1165
|
+
replayDraftEdits(committedFilters, draftEditsRef.current, onCommit);
|
|
1166
|
+
}
|
|
1167
|
+
draftEditsRef.current = [];
|
|
1168
|
+
closeFlow();
|
|
1169
|
+
}, [closeFlow, committedFilters, isDraftDirty, isInteractive, onCommit]);
|
|
1170
|
+
const requestDismiss = useCallback(() => {
|
|
1171
|
+
if (isDraftDirty) {
|
|
1172
|
+
setIsDiscardConfirmationOpen(true);
|
|
1173
|
+
} else {
|
|
1174
|
+
closeFlow();
|
|
1175
|
+
}
|
|
1176
|
+
}, [closeFlow, isDraftDirty]);
|
|
1177
|
+
const closeDiscardConfirmation = () => {
|
|
1178
|
+
// eslint-disable-next-line @eslint-react/dom-no-flush-sync -- the confirmation must be gone before focus moves back into the sheet
|
|
1179
|
+
flushSync(() => setIsDiscardConfirmationOpen(false));
|
|
1180
|
+
const target =
|
|
1181
|
+
stepRef.current === 'manage'
|
|
1182
|
+
? (managerAddButtonRef.current ??
|
|
1183
|
+
manageSheetRef.current?.closest<HTMLElement>('[tabindex="-1"]'))
|
|
1184
|
+
: fieldsSheetRef.current?.closest<HTMLElement>('[tabindex="-1"]');
|
|
1185
|
+
target?.focus({preventScroll: true});
|
|
1186
|
+
};
|
|
1008
1187
|
|
|
1009
1188
|
// Whether a Filters row is a button: the field interactive and the
|
|
1010
1189
|
// filter not read-only. The row opens the value step — the editor for its
|
|
@@ -1279,17 +1458,8 @@ export function PowerSearchBottomSheet({
|
|
|
1279
1458
|
// is quiet then, so the change is spoken here, inside the dialog. Only a
|
|
1280
1459
|
// change after the flow opened is spoken.
|
|
1281
1460
|
const announcedResultCountRef = useRef(resultCountText);
|
|
1282
|
-
// The latest result count, for Clear all's handler to read after its
|
|
1283
|
-
// commit has flushed.
|
|
1284
|
-
const latestResultCountRef = useRef(resultCountText);
|
|
1285
|
-
useLayoutEffect(() => {
|
|
1286
|
-
latestResultCountRef.current = resultCountText;
|
|
1287
|
-
}, [resultCountText]);
|
|
1288
1461
|
useEffect(() => {
|
|
1289
|
-
if (
|
|
1290
|
-
isClearingRef.current ||
|
|
1291
|
-
resultCountText === announcedResultCountRef.current
|
|
1292
|
-
) {
|
|
1462
|
+
if (resultCountText === announcedResultCountRef.current) {
|
|
1293
1463
|
return;
|
|
1294
1464
|
}
|
|
1295
1465
|
announcedResultCountRef.current = resultCountText;
|
|
@@ -1630,52 +1800,31 @@ export function PowerSearchBottomSheet({
|
|
|
1630
1800
|
// confirmation must be gone before focus moves into the sheet and the
|
|
1631
1801
|
// outcome is routed into the sheet's region, so its close is flushed
|
|
1632
1802
|
// first. The outcome is "Editable filters removed" while a read-only filter
|
|
1633
|
-
// remains, otherwise "All filters removed"
|
|
1634
|
-
//
|
|
1635
|
-
// sheet's first remaining control: a kept read-only row has none,
|
|
1636
|
-
// filter.
|
|
1803
|
+
// remains, otherwise "All filters removed"; the result count follows the
|
|
1804
|
+
// applied filters, which change on Done, so none changes here. Focus moves
|
|
1805
|
+
// to the sheet's first remaining control: a kept read-only row has none,
|
|
1806
|
+
// so Add filter.
|
|
1637
1807
|
const closeClearConfirmation = (confirmed: boolean) => {
|
|
1638
1808
|
const kept = filters.filter(filter => filter.isReadOnly);
|
|
1639
1809
|
const firstRemovedIndex = filters.findIndex(filter => !filter.isReadOnly);
|
|
1640
1810
|
const isClearing = confirmed && isInteractive && firstRemovedIndex >= 0;
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
}
|
|
1649
|
-
});
|
|
1650
|
-
} finally {
|
|
1651
|
-
isClearingRef.current = false;
|
|
1652
|
-
}
|
|
1811
|
+
// eslint-disable-next-line @eslint-react/dom-no-flush-sync -- the confirmation must be gone before focus moves into the sheet and the words are routed into it
|
|
1812
|
+
flushSync(() => {
|
|
1813
|
+
setIsClearConfirmationOpen(false);
|
|
1814
|
+
if (isClearing) {
|
|
1815
|
+
onChange(kept, 'remove', firstRemovedIndex);
|
|
1816
|
+
}
|
|
1817
|
+
});
|
|
1653
1818
|
if (!isClearing) {
|
|
1654
1819
|
clearAllButtonRef.current?.focus();
|
|
1655
1820
|
return;
|
|
1656
1821
|
}
|
|
1657
1822
|
managerAddButtonRef.current?.focus({preventScroll: true});
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
announce(
|
|
1664
|
-
changedCount == null
|
|
1665
|
-
? t('@astryx.powersearch.editableFiltersRemoved')
|
|
1666
|
-
: t('@astryx.powersearch.sheet.editableFiltersClearedWithCount', {
|
|
1667
|
-
resultCount: changedCount,
|
|
1668
|
-
}),
|
|
1669
|
-
);
|
|
1670
|
-
} else {
|
|
1671
|
-
announce(
|
|
1672
|
-
changedCount == null
|
|
1673
|
-
? t('@astryx.powersearch.allFiltersRemoved')
|
|
1674
|
-
: t('@astryx.powersearch.sheet.filtersClearedWithCount', {
|
|
1675
|
-
resultCount: changedCount,
|
|
1676
|
-
}),
|
|
1677
|
-
);
|
|
1678
|
-
}
|
|
1823
|
+
announce(
|
|
1824
|
+
kept.length > 0
|
|
1825
|
+
? t('@astryx.powersearch.editableFiltersRemoved')
|
|
1826
|
+
: t('@astryx.powersearch.allFiltersRemoved'),
|
|
1827
|
+
);
|
|
1679
1828
|
};
|
|
1680
1829
|
|
|
1681
1830
|
const handleOperatorSelect = useCallback((operator: PowerSearchOperator) => {
|
|
@@ -1776,10 +1925,10 @@ export function PowerSearchBottomSheet({
|
|
|
1776
1925
|
const handleManageOpenChange = useCallback(
|
|
1777
1926
|
(isSheetOpen: boolean) => {
|
|
1778
1927
|
if (!isSheetOpen && stepRef.current === 'manage') {
|
|
1779
|
-
|
|
1928
|
+
requestDismiss();
|
|
1780
1929
|
}
|
|
1781
1930
|
},
|
|
1782
|
-
[
|
|
1931
|
+
[requestDismiss],
|
|
1783
1932
|
);
|
|
1784
1933
|
const handleFieldsOpenChange = useCallback(
|
|
1785
1934
|
(isSheetOpen: boolean) => {
|
|
@@ -1787,13 +1936,13 @@ export function PowerSearchBottomSheet({
|
|
|
1787
1936
|
return;
|
|
1788
1937
|
}
|
|
1789
1938
|
if (fieldPickerOrigin === 'trigger') {
|
|
1790
|
-
|
|
1939
|
+
requestDismiss();
|
|
1791
1940
|
return;
|
|
1792
1941
|
}
|
|
1793
1942
|
queueManagerAddFocus();
|
|
1794
1943
|
setStep('manage');
|
|
1795
1944
|
},
|
|
1796
|
-
[
|
|
1945
|
+
[fieldPickerOrigin, queueManagerAddFocus, requestDismiss],
|
|
1797
1946
|
);
|
|
1798
1947
|
const handleValueOpenChange = useCallback(
|
|
1799
1948
|
(isSheetOpen: boolean) => {
|
|
@@ -2076,7 +2225,11 @@ export function PowerSearchBottomSheet({
|
|
|
2076
2225
|
// is spoken in this sheet when it appears.
|
|
2077
2226
|
isManageSheetOpen && (
|
|
2078
2227
|
<EmptyState
|
|
2079
|
-
title={t(
|
|
2228
|
+
title={t(
|
|
2229
|
+
isDraftDirty
|
|
2230
|
+
? '@astryx.powersearch.sheet.noFiltersInDraft'
|
|
2231
|
+
: '@astryx.powersearch.sheet.noFilters',
|
|
2232
|
+
)}
|
|
2080
2233
|
description={t(
|
|
2081
2234
|
'@astryx.powersearch.sheet.noFiltersDescription',
|
|
2082
2235
|
)}
|
|
@@ -2157,7 +2310,10 @@ export function PowerSearchBottomSheet({
|
|
|
2157
2310
|
)}
|
|
2158
2311
|
</div>
|
|
2159
2312
|
</div>
|
|
2160
|
-
{
|
|
2313
|
+
{/* The footer stays while the draft differs from the applied
|
|
2314
|
+
filters: an emptied draft still needs Done to apply the
|
|
2315
|
+
removals. */}
|
|
2316
|
+
{(filterRows.length > 0 || isDraftDirty) && (
|
|
2161
2317
|
<div {...stylex.props(styles.footer, styles.fixedFooter)}>
|
|
2162
2318
|
{isClearAllShown && (
|
|
2163
2319
|
<Button
|
|
@@ -2178,7 +2334,7 @@ export function PowerSearchBottomSheet({
|
|
|
2178
2334
|
? styles.footerEqualAction
|
|
2179
2335
|
: [styles.footerSoleAction, styles.touchHitArea]
|
|
2180
2336
|
}
|
|
2181
|
-
onClick={
|
|
2337
|
+
onClick={commitAndClose}
|
|
2182
2338
|
width={isClearAllShown ? undefined : '100%'}
|
|
2183
2339
|
/>
|
|
2184
2340
|
</div>
|
|
@@ -2373,7 +2529,7 @@ export function PowerSearchBottomSheet({
|
|
|
2373
2529
|
variant="primary"
|
|
2374
2530
|
width="100%"
|
|
2375
2531
|
xstyle={styles.touchAction}
|
|
2376
|
-
onClick={
|
|
2532
|
+
onClick={commitAndClose}
|
|
2377
2533
|
/>
|
|
2378
2534
|
</div>
|
|
2379
2535
|
)}
|
|
@@ -2518,6 +2674,25 @@ export function PowerSearchBottomSheet({
|
|
|
2518
2674
|
onAction={() => closeClearConfirmation(true)}
|
|
2519
2675
|
/>
|
|
2520
2676
|
)}
|
|
2677
|
+
{isDiscardConfirmationOpen && (
|
|
2678
|
+
<SheetConfirmation
|
|
2679
|
+
isOpen
|
|
2680
|
+
onOpenChange={isConfirmationOpen => {
|
|
2681
|
+
if (!isConfirmationOpen) {
|
|
2682
|
+
closeDiscardConfirmation();
|
|
2683
|
+
}
|
|
2684
|
+
}}
|
|
2685
|
+
title={t('@astryx.powersearch.sheet.discardTitle')}
|
|
2686
|
+
description={t('@astryx.powersearch.sheet.discardDescription')}
|
|
2687
|
+
actionLabel={t('@astryx.powersearch.sheet.discardConfirm')}
|
|
2688
|
+
cancelLabel={t('@astryx.powersearch.sheet.keepEditing')}
|
|
2689
|
+
onAction={() => {
|
|
2690
|
+
setIsDiscardConfirmationOpen(false);
|
|
2691
|
+
draftEditsRef.current = [];
|
|
2692
|
+
closeFlow();
|
|
2693
|
+
}}
|
|
2694
|
+
/>
|
|
2695
|
+
)}
|
|
2521
2696
|
</>
|
|
2522
2697
|
);
|
|
2523
2698
|
}
|
|
@@ -18,15 +18,18 @@ const english: Readonly<Record<string, string>> = {
|
|
|
18
18
|
"@astryx.powersearch.sheet.clearAllConfirm": "Clear filters",
|
|
19
19
|
"@astryx.powersearch.sheet.clearAllDescription": "This removes all editable filters from this search.",
|
|
20
20
|
"@astryx.powersearch.sheet.clearAllTitle": "Clear all filters?",
|
|
21
|
+
"@astryx.powersearch.sheet.discardConfirm": "Discard changes",
|
|
22
|
+
"@astryx.powersearch.sheet.discardDescription": "Your changes to the filters haven't been applied.",
|
|
23
|
+
"@astryx.powersearch.sheet.discardTitle": "Discard changes?",
|
|
21
24
|
"@astryx.powersearch.sheet.done": "Done",
|
|
22
|
-
"@astryx.powersearch.sheet.editableFiltersClearedWithCount": "Editable filters removed. {resultCount}",
|
|
23
25
|
"@astryx.powersearch.sheet.fieldOperator": "{field} {operator}",
|
|
24
26
|
"@astryx.powersearch.sheet.filterUnavailable": "This filter is no longer available",
|
|
25
|
-
"@astryx.powersearch.sheet.filtersClearedWithCount": "All filters removed. {resultCount}",
|
|
26
27
|
"@astryx.powersearch.sheet.filtersTitle": "Filters",
|
|
28
|
+
"@astryx.powersearch.sheet.keepEditing": "Keep editing",
|
|
27
29
|
"@astryx.powersearch.sheet.labelValue": "{label} {value}",
|
|
28
30
|
"@astryx.powersearch.sheet.noFilters": "No filters applied",
|
|
29
31
|
"@astryx.powersearch.sheet.noFiltersDescription": "Add a filter to narrow your results and find what you need faster.",
|
|
32
|
+
"@astryx.powersearch.sheet.noFiltersInDraft": "No filters",
|
|
30
33
|
"@astryx.powersearch.sheet.noMatchingFields": "No filters match your search",
|
|
31
34
|
"@astryx.powersearch.sheet.noResults": "No results found",
|
|
32
35
|
"@astryx.powersearch.sheet.removeFilter": "Remove {field} filter",
|
|
@@ -81,6 +81,7 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
81
81
|
'@astryx.powersearch.sheet.filtersTitle': 'Filters',
|
|
82
82
|
'@astryx.powersearch.sheet.addFilter': 'Add filter',
|
|
83
83
|
'@astryx.powersearch.sheet.noFilters': 'No filters applied',
|
|
84
|
+
'@astryx.powersearch.sheet.noFiltersInDraft': 'No filters',
|
|
84
85
|
'@astryx.powersearch.sheet.noFiltersDescription':
|
|
85
86
|
'Add a filter to narrow your results and find what you need faster.',
|
|
86
87
|
'@astryx.powersearch.sheet.clearAll': 'Clear all',
|
|
@@ -90,6 +91,11 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
90
91
|
'@astryx.powersearch.sheet.clearAllConfirm': 'Clear filters',
|
|
91
92
|
'@astryx.powersearch.sheet.clearAllCancel': 'Keep filters',
|
|
92
93
|
'@astryx.powersearch.sheet.done': 'Done',
|
|
94
|
+
'@astryx.powersearch.sheet.discardTitle': 'Discard changes?',
|
|
95
|
+
'@astryx.powersearch.sheet.discardDescription':
|
|
96
|
+
"Your changes to the filters haven't been applied.",
|
|
97
|
+
'@astryx.powersearch.sheet.keepEditing': 'Keep editing',
|
|
98
|
+
'@astryx.powersearch.sheet.discardConfirm': 'Discard changes',
|
|
93
99
|
'@astryx.powersearch.sheet.search': 'Search',
|
|
94
100
|
'@astryx.powersearch.sheet.searchResults': 'Search results',
|
|
95
101
|
'@astryx.powersearch.sheet.searchFields': 'Search filters',
|
|
@@ -115,10 +121,6 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
115
121
|
'{count, number} {count, plural, one {month} other {months}} from now',
|
|
116
122
|
'@astryx.powersearch.sheet.fieldOperator': '{field} {operator}',
|
|
117
123
|
'@astryx.powersearch.sheet.labelValue': '{label} {value}',
|
|
118
|
-
'@astryx.powersearch.sheet.filtersClearedWithCount':
|
|
119
|
-
'All filters removed. {resultCount}',
|
|
120
|
-
'@astryx.powersearch.sheet.editableFiltersClearedWithCount':
|
|
121
|
-
'Editable filters removed. {resultCount}',
|
|
122
124
|
'@astryx.alertDialog.cancel': 'Cancel',
|
|
123
125
|
'@astryx.appShell.mobileNavigation': 'Mobile navigation',
|
|
124
126
|
'@astryx.appShell.skipToContent': 'Skip to content',
|
|
@@ -83,6 +83,7 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
83
83
|
'@astryx.powersearch.sheet.filtersTitle': '⟦Ƒíłţéřš⟧',
|
|
84
84
|
'@astryx.powersearch.sheet.addFilter': '⟦Àðð ƒíłţéř⟧',
|
|
85
85
|
'@astryx.powersearch.sheet.noFilters': '⟦Ñó ƒíłţéřš àþþłíéð⟧',
|
|
86
|
+
'@astryx.powersearch.sheet.noFiltersInDraft': '⟦Ñó ƒíłţéřš⟧',
|
|
86
87
|
'@astryx.powersearch.sheet.noFiltersDescription':
|
|
87
88
|
'⟦Àðð à ƒíłţéř ţó ñàřřóŵ ýóúř řéšúłţš àñð ƒíñð ŵĥàţ ýóú ñééð ƒàšţéř.⟧',
|
|
88
89
|
'@astryx.powersearch.sheet.clearAll': '⟦Çłéàř àłł⟧',
|
|
@@ -92,6 +93,11 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
92
93
|
'@astryx.powersearch.sheet.clearAllConfirm': '⟦Çłéàř ƒíłţéřš⟧',
|
|
93
94
|
'@astryx.powersearch.sheet.clearAllCancel': '⟦Ķééþ ƒíłţéřš⟧',
|
|
94
95
|
'@astryx.powersearch.sheet.done': '⟦Ðóñé⟧',
|
|
96
|
+
'@astryx.powersearch.sheet.discardTitle': '⟦Ðíšçàřð çĥàñĝéš?⟧',
|
|
97
|
+
'@astryx.powersearch.sheet.discardDescription':
|
|
98
|
+
"⟦Ýóúř çĥàñĝéš ţó ţĥé ƒíłţéřš ĥàṽéñ'ţ ƀééñ àþþłíéð.⟧",
|
|
99
|
+
'@astryx.powersearch.sheet.keepEditing': '⟦Ķééþ éðíţíñĝ⟧',
|
|
100
|
+
'@astryx.powersearch.sheet.discardConfirm': '⟦Ðíšçàřð çĥàñĝéš⟧',
|
|
95
101
|
'@astryx.powersearch.sheet.search': '⟦Šéàřçĥ⟧',
|
|
96
102
|
'@astryx.powersearch.sheet.searchResults': '⟦Šéàřçĥ řéšúłţš⟧',
|
|
97
103
|
'@astryx.powersearch.sheet.searchFields': '⟦Šéàřçĥ ƒíłţéřš⟧',
|
|
@@ -118,10 +124,6 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
118
124
|
'⟦{count, number} {count, plural, one {month} other {months}} ƒřóɱ ñóŵ⟧',
|
|
119
125
|
'@astryx.powersearch.sheet.fieldOperator': '⟦{field} {operator}⟧',
|
|
120
126
|
'@astryx.powersearch.sheet.labelValue': '⟦{label} {value}⟧',
|
|
121
|
-
'@astryx.powersearch.sheet.filtersClearedWithCount':
|
|
122
|
-
'⟦Àłł ƒíłţéřš řéɱóṽéð. {resultCount}⟧',
|
|
123
|
-
'@astryx.powersearch.sheet.editableFiltersClearedWithCount':
|
|
124
|
-
'⟦Éðíţàƀłé ƒíłţéřš řéɱóṽéð. {resultCount}⟧',
|
|
125
127
|
'@astryx.alertDialog.cancel': '⟦Çàñçéł⟧',
|
|
126
128
|
'@astryx.appShell.mobileNavigation': '⟦Ṁóƀíłé ñàṽíĝàţíóñ⟧',
|
|
127
129
|
'@astryx.appShell.skipToContent': '⟦Šķíþ ţó çóñţéñţ⟧',
|