diff --git a/openbis_ng_ui/src/js/components/types/form/TypeFormControllerChange.js b/openbis_ng_ui/src/js/components/types/form/TypeFormControllerChange.js index 50a67b10e920f020fc126b2042b5b89ddd3ea5f6..1c1bbe8550298970bbb14602e42e3f63edf178e2 100644 --- a/openbis_ng_ui/src/js/components/types/form/TypeFormControllerChange.js +++ b/openbis_ng_ui/src/js/components/types/form/TypeFormControllerChange.js @@ -209,15 +209,15 @@ export default class TypeFormControllerChange extends PageControllerChange { }, vocabulary: { ...newProperty.vocabulary, - enabled: !systemInternalPropertyType + enabled: !systemInternalPropertyType && !isGlobal }, materialType: { ...newProperty.materialType, - enabled: !systemInternalPropertyType + enabled: !systemInternalPropertyType && !isGlobal }, sampleType: { ...newProperty.sampleType, - enabled: !systemInternalPropertyType + enabled: !systemInternalPropertyType && !isGlobal }, plugin: { ...newProperty.plugin, diff --git a/openbis_ng_ui/srcTest/js/common/fixture.js b/openbis_ng_ui/srcTest/js/common/fixture.js index 6f13cefad4c51d684b9d8446e2c2eb3ba6feec25..6cd9060e2f6e803a2401125315bc11eb82bba7cf 100644 --- a/openbis_ng_ui/srcTest/js/common/fixture.js +++ b/openbis_ng_ui/srcTest/js/common/fixture.js @@ -32,6 +32,9 @@ ANOTHER_USER_GROUP_DTO.setUsers([ANOTHER_USER_DTO]) const TEST_PLUGIN_DTO = new openbis.Plugin() TEST_PLUGIN_DTO.setName('TEST_PLUGIN') +const ANOTHER_PLUGIN_DTO = new openbis.Plugin() +ANOTHER_PLUGIN_DTO.setName('ANOTHER_PLUGIN') + const TEST_PROPERTY_TYPE_1_DTO = new openbis.PropertyType() TEST_PROPERTY_TYPE_1_DTO.setCode('TEST_PROPERTY_TYPE_1') TEST_PROPERTY_TYPE_1_DTO.setPermId( @@ -158,6 +161,7 @@ export default { TEST_USER_GROUP_DTO, ANOTHER_USER_GROUP_DTO, TEST_PLUGIN_DTO, + ANOTHER_PLUGIN_DTO, TEST_PROPERTY_TYPE_1_DTO, TEST_PROPERTY_TYPE_2_DTO, TEST_PROPERTY_TYPE_3_DTO, diff --git a/openbis_ng_ui/srcTest/js/components/common/form/wrapper/AutocompleterFieldWrapper.js b/openbis_ng_ui/srcTest/js/components/common/form/wrapper/AutocompleterFieldWrapper.js index 0c723599cdd502c1982d3a7846a321ae64e64b65..8e654ff2d33197fb8c9572772fb7c5c25ed46db0 100644 --- a/openbis_ng_ui/srcTest/js/components/common/form/wrapper/AutocompleterFieldWrapper.js +++ b/openbis_ng_ui/srcTest/js/components/common/form/wrapper/AutocompleterFieldWrapper.js @@ -8,4 +8,18 @@ export default class AutocompleterFieldWrapper extends FieldWrapper { return false } } + getOptions() { + return this.wrapper.prop('options') + } + + toJSON() { + if (this.wrapper.exists()) { + return { + ...super.toJSON(), + options: this.getOptions() + } + } else { + return null + } + } } diff --git a/openbis_ng_ui/srcTest/js/components/types/form/TypeFormComponent.test.js b/openbis_ng_ui/srcTest/js/components/types/form/TypeFormComponent.test.js index c0f600a38386bd107de11857e1a2c328ffb4cc97..63c2bb70c08ba79821166df402a755b3a36af934 100644 --- a/openbis_ng_ui/srcTest/js/components/types/form/TypeFormComponent.test.js +++ b/openbis_ng_ui/srcTest/js/components/types/form/TypeFormComponent.test.js @@ -4,6 +4,7 @@ import TypeForm from '@src/js/components/types/form/TypeForm.jsx' import TypeFormWrapper from '@srcTest/js/components/types/form/wrapper/TypeFormWrapper.js' import TypeFormController from '@src/js/components/types/form/TypeFormController.js' import TypeFormFacade from '@src/js/components/types/form/TypeFormFacade' +import TypeFormPropertyScope from '@src/js/components/types/form/TypeFormPropertyScope.js' import objectTypes from '@src/js/common/consts/objectType.js' import openbis from '@srcTest/js/services/openbis.js' import fixture from '@srcTest/js/common/fixture.js' @@ -30,6 +31,7 @@ beforeEach(() => { facade.loadValidationPlugins.mockReturnValue(Promise.resolve([])) facade.loadMaterials.mockReturnValue(Promise.resolve([])) facade.loadSamples.mockReturnValue(Promise.resolve([])) + facade.loadVocabularies.mockReturnValue(Promise.resolve([])) facade.loadVocabularyTerms.mockReturnValue(Promise.resolve([])) facade.loadGlobalPropertyTypes.mockReturnValue(Promise.resolve([])) }) @@ -43,7 +45,9 @@ describe('TypeFormComponent', () => { test('select property global used', testSelectPropertyGlobalUsed) test('select section', testSelectSection) test('add section', testAddSection) - test('add property', testAddProperty) + test('add local property', testAddLocalProperty) + test('add new global property', testAddNewGlobalProperty) + test('add existing global property', testAddExistingGlobalProperty) test('change type', testChangeType) test('change property', testChangeProperty) test('convert property', testConvertProperty) @@ -223,19 +227,19 @@ async function testLoadExisting() { } async function testSelectPropertyLocalUnused() { - await doTestSelectProperty('local', false) + await doTestSelectProperty(TypeFormPropertyScope.LOCAL, false) } async function testSelectPropertyLocalUsed() { - await doTestSelectProperty('local', true) + await doTestSelectProperty(TypeFormPropertyScope.LOCAL, true) } async function testSelectPropertyGlobalUnused() { - await doTestSelectProperty('global', false) + await doTestSelectProperty(TypeFormPropertyScope.GLOBAL, false) } async function testSelectPropertyGlobalUsed() { - await doTestSelectProperty('global', true) + await doTestSelectProperty(TypeFormPropertyScope.GLOBAL, true) } async function doTestSelectProperty(scope, used) { @@ -244,7 +248,9 @@ async function doTestSelectProperty(scope, used) { const propertyType = new openbis.PropertyType() propertyType.setCode( - scope === 'global' ? 'GLOBAL_PROPERTY' : 'TEST_TYPE.LOCAL_PROPERTY' + scope === TypeFormPropertyScope.GLOBAL + ? 'GLOBAL_PROPERTY' + : 'TEST_TYPE.LOCAL_PROPERTY' ) propertyType.setLabel('Test Label') propertyType.setDescription('Test Description') @@ -263,7 +269,7 @@ async function doTestSelectProperty(scope, used) { const messages = [] - if (scope === 'global') { + if (scope === TypeFormPropertyScope.GLOBAL) { messages.push({ text: 'This property is global. Changes will also influence other types where this property is used.', @@ -480,7 +486,7 @@ async function testAddSection() { }) } -async function testAddProperty() { +async function testAddLocalProperty() { const form = await mountExisting() form.expectJSON({ @@ -546,7 +552,7 @@ async function testAddProperty() { title: 'Property', scope: { label: 'Scope', - value: 'local', + value: TypeFormPropertyScope.LOCAL, enabled: true, mode: 'edit' }, @@ -579,6 +585,18 @@ async function testAddProperty() { value: null, enabled: true, mode: 'edit' + }, + visible: { + label: 'Visible', + value: true, + enabled: true, + mode: 'edit' + }, + mandatory: { + label: 'Mandatory', + value: false, + enabled: true, + mode: 'edit' } } }, @@ -607,6 +625,457 @@ async function testAddProperty() { }) } +async function testAddNewGlobalProperty() { + const EXISTING_GLOBAL_PROPERTY = new openbis.PropertyType() + EXISTING_GLOBAL_PROPERTY.setCode('EXISTING_GLOBAL_PROPERTY') + + facade.loadGlobalPropertyTypes.mockReturnValue( + Promise.resolve([EXISTING_GLOBAL_PROPERTY]) + ) + facade.loadDynamicPlugins.mockReturnValue( + Promise.resolve([fixture.TEST_PLUGIN_DTO, fixture.ANOTHER_PLUGIN_DTO]) + ) + + const form = await mountNew() + + form.getButtons().getAddSection().click() + await form.update() + + form.getButtons().getAddProperty().click() + await form.update() + + form + .getParameters() + .getProperty() + .getScope() + .change(TypeFormPropertyScope.GLOBAL) + await form.update() + + form.getParameters().getProperty().getCode().change('NEW_GLOBAL_PROPERTY') + await form.update() + + form.expectJSON({ + preview: { + sections: [ + { + name: null, + properties: [ + { + message: { + type: 'info', + text: 'Please select a data type to display the field preview.' + } + } + ] + } + ] + }, + parameters: { + property: { + title: 'Property', + scope: { + label: 'Scope', + value: TypeFormPropertyScope.GLOBAL, + enabled: true, + mode: 'edit' + }, + code: { + label: 'Code', + value: 'NEW_GLOBAL_PROPERTY', + enabled: true, + mode: 'edit', + options: [EXISTING_GLOBAL_PROPERTY.getCode()] + }, + dataType: { + label: 'Data Type', + value: null, + enabled: true, + mode: 'edit' + }, + label: { + label: 'Label', + value: null, + enabled: true, + mode: 'edit' + }, + description: { + label: 'Description', + value: null, + enabled: true, + mode: 'edit' + }, + plugin: { + label: 'Dynamic Plugin', + value: null, + enabled: true, + mode: 'edit' + }, + visible: { + label: 'Visible', + value: true, + enabled: true, + mode: 'edit' + }, + mandatory: { + label: 'Mandatory', + value: false, + enabled: true, + mode: 'edit' + } + } + }, + buttons: { + addSection: { + enabled: true + }, + addProperty: { + enabled: true + }, + remove: { + enabled: true + }, + save: { + enabled: true + }, + message: { + text: 'You have unsaved changes.', + type: 'warning' + }, + edit: null, + cancel: null + } + }) + + form.getParameters().getProperty().getDataType().change('VARCHAR') + form.getParameters().getProperty().getLabel().change('New Label') + form.getParameters().getProperty().getDescription().change('New Description') + form + .getParameters() + .getProperty() + .getPlugin() + .change(fixture.ANOTHER_PLUGIN_DTO.getName()) + form.getParameters().getProperty().getVisible().change(false) + form.getParameters().getProperty().getMandatory().change(true) + await form.update() + + form.expectJSON({ + preview: { + sections: [ + { + name: null, + properties: [{ code: 'NEW_GLOBAL_PROPERTY' }] + } + ] + }, + parameters: { + property: { + title: 'Property', + scope: { + label: 'Scope', + value: TypeFormPropertyScope.GLOBAL, + enabled: true, + mode: 'edit' + }, + code: { + label: 'Code', + value: 'NEW_GLOBAL_PROPERTY', + enabled: true, + mode: 'edit', + options: [EXISTING_GLOBAL_PROPERTY.getCode()] + }, + dataType: { + label: 'Data Type', + value: 'VARCHAR', + enabled: true, + mode: 'edit' + }, + label: { + label: 'Label', + value: 'New Label', + enabled: true, + mode: 'edit' + }, + description: { + label: 'Description', + value: 'New Description', + enabled: true, + mode: 'edit' + }, + plugin: { + label: 'Dynamic Plugin', + value: fixture.ANOTHER_PLUGIN_DTO.getName(), + enabled: true, + mode: 'edit' + }, + visible: { + label: 'Visible', + value: false, + enabled: true, + mode: 'edit' + }, + mandatory: { + label: 'Mandatory', + value: true, + enabled: true, + mode: 'edit' + } + } + }, + buttons: { + addSection: { + enabled: true + }, + addProperty: { + enabled: true + }, + remove: { + enabled: true + }, + save: { + enabled: true + }, + message: { + text: 'You have unsaved changes.', + type: 'warning' + }, + edit: null, + cancel: null + } + }) +} + +async function testAddExistingGlobalProperty() { + const EXISTING_GLOBAL_PROPERTY = new openbis.PropertyType() + EXISTING_GLOBAL_PROPERTY.setCode('EXISTING_GLOBAL_PROPERTY') + EXISTING_GLOBAL_PROPERTY.setDataType('CONTROLLEDVOCABULARY') + EXISTING_GLOBAL_PROPERTY.setVocabulary(fixture.TEST_VOCABULARY_DTO) + EXISTING_GLOBAL_PROPERTY.setLabel('Existing Label') + EXISTING_GLOBAL_PROPERTY.setDescription('Existing Description') + + facade.loadGlobalPropertyTypes.mockReturnValue( + Promise.resolve([EXISTING_GLOBAL_PROPERTY]) + ) + facade.loadDynamicPlugins.mockReturnValue( + Promise.resolve([fixture.TEST_PLUGIN_DTO, fixture.ANOTHER_PLUGIN_DTO]) + ) + facade.loadVocabularies.mockReturnValue( + Promise.resolve([fixture.TEST_VOCABULARY_DTO]) + ) + + const form = await mountNew() + + form.getButtons().getAddSection().click() + await form.update() + + form.getButtons().getAddProperty().click() + await form.update() + + form + .getParameters() + .getProperty() + .getScope() + .change(TypeFormPropertyScope.GLOBAL) + await form.update() + + form + .getParameters() + .getProperty() + .getCode() + .change(EXISTING_GLOBAL_PROPERTY.getCode()) + await form.update() + + form.expectJSON({ + preview: { + sections: [ + { + name: null, + properties: [{ code: EXISTING_GLOBAL_PROPERTY.getCode() }] + } + ] + }, + parameters: { + property: { + title: 'Property', + scope: { + label: 'Scope', + value: TypeFormPropertyScope.GLOBAL, + enabled: true, + mode: 'edit' + }, + code: { + label: 'Code', + value: EXISTING_GLOBAL_PROPERTY.getCode(), + enabled: true, + mode: 'edit', + options: [EXISTING_GLOBAL_PROPERTY.getCode()] + }, + dataType: { + label: 'Data Type', + value: EXISTING_GLOBAL_PROPERTY.getDataType(), + enabled: true, + mode: 'edit' + }, + vocabulary: { + label: 'Vocabulary', + value: EXISTING_GLOBAL_PROPERTY.vocabulary.getCode(), + enabled: false, + mode: 'edit' + }, + label: { + label: 'Label', + value: EXISTING_GLOBAL_PROPERTY.getLabel(), + enabled: true, + mode: 'edit' + }, + description: { + label: 'Description', + value: EXISTING_GLOBAL_PROPERTY.getDescription(), + enabled: true, + mode: 'edit' + }, + plugin: { + label: 'Dynamic Plugin', + value: null, + enabled: true, + mode: 'edit' + }, + visible: { + label: 'Visible', + value: true, + enabled: true, + mode: 'edit' + }, + mandatory: { + label: 'Mandatory', + value: false, + enabled: true, + mode: 'edit' + } + } + }, + buttons: { + addSection: { + enabled: true + }, + addProperty: { + enabled: true + }, + remove: { + enabled: true + }, + save: { + enabled: true + }, + message: { + text: 'You have unsaved changes.', + type: 'warning' + }, + edit: null, + cancel: null + } + }) + + form + .getParameters() + .getProperty() + .getPlugin() + .change(fixture.ANOTHER_PLUGIN_DTO.getName()) + form.getParameters().getProperty().getVisible().change(false) + form.getParameters().getProperty().getMandatory().change(true) + await form.update() + + form.expectJSON({ + preview: { + sections: [ + { + name: null, + properties: [{ code: EXISTING_GLOBAL_PROPERTY.getCode() }] + } + ] + }, + parameters: { + property: { + title: 'Property', + scope: { + label: 'Scope', + value: TypeFormPropertyScope.GLOBAL, + enabled: true, + mode: 'edit' + }, + code: { + label: 'Code', + value: EXISTING_GLOBAL_PROPERTY.getCode(), + enabled: true, + mode: 'edit', + options: [EXISTING_GLOBAL_PROPERTY.getCode()] + }, + dataType: { + label: 'Data Type', + value: EXISTING_GLOBAL_PROPERTY.getDataType(), + enabled: true, + mode: 'edit' + }, + vocabulary: { + label: 'Vocabulary', + value: EXISTING_GLOBAL_PROPERTY.vocabulary.getCode(), + enabled: false, + mode: 'edit' + }, + label: { + label: 'Label', + value: EXISTING_GLOBAL_PROPERTY.getLabel(), + enabled: true, + mode: 'edit' + }, + description: { + label: 'Description', + value: EXISTING_GLOBAL_PROPERTY.getDescription(), + enabled: true, + mode: 'edit' + }, + plugin: { + label: 'Dynamic Plugin', + value: fixture.ANOTHER_PLUGIN_DTO.getName(), + enabled: true, + mode: 'edit' + }, + visible: { + label: 'Visible', + value: false, + enabled: true, + mode: 'edit' + }, + mandatory: { + label: 'Mandatory', + value: true, + enabled: true, + mode: 'edit' + } + } + }, + buttons: { + addSection: { + enabled: true + }, + addProperty: { + enabled: true + }, + remove: { + enabled: true + }, + save: { + enabled: true + }, + message: { + text: 'You have unsaved changes.', + type: 'warning' + }, + edit: null, + cancel: null + } + }) +} + async function testChangeType() { const form = await mountExisting()