@nocobase/portal-template-default 1.0.16 → 1.0.17
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/AGENTS.md +8 -0
- package/README.MD +4 -0
- package/dist/assets/{LineDraw-vPRTWiQ5.js → LineDraw-BBB5hwuJ.js} +1 -1
- package/dist/assets/{SymbolDraw-DOl_Tss3.js → SymbolDraw-CKS3uUb_.js} +1 -1
- package/dist/assets/{VisualMapping-j08W3KBm.js → VisualMapping-BCwaW3TD.js} +1 -1
- package/dist/assets/auth-method-demo-BdCCvEEz.js +1 -0
- package/dist/assets/{auto-login-provider-Bukw7zEe.js → auto-login-provider-DO5Il6Dp.js} +2 -2
- package/dist/assets/auto-login-provider-TQ08B6-i.js +1 -0
- package/dist/assets/auto-redirect-provider-ButXp0A3.js +1 -0
- package/dist/assets/auto-redirect-provider-DnGGP2Vn.js +1 -0
- package/dist/assets/auto-redirect-provider-ja-vFPaF.js +1 -0
- package/dist/assets/calendar-C7xnRgOT.js +1 -0
- package/dist/assets/{cas-sign-in-button-BQn3Mttx.js → cas-sign-in-button-BZCa4lR6.js} +1 -1
- package/dist/assets/{components-BT5mL9gW.js → components-_g-GjQeV.js} +3 -3
- package/dist/assets/{configuration-gate-BJoadoA6.js → configuration-gate-B4XVz7tS.js} +1 -1
- package/dist/assets/{createClipPathFromCoordSys-m8IbnJ1z.js → createClipPathFromCoordSys-z9Kmh-tu.js} +1 -1
- package/dist/assets/createSeriesDataSimply-CPqysF0K.js +1 -0
- package/dist/assets/{customGraphicKeyframeAnimation-CYLPurwK.js → customGraphicKeyframeAnimation-DMU5crAu.js} +1 -1
- package/dist/assets/demo-BPlae2bp.js +1 -0
- package/dist/assets/demo-Bj_Y0RrW.js +1 -0
- package/dist/assets/demo-CKPAQOib.js +1 -0
- package/dist/assets/demo-CXRTPvIx.js +1 -0
- package/dist/assets/demo-DJuVDu1n.js +1 -0
- package/dist/assets/demo-DUmWU7ik.js +1 -0
- package/dist/assets/demo-NhIzFRE1.js +1 -0
- package/dist/assets/{dingtalk-sign-in-button-DSluFaP9.js → dingtalk-sign-in-button-DMPgE5kT.js} +1 -1
- package/dist/assets/{echarts-preview-mRXoEciY.js → echarts-preview-R96Pbqmz.js} +1 -1
- package/dist/assets/{echarts-runtime-CvLr4Slh.js → echarts-runtime-Ce_z2eX_.js} +3 -3
- package/dist/assets/{echarts-runtime-advanced-BC1tvfQ0.js → echarts-runtime-advanced-Dr80KHJR.js} +1 -1
- package/dist/assets/{echarts-runtime-common-DhNaV5B8.js → echarts-runtime-common-DB95Yfc1.js} +1 -1
- package/dist/assets/{echarts-runtime-components-BiioS8t1.js → echarts-runtime-components-DCJEaTJk.js} +1 -1
- package/dist/assets/{echarts-runtime-hierarchy-CAWqYvFh.js → echarts-runtime-hierarchy-CezgZs9O.js} +1 -1
- package/dist/assets/{floating-RVbHvIiD.js → floating-O9WmiDXk.js} +2 -2
- package/dist/assets/index-BBKV6O5d.css +1 -0
- package/dist/assets/{index-Dw20Lzpp.js → index-CPzehPGe.js} +3 -3
- package/dist/assets/index-Cc6awvdg.js +1064 -0
- package/dist/assets/index-ChA0z9ke.js +38 -0
- package/dist/assets/{index-BysibBZu.js → index-DgB7uTMs.js} +2 -2
- package/dist/assets/{index-C-tdHirk.js → index-DroUAK80.js} +1 -1
- package/dist/assets/index-WKvygTBp.js +59 -0
- package/dist/assets/{labelHelper-DbITmOUW.js → labelHelper-Dk5jkiD-.js} +1 -1
- package/dist/assets/ldap-sign-in-form-CKN4l7qM.js +1 -0
- package/dist/assets/{oidc-sign-in-button-Cgpa8Qzj.js → oidc-sign-in-button-BIRonrpC.js} +1 -1
- package/dist/assets/{page-context-AU6RU0Qi.js → page-context-DAiW_dId.js} +4 -4
- package/dist/assets/prompt-card-rGZqpqkF.js +1 -0
- package/dist/assets/prompt-output-B4h3uLWf.js +1 -0
- package/dist/assets/saml-sign-in-button-B4ugaLIb.js +1 -0
- package/dist/assets/{sectorHelper-C6L782Ue.js → sectorHelper-BuxrrJrA.js} +1 -1
- package/dist/assets/shortcut-BhKXxJLs.js +47 -0
- package/dist/assets/{sms-sign-in-form-Bo2WLZuP.js → sms-sign-in-form-DKpxRDdZ.js} +1 -1
- package/dist/assets/{static.browser-CoPxsICt.js → static.browser-kzzpH0Xt.js} +1 -1
- package/dist/assets/switch-BdVxPIVU.js +1 -0
- package/dist/assets/{tool-cards-ipgJ_3Ec.js → tool-cards-CpczIke-.js} +3 -3
- package/dist/assets/{use-authenticator-sign-in-BzFeh7qe.js → use-authenticator-sign-in-CIj210ry.js} +1 -1
- package/dist/assets/use-dingtalk-sign-in-BW4kkXD3.js +1 -0
- package/dist/assets/{use-wecom-sign-in-PPIMLvGa.js → use-wecom-sign-in-dIqMtcN9.js} +1 -1
- package/dist/assets/{wecom-sign-in-button-rUq9RW8R.js → wecom-sign-in-button-Dn_2zDab.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/index.raw.html +2 -2
- package/package.json +9 -1
- package/src/App.tsx +5 -2
- package/src/app/extension.ts +2 -0
- package/src/app/extensions.tsx +18 -6
- package/src/app/route-access-guard.tsx +22 -0
- package/src/app/route-runtime.ts +173 -0
- package/src/app/routes.tsx +2 -2
- package/src/components/app-shell/header.tsx +56 -1
- package/src/components/app-shell/sidebar.tsx +14 -2
- package/src/extensions/nocobase-acl/README.md +28 -14
- package/src/extensions/nocobase-acl/demo/index.tsx +87 -15
- package/src/extensions/nocobase-acl/demo/prompt-generator.tsx +1 -0
- package/src/extensions/nocobase-mail/README.md +74 -0
- package/src/extensions/nocobase-mail/components/index.ts +79 -0
- package/src/extensions/nocobase-mail/components/mail-api.ts +423 -0
- package/src/extensions/nocobase-mail/components/mail-attachment-list.tsx +67 -0
- package/src/extensions/nocobase-mail/components/mail-compose-attachments.tsx +166 -0
- package/src/extensions/nocobase-mail/components/mail-compose.tsx +1071 -0
- package/src/extensions/nocobase-mail/components/mail-detail.tsx +653 -0
- package/src/extensions/nocobase-mail/components/mail-draft-autosave.ts +26 -0
- package/src/extensions/nocobase-mail/components/mail-empty.tsx +48 -0
- package/src/extensions/nocobase-mail/components/mail-filters.tsx +277 -0
- package/src/extensions/nocobase-mail/components/mail-inbox.tsx +544 -0
- package/src/extensions/nocobase-mail/components/mail-inline-images.ts +69 -0
- package/src/extensions/nocobase-mail/components/mail-label-badge.tsx +25 -0
- package/src/extensions/nocobase-mail/components/mail-label-manager.tsx +271 -0
- package/src/extensions/nocobase-mail/components/mail-labels-editor.tsx +267 -0
- package/src/extensions/nocobase-mail/components/mail-mass-tracking.tsx +271 -0
- package/src/extensions/nocobase-mail/components/mail-note-editor.tsx +99 -0
- package/src/extensions/nocobase-mail/components/mail-recipient-input.tsx +260 -0
- package/src/extensions/nocobase-mail/components/mail-reply-quote.ts +28 -0
- package/src/extensions/nocobase-mail/components/mail-rich-editor.tsx +287 -0
- package/src/extensions/nocobase-mail/components/mail-send-actions.tsx +238 -0
- package/src/extensions/nocobase-mail/components/mail-senders.ts +61 -0
- package/src/extensions/nocobase-mail/components/mail-settings-drawer.tsx +708 -0
- package/src/extensions/nocobase-mail/components/mail-showcase-layout.tsx +64 -0
- package/src/extensions/nocobase-mail/components/mail-signature-manager.tsx +258 -0
- package/src/extensions/nocobase-mail/components/mail-signatures.ts +25 -0
- package/src/extensions/nocobase-mail/components/mail-table.tsx +476 -0
- package/src/extensions/nocobase-mail/components/mail-template-manager.tsx +204 -0
- package/src/extensions/nocobase-mail/components/mail-toolbar.tsx +155 -0
- package/src/extensions/nocobase-mail/components/mail-unread.tsx +111 -0
- package/src/extensions/nocobase-mail/components/types.ts +297 -0
- package/src/extensions/nocobase-mail/components/use-mail-compose.tsx +262 -0
- package/src/extensions/nocobase-mail/components/use-mail-mass-messages.ts +54 -0
- package/src/extensions/nocobase-mail/components/use-mail-messages.ts +113 -0
- package/src/extensions/nocobase-mail/components/use-mail-signatures.ts +122 -0
- package/src/extensions/nocobase-mail/components/use-mail-templates.ts +54 -0
- package/src/extensions/nocobase-mail/extension.tsx +105 -0
- package/src/extensions/nocobase-mail/index.ts +1 -0
- package/src/extensions/nocobase-mail/mail-demo-pages.tsx +503 -0
- package/src/extensions/nocobase-mail/mail-pages.tsx +201 -0
- package/src/extensions/nocobase-mail/tests/mail-quote-html-regression.mjs +51 -0
- package/src/extensions/nocobase-mail/tests/mail-regression.mjs +649 -0
- package/src/extensions/nocobase-users-example/app-routes.tsx +121 -0
- package/src/extensions/nocobase-users-example/extension.tsx +2 -100
- package/src/extensions/nocobase-users-example/index.ts +1 -0
- package/src/lib/nocobase/acl/menu.ts +17 -3
- package/src/lib/nocobase/acl/types.ts +4 -0
- package/src/locales/en-US.ts +2 -1
- package/src/locales/zh-CN.ts +2 -1
- package/src/providers/runtime-config.ts +18 -0
- package/src/routes.tsx +10 -0
- package/src/vite-env.d.ts +3 -0
- package/vite.config.ts +8 -0
- package/dist/assets/auth-method-demo-B2qcpY8z.js +0 -1
- package/dist/assets/auto-login-provider-BMtzvdxG.js +0 -1
- package/dist/assets/auto-redirect-provider-C6GNPg5r.js +0 -1
- package/dist/assets/auto-redirect-provider-D5c6kN2R.js +0 -1
- package/dist/assets/auto-redirect-provider-iTzGEDpU.js +0 -1
- package/dist/assets/calendar-Dv2RNnsr.js +0 -1
- package/dist/assets/card-C9Hpeq1c.js +0 -1
- package/dist/assets/createSeriesDataSimply-DKUV5b5e.js +0 -1
- package/dist/assets/demo-BWGOwqtJ.js +0 -1
- package/dist/assets/demo-BWbcvkya.js +0 -1
- package/dist/assets/demo-DIASSPgn.js +0 -1
- package/dist/assets/demo-DuZ6asUU.js +0 -1
- package/dist/assets/demo-Dxcy4bDE.js +0 -1
- package/dist/assets/demo-YpEC76uw.js +0 -1
- package/dist/assets/demo-wzkoR8T2.js +0 -1
- package/dist/assets/index-CBZbj45X.js +0 -58
- package/dist/assets/index-CgkdZ6Oc.js +0 -686
- package/dist/assets/index-NH3aqqQz.css +0 -1
- package/dist/assets/index-hSBzW-VA.js +0 -43
- package/dist/assets/ldap-sign-in-form-BOMNDTkK.js +0 -1
- package/dist/assets/prompt-card-FWugRgi-.js +0 -1
- package/dist/assets/prompt-output-DMTuTNab.js +0 -1
- package/dist/assets/saml-sign-in-button-qt8bMeoQ.js +0 -1
- package/dist/assets/shortcut-Bu7jT_-w.js +0 -47
- package/dist/assets/switch-DQkkIE7G.js +0 -1
- package/dist/assets/use-dingtalk-sign-in-mrq6K5Yx.js +0 -1
|
@@ -9,7 +9,13 @@ import {
|
|
|
9
9
|
UserRoundCog,
|
|
10
10
|
UsersRound,
|
|
11
11
|
} from "lucide-react";
|
|
12
|
+
import type { TreeMenuItem } from "@refinedev/core";
|
|
12
13
|
|
|
14
|
+
import {
|
|
15
|
+
buildRouteResources,
|
|
16
|
+
defineAppRoutes,
|
|
17
|
+
RouteAccessGuard,
|
|
18
|
+
} from "@/app/route-runtime";
|
|
13
19
|
import { Badge } from "@/components/ui/badge";
|
|
14
20
|
import { Button } from "@/components/ui/button";
|
|
15
21
|
import { CanAccess } from "@/components/access-control/can-access";
|
|
@@ -21,7 +27,11 @@ import {
|
|
|
21
27
|
CardTitle,
|
|
22
28
|
} from "@/components/ui/card";
|
|
23
29
|
import { Input } from "@/components/ui/input";
|
|
24
|
-
import
|
|
30
|
+
import {
|
|
31
|
+
filterMenuItemsByAcl,
|
|
32
|
+
type RoleConstraint,
|
|
33
|
+
useAclState,
|
|
34
|
+
} from "@/lib/nocobase/acl";
|
|
25
35
|
import { AclField, AclPage, AclRegion } from "../components/acl-boundary";
|
|
26
36
|
import { AclPreviewProvider } from "./acl-preview-provider";
|
|
27
37
|
import { AclBoundaryApi } from "./boundary-api";
|
|
@@ -58,6 +68,53 @@ const usersRouteRoles = {
|
|
|
58
68
|
anyOf: ["admin"],
|
|
59
69
|
} satisfies RoleConstraint;
|
|
60
70
|
|
|
71
|
+
const navigationDemoRoutes = defineAppRoutes([
|
|
72
|
+
{
|
|
73
|
+
name: "dashboard",
|
|
74
|
+
path: "/dashboard",
|
|
75
|
+
resource: {
|
|
76
|
+
meta: {
|
|
77
|
+
label: "Dashboard",
|
|
78
|
+
icon: <LayoutPanelTop />,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "users",
|
|
84
|
+
path: "/users",
|
|
85
|
+
resource: {
|
|
86
|
+
meta: {
|
|
87
|
+
label: "Users",
|
|
88
|
+
icon: <UsersRound />,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
access: {
|
|
92
|
+
roles: usersRouteRoles,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "roles",
|
|
97
|
+
path: "/roles",
|
|
98
|
+
resource: {
|
|
99
|
+
meta: {
|
|
100
|
+
label: "Roles",
|
|
101
|
+
icon: <UserRoundCog />,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
const navigationDemoResources = buildRouteResources(navigationDemoRoutes);
|
|
108
|
+
const navigationDemoMenuItems: TreeMenuItem[] = navigationDemoResources.map(
|
|
109
|
+
(resource) => ({
|
|
110
|
+
key: resource.name,
|
|
111
|
+
name: resource.name,
|
|
112
|
+
route: typeof resource.list === "string" ? resource.list : undefined,
|
|
113
|
+
meta: resource.meta,
|
|
114
|
+
children: [],
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
|
|
61
118
|
const allowedRegionPermissions = {
|
|
62
119
|
"users:list": {},
|
|
63
120
|
"departments:list": {},
|
|
@@ -127,12 +184,12 @@ export function AclPatternsPage() {
|
|
|
127
184
|
defaultScene: "User and role administration",
|
|
128
185
|
defaultTarget:
|
|
129
186
|
"Allow administrators to open Users, but remove it from navigation and block its direct URL for other roles.",
|
|
130
|
-
requirements: `-
|
|
131
|
-
-
|
|
132
|
-
- Let the
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
187
|
+
requirements: `- Define application-owned navigation once through defineAppRoutes in src/routes.tsx.
|
|
188
|
+
- Put role constraints in the route access.roles field using anyOf, allOf, or noneOf.
|
|
189
|
+
- Let the route runtime generate the Refine resource, filter the sidebar item, and wrap the direct route with CanAccess.
|
|
190
|
+
- Do not repeat the same role list in Resource meta or a manually written route guard.
|
|
191
|
+
- Keep resource/action, record, region, and field permissions in their dedicated ACL boundaries.
|
|
192
|
+
- Let the Starter choose the first accessible route after inaccessible leaves and empty groups are removed.`,
|
|
136
193
|
}}
|
|
137
194
|
>
|
|
138
195
|
<OutcomeComparison
|
|
@@ -343,21 +400,36 @@ function OutcomeComparison({
|
|
|
343
400
|
}
|
|
344
401
|
|
|
345
402
|
function NavigationPreview() {
|
|
403
|
+
const acl = useAclState();
|
|
404
|
+
const menuItems =
|
|
405
|
+
acl.status === "ready"
|
|
406
|
+
? filterMenuItemsByAcl(navigationDemoMenuItems, acl.permissions)
|
|
407
|
+
: [];
|
|
408
|
+
const usersVisible = menuItems.some((item) => item.name === "users");
|
|
409
|
+
const usersRoute = navigationDemoRoutes.find(
|
|
410
|
+
(route) => route.name === "users"
|
|
411
|
+
);
|
|
412
|
+
|
|
346
413
|
return (
|
|
347
414
|
<div className="grid min-h-48 grid-cols-[150px_minmax(0,1fr)] overflow-hidden rounded-xl border bg-background">
|
|
348
415
|
<aside className="border-r bg-muted/35 p-3">
|
|
349
416
|
<div className="mb-3 text-xs font-semibold text-muted-foreground">
|
|
350
417
|
Workspace
|
|
351
418
|
</div>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
419
|
+
{menuItems.map((item) => (
|
|
420
|
+
<NavItem
|
|
421
|
+
key={item.name}
|
|
422
|
+
icon={item.meta?.icon}
|
|
423
|
+
label={String(item.meta?.label ?? item.name)}
|
|
424
|
+
active={
|
|
425
|
+
usersVisible ? item.name === "users" : item.name === "dashboard"
|
|
426
|
+
}
|
|
427
|
+
/>
|
|
428
|
+
))}
|
|
357
429
|
</aside>
|
|
358
430
|
<div className="flex items-center justify-center p-5 text-center">
|
|
359
|
-
<
|
|
360
|
-
|
|
431
|
+
<RouteAccessGuard
|
|
432
|
+
access={usersRoute?.access}
|
|
361
433
|
fallback={
|
|
362
434
|
<div>
|
|
363
435
|
<LayoutPanelTop className="mx-auto size-7 text-muted-foreground" />
|
|
@@ -375,7 +447,7 @@ function NavigationPreview() {
|
|
|
375
447
|
Route is available
|
|
376
448
|
</div>
|
|
377
449
|
</div>
|
|
378
|
-
</
|
|
450
|
+
</RouteAccessGuard>
|
|
379
451
|
</div>
|
|
380
452
|
</div>
|
|
381
453
|
);
|
|
@@ -45,6 +45,7 @@ Implementation contract
|
|
|
45
45
|
- Use the Starter's built-in NocoBase accessControlProvider and ACL store.
|
|
46
46
|
- NocoBase roles:check is the source of truth. Do not create a second permission store. Use configured role names only when the requirement explicitly includes a role constraint.
|
|
47
47
|
- Import the Starter CanAccess from @/components/access-control/can-access. Use it with AclPage, AclRegion, and AclField for permission presentation. Do not copy their checks into local booleans or role comparisons.
|
|
48
|
+
- For route-level role access, define the route once with defineAppRoutes in src/routes.tsx and put the constraint in access.roles. Let the route runtime control both its menu item and direct URL.
|
|
48
49
|
- Use useGetRoles only when UI needs to display or pass through the current effective ACL roles; it is not a replacement permission evaluator.
|
|
49
50
|
- Keep backend ACL enforcement in place; frontend checks only control presentation and navigation.
|
|
50
51
|
- Import reusable components from the installed local entry point at @/extensions/nocobase-acl when page composition is needed.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# NocoBase Mail
|
|
2
|
+
|
|
3
|
+
Reusable mail inbox, compose, detail, and label components backed by the NocoBase mail API.
|
|
4
|
+
|
|
5
|
+
After installation, import the components from `@/extensions/nocobase-mail`.
|
|
6
|
+
|
|
7
|
+
- `MailInbox` full inbox with toolbar, table, detail panel, and compose.
|
|
8
|
+
- `MailCompose` / `MailComposeForm` standalone compose dialog or embedded form,
|
|
9
|
+
with immediate and scheduled sending plus opt-in bulk mode, account-aware sender aliases,
|
|
10
|
+
server templates/signatures, recipient suggestions, reply/forward references, automatic draft
|
|
11
|
+
saving and recovery, and real attachment uploads.
|
|
12
|
+
- `MailComposeAttachments` uploads files through `mail:messageAttachmentUpload`
|
|
13
|
+
with retry, removal, and the backend's 25 MB limit.
|
|
14
|
+
- `MailFilters` folder, read-state, label, and todo-message filters.
|
|
15
|
+
- `MailUnreadProvider` / `MailUnreadIndicator` / `MailUnreadIcon` reusable unread-count
|
|
16
|
+
display with interval, window-focus, and visibility refresh.
|
|
17
|
+
- `MailDetail` threaded message detail with per-message Reply, conditional Reply all,
|
|
18
|
+
and Forward actions.
|
|
19
|
+
- `MailSettingsDrawer` personal mailbox settings with Mailbox, Labels, Templates,
|
|
20
|
+
and Signature management tabs.
|
|
21
|
+
- `MailMassTracking` bulk delivery tracking with recipient status, cancel, and resend.
|
|
22
|
+
- `useMailMessages` hook for paginated message listing with search and filters.
|
|
23
|
+
- `useMailCompose` hook to open compose from anywhere.
|
|
24
|
+
- `MailLabelBadge` / `MailLabelsEditor` label display, assignment, and full CRUD.
|
|
25
|
+
- `MailNoteEditor` per-message private notes.
|
|
26
|
+
- `MailAttachmentList` attachment preview and download.
|
|
27
|
+
- Message detail resolves authenticated `cid:` inline images and keeps those images out of the
|
|
28
|
+
regular attachment list.
|
|
29
|
+
|
|
30
|
+
The mail API client (`mailApi`) uses the Starter's built-in `API_URL`, `getNocoBaseHeaders`, and `NOCOBASE_TOKEN_KEY` from `@/providers/constants`. A compatible NocoBase backend with the mail plugin enabled is required.
|
|
31
|
+
|
|
32
|
+
## Send modes
|
|
33
|
+
|
|
34
|
+
The standard compose form enables scheduled sending by default. Bulk sending is
|
|
35
|
+
kept on the dedicated `/dev/mail/bulk` showcase page, where the bulk form and
|
|
36
|
+
delivery jobs are visible together. Reusable compose forms can still opt into bulk mode:
|
|
37
|
+
|
|
38
|
+
- **Schedule send** calls `mail:messageSend` with an ISO `scheduleSendAt` value.
|
|
39
|
+
- **Bulk send** calls `mailMassMessages:send`, creates one separate message per
|
|
40
|
+
To recipient, and defaults to a 2-second interval between messages.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<MailComposeForm
|
|
44
|
+
allowScheduleSend
|
|
45
|
+
allowBulkSend
|
|
46
|
+
defaultBulkIntervalMs={2000}
|
|
47
|
+
/>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Bulk and scheduled sending are separate modes, matching the NocoBase email
|
|
51
|
+
manager backend. Bulk sending requires at least two recipients and does not
|
|
52
|
+
support a scheduled start time.
|
|
53
|
+
|
|
54
|
+
Scheduled messages can be canceled back into drafts and edited or rescheduled.
|
|
55
|
+
Opening a local draft enters compose mode with its uploaded attachments; local
|
|
56
|
+
drafts can be updated or permanently deleted. Provider-backed drafts remain
|
|
57
|
+
read-only and must be changed in the original mailbox so provider state and
|
|
58
|
+
attachments are preserved. Trash actions are provider-backed: messages
|
|
59
|
+
can be moved to trash, put back, or permanently deleted after confirmation.
|
|
60
|
+
|
|
61
|
+
Templates are stored in `mailTemplates`; the backend model stores template
|
|
62
|
+
content but no subject. Signatures are stored per mail account in
|
|
63
|
+
`mailAccounts.config.signatures`, so changing the selected sender also changes
|
|
64
|
+
the available/default signature. Use `recipientOptions` on the compose
|
|
65
|
+
components to add application-specific record recipients alongside NocoBase
|
|
66
|
+
users.
|
|
67
|
+
|
|
68
|
+
Gmail aliases can be viewed and refreshed from Mail settings. Synced aliases are
|
|
69
|
+
immediately available in the compose sender selector. Outlook does not expose
|
|
70
|
+
sender aliases through this integration.
|
|
71
|
+
|
|
72
|
+
Mailbox account creation, OAuth authorization, and provider settings are not
|
|
73
|
+
part of this component package; they remain owned by the separate mail settings
|
|
74
|
+
center.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export { mailApi } from "./mail-api";
|
|
3
|
+
export { MailInbox } from "./mail-inbox";
|
|
4
|
+
export type { MailInboxProps } from "./mail-inbox";
|
|
5
|
+
export { MailToolbar } from "./mail-toolbar";
|
|
6
|
+
export { MailTable } from "./mail-table";
|
|
7
|
+
export { MailDetail } from "./mail-detail";
|
|
8
|
+
export { MailCompose, MailComposeForm } from "./mail-compose";
|
|
9
|
+
export type {
|
|
10
|
+
ComposeInitialValues,
|
|
11
|
+
ComposeReference,
|
|
12
|
+
ComposeMode,
|
|
13
|
+
ComposeVariant,
|
|
14
|
+
MailComposeFormProps,
|
|
15
|
+
MailComposeProps,
|
|
16
|
+
} from "./mail-compose";
|
|
17
|
+
export { MailSendActions } from "./mail-send-actions";
|
|
18
|
+
export type { MailSendActionsProps } from "./mail-send-actions";
|
|
19
|
+
export { MailRecipientInput } from "./mail-recipient-input";
|
|
20
|
+
export type { MailRecipientInputProps } from "./mail-recipient-input";
|
|
21
|
+
export { MailComposeAttachments } from "./mail-compose-attachments";
|
|
22
|
+
export type { MailComposeAttachmentsProps } from "./mail-compose-attachments";
|
|
23
|
+
export { getMailSenderCandidates, resolveMailSender } from "./mail-senders";
|
|
24
|
+
export type { MailSenderCandidate } from "./mail-senders";
|
|
25
|
+
export { MailRichEditor } from "./mail-rich-editor";
|
|
26
|
+
export type { MailRichEditorProps } from "./mail-rich-editor";
|
|
27
|
+
export { useMailSignatures } from "./use-mail-signatures";
|
|
28
|
+
export type { MailSignatureValues } from "./use-mail-signatures";
|
|
29
|
+
export { MailSignatureManager } from "./mail-signature-manager";
|
|
30
|
+
export type { MailSignatureManagerProps } from "./mail-signature-manager";
|
|
31
|
+
export { applySignature } from "./mail-signatures";
|
|
32
|
+
export { useMailTemplates } from "./use-mail-templates";
|
|
33
|
+
export type { MailTemplateValues } from "./use-mail-templates";
|
|
34
|
+
export { MailTemplateManager } from "./mail-template-manager";
|
|
35
|
+
export type { MailTemplateManagerProps } from "./mail-template-manager";
|
|
36
|
+
export { useMailMessages } from "./use-mail-messages";
|
|
37
|
+
export type {
|
|
38
|
+
UseMailMessagesOptions,
|
|
39
|
+
UseMailMessagesResult,
|
|
40
|
+
} from "./use-mail-messages";
|
|
41
|
+
export {
|
|
42
|
+
useMailCompose,
|
|
43
|
+
buildComposeInitial,
|
|
44
|
+
canReplyAll,
|
|
45
|
+
} from "./use-mail-compose";
|
|
46
|
+
export type { UseMailComposeOptions } from "./use-mail-compose";
|
|
47
|
+
export { MailLabelBadge } from "./mail-label-badge";
|
|
48
|
+
export { MailLabelsEditor } from "./mail-labels-editor";
|
|
49
|
+
export { MailLabelManager } from "./mail-label-manager";
|
|
50
|
+
export type { MailLabelManagerProps } from "./mail-label-manager";
|
|
51
|
+
export { MailNoteEditor } from "./mail-note-editor";
|
|
52
|
+
export { MailAttachmentList } from "./mail-attachment-list";
|
|
53
|
+
export { createDebouncedDraftSaver } from "./mail-draft-autosave";
|
|
54
|
+
export type { DebouncedDraftSaver } from "./mail-draft-autosave";
|
|
55
|
+
export { serializeReplyQuote, splitReplyQuote } from "./mail-reply-quote";
|
|
56
|
+
export type { MailReplyContent } from "./mail-reply-quote";
|
|
57
|
+
export {
|
|
58
|
+
collectInlineContentIds,
|
|
59
|
+
filterInlineAttachments,
|
|
60
|
+
normalizeContentId,
|
|
61
|
+
replaceInlineImageSources,
|
|
62
|
+
} from "./mail-inline-images";
|
|
63
|
+
export { MailEmpty } from "./mail-empty";
|
|
64
|
+
export {
|
|
65
|
+
MailUnreadIcon,
|
|
66
|
+
MailUnreadIndicator,
|
|
67
|
+
MailUnreadProvider,
|
|
68
|
+
useMailUnread,
|
|
69
|
+
} from "./mail-unread";
|
|
70
|
+
export type {
|
|
71
|
+
MailUnreadIndicatorProps,
|
|
72
|
+
MailUnreadProviderProps,
|
|
73
|
+
} from "./mail-unread";
|
|
74
|
+
export { MailSettingsDrawer } from "./mail-settings-drawer";
|
|
75
|
+
export type { MailSettingsDrawerProps } from "./mail-settings-drawer";
|
|
76
|
+
export { MailMassTracking } from "./mail-mass-tracking";
|
|
77
|
+
export { useMailMassMessages } from "./use-mail-mass-messages";
|
|
78
|
+
export { MailFilters } from "./mail-filters";
|
|
79
|
+
export type { MailFilterValue, MailFiltersProps } from "./mail-filters";
|