Skip to content

Commit fdd3aa2

Browse files
authored
Multi value text choices (#1923)
1 parent d28ffd6 commit fdd3aa2

39 files changed

Lines changed: 767 additions & 238 deletions

packages/components/package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/components/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@labkey/components",
3-
"version": "7.12.2",
3+
"version": "7.13.0",
44
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
55
"sideEffects": false,
66
"files": [
@@ -50,7 +50,7 @@
5050
"homepage": "https://github.com/LabKey/labkey-ui-components#readme",
5151
"dependencies": {
5252
"@hello-pangea/dnd": "18.0.1",
53-
"@labkey/api": "1.44.1",
53+
"@labkey/api": "1.45.0",
5454
"@testing-library/dom": "~10.4.1",
5555
"@testing-library/jest-dom": "~6.9.1",
5656
"@testing-library/react": "~16.3.0",

packages/components/releaseNotes/components.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# @labkey/components
22
Components, models, actions, and utility functions for LabKey applications and pages
33

4+
### version 7.13.0
5+
*Released*: 20 January 2026
6+
- Multi value text choices
7+
- Added new MULTI_CHOICE_RANGE_URI for defining MVTC fields and updated utils to check against data type
8+
- renamed joinValues prop for SelectInput to skipJoinValues to align with its actual usage
9+
- Modified FilterFacetedSelector and QueryFilterPanel to handle array value selecting for MVTC
10+
411
### version 7.12.2
512
*Released*: 19 January 2026
613
- GitHub Issue 764: Editable grid border display issue on very small screens

packages/components/src/internal/components/domainproperties/AdvancedSettings.test.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
DOMAIN_LAST_ENTERED_DEFAULT,
2323
DOMAIN_NON_EDITABLE_DEFAULT,
2424
INT_RANGE_URI,
25+
MULTI_CHOICE_RANGE_URI,
2526
PHILEVEL_FULL_PHI,
2627
PHILEVEL_LIMITED_PHI,
2728
} from './constants';
@@ -226,4 +227,38 @@ describe('AdvancedSettings', () => {
226227
id = createFormInputId(DOMAIN_FIELD_SHOWNINDETAILSVIEW, _domainIndex, _index);
227228
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
228229
});
230+
231+
test('Multi-value Text Choice hidden properties', async () => {
232+
await act(async () => {
233+
renderWithAppContext(
234+
<AdvancedSettings
235+
{...props}
236+
field={DomainField.create({ ...fieldProps, rangeURI: MULTI_CHOICE_RANGE_URI })}
237+
/>
238+
);
239+
});
240+
241+
let id = createFormInputId(DOMAIN_FIELD_DEFAULT_VALUE_TYPE, _domainIndex, _index);
242+
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
243+
id = createFormInputId(DOMAIN_FIELD_HIDDEN, _domainIndex, _index);
244+
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
245+
id = createFormInputId(DOMAIN_FIELD_SHOWNININSERTVIEW, _domainIndex, _index);
246+
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
247+
id = createFormInputId(DOMAIN_FIELD_SHOWNINUPDATESVIEW, _domainIndex, _index);
248+
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
249+
id = createFormInputId(DOMAIN_FIELD_SHOWNINDETAILSVIEW, _domainIndex, _index);
250+
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
251+
id = createFormInputId(DOMAIN_FIELD_PHI, _domainIndex, _index);
252+
expect(document.querySelectorAll('#' + id)).toHaveLength(1);
253+
id = createFormInputId(DOMAIN_FIELD_CONSTRAINT, _domainIndex, _index);
254+
expect(document.querySelectorAll('#' + id)).toHaveLength(0);
255+
id = createFormInputId(DOMAIN_FIELD_MEASURE, _domainIndex, _index);
256+
expect(document.querySelectorAll('#' + id)).toHaveLength(0);
257+
id = createFormInputId(DOMAIN_FIELD_DIMENSION, _domainIndex, _index);
258+
expect(document.querySelectorAll('#' + id)).toHaveLength(0);
259+
id = createFormInputId(DOMAIN_FIELD_MVENABLED, _domainIndex, _index);
260+
expect(document.querySelectorAll('#' + id)).toHaveLength(0);
261+
id = createFormInputId(DOMAIN_FIELD_RECOMMENDEDVARIABLE, _domainIndex, _index);
262+
expect(document.querySelectorAll('#' + id)).toHaveLength(0);
263+
});
229264
});

packages/components/src/internal/components/domainproperties/AdvancedSettings.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
448448
</div>
449449
)}
450450

451-
{allowUniqueConstraintProperties && !field.isCalculatedField() && (
451+
{allowUniqueConstraintProperties && !field.isCalculatedField() && !field.isMultiChoiceField() && (
452452
<div className="row">
453453
<div className="col-xs-4">
454454
<DomainFieldLabel
@@ -543,20 +543,22 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
543543
</LabelHelpTip>
544544
</CheckboxLK>
545545
)}
546-
<CheckboxLK
547-
checked={recommendedVariable}
548-
id={createFormInputId(DOMAIN_FIELD_RECOMMENDEDVARIABLE, domainIndex, index)}
549-
name={createFormInputName(DOMAIN_FIELD_RECOMMENDEDVARIABLE)}
550-
onChange={this.handleCheckbox}
551-
>
552-
Make this field a recommended variable
553-
<LabelHelpTip title="Recommended Variable">
554-
<div>
555-
Indicates that this is an important variable. These variables will be displayed as
556-
recommended when creating new charts or reports.
557-
</div>
558-
</LabelHelpTip>
559-
</CheckboxLK>
546+
{!field.isMultiChoiceField() && (
547+
<CheckboxLK
548+
checked={recommendedVariable}
549+
id={createFormInputId(DOMAIN_FIELD_RECOMMENDEDVARIABLE, domainIndex, index)}
550+
name={createFormInputName(DOMAIN_FIELD_RECOMMENDEDVARIABLE)}
551+
onChange={this.handleCheckbox}
552+
>
553+
Make this field a recommended variable
554+
<LabelHelpTip title="Recommended Variable">
555+
<div>
556+
Indicates that this is an important variable. These variables will be displayed as
557+
recommended when creating new charts or reports.
558+
</div>
559+
</LabelHelpTip>
560+
</CheckboxLK>
561+
)}
560562
{PropDescType.isMvEnableable(field.dataType.rangeURI) && !field.isCalculatedField() && !isApp() && (
561563
<CheckboxLK
562564
checked={mvEnabled}

packages/components/src/internal/components/domainproperties/CalculatedFieldOptions.test.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ describe('CalculatedFieldOptions', () => {
2020
renderWithAppContext(
2121
<CalculatedFieldOptions
2222
domainIndex={0}
23+
field={DomainField.create({ rangeURI: STRING_RANGE_URI })}
2324
getDomainFields={jest.fn()}
2425
index={0}
2526
onChange={jest.fn()}
26-
field={DomainField.create({ rangeURI: STRING_RANGE_URI })}
2727
/>
2828
);
2929
});
@@ -41,10 +41,10 @@ describe('CalculatedFieldOptions', () => {
4141
renderWithAppContext(
4242
<CalculatedFieldOptions
4343
domainIndex={0}
44+
field={DomainField.create({ valueExpression: '1=0', rangeURI: INT_RANGE_URI })}
4445
getDomainFields={jest.fn()}
4546
index={0}
4647
onChange={jest.fn()}
47-
field={DomainField.create({ valueExpression: '1=0', rangeURI: INT_RANGE_URI })}
4848
/>
4949
);
5050
});
@@ -62,10 +62,10 @@ describe('CalculatedFieldOptions', () => {
6262
renderWithAppContext(
6363
<CalculatedFieldOptions
6464
domainIndex={0}
65+
field={DomainField.create({ valueExpression: '1=0', lockType: DOMAIN_FIELD_PARTIALLY_LOCKED })}
6566
getDomainFields={jest.fn()}
6667
index={0}
6768
onChange={jest.fn()}
68-
field={DomainField.create({ valueExpression: '1=0', lockType: DOMAIN_FIELD_PARTIALLY_LOCKED })}
6969
/>
7070
);
7171
});
@@ -123,6 +123,7 @@ describe('CalculatedFieldOptions', () => {
123123
List.of(
124124
{ name: 'b', dataType: { name: 'text' } } as DomainField,
125125
{ name: 'c', dataType: { name: 'calculation' } } as DomainField,
126+
{ name: 'c', dataType: { name: 'multiChoice' } } as DomainField,
126127
{ name: 'd', dataType: { name: 'INT' } } as DomainField
127128
),
128129
[{ Name: 'a', DataType: 'integer' } as SystemField]

packages/components/src/internal/components/domainproperties/CalculatedFieldOptions.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { DOMAIN_FIELD_CLIENT_SIDE_ERROR, DOMAIN_FIELD_VALUE_EXPRESSION, SEVERITY
1212
import { DomainField, DomainFieldError, SystemField } from './models';
1313
import { SectionHeading } from './SectionHeading';
1414
import { isFieldFullyLocked, isFieldPartiallyLocked } from './propertiesUtil';
15-
import { CALCULATED_TYPE, PropDescType } from './PropDescType';
15+
import { CALCULATED_TYPE, MULTI_CHOICE_TYPE, PropDescType } from './PropDescType';
1616
import { parseCalculatedColumn } from './actions';
1717

1818
// export for jest testing
@@ -47,7 +47,7 @@ export const getColumnTypeMap = (
4747
colTypeMap[df.Name] = df.DataType.toUpperCase();
4848
});
4949
domainFields?.forEach(df => {
50-
if (df.dataType.name !== CALCULATED_TYPE.name) {
50+
if (df.dataType.name !== CALCULATED_TYPE.name && df.dataType.name !== MULTI_CHOICE_TYPE.name) {
5151
colTypeMap[df.name] = df.dataType.name.toLowerCase() === 'int' ? 'INTEGER' : df.dataType.name.toUpperCase();
5252
}
5353
});
@@ -163,20 +163,20 @@ export const CalculatedFieldOptions: FC<Props> = memo(props => {
163163
>
164164
<div className="row">
165165
<div className="col-xs-12 col-md-6">
166-
<SectionHeading title="Expression" cls="bottom-padding" helpTipBody={HELP_TIP_BODY} />
166+
<SectionHeading cls="bottom-padding" helpTipBody={HELP_TIP_BODY} title="Expression" />
167167
<textarea
168168
className="form-control"
169-
rows={6}
170-
value={field.valueExpression || ''}
171-
id={createFormInputId(DOMAIN_FIELD_VALUE_EXPRESSION, domainIndex, index)}
172-
name={createFormInputName(DOMAIN_FIELD_VALUE_EXPRESSION)}
173-
onChange={handleChange}
174-
onBlur={handleBlur}
175169
disabled={
176170
isFieldPartiallyLocked(field.lockType) ||
177171
isFieldFullyLocked(field.lockType) ||
178172
field.lockExistingField
179173
}
174+
id={createFormInputId(DOMAIN_FIELD_VALUE_EXPRESSION, domainIndex, index)}
175+
name={createFormInputName(DOMAIN_FIELD_VALUE_EXPRESSION)}
176+
onBlur={handleBlur}
177+
onChange={handleChange}
178+
rows={6}
179+
value={field.valueExpression || ''}
180180
/>
181181
<div className="domain-field-calc-footer">
182182
{error && <div className="error">{error}</div>}

0 commit comments

Comments
 (0)