Skip to content

Conversation

@XingY
Copy link
Contributor

@XingY XingY commented Jan 22, 2026

Rationale

Instead of two separate data types, this PR modifies TextChoice so multi choice is no longer an explicit option in designer, but rather, can be enabled to checking a "multi" check box after selecting text choice option.

Related Pull Requests

Changes

  • Updates the Text Choice options UI to add an “Allow multiple selections” toggle, multi-choice-specific edit restrictions, and improved confirmation messaging/tests for data-type changes involving text/multi-choice.
  • Make multi-choice behaves as an internal variant of Text Choice rather than a separate visible type in data type dropdown
  • Enhances updateDataType and text choice usage counting to correctly handle conversions between string, Text Choice, and Multi Choice fields, clearing validators/flags and tracking multi-value usage where appropriate.

This comment was marked as resolved.

@XingY XingY requested a review from cnathe January 27, 2026 19:14
Comment on lines 1450 to 1469
if (!isMultiField && !isValidTextChoiceValue(value)) return;

const values: string[] = [];
if (isMultiField && Array.isArray(value)) {
values.push(...value);
hasMultiValue = hasMultiValue || value.length > 1;
} else {
values.push(value);
}

const rowLocked = row.IsLocked.value === 1;
const rowCount = row.RowCount.value;

values.forEach(val => {
if (!useCount[val]) {
useCount[val] = { count: 0, locked: false };
}
useCount[val].count += rowCount;
useCount[val].locked = useCount[val].locked || rowLocked;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code block looks to be almost an exact duplicate of the code above for the if statement. Can this be factored out to be shared by both?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, done

);
expect(document.body).toHaveTextContent(
'This change will convert the values in the field from dateTime to date. This will cause the Time portion of the value to be removed.'
'Confirm Data Type ChangeThis change will convert the values in the field from Text Choice (single select) to Text Choice (multiple select). Filters in saved views might not function as expected and any conditional formatting configured for this field will be removed.'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor but when I look at this in the UI the "Single Select" and "Multiple Select" text is capitalized. Does that matter for this test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I don't think it matters in this case.

if (
shouldShowConfirmDataTypeChange(
field.original.rangeURI ?? field.original.conceptURI,
typeConvertingTo.rangeURI ?? typeConvertingTo.conceptURI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking the same thing as copilot here. Should the conceptURI take precedence over the rangeURI? won't all fields have a rangeURI, which means it will never fall back to the conceptURI?

showFilePropertyType: boolean,
showStudyPropertyTypes: boolean
): boolean {
if (type.hideFromDomainRow) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why add this new hideFromDomainRow property when we already have type specific checks below? can't we just say "if type is multi choice text, return false"?

import { DomainField } from './models';
import { MULTI_CHOICE_RANGE_URI } from './constants';

describe('TextChoiceOptions', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hurray for another spec file converted! Just curious, did you convert this manually or did you use AI in some capacity? just want to see what others are doing / using.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep this was converted using AI. I first tried Junie but it wasn't successful. But using copilot (Gemini 3) it was a very smooth convert.

type="checkbox"
/>
<span
title={
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this span title be discoverable by the users? or should this be a ? tooltip type of display?
Oh, is this just for the disabled checkbox case?

return Filter.create(fieldKey, [], oldFilter.getFilterType());
if (allValues && newCheckedValues.length >= allValues.length) {
return Filter.create(fieldKey, allValues.filter(v => v !== ALL_VALUE_DISPLAY), oldFilter.getFilterType());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know much about this change, but should there be a related jest test for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jest tests added

@XingY XingY requested a review from cnathe January 28, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants