@reltio/components 1.4.2183 → 1.4.2185

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 (51) hide show
  1. package/CollaborationItem/components/SendMessageArea/styles.d.ts +1 -1
  2. package/DateRangeEditor/styles.d.ts +1 -1
  3. package/DependentLookupEditor/styles.d.ts +1 -1
  4. package/DropDownSelector/DropDownSelector.d.ts +28 -35
  5. package/DropDownSelector/DropDownSelector.js +3 -20
  6. package/DropDownSelector/DropDownSelector.test.js +17 -0
  7. package/DropDownSelector/components/Menu/Menu.d.ts +16 -9
  8. package/DropDownSelector/components/Menu/Menu.js +2 -7
  9. package/DropDownSelector/styles.d.ts +1 -1
  10. package/EntitySelector/EntitySelector.js +24 -4
  11. package/EntitySelector/components/Group/Group.d.ts +18 -10
  12. package/EntitySelector/components/Group/Group.js +8 -9
  13. package/HOCs/withReactSelectMuiSkin/styles.d.ts +1 -1
  14. package/HierarchyNodeTitle/HierarchyNodeTitle.test.js +83 -1
  15. package/HierarchyNodeTitle/useEntityDetails.js +8 -4
  16. package/HierarchyNodeTitle/useEntityDetails.test.js +24 -9
  17. package/MetadataTypesSelector/styles.d.ts +1 -1
  18. package/MultiSelect/styles.d.ts +1 -1
  19. package/ProfileCard/components/ProfileCardPlaceholder/styles.d.ts +1 -1
  20. package/ReactSortableTree/components/NodeRendererDefault/NodeRendererDefault.d.ts +2 -2
  21. package/RelationEditor/RelationEditor.js +5 -7
  22. package/RelationEditor/RelationEditor.test.js +40 -0
  23. package/cjs/CollaborationItem/components/SendMessageArea/styles.d.ts +1 -1
  24. package/cjs/DateRangeEditor/styles.d.ts +1 -1
  25. package/cjs/DependentLookupEditor/styles.d.ts +1 -1
  26. package/cjs/DropDownSelector/DropDownSelector.d.ts +28 -35
  27. package/cjs/DropDownSelector/DropDownSelector.js +4 -21
  28. package/cjs/DropDownSelector/DropDownSelector.test.js +17 -0
  29. package/cjs/DropDownSelector/components/Menu/Menu.d.ts +16 -9
  30. package/cjs/DropDownSelector/components/Menu/Menu.js +2 -7
  31. package/cjs/DropDownSelector/styles.d.ts +1 -1
  32. package/cjs/EntitySelector/EntitySelector.js +23 -3
  33. package/cjs/EntitySelector/components/Group/Group.d.ts +18 -10
  34. package/cjs/EntitySelector/components/Group/Group.js +8 -9
  35. package/cjs/HOCs/withReactSelectMuiSkin/styles.d.ts +1 -1
  36. package/cjs/HierarchyNodeTitle/HierarchyNodeTitle.test.js +83 -1
  37. package/cjs/HierarchyNodeTitle/useEntityDetails.js +6 -2
  38. package/cjs/HierarchyNodeTitle/useEntityDetails.test.js +27 -9
  39. package/cjs/MetadataTypesSelector/styles.d.ts +1 -1
  40. package/cjs/MultiSelect/styles.d.ts +1 -1
  41. package/cjs/ProfileCard/components/ProfileCardPlaceholder/styles.d.ts +1 -1
  42. package/cjs/ReactSortableTree/components/NodeRendererDefault/NodeRendererDefault.d.ts +2 -2
  43. package/cjs/RelationEditor/RelationEditor.js +5 -7
  44. package/cjs/RelationEditor/RelationEditor.test.js +40 -0
  45. package/cjs/features/history/hooks/useHistorySlice.js +1 -1
  46. package/cjs/features/workflow/AddWorkflowDialog/styles.d.ts +1 -1
  47. package/cjs/features/workflow/WorkflowComments/styles.d.ts +1 -1
  48. package/features/history/hooks/useHistorySlice.js +1 -1
  49. package/features/workflow/AddWorkflowDialog/styles.d.ts +1 -1
  50. package/features/workflow/WorkflowComments/styles.d.ts +1 -1
  51. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  type StylesProps = {
2
2
  isEditing?: boolean;
3
3
  };
4
- export declare const useStyles: (props: StylesProps) => import("@mui/styles").ClassNameMap<"button" | "form" | "main" | "root" | "textField" | "avatar" | "buttons">;
4
+ export declare const useStyles: (props: StylesProps) => import("@mui/styles").ClassNameMap<"button" | "form" | "main" | "root" | "avatar" | "textField" | "buttons">;
5
5
  export {};
@@ -1 +1 @@
1
- export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"underline" | "uppercase" | "dropdownIndicator" | "adornedEnd" | "inputRoot" | "inputLabel">;
1
+ export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"underline" | "uppercase" | "dropdownIndicator" | "inputLabel" | "adornedEnd" | "inputRoot">;
@@ -1 +1 @@
1
- export const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"placeholder" | "option" | "dropdownIndicator" | "isCrossedOut" | "clearIndicator">;
1
+ export const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"placeholder" | "option" | "dropdownIndicator" | "clearIndicator" | "isCrossedOut">;
@@ -1,36 +1,29 @@
1
- export function DropDownSelector({ value, label, createLabel, getOptions, options, height, onChange, onCreate, onClear, components, textFieldInputRef, TextFieldProps, classes, ...otherProps }: {
2
- [x: string]: any;
3
- value: any;
4
- label: any;
5
- createLabel: any;
6
- getOptions: any;
7
- options: any;
1
+ import React, { ForwardedRef } from 'react';
2
+ import { TextFieldProps } from '@mui/material/TextField';
3
+ import { PrimitiveValue } from '@reltio/mdm-sdk';
4
+ type Props<T> = {
5
+ value?: T;
6
+ label: string;
7
+ options?: T[];
8
+ getOptions?: (inputValue: string) => Promise<void | T[]>;
9
+ onChange?: (value: T) => void;
10
+ onCreate?: (value: PrimitiveValue, group?: string) => void;
11
+ onClear?: () => void;
12
+ createLabel?: string;
13
+ canCreateOption?: (id?: string) => boolean;
14
+ components?: {
15
+ Group?: React.ElementType;
16
+ ClearIndicator?: React.ElementType;
17
+ Option?: React.ElementType;
18
+ GroupHeading?: React.ElementType;
19
+ SingleValue?: React.ElementType;
20
+ [key: string]: React.ElementType;
21
+ };
22
+ textFieldInputRef?: ForwardedRef<HTMLInputElement>;
23
+ TextFieldProps?: TextFieldProps;
8
24
  height?: number;
9
- onChange?: any;
10
- onCreate: any;
11
- onClear?: any;
12
- components: any;
13
- textFieldInputRef: any;
14
- TextFieldProps: any;
15
- classes: any;
16
- }): React.JSX.Element;
17
- export namespace DropDownSelector {
18
- export { DropDownSelectorType as propTypes };
19
- }
20
- export namespace DropDownSelectorType {
21
- let value: PropTypes.Requireable<object>;
22
- let label: PropTypes.Validator<string>;
23
- let getOptions: PropTypes.Requireable<(...args: any[]) => any>;
24
- let options: PropTypes.Requireable<any[]>;
25
- let onChange: PropTypes.Requireable<(...args: any[]) => any>;
26
- let onCreate: PropTypes.Requireable<(...args: any[]) => any>;
27
- let onClear: PropTypes.Requireable<(...args: any[]) => any>;
28
- let createLabel: PropTypes.Requireable<string>;
29
- let components: PropTypes.Requireable<object>;
30
- let textFieldInputRef: PropTypes.Requireable<object>;
31
- let TextFieldProps: PropTypes.Requireable<object>;
32
- let height: PropTypes.Requireable<number>;
33
- let classes: PropTypes.Requireable<object>;
34
- }
35
- import React from 'react';
36
- import PropTypes from 'prop-types';
25
+ classes?: Record<string, string>;
26
+ [key: string]: unknown;
27
+ };
28
+ export declare const DropDownSelector: <T>({ value, label, options, getOptions, createLabel, height, onChange, onCreate, canCreateOption, onClear, components, textFieldInputRef, TextFieldProps, classes, ...otherProps }: Props<T>) => React.JSX.Element;
29
+ export {};
@@ -21,7 +21,6 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  return t;
22
22
  };
23
23
  import React, { useRef, useState } from 'react';
24
- import PropTypes from 'prop-types';
25
24
  import classnames from 'classnames';
26
25
  import { defaultTo, identity, isEmpty, path, prop } from 'ramda';
27
26
  import { isEmptyValue } from '@reltio/mdm-sdk';
@@ -34,9 +33,9 @@ import { SingleValue } from './components/SingleValue';
34
33
  import { useStyles, customStyles, overloadMenuListStyle, withoutLabelInputStyle } from './styles';
35
34
  export var DropDownSelector = function (_a) {
36
35
  var _b;
37
- var value = _a.value, label = _a.label, createLabel = _a.createLabel, getOptions = _a.getOptions, options = _a.options, _c = _a.height, height = _c === void 0 ? 46 : _c, _d = _a.onChange, onChange = _d === void 0 ? identity : _d, onCreate = _a.onCreate, _e = _a.onClear, onClear = _e === void 0 ? identity : _e, components = _a.components, textFieldInputRef = _a.textFieldInputRef, TextFieldProps = _a.TextFieldProps, classes = _a.classes, otherProps = __rest(_a, ["value", "label", "createLabel", "getOptions", "options", "height", "onChange", "onCreate", "onClear", "components", "textFieldInputRef", "TextFieldProps", "classes"]);
36
+ var value = _a.value, label = _a.label, options = _a.options, getOptions = _a.getOptions, createLabel = _a.createLabel, _c = _a.height, height = _c === void 0 ? 46 : _c, _d = _a.onChange, onChange = _d === void 0 ? identity : _d, onCreate = _a.onCreate, _e = _a.canCreateOption, canCreateOption = _e === void 0 ? function () { return Boolean(onCreate); } : _e, _f = _a.onClear, onClear = _f === void 0 ? identity : _f, _g = _a.components, components = _g === void 0 ? {} : _g, textFieldInputRef = _a.textFieldInputRef, TextFieldProps = _a.TextFieldProps, _h = _a.classes, classes = _h === void 0 ? {} : _h, otherProps = __rest(_a, ["value", "label", "options", "getOptions", "createLabel", "height", "onChange", "onCreate", "canCreateOption", "onClear", "components", "textFieldInputRef", "TextFieldProps", "classes"]);
38
37
  var styles = useStyles({ height: height });
39
- var _f = useState(false), open = _f[0], setOpen = _f[1];
38
+ var _j = useState(false), open = _j[0], setOpen = _j[1];
40
39
  var inputRef = useRef(null);
41
40
  var SelectComponent = getOptions ? AsyncReactSelect : ReactSelect;
42
41
  var showIndicatorSeparator = prop('ClearIndicator', components)
@@ -52,21 +51,5 @@ export var DropDownSelector = function (_a) {
52
51
  var overloadStylesIfNoLabel = isEmpty(label) ? withoutLabelInputStyle : {};
53
52
  var mergedStyles = __assign(__assign(__assign({}, customStyles), overloadStylesIfGroup), overloadStylesIfNoLabel);
54
53
  var mergedClasses = __assign(__assign({}, styles), classes);
55
- return (React.createElement(SelectComponent, __assign({ placeholder: "", defaultOptions: true }, otherProps, { value: defaultTo(null, value), loadOptions: getOptions, options: options, cacheOptions: true, onChange: onChange, onCreate: handleCreate, onClear: onClear, createLabel: createLabel, classes: mergedClasses, styles: mergedStyles, components: __assign(__assign({ DropdownIndicator: ReactSelectDropdownIndicator, LoadingIndicator: EmptyStub, SingleValue: SingleValue, Menu: Menu }, showIndicatorSeparator), components), menuPlacement: "auto", TextFieldProps: __assign(__assign({}, TextFieldProps), { label: label, variant: 'filled', size: 'small', classes: __assign(__assign({}, prop('classes', TextFieldProps)), { root: classnames(styles.formControl, path(['classes', 'root'], TextFieldProps)) }), inputProps: __assign({}, prop('inputProps', TextFieldProps)), InputProps: __assign(__assign({}, prop('InputProps', TextFieldProps)), { classes: __assign(__assign({}, path(['InputProps', 'classes'], TextFieldProps)), { root: classnames(styles.filledInputRoot, path(['InputProps', 'classes', 'root'], TextFieldProps)), underline: classnames((_b = {}, _b[styles.filledInputUnderline] = isEmptyValue(value), _b), path(['InputProps', 'classes', 'underline'], TextFieldProps)), focused: classnames('focused', path(['InputProps', 'classes', 'focused'], TextFieldProps)) }) }), InputLabelProps: __assign(__assign({}, prop('InputLabelProps', TextFieldProps)), { classes: __assign(__assign({}, path(['InputLabelProps', 'classes'], TextFieldProps)), { root: classnames(styles.inputLabel, path(['InputLabelProps', 'classes', 'root'], TextFieldProps)), shrink: classnames('shrink', path(['InputLabelProps', 'classes', 'shrink'], TextFieldProps)) }), shrink: !isEmptyValue(value) ? true : undefined }), ref: textFieldInputRef || inputRef }), inputRef: textFieldInputRef || inputRef, menuIsOpen: open, onMenuOpen: function () { return setOpen(true); }, onMenuClose: function () { return setOpen(false); } })));
54
+ return (React.createElement(SelectComponent, __assign({ placeholder: "", defaultOptions: true }, otherProps, { value: defaultTo(null, value), loadOptions: getOptions, options: options, cacheOptions: true, onChange: onChange, onCreate: handleCreate, onClear: onClear, createLabel: createLabel, canCreateOption: canCreateOption, classes: mergedClasses, styles: mergedStyles, components: __assign(__assign({ DropdownIndicator: ReactSelectDropdownIndicator, LoadingIndicator: EmptyStub, SingleValue: SingleValue, Menu: Menu }, showIndicatorSeparator), components), menuPlacement: "auto", TextFieldProps: __assign(__assign({}, TextFieldProps), { label: label, variant: 'filled', size: 'small', classes: __assign(__assign({}, prop('classes', TextFieldProps)), { root: classnames(styles.formControl, path(['classes', 'root'], TextFieldProps)) }), inputProps: __assign({}, prop('inputProps', TextFieldProps)), InputProps: __assign(__assign({}, prop('InputProps', TextFieldProps)), { classes: __assign(__assign({}, path(['InputProps', 'classes'], TextFieldProps)), { root: classnames(styles.filledInputRoot, path(['InputProps', 'classes', 'root'], TextFieldProps)), underline: classnames((_b = {}, _b[styles.filledInputUnderline] = isEmptyValue(value), _b), path(['InputProps', 'classes', 'underline'], TextFieldProps)), focused: classnames('focused', path(['InputProps', 'classes', 'focused'], TextFieldProps)) }) }), InputLabelProps: __assign(__assign({}, prop('InputLabelProps', TextFieldProps)), { classes: __assign(__assign({}, path(['InputLabelProps', 'classes'], TextFieldProps)), { root: classnames(styles.inputLabel, path(['InputLabelProps', 'classes', 'root'], TextFieldProps)), shrink: classnames('shrink', path(['InputLabelProps', 'classes', 'shrink'], TextFieldProps)) }), shrink: !isEmptyValue(value) ? true : undefined }), ref: textFieldInputRef || inputRef }), inputRef: textFieldInputRef || inputRef, menuIsOpen: open, onMenuOpen: function () { return setOpen(true); }, onMenuClose: function () { return setOpen(false); } })));
56
55
  };
57
- export var DropDownSelectorType = {
58
- value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
59
- label: PropTypes.string.isRequired,
60
- getOptions: PropTypes.func,
61
- options: PropTypes.array,
62
- onChange: PropTypes.func,
63
- onCreate: PropTypes.func,
64
- onClear: PropTypes.func,
65
- createLabel: PropTypes.string,
66
- components: PropTypes.object,
67
- textFieldInputRef: PropTypes.object,
68
- TextFieldProps: PropTypes.object,
69
- height: PropTypes.number,
70
- classes: PropTypes.object
71
- };
72
- DropDownSelector.propTypes = DropDownSelectorType;
@@ -48,6 +48,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
48
48
  import React from 'react';
49
49
  import { render, screen, within } from '@testing-library/react';
50
50
  import userEvent from '@testing-library/user-event';
51
+ import { getMuiIconByName } from '../test-utils';
51
52
  import { DropDownSelector } from './DropDownSelector';
52
53
  var defaultOptions = [
53
54
  { label: 'First option', value: 'option1' },
@@ -159,4 +160,20 @@ describe('Dropdown selector tests', function () {
159
160
  }
160
161
  });
161
162
  }); });
