chore: sync GovOPlaN module split state
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { ApiSettings } from "../types";
|
||||
import type { ApiSettings, DeltaDeletedItem } from "../types";
|
||||
import { apiFetch } from "./client";
|
||||
|
||||
export type MailSecurity = "plain" | "tls" | "starttls";
|
||||
@@ -95,6 +95,10 @@ export type MailMailboxMessageListResponse = {
|
||||
total_count?: number;
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
cursor?: string | null;
|
||||
next_cursor?: string | null;
|
||||
cursor_stable?: boolean;
|
||||
full?: boolean;
|
||||
messages: MailMailboxMessageSummary[];
|
||||
};
|
||||
|
||||
@@ -127,6 +131,16 @@ export type MailServerProfile = {
|
||||
|
||||
export type MailServerProfileListResponse = { profiles: MailServerProfile[] };
|
||||
|
||||
export type MailSettingsDeltaResponse = {
|
||||
profiles: MailServerProfile[];
|
||||
policy?: MailProfilePolicyResponse | null;
|
||||
changed_sections?: string[];
|
||||
deleted: DeltaDeletedItem[];
|
||||
watermark?: string | null;
|
||||
has_more: boolean;
|
||||
full: boolean;
|
||||
};
|
||||
|
||||
export const mailProfilePatternKeys = [
|
||||
"smtp_hosts",
|
||||
"imap_hosts",
|
||||
@@ -215,6 +229,28 @@ export async function listMailServerProfiles(settings: ApiSettings, includeInact
|
||||
return response.profiles ?? [];
|
||||
}
|
||||
|
||||
export async function fetchMailSettingsDelta(
|
||||
settings: ApiSettings,
|
||||
params: {
|
||||
scope_type?: MailProfileScope;
|
||||
scope_id?: string | null;
|
||||
include_inactive?: boolean;
|
||||
campaign_id?: string | null;
|
||||
since?: string | null;
|
||||
limit?: number;
|
||||
} = {}
|
||||
): Promise<MailSettingsDeltaResponse> {
|
||||
const search = new URLSearchParams();
|
||||
if (params.scope_type) search.set("scope_type", params.scope_type);
|
||||
if (params.scope_id) search.set("scope_id", params.scope_id);
|
||||
if (params.include_inactive) search.set("include_inactive", "true");
|
||||
if (params.campaign_id) search.set("campaign_id", params.campaign_id);
|
||||
if (params.since) search.set("since", params.since);
|
||||
if (params.limit) search.set("limit", String(params.limit));
|
||||
const suffix = search.toString() ? `?${search.toString()}` : "";
|
||||
return apiFetch<MailSettingsDeltaResponse>(settings, `/api/v1/mail/settings/delta${suffix}`);
|
||||
}
|
||||
|
||||
export async function createMailServerProfile(settings: ApiSettings, payload: MailServerProfilePayload): Promise<MailServerProfile> {
|
||||
return apiFetch<MailServerProfile>(settings, "/api/v1/mail/profiles", {
|
||||
method: "POST",
|
||||
@@ -284,9 +320,11 @@ export async function listMailboxMessages(
|
||||
profileId: string,
|
||||
folder = "INBOX",
|
||||
limit = 50,
|
||||
offset = 0
|
||||
offset = 0,
|
||||
cursor?: string | null
|
||||
): Promise<MailMailboxMessageListResponse> {
|
||||
const params = new URLSearchParams({ folder, limit: String(limit), offset: String(offset) });
|
||||
if (cursor) params.set("cursor", cursor);
|
||||
return apiFetch<MailMailboxMessageListResponse>(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/messages?${params.toString()}`);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ import {
|
||||
LoadingIndicator,
|
||||
MessageDisplayPanel,
|
||||
formatDateTime,
|
||||
i18nMessage,
|
||||
type ApiSettings
|
||||
} from "@govoplan/core-webui";
|
||||
import {
|
||||
@@ -17,11 +18,11 @@ import {
|
||||
type MailImapFolderResponse,
|
||||
type MailMailboxMessageDetail,
|
||||
type MailMailboxMessageSummary,
|
||||
type MailServerProfile
|
||||
} from "../../api/mail";
|
||||
type MailServerProfile } from
|
||||
"../../api/mail";
|
||||
import { buildMailboxFolderTree, findFolderNodeId, folderAncestorIds, type MailFolderNode } from "./mailboxFolders";
|
||||
|
||||
export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
const [profiles, setProfiles] = useState<MailServerProfile[]>([]);
|
||||
const [selectedProfileId, setSelectedProfileId] = useState("");
|
||||
const [folders, setFolders] = useState<MailImapFolderResponse[]>([]);
|
||||
@@ -48,6 +49,7 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
const folderRequestRef = useRef(0);
|
||||
const messageListRequestRef = useRef(0);
|
||||
const messageDetailRequestRef = useRef(0);
|
||||
const mailboxPageCursorsRef = useRef<Record<string, string | null>>({});
|
||||
|
||||
const selectedProfile = profiles.find((profile) => profile.id === selectedProfileId) ?? null;
|
||||
const imapProfiles = useMemo(() => profiles.filter((profile) => profile.is_active && profile.imap), [profiles]);
|
||||
@@ -60,16 +62,16 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
const foldersReady = Boolean(selectedProfileId) && foldersLoadedForProfile === selectedProfileId;
|
||||
const selectedMessageKey = pendingMessageKey || selectedMessageKeyState || (selectedMessage ? mailboxMessageKey(selectedMessage.folder || selectedFolder, selectedMessage.uid) : "");
|
||||
const messageCountLabel = messageListCountLabel(messages.length, messageTotalCount, loadingMessages, foldersReady);
|
||||
const folderEmptyText = folderError || (noImapProfiles ? "No IMAP-enabled mail profiles." : loadingFolders ? "Loading folders..." : "No folders available.");
|
||||
const messageEmptyText = messageError || (!selectedProfileId ? "Select an IMAP profile." : !foldersReady || loadingMessages ? "Loading messages..." : messages.length > 0 && filteredMessages.length === 0 ? "No messages match the current filter on this page." : "No messages in this folder.");
|
||||
const previewEmptyText = detailError || (loadingMessage ? "Loading message..." : "Select a message to inspect its content.");
|
||||
const loadingLabel = loadingProfiles ? "Loading mail profiles..." : loadingFolders ? "Loading folders..." : loadingMessages ? "Loading messages..." : "Loading message...";
|
||||
const folderEmptyText = folderError || (noImapProfiles ? "i18n:govoplan-mail.no_imap_enabled_mail_profiles.61ae44d8" : loadingFolders ? "i18n:govoplan-mail.loading_folders.17f9f0e2" : "i18n:govoplan-mail.no_folders_available.14133b26");
|
||||
const messageEmptyText = messageError || (!selectedProfileId ? "i18n:govoplan-mail.select_an_imap_profile.5445648c" : !foldersReady || loadingMessages ? "i18n:govoplan-mail.loading_messages.77b62232" : messages.length > 0 && filteredMessages.length === 0 ? "i18n:govoplan-mail.no_messages_match_the_current_filter_on_this_pag.9dda6916" : "i18n:govoplan-mail.no_messages_in_this_folder.5c7fa25d");
|
||||
const previewEmptyText = detailError || (loadingMessage ? "i18n:govoplan-mail.loading_message.815c2094" : "i18n:govoplan-mail.select_a_message_to_inspect_its_content.5f3d1342");
|
||||
const loadingLabel = loadingProfiles ? "i18n:govoplan-mail.loading_mail_profiles.87de3560" : loadingFolders ? "i18n:govoplan-mail.loading_folders.17f9f0e2" : loadingMessages ? "i18n:govoplan-mail.loading_messages.77b62232" : "i18n:govoplan-mail.loading_message.815c2094";
|
||||
|
||||
useEffect(() => { void loadProfiles(); }, [settings.apiBaseUrl, settings.apiKey, settings.accessToken]);
|
||||
useEffect(() => { selectedMessageKeyRef.current = selectedMessageKeyState; }, [selectedMessageKeyState]);
|
||||
useEffect(() => { if (messagePage > messagePageCount) setMessagePage(messagePageCount); }, [messagePage, messagePageCount]);
|
||||
useEffect(() => { if (selectedProfileId) void loadFolders(selectedProfileId); }, [selectedProfileId]);
|
||||
useEffect(() => { if (selectedProfileId && selectedFolder && foldersReady) void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize); }, [foldersReady, messagePage, messagePageSize, selectedProfileId, selectedFolder]);
|
||||
useEffect(() => {void loadProfiles();}, [settings.apiBaseUrl, settings.apiKey, settings.accessToken]);
|
||||
useEffect(() => {selectedMessageKeyRef.current = selectedMessageKeyState;}, [selectedMessageKeyState]);
|
||||
useEffect(() => {if (messagePage > messagePageCount) setMessagePage(messagePageCount);}, [messagePage, messagePageCount]);
|
||||
useEffect(() => {if (selectedProfileId) void loadFolders(selectedProfileId);}, [selectedProfileId]);
|
||||
useEffect(() => {if (selectedProfileId && selectedFolder && foldersReady) void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize);}, [foldersReady, messagePage, messagePageSize, selectedProfileId, selectedFolder]);
|
||||
|
||||
useEffect(() => {
|
||||
const handlePreviewShortcut = (event: KeyboardEvent) => {
|
||||
@@ -88,10 +90,10 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
if (shellBusy || loadingMessage || filteredMessages.length === 0) return;
|
||||
const selectedIndex = filteredMessages.findIndex((message) => mailboxMessageKey(message.folder || selectedFolder, message.uid) === selectedMessageKey);
|
||||
let nextIndex: number | null = null;
|
||||
if (event.key === "ArrowLeft") nextIndex = selectedIndex > 0 ? selectedIndex - 1 : 0;
|
||||
else if (event.key === "ArrowRight") nextIndex = selectedIndex >= 0 ? Math.min(filteredMessages.length - 1, selectedIndex + 1) : 0;
|
||||
else if (event.key === "Home") nextIndex = 0;
|
||||
else if (event.key === "End") nextIndex = filteredMessages.length - 1;
|
||||
if (event.key === "ArrowLeft") nextIndex = selectedIndex > 0 ? selectedIndex - 1 : 0;else
|
||||
if (event.key === "ArrowRight") nextIndex = selectedIndex >= 0 ? Math.min(filteredMessages.length - 1, selectedIndex + 1) : 0;else
|
||||
if (event.key === "Home") nextIndex = 0;else
|
||||
if (event.key === "End") nextIndex = filteredMessages.length - 1;
|
||||
if (nextIndex === null) return;
|
||||
event.preventDefault();
|
||||
const nextMessage = filteredMessages[nextIndex];
|
||||
@@ -155,7 +157,7 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
try {
|
||||
const response = await listMailboxFolders(settings, profileId);
|
||||
if (requestId !== folderRequestRef.current) return;
|
||||
if (!response.ok) throw new Error(response.message || "Mailbox folders could not be loaded.");
|
||||
if (!response.ok) throw new Error(response.message || "i18n:govoplan-mail.mailbox_folders_could_not_be_loaded.c3e3880e");
|
||||
const loaded = response.folders?.length ? response.folders : [{ name: "INBOX", flags: [] }];
|
||||
setFolders(loaded);
|
||||
setExpandedFolders(new Set());
|
||||
@@ -185,15 +187,19 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
if (!profileId || !folder) return;
|
||||
const requestId = ++messageListRequestRef.current;
|
||||
const offset = (Math.max(1, page) - 1) * pageSize;
|
||||
const cursorKey = mailboxCursorKey(profileId, folder, pageSize);
|
||||
const cursor = page <= 1 ? null : mailboxPageCursorsRef.current[`${cursorKey}:${page}`] || null;
|
||||
setLoadingMessages(true);
|
||||
setMessageError("");
|
||||
setDetailError("");
|
||||
setError("");
|
||||
try {
|
||||
const response = await listMailboxMessages(settings, profileId, folder, pageSize, offset);
|
||||
const response = await listMailboxMessages(settings, profileId, folder, pageSize, offset, cursor);
|
||||
if (requestId !== messageListRequestRef.current) return;
|
||||
const loaded = response.messages ?? [];
|
||||
const total = response.total_count ?? loaded.length;
|
||||
if (page <= 1) mailboxPageCursorsRef.current[`${cursorKey}:1`] = null;
|
||||
if (response.next_cursor) mailboxPageCursorsRef.current[`${cursorKey}:${page + 1}`] = response.next_cursor;
|
||||
setMessages(loaded);
|
||||
setMessageTotalCount(total);
|
||||
setFolderMessageCount(folder, total);
|
||||
@@ -269,8 +275,8 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
|
||||
function openFolderNode(node: MailFolderNode) {
|
||||
if (node.folderName) {
|
||||
if (node.folderName === selectedFolder && foldersReady) void loadMessages(selectedProfileId, node.folderName, messagePage, messagePageSize);
|
||||
else {
|
||||
if (node.folderName === selectedFolder && foldersReady) void loadMessages(selectedProfileId, node.folderName, messagePage, messagePageSize);else
|
||||
{
|
||||
setSelectedFolder(node.folderName);
|
||||
setMessagePage(1);
|
||||
setSelectedMessage(null);
|
||||
@@ -287,8 +293,8 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
function toggleFolderNode(node: MailFolderNode) {
|
||||
setExpandedFolders((current) => {
|
||||
const next = new Set(current);
|
||||
if (next.has(node.id)) next.delete(node.id);
|
||||
else next.add(node.id);
|
||||
if (next.has(node.id)) next.delete(node.id);else
|
||||
next.add(node.id);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
@@ -312,8 +318,8 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
{error && <DismissibleAlert tone="danger" resetKey={error} floating>{error}</DismissibleAlert>}
|
||||
|
||||
<div className={`file-manager-shell mailbox-shell ${shellBusy ? "is-loading" : ""}`}>
|
||||
<aside className="file-tree-panel" aria-label="Mailbox folders">
|
||||
<div className="file-tree-heading">Folders</div>
|
||||
<aside className="file-tree-panel" aria-label="i18n:govoplan-mail.mailbox_folders.c92f6de4">
|
||||
<div className="file-tree-heading">i18n:govoplan-mail.folders.19adc47b</div>
|
||||
<div className="file-tree-list">
|
||||
{folderTree.length === 0 && <p className="muted small-text mailbox-tree-empty">{folderEmptyText}</p>}
|
||||
<ExplorerTree
|
||||
@@ -336,70 +342,70 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
{showCount && <small className="mailbox-folder-count">{node.messageCount}</small>}
|
||||
</span>
|
||||
{flagText && <small>{flagText}</small>}
|
||||
</span>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</span>);
|
||||
|
||||
}} />
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section className="file-list-panel mailbox-message-list-panel" aria-label="Mailbox messages">
|
||||
<section className="file-list-panel mailbox-message-list-panel" aria-label="i18n:govoplan-mail.mailbox_messages.5c06afaf">
|
||||
<div className="file-list-sticky">
|
||||
<div className="file-manager-toolbar mailbox-toolbar" aria-label="Mail actions">
|
||||
<div className="file-manager-toolbar mailbox-toolbar" aria-label="i18n:govoplan-mail.mail_actions.c08b5f08">
|
||||
<label className="mailbox-profile-field">
|
||||
<span>IMAP profile</span>
|
||||
<span>i18n:govoplan-mail.imap_profile.5165df81</span>
|
||||
<select value={selectedProfileId} disabled={loadingProfiles || loadingFolders || imapProfiles.length === 0} onChange={(event) => selectProfile(event.target.value)}>
|
||||
{imapProfiles.length === 0 && <option value="">No IMAP profiles available</option>}
|
||||
{imapProfiles.length === 0 && <option value="">i18n:govoplan-mail.no_imap_profiles_available.d64589f8</option>}
|
||||
{imapProfiles.map((profile) => <option key={profile.id} value={profile.id}>{profile.name}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
<span className="mailbox-toolbar-meta">{selectedProfile?.imap ? transportLabel(selectedProfile) : "No IMAP profile selected"}</span>
|
||||
<span className="mailbox-toolbar-meta">{selectedProfile?.imap ? transportLabel(selectedProfile) : "i18n:govoplan-mail.no_imap_profile_selected.e7d1516f"}</span>
|
||||
<div className="mailbox-toolbar-actions">
|
||||
<Button onClick={() => void loadProfiles()} disabled={loadingProfiles} title="Reload IMAP profiles">
|
||||
<Button onClick={() => void loadProfiles()} disabled={loadingProfiles} title="i18n:govoplan-mail.reload_imap_profiles.b04c11c8">
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
Profiles
|
||||
i18n:govoplan-mail.profiles.0c2a9300
|
||||
</Button>
|
||||
<Button onClick={() => void loadFolders(selectedProfileId)} disabled={!selectedProfileId || loadingFolders} title="Refresh mailbox folders">
|
||||
<Button onClick={() => void loadFolders(selectedProfileId)} disabled={!selectedProfileId || loadingFolders} title="i18n:govoplan-mail.refresh_mailbox_folders.d9af9963">
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
Folders
|
||||
i18n:govoplan-mail.folders.19adc47b
|
||||
</Button>
|
||||
<Button onClick={() => void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize)} disabled={!selectedProfileId || !selectedFolder || !foldersReady || loadingMessages} title="Refresh messages in the current folder">
|
||||
<Button onClick={() => void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize)} disabled={!selectedProfileId || !selectedFolder || !foldersReady || loadingMessages} title="i18n:govoplan-mail.refresh_messages_in_the_current_folder.b6546a2c">
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
Messages
|
||||
i18n:govoplan-mail.messages.f1702b46
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="file-breadcrumbs" aria-label="Current mailbox folder">
|
||||
<span className="file-breadcrumb mailbox-breadcrumb-static"><Home size={15} aria-hidden="true" /> {selectedProfile?.name || "Mail"}</span>
|
||||
<nav className="file-breadcrumbs" aria-label="i18n:govoplan-mail.current_mailbox_folder.55e2aea5">
|
||||
<span className="file-breadcrumb mailbox-breadcrumb-static"><Home size={15} aria-hidden="true" /> {selectedProfile?.name || "i18n:govoplan-mail.mail.92379cbb"}</span>
|
||||
<span className="file-breadcrumb-segment"><ChevronRight size={14} aria-hidden="true" /><span className="file-breadcrumb mailbox-breadcrumb-static">{selectedFolder}</span></span>
|
||||
</nav>
|
||||
|
||||
<div className="mailbox-filter-row">
|
||||
<label className="mailbox-search-field">
|
||||
<Search size={15} aria-hidden="true" />
|
||||
<input value={messageQuery} onChange={(event) => setMessageQuery(event.target.value)} placeholder="Search messages" />
|
||||
{messageQuery && <button type="button" onClick={() => setMessageQuery("")} aria-label="Clear message search"><X size={14} /></button>}
|
||||
<input value={messageQuery} onChange={(event) => setMessageQuery(event.target.value)} placeholder="i18n:govoplan-mail.search_messages.abea65ae" />
|
||||
{messageQuery && <button type="button" onClick={() => setMessageQuery("")} aria-label="i18n:govoplan-mail.clear_message_search.cc9f2800"><X size={14} /></button>}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="file-list-meta">
|
||||
<span>{messageCountLabel}</span>
|
||||
<span>{selectedFolder}</span>
|
||||
{messageQuery && <span>{filteredMessages.length} match{filteredMessages.length === 1 ? "" : "es"} on page</span>}
|
||||
{shellBusy && <span>Working...</span>}
|
||||
{loadingMessage && <span>Loading preview...</span>}
|
||||
{messageQuery && <span>{filteredMessages.length} match{filteredMessages.length === 1 ? "" : "es"} i18n:govoplan-mail.on_page.ca7166f4</span>}
|
||||
{shellBusy && <span>i18n:govoplan-mail.working.049ac820</span>}
|
||||
{loadingMessage && <span>{i18nMessage("i18n:govoplan-mail.loading_preview.ebd86225")}</span>}
|
||||
</div>
|
||||
|
||||
<div className="file-list-table-head mailbox-message-head" role="row">
|
||||
<span>Subject</span>
|
||||
<span>Date</span>
|
||||
<span>Size</span>
|
||||
<span>i18n:govoplan-mail.subject.8d183dbd</span>
|
||||
<span>i18n:govoplan-mail.date.eb9a4bc1</span>
|
||||
<span>i18n:govoplan-mail.size.b7152342</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="file-list-drop-target mailbox-message-scroll">
|
||||
<div className="file-list-table mailbox-message-table" role="table" aria-label="Mailbox messages">
|
||||
<div className="file-list-table mailbox-message-table" role="table" aria-label="i18n:govoplan-mail.mailbox_messages.5c06afaf">
|
||||
{filteredMessages.length === 0 && <div className={`file-list-empty${messageError ? " mailbox-error-state" : ""}`}>{messageEmptyText}</div>}
|
||||
{filteredMessages.map((message) => {
|
||||
const key = mailboxMessageKey(message.folder || selectedFolder, message.uid);
|
||||
@@ -417,13 +423,13 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
event.preventDefault();
|
||||
void openMessage(message);
|
||||
}
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
|
||||
<div className="file-list-name-cell">
|
||||
<div className="file-list-name">
|
||||
<Mail className="file-row-icon" size={20} aria-hidden="true" />
|
||||
<span>
|
||||
<strong>{message.subject || "(no subject)"}</strong>
|
||||
<strong>{message.subject || "i18n:govoplan-mail.no_subject.49b20da0"}</strong>
|
||||
<small>{message.from_header || "-"}</small>
|
||||
</span>
|
||||
</div>
|
||||
@@ -433,8 +439,8 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
{message.attachment_count ? <span><Paperclip size={14} aria-hidden="true" /> {message.attachment_count}</span> : null}
|
||||
<span>{formatBytes(message.size_bytes)}</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
</div>);
|
||||
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
@@ -444,22 +450,22 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
totalRows={messageTotalCount ?? 0}
|
||||
disabled={loadingMessages || !foldersReady}
|
||||
onPageChange={changeMessagePage}
|
||||
onPageSizeChange={changeMessagePageSize}
|
||||
/>
|
||||
onPageSizeChange={changeMessagePageSize} />
|
||||
|
||||
</section>
|
||||
|
||||
<section className="mailbox-preview-panel" aria-label="Message preview">
|
||||
<div className="file-tree-heading">Preview</div>
|
||||
<section className="mailbox-preview-panel" aria-label="i18n:govoplan-mail.message_preview.58de1450">
|
||||
<div className="file-tree-heading">i18n:govoplan-mail.preview.f1fbb2b4</div>
|
||||
<div className="mailbox-preview-scroll">
|
||||
<MessageDisplayPanel
|
||||
title={selectedMessage?.subject}
|
||||
fields={selectedMessage ? [
|
||||
{ label: "From", value: selectedMessage.from_header || "-" },
|
||||
{ label: "To", value: selectedMessage.to_header || "-" },
|
||||
{ label: "Cc", value: selectedMessage.cc_header || null },
|
||||
{ label: "Bcc", value: selectedMessage.bcc_header || null },
|
||||
{ label: "Date", value: formatDateTime(selectedMessage.date, { fallback: "-" }) }
|
||||
] : []}
|
||||
{ label: "i18n:govoplan-mail.from.3f66052a", value: selectedMessage.from_header || "-" },
|
||||
{ label: "i18n:govoplan-mail.to.ae79ea1e", value: selectedMessage.to_header || "-" },
|
||||
{ label: "i18n:govoplan-mail.cc.1fd6a880", value: selectedMessage.cc_header || null },
|
||||
{ label: "i18n:govoplan-mail.bcc.8431acad", value: selectedMessage.bcc_header || null },
|
||||
{ label: "i18n:govoplan-mail.date.eb9a4bc1", value: formatDateTime(selectedMessage.date, { fallback: "-" }) }] :
|
||||
[]}
|
||||
bodyText={selectedMessage?.body_text}
|
||||
bodyHtml={selectedMessage?.body_html}
|
||||
bodyPreview={selectedMessage?.body_preview}
|
||||
@@ -469,70 +475,74 @@ export default function MailboxPage({ settings }: { settings: ApiSettings }) {
|
||||
contentType: attachment.content_type,
|
||||
sizeBytes: attachment.size_bytes
|
||||
}))}
|
||||
emptyText={previewEmptyText}
|
||||
/>
|
||||
emptyText={previewEmptyText} />
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{shellBusy && (
|
||||
<div className="file-manager-loading-overlay" aria-live="polite" aria-busy="true">
|
||||
<div className="loading-frame-panel"><LoadingIndicator label={loadingLabel} /> <span>{loadingLabel}</span></div>
|
||||
{shellBusy &&
|
||||
<div className="file-manager-loading-overlay" aria-live="polite" aria-busy="true">
|
||||
<div className="loading-frame-panel"><LoadingIndicator label={loadingLabel} /> <span>{i18nMessage(loadingLabel)}</span></div>
|
||||
</div>
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</div>);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function MailboxPagination({ page, pageSize, totalRows, disabled, onPageChange, onPageSizeChange }: { page: number; pageSize: number; totalRows: number; disabled: boolean; onPageChange: (page: number) => void; onPageSizeChange: (pageSize: number) => void }) {
|
||||
function MailboxPagination({ page, pageSize, totalRows, disabled, onPageChange, onPageSizeChange }: {page: number;pageSize: number;totalRows: number;disabled: boolean;onPageChange: (page: number) => void;onPageSizeChange: (pageSize: number) => void;}) {
|
||||
const pageCount = Math.max(1, Math.ceil(totalRows / pageSize));
|
||||
const first = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
||||
const last = Math.min(totalRows, page * pageSize);
|
||||
const options = [10, 25, 50, 100];
|
||||
return (
|
||||
<div className="data-grid-pagination mailbox-pagination" aria-label="Mailbox message pagination">
|
||||
<div className="data-grid-pagination mailbox-pagination" aria-label="i18n:govoplan-mail.mailbox_message_pagination.965407bf">
|
||||
<div className="data-grid-pagination-summary">{first}-{last} of {totalRows}</div>
|
||||
<label className="data-grid-page-size">
|
||||
<span>Rows per page</span>
|
||||
<span>i18n:govoplan-mail.rows_per_page.af2f9c1b</span>
|
||||
<select value={pageSize} disabled={disabled} onChange={(event) => onPageSizeChange(Number(event.target.value))}>
|
||||
{options.map((value) => <option key={value} value={value}>{value}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
<div className="data-grid-page-controls">
|
||||
<button type="button" aria-label="First page" disabled={disabled || page <= 1} onClick={() => onPageChange(1)}><ChevronsLeft size={16} /></button>
|
||||
<button type="button" aria-label="Previous page" disabled={disabled || page <= 1} onClick={() => onPageChange(page - 1)}><ChevronLeft size={16} /></button>
|
||||
<span>Page {page} of {pageCount}</span>
|
||||
<button type="button" aria-label="Next page" disabled={disabled || page >= pageCount} onClick={() => onPageChange(page + 1)}><ChevronRight size={16} /></button>
|
||||
<button type="button" aria-label="Last page" disabled={disabled || page >= pageCount} onClick={() => onPageChange(pageCount)}><ChevronsRight size={16} /></button>
|
||||
<button type="button" aria-label="i18n:govoplan-mail.first_page.49d74b49" disabled={disabled || page <= 1} onClick={() => onPageChange(1)}><ChevronsLeft size={16} /></button>
|
||||
<button type="button" aria-label="i18n:govoplan-mail.previous_page.81f54719" disabled={disabled || page <= 1} onClick={() => onPageChange(page - 1)}><ChevronLeft size={16} /></button>
|
||||
<span>i18n:govoplan-mail.page.fb06270f {page} of {pageCount}</span>
|
||||
<button type="button" aria-label="i18n:govoplan-mail.next_page.4bfc194b" disabled={disabled || page >= pageCount} onClick={() => onPageChange(page + 1)}><ChevronRight size={16} /></button>
|
||||
<button type="button" aria-label="i18n:govoplan-mail.last_page.b01f16ae" disabled={disabled || page >= pageCount} onClick={() => onPageChange(pageCount)}><ChevronsRight size={16} /></button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</div>);
|
||||
|
||||
}
|
||||
|
||||
function mailboxMessageKey(folder: string, uid: string): string {
|
||||
return `${folder || "INBOX"}::${uid}`;
|
||||
}
|
||||
|
||||
function mailboxCursorKey(profileId: string, folder: string, pageSize: number): string {
|
||||
return `${profileId}::${folder || "INBOX"}::${pageSize}`;
|
||||
}
|
||||
|
||||
function filterMessages(messages: MailMailboxMessageSummary[], query: string): MailMailboxMessageSummary[] {
|
||||
const normalized = query.trim().toLocaleLowerCase();
|
||||
if (!normalized) return messages;
|
||||
return messages.filter((message) => [
|
||||
message.subject,
|
||||
message.from_header,
|
||||
message.to_header,
|
||||
message.cc_header,
|
||||
message.date,
|
||||
message.body_preview
|
||||
].some((value) => String(value ?? "").toLocaleLowerCase().includes(normalized)));
|
||||
message.subject,
|
||||
message.from_header,
|
||||
message.to_header,
|
||||
message.cc_header,
|
||||
message.date,
|
||||
message.body_preview].
|
||||
some((value) => String(value ?? "").toLocaleLowerCase().includes(normalized)));
|
||||
}
|
||||
|
||||
function messageListCountLabel(visibleCount: number, totalCount: number | null, loading: boolean, ready: boolean): string {
|
||||
if (!ready) return "No folder loaded";
|
||||
if (loading) return "Loading messages";
|
||||
if (totalCount !== null && totalCount > visibleCount) return `${visibleCount} of ${totalCount} messages`;
|
||||
if (!ready) return "i18n:govoplan-mail.no_folder_loaded.889bdb1b";
|
||||
if (loading) return "i18n:govoplan-mail.loading_messages.4294022c";
|
||||
if (totalCount !== null && totalCount > visibleCount) return i18nMessage("i18n:govoplan-mail.value_of_value_messages.981a1618", { value0: visibleCount, value1: totalCount });
|
||||
const count = totalCount ?? visibleCount;
|
||||
return `${count} message${count === 1 ? "" : "s"}`;
|
||||
return i18nMessage(count === 1 ? "i18n:govoplan-mail.value_message" : "i18n:govoplan-mail.value_messages", { value0: count });
|
||||
}
|
||||
|
||||
function folderFlagLabel(flags: string[]): string {
|
||||
@@ -544,17 +554,17 @@ function displayFolderFlag(flag: string): string | null {
|
||||
const normalized = flag.replace(/^\\/, "").toLowerCase();
|
||||
switch (normalized) {
|
||||
case "sent":
|
||||
return "Sent";
|
||||
return "i18n:govoplan-mail.sent.35f49dcf";
|
||||
case "drafts":
|
||||
return "Drafts";
|
||||
return "i18n:govoplan-mail.drafts.22a31d86";
|
||||
case "trash":
|
||||
return "Trash";
|
||||
return "i18n:govoplan-mail.trash.e3bf62bb";
|
||||
case "archive":
|
||||
return "Archive";
|
||||
return "i18n:govoplan-mail.archive.2621c6fd";
|
||||
case "junk":
|
||||
return "Junk";
|
||||
return "i18n:govoplan-mail.junk.86c7d94c";
|
||||
case "flagged":
|
||||
return "Flagged";
|
||||
return "i18n:govoplan-mail.flagged.f8db8a17";
|
||||
case "haschildren":
|
||||
case "hasnochildren":
|
||||
case "noselect":
|
||||
@@ -566,15 +576,15 @@ function displayFolderFlag(flag: string): string | null {
|
||||
|
||||
function transportLabel(profile: MailServerProfile): string {
|
||||
const imap = profile.imap;
|
||||
if (!imap?.host) return "IMAP not configured";
|
||||
if (!imap?.host) return "i18n:govoplan-mail.imap_not_configured.b2892af3";
|
||||
return `${imap.host}:${imap.port ?? "?"} ${imap.security ?? ""}`.trim();
|
||||
}
|
||||
|
||||
function formatBytes(value?: number | null): string {
|
||||
if (!value) return "-";
|
||||
if (value < 1024) return `${value} B`;
|
||||
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`;
|
||||
return `${(value / 1024 / 1024).toFixed(1)} MB`;
|
||||
if (value < 1024) return i18nMessage("i18n:govoplan-mail.bytes_b", { value0: value });
|
||||
if (value < 1024 * 1024) return i18nMessage("i18n:govoplan-mail.bytes_kb", { value0: (value / 1024).toFixed(1) });
|
||||
return i18nMessage("i18n:govoplan-mail.bytes_mb", { value0: (value / 1024 / 1024).toFixed(1) });
|
||||
}
|
||||
|
||||
function errorText(error: unknown): string {
|
||||
|
||||
@@ -22,11 +22,11 @@ export type MailPolicyValidationMessage = {
|
||||
};
|
||||
|
||||
const patternLabels: Record<MailProfilePatternKey, string> = {
|
||||
smtp_hosts: "SMTP host",
|
||||
imap_hosts: "IMAP host",
|
||||
envelope_senders: "Envelope sender",
|
||||
from_headers: "From header",
|
||||
recipient_domains: "Recipient domain"
|
||||
smtp_hosts: "i18n:govoplan-mail.smtp_host.2d4a434b",
|
||||
imap_hosts: "i18n:govoplan-mail.imap_host.b53c3751",
|
||||
envelope_senders: "i18n:govoplan-mail.envelope_sender.5ec276a0",
|
||||
from_headers: "i18n:govoplan-mail.from_header.bb78e85d",
|
||||
recipient_domains: "i18n:govoplan-mail.recipient_domain.778f2dcf"
|
||||
};
|
||||
|
||||
type ValueCheck = {
|
||||
@@ -35,19 +35,19 @@ type ValueCheck = {
|
||||
};
|
||||
|
||||
export function validateMailPolicy(
|
||||
policy: MailProfilePolicy | null | undefined,
|
||||
input: MailPolicyValidationInput,
|
||||
): MailPolicyValidationMessage[] {
|
||||
policy: MailProfilePolicy | null | undefined,
|
||||
input: MailPolicyValidationInput)
|
||||
: MailPolicyValidationMessage[] {
|
||||
if (!policy) return [];
|
||||
|
||||
const checks: ValueCheck[] = [
|
||||
{ key: "smtp_hosts", value: input.smtpHost ?? "" },
|
||||
{ key: "imap_hosts", value: input.imapHost ?? "" },
|
||||
{ key: "envelope_senders", value: input.envelopeSender ?? "" },
|
||||
{ key: "from_headers", value: input.fromHeader ?? "" },
|
||||
...Array.from(new Set((input.recipientDomains ?? []).map(normalizeDomain).filter(Boolean)))
|
||||
.map((value) => ({ key: "recipient_domains" as const, value }))
|
||||
];
|
||||
{ key: "smtp_hosts", value: input.smtpHost ?? "" },
|
||||
{ key: "imap_hosts", value: input.imapHost ?? "" },
|
||||
{ key: "envelope_senders", value: input.envelopeSender ?? "" },
|
||||
{ key: "from_headers", value: input.fromHeader ?? "" },
|
||||
...Array.from(new Set((input.recipientDomains ?? []).map(normalizeDomain).filter(Boolean))).
|
||||
map((value) => ({ key: "recipient_domains" as const, value }))];
|
||||
|
||||
|
||||
return checks.flatMap(({ key, value }) => {
|
||||
const result = mailPolicyValueAllowed(policy, key, value);
|
||||
@@ -58,18 +58,18 @@ export function validateMailPolicy(
|
||||
label,
|
||||
value: result.value,
|
||||
severity: "danger" as const,
|
||||
message: result.reason === "blacklist"
|
||||
? `${label} ${result.value} is denied by pattern ${result.pattern}.`
|
||||
: `${label} ${result.value} is outside the effective allow-list.`
|
||||
message: result.reason === "blacklist" ?
|
||||
`${label} ${result.value} is denied by pattern ${result.pattern}.` :
|
||||
`${label} ${result.value} is outside the effective allow-list.`
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
export function mailPolicyValueAllowed(
|
||||
policy: MailProfilePolicy | null | undefined,
|
||||
key: MailProfilePatternKey,
|
||||
rawValue: string | null | undefined,
|
||||
): { allowed: true; value: string } | { allowed: false; value: string; reason: "blacklist" | "whitelist"; pattern?: string } {
|
||||
policy: MailProfilePolicy | null | undefined,
|
||||
key: MailProfilePatternKey,
|
||||
rawValue: string | null | undefined)
|
||||
: {allowed: true;value: string;} | {allowed: false;value: string;reason: "blacklist" | "whitelist";pattern?: string;} {
|
||||
const value = normalizePolicyValue(key, rawValue);
|
||||
if (!value || !policy) return { allowed: true, value };
|
||||
|
||||
@@ -95,9 +95,9 @@ export function wildcardPatternMatches(pattern: string, rawValue: string): boole
|
||||
}
|
||||
|
||||
function patternsFor(
|
||||
rules: MailProfilePolicy["whitelist"] | MailProfilePolicy["blacklist"],
|
||||
key: MailProfilePatternKey,
|
||||
): string[] {
|
||||
rules: MailProfilePolicy["whitelist"] | MailProfilePolicy["blacklist"],
|
||||
key: MailProfilePatternKey)
|
||||
: string[] {
|
||||
return (rules?.[key] ?? []).map((pattern) => String(pattern).trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
@@ -117,4 +117,4 @@ function normalizeDomain(value: string | null | undefined): string {
|
||||
if (!trimmed) return "";
|
||||
const emailDomain = trimmed.includes("@") ? trimmed.split("@").pop() ?? "" : trimmed;
|
||||
return emailDomain.replace(/^@+/, "");
|
||||
}
|
||||
}
|
||||
398
webui/src/i18n/generatedTranslations.ts
Normal file
398
webui/src/i18n/generatedTranslations.ts
Normal file
@@ -0,0 +1,398 @@
|
||||
import type { PlatformTranslations } from "@govoplan/core-webui";
|
||||
|
||||
export const generatedTranslations: PlatformTranslations = {
|
||||
"en": {
|
||||
"i18n:govoplan-mail.active.a733b809": "Active",
|
||||
"i18n:govoplan-mail.allow_override.ffa6e9a0": "Allow override",
|
||||
"i18n:govoplan-mail.allow.3ad0e369": "Allow",
|
||||
"i18n:govoplan-mail.allowed_profiles_and_wildcard_rules_for_this_sco.0f82b3e4": "Allowed profiles and wildcard rules for this scope.",
|
||||
"i18n:govoplan-mail.allowed.77c7b490": "Allowed",
|
||||
"i18n:govoplan-mail.an_ancestor_allow_list_limits_selectable_profile.499ec179": "An ancestor allow-list limits selectable profiles to",
|
||||
"i18n:govoplan-mail.archive.2621c6fd": "Archive",
|
||||
"i18n:govoplan-mail.bcc.8431acad": "Bcc",
|
||||
"i18n:govoplan-mail.because_an_ancestor_policy_blocks_those_definiti.5de3e30d": "because an ancestor policy blocks those definitions.",
|
||||
"i18n:govoplan-mail.blacklist_value.556334d0": "blacklist.{value0}",
|
||||
"i18n:govoplan-mail.blacklist.7b2dd04c": "Blacklist",
|
||||
"i18n:govoplan-mail.blocked.99613c74": "Blocked",
|
||||
"i18n:govoplan-mail.bytes_b": "{value0} B",
|
||||
"i18n:govoplan-mail.bytes_kb": "{value0} KB",
|
||||
"i18n:govoplan-mail.bytes_mb": "{value0} MB",
|
||||
"i18n:govoplan-mail.campaign_local_settings.920ecb62": "campaign-local settings",
|
||||
"i18n:govoplan-mail.campaign_local_settings.eb0f1061": "Campaign-local settings",
|
||||
"i18n:govoplan-mail.campaigns": "Campaigns",
|
||||
"i18n:govoplan-mail.campaign.69390e16": "Campaign",
|
||||
"i18n:govoplan-mail.cancel.77dfd213": "Cancel",
|
||||
"i18n:govoplan-mail.cc.1fd6a880": "Cc",
|
||||
"i18n:govoplan-mail.clear_allow_list.f69c8c67": "Clear allow-list",
|
||||
"i18n:govoplan-mail.clear_message_search.cc9f2800": "Clear message search",
|
||||
"i18n:govoplan-mail.controls_whether_campaigns_may_use_inline_smtp_i.fa45cbbc": "Controls whether campaigns may use inline SMTP/IMAP settings instead of reusable profiles.",
|
||||
"i18n:govoplan-mail.controls_whether_group_scoped_mail_profiles_may_.0b832ea4": "Controls whether group-scoped mail profiles may be defined below this scope.",
|
||||
"i18n:govoplan-mail.controls_whether_user_scoped_mail_profiles_may_b.00c0e0e7": "Controls whether user-scoped mail profiles may be defined below this scope.",
|
||||
"i18n:govoplan-mail.create_mail_profile.4d2f8f9f": "Create mail profile",
|
||||
"i18n:govoplan-mail.credential_inheritance_is_locked_by_an_ancestor_.1ee5d263": "credential inheritance is locked by an ancestor policy.",
|
||||
"i18n:govoplan-mail.credential_inheritance.ec8d7191": "Credential inheritance",
|
||||
"i18n:govoplan-mail.current_mailbox_folder.55e2aea5": "Current mailbox folder",
|
||||
"i18n:govoplan-mail.date.eb9a4bc1": "Date",
|
||||
"i18n:govoplan-mail.deactivate_mail_profile.0e0fd0b8": "Deactivate mail profile",
|
||||
"i18n:govoplan-mail.deactivate_value_campaign_drafts_using_it_will_n.656f1b9e": "Deactivate {value0}? Campaign drafts using it will need another allowed profile before sending.",
|
||||
"i18n:govoplan-mail.deactivate_value.a276a667": "Deactivate {value0}",
|
||||
"i18n:govoplan-mail.deactivate.d65ded94": "Deactivate",
|
||||
"i18n:govoplan-mail.decides_whether_lower_scopes_inherit_saved_imap_.ac607ee3": "Decides whether lower scopes inherit saved IMAP credentials from a selected profile or must provide local IMAP credentials.",
|
||||
"i18n:govoplan-mail.decides_whether_lower_scopes_inherit_saved_smtp_.93f1c4d0": "Decides whether lower scopes inherit saved SMTP credentials from a selected profile or must provide local SMTP credentials.",
|
||||
"i18n:govoplan-mail.deny.53577bb5": "Deny",
|
||||
"i18n:govoplan-mail.description.55f8ebc8": "Description",
|
||||
"i18n:govoplan-mail.development_mock_mailbox.1a379865": "Development mock mailbox",
|
||||
"i18n:govoplan-mail.drafts.22a31d86": "Drafts",
|
||||
"i18n:govoplan-mail.edit_mail_profile.95d1af9c": "Edit mail profile",
|
||||
"i18n:govoplan-mail.edit_value_credentials.1e2dc4f6": "Edit {value0} credentials",
|
||||
"i18n:govoplan-mail.edit_value.fad75899": "Edit {value0}",
|
||||
"i18n:govoplan-mail.effective_mail_policy_blocks_the_current_profile.1b555820": "Effective mail policy blocks the current profile values.",
|
||||
"i18n:govoplan-mail.effective_policy.feedb950": "Effective policy",
|
||||
"i18n:govoplan-mail.effective_values_are_shown_in_the_table_rows_abo.b27b900d": "Effective values are shown in the table rows above.",
|
||||
"i18n:govoplan-mail.envelope_sender.5ec276a0": "Envelope sender",
|
||||
"i18n:govoplan-mail.envelope_senders.269065cd": "Envelope senders",
|
||||
"i18n:govoplan-mail.explicit_allow_is_unavailable_for.8d05fd4a": "Explicit allow is unavailable for",
|
||||
"i18n:govoplan-mail.explicit_allow.6a7946f8": "Explicit allow",
|
||||
"i18n:govoplan-mail.first_page.49d74b49": "First page",
|
||||
"i18n:govoplan-mail.flagged.f8db8a17": "Flagged",
|
||||
"i18n:govoplan-mail.folders.19adc47b": "Folders",
|
||||
"i18n:govoplan-mail.from_header.bb78e85d": "From header",
|
||||
"i18n:govoplan-mail.from_headers.b3ea473b": "From headers",
|
||||
"i18n:govoplan-mail.from.3f66052a": "From",
|
||||
"i18n:govoplan-mail.generated_from_name.33d69a91": "Generated from name",
|
||||
"i18n:govoplan-mail.group_profiles.74568838": "Group profiles",
|
||||
"i18n:govoplan-mail.group.171a0606": "Group",
|
||||
"i18n:govoplan-mail.groups": "Groups",
|
||||
"i18n:govoplan-mail.imap_credentials.da847469": "IMAP credentials",
|
||||
"i18n:govoplan-mail.imap_host.b53c3751": "IMAP host",
|
||||
"i18n:govoplan-mail.imap_hostnames.ac9c1d78": "IMAP hostnames",
|
||||
"i18n:govoplan-mail.imap_not_configured.b2892af3": "IMAP not configured",
|
||||
"i18n:govoplan-mail.imap_profile.5165df81": "IMAP profile",
|
||||
"i18n:govoplan-mail.imap_server_host_patterns.52b20b83": "IMAP server host patterns.",
|
||||
"i18n:govoplan-mail.imap.271f9ef2": "IMAP",
|
||||
"i18n:govoplan-mail.inactive.09af574c": "Inactive",
|
||||
"i18n:govoplan-mail.inherit_parent_decision.42125bda": "Inherit parent decision",
|
||||
"i18n:govoplan-mail.inherit_profile_credentials.0034bac0": "Inherit profile credentials",
|
||||
"i18n:govoplan-mail.inherit.18f99833": "Inherit",
|
||||
"i18n:govoplan-mail.junk.86c7d94c": "Junk",
|
||||
"i18n:govoplan-mail.last_page.b01f16ae": "Last page",
|
||||
"i18n:govoplan-mail.loading_folders.17f9f0e2": "Loading folders...",
|
||||
"i18n:govoplan-mail.loading_mail_profile_policy.b746a2e8": "Loading mail profile policy...",
|
||||
"i18n:govoplan-mail.loading_mail_profiles.87de3560": "Loading mail profiles...",
|
||||
"i18n:govoplan-mail.loading_message.815c2094": "Loading message...",
|
||||
"i18n:govoplan-mail.loading_messages.4294022c": "Loading messages",
|
||||
"i18n:govoplan-mail.loading_messages.77b62232": "Loading messages...",
|
||||
"i18n:govoplan-mail.loading_preview.ebd86225": "Loading preview...",
|
||||
"i18n:govoplan-mail.loading.33ce4174": "Loading…",
|
||||
"i18n:govoplan-mail.loading.b04ba49f": "Loading...",
|
||||
"i18n:govoplan-mail.local_required.1f5f4aba": "Local required",
|
||||
"i18n:govoplan-mail.local_setting.967607a9": "Local setting",
|
||||
"i18n:govoplan-mail.local.dc99d54d": "Local",
|
||||
"i18n:govoplan-mail.lower_level_mail_definitions.d39a0a1d": "Lower-level mail definitions",
|
||||
"i18n:govoplan-mail.lower_levels.940821ee": "Lower levels",
|
||||
"i18n:govoplan-mail.mail_actions.c08b5f08": "Mail actions",
|
||||
"i18n:govoplan-mail.mail_profile_policy_saved.666847bf": "Mail profile policy saved.",
|
||||
"i18n:govoplan-mail.mail_profile_policy.f2ac4b92": "Mail profile policy",
|
||||
"i18n:govoplan-mail.mail_server_profiles.b1726682": "Mail server profiles",
|
||||
"i18n:govoplan-mail.mail.92379cbb": "Mail",
|
||||
"i18n:govoplan-mail.mailbox_folders_could_not_be_loaded.c3e3880e": "Mailbox folders could not be loaded.",
|
||||
"i18n:govoplan-mail.mailbox_folders.c92f6de4": "Mailbox folders",
|
||||
"i18n:govoplan-mail.mailbox_message_pagination.965407bf": "Mailbox message pagination",
|
||||
"i18n:govoplan-mail.mailbox_messages.5c06afaf": "Mailbox messages",
|
||||
"i18n:govoplan-mail.message_preview.58de1450": "Message preview",
|
||||
"i18n:govoplan-mail.messages.f1702b46": "Messages",
|
||||
"i18n:govoplan-mail.name.709a2322": "Name",
|
||||
"i18n:govoplan-mail.new_profile.ca36da25": "New profile",
|
||||
"i18n:govoplan-mail.next_page.4bfc194b": "Next page",
|
||||
"i18n:govoplan-mail.no_explicit_intersection.f2d62c71": "No explicit intersection",
|
||||
"i18n:govoplan-mail.no_folder_loaded.889bdb1b": "No folder loaded",
|
||||
"i18n:govoplan-mail.no_folders_available.14133b26": "No folders available.",
|
||||
"i18n:govoplan-mail.no_host.4c710d7d": "No host",
|
||||
"i18n:govoplan-mail.no_imap_enabled_mail_profiles.61ae44d8": "No IMAP-enabled mail profiles.",
|
||||
"i18n:govoplan-mail.no_imap_profile_selected.e7d1516f": "No IMAP profile selected",
|
||||
"i18n:govoplan-mail.no_imap_profiles_available.d64589f8": "No IMAP profiles available",
|
||||
"i18n:govoplan-mail.no_value_available": "No {value0} available.",
|
||||
"i18n:govoplan-mail.no_local_profile_allow_list_is_set.31072e39": "No local profile allow-list is set.",
|
||||
"i18n:govoplan-mail.no_messages_in_this_folder.5c7fa25d": "No messages in this folder.",
|
||||
"i18n:govoplan-mail.no_messages_match_the_current_filter_on_this_pag.9dda6916": "No messages match the current filter on this page.",
|
||||
"i18n:govoplan-mail.no_profiles_are_visible_for_this_policy_scope.1ec7bd85": "No profiles are visible for this policy scope.",
|
||||
"i18n:govoplan-mail.no_profiles_in_this_scope.302b21d8": "No profiles in this scope.",
|
||||
"i18n:govoplan-mail.no_saved_password.32ce2b16": "No saved password",
|
||||
"i18n:govoplan-mail.no_subject.49b20da0": "(no subject)",
|
||||
"i18n:govoplan-mail.no_username.1c182624": "No username",
|
||||
"i18n:govoplan-mail.not_configured.67f2141f": "not configured",
|
||||
"i18n:govoplan-mail.not_configured.811931bb": "Not configured",
|
||||
"i18n:govoplan-mail.on_page.ca7166f4": "on page",
|
||||
"i18n:govoplan-mail.owner_policy.1e8df143": "Owner policy",
|
||||
"i18n:govoplan-mail.page.fb06270f": "Page",
|
||||
"i18n:govoplan-mail.password_saved.f6fab237": "Password saved",
|
||||
"i18n:govoplan-mail.password.8be3c943": "Password",
|
||||
"i18n:govoplan-mail.policy_path.1ba91ee5": "Policy path",
|
||||
"i18n:govoplan-mail.policy_target.a19dcee9": "Policy target",
|
||||
"i18n:govoplan-mail.policy.bb9cf141": "Policy",
|
||||
"i18n:govoplan-mail.preview.f1fbb2b4": "Preview",
|
||||
"i18n:govoplan-mail.previous_page.81f54719": "Previous page",
|
||||
"i18n:govoplan-mail.profile_allow_list.507dfe6c": "Profile allow-list",
|
||||
"i18n:govoplan-mail.profile_inherited.ea25d2e1": "Profile inherited",
|
||||
"i18n:govoplan-mail.profile_s.742e9200": "profile(s).",
|
||||
"i18n:govoplan-mail.profile_value_created.2a088d8d": "Profile {value0} created.",
|
||||
"i18n:govoplan-mail.profile_value_deactivated.fa7fcc1a": "Profile {value0} deactivated.",
|
||||
"i18n:govoplan-mail.profile_value_updated.fdbad0ea": "Profile {value0} updated.",
|
||||
"i18n:govoplan-mail.profiles.0c2a9300": "Profiles",
|
||||
"i18n:govoplan-mail.recipient_domain_patterns.68466f5b": "Recipient domain patterns.",
|
||||
"i18n:govoplan-mail.recipient_domain.778f2dcf": "Recipient domain",
|
||||
"i18n:govoplan-mail.recipient_domains.cb9b7b44": "Recipient domains",
|
||||
"i18n:govoplan-mail.refresh_mailbox_folders.d9af9963": "Refresh mailbox folders",
|
||||
"i18n:govoplan-mail.refresh_messages_in_the_current_folder.b6546a2c": "Refresh messages in the current folder",
|
||||
"i18n:govoplan-mail.reload_imap_profiles.b04c11c8": "Reload IMAP profiles",
|
||||
"i18n:govoplan-mail.reload.cce71553": "Reload",
|
||||
"i18n:govoplan-mail.require_local_credentials.da7b1d7c": "Require local credentials",
|
||||
"i18n:govoplan-mail.rows_per_page.af2f9c1b": "Rows per page",
|
||||
"i18n:govoplan-mail.save_policy.77d67ce3": "Save policy",
|
||||
"i18n:govoplan-mail.save_profile.f597c0e8": "Save profile",
|
||||
"i18n:govoplan-mail.saved.c0ae8f6e": "Saved",
|
||||
"i18n:govoplan-mail.saving.56a2285c": "Saving…",
|
||||
"i18n:govoplan-mail.search_messages.abea65ae": "Search messages",
|
||||
"i18n:govoplan-mail.select_a_message_to_inspect_its_content.5f3d1342": "Select a message to inspect its content.",
|
||||
"i18n:govoplan-mail.select_an_imap_profile.5445648c": "Select an IMAP profile.",
|
||||
"i18n:govoplan-mail.sent.35f49dcf": "Sent",
|
||||
"i18n:govoplan-mail.server_credential.7fb9a24e": "Server / credential",
|
||||
"i18n:govoplan-mail.size.b7152342": "Size",
|
||||
"i18n:govoplan-mail.slug.094da9b9": "Slug",
|
||||
"i18n:govoplan-mail.smtp_credentials.f73ef315": "SMTP credentials",
|
||||
"i18n:govoplan-mail.smtp_envelope_sender_patterns.8c1fd95e": "SMTP envelope sender patterns.",
|
||||
"i18n:govoplan-mail.smtp_host.2d4a434b": "SMTP host",
|
||||
"i18n:govoplan-mail.smtp_hostnames.36eb51d8": "SMTP hostnames",
|
||||
"i18n:govoplan-mail.smtp_server_host_patterns.cf6120c3": "SMTP server host patterns.",
|
||||
"i18n:govoplan-mail.smtp.efff9cca": "SMTP",
|
||||
"i18n:govoplan-mail.status.bae7d5be": "Status",
|
||||
"i18n:govoplan-mail.subject.8d183dbd": "Subject",
|
||||
"i18n:govoplan-mail.system_allow.ed6744b1": "System: Allow",
|
||||
"i18n:govoplan-mail.system_profile_inherited.f4b8b5ce": "System: Profile inherited",
|
||||
"i18n:govoplan-mail.system.bc0792d8": "System",
|
||||
"i18n:govoplan-mail.target.61ad50a9": "Target",
|
||||
"i18n:govoplan-mail.tenant.3ca93c78": "Tenant",
|
||||
"i18n:govoplan-mail.test_imap.ef1bd79c": "Test IMAP",
|
||||
"i18n:govoplan-mail.test_saved_imap.923dbe4a": "Test saved IMAP",
|
||||
"i18n:govoplan-mail.test_saved_smtp.008d8054": "Test saved SMTP",
|
||||
"i18n:govoplan-mail.test_smtp.e5697981": "Test SMTP",
|
||||
"i18n:govoplan-mail.this_profile.5fd9cdf1": "this profile",
|
||||
"i18n:govoplan-mail.to.ae79ea1e": "To",
|
||||
"i18n:govoplan-mail.transport.c10d76c9": "Transport",
|
||||
"i18n:govoplan-mail.trash.e3bf62bb": "Trash",
|
||||
"i18n:govoplan-mail.user_profiles.57730285": "User profiles",
|
||||
"i18n:govoplan-mail.user.9f8a2389": "User",
|
||||
"i18n:govoplan-mail.users": "Users",
|
||||
"i18n:govoplan-mail.value_message": "{value0} message",
|
||||
"i18n:govoplan-mail.value_messages": "{value0} messages",
|
||||
"i18n:govoplan-mail.value_of_value_messages.981a1618": "{value0} of {value1} messages",
|
||||
"i18n:govoplan-mail.value_profile_s_allowed_by_this_scope.6fe9ba44": "{value0} profile(s) allowed by this scope.",
|
||||
"i18n:govoplan-mail.value_profile_s.d6b9d0af": "{value0} profile(s)",
|
||||
"i18n:govoplan-mail.value_value.c189e8bc": "{value0} ({value1})",
|
||||
"i18n:govoplan-mail.value.48afe802": "· {value0}",
|
||||
"i18n:govoplan-mail.value.8dce170d": "Value",
|
||||
"i18n:govoplan-mail.value_scope": "{value0} scope",
|
||||
"i18n:govoplan-mail.visible_from_header_patterns.ea77d99d": "Visible From header patterns.",
|
||||
"i18n:govoplan-mail.whitelist_value.d4cc3755": "whitelist.{value0}",
|
||||
"i18n:govoplan-mail.whitelist.53c2ad30": "Whitelist",
|
||||
"i18n:govoplan-mail.wildcard_rules.54fb3fc0": "Wildcard rules",
|
||||
"i18n:govoplan-mail.working.049ac820": "Working..."
|
||||
},
|
||||
"de": {
|
||||
"i18n:govoplan-mail.active.a733b809": "Aktiv",
|
||||
"i18n:govoplan-mail.allow_override.ffa6e9a0": "Allow override",
|
||||
"i18n:govoplan-mail.allow.3ad0e369": "Allow",
|
||||
"i18n:govoplan-mail.allowed_profiles_and_wildcard_rules_for_this_sco.0f82b3e4": "Allowed profiles and wildcard rules for this scope.",
|
||||
"i18n:govoplan-mail.allowed.77c7b490": "Allowed",
|
||||
"i18n:govoplan-mail.an_ancestor_allow_list_limits_selectable_profile.499ec179": "An ancestor allow-list limits selectable profiles to",
|
||||
"i18n:govoplan-mail.archive.2621c6fd": "Archive",
|
||||
"i18n:govoplan-mail.bcc.8431acad": "Bcc",
|
||||
"i18n:govoplan-mail.because_an_ancestor_policy_blocks_those_definiti.5de3e30d": "because an ancestor policy blocks those definitions.",
|
||||
"i18n:govoplan-mail.blacklist_value.556334d0": "blacklist.{value0}",
|
||||
"i18n:govoplan-mail.blacklist.7b2dd04c": "Blacklist",
|
||||
"i18n:govoplan-mail.blocked.99613c74": "Blocked",
|
||||
"i18n:govoplan-mail.bytes_b": "{value0} B",
|
||||
"i18n:govoplan-mail.bytes_kb": "{value0} KB",
|
||||
"i18n:govoplan-mail.bytes_mb": "{value0} MB",
|
||||
"i18n:govoplan-mail.campaign_local_settings.920ecb62": "campaign-local settings",
|
||||
"i18n:govoplan-mail.campaign_local_settings.eb0f1061": "Campaign-local settings",
|
||||
"i18n:govoplan-mail.campaigns": "Kampagnen",
|
||||
"i18n:govoplan-mail.campaign.69390e16": "Campaign",
|
||||
"i18n:govoplan-mail.cancel.77dfd213": "Abbrechen",
|
||||
"i18n:govoplan-mail.cc.1fd6a880": "Cc",
|
||||
"i18n:govoplan-mail.clear_allow_list.f69c8c67": "Clear allow-list",
|
||||
"i18n:govoplan-mail.clear_message_search.cc9f2800": "Clear message search",
|
||||
"i18n:govoplan-mail.controls_whether_campaigns_may_use_inline_smtp_i.fa45cbbc": "Controls whether campaigns may use inline SMTP/IMAP settings instead of reusable profiles.",
|
||||
"i18n:govoplan-mail.controls_whether_group_scoped_mail_profiles_may_.0b832ea4": "Controls whether group-scoped mail profiles may be defined below this scope.",
|
||||
"i18n:govoplan-mail.controls_whether_user_scoped_mail_profiles_may_b.00c0e0e7": "Controls whether user-scoped mail profiles may be defined below this scope.",
|
||||
"i18n:govoplan-mail.create_mail_profile.4d2f8f9f": "Create mail profile",
|
||||
"i18n:govoplan-mail.credential_inheritance_is_locked_by_an_ancestor_.1ee5d263": "credential inheritance is locked by an ancestor policy.",
|
||||
"i18n:govoplan-mail.credential_inheritance.ec8d7191": "Credential inheritance",
|
||||
"i18n:govoplan-mail.current_mailbox_folder.55e2aea5": "Current mailbox folder",
|
||||
"i18n:govoplan-mail.date.eb9a4bc1": "Date",
|
||||
"i18n:govoplan-mail.deactivate_mail_profile.0e0fd0b8": "Deactivate mail profile",
|
||||
"i18n:govoplan-mail.deactivate_value_campaign_drafts_using_it_will_n.656f1b9e": "Deactivate {value0}? Campaign drafts using it will need another allowed profile before sending.",
|
||||
"i18n:govoplan-mail.deactivate_value.a276a667": "Deactivate {value0}",
|
||||
"i18n:govoplan-mail.deactivate.d65ded94": "Deactivate",
|
||||
"i18n:govoplan-mail.decides_whether_lower_scopes_inherit_saved_imap_.ac607ee3": "Decides whether lower scopes inherit saved IMAP credentials from a selected profile or must provide local IMAP credentials.",
|
||||
"i18n:govoplan-mail.decides_whether_lower_scopes_inherit_saved_smtp_.93f1c4d0": "Decides whether lower scopes inherit saved SMTP credentials from a selected profile or must provide local SMTP credentials.",
|
||||
"i18n:govoplan-mail.deny.53577bb5": "Deny",
|
||||
"i18n:govoplan-mail.description.55f8ebc8": "Beschreibung",
|
||||
"i18n:govoplan-mail.development_mock_mailbox.1a379865": "Entwicklungs-Mailbox",
|
||||
"i18n:govoplan-mail.drafts.22a31d86": "Drafts",
|
||||
"i18n:govoplan-mail.edit_mail_profile.95d1af9c": "Edit mail profile",
|
||||
"i18n:govoplan-mail.edit_value_credentials.1e2dc4f6": "Edit {value0} credentials",
|
||||
"i18n:govoplan-mail.edit_value.fad75899": "Edit {value0}",
|
||||
"i18n:govoplan-mail.effective_mail_policy_blocks_the_current_profile.1b555820": "Effective mail policy blocks the current profile values.",
|
||||
"i18n:govoplan-mail.effective_policy.feedb950": "Effective policy",
|
||||
"i18n:govoplan-mail.effective_values_are_shown_in_the_table_rows_abo.b27b900d": "Effective values are shown in the table rows above.",
|
||||
"i18n:govoplan-mail.envelope_sender.5ec276a0": "Envelope sender",
|
||||
"i18n:govoplan-mail.envelope_senders.269065cd": "Envelope senders",
|
||||
"i18n:govoplan-mail.explicit_allow_is_unavailable_for.8d05fd4a": "Explicit allow is unavailable for",
|
||||
"i18n:govoplan-mail.explicit_allow.6a7946f8": "Explicit allow",
|
||||
"i18n:govoplan-mail.first_page.49d74b49": "Erste Seite",
|
||||
"i18n:govoplan-mail.flagged.f8db8a17": "Flagged",
|
||||
"i18n:govoplan-mail.folders.19adc47b": "Ordner",
|
||||
"i18n:govoplan-mail.from_header.bb78e85d": "From header",
|
||||
"i18n:govoplan-mail.from_headers.b3ea473b": "From headers",
|
||||
"i18n:govoplan-mail.from.3f66052a": "From",
|
||||
"i18n:govoplan-mail.generated_from_name.33d69a91": "Generated from name",
|
||||
"i18n:govoplan-mail.group_profiles.74568838": "Group profiles",
|
||||
"i18n:govoplan-mail.group.171a0606": "Group",
|
||||
"i18n:govoplan-mail.groups": "Gruppen",
|
||||
"i18n:govoplan-mail.imap_credentials.da847469": "IMAP credentials",
|
||||
"i18n:govoplan-mail.imap_host.b53c3751": "IMAP host",
|
||||
"i18n:govoplan-mail.imap_hostnames.ac9c1d78": "IMAP hostnames",
|
||||
"i18n:govoplan-mail.imap_not_configured.b2892af3": "IMAP not configured",
|
||||
"i18n:govoplan-mail.imap_profile.5165df81": "IMAP profile",
|
||||
"i18n:govoplan-mail.imap_server_host_patterns.52b20b83": "IMAP server host patterns.",
|
||||
"i18n:govoplan-mail.imap.271f9ef2": "IMAP",
|
||||
"i18n:govoplan-mail.inactive.09af574c": "Inaktiv",
|
||||
"i18n:govoplan-mail.inherit_parent_decision.42125bda": "Inherit parent decision",
|
||||
"i18n:govoplan-mail.inherit_profile_credentials.0034bac0": "Inherit profile credentials",
|
||||
"i18n:govoplan-mail.inherit.18f99833": "Inherit",
|
||||
"i18n:govoplan-mail.junk.86c7d94c": "Junk",
|
||||
"i18n:govoplan-mail.last_page.b01f16ae": "Last page",
|
||||
"i18n:govoplan-mail.loading_folders.17f9f0e2": "Loading folders...",
|
||||
"i18n:govoplan-mail.loading_mail_profile_policy.b746a2e8": "Mailprofil-Richtlinie wird geladen...",
|
||||
"i18n:govoplan-mail.loading_mail_profiles.87de3560": "Loading mail profiles...",
|
||||
"i18n:govoplan-mail.loading_message.815c2094": "Loading message...",
|
||||
"i18n:govoplan-mail.loading_messages.4294022c": "Loading messages",
|
||||
"i18n:govoplan-mail.loading_messages.77b62232": "Loading messages...",
|
||||
"i18n:govoplan-mail.loading_preview.ebd86225": "Loading preview...",
|
||||
"i18n:govoplan-mail.loading.33ce4174": "Loading…",
|
||||
"i18n:govoplan-mail.loading.b04ba49f": "Loading...",
|
||||
"i18n:govoplan-mail.local_required.1f5f4aba": "Local required",
|
||||
"i18n:govoplan-mail.local_setting.967607a9": "Local setting",
|
||||
"i18n:govoplan-mail.local.dc99d54d": "Local",
|
||||
"i18n:govoplan-mail.lower_level_mail_definitions.d39a0a1d": "Lower-level mail definitions",
|
||||
"i18n:govoplan-mail.lower_levels.940821ee": "Lower levels",
|
||||
"i18n:govoplan-mail.mail_actions.c08b5f08": "Mail actions",
|
||||
"i18n:govoplan-mail.mail_profile_policy_saved.666847bf": "Mail profile policy saved.",
|
||||
"i18n:govoplan-mail.mail_profile_policy.f2ac4b92": "Mail profile policy",
|
||||
"i18n:govoplan-mail.mail_server_profiles.b1726682": "Mail server profiles",
|
||||
"i18n:govoplan-mail.mail.92379cbb": "Mail",
|
||||
"i18n:govoplan-mail.mailbox_folders_could_not_be_loaded.c3e3880e": "Mailbox folders could not be loaded.",
|
||||
"i18n:govoplan-mail.mailbox_folders.c92f6de4": "Mailbox folders",
|
||||
"i18n:govoplan-mail.mailbox_message_pagination.965407bf": "Mailbox message pagination",
|
||||
"i18n:govoplan-mail.mailbox_messages.5c06afaf": "Mailbox messages",
|
||||
"i18n:govoplan-mail.message_preview.58de1450": "Nachrichtenvorschau",
|
||||
"i18n:govoplan-mail.messages.f1702b46": "Nachrichten",
|
||||
"i18n:govoplan-mail.name.709a2322": "Name",
|
||||
"i18n:govoplan-mail.new_profile.ca36da25": "New profile",
|
||||
"i18n:govoplan-mail.next_page.4bfc194b": "Nächste Seite",
|
||||
"i18n:govoplan-mail.no_explicit_intersection.f2d62c71": "No explicit intersection",
|
||||
"i18n:govoplan-mail.no_folder_loaded.889bdb1b": "No folder loaded",
|
||||
"i18n:govoplan-mail.no_folders_available.14133b26": "No folders available.",
|
||||
"i18n:govoplan-mail.no_host.4c710d7d": "No host",
|
||||
"i18n:govoplan-mail.no_imap_enabled_mail_profiles.61ae44d8": "No IMAP-enabled mail profiles.",
|
||||
"i18n:govoplan-mail.no_imap_profile_selected.e7d1516f": "No IMAP profile selected",
|
||||
"i18n:govoplan-mail.no_imap_profiles_available.d64589f8": "No IMAP profiles available",
|
||||
"i18n:govoplan-mail.no_value_available": "Keine {value0} verfügbar.",
|
||||
"i18n:govoplan-mail.no_local_profile_allow_list_is_set.31072e39": "No local profile allow-list is set.",
|
||||
"i18n:govoplan-mail.no_messages_in_this_folder.5c7fa25d": "No messages in this folder.",
|
||||
"i18n:govoplan-mail.no_messages_match_the_current_filter_on_this_pag.9dda6916": "No messages match the current filter on this page.",
|
||||
"i18n:govoplan-mail.no_profiles_are_visible_for_this_policy_scope.1ec7bd85": "No profiles are visible for this policy scope.",
|
||||
"i18n:govoplan-mail.no_profiles_in_this_scope.302b21d8": "No profiles in this scope.",
|
||||
"i18n:govoplan-mail.no_saved_password.32ce2b16": "No saved password",
|
||||
"i18n:govoplan-mail.no_subject.49b20da0": "(no subject)",
|
||||
"i18n:govoplan-mail.no_username.1c182624": "No username",
|
||||
"i18n:govoplan-mail.not_configured.67f2141f": "not configured",
|
||||
"i18n:govoplan-mail.not_configured.811931bb": "Nicht konfiguriert",
|
||||
"i18n:govoplan-mail.on_page.ca7166f4": "on page",
|
||||
"i18n:govoplan-mail.owner_policy.1e8df143": "Owner policy",
|
||||
"i18n:govoplan-mail.page.fb06270f": "Seite",
|
||||
"i18n:govoplan-mail.password_saved.f6fab237": "Password saved",
|
||||
"i18n:govoplan-mail.password.8be3c943": "Passwort",
|
||||
"i18n:govoplan-mail.policy_path.1ba91ee5": "Policy path",
|
||||
"i18n:govoplan-mail.policy_target.a19dcee9": "Policy target",
|
||||
"i18n:govoplan-mail.policy.bb9cf141": "Richtlinie",
|
||||
"i18n:govoplan-mail.preview.f1fbb2b4": "Vorschau",
|
||||
"i18n:govoplan-mail.previous_page.81f54719": "Vorherige Seite",
|
||||
"i18n:govoplan-mail.profile_allow_list.507dfe6c": "Profile allow-list",
|
||||
"i18n:govoplan-mail.profile_inherited.ea25d2e1": "Profile inherited",
|
||||
"i18n:govoplan-mail.profile_s.742e9200": "profile(s).",
|
||||
"i18n:govoplan-mail.profile_value_created.2a088d8d": "Profile {value0} created.",
|
||||
"i18n:govoplan-mail.profile_value_deactivated.fa7fcc1a": "Profile {value0} deactivated.",
|
||||
"i18n:govoplan-mail.profile_value_updated.fdbad0ea": "Profile {value0} updated.",
|
||||
"i18n:govoplan-mail.profiles.0c2a9300": "Profiles",
|
||||
"i18n:govoplan-mail.recipient_domain_patterns.68466f5b": "Recipient domain patterns.",
|
||||
"i18n:govoplan-mail.recipient_domain.778f2dcf": "Recipient domain",
|
||||
"i18n:govoplan-mail.recipient_domains.cb9b7b44": "Recipient domains",
|
||||
"i18n:govoplan-mail.refresh_mailbox_folders.d9af9963": "Refresh mailbox folders",
|
||||
"i18n:govoplan-mail.refresh_messages_in_the_current_folder.b6546a2c": "Refresh messages in the current folder",
|
||||
"i18n:govoplan-mail.reload_imap_profiles.b04c11c8": "Reload IMAP profiles",
|
||||
"i18n:govoplan-mail.reload.cce71553": "Neu laden",
|
||||
"i18n:govoplan-mail.require_local_credentials.da7b1d7c": "Require local credentials",
|
||||
"i18n:govoplan-mail.rows_per_page.af2f9c1b": "Zeilen pro Seite",
|
||||
"i18n:govoplan-mail.save_policy.77d67ce3": "Save policy",
|
||||
"i18n:govoplan-mail.save_profile.f597c0e8": "Save profile",
|
||||
"i18n:govoplan-mail.saved.c0ae8f6e": "Gespeichert",
|
||||
"i18n:govoplan-mail.saving.56a2285c": "Saving…",
|
||||
"i18n:govoplan-mail.search_messages.abea65ae": "Search messages",
|
||||
"i18n:govoplan-mail.select_a_message_to_inspect_its_content.5f3d1342": "Select a message to inspect its content.",
|
||||
"i18n:govoplan-mail.select_an_imap_profile.5445648c": "Select an IMAP profile.",
|
||||
"i18n:govoplan-mail.sent.35f49dcf": "Sent",
|
||||
"i18n:govoplan-mail.server_credential.7fb9a24e": "Server / credential",
|
||||
"i18n:govoplan-mail.size.b7152342": "Größe",
|
||||
"i18n:govoplan-mail.slug.094da9b9": "Slug",
|
||||
"i18n:govoplan-mail.smtp_credentials.f73ef315": "SMTP credentials",
|
||||
"i18n:govoplan-mail.smtp_envelope_sender_patterns.8c1fd95e": "SMTP envelope sender patterns.",
|
||||
"i18n:govoplan-mail.smtp_host.2d4a434b": "SMTP host",
|
||||
"i18n:govoplan-mail.smtp_hostnames.36eb51d8": "SMTP hostnames",
|
||||
"i18n:govoplan-mail.smtp_server_host_patterns.cf6120c3": "SMTP server host patterns.",
|
||||
"i18n:govoplan-mail.smtp.efff9cca": "SMTP",
|
||||
"i18n:govoplan-mail.status.bae7d5be": "Status",
|
||||
"i18n:govoplan-mail.subject.8d183dbd": "Betreff",
|
||||
"i18n:govoplan-mail.system_allow.ed6744b1": "System: Allow",
|
||||
"i18n:govoplan-mail.system_profile_inherited.f4b8b5ce": "System: Profile inherited",
|
||||
"i18n:govoplan-mail.system.bc0792d8": "System",
|
||||
"i18n:govoplan-mail.target.61ad50a9": "Target",
|
||||
"i18n:govoplan-mail.tenant.3ca93c78": "Tenant",
|
||||
"i18n:govoplan-mail.test_imap.ef1bd79c": "Test IMAP",
|
||||
"i18n:govoplan-mail.test_saved_imap.923dbe4a": "Test saved IMAP",
|
||||
"i18n:govoplan-mail.test_saved_smtp.008d8054": "Test saved SMTP",
|
||||
"i18n:govoplan-mail.test_smtp.e5697981": "Test SMTP",
|
||||
"i18n:govoplan-mail.this_profile.5fd9cdf1": "this profile",
|
||||
"i18n:govoplan-mail.to.ae79ea1e": "To",
|
||||
"i18n:govoplan-mail.transport.c10d76c9": "Transport",
|
||||
"i18n:govoplan-mail.trash.e3bf62bb": "Trash",
|
||||
"i18n:govoplan-mail.user_profiles.57730285": "User profiles",
|
||||
"i18n:govoplan-mail.user.9f8a2389": "User",
|
||||
"i18n:govoplan-mail.users": "Benutzer",
|
||||
"i18n:govoplan-mail.value_message": "{value0} message",
|
||||
"i18n:govoplan-mail.value_messages": "{value0} messages",
|
||||
"i18n:govoplan-mail.value_of_value_messages.981a1618": "{value0} of {value1} messages",
|
||||
"i18n:govoplan-mail.value_profile_s_allowed_by_this_scope.6fe9ba44": "{value0} profile(s) allowed by this scope.",
|
||||
"i18n:govoplan-mail.value_profile_s.d6b9d0af": "{value0} profile(s)",
|
||||
"i18n:govoplan-mail.value_value.c189e8bc": "{value0} ({value1})",
|
||||
"i18n:govoplan-mail.value.48afe802": "· {value0}",
|
||||
"i18n:govoplan-mail.value.8dce170d": "Value",
|
||||
"i18n:govoplan-mail.value_scope": "Geltungsbereich: {value0}",
|
||||
"i18n:govoplan-mail.visible_from_header_patterns.ea77d99d": "Visible From header patterns.",
|
||||
"i18n:govoplan-mail.whitelist_value.d4cc3755": "whitelist.{value0}",
|
||||
"i18n:govoplan-mail.whitelist.53c2ad30": "Whitelist",
|
||||
"i18n:govoplan-mail.wildcard_rules.54fb3fc0": "Wildcard rules",
|
||||
"i18n:govoplan-mail.working.049ac820": "Working..."
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
import "./styles/mail-profiles.css";
|
||||
export { default } from "./module";
|
||||
export * from "./module";
|
||||
export * from "./api/mail";
|
||||
|
||||
@@ -2,24 +2,31 @@ import { createElement, lazy } from "react";
|
||||
import type { MailDevMailboxUiCapability, MailProfilesUiCapability, PlatformWebModule } from "@govoplan/core-webui";
|
||||
import { MailProfilePolicyEditor, MailProfileScopeManager } from "./features/mail/MailProfileManagement";
|
||||
import { validateMailPolicy } from "./features/mail/mailPolicyValidation";
|
||||
import { generatedTranslations } from "./i18n/generatedTranslations";
|
||||
import "./styles/mail-profiles.css";
|
||||
|
||||
const MailboxPage = lazy(() => import("./features/mail/MailboxPage"));
|
||||
const mailboxRead = ["mail:mailbox:read"];
|
||||
const translations = {
|
||||
en: generatedTranslations.en,
|
||||
de: generatedTranslations.de
|
||||
};
|
||||
|
||||
export const mailModule: PlatformWebModule = {
|
||||
id: "mail",
|
||||
label: "Mail",
|
||||
label: "i18n:govoplan-mail.mail.92379cbb",
|
||||
version: "1.0.0",
|
||||
dependencies: ["access"],
|
||||
navItems: [{ to: "/mail", label: "Mail", iconName: "mail", anyOf: mailboxRead, order: 50 }],
|
||||
translations,
|
||||
navItems: [{ to: "/mail", label: "i18n:govoplan-mail.mail.92379cbb", iconName: "mail", anyOf: mailboxRead, order: 50 }],
|
||||
routes: [
|
||||
{ path: "/mail", anyOf: mailboxRead, order: 50, render: ({ settings }) => createElement(MailboxPage, { settings }) }
|
||||
],
|
||||
{ path: "/mail", anyOf: mailboxRead, order: 50, render: ({ settings }) => createElement(MailboxPage, { settings }) }],
|
||||
|
||||
uiCapabilities: {
|
||||
"mail.profiles": { MailProfileScopeManager, MailProfilePolicyEditor, validateMailPolicy } satisfies MailProfilesUiCapability
|
||||
},
|
||||
runtimeUiCapabilities: {
|
||||
"mail.devMailbox": { enabled: true, label: "Development mock mailbox" } satisfies MailDevMailboxUiCapability
|
||||
"mail.devMailbox": { enabled: true, label: "i18n:govoplan-mail.development_mock_mailbox.1a379865" } satisfies MailDevMailboxUiCapability
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,30 +18,6 @@
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.mail-profile-table-surface {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mail-profile-table-surface > .data-grid-shell {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.card-body > .mail-profile-table-surface:only-child {
|
||||
margin: -22px -24px;
|
||||
width: calc(100% + 48px);
|
||||
max-width: inherit;
|
||||
}
|
||||
|
||||
.card-body > .mail-profile-table-surface:only-child > .data-grid-shell {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mail-profile-dialog .dialog-body {
|
||||
max-height: min(76vh, 820px);
|
||||
overflow: auto;
|
||||
@@ -53,7 +29,6 @@
|
||||
}
|
||||
|
||||
.mail-profile-form h3,
|
||||
.mail-policy-section h3,
|
||||
.mail-policy-pattern-grid h4 {
|
||||
margin: 0;
|
||||
color: var(--text-strong);
|
||||
@@ -83,12 +58,6 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mail-policy-section {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.mail-profile-checkbox-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user