diff --git a/packages/components/package-lock.json b/packages/components/package-lock.json index dceffbb502..28892fb6cb 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.20.4", + "version": "7.20.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.20.4", + "version": "7.20.5", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/packages/components/package.json b/packages/components/package.json index dee1d57ba5..0a45262be3 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.20.4", + "version": "7.20.5", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ diff --git a/packages/components/releaseNotes/components.md b/packages/components/releaseNotes/components.md index ef9d43ec20..7b8f38530b 100644 --- a/packages/components/releaseNotes/components.md +++ b/packages/components/releaseNotes/components.md @@ -1,6 +1,10 @@ # @labkey/components Components, models, actions, and utility functions for LabKey applications and pages +### version 7.20.5 +*Released*: 25 February 2026 +- GitHub Issue #418: Remove flag field type & migrate to text + ### version 7.20.4 *Released*: 25 February 2026 - GitHub Issue #734: App narrow screen display can cut off error message for field editor pages diff --git a/packages/components/src/internal/components/domainproperties/DomainForm.test.tsx b/packages/components/src/internal/components/domainproperties/DomainForm.test.tsx index 58cba903c5..0aae4493ec 100644 --- a/packages/components/src/internal/components/domainproperties/DomainForm.test.tsx +++ b/packages/components/src/internal/components/domainproperties/DomainForm.test.tsx @@ -30,7 +30,6 @@ import { DOMAIN_FIELD_TYPE, DOUBLE_RANGE_URI, FILELINK_RANGE_URI, - FLAG_CONCEPT_URI, INT_RANGE_URI, MULTILINE_RANGE_URI, PARTICIPANTID_CONCEPT_URI, @@ -190,37 +189,30 @@ describe('DomainForm', () => { propertyId: 6, propertyURI: 'test', }); - fields.push({ - name: 'flag', - rangeURI: STRING_RANGE_URI, - conceptURI: FLAG_CONCEPT_URI, - propertyId: 7, - propertyURI: 'test', - }); fields.push({ name: 'file link', rangeURI: FILELINK_RANGE_URI, - propertyId: 8, + propertyId: 7, propertyURI: 'test', }); fields.push({ name: 'participant id', rangeURI: STRING_RANGE_URI, conceptURI: PARTICIPANTID_CONCEPT_URI, - propertyId: 9, + propertyId: 8, propertyURI: 'test', }); fields.push({ name: 'attachment', rangeURI: ATTACHMENT_RANGE_URI, - propertyId: 10, + propertyId: 9, propertyURI: 'test', }); fields.push({ name: 'sample', rangeURI: STRING_RANGE_URI, conceptURI: SAMPLE_TYPE_CONCEPT_URI, - propertyId: 11, + propertyId: 10, propertyURI: 'test', }); @@ -247,10 +239,10 @@ describe('DomainForm', () => { expect(document.querySelectorAll('.domain-toolbar-delete-btn')).toHaveLength(1); expect(document.querySelectorAll('.domain-search-input')).toHaveLength(1); expect(document.querySelectorAll('.domain-toolbar-toggle-summary')).toHaveLength(1); - expect(document.querySelectorAll('.domain-field-row')).toHaveLength(12); - expect(document.querySelectorAll('.domain-field-delete-icon')).toHaveLength(11); + expect(document.querySelectorAll('.domain-field-row')).toHaveLength(11); + expect(document.querySelectorAll('.domain-field-delete-icon')).toHaveLength(10); - expect(document.querySelectorAll('.domain-field-details')).toHaveLength(11); + expect(document.querySelectorAll('.domain-field-details')).toHaveLength(10); expect(document.querySelectorAll('.domain-field-details')[0].textContent).toContain(''); }); @@ -274,13 +266,6 @@ describe('DomainForm', () => { propertyId: 2, propertyURI: 'test', }); - fields.push({ - name: 'flag changed to attachment', - rangeURI: STRING_RANGE_URI, - conceptURI: FLAG_CONCEPT_URI, - propertyId: 3, - propertyURI: 'test', - }); let domain = DomainDesign.create({ name: 'update field types', @@ -294,7 +279,6 @@ describe('DomainForm', () => { domain = updateDomainField(domain, { id: createFormInputId(DOMAIN_FIELD_NAME, 0, 0), value: 'newfieldname' }); domain = updateDomainField(domain, { id: createFormInputId(DOMAIN_FIELD_TYPE, 0, 1), value: 'boolean' }); domain = updateDomainField(domain, { id: createFormInputId(DOMAIN_FIELD_TYPE, 0, 2), value: 'ParticipantId' }); - domain = updateDomainField(domain, { id: createFormInputId(DOMAIN_FIELD_TYPE, 0, 3), value: 'attachment' }); await act(async () => { renderWithAppContext(); @@ -304,9 +288,9 @@ describe('DomainForm', () => { expect(document.querySelectorAll('.domain-toolbar-delete-btn')).toHaveLength(1); expect(document.querySelectorAll('.domain-search-input')).toHaveLength(1); expect(document.querySelectorAll('.domain-toolbar-toggle-summary')).toHaveLength(1); - expect(document.querySelectorAll('.domain-field-row')).toHaveLength(5); - expect(document.querySelectorAll('.domain-field-delete-icon')).toHaveLength(4); - expect(document.querySelectorAll('.domain-field-details')).toHaveLength(4); + expect(document.querySelectorAll('.domain-field-row')).toHaveLength(4); + expect(document.querySelectorAll('.domain-field-delete-icon')).toHaveLength(3); + expect(document.querySelectorAll('.domain-field-details')).toHaveLength(3); expect(document.querySelectorAll('.domain-field-details')[0].textContent).toContain('Updated'); }); @@ -362,7 +346,7 @@ describe('DomainForm', () => { }); await act(async () => { - renderWithAppContext(); + renderWithAppContext(); }); expect(document.getElementsByClassName('domain-panel-header-collapsed')).toHaveLength(1); @@ -392,8 +376,8 @@ describe('DomainForm', () => { await act(async () => { renderWithAppContext( { }); await act(async () => { - renderWithAppContext(); + renderWithAppContext(); }); expect(document.getElementsByClassName('domain-panel-header-expanded')).toHaveLength(1); @@ -574,10 +558,10 @@ describe('DomainForm', () => { renderWithAppContext( ); }); @@ -593,11 +577,11 @@ describe('DomainForm', () => { renderWithAppContext( ); }); @@ -641,10 +625,10 @@ describe('DomainForm', () => { renderWithAppContext( ); }); @@ -679,11 +663,11 @@ describe('DomainForm', () => { renderWithAppContext( ); }); diff --git a/packages/components/src/internal/components/domainproperties/DomainRowExpandedOptions.test.tsx b/packages/components/src/internal/components/domainproperties/DomainRowExpandedOptions.test.tsx index b3dd31e90f..c6c95642dc 100644 --- a/packages/components/src/internal/components/domainproperties/DomainRowExpandedOptions.test.tsx +++ b/packages/components/src/internal/components/domainproperties/DomainRowExpandedOptions.test.tsx @@ -13,7 +13,6 @@ import { CALCULATED_TYPE, DATETIME_TYPE, DOUBLE_TYPE, - FLAG_TYPE, INTEGER_TYPE, MULTI_CHOICE_TYPE, MULTILINE_TYPE, @@ -158,23 +157,6 @@ describe('DomainRowExpandedOptions', () => { }); }); - test('Flag data type', async () => { - const field = DomainField.create({ - conceptURI: FLAG_TYPE.conceptURI, - rangeURI: FLAG_TYPE.rangeURI, - }); - - render(); - - await waitFor(() => { - const headers = document.querySelectorAll('.domain-field-section-heading'); - expect(headers.length).toBe(3); - expect(headers[0].textContent).toBe('Flag Options'); - expect(headers[1].textContent).toBe('Name and Linking Options'); - expect(headers[2].textContent).toBe('Conditional Formatting and Validation Options'); - }); - }); - test('Multiline data type', async () => { const field = DomainField.create({ rangeURI: MULTILINE_TYPE.rangeURI, diff --git a/packages/components/src/internal/components/domainproperties/PropDescType.ts b/packages/components/src/internal/components/domainproperties/PropDescType.ts index b68c36f347..91cc54f4c2 100644 --- a/packages/components/src/internal/components/domainproperties/PropDescType.ts +++ b/packages/components/src/internal/components/domainproperties/PropDescType.ts @@ -13,7 +13,6 @@ import { DECIMAL_RANGE_URI, DOUBLE_RANGE_URI, FILELINK_RANGE_URI, - FLAG_CONCEPT_URI, FLOAT_RANGE_URI, INT_RANGE_URI, LONG_RANGE_URI, @@ -285,12 +284,6 @@ export const DATETIME_TYPE = new PropDescType({ rangeURI: DATETIME_RANGE_URI, alternateRangeURI: 'xsd:dateTime', }); -export const FLAG_TYPE = new PropDescType({ - name: 'flag', - display: 'Flag', - rangeURI: STRING_RANGE_URI, - conceptURI: FLAG_CONCEPT_URI, -}); export const FILE_TYPE = new PropDescType({ name: 'fileLink', display: 'File', rangeURI: FILELINK_RANGE_URI }); export const ATTACHMENT_TYPE = new PropDescType({ name: 'attachment', @@ -405,7 +398,6 @@ export const PROP_DESC_TYPES = List([ DATE_TYPE, TIME_TYPE, DATETIME_TYPE, - FLAG_TYPE, FILE_TYPE, ATTACHMENT_TYPE, USERS_TYPE, diff --git a/packages/components/src/internal/components/domainproperties/actions.test.ts b/packages/components/src/internal/components/domainproperties/actions.test.ts index 097f4c29ea..cb578fad2c 100644 --- a/packages/components/src/internal/components/domainproperties/actions.test.ts +++ b/packages/components/src/internal/components/domainproperties/actions.test.ts @@ -59,7 +59,6 @@ import { DATETIME_TYPE, DOUBLE_TYPE, FILE_TYPE, - FLAG_TYPE, INTEGER_TYPE, MULTI_CHOICE_TYPE, ONTOLOGY_LOOKUP_TYPE, @@ -79,7 +78,6 @@ import { DOMAIN_FIELD_PREFIX, FIELD_NAME_CHAR_WARNING_INFO, FIELD_NAME_CHAR_WARNING_MSG, - FLAG_CONCEPT_URI, INT_RANGE_URI, MAX_TEXT_LENGTH, SEVERITY_LEVEL_ERROR, @@ -119,15 +117,6 @@ describe('domain properties actions', () => { expect(field1.dataType.rangeURI).toBe(INT_RANGE_URI); const field2 = DomainField.create({ - name: 'field2name', - rangeURI: STRING_RANGE_URI, - conceptURI: FLAG_CONCEPT_URI, - propertyId: 0, - propertyURI: 'test', - }); - expect(field2.dataType.name).toBe('flag'); - - const field3 = DomainField.create({ name: 'field3name', rangeURI: INT_RANGE_URI, lookupSchema: 'core', @@ -135,7 +124,7 @@ describe('domain properties actions', () => { propertyId: 0, propertyURI: 'test', }); - expect(field3.dataType.name).toBe('users'); + expect(field2.dataType.name).toBe('users'); }); test('server side error on the banner', () => { @@ -365,7 +354,6 @@ describe('domain properties actions', () => { __setController('project'); setModuleContext(TEST_LKS_STARTER_MODULE_CONTEXT); const domain = DomainDesign.create({ - allowFlagProperties: true, allowFileLinkProperties: true, allowAttachmentProperties: true, allowTimepointProperties: true, @@ -375,7 +363,6 @@ describe('domain properties actions', () => { allowMultiChoiceProperties: true, }); const available = getAvailableTypes(domain); - expect(available.contains(FLAG_TYPE)).toBeTruthy(); expect(available.contains(FILE_TYPE)).toBeTruthy(); expect(available.contains(ATTACHMENT_TYPE)).toBeTruthy(); expect(available.contains(ONTOLOGY_LOOKUP_TYPE)).toBeFalsy(); @@ -395,7 +382,6 @@ describe('domain properties actions', () => { __setController('project'); setModuleContext(TEST_LKS_STARTER_MODULE_CONTEXT); const domain = DomainDesign.create({ - allowFlagProperties: false, allowFileLinkProperties: false, allowAttachmentProperties: false, allowTimepointProperties: false, @@ -405,7 +391,6 @@ describe('domain properties actions', () => { allowMultiChoiceProperties: false, }); const available = getAvailableTypes(domain); - expect(available.contains(FLAG_TYPE)).toBeFalsy(); expect(available.contains(FILE_TYPE)).toBeFalsy(); expect(available.contains(ATTACHMENT_TYPE)).toBeFalsy(); expect(available.contains(ONTOLOGY_LOOKUP_TYPE)).toBeFalsy(); @@ -456,7 +441,6 @@ describe('domain properties actions', () => { }); const domain = DomainDesign.create({}); const types = await getAvailableTypesForOntology(api, domain); - expect(types.contains(FLAG_TYPE)).toBeTruthy(); expect(types.contains(FILE_TYPE)).toBeFalsy(); expect(types.contains(ATTACHMENT_TYPE)).toBeFalsy(); expect(types.contains(ONTOLOGY_LOOKUP_TYPE)).toBeTruthy(); diff --git a/packages/components/src/internal/components/domainproperties/actions.ts b/packages/components/src/internal/components/domainproperties/actions.ts index 74e4ff708d..b8e2443bb0 100644 --- a/packages/components/src/internal/components/domainproperties/actions.ts +++ b/packages/components/src/internal/components/domainproperties/actions.ts @@ -70,7 +70,6 @@ import { ATTACHMENT_TYPE, CALCULATED_TYPE, FILE_TYPE, - FLAG_TYPE, MULTI_CHOICE_TYPE, ONTOLOGY_LOOKUP_TYPE, PARTICIPANT_TYPE, @@ -339,10 +338,6 @@ export async function getAvailableTypesForOntology( } function _isAvailablePropType(type: PropDescType, domain: DomainDesign, ontologies: OntologyModel[]): boolean { - if (type === FLAG_TYPE && !domain.allowFlagProperties) { - return false; - } - if (type === FILE_TYPE && !domain.allowFileLinkProperties) { return false; } diff --git a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesPanel.spec.tsx b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesPanel.spec.tsx deleted file mode 100644 index 5f92cfc1ab..0000000000 --- a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesPanel.spec.tsx +++ /dev/null @@ -1,292 +0,0 @@ -import React from 'react'; -import { List } from 'immutable'; - -import { DomainDesign, DomainPanelStatus } from '../models'; - -import { mountWithServerContext } from '../../../test/enzymeTestHelpers'; - -import { ProductFeature } from '../../../app/constants'; - -import { AssayPropertiesPanel } from './AssayPropertiesPanel'; -import { AssayProtocolModel } from './models'; - -import { - AutoLinkDataInput, - AutoLinkCategoryInput, - BackgroundUploadInput, - DescriptionInput, - DetectionMethodsInput, - EditableResultsInput, - EditableRunsInput, - MetadataInputFormatsInput, - ModuleProvidedScriptsInput, - NameInput, - PlateMetadataInput, - PlateTemplatesInput, - QCStatesInput, - SaveScriptDataInput, - TransformScriptsInput, -} from './AssayPropertiesInput'; - -const SERVER_CONTEXT = { - // isAssayQCEnabled(moduleContext) === true - moduleContext: { - api: { moduleNames: ['assay', 'premium', 'study'] }, - core: { productFeatures: [ProductFeature.Assay, ProductFeature.AssayQC] }, - }, -}; - -const BASE_PROPS = { - panelStatus: 'NONE' as DomainPanelStatus, - validate: false, - controlledCollapse: false, - initCollapsed: false, - collapsed: false, -}; - -const EMPTY_MODEL = AssayProtocolModel.create({ - providerName: 'General', - domains: List([ - DomainDesign.create({ name: 'Batch Fields' }), - DomainDesign.create({ name: 'Run Fields' }), - DomainDesign.create({ name: 'Data Fields' }), - ]), -}); - -describe('AssayPropertiesPanel', () => { - test('default properties', () => { - const form = mountWithServerContext( - - ); - - expect(form).toMatchSnapshot(); - form.unmount(); - }); - - test('asPanel, helpTopic, and hideAdvancedProperties', () => { - const form = mountWithServerContext( - - ); - - expect(form).toMatchSnapshot(); - form.unmount(); - }); - - test('without helpTopic', () => { - const form = mountWithServerContext( - - ); - - expect(form).toMatchSnapshot(); - form.unmount(); - }); - - test('panelCls, initCollapsed, and markComplete', () => { - const form = mountWithServerContext( - - ); - - expect(form).toMatchSnapshot(); - form.unmount(); - }); - - test('with initial model', () => { - const form = mountWithServerContext( - - ); - - expect(form).toMatchSnapshot(); - form.unmount(); - }); - - test('visible properties based on empty AssayProtocolModel', () => { - const wrapper = mountWithServerContext( - , - SERVER_CONTEXT - ); - - expect(wrapper.find(NameInput)).toHaveLength(1); - expect(wrapper.find(DescriptionInput)).toHaveLength(1); - expect(wrapper.find(QCStatesInput)).toHaveLength(0); - expect(wrapper.find(PlateMetadataInput)).toHaveLength(0); - expect(wrapper.find(PlateTemplatesInput)).toHaveLength(0); - expect(wrapper.find(DetectionMethodsInput)).toHaveLength(0); - expect(wrapper.find(MetadataInputFormatsInput)).toHaveLength(0); - expect(wrapper.find(EditableRunsInput)).toHaveLength(1); - expect(wrapper.find(EditableResultsInput)).toHaveLength(0); - expect(wrapper.find(BackgroundUploadInput)).toHaveLength(0); - expect(wrapper.find(TransformScriptsInput)).toHaveLength(0); - expect(wrapper.find(SaveScriptDataInput)).toHaveLength(0); - expect(wrapper.find(ModuleProvidedScriptsInput)).toHaveLength(0); - expect(wrapper.find(AutoLinkDataInput)).toHaveLength(1); - expect(wrapper.find(AutoLinkCategoryInput)).toHaveLength(1); - wrapper.unmount(); - }); - - test('visible properties based on populated AssayProtocolModel', () => { - const model = AssayProtocolModel.create({ - allowBackgroundUpload: true, - allowEditableResults: true, - allowPlateMetadata: true, - allowQCStates: true, - allowTransformationScript: true, - availableDetectionMethods: ['a', 'b', 'c'], - availableMetadataInputFormats: { test1: 'abc' }, - availablePlateTemplates: ['d', 'e', 'f'], - moduleTransformScripts: ['validation.pl'], - }); - - const wrapper = mountWithServerContext( - , - SERVER_CONTEXT - ); - - expect(wrapper.find(NameInput)).toHaveLength(1); - expect(wrapper.find(DescriptionInput)).toHaveLength(1); - expect(wrapper.find(PlateMetadataInput)).toHaveLength(1); - expect(wrapper.find(QCStatesInput)).toHaveLength(1); - expect(wrapper.find(PlateTemplatesInput)).toHaveLength(1); - expect(wrapper.find(DetectionMethodsInput)).toHaveLength(1); - expect(wrapper.find(MetadataInputFormatsInput)).toHaveLength(1); - expect(wrapper.find(EditableRunsInput)).toHaveLength(1); - expect(wrapper.find(EditableResultsInput)).toHaveLength(1); - expect(wrapper.find(BackgroundUploadInput)).toHaveLength(1); - expect(wrapper.find(TransformScriptsInput)).toHaveLength(1); - expect(wrapper.find(SaveScriptDataInput)).toHaveLength(1); - expect(wrapper.find(ModuleProvidedScriptsInput)).toHaveLength(1); - expect(wrapper.find(AutoLinkDataInput)).toHaveLength(1); - expect(wrapper.find(AutoLinkCategoryInput)).toHaveLength(1); - wrapper.unmount(); - }); - - test('visible properties for hideAdvancedProperties based on populated AssayProtocolModel', () => { - const model = AssayProtocolModel.create({ - allowBackgroundUpload: true, - allowEditableResults: true, - allowPlateMetadata: true, - allowQCStates: true, - availableDetectionMethods: ['a', 'b', 'c'], - availableMetadataInputFormats: { test1: 'abc' }, - availablePlateTemplates: ['d', 'e', 'f'], - moduleTransformScripts: ['validation.pl'], - }); - - const wrapper = mountWithServerContext( - , - SERVER_CONTEXT - ); - expect(wrapper.find(NameInput)).toHaveLength(1); - expect(wrapper.find(DescriptionInput)).toHaveLength(1); - expect(wrapper.find(PlateMetadataInput)).toHaveLength(1); - expect(wrapper.find(QCStatesInput)).toHaveLength(0); - expect(wrapper.find(PlateTemplatesInput)).toHaveLength(1); - expect(wrapper.find(DetectionMethodsInput)).toHaveLength(1); - expect(wrapper.find(MetadataInputFormatsInput)).toHaveLength(1); - expect(wrapper.find(EditableRunsInput)).toHaveLength(1); - expect(wrapper.find(EditableResultsInput)).toHaveLength(1); - expect(wrapper.find(BackgroundUploadInput)).toHaveLength(0); - expect(wrapper.find(TransformScriptsInput)).toHaveLength(0); - expect(wrapper.find(SaveScriptDataInput)).toHaveLength(0); - expect(wrapper.find(ModuleProvidedScriptsInput)).toHaveLength(0); - expect(wrapper.find(AutoLinkDataInput)).toHaveLength(0); - expect(wrapper.find(AutoLinkCategoryInput)).toHaveLength(0); - wrapper.unmount(); - }); - - test('visible properties for appPropertiesOnly based on populated AssayProtocolModel', () => { - const model = AssayProtocolModel.create({ - allowBackgroundUpload: true, - allowEditableResults: true, - allowPlateMetadata: true, - allowQCStates: true, - availableDetectionMethods: ['a', 'b', 'c'], - availableMetadataInputFormats: { test1: 'abc' }, - availablePlateTemplates: ['d', 'e', 'f'], - moduleTransformScripts: ['validation.pl'], - }); - - const wrapper = mountWithServerContext( - , - SERVER_CONTEXT - ); - expect(wrapper.find(NameInput)).toHaveLength(1); - expect(wrapper.find(DescriptionInput)).toHaveLength(1); - expect(wrapper.find(PlateMetadataInput)).toHaveLength(0); - expect(wrapper.find(QCStatesInput)).toHaveLength(1); - expect(wrapper.find(PlateTemplatesInput)).toHaveLength(1); - expect(wrapper.find(DetectionMethodsInput)).toHaveLength(1); - expect(wrapper.find(MetadataInputFormatsInput)).toHaveLength(1); - expect(wrapper.find(EditableRunsInput)).toHaveLength(1); - expect(wrapper.find(EditableResultsInput)).toHaveLength(1); - expect(wrapper.find(BackgroundUploadInput)).toHaveLength(1); - expect(wrapper.find(TransformScriptsInput)).toHaveLength(0); - expect(wrapper.find(SaveScriptDataInput)).toHaveLength(0); - expect(wrapper.find(ModuleProvidedScriptsInput)).toHaveLength(1); - expect(wrapper.find(AutoLinkDataInput)).toHaveLength(1); - expect(wrapper.find(AutoLinkCategoryInput)).toHaveLength(1); - wrapper.unmount(); - }); - - test('visible properties for hideAdvancedProperties and appPropertiesOnly', () => { - const model = AssayProtocolModel.create({ - allowBackgroundUpload: true, - allowEditableResults: true, - allowPlateMetadata: true, - allowQCStates: true, - availableDetectionMethods: ['a', 'b', 'c'], - availableMetadataInputFormats: { test1: 'abc' }, - availablePlateTemplates: ['d', 'e', 'f'], - moduleTransformScripts: ['validation.pl'], - }); - - const wrapper = mountWithServerContext( - , - SERVER_CONTEXT - ); - expect(wrapper.find(NameInput)).toHaveLength(1); - expect(wrapper.find(DescriptionInput)).toHaveLength(1); - expect(wrapper.find(PlateMetadataInput)).toHaveLength(0); - expect(wrapper.find(QCStatesInput)).toHaveLength(0); - expect(wrapper.find(PlateTemplatesInput)).toHaveLength(1); - expect(wrapper.find(DetectionMethodsInput)).toHaveLength(1); - expect(wrapper.find(MetadataInputFormatsInput)).toHaveLength(1); - expect(wrapper.find(EditableRunsInput)).toHaveLength(1); - expect(wrapper.find(EditableResultsInput)).toHaveLength(1); - expect(wrapper.find(BackgroundUploadInput)).toHaveLength(0); - expect(wrapper.find(TransformScriptsInput)).toHaveLength(0); - expect(wrapper.find(SaveScriptDataInput)).toHaveLength(0); - expect(wrapper.find(ModuleProvidedScriptsInput)).toHaveLength(0); - expect(wrapper.find(AutoLinkDataInput)).toHaveLength(0); - expect(wrapper.find(AutoLinkCategoryInput)).toHaveLength(0); - wrapper.unmount(); - }); -}); diff --git a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesPanel.test.tsx b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesPanel.test.tsx new file mode 100644 index 0000000000..76fbd83d71 --- /dev/null +++ b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesPanel.test.tsx @@ -0,0 +1,301 @@ +import React from 'react'; +import { List } from 'immutable'; + +import { renderWithAppContext } from '../../../test/reactTestLibraryHelpers'; + +import { DomainDesign, DomainPanelStatus } from '../models'; + +import { ProductFeature } from '../../../app/constants'; + +import { AssayPropertiesPanel } from './AssayPropertiesPanel'; +import { AssayProtocolModel } from './models'; +import { waitFor } from '@testing-library/dom'; + +const SERVER_CONTEXT = { + moduleContext: { + api: { moduleNames: ['assay', 'premium', 'study'] }, + core: { productFeatures: [ProductFeature.Assay, ProductFeature.AssayQC] }, + }, +}; + +const BASE_PROPS = { + panelStatus: 'NONE' as DomainPanelStatus, + validate: false, + controlledCollapse: false, + initCollapsed: false, + collapsed: false, +}; + +const EMPTY_MODEL = AssayProtocolModel.create({ + providerName: 'General', + domains: List([ + DomainDesign.create({ name: 'Batch Fields' }), + DomainDesign.create({ name: 'Run Fields' }), + DomainDesign.create({ name: 'Data Fields' }), + ]), +}); + +describe('AssayPropertiesPanel', () => { + test('default properties', async () => { + renderWithAppContext(); + + await waitFor(() => { + expect(document.querySelector('#assay-design-name')).toBeInTheDocument(); + expect(document.querySelector('#assay-design-description')).toBeInTheDocument(); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(4); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Import Settings'); + expect(sectionLabel[3].textContent).toEqual('Plate Settings'); + }); + }); + + test('asPanel, helpTopic, and hideAdvancedProperties', async () => { + renderWithAppContext( + + ); + + await waitFor(() => { + expect(document.querySelector('#assay-design-name')).toBeInTheDocument(); + expect(document.querySelector('#assay-design-description')).toBeInTheDocument(); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(3); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Plate Settings'); + + // Help link + const help = document.querySelector('div.panel-body a'); + expect(help.textContent).toBe('Learn more about designing assays'); + expect(help.getAttribute('href')).toBe( + 'https://www.labkey.org/Documentation/wiki-page.view?referrer=inPage&name=customHelpTopic' + ); + }); + }); + + test('without helpTopic', async () => { + renderWithAppContext( + + ); + + await waitFor(() => { + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(3); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Plate Settings'); + + expect(document.querySelector('div.panel-body a')).toBeNull(); + }); + }); + + test('with initial model', async () => { + renderWithAppContext( + + ); + + await waitFor(() => { + const readOnlyName = document.querySelectorAll('#assay-design-name'); + expect(readOnlyName).toHaveLength(1); + expect(readOnlyName[0].hasAttribute('disabled')).toBeTruthy(); + expect(readOnlyName[0].getAttribute('value')).toEqual('name should not be editable'); + + expect(document.querySelectorAll('input#assay-design-editableRuns')).toHaveLength(1); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(4); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Import Settings'); + expect(sectionLabel[3].textContent).toEqual('Plate Settings'); + }); + }); + + test('visible properties based on empty AssayProtocolModel', async () => { + renderWithAppContext(, { + serverContext: SERVER_CONTEXT, + }); + + await waitFor(() => { + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(5); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Import Settings'); + expect(sectionLabel[3].textContent).toEqual('Plate Settings'); + expect(sectionLabel[4].textContent).toEqual('Link to Study Settings'); + }); + }); + + test('visible properties based on populated AssayProtocolModel', async () => { + const model = AssayProtocolModel.create({ + allowBackgroundUpload: true, + allowEditableResults: true, + allowPlateMetadata: true, + allowQCStates: true, + allowTransformationScript: true, + availableDetectionMethods: ['a', 'b', 'c'], + availableMetadataInputFormats: { test1: 'abc' }, + availablePlateTemplates: ['d', 'e', 'f'], + moduleTransformScripts: ['validation.pl'], + }); + + renderWithAppContext(, { + serverContext: SERVER_CONTEXT, + }); + + await waitFor(() => { + expect(document.querySelectorAll('input#assay-design-qcEnabled')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-editableRuns')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-editableResults')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedDetectionMethod')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedMetadataInputFormat')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-backgroundUpload')).toHaveLength(1); + + const transformScripts = document.querySelectorAll('div.module-transform-script'); + expect(transformScripts).toHaveLength(1); + expect(transformScripts[0].textContent).toContain('validation.pl'); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(5); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Import Settings'); + expect(sectionLabel[3].textContent).toEqual('Plate Settings'); + expect(sectionLabel[4].textContent).toEqual('Link to Study Settings'); + }); + }); + + test('visible properties for hideAdvancedProperties based on populated AssayProtocolModel', async () => { + const model = AssayProtocolModel.create({ + allowBackgroundUpload: true, + allowEditableResults: true, + allowPlateMetadata: true, + allowQCStates: true, + availableDetectionMethods: ['a', 'b', 'c'], + availableMetadataInputFormats: { test1: 'abc' }, + availablePlateTemplates: ['d', 'e', 'f'], + moduleTransformScripts: ['validation.pl'], + }); + + renderWithAppContext( + , + { serverContext: SERVER_CONTEXT } + ); + + await waitFor(() => { + expect(document.querySelectorAll('input#assay-design-editableRuns')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-editableResults')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedDetectionMethod')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedMetadataInputFormat')).toHaveLength(1); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(3); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Plate Settings'); + }); + }); + + test('visible properties for appPropertiesOnly based on populated AssayProtocolModel', async () => { + const model = AssayProtocolModel.create({ + allowBackgroundUpload: true, + allowEditableResults: true, + allowPlateMetadata: true, + allowQCStates: true, + availableDetectionMethods: ['a', 'b', 'c'], + availableMetadataInputFormats: { test1: 'abc' }, + availablePlateTemplates: ['d', 'e', 'f'], + moduleTransformScripts: ['validation.pl'], + }); + + renderWithAppContext( + , + { serverContext: SERVER_CONTEXT } + ); + + await waitFor(() => { + expect(document.querySelectorAll('input#assay-design-qcEnabled')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-editableRuns')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-editableResults')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedDetectionMethod')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedMetadataInputFormat')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-backgroundUpload')).toHaveLength(1); + + const transformScripts = document.querySelectorAll('div.module-transform-script'); + expect(transformScripts).toHaveLength(1); + expect(transformScripts[0].textContent).toContain('validation.pl'); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(4); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + expect(sectionLabel[2].textContent).toEqual('Import Settings'); + expect(sectionLabel[3].textContent).toEqual('Link to Study Settings'); + }); + }); + + test('visible properties for hideAdvancedProperties and appPropertiesOnly', async () => { + const model = AssayProtocolModel.create({ + allowBackgroundUpload: true, + allowEditableResults: true, + allowPlateMetadata: true, + allowQCStates: true, + availableDetectionMethods: ['a', 'b', 'c'], + availableMetadataInputFormats: { test1: 'abc' }, + availablePlateTemplates: ['d', 'e', 'f'], + moduleTransformScripts: ['validation.pl'], + }); + + renderWithAppContext( + , + { serverContext: SERVER_CONTEXT } + ); + + await waitFor(() => { + expect(document.querySelectorAll('input#assay-design-editableRuns')).toHaveLength(1); + expect(document.querySelectorAll('input#assay-design-editableResults')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedDetectionMethod')).toHaveLength(1); + expect(document.querySelectorAll('select#assay-design-selectedMetadataInputFormat')).toHaveLength(1); + + const transformScripts = document.querySelectorAll('div.module-transform-script'); + expect(transformScripts).toHaveLength(0); + + const sectionLabel = document.querySelectorAll('.domain-field-section-heading'); + expect(sectionLabel.length).toEqual(2); + expect(sectionLabel[0].textContent).toEqual('Basic Properties'); + expect(sectionLabel[1].textContent).toEqual('Editing Settings'); + }); + }); +}); diff --git a/packages/components/src/internal/components/domainproperties/assay/__snapshots__/AssayPropertiesPanel.spec.tsx.snap b/packages/components/src/internal/components/domainproperties/assay/__snapshots__/AssayPropertiesPanel.spec.tsx.snap deleted file mode 100644 index fbe8e3eb04..0000000000 --- a/packages/components/src/internal/components/domainproperties/assay/__snapshots__/AssayPropertiesPanel.spec.tsx.snap +++ /dev/null @@ -1,5358 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AssayPropertiesPanel asPanel, helpTopic, and hideAdvancedProperties 1`] = ` - - - -
-
-
- -
- Basic Properties -
-
- - -
-
- - - Name - * - - -
-
- -
-
-
-
- - - A short description for this assay design. -

- } - hideAdvancedProperties={true} - label="Description" - > -
-
- - A short description for this assay design. -

- } - label="Description" - > - - Description - - -

- A short description for this assay design. -

- - } - > -
- - - -
-
-
-
-
-
-
-