163
+ it('should not show create button if canCreateOption is false', function () { return __awaiter(void 0, void 0, void 0, function () {
164
+ var props, user;
165
+ return __generator(this, function (_a) {
166
+ switch (_a.label) {
167
+ case 0:
168
+ props = __assign(__assign({}, defaultProps), { canCreateOption: function () { return false; }, createLabel: 'Create new option' });
169
+ user = setUp(props).user;
170
+ return [4 /*yield*/, user.click(screen.getByRole('combobox'))];
171
+ case 1:
172
+ _a.sent();
173
+ expect(screen.queryByText('Create new option')).not.toBeInTheDocument();
174
+ expect(getMuiIconByName('Add')).not.toBeInTheDocument();
175
+ return [2 /*return*/];
176
+ }
177
+ });
178
+ }); });
162
179
  });
@@ -1,9 +1,16 @@
1
- export function Menu(props: any): React.JSX.Element;
2
- export namespace Menu {
3
- namespace propTypes {
4
- let children: PropTypes.Validator<PropTypes.ReactElementLike>;
5
- let selectProps: PropTypes.Validator<object>;
6
- }
7
- }
8
- import React from 'react';
9
- import PropTypes from 'prop-types';
1
+ import React, { ReactNode } from 'react';
2
+ type Props = {
3
+ selectProps: {
4
+ createLabel?: string;
5
+ canCreateOption: () => boolean;
6
+ inputValue: string;
7
+ components?: {
8
+ Group?: React.ElementType;
9
+ [key: string]: React.ElementType;
10
+ };
11
+ onCreate: (inputValue: string) => void;
12
+ };
13
+ children: ReactNode;
14
+ };
15
+ export declare const Menu: (props: Props) => React.JSX.Element;
16
+ export {};
@@ -10,21 +10,16 @@ var __assign = (this && this.__assign) || function () {
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
12
  import React from 'react';
13
- import PropTypes from 'prop-types';
14
13
  import { prop } from 'ramda';
15
14
  import AddIcon from '@mui/icons-material/Add';
16
15
  import { ReactSelectMenuWithPopper } from '../../../ReactSelectMenuWithPopper';
17
16
  import { useStyles } from './styles';
18
17
  export var Menu = function (props) {
19
- var _a = props.selectProps, onCreate = _a.onCreate, createLabel = _a.createLabel, inputValue = _a.inputValue, components = _a.components, children = props.children;
18
+ var _a = props.selectProps, onCreate = _a.onCreate, createLabel = _a.createLabel, inputValue = _a.inputValue, components = _a.components, canCreateOption = _a.canCreateOption, children = props.children;
20
19
  var styles = useStyles();
21
20
  return (React.createElement(ReactSelectMenuWithPopper, __assign({}, props),
22
21
  children,
23
- createLabel && !prop('Group', components) && (React.createElement("span", { className: styles.addLabel, onClick: function () { return onCreate(inputValue); } },
22
+ createLabel && !prop('Group', components) && canCreateOption() && (React.createElement("span", { className: styles.addLabel, onClick: function () { return onCreate(inputValue); } },
24
23
  React.createElement(AddIcon, { className: styles.addIcon }),
25
24
  createLabel))));
26
25
  };
27
- Menu.propTypes = {
28
- children: PropTypes.element.isRequired,
29
- selectProps: PropTypes.object.isRequired
30
- };
@@ -1,4 +1,4 @@
1
- export const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"formControl" | "dropdownIndicator" | "control" | "inputLabel" | "valueContainer" | "filledInputRoot" | "filledInputUnderline">;
1
+ export const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"dropdownIndicator" | "control" | "valueContainer" | "formControl" | "filledInputRoot" | "filledInputUnderline" | "inputLabel">;
2
2
  export namespace customStyles {
3
3
  function menu(baseStyles: any): any;
4
4
  function menuList(baseStyles: any): any;
@@ -23,7 +23,7 @@ var __rest = (this && this.__rest) || function (s, e) {
23
23
  import React, { useState, useMemo, useCallback } from 'react';
24
24
  import i18n from 'ui-i18n';
25
25
  import { isEmpty, prop } from 'ramda';
26
- import { typeAheadSearch, getEntityType, isTempUri, isAvailableEntityType } from '@reltio/mdm-sdk';
26
+ import { typeAheadSearch, getEntityType, isTempUri, isAvailableEntityType, checkMetadataForCreate } from '@reltio/mdm-sdk';
27
27
  import { EmptyStub } from '../EmptyStub';
28
28
  import { DropDownSelector } from '../DropDownSelector';
29
29
  import { EntityOption } from './components/EntityOption';
@@ -39,6 +39,18 @@ export var EntitySelector = function (_a) {
39
39
  var styles = useStyles();
40
40
  var _g = useState(''), inputValue = _g[0], setInputValue = _g[1];
41
41
  var entityTypes = useMemo(function () { return entityTypesUris.map(function (type) { return getEntityType(metadata, type); }).filter(isAvailableEntityType); }, [entityTypesUris, metadata]);
42
+ var creatableEntityTypesUris = useMemo(function () {
43
+ return entityTypesUris.filter(function (entityTypeUri) {
44
+ var entityType = getEntityType(metadata, entityTypeUri);
45
+ return checkMetadataForCreate(mode, entityType);
46
+ });
47
+ }, [entityTypesUris, mode, metadata]);
48
+ var canCreateEntity = useCallback(function (entityTypeUri) {
49
+ if (entityTypes.length === 0) {
50
+ return false;
51
+ }
52
+ return creatableEntityTypesUris.includes(entityTypeUri !== null && entityTypeUri !== void 0 ? entityTypeUri : entityTypes[0].uri);
53
+ }, [creatableEntityTypesUris, entityTypes]);
42
54
  var options = useMemo(function () { return (__assign(__assign({}, globalSearchRequestOptions), { max: max, sendMasked: isMasked })); }, [globalSearchRequestOptions, isMasked, max]);
43
55
  var handleCreate = onCreate
44
56
  ? function (value, entityTypeUri) {
@@ -63,8 +75,16 @@ export var EntitySelector = function (_a) {
63
75
  return (isEmpty(entityTypes) ? Promise.resolve([]) : typeAheadSearch(entityTypes, value, options)).then(buildEntityOptions(entityTypes, onCreate));
64
76
  }, [entityTypes, onCreate, options]);
65
77
  var currentEntityType = (isEmpty(entity) ? entityTypes[0] : getEntityType(metadata, entity.entityType)) || {};
66
- var createLabel = onCreate && i18n.text("Create ".concat(inputValue ? "\"".concat(inputValue, "\" as ") : '', "new ").concat(currentEntityType.label));
67
- var label = i18n.text("Select ".concat(entityTypes.length === 1 ? "".concat(entityTypes[0].label, " ") : '', "profile"));
78
+ var createLabel = onCreate &&
79
+ (inputValue
80
+ ? i18n.text('Create "${name}" as new ${entityTypeLabel}', {
81
+ name: inputValue,
82
+ entityTypeLabel: currentEntityType.label
83
+ })
84
+ : i18n.text('Create new ${entityTypeLabel}', { entityTypeLabel: currentEntityType.label }));
85
+ var label = i18n.text('Select ${entityTypeLabel}profile', {
86
+ entityTypeLabel: entityTypes.length === 1 ? "".concat(entityTypes[0].label, " ") : ''
87
+ });
68
88
  var isTempEntity = !isEmpty(entity) && isTempUri(entity.entityUri);
69
89
  var groupComponent = groupMode ? { Group: Group, GroupHeading: EmptyStub } : {};
70
90
  var clearComponent = isTempEntity ? { ClearIndicator: ClearIndicator } : {};
@@ -74,7 +94,7 @@ export var EntitySelector = function (_a) {
74
94
  return (__assign(__assign({}, (TextFieldProps || {})), (_a = {}, _a['data-reltio-id'] = 'reltio-entity-selector', _a)));
75
95
  }, [TextFieldProps]);
76
96
  return (React.createElement(React.Fragment, null,
77
- 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, components: __assign(__assign({ Option: EntityOption, SingleValue: SingleValue }, groupComponent), clearComponent), currentEntityType: currentEntityType, isClearable: true, disableLinkClick: disableLinkClick, TextFieldProps: textFieldProps }, dropDownSelectorProps)),
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)),
78
98
  isTempEntity && (React.createElement("div", { "data-reltio-id": "entity-creator", className: styles.creatorWrapper },
79
99
  React.createElement(EntityCreator, { mode: mode, attributeTypesSelectionStrategy: attributeTypesSelectionStrategy, entityType: currentEntityType, entityUri: entity.entityUri })))));
