diff --git a/extralit-frontend/components/base/base-render-table/RenderTable.vue b/extralit-frontend/components/base/base-render-table/RenderTable.vue index 0a17be224..af30e6bf5 100644 --- a/extralit-frontend/components/base/base-render-table/RenderTable.vue +++ b/extralit-frontend/components/base/base-render-table/RenderTable.vue @@ -110,6 +110,11 @@ export default { type: Array as () => Question[], default: () => [], }, + // Allows parent components to specify formatters, cellClick handlers, frozen, etc. + columnConfigs: { + type: Array as () => Array>, + default: () => [], + }, }, model: { @@ -194,10 +199,22 @@ export default { columnsConfig() { if (!this.tableJSON?.schema) return []; + // Create a map of custom column configs by field name for quick lookup + const customConfigMap = new Map>(); + if (this.columnConfigs && this.columnConfigs.length > 0) { + this.columnConfigs.forEach((config: Record) => { + if (config.field) { + customConfigMap.set(config.field, config); + } + }); + } + var configs = this.tableJSON.schema.fields.map((column: DataFrameField) => { const commonConfig = this.generateColumnConfig(column.name); const editableConfig = this.generateColumnEditableConfig(column.name); - return { ...commonConfig, ...editableConfig, ...column }; + // Merge with custom config if provided (custom config takes precedence) + const customConfig = customConfigMap.get(column.name) || {}; + return { ...commonConfig, ...editableConfig, ...column, ...customConfig }; }); if (!this.editable) { diff --git a/extralit-frontend/components/base/base-simple-table/BaseSimpleTable.vue b/extralit-frontend/components/base/base-simple-table/BaseSimpleTable.vue index a05df91f7..cf8014eea 100644 --- a/extralit-frontend/components/base/base-simple-table/BaseSimpleTable.vue +++ b/extralit-frontend/components/base/base-simple-table/BaseSimpleTable.vue @@ -6,6 +6,7 @@ :editable="editable" :hasValidValues="hasValidValues" :questions="questions" + :columnConfigs="columns" :validation="validation || validators" @table-built="$emit('table-built')" @row-click="(e, row) => $emit('row-click', e, row)" diff --git a/extralit-frontend/components/features/import/ImportFlow.vue b/extralit-frontend/components/features/import/ImportFlow.vue index ff4e66670..e015cd9bb 100644 --- a/extralit-frontend/components/features/import/ImportFlow.vue +++ b/extralit-frontend/components/features/import/ImportFlow.vue @@ -11,7 +11,9 @@ @@ -243,6 +245,7 @@ export default { dataframeData: data.dataframeData || null, rawContent: data.rawContent || "", }; + this.uploadData.documentActions = {}; this.clearError(); }, @@ -252,6 +255,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.vue b/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue index 989cb67ee..4929a5ba9 100644 --- a/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue +++ b/extralit-frontend/components/features/import/analysis/ImportAnalysisTable.vue @@ -116,17 +116,33 @@ export default { type: Boolean, default: false, }, + initialDocumentActions: { + type: Object as () => Record, + default: () => ({}), + }, }, emits: ["update", "analysis-complete"], data() { return { - localDocumentActions: {} as Record, + // Initialize from prop to persist state when navigating back/forward + localDocumentActions: { ...this.initialDocumentActions } as Record, editableTableData: [] as any[], }; }, + mounted() { + // Restore document actions from parent state when component is remounted + if (this.initialDocumentActions && Object.keys(this.initialDocumentActions).length > 0) { + this.localDocumentActions = { ...this.initialDocumentActions }; + // Emit update to sync state with parent + this.$nextTick(() => { + this.emitUpdate(); + }); + } + }, + computed: { summaryData() { if (this.analysisResult) { @@ -447,8 +463,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