@reltio/components 1.4.2206 → 1.4.2208

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/cjs/contexts/WorkflowTasksContext/index.d.ts +1 -0
  2. package/cjs/features/workflow/ChangeRequestEditor/ChangeRequestEditor.js +1 -2
  3. package/cjs/features/workflow/ChangeRequestEditor/components/ChangeItemEditor/ChangeItemEditor.js +3 -4
  4. package/cjs/features/workflow/ChangeRequestEditor/components/ChangeItemRow/ChangeItemRow.js +4 -4
  5. package/cjs/features/workflow/ChangeRequestEditor/components/DCRValueEditor/DCRValueEditor.d.ts +1 -1
  6. package/cjs/features/workflow/ChangeRequestEditor/components/DCRValueEditorFactory/DCRValueEditorFactory.d.ts +1 -1
  7. package/cjs/features/workflow/ChangeRequestEditor/hooks/useChangeRequestEditor.d.ts +2 -1
  8. package/cjs/features/workflow/ChangeRequestEditor/hooks/useChangeRequestEditor.js +14 -8
  9. package/cjs/features/workflow/ReviewDCRDialog/ReviewDCRDialog.js +10 -7
  10. package/cjs/features/workflow/TaskActionButtons/TaskActionButtons.js +6 -4
  11. package/cjs/features/workflow/WorkflowTaskCard/components/DataChangeRequestTaskCard/DataChangeRequestTaskCard.js +12 -3
  12. package/cjs/features/workflow/WorkflowTaskCard/components/GenericWorkflowTaskCard/GenericWorkflowTaskCard.js +6 -4
  13. package/cjs/features/workflow/{ChangeRequestEditor/context → contexts/ChangeRequestEditorContext}/index.d.ts +1 -0
  14. package/cjs/features/workflow/{ChangeRequestEditor/context → contexts/ChangeRequestEditorContext}/index.js +12 -0
  15. package/cjs/features/workflow/helpers/attributes.js +2 -2
  16. package/cjs/features/workflow/helpers/attributes.test.js +9 -6
  17. package/cjs/features/workflow/helpers/dcr.d.ts +8 -1
  18. package/cjs/features/workflow/helpers/dcr.js +186 -1
  19. package/cjs/features/workflow/helpers/merge.js +2 -1
  20. package/cjs/features/workflow/hooks/useApplyDcrChanges.d.ts +3 -0
  21. package/cjs/features/workflow/hooks/useApplyDcrChanges.js +145 -0
  22. package/cjs/features/workflow/hooks/useWorkflowActions.d.ts +7 -2
  23. package/cjs/features/workflow/hooks/useWorkflowActions.js +31 -8
  24. package/cjs/features/workflow/types.d.ts +4 -0
  25. package/contexts/WorkflowTasksContext/index.d.ts +1 -0
  26. package/features/workflow/ChangeRequestEditor/ChangeRequestEditor.js +1 -2
  27. package/features/workflow/ChangeRequestEditor/components/ChangeItemEditor/ChangeItemEditor.js +3 -4
  28. package/features/workflow/ChangeRequestEditor/components/ChangeItemRow/ChangeItemRow.js +1 -1
  29. package/features/workflow/ChangeRequestEditor/components/DCRValueEditor/DCRValueEditor.d.ts +1 -1
  30. package/features/workflow/ChangeRequestEditor/components/DCRValueEditorFactory/DCRValueEditorFactory.d.ts +1 -1
  31. package/features/workflow/ChangeRequestEditor/hooks/useChangeRequestEditor.d.ts +2 -1
  32. package/features/workflow/ChangeRequestEditor/hooks/useChangeRequestEditor.js +8 -2
  33. package/features/workflow/ReviewDCRDialog/ReviewDCRDialog.js +10 -7
  34. package/features/workflow/TaskActionButtons/TaskActionButtons.js +6 -4
  35. package/features/workflow/WorkflowTaskCard/components/DataChangeRequestTaskCard/DataChangeRequestTaskCard.js +14 -5
  36. package/features/workflow/WorkflowTaskCard/components/GenericWorkflowTaskCard/GenericWorkflowTaskCard.js +6 -4
  37. package/features/workflow/{ChangeRequestEditor/context → contexts/ChangeRequestEditorContext}/index.d.ts +1 -0
  38. package/features/workflow/{ChangeRequestEditor/context → contexts/ChangeRequestEditorContext}/index.js +13 -1
  39. package/features/workflow/helpers/attributes.js +2 -2
  40. package/features/workflow/helpers/attributes.test.js +9 -6
  41. package/features/workflow/helpers/dcr.d.ts +8 -1
  42. package/features/workflow/helpers/dcr.js +186 -2
  43. package/features/workflow/helpers/merge.js +2 -1
  44. package/features/workflow/hooks/useApplyDcrChanges.d.ts +3 -0
  45. package/features/workflow/hooks/useApplyDcrChanges.js +141 -0
  46. package/features/workflow/hooks/useWorkflowActions.d.ts +7 -2
  47. package/features/workflow/hooks/useWorkflowActions.js +31 -8
  48. package/features/workflow/types.d.ts +4 -0
  49. package/package.json +2 -2
@@ -9,7 +9,6 @@ import i18n from 'ui-i18n';
9
9
  import { useWorkflowCheckPermission } from '../hooks/useWorkflowCheckPermission';
10
10
  import { useWorkflowActions } from '../hooks/useWorkflowActions';
11
11
  import { useMdmEntity } from '../../../contexts/MdmModuleContext';
