diff --git a/extralit-frontend/components/features/import/ImportFlow.vue b/extralit-frontend/components/features/import/ImportFlow.vue index ceca12b1f..decaef802 100644 --- a/extralit-frontend/components/features/import/ImportFlow.vue +++ b/extralit-frontend/components/features/import/ImportFlow.vue @@ -36,6 +36,7 @@ :pdf-data="pdfData" :workspace="workspace" :loading="isAnalyzing" + :initial-document-actions="uploadData.documentActions" @update="handleAnalysisUpdate" @analysis-complete="handleAnalysisComplete" /> @@ -273,6 +274,7 @@ export default { dataframeData: data.dataframeData || null, rawContent: data.rawContent || "", }; + this.uploadData.documentActions = {}; this.clearError(); }, @@ -282,6 +284,7 @@ export default { unmatchedFiles: data.unmatchedFiles || [], totalFiles: data.totalFiles || 0, }; + this.uploadData.documentActions = {}; this.clearError(); }, diff --git a/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.spec.ts b/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.spec.ts new file mode 100644 index 000000000..bf77d80df --- /dev/null +++ b/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.spec.ts @@ -0,0 +1,49 @@ +import ImportAnalysisTable from "./ImportAnalysisTable.vue"; +import ImportFlow from "../ImportFlow.vue"; + +describe("ImportAnalysisTable document actions", () => { + it("restores persisted actions when the review step is remounted", () => { + const component = ImportAnalysisTable as any; + const state = component.data.call({ initialDocumentActions: { keep: "ignore" } }); + + expect(state.localDocumentActions).toEqual({ keep: "ignore" }); + expect(state.editableTableData).toEqual([]); + }); + + it("keeps only persisted actions that belong to the latest analysis", () => { + const component = ImportAnalysisTable as any; + const context = { + initialDocumentActions: { keep: "ignore", stale: "update" }, + localDocumentActions: {}, + $emit: vi.fn(), + emitUpdate: vi.fn(), + }; + + component.watch.analysisResult.handler.call(context, { + documents: { keep: {} }, + }); + + expect(context.localDocumentActions).toEqual({ keep: "ignore" }); + expect(context.$emit).toHaveBeenCalledWith("analysis-complete", { documents: { keep: {} } }); + expect(context.emitUpdate).toHaveBeenCalledOnce(); + }); +}); + +describe("ImportFlow input changes", () => { + it("clears persisted actions when the bibliography or PDFs change", () => { + const component = ImportFlow as any; + const context = { + bibData: {}, + pdfData: {}, + uploadData: { documentActions: { previous: "ignore" } }, + clearError: vi.fn(), + }; + + component.methods.handleBibUpdate.call(context, { fileName: "new.bib" }); + expect(context.uploadData.documentActions).toEqual({}); + + context.uploadData.documentActions = { previous: "ignore" }; + component.methods.handlePdfUpdate.call(context, { totalFiles: 1 }); + expect(context.uploadData.documentActions).toEqual({}); + }); +}); diff --git a/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue b/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue index b8a760646..7e4048b90 100644 --- a/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue +++ b/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue @@ -107,13 +107,17 @@ export default { type: Boolean, default: false, }, + initialDocumentActions: { + type: Object as () => Record, + default: () => ({}), + }, }, emits: ["update", "analysis-complete"], data() { return { - localDocumentActions: {} as Record, + localDocumentActions: { ...this.initialDocumentActions } as Record, editableTableData: [] as any[], }; }, @@ -439,8 +443,18 @@ export default { analysisResult: { handler(newData: ImportAnalysisResponse) { if (newData) { - // Reset local document actions when new analysis data arrives - this.localDocumentActions = {}; + // Filter persisted actions to only keys present in the new analysis, + // discarding stale entries from a previous Bib/PDF set + const validKeys = new Set(Object.keys(newData.documents ?? {})); + const filtered: Record = {}; + if (this.initialDocumentActions) { + for (const [key, status] of Object.entries(this.initialDocumentActions)) { + if (validKeys.has(key)) { + filtered[key] = status as ImportStatus; + } + } + } + this.localDocumentActions = filtered; // Emit the analysis complete event this.$emit("analysis-complete", newData); // Emit initial update