chore: consolidate platform split checks
This commit is contained in:
@@ -3,6 +3,7 @@ import Button from "../Button";
|
||||
import DismissibleAlert from "../DismissibleAlert";
|
||||
import FormField from "../FormField";
|
||||
import PasswordField from "../PasswordField";
|
||||
import SegmentedControl from "../SegmentedControl";
|
||||
import ToggleSwitch from "../ToggleSwitch";
|
||||
|
||||
export type MailServerSecurity = "plain" | "tls" | "starttls" | string;
|
||||
@@ -43,7 +44,7 @@ export type MailServerFolderLookupResult = {
|
||||
security?: MailServerSecurity | null;
|
||||
message: string;
|
||||
detected_sent_folder?: string | null;
|
||||
folders?: { name: string; flags?: string[] }[];
|
||||
folders?: {name: string;flags?: string[];}[];
|
||||
details?: Record<string, unknown> | null;
|
||||
};
|
||||
|
||||
@@ -133,19 +134,19 @@ export function mailNumberOrDefault(value: string | number | null | undefined, f
|
||||
}
|
||||
|
||||
export function normalizeMailServerSecurity<TSecurity extends string = MailServerSecurityOption>(
|
||||
value: string | null | undefined,
|
||||
options: { fallback: TSecurity; allowedSecurity?: readonly TSecurity[] },
|
||||
): TSecurity {
|
||||
const allowed = options.allowedSecurity ?? (mailServerSecurityOptions as unknown as readonly TSecurity[]);
|
||||
return allowed.includes(value as TSecurity) ? (value as TSecurity) : options.fallback;
|
||||
value: string | null | undefined,
|
||||
options: {fallback: TSecurity;allowedSecurity?: readonly TSecurity[];})
|
||||
: TSecurity {
|
||||
const allowed = options.allowedSecurity ?? mailServerSecurityOptions as unknown as readonly TSecurity[];
|
||||
return allowed.includes(value as TSecurity) ? value as TSecurity : options.fallback;
|
||||
}
|
||||
|
||||
export function mailTransportCredentialsPayload(
|
||||
username: string | number | null | undefined,
|
||||
password: string | number | null | undefined,
|
||||
preserveBlankPassword: boolean,
|
||||
): { username?: string | null; password?: string | null } {
|
||||
const payload: { username?: string | null; password?: string | null } = { username: mailTextOrNull(username) };
|
||||
username: string | number | null | undefined,
|
||||
password: string | number | null | undefined,
|
||||
preserveBlankPassword: boolean)
|
||||
: {username?: string | null;password?: string | null;} {
|
||||
const payload: {username?: string | null;password?: string | null;} = { username: mailTextOrNull(username) };
|
||||
if (String(password ?? "") || !preserveBlankPassword) payload.password = mailTextOrNull(password, false);
|
||||
return payload;
|
||||
}
|
||||
@@ -157,39 +158,39 @@ function mailRecordText(record: Record<string, unknown>, key: string, fallback =
|
||||
}
|
||||
|
||||
export function mailTransportCredentialsPayloadFromRecords(
|
||||
primary: Record<string, unknown>,
|
||||
legacy: Record<string, unknown>,
|
||||
preserveBlankPassword: boolean,
|
||||
): { username?: string | null; password?: string | null } {
|
||||
primary: Record<string, unknown>,
|
||||
legacy: Record<string, unknown>,
|
||||
preserveBlankPassword: boolean)
|
||||
: {username?: string | null;password?: string | null;} {
|
||||
return mailTransportCredentialsPayload(
|
||||
mailRecordText(primary, "username", mailRecordText(legacy, "username")),
|
||||
mailRecordText(primary, "password", mailRecordText(legacy, "password")),
|
||||
preserveBlankPassword,
|
||||
preserveBlankPassword
|
||||
);
|
||||
}
|
||||
|
||||
export function mailSmtpSettingsPayload<TSecurity extends string = MailServerSecurityOption>(
|
||||
settings: MailServerSmtpSettings,
|
||||
options: { fallbackSecurity: TSecurity; allowedSecurity?: readonly TSecurity[]; fallbackTimeoutSeconds?: number },
|
||||
): { host: string | null; port: number | null; security: TSecurity; timeout_seconds: number } {
|
||||
settings: MailServerSmtpSettings,
|
||||
options: {fallbackSecurity: TSecurity;allowedSecurity?: readonly TSecurity[];fallbackTimeoutSeconds?: number;})
|
||||
: {host: string | null;port: number | null;security: TSecurity;timeout_seconds: number;} {
|
||||
return {
|
||||
host: mailTextOrNull(settings.host),
|
||||
port: mailNumberOrNull(settings.port),
|
||||
security: normalizeMailServerSecurity(settings.security ? String(settings.security) : null, { fallback: options.fallbackSecurity, allowedSecurity: options.allowedSecurity }),
|
||||
timeout_seconds: mailNumberOrDefault(settings.timeout_seconds, options.fallbackTimeoutSeconds ?? 30),
|
||||
timeout_seconds: mailNumberOrDefault(settings.timeout_seconds, options.fallbackTimeoutSeconds ?? 30)
|
||||
};
|
||||
}
|
||||
|
||||
export function mailImapSettingsPayload<TSecurity extends string = MailServerSecurityOption>(
|
||||
settings: MailServerImapSettings,
|
||||
options: { fallbackSecurity: TSecurity; allowedSecurity?: readonly TSecurity[]; fallbackTimeoutSeconds?: number },
|
||||
): { host: string | null; port: number | null; security: TSecurity; sent_folder: string; timeout_seconds: number } {
|
||||
settings: MailServerImapSettings,
|
||||
options: {fallbackSecurity: TSecurity;allowedSecurity?: readonly TSecurity[];fallbackTimeoutSeconds?: number;})
|
||||
: {host: string | null;port: number | null;security: TSecurity;sent_folder: string;timeout_seconds: number;} {
|
||||
return {
|
||||
host: mailTextOrNull(settings.host),
|
||||
port: mailNumberOrNull(settings.port),
|
||||
security: normalizeMailServerSecurity(settings.security ? String(settings.security) : null, { fallback: options.fallbackSecurity, allowedSecurity: options.allowedSecurity }),
|
||||
sent_folder: mailTextOrNull(settings.sent_folder) || "auto",
|
||||
timeout_seconds: mailNumberOrDefault(settings.timeout_seconds, options.fallbackTimeoutSeconds ?? 30),
|
||||
timeout_seconds: mailNumberOrDefault(settings.timeout_seconds, options.fallbackTimeoutSeconds ?? 30)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -216,9 +217,9 @@ export default function MailServerSettingsPanel({
|
||||
imapPasswordSaved = false,
|
||||
imapSavedPasswordPlaceholder = "••••••••",
|
||||
imapActionDisabled = imapServerDisabled,
|
||||
smtpTestLabel = "Test SMTP",
|
||||
imapTestLabel = "Test IMAP",
|
||||
folderLookupLabel = "Folders...",
|
||||
smtpTestLabel = "i18n:govoplan-core.test_smtp.e5697981",
|
||||
imapTestLabel = "i18n:govoplan-core.test_imap.ef1bd79c",
|
||||
folderLookupLabel = "i18n:govoplan-core.folders.c603ab65",
|
||||
busyAction = null,
|
||||
onTestSmtp,
|
||||
onTestImap,
|
||||
@@ -250,15 +251,15 @@ export default function MailServerSettingsPanel({
|
||||
const appendTargetFolder = append ? append.folder : stringValue(imap.sent_folder, "auto");
|
||||
const appendTargetDisabled = append ? disabled || append.folderDisabled : imapFieldsDisabled;
|
||||
const canLookupAppendFolders = Boolean(onLookupFolders) && !appendTargetDisabled;
|
||||
const appendTargetHelp = append
|
||||
? "Folder for sent-message copies. Leave as auto unless this campaign needs a different target."
|
||||
: "Folder used when this IMAP account is used for sent-message copies. Leave as auto to use the server default.";
|
||||
const appendTargetHelp = append ?
|
||||
"i18n:govoplan-core.folder_for_sent_message_copies_leave_as_auto_unl.a62586e9" :
|
||||
"i18n:govoplan-core.folder_used_when_this_imap_account_is_used_for_s.08503f5e";
|
||||
const [activeSection, setActiveSection] = useState<MailServerSettingsSection>(initialSection);
|
||||
const sections: { id: MailServerSettingsSection; label: string }[] = [
|
||||
{ id: "smtp", label: "SMTP" },
|
||||
{ id: "imap", label: "IMAP" },
|
||||
{ id: "advanced", label: "Advanced" }
|
||||
];
|
||||
const sections: {id: MailServerSettingsSection;label: string;}[] = [
|
||||
{ id: "smtp", label: "i18n:govoplan-core.smtp.efff9cca" },
|
||||
{ id: "imap", label: "i18n:govoplan-core.imap.271f9ef2" },
|
||||
{ id: "advanced", label: "i18n:govoplan-core.advanced.4d064726" }];
|
||||
|
||||
|
||||
function patchSmtpSecurity(security: MailServerSecurity) {
|
||||
const port = portForSecurityChange("smtp", smtp.port, smtpSecurity, security);
|
||||
@@ -271,153 +272,147 @@ export default function MailServerSettingsPanel({
|
||||
}
|
||||
|
||||
function patchSmtpCredentials(patch: Partial<MailServerCredentialSettings>) {
|
||||
if (onSmtpCredentialsChange) onSmtpCredentialsChange(patch);
|
||||
else onSmtpChange(patch);
|
||||
if (onSmtpCredentialsChange) onSmtpCredentialsChange(patch);else
|
||||
onSmtpChange(patch);
|
||||
}
|
||||
|
||||
function patchImapCredentials(patch: Partial<MailServerCredentialSettings>) {
|
||||
if (onImapCredentialsChange) onImapCredentialsChange(patch);
|
||||
else onImapChange(patch);
|
||||
if (onImapCredentialsChange) onImapCredentialsChange(patch);else
|
||||
onImapChange(patch);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`mail-server-settings-panel ${className}`.trim()}>
|
||||
<div className="mail-server-segmented-control" role="tablist" aria-label="Mail server settings sections">
|
||||
{sections.map((section) => (
|
||||
<button
|
||||
type="button"
|
||||
key={section.id}
|
||||
role="tab"
|
||||
aria-selected={activeSection === section.id}
|
||||
className={`mail-server-segmented-tab${activeSection === section.id ? " is-active" : ""}`}
|
||||
onClick={() => setActiveSection(section.id)}
|
||||
>
|
||||
{section.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<SegmentedControl
|
||||
className="mail-server-segmented-control"
|
||||
size="equal"
|
||||
ariaLabel="i18n:govoplan-core.mail_server_settings_sections.40a163b7"
|
||||
value={activeSection}
|
||||
onChange={setActiveSection}
|
||||
options={sections}
|
||||
/>
|
||||
|
||||
<div className="mail-server-settings-view">
|
||||
{activeSection === "smtp" && (
|
||||
<section className="mail-server-subsection" role="tabpanel" aria-label="SMTP settings">
|
||||
{activeSection === "smtp" &&
|
||||
<section className="mail-server-subsection" role="tabpanel" aria-label="i18n:govoplan-core.smtp_settings.f103e570">
|
||||
<div className="form-grid compact responsive-form-grid mail-server-form-grid">
|
||||
<div className="mail-server-field-heading">Server</div>
|
||||
<FormField label="Host"><input value={stringValue(smtp.host)} disabled={smtpFieldsDisabled} onChange={(event) => onSmtpChange({ host: event.target.value })} /></FormField>
|
||||
<FormField label="Port"><input type="number" min={1} max={65535} value={smtpPort} disabled={smtpFieldsDisabled} onChange={(event) => onSmtpChange({ port: event.target.value })} /></FormField>
|
||||
<FormField label="Security"><SecuritySelect value={smtpSecurity} disabled={smtpFieldsDisabled} onChange={patchSmtpSecurity} /></FormField>
|
||||
<div className="mail-server-field-heading">Credentials</div>
|
||||
<FormField label="Username"><input value={stringValue(smtpCredentialValues.username)} disabled={smtpCredentialFieldsDisabled} onChange={(event) => patchSmtpCredentials({ username: event.target.value })} /></FormField>
|
||||
<FormField label="Password">
|
||||
<div className="mail-server-field-heading">i18n:govoplan-core.server.cb0cb170</div>
|
||||
<FormField label="i18n:govoplan-core.host.3960ec4c"><input value={stringValue(smtp.host)} disabled={smtpFieldsDisabled} onChange={(event) => onSmtpChange({ host: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.port.fe035157"><input type="number" min={1} max={65535} value={smtpPort} disabled={smtpFieldsDisabled} onChange={(event) => onSmtpChange({ port: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.security.f25ce1b8"><SecuritySelect value={smtpSecurity} disabled={smtpFieldsDisabled} onChange={patchSmtpSecurity} /></FormField>
|
||||
<div className="mail-server-field-heading">i18n:govoplan-core.credentials.dd097a22</div>
|
||||
<FormField label="i18n:govoplan-core.username.84c29015"><input value={stringValue(smtpCredentialValues.username)} disabled={smtpCredentialFieldsDisabled} onChange={(event) => patchSmtpCredentials({ username: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.password.8be3c943">
|
||||
<PasswordField
|
||||
value={stringValue(smtpCredentialValues.password)}
|
||||
disabled={smtpCredentialFieldsDisabled}
|
||||
saved={smtpPasswordSaved}
|
||||
savedPlaceholder={smtpSavedPasswordPlaceholder}
|
||||
autoComplete="new-password"
|
||||
onValueChange={(password) => patchSmtpCredentials({ password })}
|
||||
/>
|
||||
value={stringValue(smtpCredentialValues.password)}
|
||||
disabled={smtpCredentialFieldsDisabled}
|
||||
saved={smtpPasswordSaved}
|
||||
savedPlaceholder={smtpSavedPasswordPlaceholder}
|
||||
autoComplete="new-password"
|
||||
onValueChange={(password) => patchSmtpCredentials({ password })} />
|
||||
|
||||
</FormField>
|
||||
</div>
|
||||
{onTestSmtp && (
|
||||
<div className="button-row compact-actions mail-server-actions">
|
||||
<Button type="button" variant="primary" onClick={onTestSmtp} disabled={smtpActionsDisabled || busyAction === "smtp"}>{busyAction === "smtp" ? "Testing..." : smtpTestLabel}</Button>
|
||||
{onTestSmtp &&
|
||||
<div className="button-row compact-actions mail-server-actions">
|
||||
<Button type="button" variant="primary" onClick={onTestSmtp} disabled={smtpActionsDisabled || busyAction === "smtp"}>{busyAction === "smtp" ? "i18n:govoplan-core.testing.15ccc832" : smtpTestLabel}</Button>
|
||||
</div>
|
||||
)}
|
||||
}
|
||||
<MailServerActionResult result={smtpTestResult} floating={floatingResults} />
|
||||
</section>
|
||||
)}
|
||||
}
|
||||
|
||||
{activeSection === "imap" && (
|
||||
<section className="mail-server-subsection" role="tabpanel" aria-label="IMAP settings">
|
||||
{activeSection === "imap" &&
|
||||
<section className="mail-server-subsection" role="tabpanel" aria-label="i18n:govoplan-core.imap_settings.ab8d8247">
|
||||
<div className="form-grid compact responsive-form-grid mail-server-form-grid">
|
||||
<div className="mail-server-field-heading">Server</div>
|
||||
<FormField label="Host"><input value={stringValue(imap.host)} disabled={imapFieldsDisabled} onChange={(event) => onImapChange({ host: event.target.value })} /></FormField>
|
||||
<FormField label="Port"><input type="number" min={1} max={65535} value={imapPort} disabled={imapFieldsDisabled} onChange={(event) => onImapChange({ port: event.target.value })} /></FormField>
|
||||
<FormField label="Security"><SecuritySelect value={imapSecurity} disabled={imapFieldsDisabled} onChange={patchImapSecurity} /></FormField>
|
||||
<div className="mail-server-field-heading">Credentials</div>
|
||||
<FormField label="Username"><input value={stringValue(imapCredentialValues.username)} disabled={imapCredentialFieldsDisabled} onChange={(event) => patchImapCredentials({ username: event.target.value })} /></FormField>
|
||||
<FormField label="Password">
|
||||
<div className="mail-server-field-heading">i18n:govoplan-core.server.cb0cb170</div>
|
||||
<FormField label="i18n:govoplan-core.host.3960ec4c"><input value={stringValue(imap.host)} disabled={imapFieldsDisabled} onChange={(event) => onImapChange({ host: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.port.fe035157"><input type="number" min={1} max={65535} value={imapPort} disabled={imapFieldsDisabled} onChange={(event) => onImapChange({ port: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.security.f25ce1b8"><SecuritySelect value={imapSecurity} disabled={imapFieldsDisabled} onChange={patchImapSecurity} /></FormField>
|
||||
<div className="mail-server-field-heading">i18n:govoplan-core.credentials.dd097a22</div>
|
||||
<FormField label="i18n:govoplan-core.username.84c29015"><input value={stringValue(imapCredentialValues.username)} disabled={imapCredentialFieldsDisabled} onChange={(event) => patchImapCredentials({ username: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.password.8be3c943">
|
||||
<PasswordField
|
||||
value={stringValue(imapCredentialValues.password)}
|
||||
disabled={imapCredentialFieldsDisabled}
|
||||
saved={imapPasswordSaved}
|
||||
savedPlaceholder={imapSavedPasswordPlaceholder}
|
||||
autoComplete="new-password"
|
||||
onValueChange={(password) => patchImapCredentials({ password })}
|
||||
/>
|
||||
value={stringValue(imapCredentialValues.password)}
|
||||
disabled={imapCredentialFieldsDisabled}
|
||||
saved={imapPasswordSaved}
|
||||
savedPlaceholder={imapSavedPasswordPlaceholder}
|
||||
autoComplete="new-password"
|
||||
onValueChange={(password) => patchImapCredentials({ password })} />
|
||||
|
||||
</FormField>
|
||||
</div>
|
||||
{onTestImap && (
|
||||
<div className="button-row compact-actions mail-server-actions">
|
||||
<Button type="button" variant="primary" onClick={onTestImap} disabled={imapActionsDisabled || busyAction === "imap"}>{busyAction === "imap" ? "Testing..." : imapTestLabel}</Button>
|
||||
{onTestImap &&
|
||||
<div className="button-row compact-actions mail-server-actions">
|
||||
<Button type="button" variant="primary" onClick={onTestImap} disabled={imapActionsDisabled || busyAction === "imap"}>{busyAction === "imap" ? "i18n:govoplan-core.testing.15ccc832" : imapTestLabel}</Button>
|
||||
</div>
|
||||
)}
|
||||
}
|
||||
<MailServerActionResult result={imapTestResult} floating={floatingResults} />
|
||||
</section>
|
||||
)}
|
||||
}
|
||||
|
||||
{activeSection === "advanced" && (
|
||||
<section className="mail-server-subsection" role="tabpanel" aria-label="Advanced mail settings">
|
||||
{activeSection === "advanced" &&
|
||||
<section className="mail-server-subsection" role="tabpanel" aria-label="i18n:govoplan-core.advanced_mail_settings.1f69439a">
|
||||
<div className="form-grid compact responsive-form-grid mail-server-form-grid mail-server-advanced-grid">
|
||||
{mockToggle && (
|
||||
<div className="mail-server-field-span mail-server-toggle-row">
|
||||
{mockToggle &&
|
||||
<div className="mail-server-field-span mail-server-toggle-row">
|
||||
<ToggleSwitch
|
||||
label={mockToggle.label ?? "Mock server settings"}
|
||||
checked={mockToggle.checked}
|
||||
disabled={disabled || mockToggle.disabled}
|
||||
onChange={mockToggle.onChange}
|
||||
/>
|
||||
label={mockToggle.label ?? "i18n:govoplan-core.mock_server_settings.9361d5c5"}
|
||||
checked={mockToggle.checked}
|
||||
disabled={disabled || mockToggle.disabled}
|
||||
onChange={mockToggle.onChange} />
|
||||
|
||||
</div>
|
||||
)}
|
||||
<FormField label="SMTP timeout seconds"><input type="number" min={1} value={stringValue(smtp.timeout_seconds)} disabled={smtpFieldsDisabled} onChange={(event) => onSmtpChange({ timeout_seconds: event.target.value })} /></FormField>
|
||||
<FormField label="IMAP timeout seconds"><input type="number" min={1} value={stringValue(imap.timeout_seconds)} disabled={imapFieldsDisabled} onChange={(event) => onImapChange({ timeout_seconds: event.target.value })} /></FormField>
|
||||
{append && (
|
||||
<div className="mail-server-field-span mail-server-toggle-row mail-server-plain-toggle-row">
|
||||
<ToggleSwitch label="Append successfully sent messages to Sent" checked={append.enabled} disabled={disabled || append.disabled} onChange={append.onEnabledChange} />
|
||||
}
|
||||
<FormField label="i18n:govoplan-core.smtp_timeout_seconds.ac87c8d2"><input type="number" min={1} value={stringValue(smtp.timeout_seconds)} disabled={smtpFieldsDisabled} onChange={(event) => onSmtpChange({ timeout_seconds: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-core.imap_timeout_seconds.489af2a4"><input type="number" min={1} value={stringValue(imap.timeout_seconds)} disabled={imapFieldsDisabled} onChange={(event) => onImapChange({ timeout_seconds: event.target.value })} /></FormField>
|
||||
{append &&
|
||||
<div className="mail-server-field-span mail-server-toggle-row mail-server-plain-toggle-row">
|
||||
<ToggleSwitch label="i18n:govoplan-core.append_successfully_sent_messages_to_sent.002fd67e" checked={append.enabled} disabled={disabled || append.disabled} onChange={append.onEnabledChange} />
|
||||
</div>
|
||||
)}
|
||||
<FormField label="Append target folder" help={appendTargetHelp}>
|
||||
}
|
||||
<FormField label="i18n:govoplan-core.append_target_folder.0aaacc0c" help={appendTargetHelp}>
|
||||
<div className="field-with-action mail-server-folder-field">
|
||||
<input
|
||||
value={appendTargetFolder}
|
||||
disabled={appendTargetDisabled}
|
||||
onChange={(event) => append ? append.onFolderChange(event.target.value) : onImapChange({ sent_folder: event.target.value })}
|
||||
placeholder="auto"
|
||||
/>
|
||||
{canLookupAppendFolders && <Button type="button" variant="primary" onClick={onLookupFolders} disabled={imapActionsDisabled || busyAction === "folders"}>{busyAction === "folders" ? "Looking up..." : folderLookupLabel}</Button>}
|
||||
value={appendTargetFolder}
|
||||
disabled={appendTargetDisabled}
|
||||
onChange={(event) => append ? append.onFolderChange(event.target.value) : onImapChange({ sent_folder: event.target.value })}
|
||||
placeholder="i18n:govoplan-core.auto.0d612c12" />
|
||||
|
||||
{canLookupAppendFolders && <Button type="button" variant="primary" onClick={onLookupFolders} disabled={imapActionsDisabled || busyAction === "folders"}>{busyAction === "folders" ? "i18n:govoplan-core.looking_up.5fc6d2a2" : folderLookupLabel}</Button>}
|
||||
</div>
|
||||
</FormField>
|
||||
{canLookupAppendFolders && <MailServerFolderLookupResultView result={folderLookupResult} disabled={useDetectedFolderDisabled || appendTargetDisabled} onUseDetected={onUseDetectedFolder} />}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</div>);
|
||||
|
||||
}
|
||||
|
||||
export function MailServerActionResult({ result, floating = false }: { result: MailServerConnectionTestResult | null | undefined; floating?: boolean }) {
|
||||
export function MailServerActionResult({ result, floating = false }: {result: MailServerConnectionTestResult | null | undefined;floating?: boolean;}) {
|
||||
if (!result) return null;
|
||||
const authenticated = result.details?.authenticated;
|
||||
return (
|
||||
<DismissibleAlert tone={result.ok ? "success" : "danger"} resetKey={`${result.ok}:${result.message}`} floating={floating}>
|
||||
{result.message}
|
||||
{result.ok && typeof authenticated === "boolean" && (
|
||||
<span> Authentication: {authenticated ? "credentials accepted" : "not used"}.</span>
|
||||
)}
|
||||
</DismissibleAlert>
|
||||
);
|
||||
{result.ok && typeof authenticated === "boolean" &&
|
||||
<span> i18n:govoplan-core.authentication.e665f157 {authenticated ? "i18n:govoplan-core.credentials_accepted.ae8e2629" : "i18n:govoplan-core.not_used.487f8bcd"}.</span>
|
||||
}
|
||||
</DismissibleAlert>);
|
||||
|
||||
}
|
||||
|
||||
export function MailServerFolderLookupResultView({
|
||||
result,
|
||||
disabled = false,
|
||||
onUseDetected
|
||||
}: {
|
||||
result: MailServerFolderLookupResult | null | undefined;
|
||||
disabled?: boolean;
|
||||
onUseDetected?: () => void;
|
||||
}) {
|
||||
|
||||
|
||||
|
||||
|
||||
}: {result: MailServerFolderLookupResult | null | undefined;disabled?: boolean;onUseDetected?: () => void;}) {
|
||||
if (!result) return null;
|
||||
if (!result.ok) {
|
||||
return <DismissibleAlert tone="danger" resetKey={result.message}>{result.message}</DismissibleAlert>;
|
||||
@@ -427,21 +422,21 @@ export function MailServerFolderLookupResultView({
|
||||
return (
|
||||
<DismissibleAlert tone="success" resetKey={`${result.message}:${result.detected_sent_folder || ""}`}>
|
||||
<p>{result.message}</p>
|
||||
<p>Detected Sent folder: <strong>{result.detected_sent_folder || "-"}</strong></p>
|
||||
{result.detected_sent_folder && onUseDetected && <Button type="button" onClick={onUseDetected} disabled={disabled}>Use detected folder</Button>}
|
||||
{folders.length > 0 && (
|
||||
<div className="mail-server-folder-chip-list">
|
||||
{folders.slice(0, 12).map((folder) => (
|
||||
<span className="mail-server-folder-chip" key={folder.name} title={(folder.flags || []).join(" ")}>{folder.name}</span>
|
||||
))}
|
||||
<p>i18n:govoplan-core.detected_sent_folder.cbf8ec8d <strong>{result.detected_sent_folder || "-"}</strong></p>
|
||||
{result.detected_sent_folder && onUseDetected && <Button type="button" onClick={onUseDetected} disabled={disabled}>i18n:govoplan-core.use_detected_folder.5ec4965c</Button>}
|
||||
{folders.length > 0 &&
|
||||
<div className="mail-server-folder-chip-list">
|
||||
{folders.slice(0, 12).map((folder) =>
|
||||
<span className="mail-server-folder-chip" key={folder.name} title={(folder.flags || []).join(" ")}>{folder.name}</span>
|
||||
)}
|
||||
{folders.length > 12 && <span className="mail-server-folder-chip">+{folders.length - 12} more</span>}
|
||||
</div>
|
||||
)}
|
||||
</DismissibleAlert>
|
||||
);
|
||||
}
|
||||
</DismissibleAlert>);
|
||||
|
||||
}
|
||||
|
||||
function SecuritySelect({ value, disabled, onChange }: { value: string; disabled: boolean; onChange: (value: MailServerSecurity) => void }) {
|
||||
function SecuritySelect({ value, disabled, onChange }: {value: string;disabled: boolean;onChange: (value: MailServerSecurity) => void;}) {
|
||||
return <select value={value} disabled={disabled} onChange={(event) => onChange(event.target.value)}>{securityOptions.map((option) => <option key={option} value={option}>{option}</option>)}</select>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user