Skip to content

Commit 22a44f4

Browse files
authored
GitHub Issue 897: Study dataset should not allow multivalue text choice as a third key (#1948)
1 parent 5924d49 commit 22a44f4

5 files changed

Lines changed: 98 additions & 4 deletions

File tree

packages/components/package-lock.json

Lines changed: 2 additions & 2 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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@labkey/components",
3-
"version": "7.22.0",
3+
"version": "7.22.1",
44
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
55
"sideEffects": false,
66
"files": [

packages/components/releaseNotes/components.md

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

4+
### version 7.22.1
5+
*Released*: 6 March 2026
6+
- GitHub Issue 897: Study dataset should not allow multivalue text choice as a third key
7+
48
### version 7.22.0
59
*Released*: 4 March 2026
610
- Remove styles for `.app-page`
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { DomainDesign } from '../models';
2+
import { CALCULATED_CONCEPT_URI, MULTI_CHOICE_RANGE_URI } from '../constants';
3+
4+
import { TIME_KEY_FIELD_DISPLAY, TIME_KEY_FIELD_KEY, VISIT_TIMEPOINT_TYPE } from './constants';
5+
import { getAdditionalKeyFields } from './actions';
6+
7+
describe('getAdditionalKeyFields', () => {
8+
test('includes time key field for date-based study', () => {
9+
const domain = DomainDesign.create({});
10+
const result = getAdditionalKeyFields(domain, 'DATE');
11+
12+
expect(result.size).toBe(1);
13+
expect(result.get(0)).toEqual({ value: TIME_KEY_FIELD_KEY, label: TIME_KEY_FIELD_DISPLAY });
14+
});
15+
16+
test('excludes time key field for visit-based study', () => {
17+
const domain = DomainDesign.create({});
18+
const result = getAdditionalKeyFields(domain, VISIT_TIMEPOINT_TYPE);
19+
20+
expect(result.size).toBe(0);
21+
});
22+
23+
test('includes regular fields', () => {
24+
const domain = DomainDesign.create({
25+
fields: [
26+
{ name: 'Field1', rangeURI: 'int' },
27+
{ name: 'Field2', rangeURI: 'string' },
28+
],
29+
});
30+
const result = getAdditionalKeyFields(domain, VISIT_TIMEPOINT_TYPE);
31+
32+
expect(result.size).toBe(2);
33+
expect(result.get(0)).toEqual({ value: 'Field1', label: 'Field1' });
34+
expect(result.get(1)).toEqual({ value: 'Field2', label: 'Field2' });
35+
});
36+
37+
test('excludes calculated fields', () => {
38+
const domain = DomainDesign.create({
39+
fields: [
40+
{ name: 'Regular', rangeURI: 'int' },
41+
{ name: 'Calculated', rangeURI: 'int', conceptURI: CALCULATED_CONCEPT_URI },
42+
],
43+
});
44+
const result = getAdditionalKeyFields(domain, VISIT_TIMEPOINT_TYPE);
45+
46+
expect(result.size).toBe(1);
47+
expect(result.get(0)).toEqual({ value: 'Regular', label: 'Regular' });
48+
});
49+
50+
test('excludes multi-choice fields', () => {
51+
const domain = DomainDesign.create({
52+
fields: [
53+
{ name: 'Regular', rangeURI: 'int' },
54+
{ name: 'MultiChoice', rangeURI: MULTI_CHOICE_RANGE_URI },
55+
],
56+
});
57+
const result = getAdditionalKeyFields(domain, VISIT_TIMEPOINT_TYPE);
58+
59+
expect(result.size).toBe(1);
60+
expect(result.get(0)).toEqual({ value: 'Regular', label: 'Regular' });
61+
});
62+
63+
test('includes time key field before domain fields for non-visit study', () => {
64+
const domain = DomainDesign.create({
65+
fields: [{ name: 'Field1', rangeURI: 'int' }],
66+
});
67+
const result = getAdditionalKeyFields(domain, 'Timepoints');
68+
69+
expect(result.size).toBe(2);
70+
expect(result.get(0)).toEqual({ value: TIME_KEY_FIELD_KEY, label: TIME_KEY_FIELD_DISPLAY });
71+
expect(result.get(1)).toEqual({ value: 'Field1', label: 'Field1' });
72+
});
73+
74+
test('filters out both calculated and multi-choice fields while keeping regular fields', () => {
75+
const domain = DomainDesign.create({
76+
fields: [
77+
{ name: 'Regular1', rangeURI: 'int' },
78+
{ name: 'Calculated', rangeURI: 'int', conceptURI: CALCULATED_CONCEPT_URI },
79+
{ name: 'Regular2', rangeURI: 'string' },
80+
{ name: 'MultiChoice', rangeURI: MULTI_CHOICE_RANGE_URI },
81+
],
82+
});
83+
const result = getAdditionalKeyFields(domain, 'Timepoints');
84+
85+
expect(result.size).toBe(3);
86+
expect(result.get(0)).toEqual({ value: TIME_KEY_FIELD_KEY, label: TIME_KEY_FIELD_DISPLAY });
87+
expect(result.get(1)).toEqual({ value: 'Regular1', label: 'Regular1' });
88+
expect(result.get(2)).toEqual({ value: 'Regular2', label: 'Regular2' });
89+
});
90+
});

packages/components/src/internal/components/domainproperties/dataset/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function getAdditionalKeyFields(domain: DomainDesign, timepointType: stri
7979
}
8080

8181
domain.fields
82-
.filter(field => !field.isCalculatedField())
82+
.filter(field => !field.isCalculatedField() && !field.isMultiChoiceField())
8383
.map(field => {
8484
additionalKeyFields = additionalKeyFields.push({ value: field.name, label: field.name });
8585
});

0 commit comments

Comments
 (0)