@reltio/components 1.4.2177 → 1.4.2179
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.
- package/InlineSimpleAttribute/InlineSimpleAttribute.js +4 -1
- package/InlineSimpleAttribute/InlineSimpleAttribute.spec.js +63 -4
- package/cjs/InlineSimpleAttribute/InlineSimpleAttribute.js +4 -1
- package/cjs/InlineSimpleAttribute/InlineSimpleAttribute.spec.js +62 -3
- package/cjs/hooks/useRelationsLoader/useRelationsLoader.js +1 -1
- package/hooks/useRelationsLoader/useRelationsLoader.js +2 -2
- package/package.json +1 -1
|
@@ -28,7 +28,10 @@ export var InlineSimpleAttribute = function (_a) {
|
|
|
28
28
|
var id = getLastUriPart(attributeValue.uri);
|
|
29
29
|
var crosswalkDisabled = isCrosswalkDisabled(crosswalk);
|
|
30
30
|
var canModifyAttribute = !attributeType.system && !crosswalkDisabled;
|
|
31
|
-
var canEdit = canModifyAttribute &&
|
|
31
|
+
var canEdit = canModifyAttribute &&
|
|
32
|
+
!disableEdit &&
|
|
33
|
+
checkMetadataForUpdate(Mode.Editing, attributeType) &&
|
|
34
|
+
(!attributeValue.masked || isUnmaskingNeeded);
|
|
32
35
|
var canDelete = canModifyAttribute && !disableDelete && checkMetadataForDelete(Mode.Editing, attributeType);
|
|
33
36
|
var isTemporary = isTempUri(attributeValue.uri);
|
|
34
37
|
var hasBasicPermission = checkBasicMetadataPermission(MetadataPermissions.UPDATE, attributeType) && !disableEdit && canModifyAttribute;
|
|
@@ -50,8 +50,9 @@ import { render, screen } from '@testing-library/react';
|
|
|
50
50
|
import userEvent from '@testing-library/user-event';
|
|
51
51
|
import { InlineSimpleAttribute } from './InlineSimpleAttribute';
|
|
52
52
|
import * as crosswalksDisplay from '../contexts/CrosswalksDisplayContext';
|
|
53
|
-
import { createNewAttribute } from '@reltio/mdm-sdk';
|
|
53
|
+
import { createNewAttribute, Mode } from '@reltio/mdm-sdk';
|
|
54
54
|
import { MdmModuleProvider } from '../contexts/MdmModuleContext';
|
|
55
|
+
import { MaskedAttributesProvider } from '../contexts/MaskedAttributesContext';
|
|
55
56
|
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { debounce: function (x) { return x; } })); });
|
|
56
57
|
var defaultProps = {
|
|
57
58
|
attributeValue: {
|
|
@@ -83,13 +84,15 @@ var metadata = {
|
|
|
83
84
|
entityTypes: [],
|
|
84
85
|
sources: []
|
|
85
86
|
};
|
|
86
|
-
var setUp = function (props, skipHover) {
|
|
87
|
+
var setUp = function (props, skipHover, providerValues) {
|
|
87
88
|
if (props === void 0) { props = {}; }
|
|
88
89
|
if (skipHover === void 0) { skipHover = false; }
|
|
90
|
+
if (providerValues === void 0) { providerValues = {}; }
|
|
89
91
|
var user = userEvent.setup({ skipHover: skipHover });
|
|
90
92
|
var Providers = function (_a) {
|
|
91
93
|
var children = _a.children;
|
|
92
|
-
return (React.createElement(MdmModuleProvider, { values: { metadata: metadata } },
|
|
94
|
+
return (React.createElement(MdmModuleProvider, { values: __assign({ metadata: metadata }, providerValues) },
|
|
95
|
+
React.createElement(MaskedAttributesProvider, null, children)));
|
|
93
96
|
};
|
|
94
97
|
return __assign({ user: user }, render(React.createElement(InlineSimpleAttribute, __assign({}, defaultProps, props)), { wrapper: Providers }));
|
|
95
98
|
};
|
|
@@ -231,7 +234,7 @@ describe('Inline simple attribute tests', function () {
|
|
|
231
234
|
deleteButton = screen.getByLabelText("You don't have permissions to delete");
|
|
232
235
|
expect(deleteButton.children[0]).toHaveAttribute('aria-disabled', 'true');
|
|
233
236
|
expect(deleteButton).toHaveTextContent('Delete');
|
|
234
|
-
expect(screen.getByText('Edit')
|
|
237
|
+
expect(screen.getByText('Edit')).not.toBeDisabled();
|
|
235
238
|
return [2 /*return*/];
|
|
236
239
|
}
|
|
237
240
|
});
|
|
@@ -457,4 +460,60 @@ describe('Inline simple attribute tests', function () {
|
|
|
457
460
|
}
|
|
458
461
|
});
|
|
459
462
|
}); });
|
|
463
|
+
it('should disable edit action for masked attributes when user has no READ permissions', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
464
|
+
var mockEntity, user, editButton;
|
|
465
|
+
return __generator(this, function (_a) {
|
|
466
|
+
switch (_a.label) {
|
|
467
|
+
case 0:
|
|
468
|
+
mockEntity = {
|
|
469
|
+
uri: 'entities/123',
|
|
470
|
+
type: 'configuration/entityTypes/Individual',
|
|
471
|
+
access: ['READ_MASKED'],
|
|
472
|
+
label: 'Test Entity'
|
|
473
|
+
};
|
|
474
|
+
user = setUp({
|
|
475
|
+
attributeType: __assign(__assign({}, defaultProps.attributeType), { access: ['READ_MASKED'], masking: true }),
|
|
476
|
+
attributeValue: __assign(__assign({}, defaultProps.attributeValue), { masked: true, value: '****' })
|
|
477
|
+
}, true, { entity: mockEntity, showMasking: true, mode: Mode.Viewing }).user;
|
|
478
|
+
return [4 /*yield*/, user.hover(screen.getByText('****'))];
|
|
479
|
+
case 1:
|
|
480
|
+
_a.sent();
|
|
481
|
+
return [4 /*yield*/, user.click(screen.getByLabelText('More actions'))];
|
|
482
|
+
case 2:
|
|
483
|
+
_a.sent();
|
|
484
|
+
editButton = screen.getByLabelText("You don't have permissions to edit");
|
|
485
|
+
expect(editButton.children[0]).toHaveAttribute('aria-disabled', 'true');
|
|
486
|
+
expect(editButton).toHaveTextContent('Edit');
|
|
487
|
+
return [2 /*return*/];
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}); });
|
|
491
|
+
it('should enable edit action for masked attributes when user has needed permissions including READ', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
492
|
+
var mockEntity, user, editButton;
|
|
493
|
+
return __generator(this, function (_a) {
|
|
494
|
+
switch (_a.label) {
|
|
495
|
+
case 0:
|
|
496
|
+
mockEntity = {
|
|
497
|
+
uri: 'entities/123',
|
|
498
|
+
type: 'configuration/entityTypes/Individual',
|
|
499
|
+
access: ['READ_MASKED', 'READ'],
|
|
500
|
+
label: 'Test Entity'
|
|
501
|
+
};
|
|
502
|
+
user = setUp({
|
|
503
|
+
attributeType: __assign(__assign({}, defaultProps.attributeType), { access: ['UPDATE', 'READ_MASKED', 'READ'], masking: true }),
|
|
504
|
+
attributeValue: __assign(__assign({}, defaultProps.attributeValue), { masked: true, value: '****' })
|
|
505
|
+
}, true, { entity: mockEntity, showMasking: true, mode: Mode.Viewing }).user;
|
|
506
|
+
return [4 /*yield*/, user.hover(screen.getByText('****'))];
|
|
507
|
+
case 1:
|
|
508
|
+
_a.sent();
|
|
509
|
+
return [4 /*yield*/, user.click(screen.getByLabelText('More actions'))];
|
|
510
|
+
case 2:
|
|
511
|
+
_a.sent();
|
|
512
|
+
editButton = screen.getByText('Edit');
|
|
513
|
+
expect(editButton).not.toBeDisabled();
|
|
514
|
+
expect(screen.queryByLabelText("You don't have permissions to edit")).not.toBeInTheDocument();
|
|
515
|
+
return [2 /*return*/];
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
}); });
|
|
460
519
|
});
|
|
@@ -57,7 +57,10 @@ var InlineSimpleAttribute = function (_a) {
|
|
|
57
57
|
var id = (0, mdm_sdk_1.getLastUriPart)(attributeValue.uri);
|
|
58
58
|
var crosswalkDisabled = (0, mdm_sdk_1.isCrosswalkDisabled)(crosswalk);
|
|
59
59
|
var canModifyAttribute = !attributeType.system && !crosswalkDisabled;
|
|
60
|
-
var canEdit = canModifyAttribute &&
|
|
60
|
+
var canEdit = canModifyAttribute &&
|
|
61
|
+
!disableEdit &&
|
|
62
|
+
(0, mdm_sdk_1.checkMetadataForUpdate)(mdm_sdk_1.Mode.Editing, attributeType) &&
|
|
63
|
+
(!attributeValue.masked || isUnmaskingNeeded);
|
|
61
64
|
var canDelete = canModifyAttribute && !disableDelete && (0, mdm_sdk_1.checkMetadataForDelete)(mdm_sdk_1.Mode.Editing, attributeType);
|
|
62
65
|
var isTemporary = (0, mdm_sdk_1.isTempUri)(attributeValue.uri);
|
|
63
66
|
var hasBasicPermission = (0, mdm_sdk_1.checkBasicMetadataPermission)(mdm_sdk_1.MetadataPermissions.UPDATE, attributeType) && !disableEdit && canModifyAttribute;
|
|
@@ -80,6 +80,7 @@ var InlineSimpleAttribute_1 = require("./InlineSimpleAttribute");
|
|
|
80
80
|
var crosswalksDisplay = __importStar(require("../contexts/CrosswalksDisplayContext"));
|
|
81
81
|
var mdm_sdk_1 = require("@reltio/mdm-sdk");
|
|
82
82
|
var MdmModuleContext_1 = require("../contexts/MdmModuleContext");
|
|
83
|
+
var MaskedAttributesContext_1 = require("../contexts/MaskedAttributesContext");
|
|
83
84
|
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { debounce: function (x) { return x; } })); });
|
|
84
85
|
var defaultProps = {
|
|
85
86
|
attributeValue: {
|
|
@@ -111,13 +112,15 @@ var metadata = {
|
|
|
111
112
|
entityTypes: [],
|
|
112
113
|
sources: []
|
|
113
114
|
};
|
|
114
|
-
var setUp = function (props, skipHover) {
|
|
115
|
+
var setUp = function (props, skipHover, providerValues) {
|
|
115
116
|
if (props === void 0) { props = {}; }
|
|
116
117
|
if (skipHover === void 0) { skipHover = false; }
|
|
118
|
+
if (providerValues === void 0) { providerValues = {}; }
|
|
117
119
|
var user = user_event_1.default.setup({ skipHover: skipHover });
|
|
118
120
|
var Providers = function (_a) {
|
|
119
121
|
var children = _a.children;
|
|
120
|
-
return (react_1.default.createElement(MdmModuleContext_1.MdmModuleProvider, { values: { metadata: metadata } },
|
|
122
|
+
return (react_1.default.createElement(MdmModuleContext_1.MdmModuleProvider, { values: __assign({ metadata: metadata }, providerValues) },
|
|
123
|
+
react_1.default.createElement(MaskedAttributesContext_1.MaskedAttributesProvider, null, children)));
|
|
121
124
|
};
|
|
122
125
|
return __assign({ user: user }, (0, react_2.render)(react_1.default.createElement(InlineSimpleAttribute_1.InlineSimpleAttribute, __assign({}, defaultProps, props)), { wrapper: Providers }));
|
|
123
126
|
};
|
|
@@ -259,7 +262,7 @@ describe('Inline simple attribute tests', function () {
|
|
|
259
262
|
deleteButton = react_2.screen.getByLabelText("You don't have permissions to delete");
|
|
260
263
|
expect(deleteButton.children[0]).toHaveAttribute('aria-disabled', 'true');
|
|
261
264
|
expect(deleteButton).toHaveTextContent('Delete');
|
|
262
|
-
expect(react_2.screen.getByText('Edit')
|
|
265
|
+
expect(react_2.screen.getByText('Edit')).not.toBeDisabled();
|
|
263
266
|
return [2 /*return*/];
|
|
264
267
|
}
|
|
265
268
|
});
|
|
@@ -485,4 +488,60 @@ describe('Inline simple attribute tests', function () {
|
|
|
485
488
|
}
|
|
486
489
|
});
|
|
487
490
|
}); });
|
|
491
|
+
it('should disable edit action for masked attributes when user has no READ permissions', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
492
|
+
var mockEntity, user, editButton;
|
|
493
|
+
return __generator(this, function (_a) {
|
|
494
|
+
switch (_a.label) {
|
|
495
|
+
case 0:
|
|
496
|
+
mockEntity = {
|
|
497
|
+
uri: 'entities/123',
|
|
498
|
+
type: 'configuration/entityTypes/Individual',
|
|
499
|
+
access: ['READ_MASKED'],
|
|
500
|
+
label: 'Test Entity'
|
|
501
|
+
};
|
|
502
|
+
user = setUp({
|
|
503
|
+
attributeType: __assign(__assign({}, defaultProps.attributeType), { access: ['READ_MASKED'], masking: true }),
|
|
504
|
+
attributeValue: __assign(__assign({}, defaultProps.attributeValue), { masked: true, value: '****' })
|
|
505
|
+
}, true, { entity: mockEntity, showMasking: true, mode: mdm_sdk_1.Mode.Viewing }).user;
|
|
506
|
+
return [4 /*yield*/, user.hover(react_2.screen.getByText('****'))];
|
|
507
|
+
case 1:
|
|
508
|
+
_a.sent();
|
|
509
|
+
return [4 /*yield*/, user.click(react_2.screen.getByLabelText('More actions'))];
|
|
510
|
+
case 2:
|
|
511
|
+
_a.sent();
|
|
512
|
+
editButton = react_2.screen.getByLabelText("You don't have permissions to edit");
|
|
513
|
+
expect(editButton.children[0]).toHaveAttribute('aria-disabled', 'true');
|
|
514
|
+
expect(editButton).toHaveTextContent('Edit');
|
|
515
|
+
return [2 /*return*/];
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
}); });
|
|
519
|
+
it('should enable edit action for masked attributes when user has needed permissions including READ', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
520
|
+
var mockEntity, user, editButton;
|
|
521
|
+
return __generator(this, function (_a) {
|
|
522
|
+
switch (_a.label) {
|
|
523
|
+
case 0:
|
|
524
|
+
mockEntity = {
|
|
525
|
+
uri: 'entities/123',
|
|
526
|
+
type: 'configuration/entityTypes/Individual',
|
|
527
|
+
access: ['READ_MASKED', 'READ'],
|
|
528
|
+
label: 'Test Entity'
|
|
529
|
+
};
|
|
530
|
+
user = setUp({
|
|
531
|
+
attributeType: __assign(__assign({}, defaultProps.attributeType), { access: ['UPDATE', 'READ_MASKED', 'READ'], masking: true }),
|
|
532
|
+
attributeValue: __assign(__assign({}, defaultProps.attributeValue), { masked: true, value: '****' })
|
|
533
|
+
}, true, { entity: mockEntity, showMasking: true, mode: mdm_sdk_1.Mode.Viewing }).user;
|
|
534
|
+
return [4 /*yield*/, user.hover(react_2.screen.getByText('****'))];
|
|
535
|
+
case 1:
|
|
536
|
+
_a.sent();
|
|
537
|
+
return [4 /*yield*/, user.click(react_2.screen.getByLabelText('More actions'))];
|
|
538
|
+
case 2:
|
|
539
|
+
_a.sent();
|
|
540
|
+
editButton = react_2.screen.getByText('Edit');
|
|
541
|
+
expect(editButton).not.toBeDisabled();
|
|
542
|
+
expect(react_2.screen.queryByLabelText("You don't have permissions to edit")).not.toBeInTheDocument();
|
|
543
|
+
return [2 /*return*/];
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
}); });
|
|
488
547
|
});
|
|
@@ -56,7 +56,7 @@ var useRelationsLoader = function (_a) {
|
|
|
56
56
|
};
|
|
57
57
|
var suggested = config.suggested;
|
|
58
58
|
var options = (0, react_1.useMemo)(function () {
|
|
59
|
-
var sendMasked = showMasking && (0, mdm_sdk_1.hasRelationMasking)(metadata) && mode === mdm_sdk_1.Mode.Viewing;
|
|
59
|
+
var sendMasked = showMasking && ((0, mdm_sdk_1.hasRelationMasking)(metadata) || (0, mdm_sdk_1.hasAttributeMasking)(metadata)) && mode === mdm_sdk_1.Mode.Viewing;
|
|
60
60
|
return (0, mdm_sdk_1.addRelationMaskingOptions)({ searchByOv: searchByOv, searchRelationsWithFilter: searchRelationsWithFilter }, sendMasked);
|
|
61
61
|
}, [searchByOv, showMasking, metadata, mode, searchRelationsWithFilter]);
|
|
62
62
|
var filters = (0, react_1.useMemo)(function () {
|
|
@@ -12,7 +12,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
12
12
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
13
13
|
import { cond, pipe, prop, T, evolve, filter as filterFn, when, identity, times, length, ifElse, always } from 'ramda';
|
|
14
14
|
import i18n from 'ui-i18n';
|
|
15
|
-
import { ActivityFilter, addGlobalFilterToQuery, getRelationsForDataTenantEntity, getRelationsForEntity, isAvailableEntityTypeUri, isAvailableRelationTypeUri, isDataTenantEntity, getInOutRelationUri, isTempUri, Mode, wrapInArrayIfNeeded, hasRelationMasking, addRelationMaskingOptions } from '@reltio/mdm-sdk';
|
|
15
|
+
import { ActivityFilter, addGlobalFilterToQuery, getRelationsForDataTenantEntity, getRelationsForEntity, isAvailableEntityTypeUri, isAvailableRelationTypeUri, isDataTenantEntity, getInOutRelationUri, isTempUri, Mode, wrapInArrayIfNeeded, hasRelationMasking, hasAttributeMasking, addRelationMaskingOptions } from '@reltio/mdm-sdk';
|
|
16
16
|
import { useSafePromise } from '../useSafePromise';
|
|
17
17
|
import { usePrevious } from '../usePrevious';
|
|
18
18
|
import { useMdmAction, useMdmDtssPath, useMdmGlobalSearchRequestOptions, useMdmMetadata, useMdmProfileLastLoadedTime, useMdmShowMasking, useMdmTenant } from '../../contexts/MdmModuleContext';
|
|
@@ -50,7 +50,7 @@ export var useRelationsLoader = function (_a) {
|
|
|
50
50
|
};
|
|
51
51
|
var suggested = config.suggested;
|
|
52
52
|
var options = useMemo(function () {
|
|
53
|
-
var sendMasked = showMasking && hasRelationMasking(metadata) && mode === Mode.Viewing;
|
|
53
|
+
var sendMasked = showMasking && (hasRelationMasking(metadata) || hasAttributeMasking(metadata)) && mode === Mode.Viewing;
|
|
54
54
|
return addRelationMaskingOptions({ searchByOv: searchByOv, searchRelationsWithFilter: searchRelationsWithFilter }, sendMasked);
|
|
55
55
|
}, [searchByOv, showMasking, metadata, mode, searchRelationsWithFilter]);
|
|
56
56
|
var filters = useMemo(function () {
|