Skip to content
Open
9 changes: 8 additions & 1 deletion api/src/org/labkey/api/exp/property/DomainUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.labkey.api.data.ContainerManager;
import org.labkey.api.data.ContainerService;
import org.labkey.api.data.CoreSchema;
import org.labkey.api.data.DatabaseIdentifier;
import org.labkey.api.data.NameGenerator;
import org.labkey.api.data.PHI;
import org.labkey.api.data.PropertyStorageSpec;
Expand Down Expand Up @@ -983,8 +984,9 @@ else if (PropertyType.MULTI_CHOICE.getTypeUri().equals(old.getRangeURI()))
if (column != null)
{
var dialect = domainTable.getSchema().getSqlDialect();
DatabaseIdentifier columnId = p.getPropertyDescriptor().getLegalSelectName(dialect);
SQLFragment deletedArray = new SQLFragment("CAST(? AS TEXT[])").add(deletedValues.toArray(new String[0]));
SQLFragment columnFrag = new SQLFragment().appendIdentifier(column.getAlias());
SQLFragment columnFrag = new SQLFragment().appendIdentifier(columnId);

SQLFragment sql = new SQLFragment("SELECT 1 FROM ")
.append(domainTable)
Expand Down Expand Up @@ -1536,6 +1538,11 @@ private static boolean _copyValidator(IPropertyValidator pv, GWTPropertyValidato
{
return "Text choice value for field '" + field.getName() + "' must not use the reserved format '{json:[...]}': '" + StringUtils.abbreviate(option, 50) + "'";
}
// GitHub Issue 951: Multi-line values converted to text choices lose multi-line editability
if (StringUtils.containsAny(option, "\n\r"))
{
return "Text choice value for field '" + field.getName() + "' must not contain newline characters: '" + StringUtils.abbreviate(option, 50) + "'";
}
}
}
}
Expand Down
23 changes: 15 additions & 8 deletions core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
}
},
"dependencies": {
"@labkey/components": "7.26.6",
"@labkey/components": "7.29.3",
"@labkey/themes": "1.8.0"
},
"devDependencies": {
Expand Down
23 changes: 15 additions & 8 deletions experiment/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion experiment/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.26.6"
"@labkey/components": "7.29.3"
},
"devDependencies": {
"@labkey/build": "9.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
AssayDesignFieldOptions,
createAssayDesign,
createDomainField,
generateFieldNameForImport,
getAuditLogsForTransaction,
getRunQueryRow,
ImportRunOptions,
Expand Down Expand Up @@ -34,7 +35,7 @@ const RUN_TEXT_CHOICE_FIELD_NAME = 'runTextChoiceField';
const RESULT_FIELD_NAME = 'resultStringField';
const RESULT_FILE_FIELD_NAME = 'resultFileField';
const RESULT_TC_FIELD_NAME = 'resultTextChoiceField';
const RESULT_MVTC_FIELD_NAME = 'resultMultiChoiceField';
const RESULT_MVTC_FIELD_NAME = 'resultMC ' + generateFieldNameForImport();

let context;
let ASSAY_A_ID: number;
Expand All @@ -46,7 +47,6 @@ let supportMultiChoice = false;
beforeAll(async () => {
context = await initProject(server, PROJECT_NAME, ASSAY_DESIGNER_ROLE, ['assay', 'experiment']);

let supportMultiChoice = false;
const createTestPayload = {
kind: 'DataClass',
domainDesign: { name: 'Test_mvtc_support_check', fields: [{ name: 'Prop' }] },
Expand All @@ -67,8 +67,10 @@ beforeAll(async () => {
createDomainField({name: RESULT_TC_FIELD_NAME, ...TC_FIELD_PROP} as Partial<IDomainField>)
];

if (supportMultiChoice)
if (supportMultiChoice) {
console.log("Assay result MVTC field name: " + RESULT_MVTC_FIELD_NAME);
resultFields.push(createDomainField({name: RESULT_MVTC_FIELD_NAME, ...MVTC_FIELD_PROP} as Partial<IDomainField>));
}

let assayFields: AssayDesignFieldOptions = {
batchFields: [
Expand Down
77 changes: 77 additions & 0 deletions experiment/src/client/test/integration/DataClassCrud.ispec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,83 @@ describe('Multi Value Text Choice', () => {
result = await getDataClassDataByName(dataNameImported[0], dataType, '*', topFolderOptions, editorUserOptions);
expect(caseInsensitive(result, fieldName)).toEqual('Abnormal, Plasma'); // convert from ['Abnormal', 'Plasma'] to 'Abnormal, Plasma'


const textChoiceMultiLineOption = {
propertyValidators: [
{
"type": "TextChoice",
"name": "Text Choice Validator",
"new": true,
"expression": "Abnormal|multi\nline|cDNA|Plasma"
}
],
rangeURI: 'http://www.w3.org/2001/XMLSchema#string',
conceptURI: 'http://www.labkey.org/types#textChoice',
}

const textMultiChoiceMultiLineOption = {
propertyValidators: [
{
"type": "TextChoice",
"name": "Text Choice Validator",
"new": true,
"expression": "Abnormal|multi\nline|cDNA|Plasma"
}
],
rangeURI: "http://cpas.fhcrc.org/exp/xml#multiChoice",
}

// GitHub Issue 951: Multi-line values converted to text choices lose multi-line editability
// verify cannot convert MultiLine field to MultiValue Text Choice
updatePayload = {
domainId,
domainDesign: {
name: dataType,
fields: [
{
...textChoiceMultiLineOption,
name: fieldName,
propertyId,
propertyURI,
}
],
domainId,
domainURI
},
options: {
rowId: dataClassRowId,
name: dataType,
nameExpression: 'S-${' + fieldNameInExpression + '}'
}
};
failedUpdate = await server.post('property', 'saveDomain', updatePayload, {...topFolderOptions, ...adminOptions});
expect(failedUpdate?.['body']?.['exception']).toContain('must not contain newline characters');

// verify cannot convert MultiLine field to Text Choice field
updatePayload = {
domainId,
domainDesign: {
name: dataType,
fields: [
{
...textMultiChoiceMultiLineOption,
name: fieldName,
propertyId,
propertyURI,
}
],
domainId,
domainURI
},
options: {
rowId: dataClassRowId,
name: dataType,
nameExpression: 'S-${genId}'
}
};
failedUpdate = await server.post('property', 'saveDomain', updatePayload, {...topFolderOptions, ...adminOptions});
expect(failedUpdate?.['body']?.['exception']).toContain('must not contain newline characters');

});

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
import java.util.Objects;
import java.util.Set;

import static org.labkey.api.data.ColumnRenderPropertiesImpl.TEXT_CHOICE_CONCEPT_URI;

public class DomainPropertyImpl implements DomainProperty
{
private final DomainImpl _domain;
Expand Down Expand Up @@ -859,6 +861,13 @@ else if (newType == PropertyType.MULTI_CHOICE || oldType == PropertyType.MULTI_C
if (PropertyType.FILE_LINK.getInputType().equalsIgnoreCase(oldType.getInputType()) && oldType != newType)
throw new ChangePropertyDescriptorException("Cannot convert an instance of " + oldType.name() + " to " + newType.name() + ".");

// GitHub Issue 951: Multi-line values converted to text choices lose multi-line editability
if (oldType == PropertyType.MULTI_LINE &&
(PropertyType.MULTI_CHOICE == newType ||TEXT_CHOICE_CONCEPT_URI.equals(_pd.getConceptURI())))
{
throw new ChangePropertyDescriptorException("Cannot convert a multiline text field to a text choice field.");
}

OntologyManager.validatePropertyDescriptor(_pd);
Table.update(user, OntologyManager.getTinfoPropertyDescriptor(), _pd, _pdOld.getPropertyId());
OntologyManager.ensurePropertyDomain(_pd, dd, sortOrder);
Expand Down
23 changes: 15 additions & 8 deletions pipeline/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pipeline/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "7.26.6"
"@labkey/components": "7.29.3"
},
"devDependencies": {
"@labkey/build": "9.1.0",
Expand Down
Loading