80
100
  };
@@ -1,10 +1,18 @@
1
- export function Group(props: any): React.JSX.Element;
2
- export namespace Group {
3
- namespace propTypes {
4
- let selectProps: PropTypes.Validator<object>;
5
- let data: PropTypes.Requireable<object>;
6
- let children: PropTypes.Requireable<any[]>;
7
- }
8
- }
9
- import React from 'react';
10
- import PropTypes from 'prop-types';
1
+ import React, { ReactNode } from 'react';
2
+ import { GroupProps } from 'react-select';
3
+ type Props = GroupProps & {
4
+ data: {
5
+ label: string;
6
+ entityType: string;
7
+ [key: string]: unknown;
8
+ };
9
+ selectProps: {
10
+ inputValue: string;
11
+ onCreate?: (value: string, entityType: string) => void;
12
+ canCreateOption: (entityTypeUri: string) => boolean;
13
+ [key: string]: unknown;
14
+ };
15
+ children?: ReactNode;
16
+ };
17
+ export declare const Group: (props: Props) => React.JSX.Element;
18
+ export {};
@@ -10,25 +10,24 @@ var __assign = (this && this.__assign) || function () {
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
12
  import React from 'react';
13
- import PropTypes from 'prop-types';
14
13
  import i18n from 'ui-i18n';
15
14
  import { components } from 'react-select';
16
15
  import AddIcon from '@mui/icons-material/Add';
17
16
  import { useStyles } from './styles';
18
17
  var ComponentsGroup = components.Group;
19
18
  export var Group = function (props) {
20
- var _a = props.selectProps, inputValue = _a.inputValue, onCreate = _a.onCreate, data = props.data, children = props.children;
21
19
  var styles = useStyles();
20
+ var _a = props.selectProps, inputValue = _a.inputValue, onCreate = _a.onCreate, canCreateOption = _a.canCreateOption, data = props.data, children = props.children;
22
21
  return (React.createElement(ComponentsGroup, __assign({}, props),
23
22
  React.createElement("div", { className: styles.groupHeading },
24
23
  React.createElement("span", null, data.label),
25
- onCreate && (React.createElement("span", { onClick: function () { return onCreate(inputValue, data.entityType); }, className: styles.addLabel },
24
+ onCreate && canCreateOption(data.entityType) && (React.createElement("span", { onClick: function () { return onCreate(inputValue, data.entityType); }, className: styles.addLabel },
26
25
  React.createElement(AddIcon, { className: styles.addIcon }),
27
- i18n.text("Create ".concat(inputValue ? "\"".concat(inputValue, "\" as ") : '', "new ").concat(data.label))))),
26
+ inputValue
27
+ ? i18n.text('Create "${name}" as new ${entityTypeLabel}', {
28
+ name: inputValue,
29
+ entityTypeLabel: data.label
30
+ })
31
+ : i18n.text('Create new ${entityTypeLabel}', { entityTypeLabel: data.label })))),
28
32
  children));
29
33
  };
