@reltio/components 1.4.2219 → 1.4.2220

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/ExportDialog/ExportDialog.d.ts +15 -0
  2. package/ExportDialog/ExportDialog.js +144 -0
  3. package/ExportDialog/ExportDialog.module.css.js +9 -0
  4. package/ExportDialog/ExportDialog.test.d.ts +1 -0
  5. package/ExportDialog/ExportDialog.test.js +285 -0
  6. package/ExportDialog/index.d.ts +1 -0
  7. package/ExportDialog/index.js +1 -0
  8. package/cjs/ExportDialog/ExportDialog.d.ts +15 -0
  9. package/cjs/ExportDialog/ExportDialog.js +174 -0
  10. package/cjs/ExportDialog/ExportDialog.module.css.js +9 -0
  11. package/cjs/ExportDialog/ExportDialog.test.d.ts +1 -0
  12. package/cjs/ExportDialog/ExportDialog.test.js +290 -0
  13. package/cjs/ExportDialog/index.d.ts +1 -0
  14. package/cjs/ExportDialog/index.js +5 -0
  15. package/cjs/contexts/MdmModuleContext/context.d.ts +2 -0
  16. package/cjs/contexts/MdmModuleContext/hooks.d.ts +1 -0
  17. package/cjs/contexts/MdmModuleContext/hooks.js +3 -1
  18. package/cjs/contexts/SnackbarContext/index.d.ts +9 -2
  19. package/cjs/features/workflow/ReassignButton/components/ReassignDialog/styles.d.ts +1 -1
  20. package/cjs/hooks/useExportController/index.d.ts +1 -0
  21. package/cjs/hooks/useExportController/index.js +5 -0
  22. package/cjs/hooks/useExportController/useExportController.d.ts +11 -0
  23. package/cjs/hooks/useExportController/useExportController.js +20 -0
  24. package/cjs/hooks/useInternalExport/index.d.ts +1 -0
  25. package/cjs/hooks/useInternalExport/index.js +5 -0
  26. package/cjs/hooks/useInternalExport/useInternalExport.d.ts +35 -0
  27. package/cjs/hooks/useInternalExport/useInternalExport.js +205 -0
  28. package/cjs/hooks/useSnackbar/useSnackbar.d.ts +2 -1
  29. package/cjs/hooks/useSnackbar/useSnackbar.js +23 -4
  30. package/cjs/index.d.ts +2 -0
  31. package/cjs/index.js +8 -4
  32. package/contexts/MdmModuleContext/context.d.ts +2 -0
  33. package/contexts/MdmModuleContext/hooks.d.ts +1 -0
  34. package/contexts/MdmModuleContext/hooks.js +1 -0
  35. package/contexts/SnackbarContext/index.d.ts +9 -2
  36. package/features/workflow/ReassignButton/components/ReassignDialog/styles.d.ts +1 -1
  37. package/hooks/useExportController/index.d.ts +1 -0
  38. package/hooks/useExportController/index.js +1 -0
  39. package/hooks/useExportController/useExportController.d.ts +11 -0
  40. package/hooks/useExportController/useExportController.js +16 -0
  41. package/hooks/useInternalExport/index.d.ts +1 -0
  42. package/hooks/useInternalExport/index.js +1 -0
  43. package/hooks/useInternalExport/useInternalExport.d.ts +35 -0
  44. package/hooks/useInternalExport/useInternalExport.js +198 -0
  45. package/hooks/useSnackbar/useSnackbar.d.ts +2 -1
  46. package/hooks/useSnackbar/useSnackbar.js +24 -5
  47. package/index.d.ts +2 -0
  48. package/index.js +2 -0
  49. 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';
@@ -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 {};