From 99b8b7dee8c335ee217580f5af9902900c0e95bc Mon Sep 17 00:00:00 2001 From: zxyszx <299979470+zxyszx@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:52:42 +0800 Subject: [PATCH] fix: guide admins to mailbox management --- VERSION | 2 +- apps/web/src/lib/language.tsx | 4 ++++ apps/web/src/pages/mail.tsx | 25 ++++++++++++++----------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/VERSION b/VERSION index e8ea05d..c813fe1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.4 +1.2.5 diff --git a/apps/web/src/lib/language.tsx b/apps/web/src/lib/language.tsx index 323df70..0e86dde 100644 --- a/apps/web/src/lib/language.tsx +++ b/apps/web/src/lib/language.tsx @@ -69,6 +69,8 @@ const exactTranslations: Record = { "暂无标签": { "zh-TW": "暫無標籤", en: "No labels" }, "收起侧栏": { "zh-TW": "收合側欄", en: "Collapse sidebar" }, "选择邮箱": { "zh-TW": "選擇信箱", en: "Select mailbox" }, + "加载邮箱...": { "zh-TW": "載入信箱...", en: "Loading mailboxes..." }, + "未创建邮箱": { "zh-TW": "尚未建立信箱", en: "No mailbox created" }, "没有可用邮箱": { "zh-TW": "沒有可用信箱", en: "No mailboxes available" }, "邮箱地址已复制": { "zh-TW": "信箱地址已複製", en: "Mailbox address copied" }, "打开导航": { "zh-TW": "開啟導覽", en: "Open navigation" }, @@ -179,6 +181,8 @@ const exactTranslations: Record = { "还没有可用邮箱": { "zh-TW": "還沒有可用信箱", en: "No mailbox available" }, "请在个人中心申请邮箱,或联系管理员为当前账号分配邮箱。": { "zh-TW": "請在個人中心申請信箱,或聯絡管理員為目前帳號分配信箱。", en: "Apply for a mailbox in Profile, or contact an administrator to assign one to this account." }, "前往个人中心": { "zh-TW": "前往個人中心", en: "Go to profile" }, + "请前往邮箱管理,为当前账号创建或分配邮箱。": { "zh-TW": "請前往信箱管理,為目前帳號建立或分配信箱。", en: "Open mailbox management to create or assign a mailbox to this account." }, + "前往邮箱管理": { "zh-TW": "前往信箱管理", en: "Go to mailbox management" }, "无邮箱前台权限": { "zh-TW": "無信箱前台權限", en: "No mailbox access" }, "当前账号未开启邮箱前台访问权限。": { "zh-TW": "目前帳號未開啟信箱前台存取權限。", en: "Mailbox access is not enabled for this account." }, "无邮件查看权限": { "zh-TW": "無郵件檢視權限", en: "No mail read permission" }, diff --git a/apps/web/src/pages/mail.tsx b/apps/web/src/pages/mail.tsx index 374aa1f..0383c81 100644 --- a/apps/web/src/pages/mail.tsx +++ b/apps/web/src/pages/mail.tsx @@ -11,7 +11,7 @@ import TextAlign from "@tiptap/extension-text-align" import Placeholder from "@tiptap/extension-placeholder" import { BackgroundColor, Color, FontFamily, FontSize, TextStyle } from "@tiptap/extension-text-style" import { useNavigate } from "react-router-dom" -import { AlignCenter, AlignLeft, AlignRight, Archive, ArrowLeft, Ban, Bold, Calendar, Check, ChevronDown, Clock3, Code2, Copy, Download, Ellipsis, Eraser, Eye, FileText, Folder, Forward, Highlighter, History, Image, Inbox, IndentDecrease, IndentIncrease, Italic, Link, List, ListOrdered, Mail, MailCheck, MailQuestion, Moon, PanelLeftOpen, Paperclip, PencilLine, Plus, Quote, Redo2, RefreshCcw, Reply, RotateCcw, Search, Send, Settings, ShieldCheck, Signature, SlidersHorizontal, Smile, Star, Strikethrough, Sun, Trash2, Type, Underline, Undo2, Upload, X } from "lucide-react" +import { AlignCenter, AlignLeft, AlignRight, Archive, ArrowLeft, Ban, Bold, Calendar, Check, ChevronDown, Clock3, Code2, Copy, Download, Ellipsis, Eraser, Eye, FileText, Folder, Forward, Highlighter, History, Image, Inbox, IndentDecrease, IndentIncrease, Italic, Link, List, ListOrdered, Mail, Mailbox as MailboxIcon, MailCheck, MailQuestion, Moon, PanelLeftOpen, Paperclip, PencilLine, Plus, Quote, Redo2, RefreshCcw, Reply, RotateCcw, Search, Send, Settings, ShieldCheck, Signature, SlidersHorizontal, Smile, Star, Strikethrough, Sun, Trash2, Type, Underline, Undo2, Upload, X } from "lucide-react" import { api, ExternalImapAccount, ListResponse, Mailbox, MailFolder, MailLabel, MailMessage, MailSearchParams, SendPayload, DraftPayload, ScheduledSend, SendQueueItem, SendQueueAuditEvent, SendQueueStatus, PermissionLimits } from "@/lib/api" import { cn, decodeMimeHeader, formatBytes, formatDate, formatDateTime, generateLabelColor } from "@/lib/utils" import { applyTheme, getInitialTheme } from "@/lib/theme" @@ -174,6 +174,7 @@ export function MailPage() { const canDownloadAttachments = hasPermission(user, "mail.attachments.download") const canManageSignatures = hasPermission(user, "mail.signatures.manage") const canViewUnknownMail = user?.role === "admin" + const canManageMailboxes = hasPermission(user, "admin.mailboxes.view") const publicSettings = useQuery({ queryKey: ["public-settings"], queryFn: api.publicSettings }) const externalImapEnabled = publicSettings.data?.externalImapEnabled ?? false @@ -1186,9 +1187,9 @@ export function MailPage() { @@ -1468,7 +1469,7 @@ export function MailPage() { ) : !canReadMail ? ( ) : !mailboxList.isLoading && !hasMailboxes && mailView !== "unknown" ? ( - + navigate("/admin?section=mailboxes")} /> ) : mailView === "scheduled" && canScheduleMail ? ( void }) { +function NoMailboxState({ canManageMailboxes, onOpenSettings, onManageMailboxes }: { canManageMailboxes: boolean; onOpenSettings: () => void; onManageMailboxes: () => void }) { return (
@@ -2069,9 +2070,10 @@ function NoMailboxState({ onOpenSettings }: { onOpenSettings: () => void }) {
还没有可用邮箱
-
请在个人中心申请邮箱,或联系管理员为当前账号分配邮箱。
-
@@ -3215,10 +3217,11 @@ function UnreadBadge({ count, tone = "danger" }: { count?: number; tone?: "dange ) } -function MailboxSwitcher({ collapsed, mailboxes, selectedMailboxId, selectedMailbox, fallbackAddress, unreadCount, onSelect }: { collapsed: boolean; mailboxes: Mailbox[]; selectedMailboxId: string; selectedMailbox?: Mailbox; fallbackAddress?: string; unreadCount: number; onSelect: (mailboxId: string) => void }) { +function MailboxSwitcher({ collapsed, mailboxes, loading, selectedMailboxId, selectedMailbox, unreadCount, onSelect }: { collapsed: boolean; mailboxes: Mailbox[]; loading: boolean; selectedMailboxId: string; selectedMailbox?: Mailbox; unreadCount: number; onSelect: (mailboxId: string) => void }) { const [mailboxQuery, setMailboxQuery] = React.useState("") const isAllSelected = selectedMailboxId === "all" - const displayAddress = isAllSelected ? "全部邮箱" : selectedMailbox?.address || fallbackAddress || "选择邮箱" + const mailboxUnavailable = loading || mailboxes.length === 0 + const displayAddress = loading ? "加载邮箱..." : mailboxes.length === 0 ? "未创建邮箱" : isAllSelected ? "全部邮箱" : selectedMailbox?.address || "选择邮箱" const selectedUnreadCount = isAllSelected ? unreadCount : (selectedMailbox?.unreadCount ?? unreadCount) const normalizedQuery = mailboxQuery.trim().toLowerCase() const showAllMailboxOption = !normalizedQuery || "全部邮箱".includes(normalizedQuery) || "all".includes(normalizedQuery) @@ -3232,13 +3235,13 @@ function MailboxSwitcher({ collapsed, mailboxes, selectedMailboxId, selectedMail return ( { if (!open) setMailboxQuery("") }}> -