mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
update
This commit is contained in:
@@ -81,7 +81,9 @@ impl DashboardStats {
|
||||
|
||||
if has_all_accounts {
|
||||
stat.storage_usage_bytes = get_total_size(&DATA_DIR_MANAGER.eml_dir)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
+ get_total_size(&DATA_DIR_MANAGER.attachment_dir)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
|
||||
stat.index_usage_bytes = get_total_size(&DATA_DIR_MANAGER.envelope_dir)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
|
||||
@@ -50,6 +50,24 @@ pub struct SystemConfigurations {
|
||||
pub bichon_enable_rest_https: bool,
|
||||
pub bichon_http_compression_enabled: bool,
|
||||
pub bichon_sync_concurrency: Option<u16>,
|
||||
|
||||
pub bichon_base_url: String,
|
||||
pub bichon_index_dir: Option<String>,
|
||||
pub bichon_data_dir: Option<String>,
|
||||
|
||||
pub bichon_duckdb_threads: Option<i64>,
|
||||
pub bichon_duckdb_max_memory: Option<String>,
|
||||
pub bichon_tantivy_threads: u16,
|
||||
pub bichon_tantivy_buffer_size: usize,
|
||||
pub bichon_eml_compression_level: u16,
|
||||
pub bichon_eml_blocksize: usize,
|
||||
|
||||
pub bichon_enable_smtp: bool,
|
||||
pub bichon_smtp_port: u16,
|
||||
pub bichon_smtp_encryption: String,
|
||||
pub bichon_smtp_auth_required: bool,
|
||||
pub bichon_smtp_tls_key_path: Option<String>,
|
||||
pub bichon_smtp_tls_cert_path: Option<String>,
|
||||
}
|
||||
|
||||
impl From<&Settings> for SystemConfigurations {
|
||||
@@ -77,6 +95,21 @@ impl From<&Settings> for SystemConfigurations {
|
||||
bichon_enable_rest_https: s.bichon_enable_rest_https,
|
||||
bichon_http_compression_enabled: s.bichon_http_compression_enabled,
|
||||
bichon_sync_concurrency: s.bichon_sync_concurrency,
|
||||
bichon_base_url: s.bichon_base_url.clone(),
|
||||
bichon_index_dir: s.bichon_index_dir.clone(),
|
||||
bichon_data_dir: s.bichon_data_dir.clone(),
|
||||
bichon_duckdb_threads: s.bichon_duckdb_threads,
|
||||
bichon_duckdb_max_memory: s.bichon_duckdb_max_memory.clone(),
|
||||
bichon_tantivy_threads: s.bichon_tantivy_threads,
|
||||
bichon_tantivy_buffer_size: s.bichon_tantivy_buffer_size,
|
||||
bichon_eml_compression_level: s.bichon_eml_compression_level,
|
||||
bichon_eml_blocksize: s.bichon_eml_blocksize,
|
||||
bichon_enable_smtp: s.bichon_enable_smtp,
|
||||
bichon_smtp_port: s.bichon_smtp_port,
|
||||
bichon_smtp_encryption: s.bichon_smtp_encryption.to_string(),
|
||||
bichon_smtp_auth_required: s.bichon_smtp_auth_required,
|
||||
bichon_smtp_tls_key_path: s.bichon_smtp_tls_key_path.clone(),
|
||||
bichon_smtp_tls_cert_path: s.bichon_smtp_tls_cert_path.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,21 +100,42 @@ export type ServerConfigurations = {
|
||||
bichon_log_level: string
|
||||
bichon_http_port: number
|
||||
bichon_bind_ip?: string | null
|
||||
bichon_base_url: string
|
||||
bichon_public_url: string
|
||||
bichon_enable_rest_https: boolean
|
||||
bichon_http_compression_enabled: boolean
|
||||
|
||||
bichon_cors_origins?: string[] | null
|
||||
bichon_cors_max_age: number
|
||||
|
||||
bichon_ansi_logs: boolean
|
||||
bichon_log_to_file: boolean
|
||||
bichon_json_logs: boolean
|
||||
bichon_max_server_log_files: number
|
||||
|
||||
bichon_encrypt_password_set: boolean
|
||||
bichon_webui_token_expiration_hours: number
|
||||
|
||||
bichon_root_dir: string
|
||||
bichon_metadata_cache_size?: number | null
|
||||
bichon_envelope_cache_size?: number | null
|
||||
bichon_enable_rest_https: boolean
|
||||
bichon_http_compression_enabled: boolean
|
||||
bichon_index_dir?: string | null
|
||||
bichon_data_dir?: string | null
|
||||
bichon_metadata_cache_size: number
|
||||
bichon_envelope_cache_size: number
|
||||
|
||||
bichon_sync_concurrency?: number | null
|
||||
bichon_duckdb_threads?: number | null
|
||||
bichon_duckdb_max_memory?: string | null
|
||||
bichon_tantivy_threads: number
|
||||
bichon_tantivy_buffer_size: number
|
||||
bichon_eml_compression_level: number
|
||||
bichon_eml_blocksize: number
|
||||
|
||||
bichon_enable_smtp: boolean
|
||||
bichon_smtp_port: number
|
||||
bichon_smtp_encryption: "none" | "starttls" | "tls"
|
||||
bichon_smtp_auth_required: boolean
|
||||
bichon_smtp_tls_key_path?: string | null
|
||||
bichon_smtp_tls_cert_path?: string | null
|
||||
}
|
||||
|
||||
export const get_dashboard_stats = async () => {
|
||||
|
||||
@@ -36,7 +36,7 @@ export function MoreFiltersPopover() {
|
||||
const { filter, setFilter } = useSearchContext();
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const { data: meta, isLoading: metaLoading } = useAttachmentMetadata();
|
||||
const { data: meta, isLoading: metaLoading } = useAttachmentMetadata(open);
|
||||
|
||||
const [localState, setLocalState] = React.useState({
|
||||
attachment_name: filter?.attachment_name || '',
|
||||
|
||||
@@ -21,17 +21,33 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/com
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
import { ShieldCheck, Server, Database, Globe, Lock, Activity, InfoIcon } from "lucide-react"
|
||||
import {
|
||||
ShieldCheck,
|
||||
Server,
|
||||
Database,
|
||||
Globe,
|
||||
Lock,
|
||||
Activity,
|
||||
InfoIcon,
|
||||
Mail,
|
||||
Zap,
|
||||
Cpu
|
||||
} from "lucide-react"
|
||||
import { get_system_configurations } from "@/api/system/api"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
const formatMB = (bytes?: number) => {
|
||||
if (!bytes) return "—";
|
||||
return `${(bytes / 1024 / 1024).toFixed(0)} MB`;
|
||||
};
|
||||
|
||||
function BooleanBadge({ value }: { value: boolean }) {
|
||||
const { t } = useTranslation()
|
||||
return value ? (
|
||||
<Badge variant="secondary">{t("systemConfig.status.enabled")}</Badge>
|
||||
) : (
|
||||
<Badge>{t("systemConfig.status.disabled")}</Badge>
|
||||
<Badge variant="outline" className="opacity-70">{t("systemConfig.status.disabled")}</Badge>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -45,10 +61,10 @@ function SettingRow({
|
||||
description?: string
|
||||
}) {
|
||||
return (
|
||||
<div className="py-1">
|
||||
<div className="py-1.5 border-b border-border/40 last:border-0">
|
||||
<div className="grid grid-cols-[1fr_auto] items-center gap-3">
|
||||
<div className="text-sm font-medium leading-tight">{label}</div>
|
||||
<div className="text-sm text-right break-all leading-tight">{value}</div>
|
||||
<div className="text-sm font-medium text-foreground/80 leading-tight font-mono">{label}</div>
|
||||
<div className="text-sm text-right break-all leading-tight font-medium">{value}</div>
|
||||
</div>
|
||||
{description && (
|
||||
<div className="mt-0.5 text-[11px] leading-tight text-muted-foreground">{description}</div>
|
||||
@@ -69,15 +85,15 @@ function SettingsCard({
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<Card className="h-full">
|
||||
<CardHeader className="flex flex-row items-center gap-2 py-3">
|
||||
<Icon className="h-5 w-5 text-muted-foreground" />
|
||||
<div>
|
||||
<CardTitle className="font-normal">{title}</CardTitle>
|
||||
{description && <CardDescription>{description}</CardDescription>}
|
||||
<Card className="h-full shadow-sm">
|
||||
<CardHeader className="flex flex-row items-center gap-2 py-3 bg-muted/20">
|
||||
<Icon className="h-4 w-4 text-primary/70" />
|
||||
<div className="space-y-0.5">
|
||||
<CardTitle className="text-sm font-semibold">{title}</CardTitle>
|
||||
{description && <CardDescription className="text-[11px] leading-none">{description}</CardDescription>}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-1">{children}</CardContent>
|
||||
<CardContent className="pt-2 pb-1 px-4">{children}</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -94,7 +110,6 @@ function PageSkeleton() {
|
||||
<CardContent className="space-y-2">
|
||||
<Skeleton className="h-3 w-full" />
|
||||
<Skeleton className="h-3 w-5/6" />
|
||||
<Skeleton className="h-3 w-4/6" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
@@ -109,45 +124,43 @@ export default function ServerConfigurationsPage() {
|
||||
queryFn: get_system_configurations,
|
||||
})
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<ScrollArea className="h-full">
|
||||
<PageSkeleton />
|
||||
</ScrollArea>
|
||||
)
|
||||
}
|
||||
|
||||
if (isLoading) return <ScrollArea className="h-full"><PageSkeleton /></ScrollArea>
|
||||
if (isError || !data) {
|
||||
return (
|
||||
<div className="p-4 text-sm text-destructive">{t("systemConfig.fields.loadError")}</div>
|
||||
)
|
||||
return <div className="p-8 text-center text-sm text-destructive">{t("systemConfig.fields.loadError")}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-5xl ml-0 px-4">
|
||||
<div className="w-full max-w-6xl mx-auto">
|
||||
<ScrollArea className="h-full w-full">
|
||||
<div className="px-4 pt-6 pb-2">
|
||||
<div className="flex items-start gap-3 p-4 rounded-xl border bg-secondary/30">
|
||||
<InfoIcon className="h-5 w-5 mt-0.5 text-muted-foreground" />
|
||||
{/* Header Section */}
|
||||
<div className="px-6 pt-6 pb-2">
|
||||
<div className="flex items-start gap-4 p-5 rounded-xl border bg-gradient-to-br from-secondary/50 to-background shadow-inner">
|
||||
<div className="p-2 bg-primary/10 rounded-lg">
|
||||
<InfoIcon className="h-5 w-5 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold italic text-foreground/80">
|
||||
<h4 className="text-base font-bold text-foreground">
|
||||
{t("systemConfig.pageTitle")}
|
||||
</h4>
|
||||
<p className="text-xs text-muted-foreground mt-1 leading-relaxed">
|
||||
<p className="text-xs text-muted-foreground mt-1 max-w-2xl leading-relaxed">
|
||||
{t("systemConfig.pageDescription")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-4 grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Main Grid */}
|
||||
<div className="p-6 grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
|
||||
{/* Network Settings */}
|
||||
<SettingsCard
|
||||
icon={Server}
|
||||
title={t("systemConfig.sections.network.title")}
|
||||
description={t("systemConfig.sections.network.desc")}
|
||||
>
|
||||
<SettingRow label="bichon_bind_ip" value={data.bichon_bind_ip ?? "—"} />
|
||||
<SettingRow label="bichon_bind_ip" value={data.bichon_bind_ip ?? "0.0.0.0"} />
|
||||
<SettingRow label="bichon_http_port" value={data.bichon_http_port} />
|
||||
<SettingRow label="bichon_base_url" value={data.bichon_base_url} />
|
||||
<SettingRow label="bichon_public_url" value={data.bichon_public_url} />
|
||||
<SettingRow
|
||||
label="bichon_enable_rest_https"
|
||||
@@ -155,40 +168,49 @@ export default function ServerConfigurationsPage() {
|
||||
/>
|
||||
</SettingsCard>
|
||||
|
||||
{/* SMTP Server (NEW) */}
|
||||
<SettingsCard
|
||||
icon={Globe}
|
||||
title={t("systemConfig.sections.cors.title")}
|
||||
description={t("systemConfig.sections.cors.desc")}
|
||||
icon={Mail}
|
||||
title={t("systemConfig.sections.smtp.title", "SMTP Server")}
|
||||
description={t("systemConfig.sections.smtp.desc", "Incoming mail reception settings")}
|
||||
>
|
||||
<SettingRow label="bichon_enable_smtp" value={<BooleanBadge value={data.bichon_enable_smtp} />} />
|
||||
<SettingRow label="bichon_smtp_port" value={data.bichon_smtp_port} />
|
||||
<SettingRow label="bichon_smtp_encryption" value={<span className="uppercase text-xs font-bold">{data.bichon_smtp_encryption}</span>} />
|
||||
<SettingRow label="bichon_smtp_auth_required" value={<BooleanBadge value={data.bichon_smtp_auth_required} />} />
|
||||
</SettingsCard>
|
||||
|
||||
{/* Performance & Engine (NEWly structured) */}
|
||||
<SettingsCard
|
||||
icon={Zap}
|
||||
title={t("systemConfig.sections.performance.title")}
|
||||
description={t("systemConfig.sections.performance.desc")}
|
||||
>
|
||||
<SettingRow label="bichon_duckdb_threads" value={data.bichon_duckdb_threads ?? t("systemConfig.status.auto")} />
|
||||
<SettingRow label="bichon_tantivy_threads" value={data.bichon_tantivy_threads} />
|
||||
<SettingRow label="bichon_tantivy_buffer_size" value={formatMB(data.bichon_tantivy_buffer_size)} />
|
||||
<SettingRow label="bichon_eml_compression_level" value={data.bichon_eml_compression_level} />
|
||||
<SettingRow label="bichon_sync_concurrency" value={data.bichon_sync_concurrency ?? t("systemConfig.status.auto")} />
|
||||
<SettingRow
|
||||
label="bichon_cors_origins"
|
||||
value={data.bichon_cors_origins?.join(", ") ?? t("systemConfig.status.notSet")}
|
||||
label="bichon_http_compression_enabled"
|
||||
value={<BooleanBadge value={data.bichon_http_compression_enabled} />}
|
||||
/>
|
||||
<SettingRow label="bichon_cors_max_age" value={data.bichon_cors_max_age} />
|
||||
</SettingsCard>
|
||||
|
||||
<SettingsCard
|
||||
icon={Activity}
|
||||
title={t("systemConfig.sections.logging.title")}
|
||||
description={t("systemConfig.sections.logging.desc")}
|
||||
>
|
||||
<SettingRow label="bichon_log_level" value={data.bichon_log_level} />
|
||||
<SettingRow label="bichon_ansi_logs" value={<BooleanBadge value={data.bichon_ansi_logs} />} />
|
||||
<SettingRow label="bichon_json_logs" value={<BooleanBadge value={data.bichon_json_logs} />} />
|
||||
<SettingRow label="bichon_log_to_file" value={<BooleanBadge value={data.bichon_log_to_file} />} />
|
||||
<SettingRow label="bichon_max_server_log_files" value={data.bichon_max_server_log_files} />
|
||||
</SettingsCard>
|
||||
|
||||
{/* Storage & Directories */}
|
||||
<SettingsCard
|
||||
icon={Database}
|
||||
title={t("systemConfig.sections.storage.title")}
|
||||
description={t("systemConfig.sections.storage.desc")}
|
||||
>
|
||||
<SettingRow label="bichon_root_dir" value={data.bichon_root_dir} />
|
||||
<SettingRow label="bichon_metadata_cache_size" value={data.bichon_metadata_cache_size ?? "—"} />
|
||||
<SettingRow label="bichon_envelope_cache_size" value={data.bichon_envelope_cache_size ?? "—"} />
|
||||
<SettingRow label="bichon_root_dir" value={<span className="text-[10px] font-mono">{data.bichon_root_dir}</span>} />
|
||||
<SettingRow label="bichon_data_dir" value={data.bichon_data_dir ? <span className="text-[10px] font-mono">{data.bichon_data_dir}</span> : "—"} />
|
||||
<SettingRow label="bichon_index_dir" value={data.bichon_index_dir ? <span className="text-[10px] font-mono">{data.bichon_index_dir}</span> : "—"} />
|
||||
<SettingRow label="bichon_metadata_cache_size" value={formatMB(data.bichon_metadata_cache_size)} />
|
||||
<SettingRow label="bichon_envelope_cache_size" value={formatMB(data.bichon_envelope_cache_size)} />
|
||||
</SettingsCard>
|
||||
|
||||
{/* Security & Access */}
|
||||
<SettingsCard
|
||||
icon={ShieldCheck}
|
||||
title={t("systemConfig.sections.security.title")}
|
||||
@@ -198,33 +220,33 @@ export default function ServerConfigurationsPage() {
|
||||
label="bichon_encrypt_password_set"
|
||||
value={
|
||||
data.bichon_encrypt_password_set ? (
|
||||
<Badge variant="secondary">{t("systemConfig.status.configured")}</Badge>
|
||||
<Badge variant="secondary" className="bg-emerald-500/10 text-emerald-600 border-emerald-500/20">
|
||||
{t("systemConfig.status.configured")}
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="destructive">{t("systemConfig.status.missing")}</Badge>
|
||||
)
|
||||
}
|
||||
description={t("systemConfig.fields.encryptPasswordDesc")}
|
||||
/>
|
||||
<SettingRow
|
||||
label="bichon_webui_token_expiration_hours"
|
||||
value={data.bichon_webui_token_expiration_hours}
|
||||
value={`${data.bichon_webui_token_expiration_hours}h`}
|
||||
/>
|
||||
</SettingsCard>
|
||||
|
||||
{/* Logging Settings */}
|
||||
<SettingsCard
|
||||
icon={Lock}
|
||||
title={t("systemConfig.sections.performance.title")}
|
||||
description={t("systemConfig.sections.performance.desc")}
|
||||
icon={Activity}
|
||||
title={t("systemConfig.sections.logging.title")}
|
||||
description={t("systemConfig.sections.logging.desc")}
|
||||
>
|
||||
<SettingRow
|
||||
label="bichon_http_compression_enabled"
|
||||
value={<BooleanBadge value={data.bichon_http_compression_enabled} />}
|
||||
/>
|
||||
<SettingRow
|
||||
label="bichon_sync_concurrency"
|
||||
value={data.bichon_sync_concurrency ?? t("systemConfig.status.auto")}
|
||||
/>
|
||||
<SettingRow label="bichon_log_level" value={<Badge variant="outline" className="uppercase">{data.bichon_log_level}</Badge>} />
|
||||
<SettingRow label="bichon_ansi_logs" value={<BooleanBadge value={data.bichon_ansi_logs} />} />
|
||||
<SettingRow label="bichon_json_logs" value={<BooleanBadge value={data.bichon_json_logs} />} />
|
||||
<SettingRow label="bichon_log_to_file" value={<BooleanBadge value={data.bichon_log_to_file} />} />
|
||||
<SettingRow label="bichon_max_server_log_files" value={data.bichon_max_server_log_files} />
|
||||
</SettingsCard>
|
||||
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { AttachmentMetadata, get_attachment_meta } from '@/api/mailbox/envelope/api';
|
||||
import { useQuery, UseQueryOptions } from '@tanstack/react-query';
|
||||
import { get_attachment_meta } from '@/api/mailbox/envelope/api';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const ATTACHMENT_METADATA_KEY = ['attachment_metadata'] as const;
|
||||
|
||||
export const useAttachmentMetadata = (options?: Partial<UseQueryOptions<AttachmentMetadata>>) => {
|
||||
export const useAttachmentMetadata = (enabled = true) => {
|
||||
return useQuery({
|
||||
queryKey: ATTACHMENT_METADATA_KEY,
|
||||
queryFn: get_attachment_meta,
|
||||
staleTime: 1000 * 60 * 10,
|
||||
gcTime: 1000 * 60 * 30,
|
||||
...options,
|
||||
enabled: enabled
|
||||
});
|
||||
};
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "الأداء",
|
||||
"desc": "التزامن والضغط"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "خادم SMTP",
|
||||
"desc": "إعدادات استقبال البريد الوارد للأرشفة في الوقت الفعلي"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Ydeevne",
|
||||
"desc": "Samtidighed & komprimering"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-server",
|
||||
"desc": "Indstillinger for modtagelse af indgående post til arkivering i realtid"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Leistung",
|
||||
"desc": "Nebenläufigkeit & Kompression"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-Server",
|
||||
"desc": "Einstellungen für den Empfang eingehender E-Mails zur Echtzeit-Archivierung"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Performance",
|
||||
"desc": "Concurrency & compression"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP Server",
|
||||
"desc": "Incoming mail reception settings for real-time archiving"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Rendimiento",
|
||||
"desc": "Concurrencia y compresión"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "Servidor SMTP",
|
||||
"desc": "Ajustes de recepción de correo entrante para el archivado en tiempo real"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Suorituskyky",
|
||||
"desc": "Samanaikaisuus ja pakkaus"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-palvelin",
|
||||
"desc": "Saapuvan postin vastaanottoasetukset reaaliaikaista arkistointia varten"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Performance",
|
||||
"desc": "Concurrence et compression"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "Serveur SMTP",
|
||||
"desc": "Paramètres de réception du courrier entrant pour l'archivage en temps réel"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Prestazioni",
|
||||
"desc": "Concorrenza e compressione"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "Server SMTP",
|
||||
"desc": "Impostazioni di ricezione della posta in entrata per l'archiviazione in tempo reale"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "パフォーマンス",
|
||||
"desc": "並行性と圧縮"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTPサーバー",
|
||||
"desc": "リアルタイムアーカイブ用の受信メール設定"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "성능",
|
||||
"desc": "동시성 및 압축"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP 서버",
|
||||
"desc": "실시간 아카이빙을 위한 수신 메일 설정"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Prestaties",
|
||||
"desc": "Gelijktijdigheid & compressie"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-server",
|
||||
"desc": "Instellingen voor inkomende e-mailontvangst voor realtime archivering"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Ytelse",
|
||||
"desc": "Samtidighet og komprimering"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-server",
|
||||
"desc": "Innstillinger for mottak av innkommende e-post for sanntidsarkivering"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Wydajność",
|
||||
"desc": "Współbieżność i kompresja"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "Serwer SMTP",
|
||||
"desc": "Ustawienia odbierania poczty przychodzącej do archiwizacji w czasie rzeczywistym"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Desempenho",
|
||||
"desc": "Concorrência e compressão"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "Servidor SMTP",
|
||||
"desc": "Configurações de recepção de e-mail de entrada para arquivamento em tempo real"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Производительность",
|
||||
"desc": "Параллелизм и сжатие"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-сервер",
|
||||
"desc": "Настройки приема входящей почты для архивации в реальном времени"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "Prestanda",
|
||||
"desc": "Samtidighet & komprimering"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP-server",
|
||||
"desc": "Inställningar för mottagning av inkommande e-post för realtidsarkivering"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "效能",
|
||||
"desc": "並行與壓縮"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP 伺服器",
|
||||
"desc": "內置郵件接收服務設定,用於實時歸檔"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,6 +1019,10 @@
|
||||
"performance": {
|
||||
"title": "性能",
|
||||
"desc": "并发与压缩"
|
||||
},
|
||||
"smtp": {
|
||||
"title": "SMTP 服务器",
|
||||
"desc": "内置邮件接收服务设置,用于实时归档"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user