@reltio/components 1.4.2251-hotfix.0 → 1.4.2252

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 (25) hide show
  1. package/InlineAttributesPager/InlineAttributesPager.js +4 -2
  2. package/cjs/InlineAttributesPager/InlineAttributesPager.js +3 -1
  3. package/cjs/features/crosswalks/AttributesTable/AttributesTable.js +5 -3
  4. package/cjs/features/crosswalks/AttributesTable/AttributesTable.test-data.d.ts +7 -0
  5. package/cjs/features/crosswalks/AttributesTable/AttributesTable.test-data.js +84 -1
  6. package/cjs/features/crosswalks/AttributesTable/AttributesTable.test.js +129 -5
  7. package/cjs/features/crosswalks/AttributesTable/components/AttributeValuesRenderer/AttributeValuesRenderer.js +4 -1
  8. package/cjs/features/crosswalks/AttributesTable/components/OvValuesRenderer/OvValuesRenderer.js +27 -2
  9. package/cjs/features/crosswalks/AttributesTable/helpers.d.ts +2 -1
  10. package/cjs/features/crosswalks/AttributesTable/helpers.js +12 -1
  11. package/cjs/features/crosswalks/AttributesTable/types.d.ts +1 -0
  12. package/cjs/features/crosswalks/contexts/AttributeValuesSortContext.d.ts +2 -0
  13. package/cjs/features/crosswalks/contexts/AttributeValuesSortContext.js +6 -0
  14. package/features/crosswalks/AttributesTable/AttributesTable.js +6 -4
  15. package/features/crosswalks/AttributesTable/AttributesTable.test-data.d.ts +7 -0
  16. package/features/crosswalks/AttributesTable/AttributesTable.test-data.js +82 -0
  17. package/features/crosswalks/AttributesTable/AttributesTable.test.js +130 -6
  18. package/features/crosswalks/AttributesTable/components/AttributeValuesRenderer/AttributeValuesRenderer.js +4 -1
  19. package/features/crosswalks/AttributesTable/components/OvValuesRenderer/OvValuesRenderer.js +4 -2
  20. package/features/crosswalks/AttributesTable/helpers.d.ts +2 -1
  21. package/features/crosswalks/AttributesTable/helpers.js +10 -0
  22. package/features/crosswalks/AttributesTable/types.d.ts +1 -0
  23. package/features/crosswalks/contexts/AttributeValuesSortContext.d.ts +2 -0
  24. package/features/crosswalks/contexts/AttributeValuesSortContext.js +3 -0
  25. package/package.json +2 -2
@@ -20,7 +20,7 @@ var __rest = (this && this.__rest) || function (s, e) {
20
20
  }
21
21
  return t;
22
22
  };
23
- import React, { useState } from 'react';
23
+ import React, { useContext, useState } from 'react';
24
24
  import { propOr } from 'ramda';
25
25
  import { DataTypes } from '@reltio/mdm-sdk';
26
26
  import { ShowMore } from '../ShowMore';
@@ -29,10 +29,12 @@ import { InlineSimpleAttributesBlock } from './components/InlineSimpleAttributes
29
29
  import { InlineNestedAttributesBlock } from './components/InlineNestedAttributesBlock';
30
30
  import { InlineReferenceAttributesBlock } from './components/InlineReferenceAttributesBlock';
31
31
  import { InlineImageAttributesBlock } from './components/InlineImageAttributesBlock';
32
+ import { AttributeValuesSortContext } from '../features/crosswalks/contexts/AttributeValuesSortContext';
32
33
  import { useStyles } from './styles';
