@remit/web-client 0.0.59 → 0.0.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/mail/organize/MobileOrganizeFlow.tsx +9 -2
- package/src/components/mail/organize/OrganizeDialog.tsx +10 -2
- package/src/components/mail/organize/OrganizePanel.render.test.ts +6 -0
- package/src/components/mail/organize/OrganizePanel.tsx +18 -6
- package/src/components/mail/organize/smart-organize.stories.tsx +22 -0
- package/src/hooks/useOrganizePreview.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remit/web-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.60",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Remit web client, published as composable primitives — the app shell, auth shells, and runtime config. A distributor imports what it composes and bundles it.",
|
|
6
6
|
"exports": {
|
|
@@ -56,8 +56,14 @@ export function MobileOrganizeFlow({
|
|
|
56
56
|
const anchorMessageId = selectedMessageIds[0];
|
|
57
57
|
const [seed, setSeed] = useState<OrganizeSeed | undefined>();
|
|
58
58
|
|
|
59
|
-
const {
|
|
60
|
-
|
|
59
|
+
const {
|
|
60
|
+
preview,
|
|
61
|
+
matchedCount,
|
|
62
|
+
semanticUnavailable,
|
|
63
|
+
isPending,
|
|
64
|
+
isError,
|
|
65
|
+
error,
|
|
66
|
+
} = useOrganizePreview(accountId);
|
|
61
67
|
|
|
62
68
|
useEffect(() => {
|
|
63
69
|
if (!anchorMessageId) return;
|
|
@@ -121,6 +127,7 @@ export function MobileOrganizeFlow({
|
|
|
121
127
|
initialScope={seed?.scope}
|
|
122
128
|
seedMailboxId={seed?.moveMailboxId}
|
|
123
129
|
fallback={stage.fallback}
|
|
130
|
+
semanticUnavailable={semanticUnavailable}
|
|
124
131
|
onClose={onClose}
|
|
125
132
|
/>
|
|
126
133
|
)}
|
|
@@ -26,8 +26,15 @@ export function OrganizeDialog({
|
|
|
26
26
|
onClose,
|
|
27
27
|
}: OrganizeDialogProps) {
|
|
28
28
|
const anchorMessageId = selectedMessageIds[0];
|
|
29
|
-
const {
|
|
30
|
-
|
|
29
|
+
const {
|
|
30
|
+
preview,
|
|
31
|
+
reset,
|
|
32
|
+
matchedCount,
|
|
33
|
+
semanticUnavailable,
|
|
34
|
+
isPending,
|
|
35
|
+
isError,
|
|
36
|
+
error,
|
|
37
|
+
} = useOrganizePreview(accountId);
|
|
31
38
|
|
|
32
39
|
useEffect(() => {
|
|
33
40
|
if (!open || !anchorMessageId) return;
|
|
@@ -75,6 +82,7 @@ export function OrganizeDialog({
|
|
|
75
82
|
selectedMessageIds={selectedMessageIds}
|
|
76
83
|
anchorMessageId={anchorMessageId}
|
|
77
84
|
matchedCount={matchedCount}
|
|
85
|
+
semanticUnavailable={semanticUnavailable}
|
|
78
86
|
onClose={handleClose}
|
|
79
87
|
/>
|
|
80
88
|
)}
|
|
@@ -62,6 +62,12 @@ describe("OrganizePanel", () => {
|
|
|
62
62
|
assert.match(html, /organizing just your 2 selected/);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
+
it("names the missing vector pipeline and organizes just the selection when the widen is unavailable (#226/#201)", () => {
|
|
66
|
+
const html = render({ matchedCount: 0, semanticUnavailable: true });
|
|
67
|
+
assert.match(html, /available on this server/);
|
|
68
|
+
assert.match(html, /organizing just your 2 selected/);
|
|
69
|
+
});
|
|
70
|
+
|
|
65
71
|
it("pre-selects the seeded scope (a 'Something else' shortcut seeds the sentence)", () => {
|
|
66
72
|
const html = render({ initialScope: "standing" });
|
|
67
73
|
// The standing scope's "Always keep" phrasing only renders when it is active.
|
|
@@ -42,6 +42,12 @@ interface OrganizePanelProps {
|
|
|
42
42
|
* `just-these`.
|
|
43
43
|
*/
|
|
44
44
|
fallback?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The server ran no semantic widen because this deployment ships no vector
|
|
47
|
+
* pipeline. Like {@link fallback} it organizes just the selection, but the
|
|
48
|
+
* heading names the real reason rather than "no similar found".
|
|
49
|
+
*/
|
|
50
|
+
semanticUnavailable?: boolean;
|
|
45
51
|
onClose: () => void;
|
|
46
52
|
}
|
|
47
53
|
|
|
@@ -77,10 +83,14 @@ export function OrganizePanel({
|
|
|
77
83
|
initialScope,
|
|
78
84
|
seedMailboxId,
|
|
79
85
|
fallback = false,
|
|
86
|
+
semanticUnavailable = false,
|
|
80
87
|
onClose,
|
|
81
88
|
}: OrganizePanelProps) {
|
|
89
|
+
// A missing widen and an empty widen both organize just the selection; only
|
|
90
|
+
// the heading distinguishes them.
|
|
91
|
+
const noWiden = fallback || semanticUnavailable;
|
|
82
92
|
const [scope, setScope] = useState<OrganizeScope>(
|
|
83
|
-
initialScope ?? (
|
|
93
|
+
initialScope ?? (noWiden ? "just-these" : "all-like-these"),
|
|
84
94
|
);
|
|
85
95
|
const [moveMailboxId, setMoveMailboxId] = useState<string>(
|
|
86
96
|
seedMailboxId ?? "",
|
|
@@ -178,11 +188,13 @@ export function OrganizePanel({
|
|
|
178
188
|
<div className="border-b border-line px-5 py-3">
|
|
179
189
|
<h2 className="text-sm font-semibold text-fg">Organize</h2>
|
|
180
190
|
<p className="mt-0.5 text-xs text-fg-muted">
|
|
181
|
-
{
|
|
182
|
-
? `
|
|
183
|
-
:
|
|
184
|
-
|
|
185
|
-
}
|
|
191
|
+
{semanticUnavailable
|
|
192
|
+
? `Finding similar mail isn't available on this server — organizing just your ${selectionCount} selected.`
|
|
193
|
+
: fallback
|
|
194
|
+
? `No similar messages found — organizing just your ${selectionCount} selected.`
|
|
195
|
+
: `${matchedCount} similar message${matchedCount === 1 ? "" : "s"} found${
|
|
196
|
+
selectionCount > 0 ? ` from ${selectionCount} selected` : ""
|
|
197
|
+
}.`}
|
|
186
198
|
</p>
|
|
187
199
|
</div>
|
|
188
200
|
|
|
@@ -183,6 +183,28 @@ export const NoSimilarFound: Story = {
|
|
|
183
183
|
),
|
|
184
184
|
};
|
|
185
185
|
|
|
186
|
+
/**
|
|
187
|
+
* The deployment ships no vector pipeline, so the server ran no semantic widen —
|
|
188
|
+
* the sentence organizes just the selection and the heading names the real
|
|
189
|
+
* reason (#226/#201).
|
|
190
|
+
*/
|
|
191
|
+
export const SemanticUnavailable: Story = {
|
|
192
|
+
name: "Semantic Unavailable",
|
|
193
|
+
render: () => (
|
|
194
|
+
<SheetStage>
|
|
195
|
+
<OrganizePanel
|
|
196
|
+
accountId={ACCOUNT_ID}
|
|
197
|
+
mailboxId="mbx-inbox"
|
|
198
|
+
selectedMessageIds={["msg-1", "msg-2"]}
|
|
199
|
+
anchorMessageId="msg-1"
|
|
200
|
+
matchedCount={0}
|
|
201
|
+
semanticUnavailable
|
|
202
|
+
onClose={() => undefined}
|
|
203
|
+
/>
|
|
204
|
+
</SheetStage>
|
|
205
|
+
),
|
|
206
|
+
};
|
|
207
|
+
|
|
186
208
|
/** The "Something else" fallback: shortcuts derived from folders + an input. */
|
|
187
209
|
export const SomethingElse: Story = {
|
|
188
210
|
render: () => (
|
|
@@ -33,6 +33,9 @@ export const useOrganizePreview = (accountId: string | undefined) => {
|
|
|
33
33
|
reset: mutation.reset,
|
|
34
34
|
matchedCount: mutation.data?.matchedCount,
|
|
35
35
|
messageIds: mutation.data?.messageIds,
|
|
36
|
+
// True when the server ran no semantic widen because this deployment
|
|
37
|
+
// ships no vector pipeline — the matched set is literal-only (or empty).
|
|
38
|
+
semanticUnavailable: mutation.data?.semanticUnavailable ?? false,
|
|
36
39
|
isPending: mutation.isPending,
|
|
37
40
|
isError: mutation.isError,
|
|
38
41
|
error: mutation.error,
|