@reltio/components 1.4.2219 → 1.4.2221
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/ExportDialog/ExportDialog.d.ts +15 -0
- package/ExportDialog/ExportDialog.js +144 -0
- package/ExportDialog/ExportDialog.module.css.js +9 -0
- package/ExportDialog/ExportDialog.test.d.ts +1 -0
- package/ExportDialog/ExportDialog.test.js +285 -0
- package/ExportDialog/index.d.ts +1 -0
- package/ExportDialog/index.js +1 -0
- package/SimpleAttributeEditor/SimpleAttributeEditor.js +4 -1
- package/SimpleAttributeEditor/SimpleAttributeEditor.test.js +40 -3
- package/cjs/ExportDialog/ExportDialog.d.ts +15 -0
- package/cjs/ExportDialog/ExportDialog.js +174 -0
- package/cjs/ExportDialog/ExportDialog.module.css.js +9 -0
- package/cjs/ExportDialog/ExportDialog.test.d.ts +1 -0
- package/cjs/ExportDialog/ExportDialog.test.js +290 -0
- package/cjs/ExportDialog/index.d.ts +1 -0
- package/cjs/ExportDialog/index.js +5 -0
- package/cjs/SimpleAttributeEditor/SimpleAttributeEditor.js +4 -1
- package/cjs/SimpleAttributeEditor/SimpleAttributeEditor.test.js +40 -3
- package/cjs/contexts/AuthoringPerspectiveViewContext/index.d.ts +2 -0
- package/cjs/contexts/AuthoringPerspectiveViewContext/index.js +9 -0
- package/cjs/contexts/MdmModuleContext/context.d.ts +2 -0
- package/cjs/contexts/MdmModuleContext/hooks.d.ts +1 -0
- package/cjs/contexts/MdmModuleContext/hooks.js +3 -1
- package/cjs/contexts/SnackbarContext/index.d.ts +9 -2
- package/cjs/features/workflow/ReassignButton/components/ReassignDialog/styles.d.ts +1 -1
- package/cjs/hooks/useExportController/index.d.ts +1 -0
- package/cjs/hooks/useExportController/index.js +5 -0
- package/cjs/hooks/useExportController/useExportController.d.ts +11 -0
- package/cjs/hooks/useExportController/useExportController.js +20 -0
- package/cjs/hooks/useInternalExport/index.d.ts +1 -0
- package/cjs/hooks/useInternalExport/index.js +5 -0
- package/cjs/hooks/useInternalExport/useInternalExport.d.ts +35 -0
- package/cjs/hooks/useInternalExport/useInternalExport.js +205 -0
- package/cjs/hooks/useSnackbar/useSnackbar.d.ts +2 -1
- package/cjs/hooks/useSnackbar/useSnackbar.js +23 -4
- package/cjs/index.d.ts +2 -0
- package/cjs/index.js +8 -4
- package/contexts/AuthoringPerspectiveViewContext/index.d.ts +2 -0
- package/contexts/AuthoringPerspectiveViewContext/index.js +3 -0
- package/contexts/MdmModuleContext/context.d.ts +2 -0
- package/contexts/MdmModuleContext/hooks.d.ts +1 -0
- package/contexts/MdmModuleContext/hooks.js +1 -0
- package/contexts/SnackbarContext/index.d.ts +9 -2
- package/features/workflow/ReassignButton/components/ReassignDialog/styles.d.ts +1 -1
- package/hooks/useExportController/index.d.ts +1 -0
- package/hooks/useExportController/index.js +1 -0
- package/hooks/useExportController/useExportController.d.ts +11 -0
- package/hooks/useExportController/useExportController.js +16 -0
- package/hooks/useInternalExport/index.d.ts +1 -0
- package/hooks/useInternalExport/index.js +1 -0
- package/hooks/useInternalExport/useInternalExport.d.ts +35 -0
- package/hooks/useInternalExport/useInternalExport.js +198 -0
- package/hooks/useSnackbar/useSnackbar.d.ts +2 -1
- package/hooks/useSnackbar/useSnackbar.js +24 -5
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ActivityFilter } from '@reltio/mdm-sdk';
|
|
3
|
+
type Props = {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
profilesCount: number;
|
|
7
|
+
columnsByEntityType: Record<string, string[]>;
|
|
8
|
+
filter?: string;
|
|
9
|
+
activityFilter: ActivityFilter;
|
|
10
|
+
isSearchByOv: boolean;
|
|
11
|
+
onExternalExport: () => void;
|
|
12
|
+
onLoadingChange?: (loading: boolean) => void;
|
|
13
|
+
};
|
|
14
|
+
export declare const ExportDialog: ({ open, onClose, columnsByEntityType, profilesCount, onExternalExport, onLoadingChange, filter, activityFilter, isSearchByOv }: Props) => React.JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
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 React, { useCallback, useContext, useMemo, useRef } from 'react';
|
|
38
|
+
import i18n from 'ui-i18n';
|
|
39
|
+
import Dialog from '@mui/material/Dialog';
|
|
40
|
+
import DialogTitle from '@mui/material/DialogTitle';
|
|
41
|
+
import DialogActions from '@mui/material/DialogActions';
|
|
42
|
+
import Button from '@mui/material/Button';
|
|
43
|
+
import DialogContent from '@mui/material/DialogContent';
|
|
44
|
+
import Typography from '@mui/material/Typography';
|
|
45
|
+
import TextField from '@mui/material/TextField';
|
|
46
|
+
import { DropDownSelector } from '../DropDownSelector';
|
|
47
|
+
import { useInternalExport } from '../hooks/useInternalExport';
|
|
48
|
+
import { SnackbarContext } from '../contexts/SnackbarContext';
|
|
49
|
+
import { useMdmAction } from '../contexts/MdmModuleContext';
|
|
50
|
+
import { showErrorMessage } from '../helpers/errors';
|
|
51
|
+
import { ErrorWrapper } from '../ErrorWrapper';
|
|
52
|
+
import styles from './ExportDialog.module.css';
|
|
53
|
+
export var ExportDialog = function (_a) {
|
|
54
|
+
var open = _a.open, onClose = _a.onClose, columnsByEntityType = _a.columnsByEntityType, profilesCount = _a.profilesCount, onExternalExport = _a.onExternalExport, onLoadingChange = _a.onLoadingChange, _b = _a.filter, filter = _b === void 0 ? '' : _b, activityFilter = _a.activityFilter, isSearchByOv = _a.isSearchByOv;
|
|
55
|
+
var showSnackbarMessage = useContext(SnackbarContext);
|
|
56
|
+
var openConsoleApp = useMdmAction('openConsoleApp');
|
|
57
|
+
var isExportingRef = useRef(false);
|
|
58
|
+
var _c = useInternalExport({
|
|
59
|
+
columnsByEntityType: columnsByEntityType,
|
|
60
|
+
dialogOpen: open,
|
|
61
|
+
filter: filter,
|
|
62
|
+
activityFilter: activityFilter,
|
|
63
|
+
isSearchByOv: isSearchByOv
|
|
64
|
+
}), exportName = _c.exportName, onChangeExportName = _c.onChangeExportName, fileFormat = _c.fileFormat, onChangeFileFormat = _c.onChangeFileFormat, formatOptions = _c.formatOptions, onExport = _c.onExport, entityTypesDetails = _c.entityTypesDetails;
|
|
65
|
+
var handleConfirm = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
66
|
+
var result, failedCount, successfulCount, failedJobsString, errorMessage, error;
|
|
67
|
+
var _a, _b;
|
|
68
|
+
return __generator(this, function (_c) {
|
|
69
|
+
switch (_c.label) {
|
|
70
|
+
case 0:
|
|
71
|
+
if (isExportingRef.current)
|
|
72
|
+
return [2 /*return*/];
|
|
73
|
+
isExportingRef.current = true;
|
|
74
|
+
onLoadingChange === null || onLoadingChange === void 0 ? void 0 : onLoadingChange(true);
|
|
75
|
+
onClose();
|
|
76
|
+
_c.label = 1;
|
|
77
|
+
case 1:
|
|
78
|
+
_c.trys.push([1, , 3, 4]);
|
|
79
|
+
return [4 /*yield*/, onExport()];
|
|
80
|
+
case 2:
|
|
81
|
+
result = _c.sent();
|
|
82
|
+
if (result) {
|
|
83
|
+
failedCount = ((_a = result.failedJobs) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
84
|
+
successfulCount = result.total - failedCount;
|
|
85
|
+
if (successfulCount > 0) {
|
|
86
|
+
showSnackbarMessage({
|
|
87
|
+
message: i18n.text("Your export job is underway. We'll send an email with the download link once it's complete."),
|
|
88
|
+
action: {
|
|
89
|
+
label: i18n.text('View progress'),
|
|
90
|
+
onClick: function () {
|
|
91
|
+
openConsoleApp('Export');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (failedCount > 0) {
|
|
97
|
+
failedJobsString = (_b = result.failedJobs) === null || _b === void 0 ? void 0 : _b.join(', ');
|
|
98
|
+
errorMessage = i18n.text('Failed to export ${failedJobsString}.', { failedJobsString: failedJobsString });
|
|
99
|
+
error = new Error(errorMessage);
|
|
100
|
+
showErrorMessage(error, {
|
|
101
|
+
message: errorMessage
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return [3 /*break*/, 4];
|
|
106
|
+
case 3:
|
|
107
|
+
isExportingRef.current = false;
|
|
108
|
+
onLoadingChange === null || onLoadingChange === void 0 ? void 0 : onLoadingChange(false);
|
|
109
|
+
return [7 /*endfinally*/];
|
|
110
|
+
case 4: return [2 /*return*/];
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}); }, [onClose, onExport, showSnackbarMessage, openConsoleApp, onLoadingChange]);
|
|
114
|
+
var handleExternalExport = useCallback(function () {
|
|
115
|
+
onClose();
|
|
116
|
+
onExternalExport();
|
|
117
|
+
}, [onExternalExport, onClose]);
|
|
118
|
+
var renderDetails = useMemo(function () { return (React.createElement(React.Fragment, null, Object.values(entityTypesDetails).map(function (data, index) { return (React.createElement("span", { key: index },
|
|
119
|
+
React.createElement("span", { className: styles.attributesCount }, data.label),
|
|
120
|
+
i18n.text('(${selected}/${total} attributes)', {
|
|
121
|
+
selected: data.selectedAttributesCount,
|
|
122
|
+
total: data.totalAttributesCount
|
|
123
|
+
}),
|
|
124
|
+
index < Object.values(entityTypesDetails).length - 1 && ', ')); }))); }, [entityTypesDetails]);
|
|
125
|
+
return (React.createElement(Dialog, { open: open, onClose: onClose, fullWidth: true, classes: { paper: styles.dialog } },
|
|
126
|
+
React.createElement(DialogTitle, { classes: { root: styles.dialogTitle } }, i18n.text('Export')),
|
|
127
|
+
React.createElement(DialogContent, { classes: { root: styles.dialogContent } },
|
|
128
|
+
React.createElement(ErrorWrapper, { errorMessage: exportName ? '' : i18n.text('This field is required') },
|
|
129
|
+
React.createElement(TextField, { label: i18n.text('Name your export'), value: exportName, onChange: onChangeExportName, variant: 'filled', fullWidth: true, size: 'small', required: true })),
|
|
130
|
+
React.createElement(Typography, { variant: "subtitle2", className: styles.subtitle }, i18n.text('Data selected')),
|
|
131
|
+
React.createElement("div", { className: styles.summary },
|
|
132
|
+
React.createElement(Typography, { className: styles.totalCaption, color: "textSecondary" },
|
|
133
|
+
React.createElement("span", { className: styles.totalNumber }, i18n.number(profilesCount, '0,0')),
|
|
134
|
+
profilesCount === 1 ? i18n.text('Profile') : i18n.text('Profiles')),
|
|
135
|
+
React.createElement(Typography, { variant: "body2", color: "textSecondary" }, renderDetails)),
|
|
136
|
+
React.createElement(Typography, { variant: "subtitle2", className: styles.subtitle }, i18n.text('Export options')),
|
|
137
|
+
React.createElement(DropDownSelector, { height: 44, value: fileFormat, onChange: onChangeFileFormat, label: i18n.text('File format'), options: formatOptions }),
|
|
138
|
+
React.createElement("div", { className: styles.externalExportWrapper },
|
|
139
|
+
React.createElement(Typography, { component: "span", variant: "body2" }, i18n.text('Want more export options?')),
|
|
140
|
+
React.createElement(Button, { onClick: handleExternalExport, color: "primary" }, i18n.text('Go to export application')))),
|
|
141
|
+
React.createElement(DialogActions, { classes: { root: styles.dialogActions } },
|
|
142
|
+
React.createElement(Button, { onClick: onClose }, i18n.text('Cancel')),
|
|
143
|
+
React.createElement(Button, { onClick: handleConfirm, color: "primary", disabled: !exportName }, i18n.text('Export')))));
|
|
144
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const styles = {"dialog":"ExportDialog-dialog--lQGKH","dialogTitle":"ExportDialog-dialogTitle--xpDLc","dialogContent":"ExportDialog-dialogContent--r--OS","dialogActions":"ExportDialog-dialogActions--jfCax","subtitle":"ExportDialog-subtitle--rwHDK","summary":"ExportDialog-summary--TlOEd","externalExportWrapper":"ExportDialog-externalExportWrapper--vaAXD","totalCaption":"ExportDialog-totalCaption--DpfR-","totalNumber":"ExportDialog-totalNumber--emHu3","attributesCount":"ExportDialog-attributesCount--NRt8X"};
|
|
2
|
+
if (typeof document !== 'undefined') {
|
|
3
|
+
const head = document.head || document.getElementsByTagName('head')[0]
|
|
4
|
+
const style = document.createElement('style');
|
|
5
|
+
style.type = 'text/css'
|
|
6
|
+
style.innerHTML = `.ExportDialog-dialog--lQGKH{width:600px}.ExportDialog-dialogTitle--xpDLc{padding:16px 16px 4px}.ExportDialog-dialogContent--r--OS{padding:20px 16px}.ExportDialog-dialogActions--jfCax{padding:8px}.ExportDialog-subtitle--rwHDK{margin:24px 0 6px}.ExportDialog-summary--TlOEd{background-color:#fafafa;border-radius:4px;padding:12px 16px}.ExportDialog-externalExportWrapper--vaAXD{padding:16px 0}.ExportDialog-totalCaption--DpfR-{font-size:18px;padding-bottom:8px}.ExportDialog-totalNumber--emHu3{font-size:20px;font-weight:500}.ExportDialog-attributesCount--NRt8X,.ExportDialog-totalNumber--emHu3{color:rgba(0,0,0,.87);margin-right:5px}`;
|
|
7
|
+
head.appendChild(style);
|
|
8
|
+
}
|
|
9
|
+
export default styles;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,285 @@
|
|
|
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
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
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);
|
|
23
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
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;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import React from 'react';
|
|
49
|
+
import { render, screen } from '@testing-library/react';
|
|
50
|
+
import userEvent from '@testing-library/user-event';
|
|
51
|
+
import { createTheme } from '@mui/material/styles';
|
|
52
|
+
import { ThemeProvider } from '@mui/styles';
|
|
53
|
+
import { ActivityFilter, exportData, ExportDataFormat, ExportHeaderOrder } from '@reltio/mdm-sdk';
|
|
54
|
+
import { SnackbarContext } from '../contexts/SnackbarContext';
|
|
55
|
+
import { ExportDialog } from '../ExportDialog';
|
|
56
|
+
import { MdmModuleProvider } from '../contexts/MdmModuleContext';
|
|
57
|
+
import { ErrorPopup } from '../ErrorPopup';
|
|
58
|
+
import { theme } from '../constants';
|
|
59
|
+
jest.mock('@reltio/mdm-sdk', function () { return (__assign(__assign({}, jest.requireActual('@reltio/mdm-sdk')), { exportData: jest.fn() })); });
|
|
60
|
+
var metadata = {
|
|
61
|
+
entityTypes: [
|
|
62
|
+
{
|
|
63
|
+
uri: 'configuration/entityTypes/HCP',
|
|
64
|
+
label: 'HCP',
|
|
65
|
+
attributes: [
|
|
66
|
+
{
|
|
67
|
+
uri: 'configuration/entityTypes/HCP/attributes/FirstName',
|
|
68
|
+
type: 'String',
|
|
69
|
+
name: 'FirstName',
|
|
70
|
+
label: 'First Name',
|
|
71
|
+
access: ['READ', 'CREATE', 'UPDATE', 'INITIATE_CHANGE_REQUEST']
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
uri: 'configuration/entityTypes/HCP/attributes/LastName',
|
|
75
|
+
type: 'String',
|
|
76
|
+
name: 'LastName',
|
|
77
|
+
label: 'Last Name',
|
|
78
|
+
access: ['READ', 'CREATE', 'UPDATE', 'INITIATE_CHANGE_REQUEST']
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
uri: 'configuration/entityTypes/HCP/attributes/Phone',
|
|
82
|
+
type: 'String',
|
|
83
|
+
name: 'Phone',
|
|
84
|
+
label: 'Phone',
|
|
85
|
+
access: ['READ', 'CREATE', 'UPDATE', 'INITIATE_CHANGE_REQUEST']
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
uri: 'configuration/entityTypes/HCO',
|
|
91
|
+
label: 'HCO',
|
|
92
|
+
attributes: [
|
|
93
|
+
{
|
|
94
|
+
label: 'Name',
|
|
95
|
+
name: 'Name',
|
|
96
|
+
type: 'String',
|
|
97
|
+
uri: 'configuration/entityTypes/HCO/attributes/Name'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
label: 'Status',
|
|
101
|
+
name: 'Status',
|
|
102
|
+
type: 'String',
|
|
103
|
+
uri: 'configuration/entityTypes/HCO/attributes/Status'
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
};
|
|
109
|
+
var mdmValues = {
|
|
110
|
+
metadata: metadata,
|
|
111
|
+
exportPath: '/nui/export',
|
|
112
|
+
tenant: {
|
|
113
|
+
id: 't1',
|
|
114
|
+
name: 't1'
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
var mdmActions = { openConsoleApp: jest.fn() };
|
|
118
|
+
var defaultProps = {
|
|
119
|
+
open: true,
|
|
120
|
+
onClose: jest.fn(),
|
|
121
|
+
columnsByEntityType: {
|
|
122
|
+
'configuration/entityTypes/HCP': ['attributes.FirstName', 'attributes.LastName'],
|
|
123
|
+
'configuration/entityTypes/HCO': []
|
|
124
|
+
},
|
|
125
|
+
profilesCount: 15,
|
|
126
|
+
onExternalExport: jest.fn(),
|
|
127
|
+
onLoadingChange: jest.fn(),
|
|
128
|
+
filter: "(equals(type,'configuration/entityTypes/HCP') or equals(type,'configuration/entityTypes/HCO'))",
|
|
129
|
+
activityFilter: ActivityFilter.ALL,
|
|
130
|
+
isSearchByOv: true
|
|
131
|
+
};
|
|
132
|
+
var showSnackbarMessage = jest.fn();
|
|
133
|
+
var setUp = function (props) {
|
|
134
|
+
if (props === void 0) { props = defaultProps; }
|
|
135
|
+
var user = userEvent.setup();
|
|
136
|
+
var Providers = function (_a) {
|
|
137
|
+
var children = _a.children;
|
|
138
|
+
return (React.createElement(ThemeProvider, { theme: createTheme(theme) },
|
|
139
|
+
React.createElement(SnackbarContext.Provider, { value: showSnackbarMessage },
|
|
140
|
+
React.createElement(MdmModuleProvider, { values: mdmValues, actions: mdmActions },
|
|
141
|
+
React.createElement(ErrorPopup, null),
|
|
142
|
+
children))));
|
|
143
|
+
};
|
|
144
|
+
return __assign(__assign({}, render(React.createElement(ExportDialog, __assign({}, props)), { wrapper: Providers })), { user: user });
|
|
145
|
+
};
|
|
146
|
+
describe('ExportDialog tests', function () {
|
|
147
|
+
beforeEach(function () {
|
|
148
|
+
exportData.mockResolvedValue({ status: 'scheduled' });
|
|
149
|
+
});
|
|
150
|
+
afterEach(function () {
|
|
151
|
+
jest.clearAllMocks();
|
|
152
|
+
});
|
|
153
|
+
it('should render dialog correctly', function () {
|
|
154
|
+
jest.useFakeTimers();
|
|
155
|
+
jest.setSystemTime(new Date(2025, 10, 25, 9, 10, 0));
|
|
156
|
+
setUp();
|
|
157
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
158
|
+
expect(screen.getByLabelText('Export')).toBeInTheDocument();
|
|
159
|
+
expect(screen.getByText('Name your export')).toBeInTheDocument();
|
|
160
|
+
expect(screen.getByDisplayValue('Untitled Export Job 11252025_09:10')).toBeInTheDocument();
|
|
161
|
+
expect(screen.getByText('Data selected')).toBeInTheDocument();
|
|
162
|
+
expect(screen.getByText('15')).toBeInTheDocument();
|
|
163
|
+
expect(screen.getByText('Profiles')).toBeInTheDocument();
|
|
164
|
+
expect(screen.getByText('HCP')).toBeInTheDocument();
|
|
165
|
+
expect(screen.getByText('(2/13 attributes),')).toBeInTheDocument();
|
|
166
|
+
expect(screen.getByText('HCO')).toBeInTheDocument();
|
|
167
|
+
expect(screen.getByText('(12/12 attributes)')).toBeInTheDocument();
|
|
168
|
+
expect(screen.getByText('Export options')).toBeInTheDocument();
|
|
169
|
+
expect(screen.getByText('File format')).toBeInTheDocument();
|
|
170
|
+
expect(screen.getByText('CSV Flattened')).toBeInTheDocument();
|
|
171
|
+
expect(screen.getByText('Want more export options?')).toBeInTheDocument();
|
|
172
|
+
expect(screen.getByRole('button', { name: 'Go to export application' })).toBeInTheDocument();
|
|
173
|
+
expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
|
|
174
|
+
expect(screen.getByRole('button', { name: 'Export' })).toBeInTheDocument();
|
|
175
|
+
jest.useRealTimers();
|
|
176
|
+
});
|
|
177
|
+
it('should call onClose when Cancel button is clicked', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
178
|
+
var user;
|
|
179
|
+
return __generator(this, function (_a) {
|
|
180
|
+
switch (_a.label) {
|
|
181
|
+
case 0:
|
|
182
|
+
user = setUp().user;
|
|
183
|
+
return [4 /*yield*/, user.click(screen.getByRole('button', { name: 'Cancel' }))];
|
|
184
|
+
case 1:
|
|
185
|
+
_a.sent();
|
|
186
|
+
expect(defaultProps.onClose).toHaveBeenCalled();
|
|
187
|
+
return [2 /*return*/];
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}); });
|
|
191
|
+
it('should call onExternalExport when Go to export application button is clicked', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
192
|
+
var user;
|
|
193
|
+
return __generator(this, function (_a) {
|
|
194
|
+
switch (_a.label) {
|
|
195
|
+
case 0:
|
|
196
|
+
user = setUp().user;
|
|
197
|
+
return [4 /*yield*/, user.click(screen.getByRole('button', { name: 'Go to export application' }))];
|
|
198
|
+
case 1:
|
|
199
|
+
_a.sent();
|
|
200
|
+
expect(defaultProps.onExternalExport).toHaveBeenCalled();
|
|
201
|
+
return [2 /*return*/];
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}); });
|
|
205
|
+
it('should call onExport once and shows snackbar action on success', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
206
|
+
var user;
|
|
207
|
+
return __generator(this, function (_a) {
|
|
208
|
+
switch (_a.label) {
|
|
209
|
+
case 0:
|
|
210
|
+
jest.useFakeTimers();
|
|
211
|
+
jest.setSystemTime(new Date(2025, 10, 25, 9, 10, 0));
|
|
212
|
+
user = setUp().user;
|
|
213
|
+
jest.useRealTimers();
|
|
214
|
+
return [4 /*yield*/, user.click(screen.getByRole('button', { name: 'Export' }))];
|
|
215
|
+
case 1:
|
|
216
|
+
_a.sent();
|
|
217
|
+
expect(defaultProps.onLoadingChange).toHaveBeenCalledWith(true);
|
|
218
|
+
expect(exportData).toHaveBeenCalledTimes(2);
|
|
219
|
+
expect(exportData).toHaveBeenCalledWith(expect.objectContaining({
|
|
220
|
+
exportPath: '/nui/export',
|
|
221
|
+
tenant: 't1',
|
|
222
|
+
options: {
|
|
223
|
+
fileFormat: ExportDataFormat.CSV,
|
|
224
|
+
dateFormat: 'readable',
|
|
225
|
+
filter: defaultProps.filter,
|
|
226
|
+
activeness: ActivityFilter.ALL,
|
|
227
|
+
options: 'parallelExecution,searchByOv',
|
|
228
|
+
name: 'Untitled Export Job 11252025_09:10_HCP',
|
|
229
|
+
select: 'attributes.FirstName,attributes.LastName'
|
|
230
|
+
},
|
|
231
|
+
includeType: ['configuration/entityTypes/HCP'],
|
|
232
|
+
headerOrder: ExportHeaderOrder.Select
|
|
233
|
+
}));
|
|
234
|
+
expect(exportData).toHaveBeenCalledWith(expect.objectContaining({
|
|
235
|
+
exportPath: '/nui/export',
|
|
236
|
+
tenant: 't1',
|
|
237
|
+
options: {
|
|
238
|
+
fileFormat: ExportDataFormat.CSV,
|
|
239
|
+
dateFormat: 'readable',
|
|
240
|
+
filter: defaultProps.filter,
|
|
241
|
+
activeness: ActivityFilter.ALL,
|
|
242
|
+
options: 'parallelExecution,searchByOv',
|
|
243
|
+
name: 'Untitled Export Job 11252025_09:10_entities',
|
|
244
|
+
sendHidden: false
|
|
245
|
+
},
|
|
246
|
+
includeType: ['configuration/entityTypes/HCO'],
|
|
247
|
+
headerOrder: ExportHeaderOrder.Default
|
|
248
|
+
}));
|
|
249
|
+
expect(defaultProps.onLoadingChange).toHaveBeenCalledWith(false);
|
|
250
|
+
expect(defaultProps.onClose).toHaveBeenCalled();
|
|
251
|
+
expect(showSnackbarMessage).toHaveBeenCalledWith({
|
|
252
|
+
message: "Your export job is underway. We'll send an email with the download link once it's complete.",
|
|
253
|
+
action: {
|
|
254
|
+
label: 'View progress',
|
|
255
|
+
onClick: expect.any(Function)
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
return [2 /*return*/];
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}); });
|
|
262
|
+
it('should show error message when some export jobs failed', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
263
|
+
var user, errorMessage;
|
|
264
|
+
return __generator(this, function (_a) {
|
|
265
|
+
switch (_a.label) {
|
|
266
|
+
case 0:
|
|
267
|
+
exportData.mockRejectedValueOnce(new Error('Failed to export configuration/entityTypes/HCP'));
|
|
268
|
+
exportData.mockResolvedValueOnce({ status: 'scheduled' });
|
|
269
|
+
user = setUp().user;
|
|
270
|
+
return [4 /*yield*/, user.click(screen.getByRole('button', { name: 'Export' }))];
|
|
271
|
+
case 1:
|
|
272
|
+
_a.sent();
|
|
273
|
+
expect(defaultProps.onLoadingChange).toHaveBeenCalledWith(true);
|
|
274
|
+
expect(exportData).toHaveBeenCalledTimes(2);
|
|
275
|
+
expect(defaultProps.onLoadingChange).toHaveBeenCalledWith(false);
|
|
276
|
+
expect(defaultProps.onClose).toHaveBeenCalled();
|
|
277
|
+
return [4 /*yield*/, screen.findByTestId('error-message')];
|
|
278
|
+
case 2:
|
|
279
|
+
errorMessage = _a.sent();
|
|
280
|
+
expect(errorMessage).toHaveTextContent('Failed to export configuration/entityTypes/HCP.');
|
|
281
|
+
return [2 /*return*/];
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
}); });
|
|
285
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExportDialog } from './ExportDialog';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExportDialog } from './ExportDialog';
|
|
@@ -47,6 +47,7 @@ import { DependentLookupAutopopulationContext } from '../contexts/DependentLooku
|
|
|
47
47
|
import { useStyles } from './styles';
|
|
48
48
|
import { AddressAutoCompleteContext } from '../contexts/AutoCompleteContext';
|
|
49
49
|
import { AttributeValueContext } from '../contexts/AttributeValueContext';
|
|
50
|
+
import { AuthoringPerspectiveViewContext } from '../contexts/AuthoringPerspectiveViewContext';
|
|
50
51
|
var AsyncMountPlaceholder = function () {
|
|
51
52
|
var styles = useStyles();
|
|
52
53
|
return React.createElement("div", { className: styles.placeholder });
|
|
@@ -112,8 +113,10 @@ var SimpleAttributeEditor = function (_a) {
|
|
|
112
113
|
var hasError = !!errorMessage;
|
|
113
114
|
var deletedProps = deleted ? { disabled: true, isCrossedOut: true } : {};
|
|
114
115
|
var isProfilePerspectiveView = useContext(ProfilePerspectiveViewContext);
|
|
116
|
+
var isAuthoringPerspectiveView = useContext(AuthoringPerspectiveViewContext);
|
|
117
|
+
var isEntityPerspectiveView = isProfilePerspectiveView || isAuthoringPerspectiveView;
|
|
115
118
|
var autopopulationContextValue = useAutopopulationContextValue({
|
|
116
|
-
enabled:
|
|
119
|
+
enabled: isEntityPerspectiveView && isDependentLookupAttrType(attributeType),
|
|
117
120
|
attributeTypeUri: attributeType === null || attributeType === void 0 ? void 0 : attributeType.uri,
|
|
118
121
|
valueUri: attributeValue.uri
|
|
119
122
|
}).autopopulationContextValue;
|
|
@@ -54,6 +54,7 @@ import { ProfilePerspectiveViewContext } from '../contexts/ProfilePerspectiveVie
|
|
|
54
54
|
import { ScrollType, ScrollToElementContext } from '../contexts/ScrollToElementContext';
|
|
55
55
|
import { MdmModuleProvider, useMdmDependentLookupEditorContext } from '../contexts/MdmModuleContext';
|
|
56
56
|
import { AlwaysVisibleAttributesContext } from '../contexts/AlwaysVisibleAttributesContext';
|
|
57
|
+
import { AuthoringPerspectiveViewContext } from '../contexts/AuthoringPerspectiveViewContext';
|
|
57
58
|
import { useAutopopulationContextValue } from './useAutopopulationContextValue';
|
|
58
59
|
import { useScrollToAttributeError } from '../hooks/useScrollToAttributeError';
|
|
59
60
|
import { useAsyncMount } from '../hooks/useAsyncMount';
|
|
@@ -105,7 +106,7 @@ describe('SimpleAttributeEditor', function () {
|
|
|
105
106
|
onDeactivateError: jest.fn()
|
|
106
107
|
};
|
|
107
108
|
var setUp = function (_a) {
|
|
108
|
-
var _b = _a === void 0 ? {} : _a, _c = _b.props, props = _c === void 0 ? {} : _c, _d = _b.error, error = _d === void 0 ? null : _d, _e = _b.isProfilePerspective, isProfilePerspective = _e === void 0 ? false : _e, _f = _b.alwaysVisibleAttributes, alwaysVisibleAttributes =
|
|
109
|
+
var _b = _a === void 0 ? {} : _a, _c = _b.props, props = _c === void 0 ? {} : _c, _d = _b.error, error = _d === void 0 ? null : _d, _e = _b.isProfilePerspective, isProfilePerspective = _e === void 0 ? false : _e, _f = _b.isAuthoringPerspective, isAuthoringPerspective = _f === void 0 ? false : _f, _g = _b.alwaysVisibleAttributes, alwaysVisibleAttributes = _g === void 0 ? [] : _g;
|
|
109
110
|
var user = userEvent.setup();
|
|
110
111
|
var scrollToElementContextValue = getScrollToElementContextValue(error);
|
|
111
112
|
var Providers = function (_a) {
|
|
@@ -113,7 +114,8 @@ describe('SimpleAttributeEditor', function () {
|
|
|
113
114
|
return (React.createElement(MdmModuleProvider, { values: mdmValues },
|
|
114
115
|
React.createElement(AlwaysVisibleAttributesContext.Provider, { value: alwaysVisibleAttributes },
|
|
115
116
|
React.createElement(ProfilePerspectiveViewContext.Provider, { value: isProfilePerspective },
|
|
116
|
-
React.createElement(
|
|
117
|
+
React.createElement(AuthoringPerspectiveViewContext.Provider, { value: isAuthoringPerspective },
|
|
118
|
+
React.createElement(ScrollToElementContext.Provider, { value: scrollToElementContextValue }, children))))));
|
|
117
119
|
};
|
|
118
120
|
return __assign({ user: user, scrollToElementContextValue: scrollToElementContextValue }, render(React.createElement(SimpleAttributeEditor, __assign({}, defaultProps, props)), { wrapper: Providers }));
|
|
119
121
|
};
|
|
@@ -348,7 +350,7 @@ describe('SimpleAttributeEditor', function () {
|
|
|
348
350
|
uri: 'configuration/entityTypes/HCA/attributes/InternalCustomer',
|
|
349
351
|
dependentLookupCode: 'Code'
|
|
350
352
|
};
|
|
351
|
-
it('should call getDependentLookupEditorContext selector with correct arguments', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
353
|
+
it('should call getDependentLookupEditorContext selector with correct arguments for profile perspective', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
352
354
|
return __generator(this, function (_a) {
|
|
353
355
|
switch (_a.label) {
|
|
354
356
|
case 0:
|
|
@@ -366,6 +368,24 @@ describe('SimpleAttributeEditor', function () {
|
|
|
366
368
|
}
|
|
367
369
|
});
|
|
368
370
|
}); });
|
|
371
|
+
it('should call getDependentLookupEditorContext selector with correct arguments for authoring perspective', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
372
|
+
return __generator(this, function (_a) {
|
|
373
|
+
switch (_a.label) {
|
|
374
|
+
case 0:
|
|
375
|
+
setUp({ props: { attributeType: attributeType }, isAuthoringPerspective: true });
|
|
376
|
+
return [4 /*yield*/, act(function () { return Promise.resolve(); })];
|
|
377
|
+
case 1:
|
|
378
|
+
_a.sent();
|
|
379
|
+
expect(useMdmDependentLookupEditorContext).toHaveBeenCalledWith(defaultProps.attributeValue, attributeType);
|
|
380
|
+
expect(useAutopopulationContextValue).toHaveBeenCalledWith({
|
|
381
|
+
enabled: true,
|
|
382
|
+
attributeTypeUri: attributeType.uri,
|
|
383
|
+
valueUri: defaultProps.attributeValue.uri
|
|
384
|
+
});
|
|
385
|
+
return [2 /*return*/];
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}); });
|
|
369
389
|
it('should call useAutopopulationContextValue with enabled: false if component is outside of Profile perspective', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
370
390
|
return __generator(this, function (_a) {
|
|
371
391
|
switch (_a.label) {
|
|
@@ -383,6 +403,23 @@ describe('SimpleAttributeEditor', function () {
|
|
|
383
403
|
}
|
|
384
404
|
});
|
|
385
405
|
}); });
|
|
406
|
+
it('should call useAutopopulationContextValue with enabled: false if component is outside of authoring perspective', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
407
|
+
return __generator(this, function (_a) {
|
|
408
|
+
switch (_a.label) {
|
|
409
|
+
case 0:
|
|
410
|
+
setUp({ props: { attributeType: attributeType }, isAuthoringPerspective: false });
|
|
411
|
+
return [4 /*yield*/, act(function () { return Promise.resolve(); })];
|
|
412
|
+
case 1:
|
|
413
|
+
_a.sent();
|
|
414
|
+
expect(useAutopopulationContextValue).toHaveBeenCalledWith({
|
|
415
|
+
enabled: false,
|
|
416
|
+
attributeTypeUri: attributeType.uri,
|
|
417
|
+
valueUri: defaultProps.attributeValue.uri
|
|
418
|
+
});
|
|
419
|
+
return [2 /*return*/];
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}); });
|
|
386
423
|
it('should render dependent lookup editor with applied result of getDependentLookupEditorContext', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
387
424
|
var dlEditorContext, input;
|
|
388
425
|
return __generator(this, function (_a) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ActivityFilter } from '@reltio/mdm-sdk';
|
|
3
|
+
type Props = {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
profilesCount: number;
|
|
7
|
+
columnsByEntityType: Record<string, string[]>;
|
|
8
|
+
filter?: string;
|
|
9
|
+
activityFilter: ActivityFilter;
|
|
10
|
+
isSearchByOv: boolean;
|
|
11
|
+
onExternalExport: () => void;
|
|
12
|
+
onLoadingChange?: (loading: boolean) => void;
|
|
13
|
+
};
|
|
14
|
+
export declare const ExportDialog: ({ open, onClose, columnsByEntityType, profilesCount, onExternalExport, onLoadingChange, filter, activityFilter, isSearchByOv }: Props) => React.JSX.Element;
|
|
15
|
+
export {};
|