33
34
  export var InlineAttributesPager = function (_a) {
34
35
  var attributeType = _a.attributeType, _b = _a.attributeValues, attributeValues = _b === void 0 ? [] : _b, _c = _a.paging, paging = _c === void 0 ? {} : _c, _d = _a.max, max = _d === void 0 ? Infinity : _d, props = __rest(_a, ["attributeType", "attributeValues", "paging", "max"]);
35
36
  var styles = useStyles();
37
+ var sortAttributeValuesForDisplay = useContext(AttributeValuesSortContext);
36
38
  var _e = useState(max), visibleValuesCount = _e[0], setVisibleValuesCount = _e[1];
37
39
  var totalValues = propOr(attributeValues.length, 'totalValues', paging);
38
40
  var hasPaging = max < totalValues;
@@ -44,7 +46,7 @@ export var InlineAttributesPager = function (_a) {
44
46
  var onShowLess = function () {
45
47
  setVisibleValuesCount(max);
46
48
  };
47
- var shownValues = attributeValues.slice(0, visibleValuesCount);
49
+ var shownValues = sortAttributeValuesForDisplay(attributeValues).slice(0, visibleValuesCount);
48
50
  var hiddenValuesCount = totalValues - visibleValuesCount;
49
51
  var renderValues = function (values) {
50
52
  switch (attributeType.type) {
@@ -55,10 +55,12 @@ var InlineSimpleAttributesBlock_1 = require("./components/InlineSimpleAttributes
55
55
  var InlineNestedAttributesBlock_1 = require("./components/InlineNestedAttributesBlock");
56
56
  var InlineReferenceAttributesBlock_1 = require("./components/InlineReferenceAttributesBlock");
57
57
  var InlineImageAttributesBlock_1 = require("./components/InlineImageAttributesBlock");
58
+ var AttributeValuesSortContext_1 = require("../features/crosswalks/contexts/AttributeValuesSortContext");
58
59
  var styles_1 = require("./styles");
59
60
  var InlineAttributesPager = function (_a) {
60
61
  var attributeType = _a.attributeType, _b = _a.attributeValues, attributeValues = _b === void 0 ? [] : _b, _c = _a.paging, paging = _c === void 0 ? {} : _c, _d = _a.max, max = _d === void 0 ? Infinity : _d, props = __rest(_a, ["attributeType", "attributeValues", "paging", "max"]);
61
62
  var styles = (0, styles_1.useStyles)();
63
+ var sortAttributeValuesForDisplay = (0, react_1.useContext)(AttributeValuesSortContext_1.AttributeValuesSortContext);
62
64
  var _e = (0, react_1.useState)(max), visibleValuesCount = _e[0], setVisibleValuesCount = _e[1];
63
65
  var totalValues = (0, ramda_1.propOr)(attributeValues.length, 'totalValues', paging);
64
66
  var hasPaging = max < totalValues;
@@ -70,7 +72,7 @@ var InlineAttributesPager = function (_a) {
70
72
  var onShowLess = function () {
71
73
  setVisibleValuesCount(max);
72
74
  };
73
- var shownValues = attributeValues.slice(0, visibleValuesCount);
75
+ var shownValues = sortAttributeValuesForDisplay(attributeValues).slice(0, visibleValuesCount);
74
76
  var hiddenValuesCount = totalValues - visibleValuesCount;
75
77
  var renderValues = function (values) {
76
78
  switch (attributeType.type) {
@@ -55,6 +55,7 @@ var CommonRowCellRenderer_1 = require("./components/CommonRowCellRenderer");
55
55
  var LazyRenderer_1 = require("../../../LazyRenderer");
56
56
  var SyncedValueHeightsContext_1 = require("../../../contexts/SyncedValueHeightsContext");
57
57
  var SyncedExpandedAttributesContext_1 = require("../../../contexts/SyncedExpandedAttributesContext");
58
+ var AttributeValuesSortContext_1 = require("../contexts/AttributeValuesSortContext");
58
59
  var styles_1 = require("./styles");
59
60
  var DEFAULT_ROW_HEIGHT = 68;
60
61
  var getIdFromRowValue = function (rowValue) { return rowValue.ovValues.attributeType.uri; };
@@ -149,9 +150,10 @@ var AttributesTable = function (_a) {
149
150
  react_1.default.createElement(ColumnsSettings_1.ColumnsSettings, { columnsData: helpers_1.COLUMNS_DATA, selectedColumns: visibleColumns, onChangeColumns: onChangeVisibleColumns })),
150
151
  react_1.default.createElement("div", { className: styles.tableContent },
151
152
  isLoading && react_1.default.createElement(LinearLoadIndicator_1.LinearLoadIndicator, null),
152
- react_1.default.createElement(SyncedExpandedAttributesContext_1.SyncedExpandedAttributesProvider, null,
153
- react_1.default.createElement(SyncedValueHeightsContext_1.SyncedValueHeightsProvider, null,
154
- react_1.default.createElement(BasicTable_1.BasicTable, { ref: tableRef, fixFirstColumn: true, headRowHeight: 48, defaultColumnWidth: 250, defaultColumnMinWidth: 200, columnsData: visibleColumnsData, dndRowReorderingEnabled: false, dndRowReorderingHandler: handleReorderAttributeTypes, getIdFromRowValue: getIdFromRowValue, rowsData: rowsData, onScroll: debouncedNotifyLazyRenderer, renderRowCell: renderRowCell, getRowCellHeight: getRowCellHeight, context: tableContext })))),
153
+ react_1.default.createElement(AttributeValuesSortContext_1.AttributeValuesSortContext.Provider, { value: helpers_1.sortByPinIgnorePriority },
154
+ react_1.default.createElement(SyncedExpandedAttributesContext_1.SyncedExpandedAttributesProvider, null,
155
+ react_1.default.createElement(SyncedValueHeightsContext_1.SyncedValueHeightsProvider, null,
156
+ react_1.default.createElement(BasicTable_1.BasicTable, { ref: tableRef, fixFirstColumn: true, headRowHeight: 48, defaultColumnWidth: 250, defaultColumnMinWidth: 200, columnsData: visibleColumnsData, dndRowReorderingEnabled: false, dndRowReorderingHandler: handleReorderAttributeTypes, getIdFromRowValue: getIdFromRowValue, rowsData: rowsData, onScroll: debouncedNotifyLazyRenderer, renderRowCell: renderRowCell, getRowCellHeight: getRowCellHeight, context: tableContext }))))),
155
157
  react_1.default.createElement(ConfirmDeleteDialog_1.ConfirmDeleteDialog, { open: !!pendingDeletion, onClose: function () { return setPendingDeletion(null); }, onConfirm: handleDelete }),
156
158
  react_1.default.createElement(ConfirmEditIgnoredDialog_1.ConfirmEditIgnoredDialog, { open: !!pendingIgnoredEditing, onClose: function () { return setPendingIgnoredEditing(null); }, onConfirmEditWithIgnore: function () { return pendingIgnoredEditing && onEdit(pendingIgnoredEditing); }, onConfirmEditWithoutIgnore: function () {
157
159
  if (pendingIgnoredEditing)
@@ -37,3 +37,10 @@ export declare const selectedAttributeTypes: ({
37
37
  description?: undefined;
38
38
  attributes?: undefined;
39
39
  })[];
40
+ export declare const createEntityWithTextFieldSortOrder: () => Entity;
41
+ export declare const deepNestedDisplayOrderEntities: {
42
+ multipleTopLevelWithSortedChildrenInsidePinned(): Entity;
43
+ };
44
+ export declare const referenceDisplayOrderEntities: {
45
+ multipleTopLevelWithSortedAddressLinesInsidePinned(): Entity;
46
+ };
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.selectedAttributeTypes = exports.createMetadata = exports.createEntityWithAllParticipationStatuses = exports.createEntity = void 0;
14
+ exports.referenceDisplayOrderEntities = exports.deepNestedDisplayOrderEntities = exports.createEntityWithTextFieldSortOrder = exports.selectedAttributeTypes = exports.createMetadata = exports.createEntityWithAllParticipationStatuses = exports.createEntity = void 0;
15
15
  var mdm_sdk_1 = require("@reltio/mdm-sdk");
16
16
  var createEntity = function (_a) {
17
17
  var _b = _a === void 0 ? {} : _a, _c = _b.withAppliedSurvivorshipRules, withAppliedSurvivorshipRules = _c === void 0 ? false : _c;
@@ -292,6 +292,20 @@ var createMetadata = function () {
292
292
  ]
293
293
  }
294
294
  ],
295
+ relationTypes: [
296
+ {
297
+ uri: 'configuration/relationTypes/HasAddress',
298
+ label: 'Has Address',
299
+ attributes: [
300
+ {
301
+ label: 'Address Line 1',
302
+ name: 'AddressLine1',
303
+ type: 'String',
304
+ uri: 'configuration/relationTypes/HasAddress/attributes/AddressLine1'
305
+ }
306
+ ]
307
+ }
308
+ ],
295
309
  survivorshipStrategies: [
296
310
  {
297
311
  uri: 'configuration/survivorshipStrategies/LUD',
@@ -375,3 +389,72 @@ exports.selectedAttributeTypes = [
375
389
  ]
376
390
  }
377
391
  ];
392
+ var withFlags = function (flags) { return (__assign(__assign({}, ((flags === null || flags === void 0 ? void 0 : flags.pin) ? { pin: true } : {})), ((flags === null || flags === void 0 ? void 0 : flags.ignored) ? { ignored: true } : {}))); };
393
+ var createBaseEntityWithAttributes = function (attributes) {
394
+ var base = (0, exports.createEntity)();
395
+ return __assign(__assign({}, base), { attributes: __assign(__assign({}, base.attributes), attributes) });
396
+ };
397
+ var textFieldValue = function (suffix, value, flags) { return (__assign({ ov: true, type: 'configuration/entityTypes/HCP/attributes/TextField', uri: "entities/01L2n5z/attributes/TextField/".concat(suffix), value: value }, withFlags(flags))); };
398
+ var createEntityWithTextFieldSortOrder = function () {
399
+ return createBaseEntityWithAttributes({
400
+ TextField: [
401
+ textFieldValue('sort-middle', 'value-middle'),
402
+ textFieldValue('sort-ignored', 'value-ignored', { ignored: true }),
403
+ textFieldValue('sort-pinned', 'value-pinned', { pin: true })
404
+ ]
405
+ });
406
+ };
407
+ exports.createEntityWithTextFieldSortOrder = createEntityWithTextFieldSortOrder;
408
+ var deepNestedChild = function (parentSuffix, childSuffix, value, flags) { return (__assign({ type: 'configuration/entityTypes/HCP/attributes/DeepNested/attributes/FirstLevelNestedSub1', ov: true, value: value, uri: "entities/01L2n5z/attributes/DeepNested/".concat(parentSuffix, "/FirstLevelNestedSub1/").concat(childSuffix) }, withFlags(flags))); };
409
+ var deepNestedParent = function (label, parentSuffix, children, flags) { return (__assign({ label: label, value: {
410
+ FirstLevelNestedSub1: children
411
+ }, ov: true, uri: "entities/01L2n5z/attributes/DeepNested/".concat(parentSuffix) }, withFlags(flags))); };
412
+ exports.deepNestedDisplayOrderEntities = {
413
+ multipleTopLevelWithSortedChildrenInsidePinned: function () {
414
+ return createBaseEntityWithAttributes({
415
+ DeepNested: [
416
+ deepNestedParent('nested-middle', 'nested-middle', [deepNestedChild('nested-middle', 'v1', '1')]),
417
+ deepNestedParent('nested-ignored', 'nested-ignored', [deepNestedChild('nested-ignored', 'v2', '2')], {
418
+ ignored: true
419
+ }),
420
+ deepNestedParent('nested-pinned', 'nested-pinned', [
421
+ deepNestedChild('nested-pinned', 'sort-middle', 'simple-value-middle'),
422
+ deepNestedChild('nested-pinned', 'sort-ignored', 'simple-value-ignored', { ignored: true }),
423
+ deepNestedChild('nested-pinned', 'sort-pinned', 'simple-value-pinned', { pin: true })
424
+ ], { pin: true })
425
+ ]
426
+ });
427
+ }
428
+ };
429
+ var referenceAddress = function (label, parentSuffix, addressLineValues, flags) {
430
+ var parentUri = "entities/2Vek4DnE/attributes/Address/".concat(parentSuffix);
431
+ return __assign({ label: label, refEntity: {
432
+ objectURI: "entities/ref-".concat(parentSuffix),
433
+ type: 'configuration/entityTypes/Location',
434
+ crosswalks: []
435
+ }, refRelation: {
436
+ objectURI: "relations/ref-".concat(parentSuffix),
437
+ type: 'configuration/relationTypes/HasAddress',
438
+ crosswalks: []
439
+ }, uri: parentUri, value: {
440
+ AddressLine1: addressLineValues.map(function (_a) {
441
+ var suffix = _a.suffix, value = _a.value, flags = _a.flags;
442
+ return (__assign({ ov: true, type: 'configuration/entityTypes/Location/attributes/AddressLine1', uri: "".concat(parentUri, "/AddressLine1/").concat(suffix), value: value }, withFlags(flags)));
443
+ })
444
+ }, startObjectCrosswalks: [], ov: true }, withFlags(flags));
445
+ };
446
+ exports.referenceDisplayOrderEntities = {
447
+ multipleTopLevelWithSortedAddressLinesInsidePinned: function () {
448
+ return createBaseEntityWithAttributes({
449
+ Address: [
450
+ referenceAddress('ref-middle', 'ref-middle', [{ suffix: 'v1', value: 'a' }]),
451
+ referenceAddress('ref-ignored', 'ref-ignored', [{ suffix: 'v2', value: 'b' }], { ignored: true }),
452
+ referenceAddress('ref-pinned', 'ref-pinned', [
453
+ { suffix: 'sort-middle', value: 'simple-value-middle' },
454
+ { suffix: 'sort-ignored', value: 'simple-value-ignored', flags: { ignored: true } },
455
+ { suffix: 'sort-pinned', value: 'simple-value-pinned', flags: { pin: true } }
456
+ ], { pin: true })
457
+ ]
458
+ });
459
+ }
460
+ };
@@ -308,6 +308,127 @@ describe('attribute table tests', function () {
308
308
  expect((0, react_2.within)(react_2.screen.getAllByTestId('column-name-ruleType')[2]).getByText('Source system')).toBeInTheDocument();
309
309
  unmockTableSizing();
310
310
  });
311
+ it('should display TextField values in pinned, neutral, then ignored order in OV and values columns', function () {
312
+ var unmockTableSizing = (0, test_utils_1.mockBasicTableSizing)();
313
+ var entity = (0, AttributesTable_test_data_1.createEntityWithTextFieldSortOrder)();
314
+ var baseCw = crosswalksMap.entity['entities/01L2n5z/attributes/TextField/5noU1aB'];
315
+ var sortCrosswalksMap = {
316
+ entity: __assign(__assign({}, crosswalksMap.entity), { 'entities/01L2n5z/attributes/TextField/sort-middle': baseCw, 'entities/01L2n5z/attributes/TextField/sort-pinned': baseCw, 'entities/01L2n5z/attributes/TextField/sort-ignored': baseCw }),
317
+ relation: {}
318
+ };
319
+ setUp(__assign(__assign({}, defaultProps), { entity: entity, crosswalksMap: sortCrosswalksMap, selectedAttributeTypes: [AttributesTable_test_data_1.selectedAttributeTypes[0]], visibleColumns: ['ovValues', 'values'] }));
320
+ var ovCell = getCellByIndexes(0, 0);
321
+ var ovAttributeValueRoots = (0, react_2.within)(ovCell).getAllByTestId('reltio-attribute-value');
322
+ expect(ovAttributeValueRoots).toHaveLength(3);
323
+ expect(ovAttributeValueRoots[0]).toHaveTextContent('value-pinned');
324
+ expect(ovAttributeValueRoots[1]).toHaveTextContent('value-middle');
325
+ expect(ovAttributeValueRoots[2]).toHaveTextContent('value-ignored');
326
+ var valuesCell = getCellByIndexes(0, 1);
327
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-0')).toHaveTextContent('value-pinned');
328
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-1')).toHaveTextContent('value-middle');
329
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-2')).toHaveTextContent('value-ignored');
330
+ unmockTableSizing();
331
+ });
332
+ it('should display Nested attribute values in pinned, neutral, then ignored order in OV and values columns, and child values in that order within one nested parent', function () { return __awaiter(void 0, void 0, void 0, function () {
333
+ var unmockTableSizing, baseCw, nestedVisibleColumns, valuesColumnIndex, nestedCrosswalksMap, user, ovCell, ovLabels, valuesCell, pinnedNestedBlock, simpleWrapper;
334
+ return __generator(this, function (_a) {
335
+ switch (_a.label) {
336
+ case 0:
337
+ unmockTableSizing = (0, test_utils_1.mockBasicTableSizing)();
338
+ baseCw = crosswalksMap.entity['entities/01L2n5z/attributes/TextField/5noU1aB'];
339
+ nestedVisibleColumns = ['ovValues', 'values'];
340
+ valuesColumnIndex = 1;
341
+ nestedCrosswalksMap = {
342
+ entity: __assign(__assign({}, crosswalksMap.entity), { 'entities/01L2n5z/attributes/DeepNested/nested-middle': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-ignored': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-middle/FirstLevelNestedSub1/v1': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-ignored/FirstLevelNestedSub1/v2': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned/FirstLevelNestedSub1/sort-middle': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned/FirstLevelNestedSub1/sort-ignored': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned/FirstLevelNestedSub1/sort-pinned': baseCw }),
343
+ relation: {}
344
+ };
345
+ user = setUp(__assign(__assign({}, defaultProps), { selectedAttributeTypes: [AttributesTable_test_data_1.selectedAttributeTypes[2]], visibleColumns: nestedVisibleColumns, entity: AttributesTable_test_data_1.deepNestedDisplayOrderEntities.multipleTopLevelWithSortedChildrenInsidePinned(), crosswalksMap: nestedCrosswalksMap })).user;
346
+ ovCell = getCellByIndexes(0, 0);
347
+ ovLabels = (0, react_2.within)(ovCell).getAllByTestId('reltio-attribute-complex-label');
348
+ expect(ovLabels).toHaveLength(3);
349
+ expect(ovLabels[0]).toHaveTextContent('nested-pinned');
350
+ expect(ovLabels[1]).toHaveTextContent('nested-middle');
351
+ expect(ovLabels[2]).toHaveTextContent('nested-ignored');
352
+ valuesCell = getCellByIndexes(0, valuesColumnIndex);
353
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-0')).toHaveTextContent('nested-pinned');
354
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-1')).toHaveTextContent('nested-middle');
355
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-2')).toHaveTextContent('nested-ignored');
356
+ pinnedNestedBlock = (0, react_2.within)(valuesCell).getByTestId('value-index-0');
357
+ return [4 /*yield*/, user.click((0, react_2.within)(pinnedNestedBlock).getByTestId('arrow-expand-button'))];
358
+ case 1:
359
+ _a.sent();
360
+ simpleWrapper = (0, react_2.within)(pinnedNestedBlock).getByTestId('simple-attributes-wrapper');
361
+ expect((0, react_2.within)(simpleWrapper).getByTestId('value-index-0')).toHaveTextContent('simple-value-pinned');
362
+ expect((0, react_2.within)(simpleWrapper).getByTestId('value-index-1')).toHaveTextContent('simple-value-middle');
363
+ expect((0, react_2.within)(simpleWrapper).getByTestId('value-index-2')).toHaveTextContent('simple-value-ignored');
364
+ unmockTableSizing();
365
+ return [2 /*return*/];
366
+ }
367
+ });
368
+ }); });
369
+ var relationCw = function (refUri, lineUri) { return [
370
+ {
371
+ uri: "".concat(refUri, "/crosswalks/cw"),
372
+ type: 'configuration/sources/Reltio',
373
+ value: '01L2n5z',
374
+ attributeURIs: [refUri, lineUri]
375
+ }
376
+ ]; };
377
+ var addressAttributeTypeWithRelationLine = __assign(__assign({}, AttributesTable_test_data_1.selectedAttributeTypes[3]), { referencedAttributeURIs: [
378
+ 'configuration/entityTypes/Location/attributes/AddressLine1',
379
+ 'configuration/relationTypes/HasAddress/attributes/AddressLine1'
380
+ ] });
381
+ it('should display Reference attribute values in pinned, neutral, then ignored order in OV and values columns, and AddressLine1 values in that order within one reference', function () { return __awaiter(void 0, void 0, void 0, function () {
382
+ var unmockTableSizing, refVisibleColumns, valuesColumnIndex, refMiddle, lineMiddleParent, refIgnored, lineIgnoredParent, refPinned, linePinnedSortMiddle, linePinnedSortIgnored, linePinnedSortPinned, relationMap, user, ovCell, ovLabels, valuesCell, pinnedReferenceBlock, simpleWrapper;
383
+ var _a;
384
+ return __generator(this, function (_b) {
385
+ switch (_b.label) {
386
+ case 0:
387
+ unmockTableSizing = (0, test_utils_1.mockBasicTableSizing)();
388
+ refVisibleColumns = ['ovValues', 'values'];
389
+ valuesColumnIndex = 1;
390
+ refMiddle = 'entities/2Vek4DnE/attributes/Address/ref-middle';
391
+ lineMiddleParent = "".concat(refMiddle, "/AddressLine1/v1");
392
+ refIgnored = 'entities/2Vek4DnE/attributes/Address/ref-ignored';
393
+ lineIgnoredParent = "".concat(refIgnored, "/AddressLine1/v2");
394
+ refPinned = 'entities/2Vek4DnE/attributes/Address/ref-pinned';
395
+ linePinnedSortMiddle = "".concat(refPinned, "/AddressLine1/sort-middle");
396
+ linePinnedSortIgnored = "".concat(refPinned, "/AddressLine1/sort-ignored");
397
+ linePinnedSortPinned = "".concat(refPinned, "/AddressLine1/sort-pinned");
398
+ relationMap = (_a = {},
399
+ _a[refMiddle] = relationCw(refMiddle, lineMiddleParent),
400
+ _a[lineMiddleParent] = relationCw(refMiddle, lineMiddleParent),
401
+ _a[refIgnored] = relationCw(refIgnored, lineIgnoredParent),
402
+ _a[lineIgnoredParent] = relationCw(refIgnored, lineIgnoredParent),
403
+ _a[refPinned] = relationCw(refPinned, linePinnedSortMiddle),
404
+ _a[linePinnedSortMiddle] = relationCw(refPinned, linePinnedSortMiddle),
405
+ _a[linePinnedSortIgnored] = relationCw(refPinned, linePinnedSortIgnored),
406
+ _a[linePinnedSortPinned] = relationCw(refPinned, linePinnedSortPinned),
407
+ _a);
408
+ user = setUp(__assign(__assign({}, defaultProps), { entity: AttributesTable_test_data_1.referenceDisplayOrderEntities.multipleTopLevelWithSortedAddressLinesInsidePinned(), crosswalksMap: __assign(__assign({}, crosswalksMap), { relation: relationMap }), selectedAttributeTypes: [addressAttributeTypeWithRelationLine], visibleColumns: refVisibleColumns })).user;
409
+ ovCell = getCellByIndexes(0, 0);
410
+ ovLabels = (0, react_2.within)(ovCell).getAllByTestId('reltio-attribute-complex-label');
411
+ expect(ovLabels).toHaveLength(3);
412
+ expect(ovLabels[0]).toHaveTextContent('ref-pinned');
413
+ expect(ovLabels[1]).toHaveTextContent('ref-middle');
414
+ expect(ovLabels[2]).toHaveTextContent('ref-ignored');
415
+ valuesCell = getCellByIndexes(0, valuesColumnIndex);
416
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-0')).toHaveTextContent('ref-pinned');
417
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-1')).toHaveTextContent('ref-middle');
418
+ expect((0, react_2.within)(valuesCell).getByTestId('value-index-2')).toHaveTextContent('ref-ignored');
419
+ pinnedReferenceBlock = (0, react_2.within)(valuesCell).getByTestId('value-index-0');
420
+ return [4 /*yield*/, user.click((0, react_2.within)(pinnedReferenceBlock).getByTestId('arrow-expand-button'))];
421
+ case 1:
422
+ _b.sent();
423
+ simpleWrapper = (0, react_2.within)(pinnedReferenceBlock).getByTestId('simple-attributes-wrapper');
424
+ expect((0, react_2.within)(simpleWrapper).getByTestId('value-index-0')).toHaveTextContent('simple-value-pinned');
425
+ expect((0, react_2.within)(simpleWrapper).getByTestId('value-index-1')).toHaveTextContent('simple-value-middle');
426
+ expect((0, react_2.within)(simpleWrapper).getByTestId('value-index-2')).toHaveTextContent('simple-value-ignored');
427
+ unmockTableSizing();
428
+ return [2 /*return*/];
429
+ }
430
+ });
431
+ }); });
311
432
  it('should render Source sequence after clicking view details button', function () { return __awaiter(void 0, void 0, void 0, function () {
312
433
  var unmockTableSizing, user;
313
434
  return __generator(this, function (_a) {
@@ -709,7 +830,7 @@ describe('attribute table tests', function () {
709
830
  }); });
710
831
  });
711
832
  it('should add attribute to beginning on simple attribute select', function () { return __awaiter(void 0, void 0, void 0, function () {
712
- var onAdd, onSelectAttributeTypes, user, backdrop;
833
+ var onAdd, onSelectAttributeTypes, user, attributePickerPopup, backdrop;
713
834
  return __generator(this, function (_a) {
714
835
  switch (_a.label) {
715
836
  case 0:
@@ -719,14 +840,17 @@ describe('attribute table tests', function () {
719
840
  return [4 /*yield*/, user.click(react_2.screen.getByText('Attribute'))];
720
841
  case 1:
721
842
  _a.sent();
722
- expect(react_2.screen.queryByText('Image')).not.toBeInTheDocument();
723
- expect(react_2.screen.queryByText('Address')).not.toBeInTheDocument();
724
- return [4 /*yield*/, user.click(react_2.screen.getByText('String Label 2'))];
843
+ return [4 /*yield*/, react_2.screen.findByPlaceholderText(/search/i)];
725
844
  case 2:
845
+ attributePickerPopup = (_a.sent()).closest('.MuiPaper-root');
846
+ expect((0, react_2.within)(attributePickerPopup).queryByText('Image')).not.toBeInTheDocument();
847
+ expect((0, react_2.within)(attributePickerPopup).queryByText('Address')).not.toBeInTheDocument();
848
+ return [4 /*yield*/, user.click((0, react_2.within)(attributePickerPopup).getByText('String Label 2'))];
849
+ case 3:
726
850
  _a.sent();
727
851
  backdrop = react_2.screen.getByRole('presentation').children[0];
728
852
  return [4 /*yield*/, user.click(backdrop)];
729
- case 3:
853
+ case 4:
730
854
  _a.sent();
731
855
  expect(onSelectAttributeTypes).toHaveBeenCalledWith(__spreadArray([
732
856
  {
@@ -12,12 +12,15 @@ var __assign = (this && this.__assign) || function () {
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.AttributeValuesRenderer = void 0;
15
+ var react_1 = require("react");
15
16
  var ramda_1 = require("ramda");
16
17
  var AttributesFactory_1 = require("../AttributesFactory");
17
18
  var withTableContext_1 = require("../../../../../HOCs/withTableContext");
19
+ var AttributeValuesSortContext_1 = require("../../../contexts/AttributeValuesSortContext");
18
20
  var AttributeValuesRenderer = function (_a) {
19
21
  var value = _a.value, onDelete = _a.onDelete, onEdit = _a.onEdit, onPin = _a.onPin, onIgnore = _a.onIgnore, onAdd = _a.onAdd, emptyTempAttributeUris = _a.emptyTempAttributeUris, parentUri = _a.parentUri, readOnly = _a.readOnly;
20
- return AttributesFactory_1.AttributesFactory.build(value.attributeType.type, __assign(__assign({}, value), { parentUri: parentUri, onDelete: onDelete, onEdit: onEdit, onPin: onPin, onIgnore: onIgnore, onAdd: onAdd, emptyTempAttributeUris: emptyTempAttributeUris, disableEdit: readOnly, disableDelete: readOnly }));
22
+ var sortAttributeValuesForDisplay = (0, react_1.useContext)(AttributeValuesSortContext_1.AttributeValuesSortContext);
23
+ return AttributesFactory_1.AttributesFactory.build(value.attributeType.type, __assign(__assign({}, value), { attributeValues: sortAttributeValuesForDisplay(value.attributeValues), parentUri: parentUri, onDelete: onDelete, onEdit: onEdit, onPin: onPin, onIgnore: onIgnore, onAdd: onAdd, emptyTempAttributeUris: emptyTempAttributeUris, disableEdit: readOnly, disableDelete: readOnly }));
21
24
  };
22
25
  exports.AttributeValuesRenderer = AttributeValuesRenderer;
23
26
  exports.default = (0, withTableContext_1.withTableContext)((0, ramda_1.pick)(['onDelete', 'onPin', 'onIgnore', 'onEdit', 'onAdd', 'parentUri', 'readOnly', 'emptyTempAttributeUris']))(exports.AttributeValuesRenderer);
@@ -10,14 +10,38 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
13
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
38
  };
16
39
  Object.defineProperty(exports, "__esModule", { value: true });
17
40
  exports.OvValuesRenderer = void 0;
18
- var react_1 = __importDefault(require("react"));
41
+ var react_1 = __importStar(require("react"));
19
42
  var classnames_1 = __importDefault(require("classnames"));
20
43
  var DragIndicator_1 = __importDefault(require("@mui/icons-material/DragIndicator"));
44
+ var AttributeValuesSortContext_1 = require("../../../contexts/AttributeValuesSortContext");
21
45
  var ReadOnlyAttributeValuesBlock_1 = require("../../../../../ReadOnlyAttributeValuesBlock");
22
46
  var AttributeTitle_1 = require("../../../../../AttributeTitle");
23
47
  var EntityContext_1 = require("../../../../../contexts/EntityContext");
@@ -31,11 +55,12 @@ var OvValuesRenderer = function (_a) {
31
55
  var styles = (0, styles_2.useStyles)();
32
56
  var commonStyles = (0, styles_1.useCommonStyles)();
33
57
  var entity = (0, MdmModuleContext_1.useMdmEntity)();
58
+ var sortAttributeValuesForDisplay = (0, react_1.useContext)(AttributeValuesSortContext_1.AttributeValuesSortContext);
34
59
  return (react_1.default.createElement("div", { className: (0, classnames_1.default)(styles.root, commonStyles.basicCell) },
35
60
  react_1.default.createElement("div", __assign({}, draggableProps, { className: styles.dragIndicator }),
36
61
  react_1.default.createElement(DragIndicator_1.default, { className: styles.dragIndicatorIcon })),
37
62
  react_1.default.createElement(AttributeTitle_1.AttributeTitle, { className: styles.attributeTitle, label: attributeType.label }),
38
63
  !someRowIsDragging && (react_1.default.createElement(EntityContext_1.EntityContext.Provider, { value: entity },
39
- react_1.default.createElement(ReadOnlyAttributeValuesBlock_1.ReadOnlyAttributeValuesBlock, { values: values, attributeType: attributeType, valueContainerClassName: styles.ovValue, AttributeValueWrapper: SyncedValueHeight_1.ValueHeightReporter, FallbackSlot: FallbackIndicator_1.FallbackIndicator })))));
64
+ react_1.default.createElement(ReadOnlyAttributeValuesBlock_1.ReadOnlyAttributeValuesBlock, { values: sortAttributeValuesForDisplay(values), attributeType: attributeType, valueContainerClassName: styles.ovValue, AttributeValueWrapper: SyncedValueHeight_1.ValueHeightReporter, FallbackSlot: FallbackIndicator_1.FallbackIndicator })))));
40
65
  };
41
66
  exports.OvValuesRenderer = OvValuesRenderer;
@@ -1,7 +1,7 @@
1
1
  import { AppliedSurvivorshipRule, AttributeType, AttributeValue, Crosswalk, Metadata, OvDetails, RecordAttributesType } from '@reltio/mdm-sdk';
2
2
  import { CrosswalksMap } from '../../../types';
3
3
  import { CrosswalksByOwnerTypeMap } from '../types';
4
- import { AttributesTableRowValue } from './types';
4
+ import { AttributesTableRowValue, SortAttributeValuesFn } from './types';
5
5
  export declare const COLUMNS_DATA: ({
6
6
  id: string;
7
7
  readonly label: string;
@@ -34,3 +34,4 @@ export declare const getFallbackLabels: (metadata: Metadata, ovDetails: OvDetail
34
34
  export declare const getWinnerCrosswalks: (attributeValues: AttributeValue[], crosswalksMap: CrosswalksMap) => Crosswalk[];
35
35
  export declare const getBasicTableColumnsData: any;
36
36
  export declare const getBasicTableRowsData: (metadata: Metadata, parentTypeUri: string, attrTypes: AttributeType[], columns: string[], crosswalksMap: CrosswalksByOwnerTypeMap, attributes: RecordAttributesType, activeSurvivorshipGroupUri?: string) => AttributesTableRowValue[];
37
+ export declare const sortByPinIgnorePriority: SortAttributeValuesFn;
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.getBasicTableRowsData = exports.getBasicTableColumnsData = exports.getWinnerCrosswalks = exports.getFallbackLabels = exports.collectRuleNames = exports.countAttributeValues = exports.DEFAULT_VISIBLE_COLUMNS = exports.COLUMNS_DATA = void 0;
15
+ exports.sortByPinIgnorePriority = exports.getBasicTableRowsData = exports.getBasicTableColumnsData = exports.getWinnerCrosswalks = exports.getFallbackLabels = exports.collectRuleNames = exports.countAttributeValues = exports.DEFAULT_VISIBLE_COLUMNS = exports.COLUMNS_DATA = void 0;
16
16
  var ui_i18n_1 = __importDefault(require("ui-i18n"));
17
17
  var ramda_1 = require("ramda");
18
18
  var mdm_sdk_1 = require("@reltio/mdm-sdk");
@@ -305,3 +305,14 @@ var getBasicTableRowsData = function (metadata, parentTypeUri, attrTypes, column
305
305
  });
306
306
  };
307
307
  exports.getBasicTableRowsData = getBasicTableRowsData;
308
+ var getDisplayTier = function (v) {
309
+ if (v.pin)
310
+ return 0;
311
+ if (v.ignored)
312
+ return 2;
313
+ return 1;
314
+ };
315
+ var sortByPinIgnorePriority = function (values) {
316
+ return ((values && __spreadArray([], values, true)) || []).sort(function (a, b) { return getDisplayTier(a) - getDisplayTier(b); });
317
+ };
318
+ exports.sortByPinIgnorePriority = sortByPinIgnorePriority;
@@ -83,4 +83,5 @@ export type AttributesRendererProps = {
83
83
  onAdd: (event: AddInlineAttributeEvent) => void;
84
84
  emptyTempAttributeUris: string[];
85
85
  };
86
+ export type SortAttributeValuesFn = (values: AttributeValue[]) => AttributeValue[];
86
87
  export {};
@@ -0,0 +1,2 @@
1
+ import { SortAttributeValuesFn } from '../AttributesTable/types';
2
+ export declare const AttributeValuesSortContext: import("react").Context<SortAttributeValuesFn>;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AttributeValuesSortContext = void 0;
4
+ var react_1 = require("react");
5
+ var ramda_1 = require("ramda");
6
+ exports.AttributeValuesSortContext = (0, react_1.createContext)(ramda_1.identity);
@@ -21,12 +21,13 @@ import { BasicViewHeader } from '../../../BasicViewHeader';
21
21
  import { LinearLoadIndicator } from '../../../LinearLoadIndicator';
22
22
  import { ConfirmDeleteDialog } from '../../../ConfirmDeleteDialog';
23
23
  import { useMdmMetadata } from '../../../contexts/MdmModuleContext';
24
- import { COLUMNS_DATA, DEFAULT_VISIBLE_COLUMNS, getBasicTableColumnsData, getBasicTableRowsData } from './helpers';
24
+ import { COLUMNS_DATA, DEFAULT_VISIBLE_COLUMNS, getBasicTableColumnsData, getBasicTableRowsData, sortByPinIgnorePriority } from './helpers';
25
25
  import { ConfirmEditIgnoredDialog } from './components/ConfirmEditIgnoredDialog';
26
26
  import { CommonRowCellRenderer } from './components/CommonRowCellRenderer';
27
27
  import { LazyRenderer } from '../../../LazyRenderer';
28
28
  import { SyncedValueHeightsProvider } from '../../../contexts/SyncedValueHeightsContext';
29
29
  import { SyncedExpandedAttributesProvider } from '../../../contexts/SyncedExpandedAttributesContext';
30
+ import { AttributeValuesSortContext } from '../contexts/AttributeValuesSortContext';
30
31
  import { useStyles } from './styles';
31
32
  var DEFAULT_ROW_HEIGHT = 68;
32
33
  var getIdFromRowValue = function (rowValue) { return rowValue.ovValues.attributeType.uri; };
@@ -121,9 +122,10 @@ var AttributesTable = function (_a) {
121
122
  React.createElement(ColumnsSettings, { columnsData: COLUMNS_DATA, selectedColumns: visibleColumns, onChangeColumns: onChangeVisibleColumns })),
122
123
  React.createElement("div", { className: styles.tableContent },
123
124
  isLoading && React.createElement(LinearLoadIndicator, null),
124
- React.createElement(SyncedExpandedAttributesProvider, null,
125
- React.createElement(SyncedValueHeightsProvider, null,
126
- React.createElement(BasicTable, { ref: tableRef, fixFirstColumn: true, headRowHeight: 48, defaultColumnWidth: 250, defaultColumnMinWidth: 200, columnsData: visibleColumnsData, dndRowReorderingEnabled: false, dndRowReorderingHandler: handleReorderAttributeTypes, getIdFromRowValue: getIdFromRowValue, rowsData: rowsData, onScroll: debouncedNotifyLazyRenderer, renderRowCell: renderRowCell, getRowCellHeight: getRowCellHeight, context: tableContext })))),
125
+ React.createElement(AttributeValuesSortContext.Provider, { value: sortByPinIgnorePriority },
126
+ React.createElement(SyncedExpandedAttributesProvider, null,
127
+ React.createElement(SyncedValueHeightsProvider, null,
128
+ React.createElement(BasicTable, { ref: tableRef, fixFirstColumn: true, headRowHeight: 48, defaultColumnWidth: 250, defaultColumnMinWidth: 200, columnsData: visibleColumnsData, dndRowReorderingEnabled: false, dndRowReorderingHandler: handleReorderAttributeTypes, getIdFromRowValue: getIdFromRowValue, rowsData: rowsData, onScroll: debouncedNotifyLazyRenderer, renderRowCell: renderRowCell, getRowCellHeight: getRowCellHeight, context: tableContext }))))),
127
129
  React.createElement(ConfirmDeleteDialog, { open: !!pendingDeletion, onClose: function () { return setPendingDeletion(null); }, onConfirm: handleDelete }),
128
130
  React.createElement(ConfirmEditIgnoredDialog, { open: !!pendingIgnoredEditing, onClose: function () { return setPendingIgnoredEditing(null); }, onConfirmEditWithIgnore: function () { return pendingIgnoredEditing && onEdit(pendingIgnoredEditing); }, onConfirmEditWithoutIgnore: function () {
129
131
  if (pendingIgnoredEditing)
@@ -37,3 +37,10 @@ export declare const selectedAttributeTypes: ({
37
37
  description?: undefined;
38
38
  attributes?: undefined;
39
39
  })[];
40
+ export declare const createEntityWithTextFieldSortOrder: () => Entity;
41
+ export declare const deepNestedDisplayOrderEntities: {
42
+ multipleTopLevelWithSortedChildrenInsidePinned(): Entity;
43
+ };
44
+ export declare const referenceDisplayOrderEntities: {
45
+ multipleTopLevelWithSortedAddressLinesInsidePinned(): Entity;
46
+ };
@@ -287,6 +287,20 @@ export var createMetadata = function () {
287
287
  ]
288
288
  }
289
289
  ],
290
+ relationTypes: [
291
+ {
292
+ uri: 'configuration/relationTypes/HasAddress',
293
+ label: 'Has Address',
294
+ attributes: [
295
+ {
296
+ label: 'Address Line 1',
297
+ name: 'AddressLine1',
298
+ type: 'String',
299
+ uri: 'configuration/relationTypes/HasAddress/attributes/AddressLine1'
300
+ }
301
+ ]
302
+ }
303
+ ],
290
304
  survivorshipStrategies: [
291
305
  {
292
306
  uri: 'configuration/survivorshipStrategies/LUD',
@@ -369,3 +383,71 @@ export var selectedAttributeTypes = [
369
383
  ]
370
384
  }
371
385
  ];
386
+ var withFlags = function (flags) { return (__assign(__assign({}, ((flags === null || flags === void 0 ? void 0 : flags.pin) ? { pin: true } : {})), ((flags === null || flags === void 0 ? void 0 : flags.ignored) ? { ignored: true } : {}))); };
387
+ var createBaseEntityWithAttributes = function (attributes) {
388
+ var base = createEntity();
389
+ return __assign(__assign({}, base), { attributes: __assign(__assign({}, base.attributes), attributes) });
390
+ };
391
+ var textFieldValue = function (suffix, value, flags) { return (__assign({ ov: true, type: 'configuration/entityTypes/HCP/attributes/TextField', uri: "entities/01L2n5z/attributes/TextField/".concat(suffix), value: value }, withFlags(flags))); };
392
+ export var createEntityWithTextFieldSortOrder = function () {
393
+ return createBaseEntityWithAttributes({
394
+ TextField: [
395
+ textFieldValue('sort-middle', 'value-middle'),
396
+ textFieldValue('sort-ignored', 'value-ignored', { ignored: true }),
397
+ textFieldValue('sort-pinned', 'value-pinned', { pin: true })
398
+ ]
399
+ });
400
+ };
401
+ var deepNestedChild = function (parentSuffix, childSuffix, value, flags) { return (__assign({ type: 'configuration/entityTypes/HCP/attributes/DeepNested/attributes/FirstLevelNestedSub1', ov: true, value: value, uri: "entities/01L2n5z/attributes/DeepNested/".concat(parentSuffix, "/FirstLevelNestedSub1/").concat(childSuffix) }, withFlags(flags))); };
402
+ var deepNestedParent = function (label, parentSuffix, children, flags) { return (__assign({ label: label, value: {
403
+ FirstLevelNestedSub1: children
404
+ }, ov: true, uri: "entities/01L2n5z/attributes/DeepNested/".concat(parentSuffix) }, withFlags(flags))); };
405
+ export var deepNestedDisplayOrderEntities = {
406
+ multipleTopLevelWithSortedChildrenInsidePinned: function () {
407
+ return createBaseEntityWithAttributes({
408
+ DeepNested: [
409
+ deepNestedParent('nested-middle', 'nested-middle', [deepNestedChild('nested-middle', 'v1', '1')]),
410
+ deepNestedParent('nested-ignored', 'nested-ignored', [deepNestedChild('nested-ignored', 'v2', '2')], {
411
+ ignored: true
412
+ }),
413
+ deepNestedParent('nested-pinned', 'nested-pinned', [
414
+ deepNestedChild('nested-pinned', 'sort-middle', 'simple-value-middle'),
415
+ deepNestedChild('nested-pinned', 'sort-ignored', 'simple-value-ignored', { ignored: true }),
416
+ deepNestedChild('nested-pinned', 'sort-pinned', 'simple-value-pinned', { pin: true })
417
+ ], { pin: true })
418
+ ]
419
+ });
420
+ }
421
+ };
422
+ var referenceAddress = function (label, parentSuffix, addressLineValues, flags) {
423
+ var parentUri = "entities/2Vek4DnE/attributes/Address/".concat(parentSuffix);
424
+ return __assign({ label: label, refEntity: {
425
+ objectURI: "entities/ref-".concat(parentSuffix),
426
+ type: 'configuration/entityTypes/Location',
427
+ crosswalks: []
428
+ }, refRelation: {
429
+ objectURI: "relations/ref-".concat(parentSuffix),
430
+ type: 'configuration/relationTypes/HasAddress',
431
+ crosswalks: []
432
+ }, uri: parentUri, value: {
433
+ AddressLine1: addressLineValues.map(function (_a) {
434
+ var suffix = _a.suffix, value = _a.value, flags = _a.flags;
435
+ return (__assign({ ov: true, type: 'configuration/entityTypes/Location/attributes/AddressLine1', uri: "".concat(parentUri, "/AddressLine1/").concat(suffix), value: value }, withFlags(flags)));
436
+ })
437
+ }, startObjectCrosswalks: [], ov: true }, withFlags(flags));
438
+ };
439
+ export var referenceDisplayOrderEntities = {
440
+ multipleTopLevelWithSortedAddressLinesInsidePinned: function () {
441
+ return createBaseEntityWithAttributes({
442
+ Address: [
443
+ referenceAddress('ref-middle', 'ref-middle', [{ suffix: 'v1', value: 'a' }]),
444
+ referenceAddress('ref-ignored', 'ref-ignored', [{ suffix: 'v2', value: 'b' }], { ignored: true }),
445
+ referenceAddress('ref-pinned', 'ref-pinned', [
446
+ { suffix: 'sort-middle', value: 'simple-value-middle' },
447
+ { suffix: 'sort-ignored', value: 'simple-value-ignored', flags: { ignored: true } },
448
+ { suffix: 'sort-pinned', value: 'simple-value-pinned', flags: { pin: true } }
449
+ ], { pin: true })
450
+ ]
451
+ });
452
+ }
453
+ };
@@ -62,7 +62,7 @@ import { mockDndKit } from '../../../test-utils/dndKit';
62
62
  import { DndContext } from '@dnd-kit/core';
63
63
  import { getMuiIconByName, getMuiIconsByName, mockBasicTableSizing } from '../../../test-utils';
64
64
  import { MdmModuleProvider } from '../../../contexts/MdmModuleContext';
65
- import { createEntity, createEntityWithAllParticipationStatuses, createMetadata, selectedAttributeTypes } from './AttributesTable.test-data';
65
+ import { createEntity, createEntityWithAllParticipationStatuses, deepNestedDisplayOrderEntities, referenceDisplayOrderEntities, createEntityWithTextFieldSortOrder, createMetadata, selectedAttributeTypes } from './AttributesTable.test-data';
66
66
  import AttributesTable from './AttributesTable';
67
67
  jest.mock('@dnd-kit/core', function () { return mockDndKit; });
68
68
  jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { debounce: function (x) { return x; } })); });
@@ -303,6 +303,127 @@ describe('attribute table tests', function () {
303
303
  expect(within(screen.getAllByTestId('column-name-ruleType')[2]).getByText('Source system')).toBeInTheDocument();
304
304
  unmockTableSizing();
305
305
  });
306
+ it('should display TextField values in pinned, neutral, then ignored order in OV and values columns', function () {
307
+ var unmockTableSizing = mockBasicTableSizing();
308
+ var entity = createEntityWithTextFieldSortOrder();
309
+ var baseCw = crosswalksMap.entity['entities/01L2n5z/attributes/TextField/5noU1aB'];
310
+ var sortCrosswalksMap = {
311
+ entity: __assign(__assign({}, crosswalksMap.entity), { 'entities/01L2n5z/attributes/TextField/sort-middle': baseCw, 'entities/01L2n5z/attributes/TextField/sort-pinned': baseCw, 'entities/01L2n5z/attributes/TextField/sort-ignored': baseCw }),
312
+ relation: {}
313
+ };
314
+ setUp(__assign(__assign({}, defaultProps), { entity: entity, crosswalksMap: sortCrosswalksMap, selectedAttributeTypes: [selectedAttributeTypes[0]], visibleColumns: ['ovValues', 'values'] }));
315
+ var ovCell = getCellByIndexes(0, 0);
316
+ var ovAttributeValueRoots = within(ovCell).getAllByTestId('reltio-attribute-value');
317
+ expect(ovAttributeValueRoots).toHaveLength(3);
318
+ expect(ovAttributeValueRoots[0]).toHaveTextContent('value-pinned');
319
+ expect(ovAttributeValueRoots[1]).toHaveTextContent('value-middle');
320
+ expect(ovAttributeValueRoots[2]).toHaveTextContent('value-ignored');
321
+ var valuesCell = getCellByIndexes(0, 1);
322
+ expect(within(valuesCell).getByTestId('value-index-0')).toHaveTextContent('value-pinned');
323
+ expect(within(valuesCell).getByTestId('value-index-1')).toHaveTextContent('value-middle');
324
+ expect(within(valuesCell).getByTestId('value-index-2')).toHaveTextContent('value-ignored');
325
+ unmockTableSizing();
326
+ });
327
+ it('should display Nested attribute values in pinned, neutral, then ignored order in OV and values columns, and child values in that order within one nested parent', function () { return __awaiter(void 0, void 0, void 0, function () {
328
+ var unmockTableSizing, baseCw, nestedVisibleColumns, valuesColumnIndex, nestedCrosswalksMap, user, ovCell, ovLabels, valuesCell, pinnedNestedBlock, simpleWrapper;
329
+ return __generator(this, function (_a) {
330
+ switch (_a.label) {
331
+ case 0:
332
+ unmockTableSizing = mockBasicTableSizing();
333
+ baseCw = crosswalksMap.entity['entities/01L2n5z/attributes/TextField/5noU1aB'];
334
+ nestedVisibleColumns = ['ovValues', 'values'];
335
+ valuesColumnIndex = 1;
336
+ nestedCrosswalksMap = {
337
+ entity: __assign(__assign({}, crosswalksMap.entity), { 'entities/01L2n5z/attributes/DeepNested/nested-middle': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-ignored': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-middle/FirstLevelNestedSub1/v1': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-ignored/FirstLevelNestedSub1/v2': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned/FirstLevelNestedSub1/sort-middle': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned/FirstLevelNestedSub1/sort-ignored': baseCw, 'entities/01L2n5z/attributes/DeepNested/nested-pinned/FirstLevelNestedSub1/sort-pinned': baseCw }),
338
+ relation: {}
339
+ };
340
+ user = setUp(__assign(__assign({}, defaultProps), { selectedAttributeTypes: [selectedAttributeTypes[2]], visibleColumns: nestedVisibleColumns, entity: deepNestedDisplayOrderEntities.multipleTopLevelWithSortedChildrenInsidePinned(), crosswalksMap: nestedCrosswalksMap })).user;
341
+ ovCell = getCellByIndexes(0, 0);
342
+ ovLabels = within(ovCell).getAllByTestId('reltio-attribute-complex-label');
343
+ expect(ovLabels).toHaveLength(3);
344
+ expect(ovLabels[0]).toHaveTextContent('nested-pinned');
345
+ expect(ovLabels[1]).toHaveTextContent('nested-middle');
346
+ expect(ovLabels[2]).toHaveTextContent('nested-ignored');
347
+ valuesCell = getCellByIndexes(0, valuesColumnIndex);
348
+ expect(within(valuesCell).getByTestId('value-index-0')).toHaveTextContent('nested-pinned');
349
+ expect(within(valuesCell).getByTestId('value-index-1')).toHaveTextContent('nested-middle');
350
+ expect(within(valuesCell).getByTestId('value-index-2')).toHaveTextContent('nested-ignored');
351
+ pinnedNestedBlock = within(valuesCell).getByTestId('value-index-0');
352
+ return [4 /*yield*/, user.click(within(pinnedNestedBlock).getByTestId('arrow-expand-button'))];
353
+ case 1:
354
+ _a.sent();
355
+ simpleWrapper = within(pinnedNestedBlock).getByTestId('simple-attributes-wrapper');
356
+ expect(within(simpleWrapper).getByTestId('value-index-0')).toHaveTextContent('simple-value-pinned');
357
+ expect(within(simpleWrapper).getByTestId('value-index-1')).toHaveTextContent('simple-value-middle');
358
+ expect(within(simpleWrapper).getByTestId('value-index-2')).toHaveTextContent('simple-value-ignored');
359
+ unmockTableSizing();
360
+ return [2 /*return*/];
361
+ }
362
+ });
363
+ }); });
364
+ var relationCw = function (refUri, lineUri) { return [
365
+ {
366
+ uri: "".concat(refUri, "/crosswalks/cw"),
367
+ type: 'configuration/sources/Reltio',
368
+ value: '01L2n5z',
369
+ attributeURIs: [refUri, lineUri]
370
+ }
371
+ ]; };
372
+ var addressAttributeTypeWithRelationLine = __assign(__assign({}, selectedAttributeTypes[3]), { referencedAttributeURIs: [
373
+ 'configuration/entityTypes/Location/attributes/AddressLine1',
374
+ 'configuration/relationTypes/HasAddress/attributes/AddressLine1'
375
+ ] });
376
+ it('should display Reference attribute values in pinned, neutral, then ignored order in OV and values columns, and AddressLine1 values in that order within one reference', function () { return __awaiter(void 0, void 0, void 0, function () {
377
+ var unmockTableSizing, refVisibleColumns, valuesColumnIndex, refMiddle, lineMiddleParent, refIgnored, lineIgnoredParent, refPinned, linePinnedSortMiddle, linePinnedSortIgnored, linePinnedSortPinned, relationMap, user, ovCell, ovLabels, valuesCell, pinnedReferenceBlock, simpleWrapper;
378
+ var _a;
379
+ return __generator(this, function (_b) {
380
+ switch (_b.label) {
381
+ case 0:
382
+ unmockTableSizing = mockBasicTableSizing();
383
+ refVisibleColumns = ['ovValues', 'values'];
384
+ valuesColumnIndex = 1;
385
+ refMiddle = 'entities/2Vek4DnE/attributes/Address/ref-middle';
386
+ lineMiddleParent = "".concat(refMiddle, "/AddressLine1/v1");
387
+ refIgnored = 'entities/2Vek4DnE/attributes/Address/ref-ignored';
388
+ lineIgnoredParent = "".concat(refIgnored, "/AddressLine1/v2");
389
+ refPinned = 'entities/2Vek4DnE/attributes/Address/ref-pinned';
390
+ linePinnedSortMiddle = "".concat(refPinned, "/AddressLine1/sort-middle");
391
+ linePinnedSortIgnored = "".concat(refPinned, "/AddressLine1/sort-ignored");
392
+ linePinnedSortPinned = "".concat(refPinned, "/AddressLine1/sort-pinned");
393
+ relationMap = (_a = {},
394
+ _a[refMiddle] = relationCw(refMiddle, lineMiddleParent),
395
+ _a[lineMiddleParent] = relationCw(refMiddle, lineMiddleParent),
396
+ _a[refIgnored] = relationCw(refIgnored, lineIgnoredParent),
397
+ _a[lineIgnoredParent] = relationCw(refIgnored, lineIgnoredParent),
398
+ _a[refPinned] = relationCw(refPinned, linePinnedSortMiddle),
399
+ _a[linePinnedSortMiddle] = relationCw(refPinned, linePinnedSortMiddle),
400
+ _a[linePinnedSortIgnored] = relationCw(refPinned, linePinnedSortIgnored),
401
+ _a[linePinnedSortPinned] = relationCw(refPinned, linePinnedSortPinned),
402
+ _a);
403
+ user = setUp(__assign(__assign({}, defaultProps), { entity: referenceDisplayOrderEntities.multipleTopLevelWithSortedAddressLinesInsidePinned(), crosswalksMap: __assign(__assign({}, crosswalksMap), { relation: relationMap }), selectedAttributeTypes: [addressAttributeTypeWithRelationLine], visibleColumns: refVisibleColumns })).user;
404
+ ovCell = getCellByIndexes(0, 0);
405
+ ovLabels = within(ovCell).getAllByTestId('reltio-attribute-complex-label');
406
+ expect(ovLabels).toHaveLength(3);
407
+ expect(ovLabels[0]).toHaveTextContent('ref-pinned');
408
+ expect(ovLabels[1]).toHaveTextContent('ref-middle');
409
+ expect(ovLabels[2]).toHaveTextContent('ref-ignored');
410
+ valuesCell = getCellByIndexes(0, valuesColumnIndex);
411
+ expect(within(valuesCell).getByTestId('value-index-0')).toHaveTextContent('ref-pinned');
412
+ expect(within(valuesCell).getByTestId('value-index-1')).toHaveTextContent('ref-middle');
413
+ expect(within(valuesCell).getByTestId('value-index-2')).toHaveTextContent('ref-ignored');
414
+ pinnedReferenceBlock = within(valuesCell).getByTestId('value-index-0');
415
+ return [4 /*yield*/, user.click(within(pinnedReferenceBlock).getByTestId('arrow-expand-button'))];
416
+ case 1:
417
+ _b.sent();
418
+ simpleWrapper = within(pinnedReferenceBlock).getByTestId('simple-attributes-wrapper');
419
+ expect(within(simpleWrapper).getByTestId('value-index-0')).toHaveTextContent('simple-value-pinned');
420
+ expect(within(simpleWrapper).getByTestId('value-index-1')).toHaveTextContent('simple-value-middle');
421
+ expect(within(simpleWrapper).getByTestId('value-index-2')).toHaveTextContent('simple-value-ignored');
422
+ unmockTableSizing();
423
+ return [2 /*return*/];
424
+ }
425
+ });
426
+ }); });
306
427
  it('should render Source sequence after clicking view details button', function () { return __awaiter(void 0, void 0, void 0, function () {
307
428
  var unmockTableSizing, user;
308
429
  return __generator(this, function (_a) {
@@ -704,7 +825,7 @@ describe('attribute table tests', function () {
704
825
  }); });
705
826
  });
706
827
  it('should add attribute to beginning on simple attribute select', function () { return __awaiter(void 0, void 0, void 0, function () {
707
- var onAdd, onSelectAttributeTypes, user, backdrop;
828
+ var onAdd, onSelectAttributeTypes, user, attributePickerPopup, backdrop;
708
829
  return __generator(this, function (_a) {
709
830
  switch (_a.label) {
710
831
  case 0:
@@ -714,14 +835,17 @@ describe('attribute table tests', function () {
714
835
  return [4 /*yield*/, user.click(screen.getByText('Attribute'))];
715
836
  case 1:
716
837
  _a.sent();
717
- expect(screen.queryByText('Image')).not.toBeInTheDocument();
718
- expect(screen.queryByText('Address')).not.toBeInTheDocument();
719
- return [4 /*yield*/, user.click(screen.getByText('String Label 2'))];
838
+ return [4 /*yield*/, screen.findByPlaceholderText(/search/i)];
720
839
  case 2:
840
+ attributePickerPopup = (_a.sent()).closest('.MuiPaper-root');
841
+ expect(within(attributePickerPopup).queryByText('Image')).not.toBeInTheDocument();
842
+ expect(within(attributePickerPopup).queryByText('Address')).not.toBeInTheDocument();
843
+ return [4 /*yield*/, user.click(within(attributePickerPopup).getByText('String Label 2'))];
844
+ case 3:
721
845
  _a.sent();
722
846
  backdrop = screen.getByRole('presentation').children[0];
723
847
  return [4 /*yield*/, user.click(backdrop)];
724
- case 3:
848
+ case 4:
725
849
  _a.sent();
726
850
  expect(onSelectAttributeTypes).toHaveBeenCalledWith(__spreadArray([
727
851
  {
@@ -9,11 +9,14 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
+ import { useContext } from 'react';
12
13
  import { pick } from 'ramda';
13
14
  import { AttributesFactory } from '../AttributesFactory';
14
15
  import { withTableContext } from '../../../../../HOCs/withTableContext';
16
+ import { AttributeValuesSortContext } from '../../../contexts/AttributeValuesSortContext';
15
17
  export var AttributeValuesRenderer = function (_a) {
16
18
  var value = _a.value, onDelete = _a.onDelete, onEdit = _a.onEdit, onPin = _a.onPin, onIgnore = _a.onIgnore, onAdd = _a.onAdd, emptyTempAttributeUris = _a.emptyTempAttributeUris, parentUri = _a.parentUri, readOnly = _a.readOnly;
17
- return AttributesFactory.build(value.attributeType.type, __assign(__assign({}, value), { parentUri: parentUri, onDelete: onDelete, onEdit: onEdit, onPin: onPin, onIgnore: onIgnore, onAdd: onAdd, emptyTempAttributeUris: emptyTempAttributeUris, disableEdit: readOnly, disableDelete: readOnly }));
19
+ var sortAttributeValuesForDisplay = useContext(AttributeValuesSortContext);
20
+ return AttributesFactory.build(value.attributeType.type, __assign(__assign({}, value), { attributeValues: sortAttributeValuesForDisplay(value.attributeValues), parentUri: parentUri, onDelete: onDelete, onEdit: onEdit, onPin: onPin, onIgnore: onIgnore, onAdd: onAdd, emptyTempAttributeUris: emptyTempAttributeUris, disableEdit: readOnly, disableDelete: readOnly }));
18
21
  };
19
22
  export default withTableContext(pick(['onDelete', 'onPin', 'onIgnore', 'onEdit', 'onAdd', 'parentUri', 'readOnly', 'emptyTempAttributeUris']))(AttributeValuesRenderer);
@@ -9,9 +9,10 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
- import React from 'react';
12
+ import React, { useContext } from 'react';
13
13
  import classnames from 'classnames';
14
14
  import DragIndicatorIcon from '@mui/icons-material/DragIndicator';
15
+ import { AttributeValuesSortContext } from '../../../contexts/AttributeValuesSortContext';
15
16
  import { ReadOnlyAttributeValuesBlock } from '../../../../../ReadOnlyAttributeValuesBlock';
16
17
  import { AttributeTitle } from '../../../../../AttributeTitle';
17
18
  import { EntityContext } from '../../../../../contexts/EntityContext';
@@ -25,10 +26,11 @@ export var OvValuesRenderer = function (_a) {
25
26
  var styles = useStyles();
26
27
  var commonStyles = useCommonStyles();
27
28
  var entity = useMdmEntity();
29
+ var sortAttributeValuesForDisplay = useContext(AttributeValuesSortContext);
28
30
  return (React.createElement("div", { className: classnames(styles.root, commonStyles.basicCell) },
29
31
  React.createElement("div", __assign({}, draggableProps, { className: styles.dragIndicator }),
30
32
  React.createElement(DragIndicatorIcon, { className: styles.dragIndicatorIcon })),
31
33
  React.createElement(AttributeTitle, { className: styles.attributeTitle, label: attributeType.label }),
32
34
  !someRowIsDragging && (React.createElement(EntityContext.Provider, { value: entity },
33
- React.createElement(ReadOnlyAttributeValuesBlock, { values: values, attributeType: attributeType, valueContainerClassName: styles.ovValue, AttributeValueWrapper: ValueHeightReporter, FallbackSlot: FallbackIndicator })))));
35
+ React.createElement(ReadOnlyAttributeValuesBlock, { values: sortAttributeValuesForDisplay(values), attributeType: attributeType, valueContainerClassName: styles.ovValue, AttributeValueWrapper: ValueHeightReporter, FallbackSlot: FallbackIndicator })))));
34
36
  };
@@ -1,7 +1,7 @@
1
1
  import { AppliedSurvivorshipRule, AttributeType, AttributeValue, Crosswalk, Metadata, OvDetails, RecordAttributesType } from '@reltio/mdm-sdk';
2
2
  import { CrosswalksMap } from '../../../types';
3
3
  import { CrosswalksByOwnerTypeMap } from '../types';
4
- import { AttributesTableRowValue } from './types';
4
+ import { AttributesTableRowValue, SortAttributeValuesFn } from './types';
5
5
  export declare const COLUMNS_DATA: ({
6
6
  id: string;
7
7
  readonly label: string;
@@ -34,3 +34,4 @@ export declare const getFallbackLabels: (metadata: Metadata, ovDetails: OvDetail
34
34
  export declare const getWinnerCrosswalks: (attributeValues: AttributeValue[], crosswalksMap: CrosswalksMap) => Crosswalk[];
35
35
  export declare const getBasicTableColumnsData: any;
36
36
  export declare const getBasicTableRowsData: (metadata: Metadata, parentTypeUri: string, attrTypes: AttributeType[], columns: string[], crosswalksMap: CrosswalksByOwnerTypeMap, attributes: RecordAttributesType, activeSurvivorshipGroupUri?: string) => AttributesTableRowValue[];
37
+ export declare const sortByPinIgnorePriority: SortAttributeValuesFn;
@@ -294,3 +294,13 @@ export var getBasicTableRowsData = function (metadata, parentTypeUri, attrTypes,
294
294
  }, {}), assoc('rawValue', attrValues))(columns);
295
295
  });
296
296
  };
297
+ var getDisplayTier = function (v) {
298
+ if (v.pin)
299
+ return 0;
300
+ if (v.ignored)
301
+ return 2;
302
+ return 1;
303
+ };
304
+ export var sortByPinIgnorePriority = function (values) {
305
+ return ((values && __spreadArray([], values, true)) || []).sort(function (a, b) { return getDisplayTier(a) - getDisplayTier(b); });
306
+ };
@@ -83,4 +83,5 @@ export type AttributesRendererProps = {
83
83
  onAdd: (event: AddInlineAttributeEvent) => void;
84
84
  emptyTempAttributeUris: string[];
85
85
  };
86
+ export type SortAttributeValuesFn = (values: AttributeValue[]) => AttributeValue[];
86
87
  export {};
@@ -0,0 +1,2 @@
1
+ import { SortAttributeValuesFn } from '../AttributesTable/types';
2
+ export declare const AttributeValuesSortContext: import("react").Context<SortAttributeValuesFn>;
@@ -0,0 +1,3 @@
1
+ import { createContext } from 'react';
2
+ import { identity } from 'ramda';
3
+ export var AttributeValuesSortContext = createContext(identity);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reltio/components",
3
- "version": "1.4.2251-hotfix.0",
3
+ "version": "1.4.2252",
4
4
  "license": "SEE LICENSE IN LICENSE FILE",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./index.js",
@@ -11,7 +11,7 @@
11
11
  "@fluentui/react-context-selector": "^9.1.26",
12
12
  "@googlemaps/markerclusterer": "^2.5.3",
13
13
  "@react-sigma/core": "3.4.0",
14
- "@reltio/mdm-sdk": "^1.4.2036-hotfix.0",
14
+ "@reltio/mdm-sdk": "^1.4.2036",
15
15
  "@vis.gl/react-google-maps": "^1.3.0",
16
16
  "d3-cloud": "^1.2.5",
17
17
  "d3-geo": "^2.0.1",