30
- Group.propTypes = {
31
- selectProps: PropTypes.object.isRequired,
32
- data: PropTypes.object,
33
- children: PropTypes.array
34
- };
@@ -1 +1 @@
1
- export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"menu" | "placeholder" | "option" | "singleValue" | "dropdownIndicator" | "control" | "option--selected" | "option--item" | "clearIndicator" | "groupHeading" | "multiValue" | "noOptionsMessage" | "valueContainer" | "multiValue__label" | "valueContainer--multi">;
1
+ export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"menu" | "placeholder" | "option" | "singleValue" | "dropdownIndicator" | "clearIndicator" | "control" | "groupHeading" | "multiValue" | "noOptionsMessage" | "valueContainer" | "multiValue__label" | "option--selected" | "option--item" | "valueContainer--multi">;
@@ -63,7 +63,21 @@ var defaultProps = {
63
63
  entityUri: 'entities/123',
64
64
  anchorEl: document.createElement('div')
65
65
  };
66
- var defaultMdmValues = { uiPath: 'http://localhost:3000/ui/sokol/', metadata: { entityTypes: [], relationTypes: [] } };
66
+ var getDefaultMetadata = function (masking) {
67
+ if (masking === void 0) { masking = false; }
68
+ return ({
69
+ entityTypes: [
70
+ {
71
+ uri: 'configuration/entityTypes/HCP',
72
+ attributes: [
73
+ __assign({ uri: 'configuration/entityTypes/HCP/attributes/FirstName', type: 'String', name: 'FirstName', label: 'First Name' }, (masking && { masking: { regexPattern: '.*' } }))
74
+ ]
75
+ }
76
+ ],
77
+ relationTypes: []
78
+ });
79
+ };
80
+ var defaultMdmValues = { uiPath: 'http://localhost:3000/ui/sokol/', metadata: getDefaultMetadata(), showMasking: true };
67
81
  var defaultMdmActions = { openEntity: jest.fn() };
68
82
  var setUp = function (_a) {
69
83
  var _b = _a === void 0 ? {} : _a, _c = _b.props, props = _c === void 0 ? defaultProps : _c, _d = _b.mdmValues, mdmValues = _d === void 0 ? defaultMdmValues : _d, _e = _b.mdmActions, mdmActions = _e === void 0 ? defaultMdmActions : _e;
@@ -136,6 +150,9 @@ describe('Hierarchy node title tests', function () {
136
150
  }); })];
137
151
  case 2:
138
152
  _a.sent();
153
+ expect(getEntity).toHaveBeenCalledWith('entities/123', {
154
+ options: 'sendHidden,addRefAttrUriToCrosswalk'
155
+ });
139
156
  within(tooltip).getByAltText('fallback entity avatar');
140
157
  within(tooltip).getByText('perfect entity');
141
158
  within(tooltip).getByText('ID:');
@@ -148,4 +165,69 @@ describe('Hierarchy node title tests', function () {
148
165
  }
149
166
  });
150
167
  }); });
