@reltio/components 1.4.2233 → 1.4.2235

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.
Files changed (49) hide show
  1. package/EntitySelector/EntitySelector.js +1 -1
  2. package/EntitySelector/EntitySelector.test.js +23 -0
  3. package/FileDropZone/FileDropZone.d.ts +9 -0
  4. package/FileDropZone/FileDropZone.js +47 -0
  5. package/FileDropZone/FileDropZone.module.css.js +9 -0
  6. package/FileDropZone/FileDropZone.test.d.ts +1 -0
  7. package/FileDropZone/FileDropZone.test.js +114 -0
  8. package/FileDropZone/index.d.ts +1 -0
  9. package/FileDropZone/index.js +1 -0
  10. package/RelationEditor/RelationEditor.js +35 -4
  11. package/RelationEditor/RelationEditor.test.js +86 -4
  12. package/ScreenProfileBand/ScreenProfileBand.d.ts +2 -1
  13. package/ScreenProfileBand/ScreenProfileBand.js +5 -4
  14. package/ScreenProfileBand/ScreenProfileBand.module.css.js +9 -0
  15. package/ScreenProfileBand/ScreenProfileBand.test.js +5 -0
  16. package/UploadImageDialog/components/TargetBox/TargetBox.js +4 -34
  17. package/UploadImageDialog/components/TargetBox/TargetBox.module.css.js +9 -0
  18. package/UploadImageDialog/components/TargetBox/TargetBox.test.js +5 -38
  19. package/cjs/EntitySelector/EntitySelector.js +1 -1
  20. package/cjs/EntitySelector/EntitySelector.test.js +23 -0
  21. package/cjs/FileDropZone/FileDropZone.d.ts +9 -0
  22. package/cjs/FileDropZone/FileDropZone.js +76 -0
  23. package/cjs/FileDropZone/FileDropZone.module.css.js +9 -0
  24. package/cjs/FileDropZone/FileDropZone.test.d.ts +1 -0
  25. package/cjs/FileDropZone/FileDropZone.test.js +119 -0
  26. package/cjs/FileDropZone/index.d.ts +1 -0
  27. package/cjs/FileDropZone/index.js +5 -0
  28. package/cjs/RelationEditor/RelationEditor.js +34 -3
  29. package/cjs/RelationEditor/RelationEditor.test.js +86 -4
  30. package/cjs/ScreenProfileBand/ScreenProfileBand.d.ts +2 -1
  31. package/cjs/ScreenProfileBand/ScreenProfileBand.js +6 -5
  32. package/cjs/ScreenProfileBand/ScreenProfileBand.module.css.js +9 -0
  33. package/cjs/ScreenProfileBand/ScreenProfileBand.test.js +5 -0
  34. package/cjs/UploadImageDialog/components/TargetBox/TargetBox.js +7 -60
  35. package/cjs/UploadImageDialog/components/TargetBox/TargetBox.module.css.js +9 -0
  36. package/cjs/UploadImageDialog/components/TargetBox/TargetBox.test.js +5 -38
  37. package/cjs/index.d.ts +1 -0
  38. package/cjs/index.js +9 -7
  39. package/index.d.ts +1 -0
  40. package/index.js +1 -0
  41. package/package.json +2 -2
  42. package/ScreenProfileBand/styles.d.ts +0 -1
  43. package/ScreenProfileBand/styles.js +0 -10
  44. package/UploadImageDialog/components/TargetBox/styles.d.ts +0 -1
  45. package/UploadImageDialog/components/TargetBox/styles.js +0 -28
  46. package/cjs/ScreenProfileBand/styles.d.ts +0 -1
  47. package/cjs/ScreenProfileBand/styles.js +0 -13
  48. package/cjs/UploadImageDialog/components/TargetBox/styles.d.ts +0 -1
  49. package/cjs/UploadImageDialog/components/TargetBox/styles.js +0 -31
