@dhis2/analytics 26.13.4 → 27.0.0
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/build/cjs/components/FileMenu/FileMenu.js +1 -2
- package/build/cjs/components/FileMenu/RenameDialog.js +10 -66
- package/build/cjs/components/FileMenu/__tests__/RenameDialog.spec.js +65 -33
- package/build/cjs/components/FileMenu/__tests__/utils.spec.js +239 -0
- package/build/cjs/components/FileMenu/utils.js +59 -3
- package/build/cjs/index.js +14 -0
- package/build/cjs/locales/en/translations.json +2 -0
- package/build/cjs/modules/visTypes.js +32 -2
- package/build/es/components/FileMenu/FileMenu.js +1 -2
- package/build/es/components/FileMenu/RenameDialog.js +12 -68
- package/build/es/components/FileMenu/__tests__/RenameDialog.spec.js +64 -32
- package/build/es/components/FileMenu/__tests__/utils.spec.js +237 -0
- package/build/es/components/FileMenu/utils.js +56 -1
- package/build/es/index.js +2 -2
- package/build/es/locales/en/translations.json +2 -0
- package/build/es/modules/visTypes.js +30 -1
- package/package.json +3 -3
|
@@ -57,8 +57,7 @@ const FileMenu = _ref => {
|
|
|
57
57
|
type: fileType,
|
|
58
58
|
object: fileObject,
|
|
59
59
|
onClose: onDialogClose,
|
|
60
|
-
onRename: onRename
|
|
61
|
-
onError: onError
|
|
60
|
+
onRename: onRename
|
|
62
61
|
});
|
|
63
62
|
case 'translate':
|
|
64
63
|
return /*#__PURE__*/_react.default.createElement(_index3.TranslationDialog, {
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.RenameDialog = void 0;
|
|
7
7
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
8
|
-
var _appRuntime = require("@dhis2/app-runtime");
|
|
9
8
|
var _ui = require("@dhis2/ui");
|
|
10
9
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
@@ -15,70 +14,21 @@ var _utils = require("./utils.js");
|
|
|
15
14
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
16
15
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
17
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
|
-
const
|
|
19
|
-
const payload = [{
|
|
20
|
-
op: 'add',
|
|
21
|
-
path: '/name',
|
|
22
|
-
value: name
|
|
23
|
-
}];
|
|
24
|
-
if (description) {
|
|
25
|
-
payload.push({
|
|
26
|
-
op: 'add',
|
|
27
|
-
path: '/description',
|
|
28
|
-
value: description
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
return payload;
|
|
32
|
-
};
|
|
33
|
-
const getMutation = type => ({
|
|
34
|
-
resource: (0, _utils.endpointFromFileType)(type),
|
|
35
|
-
id: _ref => {
|
|
36
|
-
let {
|
|
37
|
-
id
|
|
38
|
-
} = _ref;
|
|
39
|
-
return id;
|
|
40
|
-
},
|
|
41
|
-
type: 'json-patch',
|
|
42
|
-
data: _ref2 => {
|
|
43
|
-
let {
|
|
44
|
-
name,
|
|
45
|
-
description
|
|
46
|
-
} = _ref2;
|
|
47
|
-
return formatPayload(name, description);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
const RenameDialog = _ref3 => {
|
|
17
|
+
const RenameDialog = _ref => {
|
|
51
18
|
let {
|
|
52
19
|
type,
|
|
53
20
|
object,
|
|
54
21
|
onClose,
|
|
55
|
-
onRename
|
|
56
|
-
|
|
57
|
-
} = _ref3;
|
|
22
|
+
onRename
|
|
23
|
+
} = _ref;
|
|
58
24
|
const [name, setName] = (0, _react.useState)(object.name);
|
|
59
25
|
const [description, setDescription] = (0, _react.useState)(object.description);
|
|
60
|
-
const mutation = (0, _react.useMemo)(() => getMutation(type), [type]);
|
|
61
|
-
const [mutate, {
|
|
62
|
-
loading
|
|
63
|
-
}] = (0, _appRuntime.useDataMutation)(mutation, {
|
|
64
|
-
onError: error => {
|
|
65
|
-
onError(error);
|
|
66
|
-
onClose();
|
|
67
|
-
},
|
|
68
|
-
onComplete: () => {
|
|
69
|
-
onRename({
|
|
70
|
-
name,
|
|
71
|
-
description
|
|
72
|
-
});
|
|
73
|
-
onClose();
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
26
|
const renameObject = () => {
|
|
77
|
-
|
|
78
|
-
id: object.id,
|
|
27
|
+
onRename({
|
|
79
28
|
name,
|
|
80
29
|
description
|
|
81
30
|
});
|
|
31
|
+
onClose();
|
|
82
32
|
};
|
|
83
33
|
return /*#__PURE__*/_react.default.createElement(_ui.Modal, {
|
|
84
34
|
onClose: onClose,
|
|
@@ -91,50 +41,44 @@ const RenameDialog = _ref3 => {
|
|
|
91
41
|
className: `jsx-${_FileMenuStyles.modalStyles.__hash}` + " " + "modal-content"
|
|
92
42
|
}, /*#__PURE__*/_react.default.createElement(_ui.InputField, {
|
|
93
43
|
label: _index.default.t('Name'),
|
|
94
|
-
disabled: loading,
|
|
95
44
|
required: true,
|
|
96
45
|
value: name,
|
|
97
|
-
onChange:
|
|
46
|
+
onChange: _ref2 => {
|
|
98
47
|
let {
|
|
99
48
|
value
|
|
100
|
-
} =
|
|
49
|
+
} = _ref2;
|
|
101
50
|
return setName(value);
|
|
102
51
|
},
|
|
103
52
|
dataTest: "file-menu-rename-modal-name"
|
|
104
53
|
}), /*#__PURE__*/_react.default.createElement(_ui.TextAreaField, {
|
|
105
54
|
label: _index.default.t('Description'),
|
|
106
|
-
disabled: loading,
|
|
107
55
|
value: description,
|
|
108
56
|
rows: 3,
|
|
109
|
-
onChange:
|
|
57
|
+
onChange: _ref3 => {
|
|
110
58
|
let {
|
|
111
59
|
value
|
|
112
|
-
} =
|
|
60
|
+
} = _ref3;
|
|
113
61
|
return setDescription(value);
|
|
114
62
|
},
|
|
115
63
|
dataTest: "file-menu-rename-modal-description"
|
|
116
64
|
}))), /*#__PURE__*/_react.default.createElement(_ui.ModalActions, null, /*#__PURE__*/_react.default.createElement(_ui.ButtonStrip, null, /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
117
65
|
onClick: onClose,
|
|
118
|
-
disabled: loading,
|
|
119
66
|
secondary: true,
|
|
120
67
|
dataTest: "file-menu-rename-modal-cancel"
|
|
121
68
|
}, _index.default.t('Cancel')), /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
122
69
|
onClick: renameObject,
|
|
123
|
-
disabled: loading,
|
|
124
70
|
primary: true,
|
|
125
71
|
dataTest: "file-menu-rename-modal-rename"
|
|
126
72
|
}, _index.default.t('Rename')))));
|
|
127
73
|
};
|
|
128
74
|
exports.RenameDialog = RenameDialog;
|
|
129
75
|
RenameDialog.propTypes = {
|
|
130
|
-
id: _propTypes.default.string,
|
|
131
76
|
object: _propTypes.default.shape({
|
|
132
|
-
id: _propTypes.default.string.isRequired,
|
|
133
77
|
description: _propTypes.default.string,
|
|
78
|
+
id: _propTypes.default.string,
|
|
134
79
|
name: _propTypes.default.string
|
|
135
80
|
}),
|
|
136
81
|
type: _propTypes.default.oneOf(_utils.supportedFileTypes),
|
|
137
82
|
onClose: _propTypes.default.func,
|
|
138
|
-
onError: _propTypes.default.func,
|
|
139
83
|
onRename: _propTypes.default.func
|
|
140
84
|
};
|
|
@@ -1,54 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
require("@testing-library/jest-dom");
|
|
4
|
+
var _react = require("@testing-library/react");
|
|
5
|
+
var _react2 = _interopRequireDefault(require("react"));
|
|
6
6
|
var _RenameDialog = require("../RenameDialog.js");
|
|
7
7
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
8
9
|
describe('The FileMenu - RenameDialog component', () => {
|
|
9
|
-
let shallowRenameDialog;
|
|
10
|
-
let props;
|
|
11
10
|
const onClose = jest.fn();
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
const onRename = jest.fn();
|
|
12
|
+
const props = {
|
|
13
|
+
type: 'visualization',
|
|
14
|
+
object: {
|
|
15
|
+
id: 'rename-test'
|
|
16
|
+
},
|
|
17
|
+
onClose,
|
|
18
|
+
onRename
|
|
17
19
|
};
|
|
18
20
|
beforeEach(() => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type: 'visualization',
|
|
22
|
-
object: {
|
|
23
|
-
id: 'rename-test'
|
|
24
|
-
},
|
|
25
|
-
onClose
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
it('renders a Modal component', () => {
|
|
29
|
-
expect(getRenameDialogComponent(props).find(_ui.Modal)).toHaveLength(1);
|
|
21
|
+
jest.resetAllMocks();
|
|
22
|
+
jest.clearAllMocks();
|
|
30
23
|
});
|
|
31
|
-
it('renders a
|
|
32
|
-
|
|
24
|
+
it('renders a Modal component with the correct heading', () => {
|
|
25
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, props));
|
|
26
|
+
expect(_react.screen.getAllByTestId('file-menu-rename-modal')).toHaveLength(1);
|
|
27
|
+
expect(_react.screen.getByRole('heading')).toHaveTextContent('Rename visualization');
|
|
33
28
|
});
|
|
34
29
|
it('renders a InputField for name', () => {
|
|
35
|
-
|
|
30
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, props));
|
|
31
|
+
expect(_react.screen.getByTestId('file-menu-rename-modal-name')).toBeInTheDocument();
|
|
32
|
+
expect(_react.screen.getByText('Name')).toBeInTheDocument();
|
|
33
|
+
expect(_react.screen.getByText('Name')).toBeVisible();
|
|
36
34
|
});
|
|
37
35
|
it('renders a InputField for name with prefilled value if name is in object prop', () => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, _extends({}, props, {
|
|
37
|
+
object: {
|
|
38
|
+
...props.object,
|
|
39
|
+
name: 'Vis test'
|
|
40
|
+
}
|
|
41
|
+
})));
|
|
42
|
+
const ancestorElement = _react.screen.getByTestId('file-menu-rename-modal-name');
|
|
43
|
+
const inputElement = (0, _react.within)(ancestorElement).getByRole('textbox');
|
|
44
|
+
expect(inputElement).toBeInTheDocument();
|
|
45
|
+
expect(inputElement).toHaveValue('Vis test');
|
|
41
46
|
});
|
|
42
47
|
it('renders a TextAreaField for description', () => {
|
|
43
|
-
|
|
48
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, props));
|
|
49
|
+
|
|
50
|
+
// Locate the label by its text
|
|
51
|
+
const labelElement = _react.screen.getByText('Description');
|
|
52
|
+
|
|
53
|
+
// Find the textarea element within the same container as the label
|
|
54
|
+
const descriptionField = labelElement.closest('div').querySelector('textarea');
|
|
55
|
+
expect(descriptionField).toBeInTheDocument();
|
|
56
|
+
expect(descriptionField).toBeVisible();
|
|
44
57
|
});
|
|
45
58
|
it('renders a TextAreaField for description with prefilled value if description is in object prop', () => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, _extends({}, props, {
|
|
60
|
+
object: {
|
|
61
|
+
...props.object,
|
|
62
|
+
description: 'Long explanation of the visualization'
|
|
63
|
+
}
|
|
64
|
+
})));
|
|
65
|
+
|
|
66
|
+
// Locate the label by its text
|
|
67
|
+
const labelElement = _react.screen.getByText('Description');
|
|
68
|
+
|
|
69
|
+
// Find the textarea element within the same container as the label
|
|
70
|
+
const descriptionField = labelElement.closest('div').querySelector('textarea');
|
|
71
|
+
expect(descriptionField).toBeInTheDocument();
|
|
72
|
+
expect(descriptionField).toHaveValue('Long explanation of the visualization');
|
|
73
|
+
});
|
|
74
|
+
it('calls the onClose callback when the Cancel button is clicked', async () => {
|
|
75
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, props));
|
|
76
|
+
await _react.fireEvent.click(_react.screen.getByTestId('file-menu-rename-modal-cancel'));
|
|
77
|
+
expect(onClose).toHaveBeenCalled();
|
|
78
|
+
expect(onRename).not.toHaveBeenCalled();
|
|
49
79
|
});
|
|
50
|
-
it('calls the
|
|
51
|
-
|
|
80
|
+
it('calls the onRename callback when the Rename button is clicked', async () => {
|
|
81
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_RenameDialog.RenameDialog, props));
|
|
82
|
+
await _react.fireEvent.click(_react.screen.getByTestId('file-menu-rename-modal-rename'));
|
|
83
|
+
expect(onRename).toHaveBeenCalled();
|
|
52
84
|
expect(onClose).toHaveBeenCalled();
|
|
53
85
|
});
|
|
54
86
|
});
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _utils = require("../utils.js");
|
|
4
|
+
describe('utils', () => {
|
|
5
|
+
describe('preparePayloadForSaveAs', () => {
|
|
6
|
+
it('removes unnecessary properties from the visualization object', () => {
|
|
7
|
+
const visualization = {
|
|
8
|
+
id: '123',
|
|
9
|
+
created: '2023-01-01',
|
|
10
|
+
createdBy: 'user1',
|
|
11
|
+
user: 'user2',
|
|
12
|
+
name: 'Existing Name',
|
|
13
|
+
description: 'Existing Description',
|
|
14
|
+
type: 'PIVOT_TABLE'
|
|
15
|
+
};
|
|
16
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
17
|
+
visualization
|
|
18
|
+
});
|
|
19
|
+
expect(result).not.toHaveProperty('id');
|
|
20
|
+
expect(result).not.toHaveProperty('created');
|
|
21
|
+
expect(result).not.toHaveProperty('createdBy');
|
|
22
|
+
expect(result).not.toHaveProperty('user');
|
|
23
|
+
});
|
|
24
|
+
it('sets the name to the provided name', () => {
|
|
25
|
+
const visualization = {
|
|
26
|
+
type: 'PIVOT_TABLE'
|
|
27
|
+
};
|
|
28
|
+
const name = 'New Name';
|
|
29
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
30
|
+
visualization,
|
|
31
|
+
name
|
|
32
|
+
});
|
|
33
|
+
expect(result.name).toBe(name);
|
|
34
|
+
});
|
|
35
|
+
it('sets the name to the existing name if no new name is provided', () => {
|
|
36
|
+
const visualization = {
|
|
37
|
+
name: 'Existing Name',
|
|
38
|
+
type: 'MAP'
|
|
39
|
+
};
|
|
40
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
41
|
+
visualization
|
|
42
|
+
});
|
|
43
|
+
expect(result.name).toBe('Existing Name');
|
|
44
|
+
});
|
|
45
|
+
it('sets the name to a default value if no name is provided', () => {
|
|
46
|
+
const visualization = {
|
|
47
|
+
type: 'LINE_LIST'
|
|
48
|
+
};
|
|
49
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
50
|
+
visualization
|
|
51
|
+
});
|
|
52
|
+
const expectedName = `Untitled Line list, ${new Date().toLocaleDateString(undefined, {
|
|
53
|
+
year: 'numeric',
|
|
54
|
+
month: 'short',
|
|
55
|
+
day: '2-digit'
|
|
56
|
+
})}`;
|
|
57
|
+
expect(result.name).toBe(expectedName);
|
|
58
|
+
});
|
|
59
|
+
it('sets the description to the provided description', () => {
|
|
60
|
+
const visualization = {
|
|
61
|
+
description: 'Existing Description',
|
|
62
|
+
type: 'PIVOT_TABLE'
|
|
63
|
+
};
|
|
64
|
+
const description = 'New Description';
|
|
65
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
66
|
+
visualization,
|
|
67
|
+
description
|
|
68
|
+
});
|
|
69
|
+
expect(result.description).toBe(description);
|
|
70
|
+
});
|
|
71
|
+
it('keeps the existing description if no new description is provided', () => {
|
|
72
|
+
const visualization = {
|
|
73
|
+
description: 'Existing Description',
|
|
74
|
+
type: 'PIVOT_TABLE'
|
|
75
|
+
};
|
|
76
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
77
|
+
visualization
|
|
78
|
+
});
|
|
79
|
+
expect(result.description).toBe('Existing Description');
|
|
80
|
+
});
|
|
81
|
+
it('sets the description to undefined if no description is provided and none exists', () => {
|
|
82
|
+
const visualization = {
|
|
83
|
+
type: 'PIVOT_TABLE'
|
|
84
|
+
};
|
|
85
|
+
const result = (0, _utils.preparePayloadForSaveAs)({
|
|
86
|
+
visualization
|
|
87
|
+
});
|
|
88
|
+
expect(result.description).toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('preparePayloadForSave', () => {
|
|
92
|
+
const mockEngine = {
|
|
93
|
+
query: jest.fn()
|
|
94
|
+
};
|
|
95
|
+
beforeEach(() => {
|
|
96
|
+
jest.clearAllMocks();
|
|
97
|
+
});
|
|
98
|
+
it('fetches subscribers and adds them to the visualization', async () => {
|
|
99
|
+
const visualization = {
|
|
100
|
+
id: '123',
|
|
101
|
+
type: 'BAR',
|
|
102
|
+
name: 'Existing Name',
|
|
103
|
+
description: 'Existing Description'
|
|
104
|
+
};
|
|
105
|
+
mockEngine.query.mockResolvedValue({
|
|
106
|
+
ao: {
|
|
107
|
+
subscribers: ['user1', 'user2']
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
111
|
+
visualization,
|
|
112
|
+
engine: mockEngine
|
|
113
|
+
});
|
|
114
|
+
expect(mockEngine.query).toHaveBeenCalledWith({
|
|
115
|
+
ao: {
|
|
116
|
+
resource: 'visualizations',
|
|
117
|
+
id: expect.any(Function),
|
|
118
|
+
params: {
|
|
119
|
+
fields: 'subscribers'
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}, {
|
|
123
|
+
variables: {
|
|
124
|
+
id: '123'
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
expect(result.subscribers).toEqual(['user1', 'user2']);
|
|
128
|
+
});
|
|
129
|
+
it('sets the name to the provided name', async () => {
|
|
130
|
+
const visualization = {
|
|
131
|
+
id: '123',
|
|
132
|
+
type: 'MAP',
|
|
133
|
+
name: 'Existing name'
|
|
134
|
+
};
|
|
135
|
+
const name = 'New Name';
|
|
136
|
+
mockEngine.query.mockResolvedValue({
|
|
137
|
+
ao: {
|
|
138
|
+
subscribers: []
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
142
|
+
visualization,
|
|
143
|
+
name,
|
|
144
|
+
engine: mockEngine
|
|
145
|
+
});
|
|
146
|
+
expect(result.name).toBe(name);
|
|
147
|
+
});
|
|
148
|
+
it('sets the name to the existing name if no new name is provided', async () => {
|
|
149
|
+
const visualization = {
|
|
150
|
+
id: '123',
|
|
151
|
+
type: 'LINE_LIST',
|
|
152
|
+
name: 'Existing Name'
|
|
153
|
+
};
|
|
154
|
+
mockEngine.query.mockResolvedValue({
|
|
155
|
+
ao: {
|
|
156
|
+
subscribers: []
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
160
|
+
visualization,
|
|
161
|
+
engine: mockEngine
|
|
162
|
+
});
|
|
163
|
+
expect(result.name).toBe('Existing Name');
|
|
164
|
+
});
|
|
165
|
+
it('sets the name to a default value if no name is provided', async () => {
|
|
166
|
+
const visualization = {
|
|
167
|
+
id: '123',
|
|
168
|
+
type: 'BAR'
|
|
169
|
+
};
|
|
170
|
+
mockEngine.query.mockResolvedValue({
|
|
171
|
+
ao: {
|
|
172
|
+
subscribers: []
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
176
|
+
visualization,
|
|
177
|
+
engine: mockEngine
|
|
178
|
+
});
|
|
179
|
+
const expectedName = `Untitled Bar, ${new Date().toLocaleDateString(undefined, {
|
|
180
|
+
year: 'numeric',
|
|
181
|
+
month: 'short',
|
|
182
|
+
day: '2-digit'
|
|
183
|
+
})}`;
|
|
184
|
+
expect(result.name).toBe(expectedName);
|
|
185
|
+
});
|
|
186
|
+
it('sets the description to the provided description', async () => {
|
|
187
|
+
const visualization = {
|
|
188
|
+
id: '123',
|
|
189
|
+
type: 'YEAR_OVER_YEAR_LINE',
|
|
190
|
+
description: 'Existing Description'
|
|
191
|
+
};
|
|
192
|
+
const description = 'New Description';
|
|
193
|
+
mockEngine.query.mockResolvedValue({
|
|
194
|
+
ao: {
|
|
195
|
+
subscribers: []
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
199
|
+
visualization,
|
|
200
|
+
description,
|
|
201
|
+
engine: mockEngine
|
|
202
|
+
});
|
|
203
|
+
expect(result.description).toBe(description);
|
|
204
|
+
});
|
|
205
|
+
it('keeps the existing description if no new description is provided', async () => {
|
|
206
|
+
const visualization = {
|
|
207
|
+
id: '123',
|
|
208
|
+
type: 'COLUMN',
|
|
209
|
+
description: 'Existing Description'
|
|
210
|
+
};
|
|
211
|
+
mockEngine.query.mockResolvedValue({
|
|
212
|
+
ao: {
|
|
213
|
+
subscribers: []
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
217
|
+
visualization,
|
|
218
|
+
engine: mockEngine
|
|
219
|
+
});
|
|
220
|
+
expect(result.description).toBe('Existing Description');
|
|
221
|
+
});
|
|
222
|
+
it('sets the description to undefined if no description is provided and none exists', async () => {
|
|
223
|
+
const visualization = {
|
|
224
|
+
id: '123',
|
|
225
|
+
type: 'BAR'
|
|
226
|
+
};
|
|
227
|
+
mockEngine.query.mockResolvedValue({
|
|
228
|
+
ao: {
|
|
229
|
+
subscribers: []
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
const result = await (0, _utils.preparePayloadForSave)({
|
|
233
|
+
visualization,
|
|
234
|
+
engine: mockEngine
|
|
235
|
+
});
|
|
236
|
+
expect(result.description).toBeUndefined();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.supportedFileTypes = exports.preparePayloadForSaveAs = exports.labelForFileType = exports.endpointFromFileType = exports.appPathFor = exports.FILE_TYPE_VISUALIZATION = exports.FILE_TYPE_MAP = exports.FILE_TYPE_EVENT_VISUALIZATION = exports.FILE_TYPE_EVENT_REPORT = void 0;
|
|
6
|
+
exports.supportedFileTypes = exports.preparePayloadForSaveAs = exports.preparePayloadForSave = exports.labelForFileType = exports.endpointFromFileType = exports.appPathFor = exports.FILE_TYPE_VISUALIZATION = exports.FILE_TYPE_MAP = exports.FILE_TYPE_EVENT_VISUALIZATION = exports.FILE_TYPE_EVENT_REPORT = void 0;
|
|
7
7
|
var _d2I18n = _interopRequireDefault(require("@dhis2/d2-i18n"));
|
|
8
|
+
var _visTypes = require("../../modules/visTypes.js");
|
|
8
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
10
|
const FILE_TYPE_EVENT_REPORT = exports.FILE_TYPE_EVENT_REPORT = 'eventReport';
|
|
10
11
|
const FILE_TYPE_VISUALIZATION = exports.FILE_TYPE_VISUALIZATION = 'visualization';
|
|
@@ -44,12 +45,67 @@ const appPathFor = (fileType, id, apiVersion) => {
|
|
|
44
45
|
exports.appPathFor = appPathFor;
|
|
45
46
|
const preparePayloadForSaveAs = _ref => {
|
|
46
47
|
let {
|
|
47
|
-
|
|
48
|
+
visualization,
|
|
49
|
+
name,
|
|
50
|
+
description
|
|
48
51
|
} = _ref;
|
|
49
52
|
delete visualization.id;
|
|
50
53
|
delete visualization.created;
|
|
51
54
|
delete visualization.createdBy;
|
|
52
55
|
delete visualization.user;
|
|
56
|
+
visualization.name = name || visualization.name || _d2I18n.default.t('Untitled {{visualizationType}}, {{date}}', {
|
|
57
|
+
visualizationType: (0, _visTypes.getDisplayNameByVisType)(visualization.type),
|
|
58
|
+
date: new Date().toLocaleDateString(undefined, {
|
|
59
|
+
year: 'numeric',
|
|
60
|
+
month: 'short',
|
|
61
|
+
day: '2-digit'
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
visualization.description = description !== undefined ? description : visualization.description;
|
|
53
65
|
return visualization;
|
|
54
66
|
};
|
|
55
|
-
exports.preparePayloadForSaveAs = preparePayloadForSaveAs;
|
|
67
|
+
exports.preparePayloadForSaveAs = preparePayloadForSaveAs;
|
|
68
|
+
const getSubscriberQuery = type => ({
|
|
69
|
+
ao: {
|
|
70
|
+
resource: (0, _visTypes.getApiEndpointByVisType)(type),
|
|
71
|
+
id: _ref2 => {
|
|
72
|
+
let {
|
|
73
|
+
id
|
|
74
|
+
} = _ref2;
|
|
75
|
+
return id;
|
|
76
|
+
},
|
|
77
|
+
params: {
|
|
78
|
+
fields: 'subscribers'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const apiFetchAOSubscribers = (dataEngine, id, type) => {
|
|
83
|
+
return dataEngine.query(getSubscriberQuery(type), {
|
|
84
|
+
variables: {
|
|
85
|
+
id
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
const preparePayloadForSave = async _ref3 => {
|
|
90
|
+
let {
|
|
91
|
+
visualization,
|
|
92
|
+
name,
|
|
93
|
+
description,
|
|
94
|
+
engine
|
|
95
|
+
} = _ref3;
|
|
96
|
+
const {
|
|
97
|
+
ao
|
|
98
|
+
} = await apiFetchAOSubscribers(engine, visualization.id, visualization.type);
|
|
99
|
+
visualization.subscribers = ao.subscribers;
|
|
100
|
+
visualization.name = name || visualization.name || _d2I18n.default.t('Untitled {{visualizationType}}, {{date}}', {
|
|
101
|
+
visualizationType: (0, _visTypes.getDisplayNameByVisType)(visualization.type),
|
|
102
|
+
date: new Date().toLocaleDateString(undefined, {
|
|
103
|
+
year: 'numeric',
|
|
104
|
+
month: 'short',
|
|
105
|
+
day: '2-digit'
|
|
106
|
+
})
|
|
107
|
+
});
|
|
108
|
+
visualization.description = description !== undefined ? description : visualization.description;
|
|
109
|
+
return visualization;
|
|
110
|
+
};
|
|
111
|
+
exports.preparePayloadForSave = preparePayloadForSave;
|
package/build/cjs/index.js
CHANGED
|
@@ -17,6 +17,7 @@ var _exportNames = {
|
|
|
17
17
|
PivotTable: true,
|
|
18
18
|
FileMenu: true,
|
|
19
19
|
preparePayloadForSaveAs: true,
|
|
20
|
+
preparePayloadForSave: true,
|
|
20
21
|
VisTypeIcon: true,
|
|
21
22
|
LegendKey: true,
|
|
22
23
|
AboutAOUnit: true,
|
|
@@ -150,6 +151,7 @@ var _exportNames = {
|
|
|
150
151
|
VIS_TYPE_SCATTER: true,
|
|
151
152
|
VIS_TYPE_LINE_LIST: true,
|
|
152
153
|
VIS_TYPE_OUTLIER_TABLE: true,
|
|
154
|
+
VIS_TYPE_MAP: true,
|
|
153
155
|
visTypeDisplayNames: true,
|
|
154
156
|
visTypeIcons: true,
|
|
155
157
|
getDisplayNameByVisType: true,
|
|
@@ -1149,6 +1151,12 @@ Object.defineProperty(exports, "VIS_TYPE_LINE_LIST", {
|
|
|
1149
1151
|
return _visTypes.VIS_TYPE_LINE_LIST;
|
|
1150
1152
|
}
|
|
1151
1153
|
});
|
|
1154
|
+
Object.defineProperty(exports, "VIS_TYPE_MAP", {
|
|
1155
|
+
enumerable: true,
|
|
1156
|
+
get: function () {
|
|
1157
|
+
return _visTypes.VIS_TYPE_MAP;
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1152
1160
|
Object.defineProperty(exports, "VIS_TYPE_OUTLIER_TABLE", {
|
|
1153
1161
|
enumerable: true,
|
|
1154
1162
|
get: function () {
|
|
@@ -1809,6 +1817,12 @@ Object.defineProperty(exports, "ouIdHelper", {
|
|
|
1809
1817
|
return _index7.ouIdHelper;
|
|
1810
1818
|
}
|
|
1811
1819
|
});
|
|
1820
|
+
Object.defineProperty(exports, "preparePayloadForSave", {
|
|
1821
|
+
enumerable: true,
|
|
1822
|
+
get: function () {
|
|
1823
|
+
return _utils.preparePayloadForSave;
|
|
1824
|
+
}
|
|
1825
|
+
});
|
|
1812
1826
|
Object.defineProperty(exports, "preparePayloadForSaveAs", {
|
|
1813
1827
|
enumerable: true,
|
|
1814
1828
|
get: function () {
|
|
@@ -162,6 +162,7 @@
|
|
|
162
162
|
"line list": "line list",
|
|
163
163
|
"map": "map",
|
|
164
164
|
"visualization": "visualization",
|
|
165
|
+
"Untitled {{visualizationType}}, {{date}}": "Untitled {{visualizationType}}, {{date}}",
|
|
165
166
|
"Edit": "Edit",
|
|
166
167
|
"Write a reply": "Write a reply",
|
|
167
168
|
"Post reply": "Post reply",
|
|
@@ -451,6 +452,7 @@
|
|
|
451
452
|
"Single value": "Single value",
|
|
452
453
|
"Outlier table": "Outlier table",
|
|
453
454
|
"All charts": "All charts",
|
|
455
|
+
"Map": "Map",
|
|
454
456
|
"{{seriesName}} (trend)": "{{seriesName}} (trend)",
|
|
455
457
|
"Trend": "Trend",
|
|
456
458
|
"No legend for this series": "No legend for this series",
|