@reltio/components 1.4.2232 → 1.4.2234

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,7 +94,7 @@ export var EntitySelector = function (_a) {
94
94
  return (__assign(__assign({}, (TextFieldProps || {})), (_a = {}, _a['data-reltio-id'] = 'reltio-entity-selector', _a)));
95
95
  }, [TextFieldProps]);
96
96
  return (React.createElement(React.Fragment, null,
97
- React.createElement(DropDownSelector, __assign({ value: !isEmpty(entity) ? entity : undefined, inputValue: inputValue, onInputChange: handleInputChange, getOptions: getOptions, getOptionLabel: prop('entityLabel'), onChange: handleChange, onCreate: handleCreate, onClear: handleClear, label: label, createLabel: createLabel, canCreateOption: canCreateEntity, components: __assign(__assign({ Option: EntityOption, SingleValue: SingleValue }, groupComponent), clearComponent), currentEntityType: currentEntityType, isClearable: true, disableLinkClick: disableLinkClick, TextFieldProps: textFieldProps }, dropDownSelectorProps)),
97
+ React.createElement(DropDownSelector, __assign({ key: entityTypesUris.join(','), value: !isEmpty(entity) ? entity : undefined, inputValue: inputValue, onInputChange: handleInputChange, getOptions: getOptions, getOptionLabel: prop('entityLabel'), onChange: handleChange, onCreate: handleCreate, onClear: handleClear, label: label, createLabel: createLabel, canCreateOption: canCreateEntity, components: __assign(__assign({ Option: EntityOption, SingleValue: SingleValue }, groupComponent), clearComponent), currentEntityType: currentEntityType, isClearable: true, disableLinkClick: disableLinkClick, TextFieldProps: textFieldProps }, dropDownSelectorProps)),
98
98
  isTempEntity && (React.createElement("div", { "data-reltio-id": "entity-creator", className: styles.creatorWrapper },
99
99
  React.createElement(EntityCreator, { mode: mode, attributeTypesSelectionStrategy: attributeTypesSelectionStrategy, entityType: currentEntityType, entityUri: entity.entityUri })))));
100
100
  };
@@ -385,6 +385,29 @@ describe('Entity selector tests', function () {
385
385
  }
386
386
  });
387
387
  }); });
