@rapidmx/web-client 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +381 -381
- package/apps/admin/branding/index.tsx +39 -39
- package/apps/admin/data-requests/index.tsx +482 -482
- package/apps/admin/domains/[uid].tsx +166 -166
- package/apps/admin/escrow-scopes/[uid].tsx +350 -350
- package/apps/admin/index.tsx +129 -129
- package/apps/admin/mailboxes/[uid].tsx +271 -271
- package/apps/admin/mailboxes/new/index.tsx +30 -30
- package/apps/admin/plugins/index.tsx +15 -15
- package/apps/admin/retention-policy/index.tsx +39 -39
- package/apps/admin/signing-certificates/index.tsx +343 -343
- package/apps/escrow/audit-log/index.tsx +196 -196
- package/apps/escrow/matters/[uid].tsx +621 -621
- package/apps/shared/auth/adminAccess.ts +99 -99
- package/apps/shared/components/admin/layout/AdminShell.tsx +384 -384
- package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +238 -238
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -152
- package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +194 -194
- package/apps/shared/components/admin/settings/BrandingForm.tsx +423 -423
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +119 -119
- package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +198 -198
- package/apps/shared/components/admin/settings/PluginsManager.tsx +2093 -2093
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +182 -182
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +288 -288
- package/apps/shared/components/admin/setup/SetupWizard.tsx +446 -446
- package/apps/shared/components/admin/usePagedList.tsx +129 -129
- package/apps/shared/components/calendar/EventModal.tsx +206 -206
- package/apps/shared/components/calendar/MonthView.tsx +185 -185
- package/apps/shared/components/calendar/RecurrenceEditor.tsx +227 -227
- package/apps/shared/components/calendar/SplitDayView.tsx +144 -144
- package/apps/shared/components/calendar/TimeGridView.tsx +246 -246
- package/apps/shared/components/calendar/allDay.ts +124 -124
- package/apps/shared/components/contacts/ContactForm.tsx +383 -383
- package/apps/shared/components/contacts/ContactsToolbar.tsx +103 -103
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +155 -155
- package/apps/shared/components/layout/AppShell.tsx +463 -461
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -398
- package/apps/shared/components/layout/MailboxProvisioning.tsx +168 -168
- package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -315
- package/apps/shared/components/layout/ThemeSwitch.tsx +84 -84
- package/apps/shared/components/layout/UserMenu.tsx +439 -439
- package/apps/shared/components/mail/ConversationList.tsx +332 -332
- package/apps/shared/components/mail/ConversationThreadPane.tsx +613 -613
- package/apps/shared/components/mail/MailSelectionBar.tsx +240 -240
- package/apps/shared/components/mail/MenuButton.tsx +404 -404
- package/apps/shared/components/mail/MessageDetailPane.tsx +1757 -1757
- package/apps/shared/components/mail/compose/ComposeContext.tsx +312 -312
- package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -422
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +1705 -1681
- package/apps/shared/components/mail/compose/RichTextEditor.tsx +147 -147
- package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -60
- package/apps/shared/components/mail/compose/quotedBody.ts +161 -161
- package/apps/shared/components/mail/reading/MessageMoreMenu.tsx +258 -258
- package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +79 -79
- package/apps/shared/components/mail/reading/messageExport.ts +59 -59
- package/apps/shared/components/mail/reading/printMessage.ts +99 -99
- package/apps/shared/components/mail/reading/useMessageActions.ts +443 -443
- package/apps/shared/components/mail/verificationSeals.ts +125 -125
- package/apps/shared/components/rules/RuleBuilder.tsx +311 -311
- package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -344
- package/apps/shared/keyboard/GlobalShortcuts.tsx +51 -51
- package/apps/shared/keyboard/ShortcutProvider.tsx +62 -62
- package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -84
- package/apps/shared/keyboard/dispatch.ts +124 -124
- package/apps/shared/keyboard/format.ts +89 -89
- package/apps/shared/keyboard/keymap.ts +114 -114
- package/apps/shared/keyboard/registry.ts +65 -65
- package/apps/shared/keyboard/targets.ts +79 -79
- package/apps/shared/mail/folderOfType.ts +49 -49
- package/apps/shared/mail/folderTree.ts +143 -143
- package/apps/shared/mail/listAllPages.ts +39 -39
- package/apps/shared/mail/newMailNotifications.ts +171 -171
- package/apps/shared/mail/outbox/sendJob.ts +445 -445
- package/apps/shared/mail/outbox/sendOutcomes.ts +155 -155
- package/apps/shared/mail/reportNotices.ts +66 -66
- package/apps/shared/mail/senderBlocking.ts +141 -141
- package/apps/shared/mail/useMailConnection.ts +205 -205
- package/apps/shared/mail/useMailLiveUpdates.ts +277 -277
- package/apps/shared/mail/useMailboxUpdateAccess.ts +60 -60
- package/apps/shared/mail/useMarkMessageRead.ts +47 -47
- package/apps/shared/mail/useNewMailNotifications.ts +178 -178
- package/apps/shared/notifications/store.ts +560 -560
- package/apps/shared/search/LocalIndexLifecycle.tsx +114 -114
- package/apps/shared/search/localIndexBuilder.ts +481 -481
- package/apps/shared/signing/enrollmentStorage.ts +33 -33
- package/apps/shared/signing/enrollmentTracker.ts +385 -385
- package/apps/shared/signing/enrollmentView.ts +251 -251
- package/apps/shared/signing/useNow.ts +19 -19
- package/apps/shared/signing/useSigningEnrollmentWatcher.ts +90 -90
- package/apps/shared/styles/app.css +396 -396
- package/apps/www/calendar/index.tsx +581 -581
- package/apps/www/contacts/[uid].tsx +112 -112
- package/apps/www/index.tsx +3012 -3012
- package/apps/www/messages/[uid].tsx +139 -139
- package/apps/www/settings/auto-reply/index.tsx +136 -136
- package/apps/www/settings/blocked-senders/index.tsx +303 -303
- package/apps/www/settings/encryption/index.tsx +1290 -1290
- package/apps/www/settings/filters/[uid].tsx +179 -179
- package/apps/www/settings/filters/index.tsx +105 -105
- package/apps/www/settings/filters/new/index.tsx +165 -165
- package/apps/www/settings/labels/index.tsx +207 -207
- package/apps/www/settings/privacy/index.tsx +495 -495
- package/apps/www/settings/profile/index.tsx +251 -251
- package/apps/www/settings/read-receipts/index.tsx +150 -150
- package/apps/www/settings/sharing/index.tsx +259 -259
- package/apps/www/settings/signatures/[uid].tsx +175 -175
- package/apps/www/settings/signatures/index.tsx +91 -91
- package/apps/www/settings/signatures/new/index.tsx +138 -138
- package/apps/www/tasks/index.tsx +654 -654
- package/dist/apps/shared/components/admin/layout/AdminShell.js +2 -2
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +3 -3
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +2 -2
- package/dist/apps/shared/components/layout/AppShell.js +4 -2
- package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +7 -1
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +20 -1
- package/dist/apps/shared/components/mail/reading/printMessage.js +11 -11
- package/dist/apps/shared/styles/app.css +396 -396
- package/package.json +2 -2
package/apps/admin/index.tsx
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
-
import React, { useEffect, useState } from "react";
|
|
6
|
-
import { useRouter } from "@rapidrest/react/client";
|
|
7
|
-
import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
|
|
8
|
-
import { listMailboxes, Mailbox } from "@rapidmx/react-shared/mail/mailApi.js";
|
|
9
|
-
import { reopenSetup } from "@rapidmx/react-shared/admin/setupApi.js";
|
|
10
|
-
import AdminShell, { AdminShellProps } from "../shared/components/admin/layout/AdminShell.js";
|
|
11
|
-
import LeftoverMailboxesSection from "../shared/components/admin/mailboxes/LeftoverMailboxesSection.js";
|
|
12
|
-
import MailboxTable from "../shared/components/admin/mailboxes/MailboxTable.js";
|
|
13
|
-
import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
|
|
14
|
-
import Button from "@rapidmx/react-shared/components/buttons/Button.js";
|
|
15
|
-
import Modal from "@rapidmx/react-shared/components/overlays/Modal.js";
|
|
16
|
-
|
|
17
|
-
const PAGE_SIZE = 25;
|
|
18
|
-
|
|
19
|
-
export default function MailboxesListPage(props: Omit<AdminShellProps, "active">) {
|
|
20
|
-
return (
|
|
21
|
-
<AdminShell {...props} active="mailboxes">
|
|
22
|
-
<MailboxesListContent />
|
|
23
|
-
</AdminShell>
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function MailboxesListContent() {
|
|
28
|
-
const { navigate } = useRouter();
|
|
29
|
-
const [page, setPage] = useState(0);
|
|
30
|
-
const [mailboxes, setMailboxes] = useState<Mailbox[]>([]);
|
|
31
|
-
const [loading, setLoading] = useState(true);
|
|
32
|
-
const [error, setError] = useState<string | null>(null);
|
|
33
|
-
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
setLoading(true);
|
|
36
|
-
setError(null);
|
|
37
|
-
// The administration scope: every mailbox as administrative metadata - the console never shows anybody's mail.
|
|
38
|
-
listMailboxes({ page, limit: PAGE_SIZE, scope: "admin" })
|
|
39
|
-
.then(setMailboxes)
|
|
40
|
-
.catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load mailboxes."))
|
|
41
|
-
.finally(() => setLoading(false));
|
|
42
|
-
}, [page]);
|
|
43
|
-
|
|
44
|
-
const hasNextPage = mailboxes.length === PAGE_SIZE;
|
|
45
|
-
const [reopening, setReopening] = useState(false);
|
|
46
|
-
const [confirmingSetup, setConfirmingSetup] = useState(false);
|
|
47
|
-
|
|
48
|
-
async function handleRunSetup() {
|
|
49
|
-
setReopening(true);
|
|
50
|
-
try {
|
|
51
|
-
await reopenSetup();
|
|
52
|
-
void navigate("/admin/setup");
|
|
53
|
-
} catch (err) {
|
|
54
|
-
setError(err instanceof ApiRequestError ? err.message : "Could not reopen setup.");
|
|
55
|
-
setReopening(false);
|
|
56
|
-
setConfirmingSetup(false);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<>
|
|
62
|
-
<div className="flex items-center justify-between mb-5">
|
|
63
|
-
<h1 className="text-xl font-bold uppercase tracking-wide">Mailboxes</h1>
|
|
64
|
-
<div className="flex gap-2">
|
|
65
|
-
<Button type="button" variant="secondary" className="!w-auto" disabled={reopening} onClick={() => setConfirmingSetup(true)}>
|
|
66
|
-
Run setup again
|
|
67
|
-
</Button>
|
|
68
|
-
<a href="/admin/mailboxes/new">
|
|
69
|
-
<Button type="button" className="!w-auto">
|
|
70
|
-
+ New mailbox
|
|
71
|
-
</Button>
|
|
72
|
-
</a>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
<p className="text-sm text-text-muted mb-4">
|
|
77
|
-
Administrative details only (addresses, owners, quota). The console never shows a mailbox’s mail:
|
|
78
|
-
to see someone’s account, impersonate them from their mailbox page.
|
|
79
|
-
</p>
|
|
80
|
-
|
|
81
|
-
{error && <Alert>{error}</Alert>}
|
|
82
|
-
|
|
83
|
-
<Modal open={confirmingSetup} onClose={() => setConfirmingSetup(false)} title="Run setup again?">
|
|
84
|
-
<p className="text-sm mb-4">
|
|
85
|
-
Setup starts again from its first step, and the admin console sends administrators to it until
|
|
86
|
-
it's finished. Your existing settings, domains and mailboxes are kept.
|
|
87
|
-
</p>
|
|
88
|
-
<div className="flex gap-2 justify-end">
|
|
89
|
-
<Button type="button" variant="secondary" className="!w-auto" onClick={() => setConfirmingSetup(false)}>
|
|
90
|
-
Cancel
|
|
91
|
-
</Button>
|
|
92
|
-
<Button type="button" className="!w-auto" loading={reopening} disabled={reopening} onClick={() => void handleRunSetup()}>
|
|
93
|
-
Run setup
|
|
94
|
-
</Button>
|
|
95
|
-
</div>
|
|
96
|
-
</Modal>
|
|
97
|
-
|
|
98
|
-
{loading ? (
|
|
99
|
-
<p className="text-sm text-text-muted">Loading…</p>
|
|
100
|
-
) : (
|
|
101
|
-
<MailboxTable mailboxes={mailboxes} />
|
|
102
|
-
)}
|
|
103
|
-
|
|
104
|
-
<div className="flex gap-3 items-center mt-4">
|
|
105
|
-
<Button
|
|
106
|
-
variant="secondary"
|
|
107
|
-
type="button"
|
|
108
|
-
className="!w-auto"
|
|
109
|
-
disabled={page === 0 || loading}
|
|
110
|
-
onClick={() => setPage((p) => Math.max(0, p - 1))}
|
|
111
|
-
>
|
|
112
|
-
Previous
|
|
113
|
-
</Button>
|
|
114
|
-
<span className="text-sm text-text-muted">Page {page + 1}</span>
|
|
115
|
-
<Button
|
|
116
|
-
variant="secondary"
|
|
117
|
-
type="button"
|
|
118
|
-
className="!w-auto"
|
|
119
|
-
disabled={!hasNextPage || loading}
|
|
120
|
-
onClick={() => setPage((p) => p + 1)}
|
|
121
|
-
>
|
|
122
|
-
Next
|
|
123
|
-
</Button>
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
<LeftoverMailboxesSection />
|
|
127
|
-
</>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
import React, { useEffect, useState } from "react";
|
|
6
|
+
import { useRouter } from "@rapidrest/react/client";
|
|
7
|
+
import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
|
|
8
|
+
import { listMailboxes, Mailbox } from "@rapidmx/react-shared/mail/mailApi.js";
|
|
9
|
+
import { reopenSetup } from "@rapidmx/react-shared/admin/setupApi.js";
|
|
10
|
+
import AdminShell, { AdminShellProps } from "../shared/components/admin/layout/AdminShell.js";
|
|
11
|
+
import LeftoverMailboxesSection from "../shared/components/admin/mailboxes/LeftoverMailboxesSection.js";
|
|
12
|
+
import MailboxTable from "../shared/components/admin/mailboxes/MailboxTable.js";
|
|
13
|
+
import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
|
|
14
|
+
import Button from "@rapidmx/react-shared/components/buttons/Button.js";
|
|
15
|
+
import Modal from "@rapidmx/react-shared/components/overlays/Modal.js";
|
|
16
|
+
|
|
17
|
+
const PAGE_SIZE = 25;
|
|
18
|
+
|
|
19
|
+
export default function MailboxesListPage(props: Omit<AdminShellProps, "active">) {
|
|
20
|
+
return (
|
|
21
|
+
<AdminShell {...props} active="mailboxes">
|
|
22
|
+
<MailboxesListContent />
|
|
23
|
+
</AdminShell>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function MailboxesListContent() {
|
|
28
|
+
const { navigate } = useRouter();
|
|
29
|
+
const [page, setPage] = useState(0);
|
|
30
|
+
const [mailboxes, setMailboxes] = useState<Mailbox[]>([]);
|
|
31
|
+
const [loading, setLoading] = useState(true);
|
|
32
|
+
const [error, setError] = useState<string | null>(null);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
setLoading(true);
|
|
36
|
+
setError(null);
|
|
37
|
+
// The administration scope: every mailbox as administrative metadata - the console never shows anybody's mail.
|
|
38
|
+
listMailboxes({ page, limit: PAGE_SIZE, scope: "admin" })
|
|
39
|
+
.then(setMailboxes)
|
|
40
|
+
.catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load mailboxes."))
|
|
41
|
+
.finally(() => setLoading(false));
|
|
42
|
+
}, [page]);
|
|
43
|
+
|
|
44
|
+
const hasNextPage = mailboxes.length === PAGE_SIZE;
|
|
45
|
+
const [reopening, setReopening] = useState(false);
|
|
46
|
+
const [confirmingSetup, setConfirmingSetup] = useState(false);
|
|
47
|
+
|
|
48
|
+
async function handleRunSetup() {
|
|
49
|
+
setReopening(true);
|
|
50
|
+
try {
|
|
51
|
+
await reopenSetup();
|
|
52
|
+
void navigate("/admin/setup");
|
|
53
|
+
} catch (err) {
|
|
54
|
+
setError(err instanceof ApiRequestError ? err.message : "Could not reopen setup.");
|
|
55
|
+
setReopening(false);
|
|
56
|
+
setConfirmingSetup(false);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
<div className="flex items-center justify-between mb-5">
|
|
63
|
+
<h1 className="text-xl font-bold uppercase tracking-wide">Mailboxes</h1>
|
|
64
|
+
<div className="flex gap-2">
|
|
65
|
+
<Button type="button" variant="secondary" className="!w-auto" disabled={reopening} onClick={() => setConfirmingSetup(true)}>
|
|
66
|
+
Run setup again
|
|
67
|
+
</Button>
|
|
68
|
+
<a href="/admin/mailboxes/new">
|
|
69
|
+
<Button type="button" className="!w-auto">
|
|
70
|
+
+ New mailbox
|
|
71
|
+
</Button>
|
|
72
|
+
</a>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<p className="text-sm text-text-muted mb-4">
|
|
77
|
+
Administrative details only (addresses, owners, quota). The console never shows a mailbox’s mail:
|
|
78
|
+
to see someone’s account, impersonate them from their mailbox page.
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
{error && <Alert>{error}</Alert>}
|
|
82
|
+
|
|
83
|
+
<Modal open={confirmingSetup} onClose={() => setConfirmingSetup(false)} title="Run setup again?">
|
|
84
|
+
<p className="text-sm mb-4">
|
|
85
|
+
Setup starts again from its first step, and the admin console sends administrators to it until
|
|
86
|
+
it's finished. Your existing settings, domains and mailboxes are kept.
|
|
87
|
+
</p>
|
|
88
|
+
<div className="flex gap-2 justify-end">
|
|
89
|
+
<Button type="button" variant="secondary" className="!w-auto" onClick={() => setConfirmingSetup(false)}>
|
|
90
|
+
Cancel
|
|
91
|
+
</Button>
|
|
92
|
+
<Button type="button" className="!w-auto" loading={reopening} disabled={reopening} onClick={() => void handleRunSetup()}>
|
|
93
|
+
Run setup
|
|
94
|
+
</Button>
|
|
95
|
+
</div>
|
|
96
|
+
</Modal>
|
|
97
|
+
|
|
98
|
+
{loading ? (
|
|
99
|
+
<p className="text-sm text-text-muted">Loading…</p>
|
|
100
|
+
) : (
|
|
101
|
+
<MailboxTable mailboxes={mailboxes} />
|
|
102
|
+
)}
|
|
103
|
+
|
|
104
|
+
<div className="flex gap-3 items-center mt-4">
|
|
105
|
+
<Button
|
|
106
|
+
variant="secondary"
|
|
107
|
+
type="button"
|
|
108
|
+
className="!w-auto"
|
|
109
|
+
disabled={page === 0 || loading}
|
|
110
|
+
onClick={() => setPage((p) => Math.max(0, p - 1))}
|
|
111
|
+
>
|
|
112
|
+
Previous
|
|
113
|
+
</Button>
|
|
114
|
+
<span className="text-sm text-text-muted">Page {page + 1}</span>
|
|
115
|
+
<Button
|
|
116
|
+
variant="secondary"
|
|
117
|
+
type="button"
|
|
118
|
+
className="!w-auto"
|
|
119
|
+
disabled={!hasNextPage || loading}
|
|
120
|
+
onClick={() => setPage((p) => p + 1)}
|
|
121
|
+
>
|
|
122
|
+
Next
|
|
123
|
+
</Button>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<LeftoverMailboxesSection />
|
|
127
|
+
</>
|
|
128
|
+
);
|
|
129
|
+
}
|