168
+ it('should pass sendMasked option to getEntity if metadata has masking', function () { return __awaiter(void 0, void 0, void 0, function () {
169
+ var user, entityWithMasking;
170
+ return __generator(this, function (_a) {
171
+ switch (_a.label) {
172
+ case 0:
173
+ user = setUp({ mdmValues: __assign(__assign({}, defaultMdmValues), { metadata: getDefaultMetadata(true) }) }).user;
174
+ return [4 /*yield*/, user.hover(screen.getByText('Title'))];
175
+ case 1:
176
+ _a.sent();
177
+ expect(screen.getByRole('tooltip')).toBeInTheDocument();
178
+ entityWithMasking = {
179
+ uri: 'entities/123',
180
+ label: '***t entity',
181
+ type: 'configuration/entityTypes/HCP'
182
+ };
183
+ return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
184
+ return __generator(this, function (_a) {
185
+ switch (_a.label) {
186
+ case 0: return [4 /*yield*/, resolveGetEntity(entityWithMasking)];
187
+ case 1:
188
+ _a.sent();
189
+ return [2 /*return*/];
190
+ }
191
+ });
192
+ }); })];
193
+ case 2:
194
+ _a.sent();
195
+ expect(getEntity).toHaveBeenCalledWith('entities/123', {
196
+ options: 'sendHidden,addRefAttrUriToCrosswalk,sendMasked'
197
+ });
198
+ return [2 /*return*/];
199
+ }
200
+ });
201
+ }); });
202
+ it('should not pass sendMasked option to getEntity if metadata has masking but showMasking is false', function () { return __awaiter(void 0, void 0, void 0, function () {
203
+ var user;
204
+ return __generator(this, function (_a) {
205
+ switch (_a.label) {
206
+ case 0:
207
+ user = setUp({
208
+ mdmValues: __assign(__assign({}, defaultMdmValues), { metadata: getDefaultMetadata(true), showMasking: false })
209
+ }).user;
210
+ return [4 /*yield*/, user.hover(screen.getByText('Title'))];
211
+ case 1:
212
+ _a.sent();
213
+ expect(screen.getByRole('tooltip')).toBeInTheDocument();
214
+ return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
215
+ return __generator(this, function (_a) {
216
+ switch (_a.label) {
217
+ case 0: return [4 /*yield*/, resolveGetEntity(entity)];
218
+ case 1:
219
+ _a.sent();
220
+ return [2 /*return*/];
221
+ }
222
+ });
223
+ }); })];
224
+ case 2:
225
+ _a.sent();
226
+ expect(getEntity).toHaveBeenCalledWith('entities/123', {
227
+ options: 'sendHidden,addRefAttrUriToCrosswalk'
228
+ });
229
+ return [2 /*return*/];
230
+ }
231
+ });
232
+ }); });
151
233
  });
@@ -1,20 +1,24 @@
1
- import { useState, useCallback, useEffect } from 'react';
2
- import { getEntity, debounce } from '@reltio/mdm-sdk';
1
+ import { useState, useCallback, useEffect, useMemo } from 'react';
2
+ import { getEntity, debounce, addGetEntityMaskingOptions } from '@reltio/mdm-sdk';
3
3
  import { useSafePromise } from '../hooks/useSafePromise';
4
+ import { useMdmMetadata, useMdmShowMasking } from '../contexts/MdmModuleContext';
4
5
  export var useEntityDetails = function (entityUri) {
5
6
  var _a = useState(null), entityDetails = _a[0], setEntityDetails = _a[1];
6
7
  var _b = useState(false), isLoading = _b[0], setIsLoading = _b[1];
7
8
  var safePromise = useSafePromise();
8
9
  var cancelRequest = useCallback(function () { return safePromise(Promise.resolve()); }, [safePromise]);
10
+ var metadata = useMdmMetadata();
11
+ var showMasking = useMdmShowMasking();
12
+ var entityOptions = useMemo(function () { return addGetEntityMaskingOptions(metadata, { showMasking: showMasking, showAccess: false }); }, [metadata, showMasking]);
9
13
  var showEntityDetails = useCallback(debounce(function () {
10
14
  setIsLoading(true);
11
- safePromise(getEntity(entityUri))
15
+ safePromise(getEntity(entityUri, entityOptions))
12
16
  .then(setEntityDetails)
13
17
  .catch(function (error) {
14
18
  console.warn('Failed to load entity', error);
15
19
  })
16
20
  .finally(function () { return setIsLoading(false); });
17
- }, 1000), [entityUri, safePromise]);
21
+ }, 1000), [entityUri, safePromise, entityOptions]);
18
22
  var hideEntityDetails = useCallback(function () {
19
23
  cancelRequest();
20
24
  showEntityDetails.cancel();
@@ -45,12 +45,27 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
45
45
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
46
  }
47
47
  };
48
+ import React from 'react';
48
49
  import { renderHook, act } from '@testing-library/react-hooks';
49
50
  import { getEntity, debounce } from '@reltio/mdm-sdk';
51
+ import { MdmModuleProvider } from '../contexts/MdmModuleContext';
50
52
  import { useEntityDetails } from './useEntityDetails';
51
53
  jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { getEntity: jest.fn(), debounce: jest.fn() })); });