@@ -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) {
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ children: React.ReactNode;
4
+ onFileDrop: (file: File) => void;
5
+ isAcceptableFile?: (file: File) => boolean;
6
+ className?: string;
7
+ };
8
+ export declare const FileDropZone: React.MemoExoticComponent<({ children, onFileDrop, isAcceptableFile, className }: Props) => React.JSX.Element>;
9
+ export {};
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.FileDropZone = void 0;
30
+ var react_1 = __importStar(require("react"));
31
+ var classnames_1 = __importDefault(require("classnames"));
32
+ var ui_i18n_1 = __importDefault(require("ui-i18n"));
33
+ var FileDropZone_module_css_1 = __importDefault(require("./FileDropZone.module.css"));
34
+ var DEFAULT_ACCEPTABLE_DRAG_TYPE = 'Files';
35
+ exports.FileDropZone = (0, react_1.memo)(function (_a) {
36
+ var _b;
37
+ var children = _a.children, onFileDrop = _a.onFileDrop, isAcceptableFile = _a.isAcceptableFile, className = _a.className;
38
+ var _c = (0, react_1.useState)(false), isActive = _c[0], setIsActive = _c[1];
39
+ var isAcceptableDragType = (0, react_1.useCallback)(function (dragType) { return dragType === DEFAULT_ACCEPTABLE_DRAG_TYPE; }, []);
40
+ var handleDragOver = (0, react_1.useCallback)(function (e) {
41
+ e.preventDefault();
42
+ var dragType = e.dataTransfer.types[0];
43
+ var isValid = isAcceptableDragType(dragType);
44
+ e.dataTransfer.dropEffect = isValid ? 'copy' : 'none';
45
+ setIsActive(isValid);
46
+ }, [isAcceptableDragType]);
47
+ var handleDragEnter = (0, react_1.useCallback)(function (e) {
48
+ e.preventDefault();
49
+ var dragType = e.dataTransfer.types[0];
50
+ setIsActive(isAcceptableDragType(dragType));
51
+ }, [isAcceptableDragType]);
52
+ var handleDragLeave = (0, react_1.useCallback)(function (e) {
53
+ e.preventDefault();
54
+ var relatedTarget = e.relatedTarget;
55
+ var isLeave = relatedTarget && !e.currentTarget.contains(relatedTarget);
56
+ if (isLeave || !relatedTarget) {
57
+ setIsActive(false);
58
+ }
59
+ }, []);
60
+ var handleDrop = (0, react_1.useCallback)(function (e) {
61
+ var _a, _b;
62
+ e.preventDefault();
63
+ setIsActive(false);
64
+ var dragType = e.dataTransfer.types[0];
65
+ if (!isAcceptableDragType(dragType))
66
+ return;
67
+ var file = (_b = (_a = e.dataTransfer.files) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : null;
68
+ if (!file)
69
+ return;
70
+ if (isAcceptableFile && !isAcceptableFile(file))
71
+ return;
72
+ onFileDrop(file);
73
+ }, [isAcceptableDragType, isAcceptableFile, onFileDrop]);
74
+ return (react_1.default.createElement("div", { className: (0, classnames_1.default)(FileDropZone_module_css_1.default.root, className, (_b = {}, _b[FileDropZone_module_css_1.default.active] = isActive, _b)), role: "button", tabIndex: 0, "aria-label": ui_i18n_1.default.text('Drop files here'), onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop }, children));
75
+ });
76
+ exports.FileDropZone.displayName = 'FileDropZone';
@@ -0,0 +1,9 @@
1
+ const styles = {"root":"FileDropZone-root--9QbaV","active":"FileDropZone-active--FUwfs"};
2
+ if (typeof document !== 'undefined') {
3
+ const head = document.head || document.getElementsByTagName('head')[0]
4
+ const style = document.createElement('style');
5
+ style.type = 'text/css'
6
+ style.innerHTML = `.FileDropZone-root--9QbaV{cursor:pointer}.FileDropZone-active--FUwfs{background-color:rgba(0,114,206,.12)}`;
7
+ head.appendChild(style);
8
+ }
9
+ module.exports = styles;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var react_1 = __importDefault(require("react"));
7
+ var react_2 = require("@testing-library/react");
8
+ var FileDropZone_1 = require("./FileDropZone");
9
+ var mockOnFileDrop = jest.fn();
10
+ var setUp = function (_a) {
11
+ var _b = _a === void 0 ? {} : _a, isAcceptableFile = _b.isAcceptableFile;
12
+ return (0, react_2.render)(react_1.default.createElement(FileDropZone_1.FileDropZone, { onFileDrop: mockOnFileDrop, isAcceptableFile: isAcceptableFile },
13
+ react_1.default.createElement("span", null, "Drop content here")));
14
+ };
15
+ describe('FileDropZone', function () {
16
+ afterEach(function () {
17
+ jest.clearAllMocks();
18
+ });
19
+ it('should render children', function () {
20
+ setUp();
21
+ expect(react_2.screen.getByText('Drop content here')).toBeInTheDocument();
22
+ });
23
+ it('should have correct accessibility attributes', function () {
24
+ setUp();
25
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
26
+ expect(dropZone).toBeInTheDocument();
27
+ expect(dropZone).toHaveAttribute('tabindex', '0');
28
+ });
29
+ it('should activate drag state on drag over with acceptable file type', function () {
30
+ setUp();
31
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
32
+ react_2.fireEvent.dragOver(dropZone, {
33
+ dataTransfer: { types: ['Files'], dropEffect: 'copy' }
34
+ });
35
+ expect(dropZone).toHaveClass('active');
36
+ });
37
+ it('should not activate drag state with unacceptable file type', function () {
38
+ setUp();
39
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
40
+ react_2.fireEvent.dragOver(dropZone, {
41
+ dataTransfer: { types: ['Text'], dropEffect: 'none' }
42
+ });
43
+ expect(dropZone).not.toHaveClass('active');
44
+ });
45
+ it('should activate drag state on drag enter with acceptable file type', function () {
46
+ setUp();
47
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
48
+ react_2.fireEvent.dragEnter(dropZone, {
49
+ dataTransfer: { types: ['Files'] }
50
+ });
51
+ expect(dropZone).toHaveClass('active');
52
+ });
53
+ it('should deactivate drag state on drag leave', function () {
54
+ setUp();
55
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
56
+ react_2.fireEvent.dragOver(dropZone, { dataTransfer: { types: ['Files'] } });
57
+ expect(dropZone).toHaveClass('active');
58
+ react_2.fireEvent.dragLeave(dropZone);
59
+ expect(dropZone).not.toHaveClass('active');
60
+ });
61
+ it('should call onFileDrop with the dropped file', function () {
62
+ var file = new File(['test content'], 'test.csv', { type: 'text/csv' });
63
+ setUp();
64
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
65
+ react_2.fireEvent.drop(dropZone, {
66
+ dataTransfer: {
67
+ files: [file],
68
+ types: ['Files']
69
+ }
70
+ });
71
+ expect(mockOnFileDrop).toHaveBeenCalledWith(file);
72
+ });
73
+ it('should not call onFileDrop if dropped item is not of file type', function () {
74
+ setUp();
75
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
76
+ react_2.fireEvent.drop(dropZone, {
77
+ dataTransfer: { types: ['Text'] }
78
+ });
79
+ expect(mockOnFileDrop).not.toHaveBeenCalled();
80
+ });
81
+ it('should not call onFileDrop if isAcceptableFile returns false', function () {
82
+ var file = new File(['test content'], 'test.exe', { type: 'application/octet-stream' });
83
+ setUp({ isAcceptableFile: function (f) { return f.name.endsWith('.csv'); } });
84
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
85
+ react_2.fireEvent.drop(dropZone, {
86
+ dataTransfer: {
87
+ files: [file],
88
+ types: ['Files']
89
+ }
90
+ });
91
+ expect(mockOnFileDrop).not.toHaveBeenCalled();
92
+ });
93
+ it('should call onFileDrop if isAcceptableFile returns true', function () {
94
+ var file = new File(['test content'], 'data.csv', { type: 'text/csv' });
95
+ setUp({ isAcceptableFile: function (f) { return f.name.endsWith('.csv'); } });
96
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
97
+ react_2.fireEvent.drop(dropZone, {
98
+ dataTransfer: {
99
+ files: [file],
100
+ types: ['Files']
101
+ }
102
+ });
103
+ expect(mockOnFileDrop).toHaveBeenCalledWith(file);
104
+ });
105
+ it('should deactivate drag state after drop', function () {
106
+ var file = new File(['test content'], 'test.csv', { type: 'text/csv' });
107
+ setUp();
108
+ var dropZone = react_2.screen.getByRole('button', { name: 'Drop files here' });
109
+ react_2.fireEvent.dragOver(dropZone, { dataTransfer: { types: ['Files'] } });
110
+ expect(dropZone).toHaveClass('active');
111
+ react_2.fireEvent.drop(dropZone, {
112
+ dataTransfer: {
113
+ files: [file],
114
+ types: ['Files']
115
+ }
116
+ });
117
+ expect(dropZone).not.toHaveClass('active');
118
+ });
119
+ });
@@ -0,0 +1 @@
1
+ export { FileDropZone } from './FileDropZone';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileDropZone = void 0;
4
+ var FileDropZone_1 = require("./FileDropZone");
5
+ Object.defineProperty(exports, "FileDropZone", { enumerable: true, get: function () { return FileDropZone_1.FileDropZone; } });
@@ -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
  });
