diff --git a/api/src/org/labkey/api/data/ConvertHelper.java b/api/src/org/labkey/api/data/ConvertHelper.java index 47c1ee02103..f063bed4d0e 100644 --- a/api/src/org/labkey/api/data/ConvertHelper.java +++ b/api/src/org/labkey/api/data/ConvertHelper.java @@ -1278,7 +1278,7 @@ public static String getStandardConversionErrorMessage(Object value, String fiel // Issue 50768: Need a better error message if date value is not in the expected format. if (fieldType.equalsIgnoreCase("date") || fieldType.equalsIgnoreCase("datetime") || fieldType.equalsIgnoreCase("timestamp")) - return "'" + value + "' is not a valid " + fieldType + " for " + fieldName + " using " + LookAndFeelProperties.getInstance(ContainerManager.getRoot()).getDateParsingMode().getDisplayString(); + return "'" + value + "' is not a valid " + fieldType + " for '" + fieldName + "' using " + LookAndFeelProperties.getInstance(ContainerManager.getRoot()).getDateParsingMode().getDisplayString(); return "Could not convert value '" + value + "' (" + value.getClass().getSimpleName() + ") for " + fieldType + " field '" + fieldName + "'" ; } diff --git a/api/src/org/labkey/api/dataiterator/AttachmentDataIterator.java b/api/src/org/labkey/api/dataiterator/AttachmentDataIterator.java index c8065c52077..05266bc05fc 100644 --- a/api/src/org/labkey/api/dataiterator/AttachmentDataIterator.java +++ b/api/src/org/labkey/api/dataiterator/AttachmentDataIterator.java @@ -172,7 +172,7 @@ else if (attachmentValue instanceof File file) private ValidationException propertyValidationException(DomainProperty property, Object value) { - return rowValidationException(String.format("Can't upload '%s' to field %s with type %s.", value, property.getName(), property.getType().getLabel())); + return rowValidationException(String.format("Cannot upload '%s' to %s type field '%s'.", value, property.getType().getLabel(), property.getName())); } private ValidationException rowValidationException(String message) diff --git a/api/src/org/labkey/api/query/AbstractQueryUpdateService.java b/api/src/org/labkey/api/query/AbstractQueryUpdateService.java index 1b64835bb42..26a5d4cc6e0 100644 --- a/api/src/org/labkey/api/query/AbstractQueryUpdateService.java +++ b/api/src/org/labkey/api/query/AbstractQueryUpdateService.java @@ -214,7 +214,7 @@ public Map> getExistingRows(User user, Container co if (StringUtils.isEmpty(dataContainer)) dataContainer = (String) row.get("folder"); if (!container.getId().equals(dataContainer)) - throw new InvalidKeyException("Data doesn't belong to folder '" + container.getName() + "': " + key.getValue().values()); + throw new InvalidKeyException("Data does not belong to folder '" + container.getName() + "': " + key.getValue().values()); } } else if (verifyExisting) diff --git a/assay/package-lock.json b/assay/package-lock.json index 35b187b94e3..0089c3a74a4 100644 --- a/assay/package-lock.json +++ b/assay/package-lock.json @@ -8,7 +8,7 @@ "name": "assay", "version": "0.0.0", "dependencies": { - "@labkey/components": "7.13.0" + "@labkey/components": "7.13.1-fb-crossSampleTypeWarnings.0" }, "devDependencies": { "@labkey/build": "8.7.0", @@ -2525,9 +2525,9 @@ } }, "node_modules/@labkey/components": { - "version": "7.13.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.13.0.tgz", - "integrity": "sha512-+2o42no7q9IInKbvSd5XHDrnmLKucgudQ+7C2FD6ya+Da8mRu76GWG6L168iwbtMaguQZzFQmMGpD5VScWZiyQ==", + "version": "7.13.1-fb-crossSampleTypeWarnings.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.13.1-fb-crossSampleTypeWarnings.0.tgz", + "integrity": "sha512-I4nhWVUXt5NcuvdfcRWk7MfE3BbnUT25jxW5W00a4JWNnrwVeR/ZIp3js2l0+DwZ2xTlgiv9qbg6bF6XcecHrQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/assay/package.json b/assay/package.json index 256423f62ca..a22077e8dc0 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": "7.13.0" + "@labkey/components": "7.13.1-fb-crossSampleTypeWarnings.0" }, "devDependencies": { "@labkey/build": "8.7.0", diff --git a/core/package-lock.json b/core/package-lock.json index c9c708e80a2..348527e8311 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": "7.13.0", + "@labkey/components": "7.13.1-fb-crossSampleTypeWarnings.0", "@labkey/themes": "1.5.0" }, "devDependencies": { @@ -3547,9 +3547,9 @@ } }, "node_modules/@labkey/components": { - "version": "7.13.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.13.0.tgz", - "integrity": "sha512-+2o42no7q9IInKbvSd5XHDrnmLKucgudQ+7C2FD6ya+Da8mRu76GWG6L168iwbtMaguQZzFQmMGpD5VScWZiyQ==", + "version": "7.13.1-fb-crossSampleTypeWarnings.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.13.1-fb-crossSampleTypeWarnings.0.tgz", + "integrity": "sha512-I4nhWVUXt5NcuvdfcRWk7MfE3BbnUT25jxW5W00a4JWNnrwVeR/ZIp3js2l0+DwZ2xTlgiv9qbg6bF6XcecHrQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/core/package.json b/core/package.json index 2c1202f3221..7a54f61590d 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ } }, "dependencies": { - "@labkey/components": "7.13.0", + "@labkey/components": "7.13.1-fb-crossSampleTypeWarnings.0", "@labkey/themes": "1.5.0" }, "devDependencies": { diff --git a/experiment/package-lock.json b/experiment/package-lock.json index c3ed56aedca..cf19ae767a5 100644 --- a/experiment/package-lock.json +++ b/experiment/package-lock.json @@ -8,7 +8,7 @@ "name": "experiment", "version": "0.0.0", "dependencies": { - "@labkey/components": "7.13.0" + "@labkey/components": "7.13.1-fb-crossSampleTypeWarnings.0" }, "devDependencies": { "@labkey/build": "8.7.0", @@ -3314,9 +3314,9 @@ } }, "node_modules/@labkey/components": { - "version": "7.13.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.13.0.tgz", - "integrity": "sha512-+2o42no7q9IInKbvSd5XHDrnmLKucgudQ+7C2FD6ya+Da8mRu76GWG6L168iwbtMaguQZzFQmMGpD5VScWZiyQ==", + "version": "7.13.1-fb-crossSampleTypeWarnings.0", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.13.1-fb-crossSampleTypeWarnings.0.tgz", + "integrity": "sha512-I4nhWVUXt5NcuvdfcRWk7MfE3BbnUT25jxW5W00a4JWNnrwVeR/ZIp3js2l0+DwZ2xTlgiv9qbg6bF6XcecHrQ==", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/experiment/package.json b/experiment/package.json index 6601245661c..9541dcc3f8f 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": "7.13.0" + "@labkey/components": "7.13.1-fb-crossSampleTypeWarnings.0" }, "devDependencies": { "@labkey/build": "8.7.0", diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTableImpl.java b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTableImpl.java index f4178e1dbca..2e6bc7b6375 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTableImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTableImpl.java @@ -1461,7 +1461,7 @@ protected Map _update(User user, Container c, Map distinctValueColumns = form.getDistinctValueColumns(); List fields = new ArrayList<>(); List reservedFields = new ArrayList<>(); @@ -1258,12 +1263,43 @@ private ApiSimpleResponse getInferDomainResponse(DataLoader loader, Integer numL { response.put("commentLineCount", loader.getCommentLineCount()); } + if (distinctValueColumns != null && !distinctValueColumns.isEmpty()) + { + response.put("distinctValues", getDistinctValues(loader, distinctValueColumns)); + } } response.put("fields", fields); response.put("reservedFields", reservedFields); return response; } + + /** + * Iterate through the data and get the distinct values for the specified columns. + * Response is a map of column name to set of distinct string values, for those columns + * that have at least one non-null value. + */ + private Map> getDistinctValues(DataLoader loader, Collection colKeys) throws IOException + { + Map> distinctValuesMap = new HashMap<>(); + try (var iter = loader.iterator()) + { + while (iter.hasNext()) + { + Map values = iter.next(); + if (values == null) + continue; + + for (String key : colKeys) + { + Object val = values.get(key); + if (val != null) + distinctValuesMap.computeIfAbsent(key, k -> new CaseInsensitiveHashSet()).add(val.toString()); + } + } + } + return distinctValuesMap; + } } public static class InferDomainForm @@ -1274,6 +1310,7 @@ public static class InferDomainForm private String _domainKindName; private boolean _guessFormatAsTSV; private boolean _checkCommentLineCount; + private Collection _distinctValueColumns; public Integer getNumLinesToInclude() { @@ -1324,6 +1361,16 @@ public void setCheckCommentLineCount(boolean checkCommentLineCount) { _checkCommentLineCount = checkCommentLineCount; } + + public Collection getDistinctValueColumns() + { + return _distinctValueColumns; + } + + public void setDistinctValueColumns(Collection distinctValueColumns) + { + _distinctValueColumns = distinctValueColumns; + } } /** diff --git a/list/src/org/labkey/list/model/ListQueryUpdateService.java b/list/src/org/labkey/list/model/ListQueryUpdateService.java index 8848d3d8b76..8110e0c2b13 100644 --- a/list/src/org/labkey/list/model/ListQueryUpdateService.java +++ b/list/src/org/labkey/list/model/ListQueryUpdateService.java @@ -371,7 +371,7 @@ protected Map updateRow(User user, Container container, Map