54
+ var entity = { uri: 'entities/123', type: 'configuration/entityTypes/HCP' };
55
+ var defaultMdmValues = {
56
+ metadata: {
57
+ entityTypes: []
58
+ }
59
+ };
52
60
  describe('useEntityDetails', function () {
53
- var entity = { uri: 'entities/123', type: 'configuration/entityTypes/HCP' };
61
+ var setUp = function (_a) {
62
+ var _b = _a === void 0 ? {} : _a, _c = _b.props, props = _c === void 0 ? entity.uri : _c, _d = _b.mdmValues, mdmValues = _d === void 0 ? defaultMdmValues : _d;
63
+ var Providers = function (_a) {
64
+ var children = _a.children;
65
+ return (React.createElement(MdmModuleProvider, { values: mdmValues }, children));
66
+ };
67
+ return renderHook(useEntityDetails, { initialProps: props, wrapper: Providers });
68
+ };
54
69
  beforeEach(function () {
55
70
  getEntity.mockResolvedValue(entity);
56
71
  debounce.mockImplementation(function (fn) { return jest.requireActual('@reltio/mdm-sdk').debounce(fn, 10); });
@@ -66,7 +81,7 @@ describe('useEntityDetails', function () {
66
81
  return __generator(this, function (_a) {
67
82
  switch (_a.label) {
68
83
  case 0:
69
- result = renderHook(useEntityDetails, { initialProps: entity.uri }).result;
84
+ result = setUp().result;
70
85
  expect(result.current.isLoading).toBe(false);
71
86
  act(function () {
72
87
  result.current.showEntityDetails();
@@ -78,7 +93,7 @@ describe('useEntityDetails', function () {
78
93
  });
79
94
  expect(result.current.isLoading).toBe(true);
80
95
  expect(result.current.entityDetails).toBe(null);
81
- expect(getEntity).toHaveBeenCalledWith(entity.uri);
96
+ expect(getEntity).toHaveBeenCalledWith(entity.uri, { options: 'sendHidden,addRefAttrUriToCrosswalk' });
82
97
  return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
83
98
  return __generator(this, function (_a) {
84
99
  return [2 /*return*/, Promise.resolve()];
@@ -97,7 +112,7 @@ describe('useEntityDetails', function () {
97
112
  return __generator(this, function (_a) {
98
113
  switch (_a.label) {
99
114
  case 0:
100
- result = renderHook(useEntityDetails, { initialProps: entity.uri }).result;
115
+ result = setUp().result;
101
116
  return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
102
117
  return __generator(this, function (_a) {
103
118
  result.current.showEntityDetails();
@@ -121,7 +136,7 @@ describe('useEntityDetails', function () {
121
136
  return __generator(this, function (_a) {
122
137
  switch (_a.label) {
123
138
  case 0:
124
- result = renderHook(useEntityDetails, { initialProps: entity.uri }).result;
139
+ result = setUp().result;
125
140
  act(function () {
126
141
  result.current.showEntityDetails();
127
142
  jest.runAllTimers();
@@ -144,7 +159,7 @@ describe('useEntityDetails', function () {
144
159
  });
145
160
  }); });
146
161
  it('should clear timeout if hideEntityDetails has been called before request started', function () {
147
- var result = renderHook(useEntityDetails, { initialProps: entity.uri }).result;
162
+ var result = setUp().result;
148
163
  act(function () {
149
164
  result.current.showEntityDetails();
150
165
  });
@@ -167,12 +182,12 @@ describe('useEntityDetails', function () {
167
182
  return __generator(this, function (_a) {
168
183
  switch (_a.label) {
169
184
  case 0:
170
- result = renderHook(useEntityDetails, { initialProps: entity.uri }).result;
185
+ result = setUp().result;
171
186
  act(function () {
172
187
  result.current.showEntityDetails();
173
188
  jest.runAllTimers();
174
189
  });
175
- expect(getEntity).toHaveBeenCalledWith('entities/123');
190
+ expect(getEntity).toHaveBeenCalledWith('entities/123', { options: 'sendHidden,addRefAttrUriToCrosswalk' });
176
191
  expect(result.current.isLoading).toBe(true);
177
192
  expect(result.current.entityDetails).toBe(null);
178
193
  act(function () {
@@ -201,7 +216,7 @@ describe('useEntityDetails', function () {
201
216
  case 0:
202
217
  warnSpy = jest.spyOn(global.console, 'warn');
203
218
  getEntity.mockRejectedValue({ errorCode: 403, errorMessage: 'Access is denied' });
204
- result = renderHook(useEntityDetails, { initialProps: entity.uri }).result;
219
+ result = setUp().result;
205
220
  act(function () {
206
221
  result.current.showEntityDetails();
207
222
  jest.runAllTimers();
@@ -1 +1 @@
1
- export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"icon" | "input" | "root" | "inputRoot" | "inputLabel" | "inputText" | "emptyInput" | "disabledInput" | "disabledPointer" | "disabledUnderline" | "popup-opened-icon">;
1
+ export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"icon" | "input" | "root" | "inputLabel" | "inputRoot" | "inputText" | "emptyInput" | "disabledInput" | "disabledPointer" | "disabledUnderline" | "popup-opened-icon">;
@@ -2,5 +2,5 @@ type PlaceholderProps = {
2
2
  placeholder?: string;
3
3
  label?: string;
4
4
  };
5
- export declare const useStyles: (props: PlaceholderProps) => import("@mui/styles").ClassNameMap<"placeholder" | "label" | "dropdownIndicator" | "option--selected" | "clearIndicator">;
5
+ export declare const useStyles: (props: PlaceholderProps) => import("@mui/styles").ClassNameMap<"placeholder" | "label" | "dropdownIndicator" | "clearIndicator" | "option--selected">;
6
6
  export {};
@@ -1 +1 @@
1
- export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"label" | "info" | "secondaryLabel" | "thirdRow" | "@keyframes keyframes-wave" | "wave" | "avatar">;
1
+ export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"label" | "info" | "secondaryLabel" | "avatar" | "thirdRow" | "@keyframes keyframes-wave" | "wave">;
@@ -42,9 +42,9 @@ export namespace NodeRendererDefault {
42
42
  }
43
43
  namespace propTypes {
44
44
  export let node: PropTypes.Validator<NonNullable<PropTypes.InferProps<{}>>>;
45
- let title_1: PropTypes.Requireable<NonNullable<((...args: any[]) => any) | PropTypes.ReactNodeLike>>;
45
+ let title_1: PropTypes.Requireable<NonNullable<PropTypes.ReactNodeLike | ((...args: any[]) => any)>>;
46
46
  export { title_1 as title };
47
- let subtitle_1: PropTypes.Requireable<NonNullable<((...args: any[]) => any) | PropTypes.ReactNodeLike>>;
47
+ let subtitle_1: PropTypes.Requireable<NonNullable<PropTypes.ReactNodeLike | ((...args: any[]) => any)>>;
48
48
  export { subtitle_1 as subtitle };
49
49
  export let path: PropTypes.Validator<NonNullable<string | number>[]>;
50
50
  export let treeIndex: PropTypes.Validator<number>;