add kerio format support

This commit is contained in:
2026-07-17 11:42:34 +07:00
parent 5d296c39b1
commit b352cda166
8 changed files with 393 additions and 2 deletions
+26 -1
View File
@@ -1,11 +1,12 @@
import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react'
import { cancelAccount, createAccount, deleteAccount, getTask, importCSV, probeAccountFolders, probeFolders, runTask, setAccountFolderMapping, setTaskSchedule, testAccounts, type TaskDetail as TaskDetailData } from '../api'
import { cancelAccount, createAccount, deleteAccount, getTask, importCSV, importKerioCSV, probeAccountFolders, probeFolders, runTask, setAccountFolderMapping, setTaskSchedule, testAccounts, type TaskDetail as TaskDetailData } from '../api'
import { connectTaskWS, type TaskEvent } from '../ws'
import { StatusBadge } from '../components/StatusBadge'
import { useConfirm } from '../components/ConfirmProvider'
import { FolderMappingModal } from '../components/FolderMappingModal'
import { RunLogModal } from '../components/RunLogModal'
import { AccountErrorsModal } from '../components/AccountErrorsModal'
import { KerioImportModal } from '../components/KerioImportModal'
const emptyAccount = { src_login: '', src_pass: '', dst_login: '', dst_pass: '' }
@@ -90,6 +91,7 @@ export function TaskDetail({ id }: { id: number }) {
const [live, setLive] = useState<Record<number, LiveProgress>>({})
const [showRuns, setShowRuns] = useState(false)
const [errorsFor, setErrorsFor] = useState<{ id: number; src_login: string } | null>(null)
const [kerioOpen, setKerioOpen] = useState(false)
const [selected, setSelected] = useState<Set<number>>(new Set())
const fileInputRef = useRef<HTMLInputElement>(null)
@@ -288,6 +290,20 @@ export function TaskDetail({ id }: { id: number }) {
}
}
async function onKerioImport(file: File, domain: string) {
setBusy('import')
setError(null)
try {
await importKerioCSV(id, file, domain)
setKerioOpen(false)
reload()
} catch (err) {
setError(err instanceof Error ? err.message : 'Kerio import failed')
} finally {
setBusy(null)
}
}
async function onDeleteAccount(accId: number, login: string) {
const ok = await confirm({
title: 'Remove account',
@@ -544,6 +560,9 @@ export function TaskDetail({ id }: { id: number }) {
{busy === 'import' ? 'Importing…' : 'Upload CSV'}
<input ref={fileInputRef} type="file" accept=".csv,text/csv" onChange={onFileChosen} disabled={busy !== null} />
</label>
<button type="button" className="btn" onClick={() => setKerioOpen(true)} disabled={busy !== null}>
Import from Kerio
</button>
<button type="button" className="link-btn" onClick={downloadExampleCSV}>
download example.csv
</button>
@@ -768,6 +787,12 @@ export function TaskDetail({ id }: { id: number }) {
)}
<RunLogModal taskId={id} open={showRuns} onClose={() => setShowRuns(false)} />
<AccountErrorsModal taskId={id} account={errorsFor} onClose={() => setErrorsFor(null)} />
<KerioImportModal
open={kerioOpen}
busy={busy === 'import'}
onClose={() => setKerioOpen(false)}
onSubmit={onKerioImport}
/>
</>
)
}