From d741c46d4e0dbbbacdcf7e95f725022c262de8c5 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:29:36 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20show=20Ers=C3=A4tt=20befintlig=20import?= =?UTF-8?q?=20button=20for=20duplicate-file=20SIE=20uploads=20(#270)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The duplicate (file-hash) error path returned an importId but the UI only captured it for the duplicate_period branch, so users saw a misleading "ta bort under Bokföring" message with no way to act on it. The replace flow (and its BFL 5:5 audit trail) is identical in both cases, so expose the existing button for both. Co-authored-by: Claude Opus 4.7 (1M context) --- app/(dashboard)/import/page.tsx | 12 ++++++------ components/import/SIEUploadStep.tsx | 13 +++++-------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/(dashboard)/import/page.tsx b/app/(dashboard)/import/page.tsx index 5dde7586..701e1e81 100644 --- a/app/(dashboard)/import/page.tsx +++ b/app/(dashboard)/import/page.tsx @@ -334,7 +334,7 @@ function SIEImportWizard() { const [errorType, setErrorType] = useState<'duplicate' | 'duplicate_period' | 'validation' | 'parse' | undefined>() const [validationErrors, setValidationErrors] = useState([]) const [validationWarnings, setValidationWarnings] = useState([]) - const [duplicatePeriodImportId, setDuplicatePeriodImportId] = useState(null) + const [duplicateImportId, setDuplicateImportId] = useState(null) const [isReplacing, setIsReplacing] = useState(false) const [file, setFile] = useState(null) @@ -380,8 +380,8 @@ function SIEImportWizard() { if (type === 'duplicate' || type === 'duplicate_period') { setErrorType(type) setError(data.message) - if (type === 'duplicate_period' && data.importId) { - setDuplicatePeriodImportId(data.importId) + if (data.importId) { + setDuplicateImportId(data.importId) } toast({ title: type === 'duplicate' ? 'Filen har redan importerats' : 'Överlappande räkenskapsår', description: data.message, variant: 'destructive' }) } else if (type === 'validation') { @@ -459,7 +459,7 @@ function SIEImportWizard() { // Clear error state and re-trigger the file upload setError(null) setErrorType(undefined) - setDuplicatePeriodImportId(null) + setDuplicateImportId(null) // Small delay so the user sees the success toast before re-upload starts await new Promise(resolve => setTimeout(resolve, 500)) @@ -618,7 +618,7 @@ function SIEImportWizard() { const handleNewImport = () => { setStep('upload'); setFile(null); setParsed(null); setMappings([]) setPreview(null); setIssues([]); setImportResult(null); setError(null); setErrorType(undefined) - setValidationErrors([]); setValidationWarnings([]); setDuplicatePeriodImportId(null) + setValidationErrors([]); setValidationWarnings([]); setDuplicateImportId(null) setSieAccounts([]); setIsCreatingAccounts(false) } @@ -645,7 +645,7 @@ function SIEImportWizard() { - {step === 'upload' && } + {step === 'upload' && } {step === 'preview' && preview && ( Promise isReplacing?: boolean } -export default function SIEUploadStep({ onFileSelect, isLoading, error, errorType, validationErrors, validationWarnings, duplicatePeriodImportId, onReplace, isReplacing }: SIEUploadStepProps) { +export default function SIEUploadStep({ onFileSelect, isLoading, error, errorType, validationErrors, validationWarnings, duplicateImportId, onReplace, isReplacing }: SIEUploadStepProps) { const [isDragging, setIsDragging] = useState(false) const [selectedFile, setSelectedFile] = useState(null) const [loadingPhase, setLoadingPhase] = useState(0) @@ -192,13 +192,10 @@ export default function SIEUploadStep({ onFileSelect, isLoading, error, errorTyp {/* Actionable guidance */}
- {errorType === 'duplicate' && ( -

Om du vill importera om filen, ta först bort den tidigare importen under Bokföring.

- )} - {errorType === 'duplicate_period' && ( + {(errorType === 'duplicate' || errorType === 'duplicate_period') && (

Den befintliga importens verifikationer kommer att makuleras (status ändras till "makulerad"). De finns kvar som spårbar historik.

- {duplicatePeriodImportId && onReplace && ( + {duplicateImportId && onReplace && (