@reltio/components 1.4.2276 → 1.4.2277
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/MatchRulesBlock/MatchRulesBlock.d.ts +3 -2
- package/MatchRulesBlock/MatchRulesBlock.js +15 -1
- package/MatchRulesBlock/MatchRulesBlock.test.js +25 -0
- package/cjs/MatchRulesBlock/MatchRulesBlock.d.ts +3 -2
- package/cjs/MatchRulesBlock/MatchRulesBlock.js +15 -1
- package/cjs/MatchRulesBlock/MatchRulesBlock.test.js +25 -0
- package/cjs/hooks/useMatchesLoader/types.d.ts +4 -0
- package/cjs/hooks/useMatchesLoader/types.js +2 -0
- package/cjs/hooks/useMatchesLoader/useMatchesLoader.d.ts +3 -2
- package/cjs/hooks/useMatchesLoader/useMatchesLoader.js +52 -5
- package/cjs/hooks/useMatchesLoader/useMatchesLoader.test.js +44 -1
- package/hooks/useMatchesLoader/types.d.ts +4 -0
- package/hooks/useMatchesLoader/types.js +1 -0
- package/hooks/useMatchesLoader/useMatchesLoader.d.ts +3 -2
- package/hooks/useMatchesLoader/useMatchesLoader.js +53 -6
- package/hooks/useMatchesLoader/useMatchesLoader.test.js +45 -2
- package/package.json +2 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Entity, Metadata,
|
|
2
|
+
import { Entity, Metadata, EntitiesMap } from '@reltio/mdm-sdk';
|
|
3
3
|
import { MatchRuleVariant } from '../types';
|
|
4
|
+
import type { MatchWithRuleLabels } from '../hooks/useMatchesLoader/types';
|
|
4
5
|
type Props = {
|
|
5
6
|
entitiesMap: EntitiesMap;
|
|
6
7
|
entity: Entity;
|
|
7
|
-
match:
|
|
8
|
+
match: MatchWithRuleLabels;
|
|
8
9
|
metadata: Metadata;
|
|
9
10
|
variant?: MatchRuleVariant;
|
|
10
11
|
};
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
1
12
|
import React from 'react';
|
|
2
13
|
import { getMatchRules, getTransitiveMatchRules, isTransitiveMatch, NOT_MATCH } from '@reltio/mdm-sdk';
|
|
3
14
|
import { SimpleMatchRulesBlock } from '../SimpleMatchRulesBlock';
|
|
@@ -11,7 +22,10 @@ export var MatchRulesBlock = function (_a) {
|
|
|
11
22
|
return null;
|
|
12
23
|
}
|
|
13
24
|
var isTransitive = isTransitiveMatch(match);
|
|
14
|
-
var matchRules = getMatchRules(metadata, entity.type, (match.matchRules || []).concat(match.negativeRules || []))
|
|
25
|
+
var matchRules = getMatchRules(metadata, entity.type, (match.matchRules || []).concat(match.negativeRules || [])).map(function (matchRule) {
|
|
26
|
+
var _a;
|
|
27
|
+
return (__assign(__assign({}, matchRule), { label: ((_a = match.matchRuleLabels) === null || _a === void 0 ? void 0 : _a[matchRule.uri]) || matchRule.label }));
|
|
28
|
+
});
|
|
15
29
|
var rules = matchRules.filter(function (_a) {
|
|
16
30
|
var uri = _a.uri;
|
|
17
31
|
return uri !== NOT_MATCH;
|
|
@@ -163,6 +163,31 @@ describe('MatchRulesBlock test', function () {
|
|
|
163
163
|
matchRules: [metadata.entityTypes[0].matchGroups[2]]
|
|
164
164
|
}));
|
|
165
165
|
});
|
|
166
|
+
it('should use data tenant match rule labels for rules that are not in customer tenant metadata', function () {
|
|
167
|
+
var _a;
|
|
168
|
+
var dataTenantMatchRuleUri = 'configuration/entityTypes/HCP/matchGroups/DataTenantRule';
|
|
169
|
+
var match = {
|
|
170
|
+
matchRules: [dataTenantMatchRuleUri],
|
|
171
|
+
matchRuleLabels: (_a = {},
|
|
172
|
+
_a[dataTenantMatchRuleUri] = 'Data Tenant Match Rule',
|
|
173
|
+
_a),
|
|
174
|
+
object: {
|
|
175
|
+
uri: 'entities/dataTenantEntity',
|
|
176
|
+
type: 'configuration/entityTypes/HCP',
|
|
177
|
+
dataTenant: 'dt1'
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
render(React.createElement(MatchRulesBlock, { match: match, metadata: metadata, entity: entity, entitiesMap: {} }));
|
|
181
|
+
expect(mockTransitiveMatchRules).not.toHaveBeenCalled();
|
|
182
|
+
expect(mockSimpleMatchRulesBuilder).toHaveBeenCalledWith(expect.objectContaining({
|
|
183
|
+
matchRules: [
|
|
184
|
+
{
|
|
185
|
+
uri: dataTenantMatchRuleUri,
|
|
186
|
+
label: 'Data Tenant Match Rule'
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}));
|
|
190
|
+
});
|
|
166
191
|
it('should render SimpleMatchRulesBuilder for non transitive match and work correctly with negativeRules', function () {
|
|
167
192
|
render(React.createElement(MatchRulesBlock, { match: potentialMatches[4], metadata: metadata, entity: entity, entitiesMap: {} }));
|
|
168
193
|
expect(mockTransitiveMatchRules).not.toHaveBeenCalled();
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Entity, Metadata,
|
|
2
|
+
import { Entity, Metadata, EntitiesMap } from '@reltio/mdm-sdk';
|
|
3
3
|
import { MatchRuleVariant } from '../types';
|
|
4
|
+
import type { MatchWithRuleLabels } from '../hooks/useMatchesLoader/types';
|
|
4
5
|
type Props = {
|
|
5
6
|
entitiesMap: EntitiesMap;
|
|
6
7
|
entity: Entity;
|
|
7
|
-
match:
|
|
8
|
+
match: MatchWithRuleLabels;
|
|
8
9
|
metadata: Metadata;
|
|
9
10
|
variant?: MatchRuleVariant;
|
|
10
11
|
};
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
15
|
};
|
|
@@ -17,7 +28,10 @@ var MatchRulesBlock = function (_a) {
|
|
|
17
28
|
return null;
|
|
18
29
|
}
|
|
19
30
|
var isTransitive = (0, mdm_sdk_1.isTransitiveMatch)(match);
|
|
20
|
-
var matchRules = (0, mdm_sdk_1.getMatchRules)(metadata, entity.type, (match.matchRules || []).concat(match.negativeRules || []))
|
|
31
|
+
var matchRules = (0, mdm_sdk_1.getMatchRules)(metadata, entity.type, (match.matchRules || []).concat(match.negativeRules || [])).map(function (matchRule) {
|
|
32
|
+
var _a;
|
|
33
|
+
return (__assign(__assign({}, matchRule), { label: ((_a = match.matchRuleLabels) === null || _a === void 0 ? void 0 : _a[matchRule.uri]) || matchRule.label }));
|
|
34
|
+
});
|
|
21
35
|
var rules = matchRules.filter(function (_a) {
|
|
22
36
|
var uri = _a.uri;
|
|
23
37
|
return uri !== mdm_sdk_1.NOT_MATCH;
|
|
@@ -168,6 +168,31 @@ describe('MatchRulesBlock test', function () {
|
|
|
168
168
|
matchRules: [metadata.entityTypes[0].matchGroups[2]]
|
|
169
169
|
}));
|
|
170
170
|
});
|
|
171
|
+
it('should use data tenant match rule labels for rules that are not in customer tenant metadata', function () {
|
|
172
|
+
var _a;
|
|
173
|
+
var dataTenantMatchRuleUri = 'configuration/entityTypes/HCP/matchGroups/DataTenantRule';
|
|
174
|
+
var match = {
|
|
175
|
+
matchRules: [dataTenantMatchRuleUri],
|
|
176
|
+
matchRuleLabels: (_a = {},
|
|
177
|
+
_a[dataTenantMatchRuleUri] = 'Data Tenant Match Rule',
|
|
178
|
+
_a),
|
|
179
|
+
object: {
|
|
180
|
+
uri: 'entities/dataTenantEntity',
|
|
181
|
+
type: 'configuration/entityTypes/HCP',
|
|
182
|
+
dataTenant: 'dt1'
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
(0, react_2.render)(react_1.default.createElement(MatchRulesBlock_1.MatchRulesBlock, { match: match, metadata: metadata, entity: entity, entitiesMap: {} }));
|
|
186
|
+
expect(mockTransitiveMatchRules).not.toHaveBeenCalled();
|
|
187
|
+
expect(mockSimpleMatchRulesBuilder).toHaveBeenCalledWith(expect.objectContaining({
|
|
188
|
+
matchRules: [
|
|
189
|
+
{
|
|
190
|
+
uri: dataTenantMatchRuleUri,
|
|
191
|
+
label: 'Data Tenant Match Rule'
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
}));
|
|
195
|
+
});
|
|
171
196
|
it('should render SimpleMatchRulesBuilder for non transitive match and work correctly with negativeRules', function () {
|
|
172
197
|
(0, react_2.render)(react_1.default.createElement(MatchRulesBlock_1.MatchRulesBlock, { match: potentialMatches[4], metadata: metadata, entity: entity, entitiesMap: {} }));
|
|
173
198
|
expect(mockTransitiveMatchRules).not.toHaveBeenCalled();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Entity,
|
|
1
|
+
import { Entity, SortingField, EntitiesMap } from '@reltio/mdm-sdk';
|
|
2
|
+
import type { MatchWithRuleLabels } from './types';
|
|
2
3
|
type Props = {
|
|
3
4
|
enabled: boolean;
|
|
4
5
|
entity: Entity;
|
|
@@ -17,7 +18,7 @@ type Props = {
|
|
|
17
18
|
};
|
|
18
19
|
export declare const useMatchesLoader: ({ enabled, entity, filter, rules, onFinishLoading, onStartLoading, options, page, rowsPerPage, sorting, markMatchedValues }: Props) => {
|
|
19
20
|
total: number;
|
|
20
|
-
matches:
|
|
21
|
+
matches: MatchWithRuleLabels[];
|
|
21
22
|
entitiesMap: EntitiesMap<Pick<Entity, "label" | "type" | "uri">>;
|
|
22
23
|
loadMatches: () => void;
|
|
23
24
|
};
|
|
@@ -17,18 +17,48 @@ var mdm_sdk_1 = require("@reltio/mdm-sdk");
|
|
|
17
17
|
var usePagingSimulator_1 = require("../usePagingSimulator");
|
|
18
18
|
var useSafePromise_1 = require("../useSafePromise");
|
|
19
19
|
var MdmModuleContext_1 = require("../../contexts/MdmModuleContext");
|
|
20
|
+
var matchRuleLabelsCache = new Map();
|
|
21
|
+
// Match rule labels are static per (dtssPath, customerTenant), so the request is
|
|
22
|
+
// cached and reused across reloads (paging, filtering, sorting) instead of being
|
|
23
|
+
// refetched every time matches are loaded. Failed requests are evicted so a later
|
|
24
|
+
// load can retry.
|
|
25
|
+
var getCachedDataTenantMatchRuleLabels = function (dtssPath, customerTenant) {
|
|
26
|
+
var cacheKey = "".concat(dtssPath, "::").concat(customerTenant);
|
|
27
|
+
var cachedRequest = matchRuleLabelsCache.get(cacheKey);
|
|
28
|
+
if (cachedRequest !== undefined) {
|
|
29
|
+
return cachedRequest;
|
|
30
|
+
}
|
|
31
|
+
var request = (0, mdm_sdk_1.getDataTenantMatchGroups)({ dtssPath: dtssPath, customerTenant: customerTenant }).catch(function () {
|
|
32
|
+
matchRuleLabelsCache.delete(cacheKey);
|
|
33
|
+
return {};
|
|
34
|
+
});
|
|
35
|
+
matchRuleLabelsCache.set(cacheKey, request);
|
|
36
|
+
return request;
|
|
37
|
+
};
|
|
38
|
+
var addDataTenantMatchRuleLabels = function (matches, entity, matchRuleLabels) {
|
|
39
|
+
if (!Object.keys(matchRuleLabels).length) {
|
|
40
|
+
return matches;
|
|
41
|
+
}
|
|
42
|
+
return matches.map(function (match) {
|
|
43
|
+
var _a;
|
|
44
|
+
return ((0, mdm_sdk_1.isDataTenantEntity)(entity) || (0, mdm_sdk_1.isDataTenantEntity)(match.object)) &&
|
|
45
|
+
((_a = match.matchRules) === null || _a === void 0 ? void 0 : _a.some(function (matchRuleUri) { return matchRuleLabels[matchRuleUri]; }))
|
|
46
|
+
? __assign(__assign({}, match), { matchRuleLabels: matchRuleLabels }) : match;
|
|
47
|
+
});
|
|
48
|
+
};
|
|
20
49
|
var useMatchesLoader = function (_a) {
|
|
21
50
|
var enabled = _a.enabled, entity = _a.entity, filter = _a.filter, rules = _a.rules, onFinishLoading = _a.onFinishLoading, onStartLoading = _a.onStartLoading, options = _a.options, page = _a.page, rowsPerPage = _a.rowsPerPage, sorting = _a.sorting, markMatchedValues = _a.markMatchedValues;
|
|
22
51
|
var _b = sorting || {}, order = _b.order, field = _b.field;
|
|
23
52
|
var _c = (0, react_1.useState)(0), total = _c[0], setTotal = _c[1];
|
|
24
53
|
var _d = (0, react_1.useState)([]), matches = _d[0], setMatches = _d[1];
|
|
25
|
-
var _e = (0, react_1.useState)({}),
|
|
54
|
+
var _e = (0, react_1.useState)({}), matchRuleLabels = _e[0], setMatchRuleLabels = _e[1];
|
|
55
|
+
var _f = (0, react_1.useState)({}), entitiesMap = _f[0], setEntitiesMap = _f[1];
|
|
26
56
|
var metadata = (0, MdmModuleContext_1.useMdmMetadata)();
|
|
27
57
|
var tenant = (0, MdmModuleContext_1.useMdmTenant)();
|
|
28
58
|
var dtssPath = (0, MdmModuleContext_1.useMdmDtssPath)();
|
|
29
59
|
var dataTenants = (0, MdmModuleContext_1.useMdmDataTenantsWithIdBuilder)();
|
|
30
60
|
var showMasking = (0, MdmModuleContext_1.useMdmShowMasking)();
|
|
31
|
-
var
|
|
61
|
+
var _g = (0, MdmModuleContext_1.useMdmGlobalSearchRequestOptions)() || {}, activityFilter = _g.activityFilter, globalFilter = _g.globalFilter;
|
|
32
62
|
var activeness = typeof options.showInactiveEntities === 'boolean'
|
|
33
63
|
? options.showInactiveEntities
|
|
34
64
|
? mdm_sdk_1.ActivityFilter.ALL
|
|
@@ -51,6 +81,7 @@ var useMatchesLoader = function (_a) {
|
|
|
51
81
|
var getTransitiveMatchesWithPaging = (0, usePagingSimulator_1.usePagingSimulator)(getTransitiveMatchesWithDtss);
|
|
52
82
|
var getPagedMatchesForDataTenantEntity = (0, usePagingSimulator_1.usePagingSimulator)(mdm_sdk_1.getMatchesForDataTenantEntity);
|
|
53
83
|
var safePromise = (0, useSafePromise_1.useSafePromise)();
|
|
84
|
+
var safeMatchRuleLabelsPromise = (0, useSafePromise_1.useSafePromise)();
|
|
54
85
|
var getMatches = (0, react_1.useCallback)(function (force) {
|
|
55
86
|
if (force === void 0) { force = false; }
|
|
56
87
|
if (!enabled || (0, mdm_sdk_1.isTempUri)(entityUri)) {
|
|
@@ -60,7 +91,7 @@ var useMatchesLoader = function (_a) {
|
|
|
60
91
|
return;
|
|
61
92
|
}
|
|
62
93
|
onStartLoading === null || onStartLoading === void 0 ? void 0 : onStartLoading();
|
|
63
|
-
|
|
94
|
+
var matchesRequest = (0, mdm_sdk_1.isDataTenantEntity)(entity)
|
|
64
95
|
? getPagedMatchesForDataTenantEntity({
|
|
65
96
|
dtssPath: dtssPath,
|
|
66
97
|
entity: entity,
|
|
@@ -80,7 +111,8 @@ var useMatchesLoader = function (_a) {
|
|
|
80
111
|
markMatchedValues: markMatchedValues,
|
|
81
112
|
deep: options.showTransitiveMatches ? undefined : 1,
|
|
82
113
|
activeness: activeness
|
|
83
|
-
}, showMasking)), { offset: page * rowsPerPage, force: force }))
|
|
114
|
+
}, showMasking)), { offset: page * rowsPerPage, force: force }));
|
|
115
|
+
safePromise(matchesRequest)
|
|
84
116
|
.then(function (result) {
|
|
85
117
|
var response = result.response, total = result.total, originalResponse = result.originalResponse;
|
|
86
118
|
setTotal(total);
|
|
@@ -126,12 +158,27 @@ var useMatchesLoader = function (_a) {
|
|
|
126
158
|
(0, react_1.useEffect)(function () {
|
|
127
159
|
getMatches();
|
|
128
160
|
}, [getMatches]);
|
|
161
|
+
// Match rule labels are loaded independently of the matches request so the
|
|
162
|
+
// matches list renders without waiting for them; they are applied as a
|
|
163
|
+
// derived layer once available. Keyed on a stable boolean rather than the
|
|
164
|
+
// dataTenants array reference to avoid re-firing on every render.
|
|
165
|
+
var hasDataTenants = !!(dataTenants === null || dataTenants === void 0 ? void 0 : dataTenants.length);
|
|
166
|
+
(0, react_1.useEffect)(function () {
|
|
167
|
+
if (!dtssPath || !tenant || !hasDataTenants) {
|
|
168
|
+
setMatchRuleLabels({});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
safeMatchRuleLabelsPromise(getCachedDataTenantMatchRuleLabels(dtssPath, tenant))
|
|
172
|
+
.then(setMatchRuleLabels)
|
|
173
|
+
.catch(function () { return setMatchRuleLabels({}); });
|
|
174
|
+
}, [dtssPath, tenant, hasDataTenants, safeMatchRuleLabelsPromise]);
|
|
175
|
+
var matchesWithRuleLabels = (0, react_1.useMemo)(function () { return addDataTenantMatchRuleLabels(matches, entity, matchRuleLabels); }, [matches, entity, matchRuleLabels]);
|
|
129
176
|
var loadMatches = (0, react_1.useCallback)(function () {
|
|
130
177
|
getMatches(true);
|
|
131
178
|
}, [getMatches]);
|
|
132
179
|
return {
|
|
133
180
|
total: total,
|
|
134
|
-
matches:
|
|
181
|
+
matches: matchesWithRuleLabels,
|
|
135
182
|
entitiesMap: entitiesMap,
|
|
136
183
|
loadMatches: loadMatches
|
|
137
184
|
};
|
|
@@ -55,7 +55,7 @@ var mdm_sdk_1 = require("@reltio/mdm-sdk");
|
|
|
55
55
|
var react_2 = require("@testing-library/react");
|
|
56
56
|
var MdmModuleContext_1 = require("../../contexts/MdmModuleContext");
|
|
57
57
|
var useMatchesLoader_1 = require("./useMatchesLoader");
|
|
58
|
-
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { getTransitiveMatches: jest.fn(), getMatchesForDataTenantEntity: jest.fn(), isDataTenantEntity: jest.fn().mockImplementation(function (entity) { return !!entity.dataTenant; }) })); });
|
|
58
|
+
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { getTransitiveMatches: jest.fn(), getMatchesForDataTenantEntity: jest.fn(), getDataTenantMatchGroups: jest.fn(), isDataTenantEntity: jest.fn().mockImplementation(function (entity) { return !!entity.dataTenant; }) })); });
|
|
59
59
|
/**
|
|
60
60
|
* useMatchesLoader runs a useEffect that calls getMatches() on mount. getMatches() is async:
|
|
61
61
|
* it calls the SDK (getTransitiveMatches / getMatchesForDataTenantEntity), and when the
|
|
@@ -192,4 +192,47 @@ describe('Test useMatchesLoader hook', function () {
|
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
194
|
}); });
|
|
195
|
+
it('should add data tenant match rule labels to DTSS matches', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
196
|
+
var matchRuleUri, result;
|
|
197
|
+
var _a;
|
|
198
|
+
return __generator(this, function (_b) {
|
|
199
|
+
switch (_b.label) {
|
|
200
|
+
case 0:
|
|
201
|
+
matchRuleUri = 'configuration/entityTypes/HCP/matchGroups/DataTenantRule';
|
|
202
|
+
mdm_sdk_1.getMatchesForDataTenantEntity.mockResolvedValueOnce([
|
|
203
|
+
{
|
|
204
|
+
object: {
|
|
205
|
+
uri: 'entities/customerTenantMatch',
|
|
206
|
+
type: 'configuration/entityTypes/HCP'
|
|
207
|
+
},
|
|
208
|
+
matchRules: [matchRuleUri]
|
|
209
|
+
}
|
|
210
|
+
]);
|
|
211
|
+
mdm_sdk_1.getDataTenantMatchGroups.mockResolvedValueOnce((_a = {},
|
|
212
|
+
_a[matchRuleUri] = 'Data Tenant Match Rule',
|
|
213
|
+
_a));
|
|
214
|
+
result = setUp({
|
|
215
|
+
props: __assign(__assign({}, defaultProps), { entity: __assign(__assign({}, defaultProps.entity), { dataTenant: 'tenantId4' }) }),
|
|
216
|
+
mdmValues: __assign(__assign({}, defaultMdmValues), { dtssPath: 'dtssPath/', tenant: { id: 'customerTenant', name: 'customerTenant' } })
|
|
217
|
+
}).result;
|
|
218
|
+
return [4 /*yield*/, (0, react_2.waitFor)(function () {
|
|
219
|
+
var _a;
|
|
220
|
+
expect(result.current.matches).toEqual([
|
|
221
|
+
expect.objectContaining({
|
|
222
|
+
matchRuleLabels: (_a = {},
|
|
223
|
+
_a[matchRuleUri] = 'Data Tenant Match Rule',
|
|
224
|
+
_a)
|
|
225
|
+
})
|
|
226
|
+
]);
|
|
227
|
+
})];
|
|
228
|
+
case 1:
|
|
229
|
+
_b.sent();
|
|
230
|
+
expect(mdm_sdk_1.getDataTenantMatchGroups).toHaveBeenCalledWith({
|
|
231
|
+
dtssPath: 'dtssPath/',
|
|
232
|
+
customerTenant: 'customerTenant'
|
|
233
|
+
});
|
|
234
|
+
return [2 /*return*/];
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}); });
|
|
195
238
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Entity,
|
|
1
|
+
import { Entity, SortingField, EntitiesMap } from '@reltio/mdm-sdk';
|
|
2
|
+
import type { MatchWithRuleLabels } from './types';
|
|
2
3
|
type Props = {
|
|
3
4
|
enabled: boolean;
|
|
4
5
|
entity: Entity;
|
|
@@ -17,7 +18,7 @@ type Props = {
|
|
|
17
18
|
};
|
|
18
19
|
export declare const useMatchesLoader: ({ enabled, entity, filter, rules, onFinishLoading, onStartLoading, options, page, rowsPerPage, sorting, markMatchedValues }: Props) => {
|
|
19
20
|
total: number;
|
|
20
|
-
matches:
|
|
21
|
+
matches: MatchWithRuleLabels[];
|
|
21
22
|
entitiesMap: EntitiesMap<Pick<Entity, "label" | "type" | "uri">>;
|
|
22
23
|
loadMatches: () => void;
|
|
23
24
|
};
|
|
@@ -10,22 +10,52 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
12
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
13
|
-
import { ActivityFilter, collectAllTransitiveEntitiesUris, getEntitiesMapForTransitiveMatches, getMatchesForDataTenantEntity, getMatchesFromDataTenants, getTransitiveMatches, isDataTenantEntity, isTempUri, withDtssPotentialItems, addGlobalFilterToQuery, addGetTransitiveMatchesMaskingOptions } from '@reltio/mdm-sdk';
|
|
13
|
+
import { ActivityFilter, collectAllTransitiveEntitiesUris, getEntitiesMapForTransitiveMatches, getDataTenantMatchGroups, getMatchesForDataTenantEntity, getMatchesFromDataTenants, getTransitiveMatches, isDataTenantEntity, isTempUri, withDtssPotentialItems, addGlobalFilterToQuery, addGetTransitiveMatchesMaskingOptions } from '@reltio/mdm-sdk';
|
|
14
14
|
import { usePagingSimulator } from '../usePagingSimulator';
|
|
15
15
|
import { useSafePromise } from '../useSafePromise';
|
|
16
16
|
import { useMdmDataTenantsWithIdBuilder, useMdmDtssPath, useMdmGlobalSearchRequestOptions, useMdmMetadata, useMdmTenant, useMdmShowMasking } from '../../contexts/MdmModuleContext';
|
|
17
|
+
var matchRuleLabelsCache = new Map();
|
|
18
|
+
// Match rule labels are static per (dtssPath, customerTenant), so the request is
|
|
19
|
+
// cached and reused across reloads (paging, filtering, sorting) instead of being
|
|
20
|
+
// refetched every time matches are loaded. Failed requests are evicted so a later
|
|
21
|
+
// load can retry.
|
|
22
|
+
var getCachedDataTenantMatchRuleLabels = function (dtssPath, customerTenant) {
|
|
23
|
+
var cacheKey = "".concat(dtssPath, "::").concat(customerTenant);
|
|
24
|
+
var cachedRequest = matchRuleLabelsCache.get(cacheKey);
|
|
25
|
+
if (cachedRequest !== undefined) {
|
|
26
|
+
return cachedRequest;
|
|
27
|
+
}
|
|
28
|
+
var request = getDataTenantMatchGroups({ dtssPath: dtssPath, customerTenant: customerTenant }).catch(function () {
|
|
29
|
+
matchRuleLabelsCache.delete(cacheKey);
|
|
30
|
+
return {};
|
|
31
|
+
});
|
|
32
|
+
matchRuleLabelsCache.set(cacheKey, request);
|
|
33
|
+
return request;
|
|
34
|
+
};
|
|
35
|
+
var addDataTenantMatchRuleLabels = function (matches, entity, matchRuleLabels) {
|
|
36
|
+
if (!Object.keys(matchRuleLabels).length) {
|
|
37
|
+
return matches;
|
|
38
|
+
}
|
|
39
|
+
return matches.map(function (match) {
|
|
40
|
+
var _a;
|
|
41
|
+
return (isDataTenantEntity(entity) || isDataTenantEntity(match.object)) &&
|
|
42
|
+
((_a = match.matchRules) === null || _a === void 0 ? void 0 : _a.some(function (matchRuleUri) { return matchRuleLabels[matchRuleUri]; }))
|
|
43
|
+
? __assign(__assign({}, match), { matchRuleLabels: matchRuleLabels }) : match;
|
|
44
|
+
});
|
|
45
|
+
};
|
|
17
46
|
export var useMatchesLoader = function (_a) {
|
|
18
47
|
var enabled = _a.enabled, entity = _a.entity, filter = _a.filter, rules = _a.rules, onFinishLoading = _a.onFinishLoading, onStartLoading = _a.onStartLoading, options = _a.options, page = _a.page, rowsPerPage = _a.rowsPerPage, sorting = _a.sorting, markMatchedValues = _a.markMatchedValues;
|
|
19
48
|
var _b = sorting || {}, order = _b.order, field = _b.field;
|
|
20
49
|
var _c = useState(0), total = _c[0], setTotal = _c[1];
|
|
21
50
|
var _d = useState([]), matches = _d[0], setMatches = _d[1];
|
|
22
|
-
var _e = useState({}),
|
|
51
|
+
var _e = useState({}), matchRuleLabels = _e[0], setMatchRuleLabels = _e[1];
|
|
52
|
+
var _f = useState({}), entitiesMap = _f[0], setEntitiesMap = _f[1];
|
|
23
53
|
var metadata = useMdmMetadata();
|
|
24
54
|
var tenant = useMdmTenant();
|
|
25
55
|
var dtssPath = useMdmDtssPath();
|
|
26
56
|
var dataTenants = useMdmDataTenantsWithIdBuilder();
|
|
27
57
|
var showMasking = useMdmShowMasking();
|
|
28
|
-
var
|
|
58
|
+
var _g = useMdmGlobalSearchRequestOptions() || {}, activityFilter = _g.activityFilter, globalFilter = _g.globalFilter;
|
|
29
59
|
var activeness = typeof options.showInactiveEntities === 'boolean'
|
|
30
60
|
? options.showInactiveEntities
|
|
31
61
|
? ActivityFilter.ALL
|
|
@@ -48,6 +78,7 @@ export var useMatchesLoader = function (_a) {
|
|
|
48
78
|
var getTransitiveMatchesWithPaging = usePagingSimulator(getTransitiveMatchesWithDtss);
|
|
49
79
|
var getPagedMatchesForDataTenantEntity = usePagingSimulator(getMatchesForDataTenantEntity);
|
|
50
80
|
var safePromise = useSafePromise();
|
|
81
|
+
var safeMatchRuleLabelsPromise = useSafePromise();
|
|
51
82
|
var getMatches = useCallback(function (force) {
|
|
52
83
|
if (force === void 0) { force = false; }
|
|
53
84
|
if (!enabled || isTempUri(entityUri)) {
|
|
@@ -57,7 +88,7 @@ export var useMatchesLoader = function (_a) {
|
|
|
57
88
|
return;
|
|
58
89
|
}
|
|
59
90
|
onStartLoading === null || onStartLoading === void 0 ? void 0 : onStartLoading();
|
|
60
|
-
|
|
91
|
+
var matchesRequest = isDataTenantEntity(entity)
|
|
61
92
|
? getPagedMatchesForDataTenantEntity({
|
|
62
93
|
dtssPath: dtssPath,
|
|
63
94
|
entity: entity,
|
|
@@ -77,7 +108,8 @@ export var useMatchesLoader = function (_a) {
|
|
|
77
108
|
markMatchedValues: markMatchedValues,
|
|
78
109
|
deep: options.showTransitiveMatches ? undefined : 1,
|
|
79
110
|
activeness: activeness
|
|
80
|
-
}, showMasking)), { offset: page * rowsPerPage, force: force }))
|
|
111
|
+
}, showMasking)), { offset: page * rowsPerPage, force: force }));
|
|
112
|
+
safePromise(matchesRequest)
|
|
81
113
|
.then(function (result) {
|
|
82
114
|
var response = result.response, total = result.total, originalResponse = result.originalResponse;
|
|
83
115
|
setTotal(total);
|
|
@@ -123,12 +155,27 @@ export var useMatchesLoader = function (_a) {
|
|
|
123
155
|
useEffect(function () {
|
|
124
156
|
getMatches();
|
|
125
157
|
}, [getMatches]);
|
|
158
|
+
// Match rule labels are loaded independently of the matches request so the
|
|
159
|
+
// matches list renders without waiting for them; they are applied as a
|
|
160
|
+
// derived layer once available. Keyed on a stable boolean rather than the
|
|
161
|
+
// dataTenants array reference to avoid re-firing on every render.
|
|
162
|
+
var hasDataTenants = !!(dataTenants === null || dataTenants === void 0 ? void 0 : dataTenants.length);
|
|
163
|
+
useEffect(function () {
|
|
164
|
+
if (!dtssPath || !tenant || !hasDataTenants) {
|
|
165
|
+
setMatchRuleLabels({});
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
safeMatchRuleLabelsPromise(getCachedDataTenantMatchRuleLabels(dtssPath, tenant))
|
|
169
|
+
.then(setMatchRuleLabels)
|
|
170
|
+
.catch(function () { return setMatchRuleLabels({}); });
|
|
171
|
+
}, [dtssPath, tenant, hasDataTenants, safeMatchRuleLabelsPromise]);
|
|
172
|
+
var matchesWithRuleLabels = useMemo(function () { return addDataTenantMatchRuleLabels(matches, entity, matchRuleLabels); }, [matches, entity, matchRuleLabels]);
|
|
126
173
|
var loadMatches = useCallback(function () {
|
|
127
174
|
getMatches(true);
|
|
128
175
|
}, [getMatches]);
|
|
129
176
|
return {
|
|
130
177
|
total: total,
|
|
131
|
-
matches:
|
|
178
|
+
matches: matchesWithRuleLabels,
|
|
132
179
|
entitiesMap: entitiesMap,
|
|
133
180
|
loadMatches: loadMatches
|
|
134
181
|
};
|
|
@@ -46,11 +46,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
import React from 'react';
|
|
49
|
-
import { getTransitiveMatches, getMatchesForDataTenantEntity } from '@reltio/mdm-sdk';
|
|
49
|
+
import { getTransitiveMatches, getMatchesForDataTenantEntity, getDataTenantMatchGroups } from '@reltio/mdm-sdk';
|
|
50
50
|
import { renderHook, waitFor } from '@testing-library/react';
|
|
51
51
|
import { MdmModuleProvider } from '../../contexts/MdmModuleContext';
|
|
52
52
|
import { useMatchesLoader } from './useMatchesLoader';
|
|
53
|
-
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { getTransitiveMatches: jest.fn(), getMatchesForDataTenantEntity: jest.fn(), isDataTenantEntity: jest.fn().mockImplementation(function (entity) { return !!entity.dataTenant; }) })); });
|
|
53
|
+
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { getTransitiveMatches: jest.fn(), getMatchesForDataTenantEntity: jest.fn(), getDataTenantMatchGroups: jest.fn(), isDataTenantEntity: jest.fn().mockImplementation(function (entity) { return !!entity.dataTenant; }) })); });
|
|
54
54
|
/**
|
|
55
55
|
* useMatchesLoader runs a useEffect that calls getMatches() on mount. getMatches() is async:
|
|
56
56
|
* it calls the SDK (getTransitiveMatches / getMatchesForDataTenantEntity), and when the
|
|
@@ -187,4 +187,47 @@ describe('Test useMatchesLoader hook', function () {
|
|
|
187
187
|
}
|
|
188
188
|
});
|
|
189
189
|
}); });
|
|
190
|
+
it('should add data tenant match rule labels to DTSS matches', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
191
|
+
var matchRuleUri, result;
|
|
192
|
+
var _a;
|
|
193
|
+
return __generator(this, function (_b) {
|
|
194
|
+
switch (_b.label) {
|
|
195
|
+
case 0:
|
|
196
|
+
matchRuleUri = 'configuration/entityTypes/HCP/matchGroups/DataTenantRule';
|
|
197
|
+
getMatchesForDataTenantEntity.mockResolvedValueOnce([
|
|
198
|
+
{
|
|
199
|
+
object: {
|
|
200
|
+
uri: 'entities/customerTenantMatch',
|
|
201
|
+
type: 'configuration/entityTypes/HCP'
|
|
202
|
+
},
|
|
203
|
+
matchRules: [matchRuleUri]
|
|
204
|
+
}
|
|
205
|
+
]);
|
|
206
|
+
getDataTenantMatchGroups.mockResolvedValueOnce((_a = {},
|
|
207
|
+
_a[matchRuleUri] = 'Data Tenant Match Rule',
|
|
208
|
+
_a));
|
|
209
|
+
result = setUp({
|
|
210
|
+
props: __assign(__assign({}, defaultProps), { entity: __assign(__assign({}, defaultProps.entity), { dataTenant: 'tenantId4' }) }),
|
|
211
|
+
mdmValues: __assign(__assign({}, defaultMdmValues), { dtssPath: 'dtssPath/', tenant: { id: 'customerTenant', name: 'customerTenant' } })
|
|
212
|
+
}).result;
|
|
213
|
+
return [4 /*yield*/, waitFor(function () {
|
|
214
|
+
var _a;
|
|
215
|
+
expect(result.current.matches).toEqual([
|
|
216
|
+
expect.objectContaining({
|
|
217
|
+
matchRuleLabels: (_a = {},
|
|
218
|
+
_a[matchRuleUri] = 'Data Tenant Match Rule',
|
|
219
|
+
_a)
|
|
220
|
+
})
|
|
221
|
+
]);
|
|
222
|
+
})];
|
|
223
|
+
case 1:
|
|
224
|
+
_b.sent();
|
|
225
|
+
expect(getDataTenantMatchGroups).toHaveBeenCalledWith({
|
|
226
|
+
dtssPath: 'dtssPath/',
|
|
227
|
+
customerTenant: 'customerTenant'
|
|
228
|
+
});
|
|
229
|
+
return [2 /*return*/];
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}); });
|
|
190
233
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reltio/components",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2277",
|
|
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.
|
|
14
|
+
"@reltio/mdm-sdk": "^1.4.2053",
|
|
15
15
|
"@vis.gl/react-google-maps": "^1.3.0",
|
|
16
16
|
"d3-cloud": "^1.2.5",
|
|
17
17
|
"d3-geo": "^2.0.1",
|