@@ -4,6 +4,7 @@ type Props = {
4
4
  entity: Entity;
5
5
  className?: string;
6
6
  historySlice?: HistorySlice;
7
+ children?: React.ReactNode;
7
8
  };
8
- export declare const ScreenProfileBand: React.MemoExoticComponent<({ entity, className, historySlice }: Props) => React.JSX.Element>;
9
+ export declare const ScreenProfileBand: React.MemoExoticComponent<({ entity, className, historySlice, children }: Props) => React.JSX.Element>;
9
10
  export {};
@@ -37,17 +37,18 @@ var CollaborationContext_1 = require("../contexts/CollaborationContext");
37
37
  var constants_1 = require("../constants");
38
38
  var useCollaboration_1 = require("../hooks/useCollaboration");
39
39
  var history_1 = require("../features/history");
40
- var styles_1 = require("./styles");
40
+ var ScreenProfileBand_module_css_1 = __importDefault(require("./ScreenProfileBand.module.css"));
41
41
  exports.ScreenProfileBand = (0, react_1.memo)(function (_a) {
42
- var entity = _a.entity, className = _a.className, historySlice = _a.historySlice;
43
- var styles = (0, styles_1.useStyles)();
42
+ var entity = _a.entity, className = _a.className, historySlice = _a.historySlice, children = _a.children;
44
43
  var objectIds = (0, react_1.useMemo)(function () { return (0, mdm_sdk_1.getProfileBandObjectIdsForCollaboration)(entity); }, [entity]);
45
44
  var collaboration = (0, useCollaboration_1.useCollaboration)({ objectIds: objectIds });
46
45
  var entityUri = (0, mdm_sdk_1.getEntityUriForLink)(entity);
47
46
  return (react_1.default.createElement(CollaborationContext_1.CollaborationContextProvider, { collaboration: collaboration },
48
47
  react_1.default.createElement(ProfileBand_1.ProfileBand, { className: (0, classnames_1.default)(className, constants_1.COMMENTS_CONTAINER_VISIBILITY_AREA), entity: (historySlice === null || historySlice === void 0 ? void 0 : historySlice.aEntity) || entity }, historySlice ? (react_1.default.createElement(history_1.ProfileBandHistory, null)) : (react_1.default.createElement(react_1.default.Fragment, null,
49
- react_1.default.createElement(ProfileBandNavigation_1.ProfileBandNavigation, { className: styles.profileBandNavigation }),
50
- react_1.default.createElement(CommentsContainer_1.CommentsContainer, { className: styles.comments, uri: entityUri, relatedObjectUris: (0, mdm_sdk_1.createRelatedObjectUris)(mdm_sdk_1.CollaborationObjectTypes.ENTITY, {
48
+ children ? (react_1.default.createElement("div", { className: (0, classnames_1.default)(ScreenProfileBand_module_css_1.default.profileBandNavigation, ScreenProfileBand_module_css_1.default.navigationRow) },
49
+ react_1.default.createElement(ProfileBandNavigation_1.ProfileBandNavigation, null),
50
+ children)) : (react_1.default.createElement(ProfileBandNavigation_1.ProfileBandNavigation, { className: ScreenProfileBand_module_css_1.default.profileBandNavigation })),
51
+ react_1.default.createElement(CommentsContainer_1.CommentsContainer, { className: ScreenProfileBand_module_css_1.default.comments, uri: entityUri, relatedObjectUris: (0, mdm_sdk_1.createRelatedObjectUris)(mdm_sdk_1.CollaborationObjectTypes.ENTITY, {
51
52
  entityUri: entityUri
52
53
  }), objectType: mdm_sdk_1.CollaborationObjectTypes.ENTITY }))))));
53
54
  });
@@ -0,0 +1,9 @@
1
+ const styles = {"profileBandNavigation":"ScreenProfileBand-profileBandNavigation--5BMn5","navigationRow":"ScreenProfileBand-navigationRow---CH-F","comments":"ScreenProfileBand-comments--RRYzS"};
2
+ if (typeof document !== 'undefined') {
3
+ const head = document.head || document.getElementsByTagName('head')[0]
4
+ const style = document.createElement('style');
5
+ style.type = 'text/css'
6
+ style.innerHTML = `.ScreenProfileBand-profileBandNavigation--5BMn5{margin-bottom:10px}.ScreenProfileBand-navigationRow---CH-F{align-items:center;display:flex;gap:8px}.ScreenProfileBand-comments--RRYzS{display:flex;justify-content:flex-end}`;
7
+ head.appendChild(style);
8
+ }
9
+ module.exports = styles;
@@ -127,6 +127,11 @@ describe('Screen profile band tests', function () {
127
127
  }
128
128
  });
129
129
  }); });
