From 667ddf84305ba209c9180de0d639c7031fd7384e Mon Sep 17 00:00:00 2001
From: Jason Loux
Date: Tue, 17 Mar 2026 10:33:45 -0400
Subject: [PATCH 1/5] Initial implementation
---
package-lock.json | 4 ++--
src/views/import/ImportExperiment.vue | 32 +++++++++++++++++++++++++--
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 494aa6eb..1c892c89 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "bi-web",
- "version": "v1.0.0+789",
+ "version": "v1.3.0+907",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bi-web",
- "version": "v1.0.0+789",
+ "version": "v1.3.0+907",
"hasInstallScript": true,
"dependencies": {
"@casl/ability": "~4.0.0",
diff --git a/src/views/import/ImportExperiment.vue b/src/views/import/ImportExperiment.vue
index da6739f3..3c1e63af 100644
--- a/src/views/import/ImportExperiment.vue
+++ b/src/views/import/ImportExperiment.vue
@@ -308,12 +308,19 @@ import {ImportObjectState} from "@/breeding-insight/model/import/ImportObjectSta
import { GeoCoordinates } from '@/breeding-insight/model/GeoCoordinates';
import {ExperimentUserInput} from "@/breeding-insight/model/ExperimentUserInput";
import {StringFormatters} from "../../breeding-insight/utils/StringFormatters";
+import {TraitService} from "@/breeding-insight/service/TraitService";
+import {mapGetters} from "vuex";
+import {Program} from "@/breeding-insight/model/Program";
+import {Trait} from "@/breeding-insight/model/Trait";
@Component({
computed: {
StringFormatters() {
return StringFormatters
- }
+ },
+ ...mapGetters([
+ 'activeProgram'
+ ]),
},
components: {
ImportInfoTemplateMessageBox, ConfirmImportMessageBox, ImportTemplate, AlertTriangleIcon, BasicInputField, ExpandableTable
@@ -327,6 +334,15 @@ import {StringFormatters} from "../../breeding-insight/utils/StringFormatters";
})
export default class ImportExperiment extends ProgramsBase {
+ async mounted() {
+ // Hopefully no more than 100 ontology terms
+ let traitResponse = await TraitService.getTraits(this.activeProgram.id, {}, {pageSize: 100, page: 1});
+
+ this.traits = traitResponse.value.result.data.map(
+ (trait: any) => trait.observationVariableName
+ );
+ }
+
private experimentImportTemplateName = 'ExperimentsTemplateMap';
private confirmImportState: DataFormEventBusHandler = new DataFormEventBusHandler();
private phenotypeColumns?: Array = [];
@@ -334,6 +350,10 @@ export default class ImportExperiment extends ProgramsBase {
private experimentUserInput: ExperimentUserInput = new ExperimentUserInput();
private repeatObservationsCount = 10;
+
+ private activeProgram!: Program;
+ private traits : String[] = [];
+
get showProceedDialog() {
return this.experimentUserInput.overwrite;
}
@@ -415,7 +435,15 @@ export default class ImportExperiment extends ProgramsBase {
}
previewDataLoaded(dynamicColumns: String[]) {
- this.phenotypeColumns = dynamicColumns;
+
+ for (const dynCol of dynamicColumns) {
+ if (this.traits.includes(dynCol)) {
+ this.phenotypeColumns.push(dynCol);
+ } else {
+ console.log(`Dynamic column [${dynCol}] not found in the list of available traits for program [${this.activeProgram.name}]`)
+ }
+ }
+
this.createObservationIndexMap();
}
From 4eafe82b828cd8e0e8d32f6bc818779d7413a2d8 Mon Sep 17 00:00:00 2001
From: Jason Loux
Date: Tue, 17 Mar 2026 12:07:09 -0400
Subject: [PATCH 2/5] Fix bug where if import tab not reloaded previews would
break
---
src/views/import/ImportExperiment.vue | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/views/import/ImportExperiment.vue b/src/views/import/ImportExperiment.vue
index 3c1e63af..ec437912 100644
--- a/src/views/import/ImportExperiment.vue
+++ b/src/views/import/ImportExperiment.vue
@@ -436,6 +436,10 @@ export default class ImportExperiment extends ProgramsBase {
previewDataLoaded(dynamicColumns: String[]) {
+ // To ensure correct phenotype mapping when multiple appends/create experiments on a single page load,
+ // reset the phenotypeColumns every time a new preview is loaded.
+ this.phenotypeColumns = [];
+
for (const dynCol of dynamicColumns) {
if (this.traits.includes(dynCol)) {
this.phenotypeColumns.push(dynCol);
From aec232cb7ff7ede4577b27185365a27a75a5a40f Mon Sep 17 00:00:00 2001
From: Jason Loux
Date: Wed, 18 Mar 2026 10:06:55 -0400
Subject: [PATCH 3/5] Utilize new obsVarCount stat, remove filter on OUID
OUIDs will now be filtered by function which filters on dynCols
that exist in the associated trait list for a program.
---
src/views/import/ImportExperiment.vue | 6 ++++--
src/views/import/ImportTemplate.vue | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/views/import/ImportExperiment.vue b/src/views/import/ImportExperiment.vue
index ec437912..7316437a 100644
--- a/src/views/import/ImportExperiment.vue
+++ b/src/views/import/ImportExperiment.vue
@@ -83,7 +83,7 @@
Import Summary
-
Observation Variables: {{ dynamicColumns.filter( obsVar => !obsVar.startsWith("TS:") ).length }}
+
Observation Variables: {{ statistics.Observation_Variables.newObjectCount }}
New Observations: {{ statistics.Observations.newObjectCount }}
Existing Observations: {{ statistics.Existing_Observations.newObjectCount }}
@@ -444,11 +444,13 @@ export default class ImportExperiment extends ProgramsBase {
if (this.traits.includes(dynCol)) {
this.phenotypeColumns.push(dynCol);
} else {
- console.log(`Dynamic column [${dynCol}] not found in the list of available traits for program [${this.activeProgram.name}]`)
+ console.log(`Dynamic column [${dynCol}] not found in the list of available traits for program [${this.activeProgram.name}]`);
}
}
this.createObservationIndexMap();
+
+ return this.phenotypeColumns.length;
}
// Map phenotypeColumn indices to brapi observation indices for use in highlighting
diff --git a/src/views/import/ImportTemplate.vue b/src/views/import/ImportTemplate.vue
index 0ef2a29e..aaafb529 100644
--- a/src/views/import/ImportTemplate.vue
+++ b/src/views/import/ImportTemplate.vue
@@ -633,7 +633,7 @@ export default class ImportTemplate extends ProgramsBase {
this.previewData = previewResponse.preview.rows as any[];
this.newObjectCounts = previewResponse.preview.statistics;
this.$emit('statistics-loaded', this.newObjectCounts);
- this.dynamicColumns = previewResponse.preview.dynamicColumnNames.filter(name => !name.includes('ObsUnitID'));
+ this.dynamicColumns = previewResponse.preview.dynamicColumnNames;
this.$emit('preview-data-loaded', this.dynamicColumns);
this.importService.send(ImportEvent.IMPORT_SUCCESS);
// TODO: Temp pagination
From 1d650a913d3f1162d7a830e04a66038a86de9348 Mon Sep 17 00:00:00 2001
From: Jason Loux
Date: Wed, 18 Mar 2026 11:20:50 -0400
Subject: [PATCH 4/5] Restore package-lock.json to develop
---
package-lock.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 1c892c89..494aa6eb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "bi-web",
- "version": "v1.3.0+907",
+ "version": "v1.0.0+789",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bi-web",
- "version": "v1.3.0+907",
+ "version": "v1.0.0+789",
"hasInstallScript": true,
"dependencies": {
"@casl/ability": "~4.0.0",
From 351a134fabbb280a2ef3aea91e826ed13742dc51 Mon Sep 17 00:00:00 2001
From: Jason Loux
Date: Fri, 20 Mar 2026 12:34:29 -0400
Subject: [PATCH 5/5] Use vue-js logging, remove erroneous return
---
src/views/import/ImportExperiment.vue | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/views/import/ImportExperiment.vue b/src/views/import/ImportExperiment.vue
index 7316437a..f55959f7 100644
--- a/src/views/import/ImportExperiment.vue
+++ b/src/views/import/ImportExperiment.vue
@@ -338,6 +338,10 @@ export default class ImportExperiment extends ProgramsBase {
// Hopefully no more than 100 ontology terms
let traitResponse = await TraitService.getTraits(this.activeProgram.id, {}, {pageSize: 100, page: 1});
+ if (traitResponse.value.metadata.pagination.totalCount > 100) {
+ this.$log.error("More than 100 traits detected while loading experiment import preview");
+ }
+
this.traits = traitResponse.value.result.data.map(
(trait: any) => trait.observationVariableName
);
@@ -444,13 +448,11 @@ export default class ImportExperiment extends ProgramsBase {
if (this.traits.includes(dynCol)) {
this.phenotypeColumns.push(dynCol);
} else {
- console.log(`Dynamic column [${dynCol}] not found in the list of available traits for program [${this.activeProgram.name}]`);
+ this.$log.info(`Dynamic column [${dynCol}] not found in the list of available traits for program [${this.activeProgram.name}]`);
}
}
this.createObservationIndexMap();
-
- return this.phenotypeColumns.length;
}
// Map phenotypeColumn indices to brapi observation indices for use in highlighting