@remit/web-client 0.0.321 → 0.0.323
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 +4 -4
- package/src/auth/SignInAgain.tsx +18 -0
- package/src/auth/amplify-config.test.ts +1 -107
- package/src/auth/auth-interceptor.test.ts +0 -6
- package/src/auth/cognito/cognito-token.test.ts +2 -4
- package/src/components/calendar/AgendaStrip.tsx +1 -1
- package/src/components/calendar/CalendarWorkspace.tsx +1 -1
- package/src/components/calendar/ChangeCalendarSuggestion.tsx +1 -1
- package/src/components/calendar/OpenCalendarEvent.tsx +1 -18
- package/src/components/compose/ComposeForm.tsx +11 -6
- package/src/components/compose/FullCompose.tsx +1 -1
- package/src/components/compose/MobileComposeSheet.tsx +1 -2
- package/src/components/compose/compose.stories.tsx +18 -0
- package/src/components/compose/draft-discard-failure.render.test.ts +138 -0
- package/src/components/config-import/config-import.fixtures.ts +8 -9
- package/src/components/config-import/config-import.stories.tsx +2 -2
- package/src/components/layout/MailTopBar.tsx +3 -0
- package/src/components/mail/BriefPane.tsx +0 -3
- package/src/components/mail/ConversationView.tsx +1 -3
- package/src/components/mail/DailyBrief.tsx +5 -28
- package/src/components/mail/FlaggedList.tsx +3 -4
- package/src/components/mail/FlaggedPane.tsx +0 -3
- package/src/components/mail/IntelligenceDrawer.tsx +0 -3
- package/src/components/mail/IntelligencePane.render.test.ts +0 -1
- package/src/components/mail/IntelligencePane.test.ts +1 -95
- package/src/components/mail/IntelligencePane.tsx +3 -93
- package/src/components/mail/MailListHeader.tsx +12 -43
- package/src/components/mail/MailNav.tsx +6 -2
- package/src/components/mail/MailViewChrome.tsx +1 -11
- package/src/components/mail/MailboxPane.tsx +4 -34
- package/src/components/mail/MessageActionMenu.tsx +6 -6
- package/src/components/mail/MessageAttachments.tsx +35 -0
- package/src/components/mail/MessageBody.tsx +1 -0
- package/src/components/mail/MessageBodyErrorBanner.test.ts +0 -30
- package/src/components/mail/MessageCard.tsx +16 -4
- package/src/components/mail/MessageList.run-reporting.test.ts +2 -46
- package/src/components/mail/MessageList.tsx +23 -11
- package/src/components/mail/MessageRow.render.test.ts +0 -7
- package/src/components/mail/MoveToTrigger.tsx +1 -1
- package/src/components/mail/RawMessageView.tsx +1 -1
- package/src/components/mail/SelectionWizardHost.search-entry.test.ts +0 -1
- package/src/components/mail/SelectionWizardHost.tsx +16 -102
- package/src/components/mail/authenticity-warning.stories.tsx +0 -21
- package/src/components/mail/daily-brief.stories.tsx +31 -17
- package/src/components/mail/enter-cursor-late-open.render.test.ts +197 -0
- package/src/components/mail/intelligence-drawer.stories.tsx +0 -2
- package/src/components/mail/message-gone.stories.tsx +44 -0
- package/src/components/mail/offer-times-reply.render.test.ts +25 -1
- package/src/components/mail/reclassify-remove-override.render.test.ts +2 -6
- package/src/components/overlay-escape.render.test.ts +7 -3
- package/src/components/settings/AccountFormPanel.render.test.ts +26 -3
- package/src/components/settings/AccountFormPanel.test.ts +1 -36
- package/src/components/settings/AccountFormPanel.tsx +5 -25
- package/src/components/settings/AccountServices.tsx +1 -1
- package/src/components/settings/AdvancedNavIcon.tsx +3 -3
- package/src/components/settings/CalendarFeedCard.tsx +2 -1
- package/src/components/settings/CalendarSubscribeCard.tsx +1 -1
- package/src/components/settings/CalendarSubscriptionStatus.tsx +1 -2
- package/src/components/settings/FilterActionError.tsx +1 -1
- package/src/components/settings/FilterEditor.render.test.ts +3 -27
- package/src/components/settings/FilterEditor.tsx +4 -24
- package/src/components/settings/FilterEditorSurface.tsx +0 -3
- package/src/components/settings/FiltersList.render.test.ts +5 -24
- package/src/components/settings/FiltersList.stories.tsx +0 -1
- package/src/components/settings/FiltersList.tsx +10 -35
- package/src/components/settings/WarningsNavIcon.tsx +12 -0
- package/src/components/settings/{QuarantinePanel.delimiter.test.ts → WarningsPanel.dom.test.ts} +64 -5
- package/src/components/settings/WarningsPanel.render.test.ts +56 -0
- package/src/components/settings/WarningsPanel.tsx +244 -0
- package/src/components/settings/accounts.stories.tsx +18 -0
- package/src/components/settings/advanced.stories.tsx +3 -125
- package/src/components/settings/settings-filter.stories.tsx +2 -42
- package/src/components/settings/warnings.stories.tsx +290 -0
- package/src/components/ui/ErrorBannerProvider.tsx +5 -3
- package/src/components/ui/error-banners.test.ts +1 -22
- package/src/components/ui/error-banners.ts +9 -20
- package/src/hooks/calendar/useCalendarCollectionWrites.ts +2 -1
- package/src/hooks/calendar/useCalendarSuggestions.ts +2 -1
- package/src/hooks/calendar/useCalendarWrites.ts +2 -1
- package/src/hooks/intelligence-calendar.render.test.ts +0 -1
- package/src/hooks/useDeleteMessages.test.ts +1 -42
- package/src/hooks/useFilters.test.ts +0 -8
- package/src/hooks/useFollowFocusOpen.render.test.ts +1 -11
- package/src/hooks/useIntelligenceData.test.ts +9 -47
- package/src/hooks/useIntelligenceData.ts +7 -100
- package/src/hooks/useLayoutTier.test.ts +0 -48
- package/src/hooks/useReportSpam.ts +1 -1
- package/src/hooks/useRescueCandidates.test.ts +0 -23
- package/src/hooks/useRulePreview.ts +8 -7
- package/src/hooks/useSearchTokenContext.ts +2 -3
- package/src/hooks/useStaleAccountSync.test.ts +0 -17
- package/src/hooks/useStarredThreads.test.ts +0 -10
- package/src/hooks/useTriggerSync.test.ts +0 -6
- package/src/hooks/useVisualViewport.render.test.ts +63 -0
- package/src/hooks/useWarningsAttention.ts +37 -0
- package/src/lib/account-order.test.ts +0 -10
- package/src/lib/adjacent-message.test.ts +0 -9
- package/src/lib/app-info.ts +0 -3
- package/src/lib/autodiscovery.test.ts +0 -47
- package/src/lib/bug-report.test.ts +38 -0
- package/src/lib/bug-report.ts +10 -7
- package/src/lib/bulk-action-copy.ts +1 -1
- package/src/lib/calendar-route.test.ts +0 -5
- package/src/lib/config-import.test.ts +3 -39
- package/src/lib/dedupe-thread-messages.test.ts +0 -4
- package/src/lib/desktop-breakpoint.test.ts +0 -8
- package/src/lib/drafts.test.ts +0 -23
- package/src/lib/fatal-error.test.ts +0 -19
- package/src/lib/folder-roles.test.ts +0 -4
- package/src/lib/hot-sync-window.test.ts +0 -5
- package/src/lib/list-header-chrome.ts +1 -1
- package/src/lib/mail-context.ts +1 -1
- package/src/lib/message-attachments.test.ts +77 -0
- package/src/lib/message-attachments.ts +31 -15
- package/src/lib/message-body-source.test.ts +21 -4
- package/src/lib/message-body-source.ts +5 -2
- package/src/lib/onboarding-completion.test.ts +0 -16
- package/src/lib/organize/filter-edit-model.test.ts +2 -32
- package/src/lib/organize/filter-edit-model.ts +6 -16
- package/src/lib/organize/organize-model.test.ts +7 -40
- package/src/lib/organize/organize-model.ts +16 -18
- package/src/lib/organize/rule-model.test.ts +24 -202
- package/src/lib/organize/rule-model.ts +19 -166
- package/src/lib/organize/search-to-rule.test.ts +2 -36
- package/src/lib/organize/search-to-rule.ts +1 -16
- package/src/lib/provider-presets.test.ts +1 -77
- package/src/lib/query-error-handler.test.ts +0 -61
- package/src/lib/query-escalation.integration.test.ts +4 -4
- package/src/lib/result-count.ts +1 -1
- package/src/lib/result-folder.ts +1 -1
- package/src/lib/rum-adapter.test.ts +0 -104
- package/src/lib/search-query.test.ts +0 -11
- package/src/lib/search-result.test.ts +2 -142
- package/src/lib/search-result.ts +3 -73
- package/src/lib/search-scope.test.ts +1 -92
- package/src/lib/search-scope.ts +0 -29
- package/src/lib/search-surface.ts +2 -2
- package/src/lib/search-token-index.test.ts +0 -8
- package/src/lib/search-tokens.ts +15 -16
- package/src/lib/starred-rows.test.ts +0 -4
- package/src/lib/sync-warning-entries.ts +33 -0
- package/src/lib/wizard-selection.ts +1 -1
- package/src/mocks/story-frame/mail-handlers.ts +12 -8
- package/src/mocks/story-frame/mail-world.ts +5 -0
- package/src/routeTree.gen.ts +21 -0
- package/src/routes/calendar/$view.$date/index.tsx +1 -1
- package/src/routes/calendar.tsx +2 -1
- package/src/routes/mail/brief.tsx +1 -1
- package/src/routes/mail/flagged.tsx +1 -1
- package/src/routes/mail.tsx +5 -3
- package/src/routes/settings/-accounts.test.ts +0 -5
- package/src/routes/settings/-filters.test.ts +0 -1
- package/src/routes/settings/-shared/help-copy.tsx +15 -0
- package/src/routes/settings/accounts.tsx +1 -1
- package/src/routes/settings/advanced.tsx +1 -4
- package/src/routes/settings/filters.tsx +1 -2
- package/src/routes/settings/folders.tsx +1 -1
- package/src/routes/settings/labels.tsx +1 -1
- package/src/routes/settings/senders.tsx +1 -1
- package/src/routes/settings/warnings.tsx +36 -0
- package/src/routes/settings.tsx +7 -0
- package/src/routing/wizard-history.test.ts +1 -45
- package/src/runtime-config.ts +5 -0
- package/src/test-support/fixtures.ts +1 -1
- package/src/components/compose/draft-discard-banner.test.ts +0 -76
- package/src/components/mail/ReadingPaneEmpty.render.test.ts +0 -42
- package/src/components/mail/SpamRescue.render.test.ts +0 -35
- package/src/components/mail/intelligence-semantic-off.render.test.ts +0 -111
- package/src/components/mail/selection-surface-rollcall.test.ts +0 -270
- package/src/components/settings/QuarantinePanel.render.test.ts +0 -71
- package/src/components/settings/QuarantinePanel.tsx +0 -178
- package/src/components/ui/DropdownMenu.tsx +0 -99
- package/src/components/ui/EmptyState.tsx +0 -11
- package/src/components/ui/ErrorBanner.render.test.ts +0 -104
- package/src/components/ui/ErrorBanner.stories.tsx +0 -132
- package/src/components/ui/ErrorBanner.tsx +0 -106
- package/src/components/ui/ErrorBannerStack.tsx +0 -35
- package/src/components/ui/ErrorState.render.test.ts +0 -82
- package/src/components/ui/ErrorState.tsx +0 -80
- package/src/components/ui/KeyboardShortcutsModal.tsx +0 -113
- package/src/hooks/useMoveMessages.test.ts +0 -63
- package/src/hooks/useOrganizeWiden.test.ts +0 -217
- package/src/hooks/useOrganizeWiden.ts +0 -112
- package/src/hooks/useSemanticSearch.ts +0 -132
- package/src/hooks/useSemanticSearchEnabled.ts +0 -23
- package/src/hooks/useVisualViewport.test.ts +0 -126
- package/src/lib/organize/sender-fallback.test.ts +0 -52
- package/src/lib/organize/sender-fallback.ts +0 -38
- package/src/lib/rescue-telemetry.test.ts +0 -75
- package/src/router.test.ts +0 -81
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
SEARCH_SCOPE_CHIP_ID,
|
|
14
14
|
scopeLabelForMailboxName,
|
|
15
15
|
searchScopeForRoute,
|
|
16
|
-
semanticMailboxScope,
|
|
17
16
|
} from "./search-scope";
|
|
18
17
|
|
|
19
18
|
const listFor: Record<string, BrowsedList["list"]> = {
|
|
@@ -117,97 +116,7 @@ describe("scopeLabelForMailboxName", () => {
|
|
|
117
116
|
});
|
|
118
117
|
|
|
119
118
|
// The invariant: no chip means global, a chip means every engine on that route
|
|
120
|
-
// respects it.
|
|
121
|
-
// an "Everywhere" heading, contradicting the `in:` chip the same bar showed.
|
|
122
|
-
describe("semanticMailboxScope — a chip binds every engine on the route", () => {
|
|
123
|
-
const mailbox = (mailboxId: string): BrowsedList => ({
|
|
124
|
-
list: "mailbox",
|
|
125
|
-
mailboxId,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it("pins a mailbox route to its own mailbox", () => {
|
|
129
|
-
assert.equal(
|
|
130
|
-
semanticMailboxScope({ browsed: mailbox("mbx-spam") }),
|
|
131
|
-
"mbx-spam",
|
|
132
|
-
);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it("a mailbox route ignores a caller asking for somewhere else", () => {
|
|
136
|
-
assert.equal(
|
|
137
|
-
semanticMailboxScope({
|
|
138
|
-
browsed: mailbox("mbx-spam"),
|
|
139
|
-
callerMailboxId: "mbx-archive",
|
|
140
|
-
}),
|
|
141
|
-
"mbx-spam",
|
|
142
|
-
);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("a mailbox route ignores a typed in: term", () => {
|
|
146
|
-
assert.equal(
|
|
147
|
-
semanticMailboxScope({
|
|
148
|
-
browsed: mailbox("mbx-spam"),
|
|
149
|
-
inTokenMailboxId: "mbx-archive",
|
|
150
|
-
}),
|
|
151
|
-
"mbx-spam",
|
|
152
|
-
);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("a mailbox route never widens to global", () => {
|
|
156
|
-
const scope = semanticMailboxScope({ browsed: mailbox("mbx-spam") });
|
|
157
|
-
assert.notEqual(scope, undefined, "a scoped route must carry a scope");
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// Flagged and outbox are scoped to a collection, which the mailbox-scoped
|
|
161
|
-
// semantic API cannot express — so neither runs a semantic section, and
|
|
162
|
-
// neither may fall back to a typed `in:` under its own chip.
|
|
163
|
-
for (const routeId of [MAIL_FLAGGED_ROUTE_ID, MAIL_OUTBOX_ROUTE_ID]) {
|
|
164
|
-
it(`${routeId} never honours a typed in: term`, () => {
|
|
165
|
-
assert.equal(
|
|
166
|
-
semanticMailboxScope({
|
|
167
|
-
browsed: browsing(routeId),
|
|
168
|
-
inTokenMailboxId: "mbx-archive",
|
|
169
|
-
}),
|
|
170
|
-
undefined,
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
it("the daily brief is global — no route scope, no chip", () => {
|
|
176
|
-
assert.equal(
|
|
177
|
-
semanticMailboxScope({ browsed: browsing(MAIL_BRIEF_ROUTE_ID) }),
|
|
178
|
-
undefined,
|
|
179
|
-
);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("the daily brief is the one route a typed in: narrows", () => {
|
|
183
|
-
assert.equal(
|
|
184
|
-
semanticMailboxScope({
|
|
185
|
-
browsed: browsing(MAIL_BRIEF_ROUTE_ID),
|
|
186
|
-
inTokenMailboxId: "mbx-archive",
|
|
187
|
-
}),
|
|
188
|
-
"mbx-archive",
|
|
189
|
-
);
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it("every scoped route resolves a scope or refuses to widen", () => {
|
|
193
|
-
// Pins the invariant across the route table rather than one case at a
|
|
194
|
-
// time: on a scoped route the resolved scope is either the route's own
|
|
195
|
-
// mailbox, or nothing that came from the typed query.
|
|
196
|
-
const scoped = [
|
|
197
|
-
{ browsed: mailbox("mbx-spam"), expected: "mbx-spam" },
|
|
198
|
-
{ browsed: browsing(MAIL_FLAGGED_ROUTE_ID), expected: undefined },
|
|
199
|
-
{ browsed: browsing(MAIL_OUTBOX_ROUTE_ID), expected: undefined },
|
|
200
|
-
];
|
|
201
|
-
for (const { browsed: m, expected } of scoped) {
|
|
202
|
-
assert.equal(isScopedRoute(m), true);
|
|
203
|
-
assert.equal(
|
|
204
|
-
semanticMailboxScope({ browsed: m, inTokenMailboxId: "mbx-elsewhere" }),
|
|
205
|
-
expected,
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
119
|
+
// respects it.
|
|
211
120
|
describe("resultsScopeForRoute", () => {
|
|
212
121
|
it("passes the global search through as global", () => {
|
|
213
122
|
assert.deepEqual(
|
package/src/lib/search-scope.ts
CHANGED
|
@@ -75,35 +75,6 @@ export function routeMailboxId(browsed: BrowsedList): string | undefined {
|
|
|
75
75
|
return browsed.list === "mailbox" ? browsed.mailboxId : undefined;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
/**
|
|
79
|
-
* The mailbox every engine on the active route must be pinned to.
|
|
80
|
-
*
|
|
81
|
-
* No chip means global; a chip means nothing on the route reaches past it. The
|
|
82
|
-
* semantic engine used to run unscoped inside a mailbox under an "Everywhere"
|
|
83
|
-
* heading, which contradicted the `in:` chip the same bar was showing, so the
|
|
84
|
-
* scope is now resolved from the route here rather than left to each caller:
|
|
85
|
-
*
|
|
86
|
-
* - A mailbox route pins to its own mailbox. It beats both the caller's
|
|
87
|
-
* argument and a typed `in:`, so no call site can widen or redirect it.
|
|
88
|
-
* - Any other scoped route (flagged, outbox) never falls back to a typed
|
|
89
|
-
* `in:`. Its scope is a collection rather than a folder, which the semantic
|
|
90
|
-
* API cannot express — which is why neither view runs a semantic section
|
|
91
|
-
* today. Honouring `in:` there would be a search reaching past a chip that
|
|
92
|
-
* promises otherwise.
|
|
93
|
-
* - An unscoped route (the daily brief) is global unless a typed `in:` narrows
|
|
94
|
-
* it, which is the one place `useSearchTokenContext` resolves that term.
|
|
95
|
-
*/
|
|
96
|
-
export function semanticMailboxScope(args: {
|
|
97
|
-
browsed: BrowsedList;
|
|
98
|
-
callerMailboxId?: string;
|
|
99
|
-
inTokenMailboxId?: string;
|
|
100
|
-
}): string | undefined {
|
|
101
|
-
const fromRoute = routeMailboxId(args.browsed);
|
|
102
|
-
if (fromRoute) return fromRoute;
|
|
103
|
-
if (isScopedRoute(args.browsed)) return args.callerMailboxId;
|
|
104
|
-
return args.callerMailboxId ?? args.inTokenMailboxId;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
78
|
/**
|
|
108
79
|
* The scope of the active route.
|
|
109
80
|
*
|
|
@@ -3,8 +3,8 @@ import type { LayoutTier } from "@/hooks/useLayoutTier";
|
|
|
3
3
|
/**
|
|
4
4
|
* Which surface a list view shows its search on. Two surfaces exist:
|
|
5
5
|
*
|
|
6
|
-
* - the read-only
|
|
7
|
-
*
|
|
6
|
+
* - the read-only `SearchResults` panel ("Top matches", cross-folder, spam
|
|
7
|
+
* offer), swapped into the list-pane
|
|
8
8
|
* body on tablet/desktop while searching; and
|
|
9
9
|
* - the view's own body — for the mailbox route a selectable `MessageList` whose
|
|
10
10
|
* threads filter to the committed search — which hosts multi-select and the
|
|
@@ -69,10 +69,6 @@ describe("buildAccountNameIndex", () => {
|
|
|
69
69
|
]);
|
|
70
70
|
assert.equal(index.get("work"), "acct-1");
|
|
71
71
|
});
|
|
72
|
-
|
|
73
|
-
it("empty accounts yields an empty index", () => {
|
|
74
|
-
assert.deepEqual(buildAccountNameIndex([]), new Map());
|
|
75
|
-
});
|
|
76
72
|
});
|
|
77
73
|
|
|
78
74
|
describe("buildMailboxNameIndex", () => {
|
|
@@ -107,10 +103,6 @@ describe("buildMailboxNameIndex", () => {
|
|
|
107
103
|
]);
|
|
108
104
|
assert.equal(index.size, 0);
|
|
109
105
|
});
|
|
110
|
-
|
|
111
|
-
it("empty input yields an empty index", () => {
|
|
112
|
-
assert.deepEqual(buildMailboxNameIndex([]), new Map());
|
|
113
|
-
});
|
|
114
106
|
});
|
|
115
107
|
|
|
116
108
|
describe("buildMailboxSuggestionValues", () => {
|
package/src/lib/search-tokens.ts
CHANGED
|
@@ -4,20 +4,20 @@
|
|
|
4
4
|
* into removable chips. Only tokens the search APIs can actually honor are
|
|
5
5
|
* recognized — everything else is left untouched as ordinary free-text words.
|
|
6
6
|
*
|
|
7
|
-
* The vocabulary is the search parameters `threadOperationsSearchThreads`
|
|
8
|
-
*
|
|
7
|
+
* The vocabulary is the search parameters `threadOperationsSearchThreads`
|
|
8
|
+
* takes, said in words:
|
|
9
9
|
*
|
|
10
|
-
* | token | thread search |
|
|
11
|
-
* | ---------------------- | ------------------ |
|
|
12
|
-
* | `from:` | `from` |
|
|
13
|
-
* | `subject:` | `subject` |
|
|
14
|
-
* | `category:` | `category[]` |
|
|
15
|
-
* | `is:unread` / `is:read`| `unread` |
|
|
16
|
-
* | `is:starred` | `starred` |
|
|
17
|
-
* | `has:attachment` | `attachments` |
|
|
18
|
-
* | `before:` / `after:` | — |
|
|
19
|
-
* | `in:` | route scope |
|
|
20
|
-
* | `account:` | — |
|
|
10
|
+
* | token | thread search |
|
|
11
|
+
* | ---------------------- | ------------------ |
|
|
12
|
+
* | `from:` | `from` |
|
|
13
|
+
* | `subject:` | `subject` |
|
|
14
|
+
* | `category:` | `category[]` |
|
|
15
|
+
* | `is:unread` / `is:read`| `unread` |
|
|
16
|
+
* | `is:starred` | `starred` |
|
|
17
|
+
* | `has:attachment` | `attachments` |
|
|
18
|
+
* | `before:` / `after:` | — |
|
|
19
|
+
* | `in:` | route scope |
|
|
20
|
+
* | `account:` | — |
|
|
21
21
|
*
|
|
22
22
|
* A token an engine has no parameter for is applied client-side over the rows
|
|
23
23
|
* that engine returned (`matchesSearchTokens` in `lib/brief.ts`), never dropped.
|
|
@@ -35,9 +35,8 @@
|
|
|
35
35
|
*
|
|
36
36
|
* Pure functions only: no React, no fetch — the name index is injected, not
|
|
37
37
|
* fetched here. `MailListHeader` renders the chips and the callers that issue
|
|
38
|
-
* search requests (`MailboxPane`, `DailyBrief`, `FlaggedList
|
|
39
|
-
*
|
|
40
|
-
* actually supports.
|
|
38
|
+
* search requests (`MailboxPane`, `DailyBrief`, `FlaggedList`) apply the
|
|
39
|
+
* parsed tokens to the params each engine's API actually supports.
|
|
41
40
|
*/
|
|
42
41
|
|
|
43
42
|
import type { RemitImapMessageCategory } from "@remit/api-http-client/types.gen.ts";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RemitImapSyncWarningResponse } from "@remit/api-http-client/types.gen.ts";
|
|
2
|
+
import { syncWarningState } from "@remit/data-ports/sync-warning-state";
|
|
3
|
+
import {
|
|
4
|
+
canonicalRoleLabel,
|
|
5
|
+
folderLeaf,
|
|
6
|
+
type ResultFolder,
|
|
7
|
+
type SyncWarningEntry,
|
|
8
|
+
} from "@remit/ui";
|
|
9
|
+
|
|
10
|
+
export const UNLISTED_FOLDER_LABEL = "A folder no longer listed";
|
|
11
|
+
|
|
12
|
+
function folderLabel(folder: ResultFolder | undefined): string {
|
|
13
|
+
if (folder?.role) return canonicalRoleLabel(folder.role);
|
|
14
|
+
if (folder?.providerPath) {
|
|
15
|
+
return folderLeaf(folder.providerPath, folder.hierarchyDelimiter);
|
|
16
|
+
}
|
|
17
|
+
return UNLISTED_FOLDER_LABEL;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function toSyncWarningEntry(
|
|
21
|
+
wire: RemitImapSyncWarningResponse,
|
|
22
|
+
folder: ResultFolder | undefined,
|
|
23
|
+
): SyncWarningEntry {
|
|
24
|
+
return {
|
|
25
|
+
syncWarningId: wire.syncWarningId,
|
|
26
|
+
uid: wire.uid,
|
|
27
|
+
stage: wire.stage,
|
|
28
|
+
state: syncWarningState(wire.stage, wire.attempts),
|
|
29
|
+
attempts: wire.attempts,
|
|
30
|
+
createdAt: wire.createdAt,
|
|
31
|
+
folderLabel: folderLabel(folder),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -2,7 +2,7 @@ import type { ThreadRowData, WizardMessage } from "@remit/ui";
|
|
|
2
2
|
|
|
3
3
|
/** A ticked row, as the wizard's samples and its clause prefill read it. */
|
|
4
4
|
export interface WizardSelectionMessage extends WizardMessage {
|
|
5
|
-
/** Sender address — the
|
|
5
|
+
/** Sender address — the properties prefill matches on it. */
|
|
6
6
|
email: string;
|
|
7
7
|
/**
|
|
8
8
|
* Owning account, which a bulk run splits its batches by (#872) — the bulk
|
|
@@ -27,7 +27,6 @@ import type {
|
|
|
27
27
|
RemitImapThreadMessageResponse,
|
|
28
28
|
RemitImapThreadSearchResponse,
|
|
29
29
|
RemitImapUpdateOutboxMessageInput,
|
|
30
|
-
SemanticSearchOperationsSemanticSearchResponse,
|
|
31
30
|
SyncOperationsGetSyncStatusResponse,
|
|
32
31
|
SyncOperationsTriggerSyncResponse,
|
|
33
32
|
SystemOperationsGetSystemUpdateResponse,
|
|
@@ -46,6 +45,7 @@ export interface MailHandlerOptions {
|
|
|
46
45
|
pageSize?: number;
|
|
47
46
|
holdLaterPages?: boolean;
|
|
48
47
|
draftSave?: "saves" | "refused";
|
|
48
|
+
draftDiscard?: "discards" | "refused";
|
|
49
49
|
send?: "sends" | "holds";
|
|
50
50
|
search?: "answers" | "holds";
|
|
51
51
|
config?: "answers" | "holds";
|
|
@@ -64,6 +64,7 @@ const bodyPartsOf = (
|
|
|
64
64
|
? [
|
|
65
65
|
{
|
|
66
66
|
bodyPartId: `part-${row.messageId}`,
|
|
67
|
+
partPath: "1",
|
|
67
68
|
mediaType: "APPLICATION",
|
|
68
69
|
mediaSubtype: "pdf",
|
|
69
70
|
sizeOctets: 48_000,
|
|
@@ -76,6 +77,7 @@ const bodyPartsOf = (
|
|
|
76
77
|
: [
|
|
77
78
|
{
|
|
78
79
|
bodyPartId: `part-${row.messageId}`,
|
|
80
|
+
partPath: "1",
|
|
79
81
|
mediaType: "TEXT",
|
|
80
82
|
mediaSubtype: "plain",
|
|
81
83
|
sizeOctets: (row.snippet ?? "").length,
|
|
@@ -215,6 +217,12 @@ export const mailHandlers = (
|
|
|
215
217
|
{ status: 409 },
|
|
216
218
|
);
|
|
217
219
|
|
|
220
|
+
const refuseDiscard = () =>
|
|
221
|
+
HttpResponse.json(
|
|
222
|
+
{ status: 409, message: "The draft is already gone." },
|
|
223
|
+
{ status: 409 },
|
|
224
|
+
);
|
|
225
|
+
|
|
218
226
|
return [
|
|
219
227
|
http.get(`${API}/config`, () =>
|
|
220
228
|
options.config === "holds"
|
|
@@ -485,6 +493,7 @@ export const mailHandlers = (
|
|
|
485
493
|
return HttpResponse.json<RemitImapOutboxMessageResponse>(queued);
|
|
486
494
|
}),
|
|
487
495
|
http.delete(`${API}/outbox/:outboxMessageId`, ({ params }) => {
|
|
496
|
+
if (options.draftDiscard === "refused") return refuseDiscard();
|
|
488
497
|
outbox.delete(String(params.outboxMessageId));
|
|
489
498
|
return new HttpResponse(null, { status: 204 });
|
|
490
499
|
}),
|
|
@@ -517,16 +526,11 @@ export const mailHandlers = (
|
|
|
517
526
|
{ items: [] },
|
|
518
527
|
),
|
|
519
528
|
),
|
|
520
|
-
http.get(`${API}/search/semantic`, () =>
|
|
521
|
-
options.search === "holds"
|
|
522
|
-
? pending()
|
|
523
|
-
: HttpResponse.json<SemanticSearchOperationsSemanticSearchResponse>({
|
|
524
|
-
items: [],
|
|
525
|
-
}),
|
|
526
|
-
),
|
|
527
529
|
http.get(`${API}/me/quarantine`, () =>
|
|
528
530
|
HttpResponse.json<MeOperationsListQuarantineResponse>({
|
|
529
531
|
entries: world.quarantine,
|
|
532
|
+
warnings: world.syncWarnings,
|
|
533
|
+
warningsTotal: world.syncWarningsTotal,
|
|
530
534
|
}),
|
|
531
535
|
),
|
|
532
536
|
http.get(`${API}/me/vip-suggestions`, () =>
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
RemitImapOutboxMessageResponse,
|
|
11
11
|
RemitImapOutboxMessageStatus,
|
|
12
12
|
RemitImapQuarantineResponse,
|
|
13
|
+
RemitImapSyncWarningResponse,
|
|
13
14
|
RemitImapSystemUpdateResponse,
|
|
14
15
|
RemitImapThreadMessageResponse,
|
|
15
16
|
RemitImapVipSuggestionEntry,
|
|
@@ -26,6 +27,8 @@ export interface MailWorld {
|
|
|
26
27
|
threads: RemitImapThreadMessageResponse[];
|
|
27
28
|
outbox: RemitImapOutboxMessageResponse[];
|
|
28
29
|
quarantine: RemitImapQuarantineResponse[];
|
|
30
|
+
syncWarnings: RemitImapSyncWarningResponse[];
|
|
31
|
+
syncWarningsTotal: number;
|
|
29
32
|
vipSuggestions: RemitImapVipSuggestionEntry[];
|
|
30
33
|
addresses: RemitImapAddressResponse[];
|
|
31
34
|
systemUpdate: RemitImapSystemUpdateResponse;
|
|
@@ -427,6 +430,8 @@ export const mailWorld = (overrides: Partial<MailWorld> = {}): MailWorld => ({
|
|
|
427
430
|
threads: [...inboxThreads, ...serverDrafts],
|
|
428
431
|
outbox: [...remitDrafts, ...outboxInEveryStatus],
|
|
429
432
|
quarantine: [],
|
|
433
|
+
syncWarnings: [],
|
|
434
|
+
syncWarningsTotal: 0,
|
|
430
435
|
vipSuggestions: [],
|
|
431
436
|
addresses: [],
|
|
432
437
|
systemUpdate: {
|
package/src/routeTree.gen.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { Route as SettingsFoldersRouteImport } from './routes/settings/folders'
|
|
|
31
31
|
import { Route as SettingsLabelsRouteImport } from './routes/settings/labels'
|
|
32
32
|
import { Route as SettingsSendersRouteImport } from './routes/settings/senders'
|
|
33
33
|
import { Route as SettingsSuggestedVipsRouteImport } from './routes/settings/suggested-vips'
|
|
34
|
+
import { Route as SettingsWarningsRouteImport } from './routes/settings/warnings'
|
|
34
35
|
import { Route as CalendarViewDateRouteImport } from './routes/calendar/$view.$date'
|
|
35
36
|
import { Route as MailMailboxIdIndexRouteImport } from './routes/mail/$mailboxId/index'
|
|
36
37
|
import { Route as MailMailboxIdThreadIdRouteImport } from './routes/mail/$mailboxId/$threadId'
|
|
@@ -170,6 +171,11 @@ const SettingsSuggestedVipsRoute = SettingsSuggestedVipsRouteImport.update({
|
|
|
170
171
|
path: '/suggested-vips',
|
|
171
172
|
getParentRoute: () => SettingsRoute,
|
|
172
173
|
} as any)
|
|
174
|
+
const SettingsWarningsRoute = SettingsWarningsRouteImport.update({
|
|
175
|
+
id: '/warnings',
|
|
176
|
+
path: '/warnings',
|
|
177
|
+
getParentRoute: () => SettingsRoute,
|
|
178
|
+
} as any)
|
|
173
179
|
const CalendarViewDateRoute = CalendarViewDateRouteImport.update({
|
|
174
180
|
id: '/$view/$date',
|
|
175
181
|
path: '/$view/$date',
|
|
@@ -354,6 +360,7 @@ export interface FileRoutesByFullPath {
|
|
|
354
360
|
'/settings/labels': typeof SettingsLabelsRoute
|
|
355
361
|
'/settings/senders': typeof SettingsSendersRoute
|
|
356
362
|
'/settings/suggested-vips': typeof SettingsSuggestedVipsRoute
|
|
363
|
+
'/settings/warnings': typeof SettingsWarningsRoute
|
|
357
364
|
'/calendar/': typeof CalendarIndexRoute
|
|
358
365
|
'/mail/': typeof MailIndexRoute
|
|
359
366
|
'/settings/': typeof SettingsIndexRoute
|
|
@@ -399,6 +406,7 @@ export interface FileRoutesByTo {
|
|
|
399
406
|
'/settings/labels': typeof SettingsLabelsRoute
|
|
400
407
|
'/settings/senders': typeof SettingsSendersRoute
|
|
401
408
|
'/settings/suggested-vips': typeof SettingsSuggestedVipsRoute
|
|
409
|
+
'/settings/warnings': typeof SettingsWarningsRoute
|
|
402
410
|
'/calendar': typeof CalendarIndexRoute
|
|
403
411
|
'/mail': typeof MailIndexRoute
|
|
404
412
|
'/settings': typeof SettingsIndexRoute
|
|
@@ -447,6 +455,7 @@ export interface FileRoutesById {
|
|
|
447
455
|
'/settings/labels': typeof SettingsLabelsRoute
|
|
448
456
|
'/settings/senders': typeof SettingsSendersRoute
|
|
449
457
|
'/settings/suggested-vips': typeof SettingsSuggestedVipsRoute
|
|
458
|
+
'/settings/warnings': typeof SettingsWarningsRoute
|
|
450
459
|
'/calendar/': typeof CalendarIndexRoute
|
|
451
460
|
'/mail/': typeof MailIndexRoute
|
|
452
461
|
'/settings/': typeof SettingsIndexRoute
|
|
@@ -501,6 +510,7 @@ export interface FileRouteTypes {
|
|
|
501
510
|
| '/settings/labels'
|
|
502
511
|
| '/settings/senders'
|
|
503
512
|
| '/settings/suggested-vips'
|
|
513
|
+
| '/settings/warnings'
|
|
504
514
|
| '/calendar/'
|
|
505
515
|
| '/mail/'
|
|
506
516
|
| '/settings/'
|
|
@@ -546,6 +556,7 @@ export interface FileRouteTypes {
|
|
|
546
556
|
| '/settings/labels'
|
|
547
557
|
| '/settings/senders'
|
|
548
558
|
| '/settings/suggested-vips'
|
|
559
|
+
| '/settings/warnings'
|
|
549
560
|
| '/calendar'
|
|
550
561
|
| '/mail'
|
|
551
562
|
| '/settings'
|
|
@@ -593,6 +604,7 @@ export interface FileRouteTypes {
|
|
|
593
604
|
| '/settings/labels'
|
|
594
605
|
| '/settings/senders'
|
|
595
606
|
| '/settings/suggested-vips'
|
|
607
|
+
| '/settings/warnings'
|
|
596
608
|
| '/calendar/'
|
|
597
609
|
| '/mail/'
|
|
598
610
|
| '/settings/'
|
|
@@ -791,6 +803,13 @@ declare module '@tanstack/react-router' {
|
|
|
791
803
|
preLoaderRoute: typeof SettingsSuggestedVipsRouteImport
|
|
792
804
|
parentRoute: typeof SettingsRoute
|
|
793
805
|
}
|
|
806
|
+
'/settings/warnings': {
|
|
807
|
+
id: '/settings/warnings'
|
|
808
|
+
path: '/warnings'
|
|
809
|
+
fullPath: '/settings/warnings'
|
|
810
|
+
preLoaderRoute: typeof SettingsWarningsRouteImport
|
|
811
|
+
parentRoute: typeof SettingsRoute
|
|
812
|
+
}
|
|
794
813
|
'/calendar/$view/$date': {
|
|
795
814
|
id: '/calendar/$view/$date'
|
|
796
815
|
path: '/$view/$date'
|
|
@@ -1225,6 +1244,7 @@ interface SettingsRouteChildren {
|
|
|
1225
1244
|
SettingsLabelsRoute: typeof SettingsLabelsRoute
|
|
1226
1245
|
SettingsSendersRoute: typeof SettingsSendersRoute
|
|
1227
1246
|
SettingsSuggestedVipsRoute: typeof SettingsSuggestedVipsRoute
|
|
1247
|
+
SettingsWarningsRoute: typeof SettingsWarningsRoute
|
|
1228
1248
|
SettingsIndexRoute: typeof SettingsIndexRoute
|
|
1229
1249
|
}
|
|
1230
1250
|
|
|
@@ -1238,6 +1258,7 @@ const SettingsRouteChildren: SettingsRouteChildren = {
|
|
|
1238
1258
|
SettingsLabelsRoute: SettingsLabelsRoute,
|
|
1239
1259
|
SettingsSendersRoute: SettingsSendersRoute,
|
|
1240
1260
|
SettingsSuggestedVipsRoute: SettingsSuggestedVipsRoute,
|
|
1261
|
+
SettingsWarningsRoute: SettingsWarningsRoute,
|
|
1241
1262
|
SettingsIndexRoute: SettingsIndexRoute,
|
|
1242
1263
|
}
|
|
1243
1264
|
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* as segments beside it.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { EmptyState } from "@remit/ui";
|
|
8
9
|
import { createFileRoute } from "@tanstack/react-router";
|
|
9
10
|
import { CalendarDays } from "lucide-react";
|
|
10
|
-
import { EmptyState } from "@/components/ui/EmptyState";
|
|
11
11
|
|
|
12
12
|
function CalendarReadingPane() {
|
|
13
13
|
return (
|
package/src/routes/calendar.tsx
CHANGED
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
* through and takes it back to their mail — nothing calendar-specific joins the
|
|
11
11
|
* union, because none of the calendar's own chrome is a panel.
|
|
12
12
|
*/
|
|
13
|
+
|
|
13
14
|
import { configOperationsGetConfigOptions } from "@remit/api-http-client/@tanstack/react-query.gen.ts";
|
|
15
|
+
import { ErrorState } from "@remit/ui";
|
|
14
16
|
import { useQuery } from "@tanstack/react-query";
|
|
15
17
|
import { createFileRoute, Outlet, useNavigate } from "@tanstack/react-router";
|
|
16
18
|
import { useCallback, useEffect } from "react";
|
|
17
19
|
import { CalendarShellProvider } from "@/components/calendar/CalendarShell";
|
|
18
20
|
import { MailNav } from "@/components/mail/MailNav";
|
|
19
|
-
import { ErrorState } from "@/components/ui/ErrorState";
|
|
20
21
|
import { isSinglePaneTier, useLayoutTier } from "@/hooks/useLayoutTier";
|
|
21
22
|
import { panelsWithOverlay, useOpenPanels, useSetOpenPanels } from "@/routing";
|
|
22
23
|
import "@/lib/client";
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* message inside it are the segments below, which is why nothing here reads a
|
|
8
8
|
* selection out of the query.
|
|
9
9
|
*/
|
|
10
|
+
import { ErrorState } from "@remit/ui";
|
|
10
11
|
import {
|
|
11
12
|
createFileRoute,
|
|
12
13
|
type ErrorComponentProps,
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
} from "@tanstack/react-router";
|
|
15
16
|
import { MailShell } from "@/components/layout/MailShell";
|
|
16
17
|
import { BriefPane } from "@/components/mail/BriefPane";
|
|
17
|
-
import { ErrorState } from "@/components/ui/ErrorState";
|
|
18
18
|
import { briefSearchSchema } from "@/lib/mail-search";
|
|
19
19
|
import { useOpenThreadPath, useSearchMirror } from "@/routing";
|
|
20
20
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* route matched below this one, and the open thread and the message inside it
|
|
7
7
|
* are the segments there rather than a selection read out of the query.
|
|
8
8
|
*/
|
|
9
|
+
import { ErrorState } from "@remit/ui";
|
|
9
10
|
import {
|
|
10
11
|
createFileRoute,
|
|
11
12
|
type ErrorComponentProps,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
} from "@tanstack/react-router";
|
|
14
15
|
import { MailShell } from "@/components/layout/MailShell";
|
|
15
16
|
import { FlaggedPane } from "@/components/mail/FlaggedPane";
|
|
16
|
-
import { ErrorState } from "@/components/ui/ErrorState";
|
|
17
17
|
import { flaggedSearchSchema } from "@/lib/mail-search";
|
|
18
18
|
import { useOpenThreadPath, useSearchMirror } from "@/routing";
|
|
19
19
|
|
package/src/routes/mail.tsx
CHANGED
|
@@ -2,7 +2,11 @@ import {
|
|
|
2
2
|
configOperationsGetConfigOptions,
|
|
3
3
|
unifiedThreadOperationsListAllThreadsOptions,
|
|
4
4
|
} from "@remit/api-http-client/@tanstack/react-query.gen.ts";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ErrorState,
|
|
7
|
+
KeyboardShortcutsModal,
|
|
8
|
+
useTriageKeyboard,
|
|
9
|
+
} from "@remit/ui";
|
|
6
10
|
import { useQuery } from "@tanstack/react-query";
|
|
7
11
|
import {
|
|
8
12
|
createFileRoute,
|
|
@@ -16,8 +20,6 @@ import { ComposeFab } from "@/components/layout/ComposeFab";
|
|
|
16
20
|
import { MailShellProvider } from "@/components/layout/MailShell";
|
|
17
21
|
import { MailTopBar } from "@/components/layout/MailTopBar";
|
|
18
22
|
import { MailNav } from "@/components/mail/MailNav";
|
|
19
|
-
import { ErrorState } from "@/components/ui/ErrorState";
|
|
20
|
-
import { KeyboardShortcutsModal } from "@/components/ui/KeyboardShortcutsModal";
|
|
21
23
|
import { useKeyboardNavigation } from "@/hooks/useKeyboardNavigation";
|
|
22
24
|
import { isSinglePaneTier, useLayoutTier } from "@/hooks/useLayoutTier";
|
|
23
25
|
import { useMailboxNameIndex } from "@/hooks/useMailboxNameIndex";
|
|
@@ -80,11 +80,6 @@ describe("mapOauthError", () => {
|
|
|
80
80
|
`Expected code in message, got: ${result}`,
|
|
81
81
|
);
|
|
82
82
|
});
|
|
83
|
-
|
|
84
|
-
test("empty string returns generic fallback", () => {
|
|
85
|
-
const result = mapOauthError("");
|
|
86
|
-
assert.ok(typeof result === "string" && result.length > 0);
|
|
87
|
-
});
|
|
88
83
|
});
|
|
89
84
|
|
|
90
85
|
/**
|
|
@@ -66,11 +66,26 @@ export const advancedHelp = (
|
|
|
66
66
|
<strong className="text-fg">Notification rules</strong> and data export
|
|
67
67
|
are coming in a future release.
|
|
68
68
|
</p>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
export const warningsHelp = (
|
|
73
|
+
<div className="space-y-3">
|
|
74
|
+
<p>
|
|
75
|
+
A message that fails to sync three times shows here. A{" "}
|
|
76
|
+
<strong className="text-fg">retrying</strong> one is tried again every
|
|
77
|
+
sync; a body that <strong className="text-fg">gave up</strong> is not.
|
|
78
|
+
Either leaves the list once it syncs.
|
|
79
|
+
</p>
|
|
69
80
|
<p>
|
|
70
81
|
A message Remit cannot read is{" "}
|
|
71
82
|
<strong className="text-fg">set aside</strong> rather than skipped, and
|
|
72
83
|
the folder keeps syncing. Setting one aside is a defect in Remit, so every
|
|
73
84
|
entry can be reported with the diagnostics already attached.
|
|
74
85
|
</p>
|
|
86
|
+
<p>
|
|
87
|
+
A report carries no folder name, subject, address, message content or
|
|
88
|
+
error text.
|
|
89
|
+
</p>
|
|
75
90
|
</div>
|
|
76
91
|
);
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Banner,
|
|
13
13
|
Button,
|
|
14
14
|
Dialog,
|
|
15
|
+
ErrorState,
|
|
15
16
|
type RowAction,
|
|
16
17
|
RowActions,
|
|
17
18
|
SettingsShell,
|
|
@@ -28,7 +29,6 @@ import {
|
|
|
28
29
|
import { AccountFormPanel } from "@/components/settings/AccountFormPanel";
|
|
29
30
|
import { AccountServices } from "@/components/settings/AccountServices";
|
|
30
31
|
import { DangerZone } from "@/components/settings/DangerZone";
|
|
31
|
-
import { ErrorState } from "@/components/ui/ErrorState";
|
|
32
32
|
import {
|
|
33
33
|
REDIRECT_STALL_MESSAGE,
|
|
34
34
|
useRedirectEnded,
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Advanced settings. Updates live here — and only here — with a full pane in
|
|
3
|
-
* Settings › Advanced
|
|
4
|
-
* rules and export are future scope.
|
|
3
|
+
* Settings › Advanced. Notification rules and export are future scope.
|
|
5
4
|
*/
|
|
6
5
|
import { SettingsShell } from "@remit/ui";
|
|
7
6
|
import { createFileRoute, useNavigate } from "@tanstack/react-router";
|
|
8
7
|
import { useState } from "react";
|
|
9
8
|
import { ConfigTransferPanel } from "@/components/settings/ConfigTransferPanel";
|
|
10
|
-
import { QuarantinePanel } from "@/components/settings/QuarantinePanel";
|
|
11
9
|
import { SelfUpdatePanel } from "@/components/settings/SelfUpdatePanel";
|
|
12
10
|
import { TlsRootCaDownload } from "@/components/settings/TlsRootCaDownload";
|
|
13
11
|
import { AppVersion } from "@/components/ui/AppVersion";
|
|
@@ -40,7 +38,6 @@ function AdvancedSettings() {
|
|
|
40
38
|
onBackToMail={() => void navigate({ to: "/mail" })}
|
|
41
39
|
>
|
|
42
40
|
<SelfUpdatePanel />
|
|
43
|
-
<QuarantinePanel />
|
|
44
41
|
<div className="mt-6 border-t border-line pt-4">
|
|
45
42
|
<ConfigTransferPanel />
|
|
46
43
|
</div>
|
|
@@ -3,14 +3,13 @@ import {
|
|
|
3
3
|
mailboxOperationsListMailboxesOptions,
|
|
4
4
|
} from "@remit/api-http-client/@tanstack/react-query.gen.ts";
|
|
5
5
|
import type { RemitImapAccountResponse } from "@remit/api-http-client/types.gen.ts";
|
|
6
|
-
import { type LabelOption, SettingsShell } from "@remit/ui";
|
|
6
|
+
import { ErrorState, type LabelOption, SettingsShell } from "@remit/ui";
|
|
7
7
|
import { useQuery } from "@tanstack/react-query";
|
|
8
8
|
import { createFileRoute, useNavigate } from "@tanstack/react-router";
|
|
9
9
|
import { useCallback, useMemo, useState } from "react";
|
|
10
10
|
import { FilterActionError } from "@/components/settings/FilterActionError";
|
|
11
11
|
import { FilterEditorSurface } from "@/components/settings/FilterEditorSurface";
|
|
12
12
|
import { FiltersList } from "@/components/settings/FiltersList";
|
|
13
|
-
import { ErrorState } from "@/components/ui/ErrorState";
|
|
14
13
|
import {
|
|
15
14
|
useDeleteFilter,
|
|
16
15
|
useFilterList,
|