130
+ it('should render children when provided', function () {
131
+ var props = __assign(__assign({}, defaultProps), { children: react_1.default.createElement("button", null, "Custom Action") });
132
+ setUp({ props: props });
133
+ expect(react_2.screen.getByRole('button', { name: 'Custom Action' })).toBeInTheDocument();
134
+ });
130
135
  it('should render profile band history if historySlice prop is provided', function () { return __awaiter(void 0, void 0, void 0, function () {
131
136
  var historySlice, props, mdmValues;
132
137
  return __generator(this, function (_a) {
@@ -1,77 +1,24 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  exports.TargetBox = void 0;
30
- var react_1 = __importStar(require("react"));
7
+ var react_1 = __importDefault(require("react"));
31
8
  var classnames_1 = __importDefault(require("classnames"));
32
9
  var ui_i18n_1 = __importDefault(require("ui-i18n"));
33
10
  var Typography_1 = __importDefault(require("@mui/material/Typography"));
11
+ var FileDropZone_1 = require("../../../FileDropZone");
34
12
  var SelectImageButton_1 = require("../SelectImageButton");
35
13
  var UploadIcon_1 = __importDefault(require("../../../icons/UploadIcon"));
36
14
  var constants_1 = require("../../constants");
37
- var styles_1 = require("./styles");
38
- var ACCEPTABLE_FILE_TYPE = 'Files';
15
+ var TargetBox_module_css_1 = __importDefault(require("./TargetBox.module.css"));
39
16
  var TargetBox = function (_a) {
40
- var _b;
41
17
  var onAppendFile = _a.onAppendFile, className = _a.className;
42
- var styles = (0, styles_1.useStyles)();
43
- var _c = (0, react_1.useState)(false), isActive = _c[0], setIsActive = _c[1];
44
- var handleDragOver = (0, react_1.useCallback)(function (e) {
45
- e.preventDefault();
46
- e.stopPropagation();
47
- var filesType = e.dataTransfer.types[0];
48
- var isValidType = filesType === ACCEPTABLE_FILE_TYPE;
49
- e.dataTransfer.dropEffect = isValidType ? 'copy' : 'none';
50
- setIsActive(isValidType);
51
- }, []);
52
- var handleDragLeave = (0, react_1.useCallback)(function (e) {
53
- e.preventDefault();
54
- e.stopPropagation();
55
- var relatedTarget = e.relatedTarget;
56
- var isLeave = relatedTarget && !e.currentTarget.contains(relatedTarget);
57
- if (isLeave || !relatedTarget) {
58
- setIsActive(false);
59
- }
60
- }, []);
61
- var handleDrop = (0, react_1.useCallback)(function (e) {
62
- e.preventDefault();
63
- e.stopPropagation();
64
- setIsActive(false);
65
- var filesType = e.dataTransfer.types[0];
66
- if (filesType === ACCEPTABLE_FILE_TYPE) {
67
- var file = e.dataTransfer.files[0];
68
- onAppendFile(file);
69
- }
70
- }, [onAppendFile]);
71
- return (react_1.default.createElement("div", { className: (0, classnames_1.default)(styles.root, (_b = {}, _b[styles.isActive] = isActive, _b), className), onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop },
72
- react_1.default.createElement(UploadIcon_1.default, { className: styles.icon }),
73
- react_1.default.createElement(Typography_1.default, { className: styles.title }, ui_i18n_1.default.text('Drag an image here')),
74
- react_1.default.createElement(Typography_1.default, { className: styles.description }, ui_i18n_1.default.text('Acceptable image types would include JPG, PNG, TIFF, GIF, BMP. Maximum image size: ${MAX_IMAGE_SIZE}Mb', {
18
+ return (react_1.default.createElement(FileDropZone_1.FileDropZone, { className: (0, classnames_1.default)(TargetBox_module_css_1.default.root, className), onFileDrop: onAppendFile },
19
+ react_1.default.createElement(UploadIcon_1.default, { className: TargetBox_module_css_1.default.icon }),
20
+ react_1.default.createElement(Typography_1.default, { className: TargetBox_module_css_1.default.title }, ui_i18n_1.default.text('Drag an image here')),
21
+ react_1.default.createElement(Typography_1.default, { className: TargetBox_module_css_1.default.description }, ui_i18n_1.default.text('Acceptable image types would include JPG, PNG, TIFF, GIF, BMP. Maximum image size: ${MAX_IMAGE_SIZE}Mb', {
75
22
  MAX_IMAGE_SIZE: constants_1.MAX_IMAGE_SIZE
76
23
  })),
77
24
  react_1.default.createElement(SelectImageButton_1.SelectImageButton, { onAppendFile: onAppendFile })));
@@ -0,0 +1,9 @@
1
+ const styles = {"root":"TargetBox-root--T8Dyg","icon":"TargetBox-icon--qfl13","title":"TargetBox-title--zQaNU","description":"TargetBox-description--Jyqo5"};
2
+ if (typeof document !== 'undefined') {
3
+ const head = document.head || document.getElementsByTagName('head')[0]
4
+ const style = document.createElement('style');
5
+ style.type = 'text/css'
6
+ style.innerHTML = `.TargetBox-root--T8Dyg{padding:36px 0 29px}.TargetBox-icon--qfl13{height:190px;margin-bottom:24px;pointer-events:none;width:190px}.TargetBox-title--zQaNU{color:var(--mui-palette-text-primary);font-size:20px;font-weight:500;line-height:24px;margin-bottom:8px}.TargetBox-description--Jyqo5{color:var(--mui-palette-text-secondary);font-size:14px;line-height:16px;margin-bottom:24px}`;
7
+ head.appendChild(style);
8
+ }
9
+ module.exports = styles;