12
- import { ChangeRequestEditorProvider } from '../ChangeRequestEditor/context';
13
12
  import { ProfileBand } from '../../../ProfileBand';
14
13
  import { DueDateField } from '../DueDateField';
15
14
  import { PrioritySelector } from '../PrioritySelector';
@@ -18,17 +17,22 @@ import { WorkflowComments } from '../WorkflowComments';
18
17
  import { WorkflowActionButtons } from '../WorkflowActionButtons';
19
18
  import { DCRSummaryInfo } from './components/DCRSummaryInfo/DCRSummaryInfo';
20
19
  import { ChangeRequestEditor } from '../ChangeRequestEditor';
20
+ import { useApplyDcrChanges } from '../hooks/useApplyDcrChanges';
21
21
  import styles from './ReviewDCRDialog.module.css';
22
22
  export var ReviewDCRDialog = function (_a) {
23
23
  var open = _a.open, onClose = _a.onClose, dcr = _a.dcr, task = _a.task, groupedObjects = _a.groupedObjects;
24
24
  var entity = useMdmEntity();
25
25
  var checkWorkflowPermission = useWorkflowCheckPermission();
26
26
  var canViewComments = checkWorkflowPermission('VIEW_PROCESS_INSTANCE_COMMENTS');
27
+ var applyDcrChanges = useApplyDcrChanges(dcr);
27
28
  var _b = useWorkflowActions({
28
- taskId: task.taskId,
29
- possibleActions: task.possibleActions,
30
- assignee: task.assignee,
31
- isOpen: task.isOpen
29
+ task: {
30
+ taskId: task.taskId,
31
+ possibleActions: task.possibleActions,
32
+ assignee: task.assignee,
33
+ isOpen: task.isOpen
34
+ },
35
+ beforeAction: applyDcrChanges
32
36
  }), workflowActions = _b.actions, actionRequestIsInProgress = _b.actionRequestIsInProgress;
33
37
  return (React.createElement(Dialog, { open: open, onClose: onClose, fullScreen: true },
34
38
  React.createElement(DialogTitle, { className: styles.dialogTitle },
@@ -49,8 +53,7 @@ export var ReviewDCRDialog = function (_a) {
49
53
  React.createElement("div", { className: styles.editableItem },
50
54
  React.createElement(AssigneeSelector, { taskId: task.taskId, assignee: task.assignee, isTaskOpen: task.isOpen })))),
51
55
  React.createElement("div", { className: styles.changesSection },
52
- React.createElement(ChangeRequestEditorProvider, null,
53
- React.createElement(ChangeRequestEditor, { dcr: dcr, task: task, groupedObjects: groupedObjects })))),
56
+ React.createElement(ChangeRequestEditor, { dcr: dcr, task: task, groupedObjects: groupedObjects }))),
54
57
  canViewComments && (React.createElement(WorkflowComments, { workflowActions: workflowActions, actionRequestIsInProgress: actionRequestIsInProgress, preferredAction: task.preferredAction, taskId: task.taskId, processInstanceComments: task.processInstanceComments, isTaskOpen: task.isOpen, showActionButtons: false, alwaysExpanded: true, classes: {
55
58
  container: styles.commentsRootContainer,
56
59
  commentsContainer: styles.commentsContainer
@@ -6,10 +6,12 @@ export var TaskActionButtons = function (_a) {
6
6
  var task = _a.task;
7
7
  var taskId = task.taskId, possibleActions = task.possibleActions, assignee = task.assignee, isOpen = task.isOpen, preferredAction = task.preferredAction;
8
8
  var _b = useWorkflowActions({
9
- taskId: taskId,
10
- possibleActions: possibleActions,
11
- assignee: assignee,
12
- isOpen: isOpen
9
+ task: {
10
+ taskId: taskId,
11
+ possibleActions: possibleActions,
12
+ assignee: assignee,
13
+ isOpen: isOpen
14
+ }
13
15
  }), actions = _b.actions, disabled = _b.actionRequestIsInProgress;
14
16
  var _c = partition(propEq('text', preferredAction === null || preferredAction === void 0 ? void 0 : preferredAction.label), actions), preferredActions = _c[0], otherActions = _c[1];
15
17
  return (React.createElement(React.Fragment, null,
@@ -1,6 +1,8 @@
1
- import React, { useCallback, useMemo, useState } from 'react';
1
+ import React, { useCallback, useContext, useMemo, useState } from 'react';
2
+ import { isNil } from 'ramda';
3
+ import { isDCRUri } from '@reltio/mdm-sdk';
2
4
  import DcrTaskIcon from '../../../../../icons/DcrTaskIcon';
3
- import { useMdmReviewDCREnabled, useMdmUsername } from '../../../../../contexts/MdmModuleContext';
5
+ import { useMdmEntity, useMdmReviewDCREnabled, useMdmUsername } from '../../../../../contexts/MdmModuleContext';
4
6
  import { GenericWorkflowTaskCard } from '../GenericWorkflowTaskCard';
5
7
  import { AttributesChanges } from '../../../AttributesChanges';
6
8
  import { LineDecorator } from '../../../LineDecorator';
@@ -8,9 +10,15 @@ import { useChangeRequest } from '../../../hooks/useChangeRequest';
8
10
  import { getDCRUri } from '../../../helpers/common';
9
11
  import { ReviewDCRDialog } from '../../../ReviewDCRDialog';
10
12
  import { ReviewDCRButton } from '../../../ReviewDCRButton';
13
+ import { ChangeRequestEditorProvider } from '../../../contexts/ChangeRequestEditorContext';
14
+ import { WorkflowTasksContext } from '../../../../../contexts/WorkflowTasksContext';
11
15
  export var DataChangeRequestTaskCard = function (_a) {
12
16
  var task = _a.task;
17
+ var reviewDCREnabledByEntityType = (useContext(WorkflowTasksContext) || {}).reviewDCR;
13
18
  var reviewDCREnabled = useMdmReviewDCREnabled();
19
+ var entity = useMdmEntity();
20
+ var isDCREntity = isDCRUri(entity === null || entity === void 0 ? void 0 : entity.uri);
21
+ var isReviewDCREnabled = isNil(reviewDCREnabledByEntityType) ? reviewDCREnabled : reviewDCREnabledByEntityType;
14
22
  var username = useMdmUsername();
15
23
  var _b = useState(false), isReviewDCRDialogOpen = _b[0], setIsReviewDCRDialogOpen = _b[1];
16
24
  var objectURIs = task.objectURIs, assignee = task.assignee;
@@ -22,12 +30,13 @@ export var DataChangeRequestTaskCard = function (_a) {
22
30
  var handleCloseReviewDCRDialog = useCallback(function () {
23
31
  setIsReviewDCRDialogOpen(false);
24
32
  }, []);
25
- var showReviewDCRButton = reviewDCREnabled && assignee == username;
26
- var showReviewDialog = isReviewDCRDialogOpen && (showReviewDCRButton || reviewDCREnabled);
33
+ var showReviewDCRButton = !isDCREntity && isReviewDCREnabled && assignee == username;
34
+ var showReviewDialog = !isDCREntity && isReviewDCRDialogOpen && (showReviewDCRButton || isReviewDCREnabled);
27
35
  var customActionsSlot = useMemo(function () { return showReviewDCRButton && React.createElement(ReviewDCRButton, { onClick: handleReviewDCR }); }, [showReviewDCRButton, handleReviewDCR]);
28
36
  return (React.createElement(React.Fragment, null,
29
37
  React.createElement(GenericWorkflowTaskCard, { task: task, Icon: DcrTaskIcon, customActionsSlot: customActionsSlot }, dcr &&
30
38
  groupedObjects.map(function (object, index) { return (React.createElement(LineDecorator, { key: index, last: index === groupedObjects.length - 1, divider: true },
31
39
  React.createElement(AttributesChanges, { entityInfo: object.entity, relationsInfo: object.relations, changes: dcr.changes, objectsInfo: dcr.objectsInfo, dcrUri: dcrUri }))); })),
32
- showReviewDialog && (React.createElement(ReviewDCRDialog, { open: isReviewDCRDialogOpen, onClose: handleCloseReviewDCRDialog, dcr: dcr, groupedObjects: groupedObjects, task: task }))));
40
+ showReviewDialog && (React.createElement(ChangeRequestEditorProvider, null,
41
+ React.createElement(ReviewDCRDialog, { open: isReviewDCRDialogOpen, onClose: handleCloseReviewDCRDialog, dcr: dcr, groupedObjects: groupedObjects, task: task })))));
33
42
  };
@@ -26,10 +26,12 @@ export var GenericWorkflowTaskCard = function (_a) {
26
26
  var checkWorkflowPermission = useWorkflowCheckPermission();
27
27
  var canViewComments = checkWorkflowPermission('VIEW_PROCESS_INSTANCE_COMMENTS');
28
28
  var _d = useWorkflowActions({
29
- taskId: taskId,
30
- possibleActions: possibleActions,
31
- assignee: assignee,
32
- isOpen: isTaskOpen
29
+ task: {
30
+ taskId: taskId,
31
+ possibleActions: possibleActions,
32
+ assignee: assignee,
33
+ isOpen: isTaskOpen
34
+ }
33
35
  }), workflowActions = _d.actions, actionRequestIsInProgress = _d.actionRequestIsInProgress;
34
36
  return (React.createElement("div", { className: styles.card },
35
37
  React.createElement("div", { className: classnames((_b = {}, _b[styles.withBackground] = isExpanded, _b)) },
@@ -10,6 +10,7 @@ export type LineData = {
10
10
  type ChangeRequestEditorContextType = {
11
11
  updateChange: (lineIds: string[], data: LineDataValue) => void;
12
12
  getLineData: (lineId: string) => LineData | undefined;
13
+ getLinesByChangeId: (changeId: string) => Array<[string, LineData]>;
13
14
  rejectChange: (lineIds: string[]) => void;
14
15
  revertChangeUpdateOrReject: (lineIds: string[]) => void;
15
16
  getIsParentLineRejected: (lineId: string) => boolean;
@@ -1,9 +1,10 @@
1
- import React, { useCallback, useState } from 'react';
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { isNil } from 'ramda';
3
3
  import { createContext } from '@fluentui/react-context-selector';
4
4
  export var ChangeRequestEditorContext = createContext({
5
5
  updateChange: undefined,
6
6
  getLineData: undefined,
7
+ getLinesByChangeId: undefined,
7
8
  rejectChange: undefined,
8
9
  revertChangeUpdateOrReject: undefined,
9
10
  getIsParentLineRejected: undefined,
@@ -13,6 +14,7 @@ export var ChangeRequestEditorContext = createContext({
13
14
  export var ChangeRequestEditorProvider = function (_a) {
14
15
  var children = _a.children;
15
16
  var _b = useState(new Map()), lineDataMap = _b[0], setLineDataMap = _b[1];
17
+ var lineDataMapRef = useRef(lineDataMap);
16
18
  var updateChange = useCallback(function (lineIds, data) {
17
19
  setLineDataMap(function (prevMap) {
18
20
  var newMap = new Map(prevMap);
@@ -62,9 +64,19 @@ export var ChangeRequestEditorProvider = function (_a) {
62
64
  var _a;
63
65
  return !isNil((_a = lineDataMap.get(lineId)) === null || _a === void 0 ? void 0 : _a.value);
64
66
  }, [lineDataMap]);
67
+ var getLinesByChangeId = useCallback(function (changeId) {
68
+ return Array.from(lineDataMapRef.current).filter(function (_a) {
69
+ var key = _a[0], _value = _a[1];
70
+ return key.split('/')[1] === changeId;
71
+ });
72
+ }, []);
73
+ useEffect(function () {
74
+ lineDataMapRef.current = lineDataMap;
75
+ }, [lineDataMap]);
65
76
  var contextValue = {
66
77
  updateChange: updateChange,
67
78
  getLineData: getLineData,
79
+ getLinesByChangeId: getLinesByChangeId,
68
80
  rejectChange: rejectChange,
69
81
  revertChangeUpdateOrReject: revertChangeUpdateOrReject,
70
82
  getIsParentLineRejected: getIsParentLineRejected,
@@ -113,7 +113,7 @@ export var getEntityChanges = curry(function (metadata, entityInfo, changes) {
113
113
  var attrTypes = getFilteredAttrTypes(metadata, entityInfo.type, [], []);
114
114
  return getAttributesList(metadata, attrTypes, changes);
115
115
  });
116
- export var getRelationChanges = curry(function (metadata, relationInfo, changes, changeType) {
116
+ export var getRelationChanges = curry(function (metadata, relationInfo, changes, changeType, relationChangeLineIds) {
117
117
  var addRelationOperationIfNeeded = function (changes, changeType) {
118
118
  if (changeType === DCRTypes.CREATE_RELATIONSHIP || isEmptyValue(changes)) {
119
119
  var operation = getOperationType(changeType);
@@ -124,7 +124,7 @@ export var getRelationChanges = curry(function (metadata, relationInfo, changes,
124
124
  var relationType = getRelationType(metadata, relationInfo.type);
125
125
  var attrTypes = getRelationAttributesList(metadata, relationInfo.type);
126
126
  return flatten([
127
- __assign({ level: 1, label: propOr('', 'label', relationType), attributeType: null, relationType: relationType, attributeValue: __assign(__assign({}, relationInfo), changes), lineIds: changes === null || changes === void 0 ? void 0 : changes.lineIds }, addRelationOperationIfNeeded(changes, changeType)),
127
+ __assign({ level: 1, label: propOr('', 'label', relationType), attributeType: null, relationType: relationType, attributeValue: __assign(__assign({}, relationInfo), changes), lineIds: (changes === null || changes === void 0 ? void 0 : changes.lineIds) || relationChangeLineIds }, addRelationOperationIfNeeded(changes, changeType)),
128
128
  getAttributesList(metadata, attrTypes, changes, 2)
129
129
  ]);
130
130
  });
@@ -139,13 +139,14 @@ describe('attributes helpers tests', function () {
139
139
  ]
140
140
  };
141
141
  it('should not show operation for relation title', function () {
142
- expect(getRelationChanges(metadata, relationInfo, changes, DCRTypes.INSERT_ATTRIBUTE)).toEqual([
142
+ expect(getRelationChanges(metadata, relationInfo, changes, DCRTypes.INSERT_ATTRIBUTE, ['lineIds'])).toEqual([
143
143
  {
144
144
  attributeType: null,
145
145
  relationType: metadata.relationTypes[1],
146
146
  attributeValue: __assign(__assign({}, relationInfo), changes),
147
147
  label: metadata.relationTypes[1].label,
148
- level: 1
148
+ level: 1,
149
+ lineIds: ['lineIds']
149
150
  },
150
151
  {
151
152
  attributeType: EntityAttrTypes.startDate,
@@ -166,14 +167,15 @@ describe('attributes helpers tests', function () {
166
167
  ]);
167
168
  });
168
169
  it('should show operation for relation title if it is new', function () {
169
- expect(getRelationChanges(metadata, relationInfo, changes, DCRTypes.CREATE_RELATIONSHIP)).toEqual([
170
+ expect(getRelationChanges(metadata, relationInfo, changes, DCRTypes.CREATE_RELATIONSHIP, ['lineIds'])).toEqual([
170
171
  {
171
172
  attributeType: null,
172
173
  relationType: metadata.relationTypes[1],
173
174
  attributeValue: __assign(__assign({}, relationInfo), changes),
174
175
  label: metadata.relationTypes[1].label,
175
176
  level: 1,
176
- operation: DCROperationTypes.ADDED
177
+ operation: DCROperationTypes.ADDED,
178
+ lineIds: ['lineIds']
177
179
  },
178
180
  {
179
181
  attributeType: EntityAttrTypes.startDate,
@@ -194,14 +196,15 @@ describe('attributes helpers tests', function () {
194
196
  ]);
195
197
  });
196
198
  it('should show operation for relation title if it was deleted and changes are empty', function () {
197
- expect(getRelationChanges(metadata, relationInfo, {}, DCRTypes.DELETE_RELATIONSHIP)).toEqual([
199
+ expect(getRelationChanges(metadata, relationInfo, {}, DCRTypes.DELETE_RELATIONSHIP, ['lineIds'])).toEqual([
198
200
  {
199
201
  attributeType: null,
200
202
  relationType: metadata.relationTypes[1],
201
203
  attributeValue: relationInfo,
202
204
  label: metadata.relationTypes[1].label,
203
205
  level: 1,
204
- operation: DCROperationTypes.DELETED
206
+ operation: DCROperationTypes.DELETED,
207
+ lineIds: ['lineIds']
205
208
  }
206
209
  ]);
207
210
  });
@@ -1,4 +1,5 @@
1
- import { ChangeRequest, DCRChanges, DCRObjectInfo, DCRObjectsInfo, GroupedObjectsInfo } from '@reltio/mdm-sdk';
1
+ import { AttributeDelete, ChangeRequest, DCRChange, DCRChanges, DCRObjectInfo, DCRObjectsInfo, GroupedObjectsInfo, Metadata } from '@reltio/mdm-sdk';
2
+ import { LineData } from '../contexts/ChangeRequestEditorContext';
2
3
  export declare const getEntitiesObjects: any;
3
4
  export declare const getRelationsObjects: any;
4
5
  export declare const extractObjectsFromChangeRequest: (changes: DCRChanges, objectsInfo: DCRObjectsInfo) => DCRObjectInfo[];
@@ -7,3 +8,9 @@ export declare const createEntityRelationsObjectByRelation: any;
7
8
  export declare const concatEntityRelationsObjects: (acc: Record<string, GroupedObjectsInfo>, object: GroupedObjectsInfo) => Record<string, GroupedObjectsInfo>;
8
9
  export declare const getEntityUriForChangeRequest: (dcrUri: string, entityUri: string) => string;
9
10
  export declare const isCreateEntityOperation: (dcr: ChangeRequest) => boolean;
11
+ export declare const buildDCRSavePlan: (changes: DCRChanges, getLinesByChangeId: (changeId: string) => Array<[string, LineData]>, metadata: Metadata) => {
12
+ rejectedChangeIds: string[];
13
+ updatedChanges: Record<string, DCRChange[]>;
14
+ deleteEntityAttributes: Record<string, AttributeDelete[]>;
15
+ deleteRelationAttributes: Record<string, AttributeDelete[]>;
16
+ };
@@ -9,8 +9,17 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
- import { DCRTypes, isEntityUri, isRelationUri } from '@reltio/mdm-sdk';
13
- import { allPass, concat, curry, equals, filter, keys, map, pathOr, pipe, prop, uniq } from 'ramda';
12
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
13
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
14
+ if (ar || !(i in from)) {
15
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
16
+ ar[i] = from[i];
17
+ }
18
+ }
19
+ return to.concat(ar || Array.prototype.slice.call(from));
20
+ };
21
+ import { createEntryDeleteAttribute, DCRTypes, findAttributeTypeByUri, isEntityUri, isNested, isRelationTypeUri, isRelationUri } from '@reltio/mdm-sdk';
22
+ import { allPass, append, assocPath, concat, curry, dissocPath, equals, filter, flatten, fromPairs, groupBy, has, hasPath, isEmpty, isNil, keys, map, partition, path, pathOr, pipe, pluck, prop, propOr, toPairs, values, uniq, uniqBy, when } from 'ramda';
14
23
  export var getEntitiesObjects = filter(pipe(prop('uri'), isEntityUri));
15
24
  export var getRelationsObjects = filter(pipe(prop('uri'), isRelationUri));
16
25
  var getRelations = function (objectsWithChanges, entityUri) {
@@ -47,3 +56,178 @@ export var getEntityUriForChangeRequest = function (dcrUri, entityUri) {
47
56
  export var isCreateEntityOperation = function (dcr) {
48
57
  return dcr.type === DCRTypes.CREATE_ENTITY;
49
58
  };
59
+ var cleanValueRecursively = function (value) {
60
+ if (typeof value === 'string' || isEmpty(value)) {
61
+ return value;
62
+ }
63
+ var cleanedProperties = map(function (propertyValues) {
64
+ return propertyValues
65
+ .map(function (item) {
66
+ var itemValue = item.value;
67
+ var cleanedItemValue = itemValue && typeof itemValue === 'object' ? cleanValueRecursively(itemValue) : itemValue;
68
+ return __assign(__assign({}, item), { value: cleanedItemValue });
69
+ })
70
+ .filter(function (item) {
71
+ var itemValue = item.value;
72
+ return !isEmpty(itemValue) && !isNil(itemValue);
73
+ });
74
+ }, value);
75
+ return filter(function (propertyValues) { return !isEmpty(propertyValues); }, cleanedProperties);
76
+ };
77
+ var cleanChange = function (change) {
78
+ var _a, _b, _c;
79
+ if (Array.isArray(change.newValue)) {
80
+ return change;
81
+ }
82
+ if (isRelationTypeUri(change.objectType)) {
83
+ if (change.type === DCRTypes.INSERT_ATTRIBUTE || change.type === DCRTypes.UPDATE_ATTRIBUTE) {
84
+ var cleanedValues = cleanValueRecursively((_a = change.newValue) === null || _a === void 0 ? void 0 : _a.value);
85
+ return assocPath(['newValue', 'value'], cleanedValues, change);
86
+ }
87
+ var cleanedAttributes = cleanValueRecursively((_b = change.newValue) === null || _b === void 0 ? void 0 : _b.attributes);
88
+ var changeWithCleanedAttributes = assocPath(['newValue', 'attributes'], cleanedAttributes, change);
89
+ if (change.type === DCRTypes.CREATE_RELATIONSHIP) {
90
+ var cleanByPath = function (valuePath) {
91
+ return when(allPass([hasPath(valuePath), pipe(path(valuePath), isNil)]), dissocPath(valuePath));
92
+ };
93
+ return pipe(cleanByPath(['newValue', 'startDate']), cleanByPath(['newValue', 'endDate']))(changeWithCleanedAttributes);
94
+ }
95
+ return changeWithCleanedAttributes;
96
+ }
97
+ if (typeof change.newValue === 'object') {
98
+ var cleanedValue = cleanValueRecursively((_c = change.newValue) === null || _c === void 0 ? void 0 : _c.value);
99
+ return assocPath(['newValue', 'value'], cleanedValue, change);
100
+ }
101
+ return change;
102
+ };
103
+ var calculateValuePath = function (key, change) {
104
+ var path = key
105
+ .split('/')
106
+ .slice(2)
107
+ .map(function (part) { return (isNaN(Number(part)) ? part : parseInt(part)); });
108
+ switch (change.type) {
109
+ case DCRTypes.UPDATE_TAGS:
110
+ case DCRTypes.UPDATE_ROLES:
111
+ return path;
112
+ case DCRTypes.UPDATE_START_DATE:
113
+ case DCRTypes.UPDATE_END_DATE:
114
+ return __spreadArray(__spreadArray([], path, true), [0], false);
115
+ case DCRTypes.CREATE_RELATIONSHIP:
116
+ if (path.length === 2) {
117
+ if (path[1] === 'activeness.startDate') {
118
+ return [path[0], 'startDate'];
119
+ }
120
+ if (path[1] === 'activeness.endDate') {
121
+ return [path[0], 'endDate'];
122
+ }
123
+ }
124
+ return __spreadArray(__spreadArray([], path, true), ['value'], false);
125
+ default:
126
+ return __spreadArray(__spreadArray([], path, true), ['value'], false);
127
+ }
128
+ };
129
+ var valuesAreEqual = function (oldValue, newValue) {
130
+ var sortWithLocale = function (array) { return array.slice().sort(function (a, b) { return a.localeCompare(b); }); };
131
+ if (Array.isArray(oldValue) && Array.isArray(newValue)) {
132
+ return oldValue.length === newValue.length && equals(sortWithLocale(oldValue), sortWithLocale(newValue));
133
+ }
134
+ if (typeof oldValue === 'string' && typeof newValue === 'number') {
135
+ return oldValue === newValue.toString();
136
+ }
137
+ return oldValue === newValue;
138
+ };
139
+ var getOldValueByNewValuePath = function (valuePath, change) {
140
+ if (valuePath.includes('newValue')) {
141
+ return pathOr(null, valuePath.map(function (item) { return (item === 'newValue' ? 'oldValue' : item); }), change);
142
+ }
143
+ return null;
144
+ };
145
+ export var buildDCRSavePlan = function (changes, getLinesByChangeId, metadata) {
146
+ var _a, _b;
147
+ var rejectedChangeIds = [];
148
+ var updatedChanges = {};
149
+ var deleteAttributes = {};
150
+ for (var _i = 0, _c = Object.entries(changes); _i < _c.length; _i++) {
151
+ var _d = _c[_i], objectUri = _d[0], objectChanges = _d[1];
152
+ var rawChanges = new Map();
153
+ var _loop_1 = function (change) {
154
+ var _h = pipe(prop('id'), getLinesByChangeId, partition(function (_a) {
155
+ var _b;
156
+ var key = _a[0], lineData = _a[1];
157
+ return key.split('/').length === 3 &&
158
+ (lineData.isRejected ||
159
+ (isEmpty((_b = lineData.value) === null || _b === void 0 ? void 0 : _b.value) && change.type !== DCRTypes.UPDATE_ATTRIBUTE));
160
+ }))(change), rejectedRootLines = _h[0], otherLines = _h[1];
161
+ rejectedChangeIds.push.apply(rejectedChangeIds, rejectedRootLines.map(function (_a) {
162
+ var key = _a[0];
163
+ return key.split('/')[1];
164
+ }));
165
+ var rejectedRootLinesMap = new Map(rejectedRootLines);
166
+ for (var _j = 0, otherLines_1 = otherLines; _j < otherLines_1.length; _j++) {
167
+ var _k = otherLines_1[_j], key = _k[0], lineData = _k[1];
168
+ var rootId = key.split('/').slice(0, 3).join('/');
169
+ var newValue = (_a = lineData.value) === null || _a === void 0 ? void 0 : _a.value;
170
+ if (rootId === key && change.type === DCRTypes.UPDATE_ATTRIBUTE && isEmpty(newValue)) {
171
+ var attributeUri = [objectUri, 'attributes', change.attributePath].join('/');
172
+ var entry = __assign(__assign({}, createEntryDeleteAttribute({ uri: attributeUri })[0]), (change.crosswalk && { crosswalk: change.crosswalk }));
173
+ deleteAttributes[objectUri] = uniqBy(prop('uri'), append(entry, propOr([], objectUri, deleteAttributes)));
174
+ rejectedChangeIds.push(change.id);
175
+ }
176
+ else if (!rejectedRootLinesMap.has(rootId)) {
177
+ var valuePath = calculateValuePath(key, change);
178
+ var oldDCRValue = path(valuePath, change);
179
+ var oldValue = getOldValueByNewValuePath(valuePath, change);
180
+ var initialChange = rawChanges.has(change.id) ? rawChanges.get(change.id) : change;
181
+ var updatedChange = void 0;
182
+ if (lineData.isRejected || isEmpty(newValue)) {
183
+ updatedChange = assocPath(valuePath, null, initialChange);
184
+ }
185
+ else if (!valuesAreEqual(oldDCRValue, newValue)) {
186
+ if (oldValue && valuesAreEqual(oldValue, newValue)) {
187
+ rejectedChangeIds.push(change.id);
188
+ }
189
+ else {
190
+ var processedNewValue = typeof oldDCRValue === 'string' && typeof newValue === 'number'
191
+ ? newValue.toString()
192
+ : newValue;
193
+ updatedChange = assocPath(valuePath, processedNewValue, initialChange);
194
+ }
195
+ }
196
+ if (updatedChange) {
197
+ rawChanges.set(change.id, updatedChange);
198
+ }
199
+ }
200
+ }
201
+ };
202
+ for (var _e = 0, objectChanges_1 = objectChanges; _e < objectChanges_1.length; _e++) {
203
+ var change = objectChanges_1[_e];
204
+ _loop_1(change);
205
+ }
206
+ for (var _f = 0, _g = Array.from(rawChanges.values()); _f < _g.length; _f++) {
207
+ var rawChange = _g[_f];
208
+ var cleanedChange = cleanChange(rawChange);
209
+ var isNestedChange = has('attributeType', cleanedChange) &&
210
+ isNested(findAttributeTypeByUri(metadata, cleanedChange.attributeType));
211
+ if (isNestedChange && isEmpty((_b = cleanedChange.newValue) === null || _b === void 0 ? void 0 : _b.value)) {
212
+ rejectedChangeIds.push(cleanedChange.id);
213
+ }
214
+ else {
215
+ updatedChanges[objectUri] = append(cleanedChange, propOr([], objectUri, updatedChanges));
216
+ }
217
+ }
218
+ }
219
+ var rejectedBeforeUpdateIds = pipe(values, flatten, pluck('id'))(updatedChanges);
220
+ rejectedChangeIds.push.apply(rejectedChangeIds, rejectedBeforeUpdateIds);
221
+ var deleteAttributesGroups = groupBy(function (_a) {
222
+ var uri = _a[0];
223
+ return (isRelationUri(uri) ? 'relation' : 'entity');
224
+ }, toPairs(deleteAttributes));
225
+ var deleteRelationAttributes = fromPairs(deleteAttributesGroups.relation || []);
226
+ var deleteEntityAttributes = fromPairs(deleteAttributesGroups.entity || []);
227
+ return {
228
+ rejectedChangeIds: rejectedChangeIds,
229
+ updatedChanges: updatedChanges,
230
+ deleteEntityAttributes: deleteEntityAttributes,
231
+ deleteRelationAttributes: deleteRelationAttributes
232
+ };
233
+ };
@@ -252,7 +252,8 @@ export var mergeChanges = function (metadata, changes, entityInfo, relationsInfo
252
252
  ], changesTree);
253
253
  var relationsChanges = flatten(relationsInfo.map(function (relationInfo, index) {
254
254
  var changeType = path([relationInfo.uri, 0, 'type'], changes);
255
- return getRelationChanges(metadata, relationInfo, relationsTrees[index], changeType);
255
+ var relationChangeLineIds = path([relationInfo.uri, 0, 'lineIds'], changes);
256
+ return getRelationChanges(metadata, relationInfo, relationsTrees[index], changeType, relationChangeLineIds);
256
257
  }));
257
258
  return [entityChanges, relationsChanges];
258
259
  };
@@ -0,0 +1,3 @@
1
+ import { ChangeRequest } from '@reltio/mdm-sdk';
2
+ import { BeforeActionOutcome } from '../types';
3
+ export declare const useApplyDcrChanges: (dcr: ChangeRequest) => () => Promise<BeforeActionOutcome>;
@@ -0,0 +1,141 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { useCallback } from 'react';
38
+ import { useContextSelector } from '@fluentui/react-context-selector';
39
+ import { deleteChangeRequestItem, updateChangeRequest, promiseAllSettled, entityCumulativeUpdate, updateRelationWithDiff } from '@reltio/mdm-sdk';
40
+ import { isEmpty } from 'ramda';
41
+ import { useMdmMetadata } from '../../../contexts/MdmModuleContext';
42
+ import { ChangeRequestEditorContext } from '../contexts/ChangeRequestEditorContext';
43
+ import { buildDCRSavePlan } from '../helpers/dcr';
44
+ var withChangeRequestId = function (dcrUri) { return function (url) {
45
+ return url + (url.includes('?') ? '&' : '?') + "changeRequestId=".concat(encodeURIComponent(dcrUri.split('/')[1]));
46
+ }; };
47
+ export var useApplyDcrChanges = function (dcr) {
48
+ var getLinesByChangeId = useContextSelector(ChangeRequestEditorContext, function (context) { return context.getLinesByChangeId; });
49
+ var metadata = useMdmMetadata();
50
+ var applyDcrChanges = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
51
+ var _a, rejectedChangeIds, updatedChanges, deleteEntityAttributes, deleteRelationAttributes, deleteChangeResults, deleteEntityAttributesResults, deleteRelationAttributesResults, deleteChangeFailures, error_1, deleteEntityAttributesFailures, deleteRelationAttributesFailures;
52
+ return __generator(this, function (_b) {
53
+ switch (_b.label) {
54
+ case 0:
55
+ if (!(dcr === null || dcr === void 0 ? void 0 : dcr.changes)) return [3 /*break*/, 11];
56
+ _a = buildDCRSavePlan(dcr.changes, getLinesByChangeId, metadata), rejectedChangeIds = _a.rejectedChangeIds, updatedChanges = _a.updatedChanges, deleteEntityAttributes = _a.deleteEntityAttributes, deleteRelationAttributes = _a.deleteRelationAttributes;
57
+ deleteChangeResults = [];
58
+ deleteEntityAttributesResults = [];
59
+ deleteRelationAttributesResults = [];
60
+ if (!(rejectedChangeIds.length > 0)) return [3 /*break*/, 2];
61
+ return [4 /*yield*/, promiseAllSettled(rejectedChangeIds.map(function (changeId) {
62
+ return deleteChangeRequestItem({ dcrUri: dcr.uri, changeItemId: changeId });
63
+ }))];
64
+ case 1:
65
+ deleteChangeResults = _b.sent();
66
+ _b.label = 2;
67
+ case 2:
68
+ deleteChangeFailures = deleteChangeResults.filter(function (result) { return result.status === 'rejected'; });
69
+ if (deleteChangeFailures.length) {
70
+ return [2 /*return*/, {
71
+ proceed: false,
72
+ error: new Error("Failed to delete DCR change(s): ".concat(deleteChangeFailures.map(function (result) { return result.reason; }).join(', ')))
73
+ }];
74
+ }
75
+ if (!!isEmpty(updatedChanges)) return [3 /*break*/, 6];
76
+ _b.label = 3;
77
+ case 3:
78
+ _b.trys.push([3, 5, , 6]);
79
+ return [4 /*yield*/, updateChangeRequest({ dcrUri: dcr.uri, payload: updatedChanges })];
80
+ case 4:
81
+ _b.sent();
82
+ return [3 /*break*/, 6];
83
+ case 5:
84
+ error_1 = _b.sent();
85
+ return [2 /*return*/, {
86
+ proceed: false,
87
+ error: error_1
88
+ }];
89
+ case 6:
90
+ if (!!isEmpty(deleteEntityAttributes)) return [3 /*break*/, 8];
91
+ return [4 /*yield*/, promiseAllSettled(Object.entries(deleteEntityAttributes).map(function (_a) {
92
+ var entityUri = _a[0], diff = _a[1];
93
+ return entityCumulativeUpdate({
94
+ uri: entityUri,
95
+ diff: diff,
96
+ uriPreprocessor: withChangeRequestId(dcr.uri)
97
+ });
98
+ }))];
99
+ case 7:
100
+ deleteEntityAttributesResults = _b.sent();
101
+ _b.label = 8;
102
+ case 8:
103
+ deleteEntityAttributesFailures = deleteEntityAttributesResults.filter(function (result) { return result.status === 'rejected'; });
104
+ if (deleteEntityAttributesFailures.length) {
105
+ return [2 /*return*/, {
106
+ proceed: false,
107
+ error: new Error("Failed to delete entity attributes: ".concat(deleteEntityAttributesFailures.map(function (result) { return result.reason; }).join(', ')))
108
+ }];
109
+ }
110
+ if (!!isEmpty(deleteRelationAttributes)) return [3 /*break*/, 10];
111
+ return [4 /*yield*/, promiseAllSettled(Object.entries(deleteRelationAttributes).map(function (_a) {
112
+ var relationUri = _a[0], diff = _a[1];
113
+ return updateRelationWithDiff({
114
+ uri: relationUri,
115
+ diff: diff,
116
+ uriPreprocessor: withChangeRequestId(dcr.uri)
117
+ });
118
+ }))];
119
+ case 9:
120
+ deleteRelationAttributesResults = _b.sent();
121
+ _b.label = 10;
122
+ case 10:
123
+ deleteRelationAttributesFailures = deleteRelationAttributesResults.filter(function (result) { return result.status === 'rejected'; });
124
+ if (deleteRelationAttributesFailures.length) {
125
+ return [2 /*return*/, {
126
+ proceed: false,
127
+ error: new Error("Failed to delete relation attributes: ".concat(deleteRelationAttributesFailures.map(function (result) { return result.reason; }).join(', ')))
128
+ }];
129
+ }
130
+ return [2 /*return*/, {
131
+ proceed: true
132
+ }];
133
+ case 11: return [2 /*return*/, {
134
+ proceed: false,
135
+ error: new Error('No changes to apply')
136
+ }];
137
+ }
138
+ });
139
+ }); }, [dcr, getLinesByChangeId, metadata]);
140
+ return applyDcrChanges;
141
+ };
@@ -1,7 +1,12 @@
1
1
  import { WorkflowTaskData } from '@reltio/mdm-sdk';
2
- import { TaskAction } from '../types';
2
+ import { BeforeActionOutcome, TaskAction } from '../types';
3
3
  type Task = Partial<Pick<WorkflowTaskData, 'taskId' | 'possibleActions' | 'assignee' | 'isOpen'>>;
4
- export declare const useWorkflowActions: (task: Task, onActionSuccess?: (action: string) => void) => {
4
+ type Props = {
5
+ task: Task;
6
+ onActionSuccess?: (action: string) => void;
7
+ beforeAction?: () => Promise<BeforeActionOutcome>;
8
+ };
9
+ export declare const useWorkflowActions: ({ task, onActionSuccess, beforeAction }: Props) => {
5
10
  actions: TaskAction[];
6
11
  actionRequestIsInProgress: boolean;
7
12
  };