From 7690059f8b99409cd5f328bd29d6c6d89f35a656 Mon Sep 17 00:00:00 2001 From: alanv Date: Wed, 1 Oct 2025 11:48:30 -0500 Subject: [PATCH 1/9] Mark plate well samples as assay run materials inputs Clean up the material inputs during assay data row delete --- .../assay/AbstractAssayTsvDataHandler.java | 75 ++++++++++++++++--- .../plate/AssayPlateMetadataService.java | 8 ++ .../sample/AssaySampleLookupContext.java | 43 ++++++++++- .../api/assay/AssayResultUpdateService.java | 6 +- .../plate/AssayPlateMetadataServiceImpl.java | 32 ++++++++ 5 files changed, 146 insertions(+), 18 deletions(-) diff --git a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java index ebf14e7febc..497ffe561b7 100644 --- a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java +++ b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java @@ -517,7 +517,7 @@ public boolean next() throws BatchValidationException } Map rowBasedInputMaterials = new LinkedHashMap<>(); - DataIterator fileData = checkData(container, user, dataTable, dataDomain, iter, settings, resolver, protocolInputMaterials, cf, rowBasedInputMaterials); + DataIterator fileData = checkData(container, user, protocol, dataTable, dataDomain, iter, settings, resolver, protocolInputMaterials, cf, rowBasedInputMaterials); fileData = convertPropertyNamesToURIs(fileData, dataDomain); OntologyManager.RowCallback rowCallback = NO_OP_ROW_CALLBACK; @@ -682,16 +682,17 @@ private void checkColumns(Domain dataDomain, DataIterator rawData) throws BatchV * @param rowBasedInputMaterials the map of materials that are inputs to this run based on the data rows */ private DataIterator checkData( - Container container, - User user, - TableInfo dataTable, - Domain dataDomain, - DataIterator rawData, - DataLoaderSettings settings, - ParticipantVisitResolver resolver, - Map inputMaterials, - ContainerFilter containerFilter, - Map rowBasedInputMaterials + Container container, + User user, + ExpProtocol protocol, + TableInfo dataTable, + Domain dataDomain, + DataIterator rawData, + DataLoaderSettings settings, + ParticipantVisitResolver resolver, + Map inputMaterials, + ContainerFilter containerFilter, + Map rowBasedInputMaterials ) throws BatchValidationException { final ExperimentService exp = ExperimentService.get(); @@ -705,10 +706,14 @@ private DataIterator checkData( DomainProperty visitPropFinder = null; DomainProperty datePropFinder = null; DomainProperty targetStudyPropFinder = null; + DomainProperty platePropFinder = null; + DomainProperty wellLocationPropFinder = null; + DomainProperty wellLsidPropFinder = null; RemapCache cache = new RemapCache(); Map remappableLookup = new HashMap<>(); Map materialCache = new LongHashMap<>(); + Map> plateWellCache = new LongHashMap<>(); Map lookupToSampleTypeByName = new HashMap<>(); Map lookupToSampleTypeById = new HashMap<>(); @@ -748,6 +753,19 @@ else if (pd.getName().equalsIgnoreCase(AbstractAssayProvider.TARGET_STUDY_PROPER { targetStudyPropFinder = pd; } + else if (pd.getName().equalsIgnoreCase("WellLocation") && pd.getPropertyDescriptor().getPropertyType() == PropertyType.STRING) + { + wellLocationPropFinder = pd; + } + else if (pd.getName().equalsIgnoreCase("WellLsid") && pd.getPropertyDescriptor().getPropertyType() == PropertyType.STRING) + { + wellLsidPropFinder = pd; + } + else if (pd.getName().equalsIgnoreCase("Plate") && pd.getPropertyDescriptor().isLookup()) + { + platePropFinder = pd; + } + else { var sampleLookup = AssaySampleLookupContext.checkSampleLookup(container, user, pd); @@ -794,6 +812,13 @@ else if (sampleLookup.isLookup()) DomainProperty visitPD = visitPropFinder; DomainProperty datePD = datePropFinder; DomainProperty targetStudyPD = targetStudyPropFinder; + DomainProperty platePD = platePropFinder; + DomainProperty wellLocationPD = wellLocationPropFinder; + DomainProperty wellLsidPD = wellLsidPropFinder; + + AssayProvider provider = AssayService.get().getProvider(protocol); + boolean isPlateMetadataEnabled = provider != null && provider.isPlateMetadataEnabled(protocol); + boolean resolvePlateSamples = isPlateMetadataEnabled && platePD != null && wellLocationPD != null && wellLsidPD != null; return DataIteratorUtil.mapTransformer(rawData, inputCols -> { @@ -1042,6 +1067,34 @@ else if (validatorMap.containsKey(pd)) } } + // Wire up well samples as materials inputs + if (resolvePlateSamples) + { + Long plateId = (Long) map.get(platePD.getName()); + String wellLocation = (String) map.get(wellLocationPD.getName()); + Long sampleId = null; + ExpMaterial material = null; + + if (plateId != null && wellLocation != null) + { + Map wellSampleCache = plateWellCache.computeIfAbsent(plateId, (id) -> AssayPlateMetadataService.get().getWellLocationToSampleIdMap(plateId)); + sampleId = wellSampleCache.get(wellLocation); + } + + if (sampleId != null) + { + material = materialCache.computeIfAbsent(sampleId, (id) -> exp.getExpMaterial(id, containerFilter)); + } + + if (material != null) + { + // Note: we have to use the wellLsidPD as the Property Input Lineage Role because we resolve + // the material inputs for a plate assay based on WellLsid during delete. + rowBasedInputMaterials.putIfAbsent(material, AssayService.get().getPropertyInputLineageRole(wellLsidPD)); + rowInputLSIDs.add(material.getLSID()); + } + } + if (!errors.isEmpty()) throw new RuntimeValidationException(new ValidationException(errors, rowNum)); diff --git a/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java b/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java index 44c539c631c..f4b60adb492 100644 --- a/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java +++ b/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.assay.AssayProvider; import org.labkey.api.assay.AssayRunUploadContext; +import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.TableInfo; @@ -183,6 +184,13 @@ void applyHitSelectionCriteria( List runIds ) throws ValidationException; + /** + * Returns a Map of Well Location to Sample RowID for a given Plate ID. + */ + Map getWellLocationToSampleIdMap(Long plateId); + + boolean isWellLookup(ColumnInfo col); + /** * Should only be used to get a local instance of a plate schema where a contextual role might be involved. Schemas created this way are not cached, * and all other usages should retrieve schemas from the QueryService. diff --git a/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java b/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java index 25bf84be0f7..8c407a07a66 100644 --- a/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java +++ b/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.assay.AssayProvider; import org.labkey.api.assay.AssayService; +import org.labkey.api.assay.plate.AssayPlateMetadataService; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.CompareType; import org.labkey.api.data.Container; @@ -11,6 +12,7 @@ import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.SqlSelector; import org.labkey.api.data.TableInfo; +import org.labkey.api.exp.api.ExpProtocol; import org.labkey.api.exp.api.ExpProtocolApplication; import org.labkey.api.exp.api.ExpRun; import org.labkey.api.exp.api.ExpSampleType; @@ -93,6 +95,31 @@ public void trackSampleLookupChange(Container container, User user, TableInfo ta } } + /** + * Keeps track of experiment runs for assays that have columns with a sample lookup, including plate metadata + * enabled assays. Useful in data updates of assay run/result domains where sample lookups are subsequently + * reflected as material inputs to an experiment run. + * @param container Container from which to resolve sample lookup information. + * @param user User to utilize to resolve sample lookup information. + * @param table The table to utilize to resole sample lookup information. + * @param protocol The experiment protocol associated with the run. + * @param run The experiment run to track. + */ + public void trackSampleLookupChange(Container container, User user, TableInfo table, ExpProtocol protocol, ExpRun run) + { + if (table.getDomain() == null) return; + + AssayProvider provider = AssayService.get().getProvider(protocol); + + if (provider != null && provider.isPlateMetadataEnabled(protocol)) + { + _runIds.add(run.getRowId()); + } + + for (DomainProperty dp : table.getDomain().getNonBaseProperties()) + trackSampleLookupChange(container, user, table, table.getColumn(dp.getName()), run); + } + /** * Check if a domain property is considered a valid sample lookup. * @param container Container from which to resolve sample lookup information. @@ -112,8 +139,9 @@ private static SampleLookup checkSampleLookup(Container container, User user, @N ExpSampleType sampleType = ExperimentService.get().getLookupSampleType(dp, container, user); boolean isSampleLookup = sampleType != null || ExperimentService.get().isLookupToMaterials(dp); + boolean isWellLookup = dp.getName().equalsIgnoreCase("WellLsid") && col != null && AssayPlateMetadataService.get().isWellLookup(col); - return new SampleLookup(isSampleLookup, col, dp, sampleType); + return new SampleLookup(isSampleLookup || isWellLookup, col, dp, sampleType); } private SampleLookup checkSampleLookup(Container container, User user, TableInfo table, ColumnInfo col) @@ -384,7 +412,18 @@ private SQLFragment getLookupColumnSql(TableInfoKey tableInfoKey, SampleLookup s var role = AssayService.get().getPropertyInputLineageRole(sampleLookup.domainProperty); var sql = new SQLFragment(); - if (column.getJdbcType().isInteger()) + if (AssayPlateMetadataService.get().isWellLookup(column)) + { + // tableSql selects all the Well LSIDs for the given runId, we then select all the SampleIds from the + // assay.well table that match those Well LSIDs. + tableSql = QueryService.get().getSelectBuilder(table) + .columns(Set.of(column)) + .filter(tableFilter) + .buildSqlFragment(); + sql.append("SELECT WS.SampleId as MaterialRowId, ").appendValue(role).append(" AS MaterialInputRole\n"); + sql.append("FROM assay.well WS WHERE LSID IN (").append(tableSql).append(")"); + } + else if (column.getJdbcType().isInteger()) { sql.append("SELECT DA.").appendIdentifier(column.getAlias()).append(" AS MaterialRowId"); sql.append(", ?").add(role).append(" AS MaterialInputRole\n"); diff --git a/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java b/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java index 379feab34f1..0a0e8486513 100644 --- a/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java +++ b/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java @@ -368,11 +368,7 @@ protected Map deleteRow( } // Issue 51126: need to track and resync run/sample lineage on delete in the same way we do for update - if (datatableInfo.getDomain() != null) - { - for (DomainProperty dp : datatableInfo.getDomain().getNonBaseProperties()) - _assaySampleLookupContext.trackSampleLookupChange(container, user, datatableInfo, datatableInfo.getColumn(dp.getName()), run); - } + _assaySampleLookupContext.trackSampleLookupChange(container, user, datatableInfo, _schema.getProtocol(), run); return result; } diff --git a/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java b/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java index 43ddec4b5ba..fef0e0ff15b 100644 --- a/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java @@ -1517,6 +1517,38 @@ public String format(FieldKey fieldKey) return new PlateSchema(querySchema, contextualRoles); } + record WellSampleData(Long sampleId, Integer row, Integer col) {} + + @Override + public Map getWellLocationToSampleIdMap(Long plateId) + { + SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("plateid"), plateId); + List wells = new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), Set.of("SampleId", "Row", "Col"), filter, null).getArrayList(WellSampleData.class); + Map wellLocationToSampleIdMap = new HashMap<>(); + + for (WellSampleData well : wells) + { + PositionImpl pos = new PositionImpl(null, well.row, well.col); + wellLocationToSampleIdMap.put(pos.getDescription(), well.sampleId); + } + + return wellLocationToSampleIdMap; + } + + @Override + public boolean isWellLookup(ColumnInfo col) + { + if (col == null) return false; + + if (!col.isLookup()) return false; + + var wellTable = AssayDbSchema.getInstance().getTableInfoWell(); + var lookupTable = col.getFkTableInfo(); + + return lookupTable.getSchema().getName().equalsIgnoreCase(wellTable.getSchema().getName()) + && lookupTable.getName().equalsIgnoreCase(wellTable.getName()); + } + private static class PlateMetadataImportHelper extends SimpleAssayDataImportHelper { private final Map> _wellPositionMap; // map of plate position to well table From 533511fce4bcafab7571df90fcc026086b4d8d83 Mon Sep 17 00:00:00 2001 From: alanv Date: Fri, 3 Oct 2025 15:52:15 -0500 Subject: [PATCH 2/9] Bump components --- assay/package-lock.json | 8 ++++---- assay/package.json | 2 +- core/package-lock.json | 8 ++++---- core/package.json | 2 +- experiment/package-lock.json | 8 ++++---- experiment/package.json | 2 +- pipeline/package-lock.json | 8 ++++---- pipeline/package.json | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/assay/package-lock.json b/assay/package-lock.json index 0e7e0b96fb2..a0a1cdd0193 100644 --- a/assay/package-lock.json +++ b/assay/package-lock.json @@ -8,7 +8,7 @@ "name": "assay", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1" + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2458,9 +2458,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1.tgz", - "integrity": "sha512-HHniE4AIh1y4g/k5acx1XtdVPck/MpRpA3e6nacjedhVPS811DgRYwPuqrWu4dRYLWFKpG5ddGqTbyU1QYMxpA==", + "version": "6.62.8-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/assay/package.json b/assay/package.json index 6ef1ee70153..60c821315da 100644 --- a/assay/package.json +++ b/assay/package.json @@ -12,7 +12,7 @@ "clean": "rimraf resources/web/assay/gen && rimraf resources/views/gen && rimraf resources/web/gen" }, "dependencies": { - "@labkey/components": "6.63.1" + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/core/package-lock.json b/core/package-lock.json index 5633d6d3bdf..7aa2209b088 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -8,7 +8,7 @@ "name": "labkey-core", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1", + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { @@ -3504,9 +3504,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1.tgz", - "integrity": "sha512-HHniE4AIh1y4g/k5acx1XtdVPck/MpRpA3e6nacjedhVPS811DgRYwPuqrWu4dRYLWFKpG5ddGqTbyU1QYMxpA==", + "version": "6.62.8-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/core/package.json b/core/package.json index a102cf30290..6226e876a3b 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ } }, "dependencies": { - "@labkey/components": "6.63.1", + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { diff --git a/experiment/package-lock.json b/experiment/package-lock.json index 9bb3af3cd0c..ac797a45f71 100644 --- a/experiment/package-lock.json +++ b/experiment/package-lock.json @@ -8,7 +8,7 @@ "name": "experiment", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1" + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -3247,9 +3247,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1.tgz", - "integrity": "sha512-HHniE4AIh1y4g/k5acx1XtdVPck/MpRpA3e6nacjedhVPS811DgRYwPuqrWu4dRYLWFKpG5ddGqTbyU1QYMxpA==", + "version": "6.62.8-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/experiment/package.json b/experiment/package.json index df69e4ccddc..b62af38e122 100644 --- a/experiment/package.json +++ b/experiment/package.json @@ -13,7 +13,7 @@ "test-integration": "cross-env NODE_ENV=test jest --ci --runInBand -c test/js/jest.config.integration.js" }, "dependencies": { - "@labkey/components": "6.63.1" + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/pipeline/package-lock.json b/pipeline/package-lock.json index 0867f28150e..833ddff2078 100644 --- a/pipeline/package-lock.json +++ b/pipeline/package-lock.json @@ -8,7 +8,7 @@ "name": "pipeline", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1" + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2716,9 +2716,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1.tgz", - "integrity": "sha512-HHniE4AIh1y4g/k5acx1XtdVPck/MpRpA3e6nacjedhVPS811DgRYwPuqrWu4dRYLWFKpG5ddGqTbyU1QYMxpA==", + "version": "6.62.8-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/pipeline/package.json b/pipeline/package.json index 005d31b432d..e56c6368cfc 100644 --- a/pipeline/package.json +++ b/pipeline/package.json @@ -14,7 +14,7 @@ "build-prod": "npm run clean && cross-env NODE_ENV=production PROD_SOURCE_MAP=source-map webpack --config node_modules/@labkey/build/webpack/prod.config.js --color --progress --profile" }, "dependencies": { - "@labkey/components": "6.63.1" + "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", From a8f301fdf7b02c0b3c54f4150d5f18ee0781bdfb Mon Sep 17 00:00:00 2001 From: alanv Date: Tue, 7 Oct 2025 16:08:25 -0500 Subject: [PATCH 3/9] Address PR feedback --- .../assay/AbstractAssayTsvDataHandler.java | 20 +++++++++++------- .../plate/AssayPlateMetadataService.java | 2 +- .../sample/AssaySampleLookupContext.java | 21 +++++++++++-------- .../api/assay/AssayResultUpdateService.java | 2 +- .../plate/AssayPlateMetadataServiceImpl.java | 15 +++++-------- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java index 497ffe561b7..5e7de35f0b1 100644 --- a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java +++ b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java @@ -517,7 +517,7 @@ public boolean next() throws BatchValidationException } Map rowBasedInputMaterials = new LinkedHashMap<>(); - DataIterator fileData = checkData(container, user, protocol, dataTable, dataDomain, iter, settings, resolver, protocolInputMaterials, cf, rowBasedInputMaterials); + DataIterator fileData = checkData(container, user, provider, protocol, dataTable, dataDomain, iter, settings, resolver, protocolInputMaterials, cf, rowBasedInputMaterials); fileData = convertPropertyNamesToURIs(fileData, dataDomain); OntologyManager.RowCallback rowCallback = NO_OP_ROW_CALLBACK; @@ -684,6 +684,7 @@ private void checkColumns(Domain dataDomain, DataIterator rawData) throws BatchV private DataIterator checkData( Container container, User user, + AssayProvider provider, ExpProtocol protocol, TableInfo dataTable, Domain dataDomain, @@ -722,6 +723,7 @@ private DataIterator checkData( List columns = dataDomain.getProperties(); Map> validatorMap = new HashMap<>(); + boolean isPlateMetadataEnabled = provider.isPlateMetadataEnabled(protocol); for (DomainProperty pd : columns) { @@ -753,15 +755,21 @@ else if (pd.getName().equalsIgnoreCase(AbstractAssayProvider.TARGET_STUDY_PROPER { targetStudyPropFinder = pd; } - else if (pd.getName().equalsIgnoreCase("WellLocation") && pd.getPropertyDescriptor().getPropertyType() == PropertyType.STRING) + else if (isPlateMetadataEnabled && + pd.getName().equalsIgnoreCase("WellLocation") && + pd.getPropertyDescriptor().getPropertyType() == PropertyType.STRING) { wellLocationPropFinder = pd; } - else if (pd.getName().equalsIgnoreCase("WellLsid") && pd.getPropertyDescriptor().getPropertyType() == PropertyType.STRING) + else if (isPlateMetadataEnabled && + pd.getName().equalsIgnoreCase("WellLsid") && + pd.getPropertyDescriptor().getPropertyType() == PropertyType.STRING) { wellLsidPropFinder = pd; } - else if (pd.getName().equalsIgnoreCase("Plate") && pd.getPropertyDescriptor().isLookup()) + else if (isPlateMetadataEnabled && + pd.getName().equalsIgnoreCase("Plate") && + pd.getPropertyDescriptor().isLookup()) { platePropFinder = pd; } @@ -816,8 +824,6 @@ else if (sampleLookup.isLookup()) DomainProperty wellLocationPD = wellLocationPropFinder; DomainProperty wellLsidPD = wellLsidPropFinder; - AssayProvider provider = AssayService.get().getProvider(protocol); - boolean isPlateMetadataEnabled = provider != null && provider.isPlateMetadataEnabled(protocol); boolean resolvePlateSamples = isPlateMetadataEnabled && platePD != null && wellLocationPD != null && wellLsidPD != null; return DataIteratorUtil.mapTransformer(rawData, inputCols -> @@ -1077,7 +1083,7 @@ else if (validatorMap.containsKey(pd)) if (plateId != null && wellLocation != null) { - Map wellSampleCache = plateWellCache.computeIfAbsent(plateId, (id) -> AssayPlateMetadataService.get().getWellLocationToSampleIdMap(plateId)); + Map wellSampleCache = plateWellCache.computeIfAbsent(plateId, (id) -> AssayPlateMetadataService.get().getWellLocationToSampleIdMap(container, user, plateId)); sampleId = wellSampleCache.get(wellLocation); } diff --git a/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java b/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java index f4b60adb492..1f35bd5c560 100644 --- a/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java +++ b/api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java @@ -187,7 +187,7 @@ void applyHitSelectionCriteria( /** * Returns a Map of Well Location to Sample RowID for a given Plate ID. */ - Map getWellLocationToSampleIdMap(Long plateId); + Map getWellLocationToSampleIdMap(Container container, User user, Long plateId); boolean isWellLookup(ColumnInfo col); diff --git a/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java b/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java index 8c407a07a66..1c367c566f3 100644 --- a/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java +++ b/api/src/org/labkey/api/assay/sample/AssaySampleLookupContext.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.labkey.api.assay.AssayProtocolSchema; import org.labkey.api.assay.AssayProvider; import org.labkey.api.assay.AssayService; import org.labkey.api.assay.plate.AssayPlateMetadataService; @@ -102,22 +103,24 @@ public void trackSampleLookupChange(Container container, User user, TableInfo ta * @param container Container from which to resolve sample lookup information. * @param user User to utilize to resolve sample lookup information. * @param table The table to utilize to resole sample lookup information. - * @param protocol The experiment protocol associated with the run. + * @param schema The AssayProtocolSchema associated with the run. * @param run The experiment run to track. */ - public void trackSampleLookupChange(Container container, User user, TableInfo table, ExpProtocol protocol, ExpRun run) + public void trackSampleLookupChange(Container container, User user, TableInfo table, AssayProtocolSchema schema, ExpRun run) { if (table.getDomain() == null) return; - AssayProvider provider = AssayService.get().getProvider(protocol); - - if (provider != null && provider.isPlateMetadataEnabled(protocol)) - { - _runIds.add(run.getRowId()); - } - for (DomainProperty dp : table.getDomain().getNonBaseProperties()) trackSampleLookupChange(container, user, table, table.getColumn(dp.getName()), run); + + if (_runIds.contains(run.getRowId())) + return; + + AssayProvider provider = schema.getProvider(); + ExpProtocol protocol = schema.getProtocol(); + + if (provider.isPlateMetadataEnabled(protocol)) + _runIds.add(run.getRowId()); } /** diff --git a/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java b/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java index 0a0e8486513..c04afcebd78 100644 --- a/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java +++ b/assay/api-src/org/labkey/api/assay/AssayResultUpdateService.java @@ -368,7 +368,7 @@ protected Map deleteRow( } // Issue 51126: need to track and resync run/sample lineage on delete in the same way we do for update - _assaySampleLookupContext.trackSampleLookupChange(container, user, datatableInfo, _schema.getProtocol(), run); + _assaySampleLookupContext.trackSampleLookupChange(container, user, datatableInfo, _schema, run); return result; } diff --git a/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java b/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java index fef0e0ff15b..66f37dc79ca 100644 --- a/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java @@ -96,6 +96,7 @@ import org.labkey.api.util.logging.LogHelper; import org.labkey.api.view.ActionURL; import org.labkey.assay.TSVProtocolSchema; +import org.labkey.assay.plate.data.WellData; import org.labkey.assay.plate.model.WellBean; import org.labkey.assay.plate.query.PlateSchema; import org.labkey.assay.plate.query.PlateTable; @@ -1517,20 +1518,14 @@ public String format(FieldKey fieldKey) return new PlateSchema(querySchema, contextualRoles); } - record WellSampleData(Long sampleId, Integer row, Integer col) {} - @Override - public Map getWellLocationToSampleIdMap(Long plateId) + public Map getWellLocationToSampleIdMap(Container container, User user, Long plateId) { - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("plateid"), plateId); - List wells = new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), Set.of("SampleId", "Row", "Col"), filter, null).getArrayList(WellSampleData.class); Map wellLocationToSampleIdMap = new HashMap<>(); + List wellData = PlateManager.get().getWellData(container, user, plateId, true, false); - for (WellSampleData well : wells) - { - PositionImpl pos = new PositionImpl(null, well.row, well.col); - wellLocationToSampleIdMap.put(pos.getDescription(), well.sampleId); - } + for (WellData data : wellData) + wellLocationToSampleIdMap.put(data.getPosition(), data.getSampleId()); return wellLocationToSampleIdMap; } From 04f20d3cee3a46a5f8ea9138b30084735025cf42 Mon Sep 17 00:00:00 2001 From: alanv Date: Tue, 7 Oct 2025 16:42:49 -0500 Subject: [PATCH 4/9] Bump components --- assay/package-lock.json | 8 ++++---- assay/package.json | 2 +- core/package-lock.json | 8 ++++---- core/package.json | 2 +- experiment/package-lock.json | 8 ++++---- experiment/package.json | 2 +- pipeline/package-lock.json | 8 ++++---- pipeline/package.json | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/assay/package-lock.json b/assay/package-lock.json index a0a1cdd0193..d0cd0b9ba3a 100644 --- a/assay/package-lock.json +++ b/assay/package-lock.json @@ -8,7 +8,7 @@ "name": "assay", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2458,9 +2458,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.62.8-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", + "version": "6.63.0-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/assay/package.json b/assay/package.json index 60c821315da..673bc4df355 100644 --- a/assay/package.json +++ b/assay/package.json @@ -12,7 +12,7 @@ "clean": "rimraf resources/web/assay/gen && rimraf resources/views/gen && rimraf resources/web/gen" }, "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/core/package-lock.json b/core/package-lock.json index 7aa2209b088..f501557c1c1 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -8,7 +8,7 @@ "name": "labkey-core", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { @@ -3504,9 +3504,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.62.8-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", + "version": "6.63.0-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/core/package.json b/core/package.json index 6226e876a3b..3f4dbc2c38b 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ } }, "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { diff --git a/experiment/package-lock.json b/experiment/package-lock.json index ac797a45f71..75d584e8209 100644 --- a/experiment/package-lock.json +++ b/experiment/package-lock.json @@ -8,7 +8,7 @@ "name": "experiment", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -3247,9 +3247,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.62.8-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", + "version": "6.63.0-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/experiment/package.json b/experiment/package.json index b62af38e122..80791ea1f42 100644 --- a/experiment/package.json +++ b/experiment/package.json @@ -13,7 +13,7 @@ "test-integration": "cross-env NODE_ENV=test jest --ci --runInBand -c test/js/jest.config.integration.js" }, "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/pipeline/package-lock.json b/pipeline/package-lock.json index 833ddff2078..38b7467dc4a 100644 --- a/pipeline/package-lock.json +++ b/pipeline/package-lock.json @@ -8,7 +8,7 @@ "name": "pipeline", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2716,9 +2716,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.62.8-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.62.8-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-2cM1esIbHmPha4KP8T09GKgBo8K7EKrqPTAFU8ymTDByH9amQ2Xc+l0k3u5sVq0C0acfnXkZzLvGVjUdBdVh3A==", + "version": "6.63.0-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/pipeline/package.json b/pipeline/package.json index e56c6368cfc..a372126d544 100644 --- a/pipeline/package.json +++ b/pipeline/package.json @@ -14,7 +14,7 @@ "build-prod": "npm run clean && cross-env NODE_ENV=production PROD_SOURCE_MAP=source-map webpack --config node_modules/@labkey/build/webpack/prod.config.js --color --progress --profile" }, "dependencies": { - "@labkey/components": "6.62.8-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", From c774276dec2695dc9db58ae29d0841ddb9250013 Mon Sep 17 00:00:00 2001 From: alanv Date: Wed, 8 Oct 2025 09:37:28 -0500 Subject: [PATCH 5/9] Bump components --- assay/package-lock.json | 8 ++++---- assay/package.json | 2 +- core/package-lock.json | 8 ++++---- core/package.json | 2 +- experiment/package-lock.json | 8 ++++---- experiment/package.json | 2 +- pipeline/package-lock.json | 8 ++++---- pipeline/package.json | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/assay/package-lock.json b/assay/package-lock.json index d0cd0b9ba3a..466fa4b07d0 100644 --- a/assay/package-lock.json +++ b/assay/package-lock.json @@ -8,7 +8,7 @@ "name": "assay", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2458,9 +2458,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.0-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", + "version": "6.63.1-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/assay/package.json b/assay/package.json index 673bc4df355..23c430f6112 100644 --- a/assay/package.json +++ b/assay/package.json @@ -12,7 +12,7 @@ "clean": "rimraf resources/web/assay/gen && rimraf resources/views/gen && rimraf resources/web/gen" }, "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/core/package-lock.json b/core/package-lock.json index f501557c1c1..1cd4d469a4e 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -8,7 +8,7 @@ "name": "labkey-core", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { @@ -3504,9 +3504,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.0-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", + "version": "6.63.1-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/core/package.json b/core/package.json index 3f4dbc2c38b..291874d87eb 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ } }, "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { diff --git a/experiment/package-lock.json b/experiment/package-lock.json index 75d584e8209..6e267bc4a9c 100644 --- a/experiment/package-lock.json +++ b/experiment/package-lock.json @@ -8,7 +8,7 @@ "name": "experiment", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -3247,9 +3247,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.0-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", + "version": "6.63.1-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/experiment/package.json b/experiment/package.json index 80791ea1f42..84af46be890 100644 --- a/experiment/package.json +++ b/experiment/package.json @@ -13,7 +13,7 @@ "test-integration": "cross-env NODE_ENV=test jest --ci --runInBand -c test/js/jest.config.integration.js" }, "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/pipeline/package-lock.json b/pipeline/package-lock.json index 38b7467dc4a..0b26b107648 100644 --- a/pipeline/package-lock.json +++ b/pipeline/package-lock.json @@ -8,7 +8,7 @@ "name": "pipeline", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2716,9 +2716,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.0-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.0-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-4g6/2lZOJ2yXwwp9wAw/IgG0Vp8r5uUDXc3MBvowYwjJXUSHz8Yz+YiA1KpQXDKGCTpaSTpp07e0Y1EKBNnkzQ==", + "version": "6.63.1-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/pipeline/package.json b/pipeline/package.json index a372126d544..f08fc18a8ba 100644 --- a/pipeline/package.json +++ b/pipeline/package.json @@ -14,7 +14,7 @@ "build-prod": "npm run clean && cross-env NODE_ENV=production PROD_SOURCE_MAP=source-map webpack --config node_modules/@labkey/build/webpack/prod.config.js --color --progress --profile" }, "dependencies": { - "@labkey/components": "6.63.0-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", From 14229471c1e02338856126f5180736a8f00dc3f4 Mon Sep 17 00:00:00 2001 From: alanv Date: Wed, 8 Oct 2025 15:08:41 -0500 Subject: [PATCH 6/9] AbstractAssayTsvDataHandler: handle long conversion issues --- .../api/assay/AbstractAssayTsvDataHandler.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java index 5e7de35f0b1..2989a0c99e9 100644 --- a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java +++ b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java @@ -1076,7 +1076,20 @@ else if (validatorMap.containsKey(pd)) // Wire up well samples as materials inputs if (resolvePlateSamples) { - Long plateId = (Long) map.get(platePD.getName()); + Long _plateId; + + try + { + _plateId = (Long) map.get(platePD.getName()); + } + catch (ClassCastException e) + { + // File import can cause ClassCastException to be thrown, so we manually convert from integer. + Integer plateIdInt = (Integer) map.get(platePD.getName()); + _plateId = plateIdInt.longValue(); + } + + Long plateId = _plateId; // Re-assign so it's final String wellLocation = (String) map.get(wellLocationPD.getName()); Long sampleId = null; ExpMaterial material = null; From bfaf2d86063817a67310d4ddd96629432df2bd67 Mon Sep 17 00:00:00 2001 From: alanv Date: Wed, 8 Oct 2025 15:10:35 -0500 Subject: [PATCH 7/9] Bump components --- assay/package-lock.json | 8 ++++---- assay/package.json | 2 +- core/package-lock.json | 8 ++++---- core/package.json | 2 +- experiment/package-lock.json | 8 ++++---- experiment/package.json | 2 +- pipeline/package-lock.json | 8 ++++---- pipeline/package.json | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/assay/package-lock.json b/assay/package-lock.json index 466fa4b07d0..6528867eb65 100644 --- a/assay/package-lock.json +++ b/assay/package-lock.json @@ -8,7 +8,7 @@ "name": "assay", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2458,9 +2458,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", + "version": "6.63.2-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/assay/package.json b/assay/package.json index 23c430f6112..4760558225b 100644 --- a/assay/package.json +++ b/assay/package.json @@ -12,7 +12,7 @@ "clean": "rimraf resources/web/assay/gen && rimraf resources/views/gen && rimraf resources/web/gen" }, "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/core/package-lock.json b/core/package-lock.json index 1cd4d469a4e..07396f9e219 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -8,7 +8,7 @@ "name": "labkey-core", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { @@ -3504,9 +3504,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", + "version": "6.63.2-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/core/package.json b/core/package.json index 291874d87eb..25f7692b885 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ } }, "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0", "@labkey/themes": "1.4.2" }, "devDependencies": { diff --git a/experiment/package-lock.json b/experiment/package-lock.json index 6e267bc4a9c..9b44573d1a9 100644 --- a/experiment/package-lock.json +++ b/experiment/package-lock.json @@ -8,7 +8,7 @@ "name": "experiment", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -3247,9 +3247,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", + "version": "6.63.2-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/experiment/package.json b/experiment/package.json index 84af46be890..d93333acc90 100644 --- a/experiment/package.json +++ b/experiment/package.json @@ -13,7 +13,7 @@ "test-integration": "cross-env NODE_ENV=test jest --ci --runInBand -c test/js/jest.config.integration.js" }, "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/pipeline/package-lock.json b/pipeline/package-lock.json index 0b26b107648..814fb2f96de 100644 --- a/pipeline/package-lock.json +++ b/pipeline/package-lock.json @@ -8,7 +8,7 @@ "name": "pipeline", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2716,9 +2716,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.1-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.1-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-Nt7bqWozrXMbSqTSbbLxLCj4sQ+YFJQ/0ukZeYXdGTpuZjYIhYpQ4cpqWmGjI/C8CcekwlMuiduXqjLkIeBmCQ==", + "version": "6.63.2-fb-plate-assay-material-inputs.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", + "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/pipeline/package.json b/pipeline/package.json index f08fc18a8ba..fc4e6c4caf1 100644 --- a/pipeline/package.json +++ b/pipeline/package.json @@ -14,7 +14,7 @@ "build-prod": "npm run clean && cross-env NODE_ENV=production PROD_SOURCE_MAP=source-map webpack --config node_modules/@labkey/build/webpack/prod.config.js --color --progress --profile" }, "dependencies": { - "@labkey/components": "6.63.1-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" }, "devDependencies": { "@labkey/build": "8.6.0", From 39849e4fb0d38d4b71bb7b2e584239cb1cba5f05 Mon Sep 17 00:00:00 2001 From: alanv Date: Wed, 8 Oct 2025 18:22:44 -0500 Subject: [PATCH 8/9] Use IntegerUtils.asLong --- .../api/assay/AbstractAssayTsvDataHandler.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java index 2989a0c99e9..f8f3f3b2158 100644 --- a/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java +++ b/api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java @@ -93,6 +93,7 @@ import org.labkey.api.study.StudyService; import org.labkey.api.study.assay.ParticipantVisitResolver; import org.labkey.api.study.publish.StudyPublishService; +import org.labkey.api.util.IntegerUtils; import org.labkey.api.util.PageFlowUtil; import org.labkey.api.util.ResultSetUtil; import org.labkey.api.util.UnexpectedException; @@ -1076,20 +1077,7 @@ else if (validatorMap.containsKey(pd)) // Wire up well samples as materials inputs if (resolvePlateSamples) { - Long _plateId; - - try - { - _plateId = (Long) map.get(platePD.getName()); - } - catch (ClassCastException e) - { - // File import can cause ClassCastException to be thrown, so we manually convert from integer. - Integer plateIdInt = (Integer) map.get(platePD.getName()); - _plateId = plateIdInt.longValue(); - } - - Long plateId = _plateId; // Re-assign so it's final + Long plateId = IntegerUtils.asLong(map.get(platePD.getName())); String wellLocation = (String) map.get(wellLocationPD.getName()); Long sampleId = null; ExpMaterial material = null; From f8bb28fdc96c58bbbafc9a72623b1d8dae144ffe Mon Sep 17 00:00:00 2001 From: alanv Date: Thu, 9 Oct 2025 14:46:26 -0500 Subject: [PATCH 9/9] Bump components --- assay/package-lock.json | 8 ++++---- assay/package.json | 2 +- core/package-lock.json | 8 ++++---- core/package.json | 2 +- experiment/package-lock.json | 8 ++++---- experiment/package.json | 2 +- pipeline/package-lock.json | 8 ++++---- pipeline/package.json | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/assay/package-lock.json b/assay/package-lock.json index 6528867eb65..1dd0742aad6 100644 --- a/assay/package-lock.json +++ b/assay/package-lock.json @@ -8,7 +8,7 @@ "name": "assay", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.64.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2458,9 +2458,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.2-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", + "version": "6.64.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.64.0.tgz", + "integrity": "sha512-PvaxxI03mJ64L/F0FFWrtHDFwrFiyYm+/w/uyCTjFv/RZ/A+CIjkb5+v4iaQyAzJPUr1HzVPUfDlNxWkd3r2OQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/assay/package.json b/assay/package.json index 4760558225b..6d212f4b7c5 100644 --- a/assay/package.json +++ b/assay/package.json @@ -12,7 +12,7 @@ "clean": "rimraf resources/web/assay/gen && rimraf resources/views/gen && rimraf resources/web/gen" }, "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.64.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/core/package-lock.json b/core/package-lock.json index 07396f9e219..46504810605 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -8,7 +8,7 @@ "name": "labkey-core", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.64.0", "@labkey/themes": "1.4.2" }, "devDependencies": { @@ -3504,9 +3504,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.2-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", + "version": "6.64.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.64.0.tgz", + "integrity": "sha512-PvaxxI03mJ64L/F0FFWrtHDFwrFiyYm+/w/uyCTjFv/RZ/A+CIjkb5+v4iaQyAzJPUr1HzVPUfDlNxWkd3r2OQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/core/package.json b/core/package.json index 25f7692b885..687653438c5 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ } }, "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0", + "@labkey/components": "6.64.0", "@labkey/themes": "1.4.2" }, "devDependencies": { diff --git a/experiment/package-lock.json b/experiment/package-lock.json index 9b44573d1a9..03bae7fdb3f 100644 --- a/experiment/package-lock.json +++ b/experiment/package-lock.json @@ -8,7 +8,7 @@ "name": "experiment", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.64.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -3247,9 +3247,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.2-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", + "version": "6.64.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.64.0.tgz", + "integrity": "sha512-PvaxxI03mJ64L/F0FFWrtHDFwrFiyYm+/w/uyCTjFv/RZ/A+CIjkb5+v4iaQyAzJPUr1HzVPUfDlNxWkd3r2OQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/experiment/package.json b/experiment/package.json index d93333acc90..98d3265698d 100644 --- a/experiment/package.json +++ b/experiment/package.json @@ -13,7 +13,7 @@ "test-integration": "cross-env NODE_ENV=test jest --ci --runInBand -c test/js/jest.config.integration.js" }, "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.64.0" }, "devDependencies": { "@labkey/build": "8.6.0", diff --git a/pipeline/package-lock.json b/pipeline/package-lock.json index 814fb2f96de..aa9dd37a6a6 100644 --- a/pipeline/package-lock.json +++ b/pipeline/package-lock.json @@ -8,7 +8,7 @@ "name": "pipeline", "version": "0.0.0", "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.64.0" }, "devDependencies": { "@labkey/build": "8.6.0", @@ -2716,9 +2716,9 @@ } }, "node_modules/@labkey/components": { - "version": "6.63.2-fb-plate-assay-material-inputs.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.63.2-fb-plate-assay-material-inputs.0.tgz", - "integrity": "sha512-9ppFdKfxfdH+0Rzhz6i2Q981Z3eApqNy9jblwG2jl6uvCmaGaiTewUonAHrj7D7ihCj027gI3WCTKiYywHpp6A==", + "version": "6.64.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-6.64.0.tgz", + "integrity": "sha512-PvaxxI03mJ64L/F0FFWrtHDFwrFiyYm+/w/uyCTjFv/RZ/A+CIjkb5+v4iaQyAzJPUr1HzVPUfDlNxWkd3r2OQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/pipeline/package.json b/pipeline/package.json index fc4e6c4caf1..ce5c72e47ac 100644 --- a/pipeline/package.json +++ b/pipeline/package.json @@ -14,7 +14,7 @@ "build-prod": "npm run clean && cross-env NODE_ENV=production PROD_SOURCE_MAP=source-map webpack --config node_modules/@labkey/build/webpack/prod.config.js --color --progress --profile" }, "dependencies": { - "@labkey/components": "6.63.2-fb-plate-assay-material-inputs.0" + "@labkey/components": "6.64.0" }, "devDependencies": { "@labkey/build": "8.6.0",