388
+ it('should call typeAheadSearch with new entity types when entityTypesUris prop changes after rerender', function () { return __awaiter(void 0, void 0, void 0, function () {
389
+ var initialProps, _a, user, rerender, updatedProps;
390
+ return __generator(this, function (_b) {
391
+ switch (_b.label) {
392
+ case 0:
393
+ initialProps = __assign(__assign({}, defaultProps), { entityTypesUris: ['configuration/entityTypes/HCP'] });
394
+ _a = setUp({ props: initialProps }), user = _a.user, rerender = _a.rerender;
395
+ return [4 /*yield*/, user.click(screen.getByTestId('select-dropdown-indicator'))];
396
+ case 1:
397
+ _b.sent();
398
+ expect(typeAheadSearch).toHaveBeenCalledWith([defaultMetadata.entityTypes[0]], '', expect.any(Object));
399
+ typeAheadSearch.mockClear();
400
+ updatedProps = __assign(__assign({}, defaultProps), { entityTypesUris: ['configuration/entityTypes/HCP', 'configuration/entityTypes/Company'] });
401
+ rerender(React.createElement(MdmModuleProvider, { values: defaultMdmValues, actions: defaultMdmActions },
402
+ React.createElement(EntitySelector, __assign({}, updatedProps))));
403
+ return [4 /*yield*/, user.click(screen.getByTestId('select-dropdown-indicator'))];
404
+ case 2:
405
+ _b.sent();
406
+ expect(typeAheadSearch).toHaveBeenCalledWith([defaultMetadata.entityTypes[0], defaultMetadata.entityTypes[1]], '', expect.any(Object));
407
+ return [2 /*return*/];
408
+ }
409
+ });
410
+ }); });
388
411
  it('should render create button and handle click correctly for single entity type in case of onCreate prop is passed and input is filled', function () { return __awaiter(void 0, void 0, void 0, function () {
389
412
  var props, user;
390
413
  return __generator(this, function (_a) {
@@ -15,7 +15,7 @@ import classnames from 'classnames';
15
15
  import { always, assoc, concat, differenceWith, equals, forEach, map, path, pick, pipe, prop, propEq, when, uniq, curry, values, flatten, any } from 'ramda';
16
16
  import Button from '@mui/material/Button';
17
17
  import Typography from '@mui/material/Typography';
18
- import { createTemporaryEntity, findRelatedTemporaryEntities, getActivenessAttributes, getCreatableAttributeTypes, getEntityType, getErrorMessage, getErrorId, omitMarks, relationEditorAttributeTypesSelectionStrategy, validateConnection, updateConnectionEntityLabel, isTempUri, isEmptyValue, getRelationAttributesList, getDefaultRelationTypeObject, getInOutRelations, isSuggestMode, isAttributeTypeError, getRelationUriFromConnection, getRelationEditorActiveError, getRelationAttributesFromConnection, getEntityUriFromConnection, evaluateErrorPath, AttributeValuePathItemType, getAllRelationEditorActiveErrors, isAttributeHasMaskedValue } from '@reltio/mdm-sdk';
18
+ import { createTemporaryEntity, Directions, findRelatedTemporaryEntities, getActivenessAttributes, getCreatableAttributeTypes, getEntityType, getErrorMessage, getErrorId, getRelationType, getSuitableEntityTypeUrisForRelationTypes, isAvailableRelationBetweenEntities, omitMarks, relationEditorAttributeTypesSelectionStrategy, validateConnection, updateConnectionEntityLabel, isTempUri, isEmptyValue, getRelationAttributesList, getDefaultRelationTypeObject, getInOutRelations, isSuggestMode, isAttributeTypeError, getRelationUriFromConnection, getRelationEditorActiveError, getRelationAttributesFromConnection, getEntityUriFromConnection, evaluateErrorPath, AttributeValuePathItemType, getAllRelationEditorActiveErrors, isAttributeHasMaskedValue } from '@reltio/mdm-sdk';
19
19
  import { ConnectionRelationTypeSelector } from '../ConnectionRelationTypeSelector';
20
20
  import { ErrorWrapper } from '../ErrorWrapper';
21
21
  import { EntitySelector } from '../EntitySelector';
@@ -110,7 +110,6 @@ var RelationEditor = function (_a) {
110
110
  areRelatedEntitiesChanged(initialRelatedTempEntities.current, relatedTempEntities));
111
111
  var applyAction = useMemo(function () { return curry(isNew ? addRelation : editRelation); }, [isNew, addRelation, editRelation]);
112
112
  var canCreateNewEntity = !isSuggestMode(mode) || !isTempUri(mainEntity === null || mainEntity === void 0 ? void 0 : mainEntity.uri) || !isEmptyValue(authoringItems);
113
- var onRelationTypeChange = useCallback(function (relationType) { return setRelationType(config.id, relationUri, relationType); }, [config, relationUri, setRelationType]);
114
113
  var handleClose = useCallback(function () { return closeRelationEditor(config.id, relationUri); }, [config, relationUri, closeRelationEditor]);
115
114
  var updateModifiedEntityLabel = useCallback(function (connection) {
116
115
  if (modifiedEntity) {
@@ -121,6 +120,31 @@ var RelationEditor = function (_a) {
121
120
  }, [modifiedEntity, metadata]);
122
121
  var setModifiedEntity = useCallback(function (entity) { return entityCreated(entity); }, [entityCreated]);
123
122
  var deleteModifiedEntity = useCallback(function (entityUri) { return entityDeleted(entityUri); }, [entityDeleted]);
123
+ var onRelationTypeChange = useCallback(function (newRelationType) {
124
+ var connectionEntity = connection.entity;
125
+ var hasConnectionEntity = connectionEntity && connectionEntity.entityUri;
126
+ var isEntitySuitableForNewRelationType = mainEntity &&
127
+ newRelationType &&
128
+ hasConnectionEntity &&
129
+ isAvailableRelationBetweenEntities(newRelationType.direction === Directions.OUT, __assign(__assign({}, connectionEntity), { type: connectionEntity.entityType }), mainEntity, metadata, newRelationType.type);
130
+ setRelationType(config.id, relationUri, newRelationType);
131
+ if (hasConnectionEntity && !isEntitySuitableForNewRelationType) {
132
+ if (modifiedEntity) {
133
+ deleteModifiedEntity(modifiedEntity.uri);
134
+ }
135
+ setRelationEntity(config.id, relationUri, {});
136
+ }
137
+ }, [
138
+ metadata,
139
+ connection.entity,
140
+ mainEntity,
141
+ setRelationType,
142
+ config.id,
143
+ relationUri,
144
+ modifiedEntity,
145
+ setRelationEntity,
146
+ deleteModifiedEntity
147
+ ]);
124
148
  var onChangeEntity = useCallback(function (entity) {
125
149
  if (modifiedEntity) {
126
150
  deleteModifiedEntity(modifiedEntity.uri);
@@ -190,8 +214,15 @@ var RelationEditor = function (_a) {
190
214
  var entityTypesUris = useMemo(function () {
191
215
  var _a;
192
216
  var _b = config, content = _b.content, contentSecondLevel = _b.contentSecondLevel;
193
- return ((_a = (contentSecondLevel && connection.parentEntityUri ? contentSecondLevel.entityTypes : content.entityTypes)) !== null && _a !== void 0 ? _a : []);
194
- }, [config, connection.parentEntityUri]);
217
+ var entityTypeUrisFromConfig = (_a = (contentSecondLevel && connection.parentEntityUri ? contentSecondLevel.entityTypes : content.entityTypes)) !== null && _a !== void 0 ? _a : [];
218
+ var relationTypeObj = relationType ? getRelationType(metadata, relationType) : null;
219
+ var suitableEntityTypeUrisForRelationType = relationTypeObj
220
+ ? getSuitableEntityTypeUrisForRelationTypes(direction === Directions.OUT, metadata, [relationTypeObj])
221
+ : [];
222
+ return entityTypeUrisFromConfig.length > 0
223
+ ? entityTypeUrisFromConfig.filter(function (uri) { return suitableEntityTypeUrisForRelationType.includes(uri); })
224
+ : suitableEntityTypeUrisForRelationType;
225
+ }, [config, connection.parentEntityUri, relationType, direction, metadata]);
195
226
  var isEntityHasMaskedAttrValue = pipe(values, flatten, any(isAttributeHasMaskedValue))(((_d = (_c = connection.entity) === null || _c === void 0 ? void 0 : _c.object) === null || _d === void 0 ? void 0 : _d.attributes) || {});
196
227
  var isMasked = showMasking && isEntityHasMaskedAttrValue;
197
228
  return (React.createElement(React.Fragment, null,
@@ -293,6 +293,51 @@ describe('relation editor behaviour', function () {
293
293
  }
294
294
  });
295
295
  }); });
296
+ it('should pass only entity types suitable for current relation type to EntitySelector', function () { return __awaiter(void 0, void 0, void 0, function () {
297
+ var config, props, user;
298
+ return __generator(this, function (_a) {
299
+ switch (_a.label) {
300
+ case 0:
301
+ typeAheadSearch.mockResolvedValue([
302
+ { type: 'configuration/entityTypes/Location', label: 'location entity 1', uri: 'entities/0C32GxR' }
303
+ ]);
304
+ config = __assign(__assign({}, defaultProps.config), { content: {
305
+ entityTypes: ['configuration/entityTypes/Location', 'configuration/entityTypes/HCA'],
306
+ outRelations: [{ uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' }]
307
+ } });
308
+ props = __assign(__assign({}, defaultProps), { config: config });
309
+ user = setUp({ props: props }).user;
310
+ return [4 /*yield*/, user.click(screen.getByTestId('select-dropdown-indicator'))];
311
+ case 1:
312
+ _a.sent();
313
+ expect(typeAheadSearch).toHaveBeenCalledWith([defaultProps.metadata.entityTypes[1]], '', expect.any(Object));
314
+ expect(typeAheadSearch).not.toHaveBeenCalledWith(expect.arrayContaining([expect.objectContaining({ uri: 'configuration/entityTypes/HCA' })]), expect.any(String), expect.any(Object));
315
+ return [2 /*return*/];
316
+ }
317
+ });
318
+ }); });
319
+ it('should pass all suitable entity types from metadata to EntitySelector when entityTypes from config is empty', function () { return __awaiter(void 0, void 0, void 0, function () {
320
+ var config, props, user;
321
+ return __generator(this, function (_a) {
322
+ switch (_a.label) {
323
+ case 0:
324
+ typeAheadSearch.mockResolvedValue([
325
+ { type: 'configuration/entityTypes/Location', label: 'location entity 1', uri: 'entities/0C32GxR' }
326
+ ]);
327
+ config = __assign(__assign({}, defaultProps.config), { content: {
328
+ entityTypes: [],
329
+ outRelations: [{ uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' }]
330
+ } });
331
+ props = __assign(__assign({}, defaultProps), { config: config });
332
+ user = setUp({ props: props }).user;
333
+ return [4 /*yield*/, user.click(screen.getByTestId('select-dropdown-indicator'))];
334
+ case 1:
335
+ _a.sent();
336
+ expect(typeAheadSearch).toHaveBeenCalledWith([defaultProps.metadata.entityTypes[1]], '', expect.any(Object));
337
+ return [2 /*return*/];
338
+ }
339
+ });
340
+ }); });
296
341
  it('should render attributes list correctly', function () { return __awaiter(void 0, void 0, void 0, function () {
297
342
  var labels, values;
298
343
  return __generator(this, function (_a) {
@@ -351,7 +396,7 @@ describe('relation editor behaviour', function () {
351
396
  return __generator(this, function (_a) {
352
397
  switch (_a.label) {
353
398
  case 0:
354
- connection = __assign(__assign({}, defaultProps.connection), { parentEntityUri: 'entities/HsPM72G' });
399
+ connection = __assign(__assign({}, defaultProps.connection), { parentEntityUri: 'entities/HsPM72G', relation: __assign(__assign({}, defaultRelation), { relationType: 'configuration/relationTypes/InternalHCAtoHCA', direction: 'out' }) });
355
400
  config = __assign(__assign({}, defaultProps.config), { contentSecondLevel: {
356
401
  entityTypes: ['configuration/entityTypes/HCA'],
357
402
  outRelations: [{ uri: 'configuration/relationTypes/InternalHCAtoHCA', label: '{directionalLabel}' }]
@@ -458,6 +503,43 @@ describe('relation editor behaviour', function () {
458
503
  }
459
504
  });
460
505
  }); });
506
+ it('should clear connection entity and delete modified entity when relation type changes to one unsuitable for current connection entity', function () { return __awaiter(void 0, void 0, void 0, function () {
507
+ var entityUri, modifiedEntity, connection, config, mdmValues, props, user;
508
+ var _a;
509
+ return __generator(this, function (_b) {
510
+ switch (_b.label) {
511
+ case 0:
512
+ entityUri = 'entities/uri$$tempLocation';
513
+ modifiedEntity = {
514
+ type: 'configuration/entityTypes/Location',
515
+ uri: entityUri,
516
+ attributes: {}
517
+ };
518
+ connection = __assign(__assign({}, defaultProps.connection), { entity: { entityUri: entityUri, entityType: 'configuration/entityTypes/Location' } });
519
+ config = __assign(__assign({}, defaultProps.config), { content: {
520
+ entityTypes: ['configuration/entityTypes/Location', 'configuration/entityTypes/HCA'],
521
+ inRelations: [{ uri: 'configuration/relationTypes/InternalHCAtoHCA', label: '{directionalLabel}' }],
522
+ outRelations: [{ uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' }]
523
+ } });
524
+ mdmValues = __assign(__assign({}, defaultMdmValues), { modifiedEntities: (_a = {}, _a[entityUri] = modifiedEntity, _a) });
525
+ props = __assign(__assign({}, defaultProps), { config: config, connection: connection });
526
+ user = setUp({ mdmValues: mdmValues, props: props }).user;
527
+ return [4 /*yield*/, user.click(within(screen.getByTestId('relation-type-selector')).getByTestId('select-dropdown-indicator'))];
528
+ case 1:
529
+ _b.sent();
530
+ return [4 /*yield*/, user.click(screen.getByText('InternalHCAtoHCA affiliation'))];
531
+ case 2:
532
+ _b.sent();
533
+ expect(mdmActions.setRelationType).toHaveBeenCalledWith(props.config.id, props.connection.relation.relationUri, expect.objectContaining({
534
+ direction: 'in',
535
+ type: expect.objectContaining({ uri: 'configuration/relationTypes/InternalHCAtoHCA' })
536
+ }));
537
+ expect(mdmActions.entityDeleted).toHaveBeenCalledWith(entityUri);
538
+ expect(mdmActions.setRelationEntity).toHaveBeenCalledWith(props.config.id, props.connection.relation.relationUri, {});
539
+ return [2 /*return*/];
540
+ }
541
+ });
542
+ }); });
461
543
  it('should show "create entity" button if mode is not suggesting', function () { return __awaiter(void 0, void 0, void 0, function () {
462
544
  var user, inputs;
463
545
  return __generator(this, function (_a) {
@@ -496,24 +578,24 @@ describe('relation editor behaviour', function () {
496
578
  });
497
579
  }); });
498
580
  it('should hide create button for one of the entity types when user lacks metadata permissions', function () { return __awaiter(void 0, void 0, void 0, function () {
499
- var props, user, inputs;
581
+ var connection, props, user, inputs;
500
582
  return __generator(this, function (_a) {
501
583
  switch (_a.label) {
502
584
  case 0:
585
+ connection = __assign(__assign({}, defaultProps.connection), { relation: __assign(__assign({}, defaultRelation), { relationType: 'configuration/relationTypes/HasAddress', direction: 'out' }) });
503
586
  props = pipe(assocPath(['metadata', 'entityTypes', 1, 'access'], ['READ', 'UPDATE', 'INITIATE_CHANGE_REQUEST']), assocPath(['config', 'content'], {
504
587
  entityTypes: ['configuration/entityTypes/Location', 'configuration/entityTypes/HCA'],
505
588
  outRelations: [
506
589
  { uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' },
507
590
  { uri: 'configuration/relationTypes/InternalHCAtoHCA', label: '{directionalLabel}' }
508
591
  ]
509
- }))(defaultProps);
592
+ }), assocPath(['connection'], connection))(defaultProps);
510
593
  user = setUp({ props: props }).user;
511
594
  inputs = screen.getAllByRole('combobox');
512
595
  return [4 /*yield*/, user.click(inputs[1])];
513
596
  case 1:
514
597
  _a.sent();
515
598
  expect(screen.queryByText('Create new Address')).not.toBeInTheDocument();
516
- expect(screen.getByText('Create new HCA')).toBeInTheDocument();
517
599
  return [2 /*return*/];
518
600
  }
519
601
  });
@@ -123,7 +123,7 @@ var EntitySelector = function (_a) {
123
123
  return (__assign(__assign({}, (TextFieldProps || {})), (_a = {}, _a['data-reltio-id'] = 'reltio-entity-selector', _a)));
124
124
  }, [TextFieldProps]);
125
125
  return (react_1.default.createElement(react_1.default.Fragment, null,
126
- react_1.default.createElement(DropDownSelector_1.DropDownSelector, __assign({ value: !(0, ramda_1.isEmpty)(entity) ? entity : undefined, inputValue: inputValue, onInputChange: handleInputChange, getOptions: getOptions, getOptionLabel: (0, ramda_1.prop)('entityLabel'), onChange: handleChange, onCreate: handleCreate, onClear: handleClear, label: label, createLabel: createLabel, canCreateOption: canCreateEntity, components: __assign(__assign({ Option: EntityOption_1.EntityOption, SingleValue: SingleValue_1.SingleValue }, groupComponent), clearComponent), currentEntityType: currentEntityType, isClearable: true, disableLinkClick: disableLinkClick, TextFieldProps: textFieldProps }, dropDownSelectorProps)),
126
+ react_1.default.createElement(DropDownSelector_1.DropDownSelector, __assign({ key: entityTypesUris.join(','), value: !(0, ramda_1.isEmpty)(entity) ? entity : undefined, inputValue: inputValue, onInputChange: handleInputChange, getOptions: getOptions, getOptionLabel: (0, ramda_1.prop)('entityLabel'), onChange: handleChange, onCreate: handleCreate, onClear: handleClear, label: label, createLabel: createLabel, canCreateOption: canCreateEntity, components: __assign(__assign({ Option: EntityOption_1.EntityOption, SingleValue: SingleValue_1.SingleValue }, groupComponent), clearComponent), currentEntityType: currentEntityType, isClearable: true, disableLinkClick: disableLinkClick, TextFieldProps: textFieldProps }, dropDownSelectorProps)),
127
127
  isTempEntity && (react_1.default.createElement("div", { "data-reltio-id": "entity-creator", className: styles.creatorWrapper },
128
128
  react_1.default.createElement(EntityCreator_1.EntityCreator, { mode: mode, attributeTypesSelectionStrategy: attributeTypesSelectionStrategy, entityType: currentEntityType, entityUri: entity.entityUri })))));
129
129
  };
@@ -390,6 +390,29 @@ describe('Entity selector tests', function () {
390
390
  }
391
391
  });
392
392
  }); });
393
+ it('should call typeAheadSearch with new entity types when entityTypesUris prop changes after rerender', function () { return __awaiter(void 0, void 0, void 0, function () {
394
+ var initialProps, _a, user, rerender, updatedProps;
395
+ return __generator(this, function (_b) {
396
+ switch (_b.label) {
397
+ case 0:
398
+ initialProps = __assign(__assign({}, defaultProps), { entityTypesUris: ['configuration/entityTypes/HCP'] });
399
+ _a = setUp({ props: initialProps }), user = _a.user, rerender = _a.rerender;
400
+ return [4 /*yield*/, user.click(react_2.screen.getByTestId('select-dropdown-indicator'))];
401
+ case 1:
402
+ _b.sent();
403
+ expect(mdm_sdk_1.typeAheadSearch).toHaveBeenCalledWith([defaultMetadata.entityTypes[0]], '', expect.any(Object));
404
+ mdm_sdk_1.typeAheadSearch.mockClear();
405
+ updatedProps = __assign(__assign({}, defaultProps), { entityTypesUris: ['configuration/entityTypes/HCP', 'configuration/entityTypes/Company'] });
406
+ rerender(react_1.default.createElement(MdmModuleContext_1.MdmModuleProvider, { values: defaultMdmValues, actions: defaultMdmActions },
407
+ react_1.default.createElement(EntitySelector_1.EntitySelector, __assign({}, updatedProps))));
408
+ return [4 /*yield*/, user.click(react_2.screen.getByTestId('select-dropdown-indicator'))];
409
+ case 2:
410
+ _b.sent();
411
+ expect(mdm_sdk_1.typeAheadSearch).toHaveBeenCalledWith([defaultMetadata.entityTypes[0], defaultMetadata.entityTypes[1]], '', expect.any(Object));
412
+ return [2 /*return*/];
413
+ }
414
+ });
415
+ }); });
393
416
  it('should render create button and handle click correctly for single entity type in case of onCreate prop is passed and input is filled', function () { return __awaiter(void 0, void 0, void 0, function () {
394
417
  var props, user;
395
418
  return __generator(this, function (_a) {
@@ -138,7 +138,6 @@ var RelationEditor = function (_a) {
138
138
  areRelatedEntitiesChanged(initialRelatedTempEntities.current, relatedTempEntities));
139
139
  var applyAction = (0, react_1.useMemo)(function () { return (0, ramda_1.curry)(isNew ? addRelation : editRelation); }, [isNew, addRelation, editRelation]);
140
140
  var canCreateNewEntity = !(0, mdm_sdk_1.isSuggestMode)(mode) || !(0, mdm_sdk_1.isTempUri)(mainEntity === null || mainEntity === void 0 ? void 0 : mainEntity.uri) || !(0, mdm_sdk_1.isEmptyValue)(authoringItems);
141
- var onRelationTypeChange = (0, react_1.useCallback)(function (relationType) { return setRelationType(config.id, relationUri, relationType); }, [config, relationUri, setRelationType]);
142
141
  var handleClose = (0, react_1.useCallback)(function () { return closeRelationEditor(config.id, relationUri); }, [config, relationUri, closeRelationEditor]);
143
142
  var updateModifiedEntityLabel = (0, react_1.useCallback)(function (connection) {
144
143
  if (modifiedEntity) {
@@ -149,6 +148,31 @@ var RelationEditor = function (_a) {
149
148
  }, [modifiedEntity, metadata]);
150
149
  var setModifiedEntity = (0, react_1.useCallback)(function (entity) { return entityCreated(entity); }, [entityCreated]);
151
150
  var deleteModifiedEntity = (0, react_1.useCallback)(function (entityUri) { return entityDeleted(entityUri); }, [entityDeleted]);
151
+ var onRelationTypeChange = (0, react_1.useCallback)(function (newRelationType) {
152
+ var connectionEntity = connection.entity;
153
+ var hasConnectionEntity = connectionEntity && connectionEntity.entityUri;
154
+ var isEntitySuitableForNewRelationType = mainEntity &&
155
+ newRelationType &&
156
+ hasConnectionEntity &&
157
+ (0, mdm_sdk_1.isAvailableRelationBetweenEntities)(newRelationType.direction === mdm_sdk_1.Directions.OUT, __assign(__assign({}, connectionEntity), { type: connectionEntity.entityType }), mainEntity, metadata, newRelationType.type);
158
+ setRelationType(config.id, relationUri, newRelationType);
159
+ if (hasConnectionEntity && !isEntitySuitableForNewRelationType) {
160
+ if (modifiedEntity) {
161
+ deleteModifiedEntity(modifiedEntity.uri);
162
+ }
163
+ setRelationEntity(config.id, relationUri, {});
164
+ }
165
+ }, [
166
+ metadata,
167
+ connection.entity,
168
+ mainEntity,
169
+ setRelationType,
170
+ config.id,
171
+ relationUri,
172
+ modifiedEntity,
173
+ setRelationEntity,
174
+ deleteModifiedEntity
175
+ ]);
152
176
  var onChangeEntity = (0, react_1.useCallback)(function (entity) {
153
177
  if (modifiedEntity) {
154
178
  deleteModifiedEntity(modifiedEntity.uri);
@@ -218,8 +242,15 @@ var RelationEditor = function (_a) {
218
242
  var entityTypesUris = (0, react_1.useMemo)(function () {
219
243
  var _a;
220
244
  var _b = config, content = _b.content, contentSecondLevel = _b.contentSecondLevel;
221
- return ((_a = (contentSecondLevel && connection.parentEntityUri ? contentSecondLevel.entityTypes : content.entityTypes)) !== null && _a !== void 0 ? _a : []);
222
- }, [config, connection.parentEntityUri]);
245
+ var entityTypeUrisFromConfig = (_a = (contentSecondLevel && connection.parentEntityUri ? contentSecondLevel.entityTypes : content.entityTypes)) !== null && _a !== void 0 ? _a : [];
246
+ var relationTypeObj = relationType ? (0, mdm_sdk_1.getRelationType)(metadata, relationType) : null;
247
+ var suitableEntityTypeUrisForRelationType = relationTypeObj
248
+ ? (0, mdm_sdk_1.getSuitableEntityTypeUrisForRelationTypes)(direction === mdm_sdk_1.Directions.OUT, metadata, [relationTypeObj])
249
+ : [];
250
+ return entityTypeUrisFromConfig.length > 0
251
+ ? entityTypeUrisFromConfig.filter(function (uri) { return suitableEntityTypeUrisForRelationType.includes(uri); })
252
+ : suitableEntityTypeUrisForRelationType;
253
+ }, [config, connection.parentEntityUri, relationType, direction, metadata]);
223
254
  var isEntityHasMaskedAttrValue = (0, ramda_1.pipe)(ramda_1.values, ramda_1.flatten, (0, ramda_1.any)(mdm_sdk_1.isAttributeHasMaskedValue))(((_d = (_c = connection.entity) === null || _c === void 0 ? void 0 : _c.object) === null || _d === void 0 ? void 0 : _d.attributes) || {});
224
255
  var isMasked = showMasking && isEntityHasMaskedAttrValue;
225
256
  return (react_1.default.createElement(react_1.default.Fragment, null,
@@ -298,6 +298,51 @@ describe('relation editor behaviour', function () {
298
298
  }
299
299
  });
300
300
  }); });
301
+ it('should pass only entity types suitable for current relation type to EntitySelector', function () { return __awaiter(void 0, void 0, void 0, function () {
302
+ var config, props, user;
303
+ return __generator(this, function (_a) {
304
+ switch (_a.label) {
305
+ case 0:
306
+ mdm_sdk_1.typeAheadSearch.mockResolvedValue([
307
+ { type: 'configuration/entityTypes/Location', label: 'location entity 1', uri: 'entities/0C32GxR' }
308
+ ]);
309
+ config = __assign(__assign({}, defaultProps.config), { content: {
310
+ entityTypes: ['configuration/entityTypes/Location', 'configuration/entityTypes/HCA'],
311
+ outRelations: [{ uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' }]
312
+ } });
313
+ props = __assign(__assign({}, defaultProps), { config: config });
314
+ user = setUp({ props: props }).user;
315
+ return [4 /*yield*/, user.click(react_2.screen.getByTestId('select-dropdown-indicator'))];
316
+ case 1:
317
+ _a.sent();
318
+ expect(mdm_sdk_1.typeAheadSearch).toHaveBeenCalledWith([defaultProps.metadata.entityTypes[1]], '', expect.any(Object));
319
+ expect(mdm_sdk_1.typeAheadSearch).not.toHaveBeenCalledWith(expect.arrayContaining([expect.objectContaining({ uri: 'configuration/entityTypes/HCA' })]), expect.any(String), expect.any(Object));
320
+ return [2 /*return*/];
321
+ }
322
+ });
323
+ }); });
324
+ it('should pass all suitable entity types from metadata to EntitySelector when entityTypes from config is empty', function () { return __awaiter(void 0, void 0, void 0, function () {
325
+ var config, props, user;
326
+ return __generator(this, function (_a) {
327
+ switch (_a.label) {
328
+ case 0:
329
+ mdm_sdk_1.typeAheadSearch.mockResolvedValue([
330
+ { type: 'configuration/entityTypes/Location', label: 'location entity 1', uri: 'entities/0C32GxR' }
331
+ ]);
332
+ config = __assign(__assign({}, defaultProps.config), { content: {
333
+ entityTypes: [],
334
+ outRelations: [{ uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' }]
335
+ } });
336
+ props = __assign(__assign({}, defaultProps), { config: config });
337
+ user = setUp({ props: props }).user;
338
+ return [4 /*yield*/, user.click(react_2.screen.getByTestId('select-dropdown-indicator'))];
339
+ case 1:
340
+ _a.sent();
341
+ expect(mdm_sdk_1.typeAheadSearch).toHaveBeenCalledWith([defaultProps.metadata.entityTypes[1]], '', expect.any(Object));
342
+ return [2 /*return*/];
343
+ }
344
+ });
345
+ }); });
301
346
  it('should render attributes list correctly', function () { return __awaiter(void 0, void 0, void 0, function () {
302
347
  var labels, values;
303
348
  return __generator(this, function (_a) {
@@ -356,7 +401,7 @@ describe('relation editor behaviour', function () {
356
401
  return __generator(this, function (_a) {
357
402
  switch (_a.label) {
358
403
  case 0:
359
- connection = __assign(__assign({}, defaultProps.connection), { parentEntityUri: 'entities/HsPM72G' });
404
+ connection = __assign(__assign({}, defaultProps.connection), { parentEntityUri: 'entities/HsPM72G', relation: __assign(__assign({}, defaultRelation), { relationType: 'configuration/relationTypes/InternalHCAtoHCA', direction: 'out' }) });
360
405
  config = __assign(__assign({}, defaultProps.config), { contentSecondLevel: {
361
406
  entityTypes: ['configuration/entityTypes/HCA'],
362
407
  outRelations: [{ uri: 'configuration/relationTypes/InternalHCAtoHCA', label: '{directionalLabel}' }]
@@ -463,6 +508,43 @@ describe('relation editor behaviour', function () {
463
508
  }
464
509
  });
465
510
  }); });
511
+ it('should clear connection entity and delete modified entity when relation type changes to one unsuitable for current connection entity', function () { return __awaiter(void 0, void 0, void 0, function () {
512
+ var entityUri, modifiedEntity, connection, config, mdmValues, props, user;
513
+ var _a;
514
+ return __generator(this, function (_b) {
515
+ switch (_b.label) {
516
+ case 0:
517
+ entityUri = 'entities/uri$$tempLocation';
518
+ modifiedEntity = {
519
+ type: 'configuration/entityTypes/Location',
520
+ uri: entityUri,
521
+ attributes: {}
522
+ };
523
+ connection = __assign(__assign({}, defaultProps.connection), { entity: { entityUri: entityUri, entityType: 'configuration/entityTypes/Location' } });
524
+ config = __assign(__assign({}, defaultProps.config), { content: {
525
+ entityTypes: ['configuration/entityTypes/Location', 'configuration/entityTypes/HCA'],
526
+ inRelations: [{ uri: 'configuration/relationTypes/InternalHCAtoHCA', label: '{directionalLabel}' }],
527
+ outRelations: [{ uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' }]
528
+ } });
529
+ mdmValues = __assign(__assign({}, defaultMdmValues), { modifiedEntities: (_a = {}, _a[entityUri] = modifiedEntity, _a) });
530
+ props = __assign(__assign({}, defaultProps), { config: config, connection: connection });
531
+ user = setUp({ mdmValues: mdmValues, props: props }).user;
532
+ return [4 /*yield*/, user.click((0, react_2.within)(react_2.screen.getByTestId('relation-type-selector')).getByTestId('select-dropdown-indicator'))];
533
+ case 1:
534
+ _b.sent();
535
+ return [4 /*yield*/, user.click(react_2.screen.getByText('InternalHCAtoHCA affiliation'))];
536
+ case 2:
537
+ _b.sent();
538
+ expect(mdmActions.setRelationType).toHaveBeenCalledWith(props.config.id, props.connection.relation.relationUri, expect.objectContaining({
539
+ direction: 'in',
540
+ type: expect.objectContaining({ uri: 'configuration/relationTypes/InternalHCAtoHCA' })
541
+ }));
542
+ expect(mdmActions.entityDeleted).toHaveBeenCalledWith(entityUri);
543
+ expect(mdmActions.setRelationEntity).toHaveBeenCalledWith(props.config.id, props.connection.relation.relationUri, {});
544
+ return [2 /*return*/];
545
+ }
546
+ });
547
+ }); });
466
548
  it('should show "create entity" button if mode is not suggesting', function () { return __awaiter(void 0, void 0, void 0, function () {
467
549
  var user, inputs;
468
550
  return __generator(this, function (_a) {
@@ -501,24 +583,24 @@ describe('relation editor behaviour', function () {
501
583
  });
502
584
  }); });
503
585
  it('should hide create button for one of the entity types when user lacks metadata permissions', function () { return __awaiter(void 0, void 0, void 0, function () {
504
- var props, user, inputs;
586
+ var connection, props, user, inputs;
505
587
  return __generator(this, function (_a) {
506
588
  switch (_a.label) {
507
589
  case 0:
590
+ connection = __assign(__assign({}, defaultProps.connection), { relation: __assign(__assign({}, defaultRelation), { relationType: 'configuration/relationTypes/HasAddress', direction: 'out' }) });
508
591
  props = (0, ramda_1.pipe)((0, ramda_1.assocPath)(['metadata', 'entityTypes', 1, 'access'], ['READ', 'UPDATE', 'INITIATE_CHANGE_REQUEST']), (0, ramda_1.assocPath)(['config', 'content'], {
509
592
  entityTypes: ['configuration/entityTypes/Location', 'configuration/entityTypes/HCA'],
510
593
  outRelations: [
511
594
  { uri: 'configuration/relationTypes/HasAddress', label: '{directionalLabel}' },
512
595
  { uri: 'configuration/relationTypes/InternalHCAtoHCA', label: '{directionalLabel}' }
513
596
  ]
514
- }))(defaultProps);
597
+ }), (0, ramda_1.assocPath)(['connection'], connection))(defaultProps);
515
598
  user = setUp({ props: props }).user;
516
599
  inputs = react_2.screen.getAllByRole('combobox');
517
600
  return [4 /*yield*/, user.click(inputs[1])];
518
601
  case 1:
519
602
  _a.sent();
520
603
  expect(react_2.screen.queryByText('Create new Address')).not.toBeInTheDocument();
521
- expect(react_2.screen.getByText('Create new HCA')).toBeInTheDocument();
522
604
  return [2 /*return*/];
523
605
  }
524
606
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reltio/components",
3
- "version": "1.4.2232",
3
+ "version": "1.4.2234",
4
4
  "license": "SEE LICENSE IN LICENSE FILE",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./index.js",
@@ -11,7 +11,7 @@
11
11
  "@fluentui/react-context-selector": "^9.1.26",
12
12
  "@googlemaps/markerclusterer": "^2.5.3",
13
13
  "@react-sigma/core": "3.4.0",
14
- "@reltio/mdm-sdk": "^1.4.2023",
14
+ "@reltio/mdm-sdk": "^1.4.2024",
15
15
  "@vis.gl/react-google-maps": "^1.3.0",
16
16
  "d3-cloud": "^1.2.5",
17
17
  "d3-geo": "^2.0.1",