@dhis2/analytics 28.0.4 → 28.0.5
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/__demo__/OpenFileDialog.stories.js +19 -1
- package/build/cjs/components/DimensionsPanel/List/DimensionList.js +3 -1
- package/build/cjs/components/DimensionsPanel/List/__tests__/DimensionItem.spec.js +48 -41
- package/build/cjs/components/DimensionsPanel/List/__tests__/__snapshots__/DimensionItem.spec.js.snap +110 -114
- package/build/cjs/components/DimensionsPanel/__tests__/DimensionsPanel.spec.js +36 -33
- package/build/cjs/components/FileMenu/__tests__/DeleteDialog.spec.js +24 -27
- package/build/cjs/components/FileMenu/__tests__/FileMenu.spec.js +51 -31
- package/build/cjs/components/FileMenu/__tests__/GetLinkDialog.spec.js +28 -31
- package/build/cjs/components/FileMenu/__tests__/RenameDialog.spec.js +17 -11
- package/build/cjs/components/FileMenu/__tests__/SaveAsDialog.spec.js +44 -37
- package/build/cjs/components/Filter/__tests__/Filter.spec.js +29 -34
- package/build/cjs/components/OpenFileDialog/CreatedByFilter.js +9 -1
- package/build/cjs/components/OpenFileDialog/OpenFileDialog.js +14 -34
- package/build/cjs/components/OpenFileDialog/VisTypeFilter.js +39 -1
- package/build/cjs/components/OpenFileDialog/__tests__/OpenFileDialog.spec.js +51 -0
- package/build/cjs/components/OrgUnitDimension/__tests__/OrgUnitDimension.spec.js +78 -44
- package/build/cjs/components/PeriodDimension/FixedPeriodFilter.js +1 -0
- package/build/cjs/components/PeriodDimension/RelativePeriodFilter.js +3 -2
- package/build/cjs/components/PeriodDimension/__tests__/FixedPeriodSingleSelect.spec.js +14 -21
- package/build/cjs/components/PeriodDimension/__tests__/PeriodDimension.spec.js +27 -23
- package/build/cjs/components/RichText/Editor/__tests__/Editor.spec.js +6 -7
- package/build/cjs/components/RichText/Parser/__tests__/MdParser.spec.js +1 -1
- package/build/cjs/components/RichText/Parser/__tests__/Parser.spec.js +22 -23
- package/build/cjs/components/Toolbar/HoverMenuBar/__tests__/HoverMenuBar.spec.js +52 -42
- package/build/cjs/components/Toolbar/HoverMenuBar/__tests__/HoverMenuDropdown.spec.js +8 -8
- package/build/cjs/components/Toolbar/HoverMenuBar/__tests__/HoverMenuList.spec.js +23 -18
- package/build/cjs/components/Toolbar/HoverMenuBar/__tests__/HoverMenuListItem.spec.js +23 -17
- package/build/cjs/components/Toolbar/HoverMenuBar/__tests__/__snapshots__/HoverMenuList.spec.js.snap +63 -0
- package/build/cjs/components/Toolbar/InterpretationsAndDetailsToggler.js +3 -1
- package/build/cjs/components/Toolbar/__tests__/InterpretationsAndDetailsToggler.spec.js +19 -18
- package/build/cjs/components/Toolbar/__tests__/Toolbar.spec.js +8 -8
- package/build/cjs/components/Toolbar/__tests__/ToolbarSidebar.spec.js +14 -11
- package/build/cjs/components/Toolbar/__tests__/UpdateButton.spec.js +16 -14
- package/build/cjs/components/TranslationDialog/TranslationModal/TranslationModal.js +2 -1
- package/build/cjs/components/TranslationDialog/TranslationModal/__tests__/TranslationModal.spec.js +25 -16
- package/build/es/__demo__/OpenFileDialog.stories.js +17 -0
- package/build/es/components/DimensionsPanel/List/DimensionList.js +3 -1
- package/build/es/components/DimensionsPanel/List/__tests__/DimensionItem.spec.js +47 -40
- package/build/es/components/DimensionsPanel/List/__tests__/__snapshots__/DimensionItem.spec.js.snap +110 -114
- package/build/es/components/DimensionsPanel/__tests__/DimensionsPanel.spec.js +35 -32
- package/build/es/components/FileMenu/__tests__/DeleteDialog.spec.js +23 -26
- package/build/es/components/FileMenu/__tests__/FileMenu.spec.js +52 -32
- package/build/es/components/FileMenu/__tests__/GetLinkDialog.spec.js +27 -30
- package/build/es/components/FileMenu/__tests__/RenameDialog.spec.js +18 -12
- package/build/es/components/FileMenu/__tests__/SaveAsDialog.spec.js +43 -36
- package/build/es/components/Filter/__tests__/Filter.spec.js +28 -33
- package/build/es/components/OpenFileDialog/CreatedByFilter.js +7 -0
- package/build/es/components/OpenFileDialog/OpenFileDialog.js +14 -35
- package/build/es/components/OpenFileDialog/VisTypeFilter.js +38 -1
- package/build/es/components/OpenFileDialog/__tests__/OpenFileDialog.spec.js +49 -0
- package/build/es/components/OrgUnitDimension/__tests__/OrgUnitDimension.spec.js +77 -43
- package/build/es/components/PeriodDimension/FixedPeriodFilter.js +1 -0
- package/build/es/components/PeriodDimension/RelativePeriodFilter.js +3 -2
- package/build/es/components/PeriodDimension/__tests__/FixedPeriodSingleSelect.spec.js +13 -20
- package/build/es/components/PeriodDimension/__tests__/PeriodDimension.spec.js +26 -22
- package/build/es/components/RichText/Editor/__tests__/Editor.spec.js +7 -8
- package/build/es/components/RichText/Parser/__tests__/MdParser.spec.js +1 -1
- package/build/es/components/RichText/Parser/__tests__/Parser.spec.js +21 -22
- package/build/es/components/Toolbar/HoverMenuBar/__tests__/HoverMenuBar.spec.js +53 -43
- package/build/es/components/Toolbar/HoverMenuBar/__tests__/HoverMenuDropdown.spec.js +7 -7
- package/build/es/components/Toolbar/HoverMenuBar/__tests__/HoverMenuList.spec.js +23 -18
- package/build/es/components/Toolbar/HoverMenuBar/__tests__/HoverMenuListItem.spec.js +21 -15
- package/build/es/components/Toolbar/HoverMenuBar/__tests__/__snapshots__/HoverMenuList.spec.js.snap +63 -0
- package/build/es/components/Toolbar/InterpretationsAndDetailsToggler.js +3 -1
- package/build/es/components/Toolbar/__tests__/InterpretationsAndDetailsToggler.spec.js +18 -17
- package/build/es/components/Toolbar/__tests__/Toolbar.spec.js +7 -7
- package/build/es/components/Toolbar/__tests__/ToolbarSidebar.spec.js +13 -10
- package/build/es/components/Toolbar/__tests__/UpdateButton.spec.js +15 -13
- package/build/es/components/TranslationDialog/TranslationModal/TranslationModal.js +2 -1
- package/build/es/components/TranslationDialog/TranslationModal/__tests__/TranslationModal.spec.js +24 -15
- package/package.json +2 -4
- package/build/cjs/components/OrgUnitDimension/__tests__/__snapshots__/OrgUnitDimension.spec.js.snap +0 -89
- package/build/cjs/components/PeriodDimension/__tests__/PeriodSelector.spec.js +0 -29
- package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/FixedPeriodSingleSelect.spec.js.snap +0 -92
- package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +0 -16
- package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +0 -89
- package/build/es/components/OrgUnitDimension/__tests__/__snapshots__/OrgUnitDimension.spec.js.snap +0 -89
- package/build/es/components/PeriodDimension/__tests__/PeriodSelector.spec.js +0 -26
- package/build/es/components/PeriodDimension/__tests__/__snapshots__/FixedPeriodSingleSelect.spec.js.snap +0 -92
- package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +0 -16
- package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +0 -89
|
@@ -5,14 +5,13 @@ import { Box, Modal, ModalTitle, ModalContent, DataTable, DataTableHead, DataTab
|
|
|
5
5
|
import isEqual from 'lodash/isEqual';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import React, { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
|
8
|
-
import {
|
|
9
|
-
import { CreatedByFilter, CREATED_BY_ALL, CREATED_BY_ALL_BUT_CURRENT_USER, CREATED_BY_CURRENT_USER } from './CreatedByFilter.js';
|
|
8
|
+
import { CreatedByFilter, formatUserFilter, CREATED_BY_ALL } from './CreatedByFilter.js';
|
|
10
9
|
import { FileList } from './FileList.js';
|
|
11
10
|
import { NameFilter } from './NameFilter.js';
|
|
12
11
|
import { styles } from './OpenFileDialog.styles.js';
|
|
13
12
|
import { PaginationControls } from './PaginationControls.js';
|
|
14
13
|
import { getTranslatedString, AOTypeMap } from './utils.js';
|
|
15
|
-
import { VisTypeFilter } from './VisTypeFilter.js';
|
|
14
|
+
import { VisTypeFilter, formatTypeFilter } from './VisTypeFilter.js';
|
|
16
15
|
const getQuery = type => ({
|
|
17
16
|
files: {
|
|
18
17
|
resource: AOTypeMap[type].apiEndpoint,
|
|
@@ -36,6 +35,15 @@ const getQuery = type => ({
|
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
});
|
|
38
|
+
export const formatFilters = (currentUser, filters, filterVisTypes) => {
|
|
39
|
+
const queryFilters = [];
|
|
40
|
+
filters.searchTerm && queryFilters.push(`identifiable:token:${filters.searchTerm}`);
|
|
41
|
+
const userFilter = formatUserFilter(filters.createdBy, currentUser.id);
|
|
42
|
+
userFilter && queryFilters.push(userFilter);
|
|
43
|
+
const typeFilter = formatTypeFilter(filterVisTypes, filters.visType);
|
|
44
|
+
typeFilter && queryFilters.push(typeFilter);
|
|
45
|
+
return queryFilters;
|
|
46
|
+
};
|
|
39
47
|
export const OpenFileDialog = ({
|
|
40
48
|
type,
|
|
41
49
|
open,
|
|
@@ -68,36 +76,7 @@ export const OpenFileDialog = ({
|
|
|
68
76
|
});
|
|
69
77
|
const [nameFilterValue, setNameFilterValue] = useState(defaultFilters.searchTerm);
|
|
70
78
|
const [searchTimeout, setSearchTimeout] = useState(null);
|
|
71
|
-
const
|
|
72
|
-
const queryFilters = [];
|
|
73
|
-
switch (filters.createdBy) {
|
|
74
|
-
case CREATED_BY_ALL_BUT_CURRENT_USER:
|
|
75
|
-
queryFilters.push(`user.id:!eq:${currentUser.id}`);
|
|
76
|
-
break;
|
|
77
|
-
case CREATED_BY_CURRENT_USER:
|
|
78
|
-
queryFilters.push(`user.id:eq:${currentUser.id}`);
|
|
79
|
-
break;
|
|
80
|
-
case CREATED_BY_ALL:
|
|
81
|
-
default:
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
if (filters.visType) {
|
|
85
|
-
switch (filters.visType) {
|
|
86
|
-
case VIS_TYPE_GROUP_ALL:
|
|
87
|
-
break;
|
|
88
|
-
case VIS_TYPE_GROUP_CHARTS:
|
|
89
|
-
queryFilters.push('type:!eq:PIVOT_TABLE');
|
|
90
|
-
break;
|
|
91
|
-
default:
|
|
92
|
-
queryFilters.push(`type:eq:${filters.visType}`);
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (filters.searchTerm) {
|
|
97
|
-
queryFilters.push(`identifiable:token:${filters.searchTerm}`);
|
|
98
|
-
}
|
|
99
|
-
return queryFilters;
|
|
100
|
-
}, [currentUser, filters]);
|
|
79
|
+
const formatFiltersCb = useCallback(() => formatFilters(currentUser, filters, filterVisTypes), [currentUser, filters, filterVisTypes]);
|
|
101
80
|
const formatSortDirection = useCallback(() => {
|
|
102
81
|
if (sortField === 'displayName' && sortDirection !== 'default') {
|
|
103
82
|
return `i${sortDirection}`;
|
|
@@ -142,10 +121,10 @@ export const OpenFileDialog = ({
|
|
|
142
121
|
page,
|
|
143
122
|
sortField,
|
|
144
123
|
sortDirection: formatSortDirection(),
|
|
145
|
-
filters:
|
|
124
|
+
filters: formatFiltersCb()
|
|
146
125
|
});
|
|
147
126
|
}
|
|
148
|
-
}, [open, page, sortField, filters, refetch,
|
|
127
|
+
}, [open, page, sortField, filters, refetch, formatFiltersCb, formatSortDirection]);
|
|
149
128
|
const headers = [{
|
|
150
129
|
field: 'displayName',
|
|
151
130
|
label: i18n.t('Name'),
|
|
@@ -2,9 +2,46 @@ import i18n from '@dhis2/d2-i18n';
|
|
|
2
2
|
import { SingleSelect, colors } from '@dhis2/ui';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import React from 'react';
|
|
5
|
-
import { getDisplayNameByVisType, visTypeIcons } from '../../modules/visTypes.js';
|
|
5
|
+
import { getDisplayNameByVisType, visTypeIcons, VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS, VIS_TYPE_PIVOT_TABLE } from '../../modules/visTypes.js';
|
|
6
6
|
import { VisTypeIcon } from '../VisTypeIcon.js';
|
|
7
7
|
import { CustomSelectOption } from './CustomSelectOption.js';
|
|
8
|
+
export const formatTypeFilter = (filterVisTypes, visType) => {
|
|
9
|
+
const defaultFilterTypes = [];
|
|
10
|
+
let defaultTypeFilter;
|
|
11
|
+
if (Array.isArray(filterVisTypes)) {
|
|
12
|
+
defaultFilterTypes.push(...filterVisTypes.filter(({
|
|
13
|
+
type,
|
|
14
|
+
disabled
|
|
15
|
+
}) => !(disabled || [VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS].includes(type))).map(({
|
|
16
|
+
type
|
|
17
|
+
}) => type));
|
|
18
|
+
if (defaultFilterTypes.length) {
|
|
19
|
+
defaultTypeFilter = `type:in:[${defaultFilterTypes.join(',')}]`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
switch (visType) {
|
|
23
|
+
case VIS_TYPE_GROUP_ALL:
|
|
24
|
+
{
|
|
25
|
+
return defaultTypeFilter;
|
|
26
|
+
}
|
|
27
|
+
case VIS_TYPE_GROUP_CHARTS:
|
|
28
|
+
{
|
|
29
|
+
if (defaultFilterTypes.length) {
|
|
30
|
+
return `type:in:[${defaultFilterTypes.filter(item => item !== VIS_TYPE_PIVOT_TABLE).join(',')}]`;
|
|
31
|
+
} else {
|
|
32
|
+
return `type:!eq:${VIS_TYPE_PIVOT_TABLE}`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
default:
|
|
36
|
+
{
|
|
37
|
+
if (visType) {
|
|
38
|
+
return `type:eq:${visType}`;
|
|
39
|
+
} else if (defaultTypeFilter) {
|
|
40
|
+
return defaultTypeFilter;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
8
45
|
export const VisTypeFilter = ({
|
|
9
46
|
visTypes,
|
|
10
47
|
selected,
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { VIS_TYPE_COLUMN, VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS, VIS_TYPE_LINE_LIST, VIS_TYPE_PIVOT_TABLE } from '../../../modules/visTypes.js';
|
|
2
|
+
import { CREATED_BY_ALL, CREATED_BY_ALL_BUT_CURRENT_USER, CREATED_BY_CURRENT_USER } from '../CreatedByFilter.js';
|
|
3
|
+
import { formatFilters } from '../OpenFileDialog.js';
|
|
4
|
+
describe('OpenFileDialog - formatFilters', () => {
|
|
5
|
+
const currentUser = {
|
|
6
|
+
id: 'test-user'
|
|
7
|
+
};
|
|
8
|
+
const createdByTestCases = [[CREATED_BY_ALL, []], [CREATED_BY_CURRENT_USER, [`user.id:eq:${currentUser.id}`]], [CREATED_BY_ALL_BUT_CURRENT_USER, [`user.id:!eq:${currentUser.id}`]]];
|
|
9
|
+
test.each(createdByTestCases)('formats the createdBy filter given %p', (createdBy, expected) => expect(formatFilters(currentUser, {
|
|
10
|
+
createdBy
|
|
11
|
+
})).toEqual(expected));
|
|
12
|
+
test('formats the searchTerm filter', () => {
|
|
13
|
+
const testSearchTerm = 'test search term';
|
|
14
|
+
expect(formatFilters(currentUser, {
|
|
15
|
+
searchTerm: testSearchTerm
|
|
16
|
+
})).toEqual([`identifiable:token:${testSearchTerm}`]);
|
|
17
|
+
});
|
|
18
|
+
const typeTestCases = [
|
|
19
|
+
// no type filter when no visType nor filterVisTypes
|
|
20
|
+
[undefined, undefined, []],
|
|
21
|
+
// no type filter because VIS_TYPE_GROUP_ALL is selected
|
|
22
|
+
[undefined, VIS_TYPE_GROUP_ALL, []],
|
|
23
|
+
// only VIS_TYPE_PIVOT_TABLE ignored because no filterVisTypes is passed and VIS_TYPE_GROUP_CHARTS is selected
|
|
24
|
+
[undefined, VIS_TYPE_GROUP_CHARTS, [`type:!eq:${VIS_TYPE_PIVOT_TABLE}`]],
|
|
25
|
+
// no filterVisTypes and VIS_TYPE_PIVOT_TABLE selected
|
|
26
|
+
[undefined, VIS_TYPE_PIVOT_TABLE, [`type:eq:${VIS_TYPE_PIVOT_TABLE}`]],
|
|
27
|
+
// group types are ignored
|
|
28
|
+
[[VIS_TYPE_PIVOT_TABLE, VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS], VIS_TYPE_GROUP_ALL, [`type:in:[${VIS_TYPE_PIVOT_TABLE}]`]],
|
|
29
|
+
// VIS_TYPE_PIVOT_TABLE is ignored because VIS_TYPE_GROUP_CHARTS is selected
|
|
30
|
+
[[VIS_TYPE_PIVOT_TABLE, VIS_TYPE_COLUMN, VIS_TYPE_GROUP_CHARTS], VIS_TYPE_GROUP_CHARTS, [`type:in:[${VIS_TYPE_COLUMN}]`]],
|
|
31
|
+
// when filterVisTypes is passed the default type filter only include those
|
|
32
|
+
[[VIS_TYPE_PIVOT_TABLE], '', [`type:in:[${VIS_TYPE_PIVOT_TABLE}]`]], [[VIS_TYPE_LINE_LIST, VIS_TYPE_PIVOT_TABLE], '', [`type:in:[${VIS_TYPE_LINE_LIST},${VIS_TYPE_PIVOT_TABLE}]`]]];
|
|
33
|
+
test.each(typeTestCases)('formats the type filter given %p and %p', (types, visType, expected) => expect(formatFilters(currentUser, {
|
|
34
|
+
visType
|
|
35
|
+
}, types === null || types === void 0 ? void 0 : types.map(type => ({
|
|
36
|
+
type
|
|
37
|
+
})))).toEqual(expected));
|
|
38
|
+
test('combined filters', () => {
|
|
39
|
+
expect(formatFilters(currentUser, {
|
|
40
|
+
createdBy: CREATED_BY_CURRENT_USER,
|
|
41
|
+
searchTerm: 'test',
|
|
42
|
+
visType: VIS_TYPE_GROUP_ALL
|
|
43
|
+
}, [{
|
|
44
|
+
type: VIS_TYPE_LINE_LIST
|
|
45
|
+
}, {
|
|
46
|
+
type: VIS_TYPE_PIVOT_TABLE
|
|
47
|
+
}])).toEqual([`identifiable:token:test`, `user.id:eq:${currentUser.id}`, `type:in:[${VIS_TYPE_LINE_LIST},${VIS_TYPE_PIVOT_TABLE}]`]);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -1,55 +1,89 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CustomDataProvider } from '@dhis2/app-runtime';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
2
4
|
import React from 'react';
|
|
3
5
|
import OrgUnitDimension from '../OrgUnitDimension.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
shallowOrgUnitDimension = shallow(/*#__PURE__*/React.createElement(OrgUnitDimension, props));
|
|
10
|
-
}
|
|
11
|
-
return shallowOrgUnitDimension;
|
|
6
|
+
jest.mock('@dhis2-ui/organisation-unit-tree', () => {
|
|
7
|
+
const lib = jest.requireActual('@dhis2-ui/organisation-unit-tree');
|
|
8
|
+
return {
|
|
9
|
+
...lib,
|
|
10
|
+
OrganisationUnitTree: () => /*#__PURE__*/React.createElement("div", null, "Org unit tree component mock")
|
|
12
11
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
});
|
|
13
|
+
describe('OrgUnitDimension', () => {
|
|
14
|
+
const onSelect = jest.fn();
|
|
15
|
+
const props = {
|
|
16
|
+
roots: [],
|
|
17
|
+
selected: [],
|
|
18
|
+
onSelect: onSelect,
|
|
19
|
+
hideGroupSelect: false,
|
|
20
|
+
hideLevelSelect: false,
|
|
21
|
+
hideUserOrgUnits: false,
|
|
22
|
+
warning: ''
|
|
23
|
+
};
|
|
24
|
+
const renderOrgUnitDimension = props => render(/*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
25
|
+
data: {
|
|
26
|
+
organisationUnitLevels: {
|
|
27
|
+
organisationUnitLevels: []
|
|
28
|
+
},
|
|
29
|
+
organisationUnitGroups: {
|
|
30
|
+
organisationUnitGroups: []
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, /*#__PURE__*/React.createElement(OrgUnitDimension, props)));
|
|
34
|
+
beforeEach(() => onSelect.mockClear());
|
|
35
|
+
test('OrgUnitDimension is rendered correctly', async () => {
|
|
36
|
+
renderOrgUnitDimension(props);
|
|
37
|
+
|
|
38
|
+
// wait for the component to be loaded, here done by testing that the OrganisationUnitTree component is loaded
|
|
39
|
+
// avoid the act warning due to the snapshot being taken before async code is run
|
|
40
|
+
await screen.findByText('Org unit tree component mock');
|
|
41
|
+
|
|
42
|
+
// the top user org unit checkboxes are rendered
|
|
43
|
+
expect(screen.getByLabelText('User organisation unit')).toBeInTheDocument();
|
|
44
|
+
expect(screen.getByLabelText('User sub-units')).toBeInTheDocument();
|
|
45
|
+
expect(screen.getByLabelText('User sub-x2-units')).toBeInTheDocument();
|
|
46
|
+
|
|
47
|
+
// the OrganisationUnitTree component is rendered
|
|
48
|
+
expect(screen.getByText('Org unit tree component mock')).toBeInTheDocument();
|
|
49
|
+
|
|
50
|
+
// the level selector is rendered
|
|
51
|
+
expect(screen.getByText('Select a level')).toBeInTheDocument();
|
|
52
|
+
|
|
53
|
+
// the group selector is rendered
|
|
54
|
+
expect(screen.getByText('Select a group')).toBeInTheDocument();
|
|
55
|
+
|
|
56
|
+
// the Deselect all button is rendered
|
|
57
|
+
expect(screen.getByRole('button', {
|
|
58
|
+
name: 'Deselect all'
|
|
59
|
+
})).toBeInTheDocument();
|
|
28
60
|
});
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
path: '/testPath',
|
|
35
|
-
displayName: 'Test Org Unit',
|
|
36
|
-
checked: true
|
|
37
|
-
};
|
|
38
|
-
orgUnitTree.props().onChange(testOrgUnit);
|
|
39
|
-
expect(props.onSelect).toHaveBeenCalledWith({
|
|
61
|
+
test('OrgUnitDimension calls onSelect when an organisation unit is selected', async () => {
|
|
62
|
+
const user = userEvent.setup();
|
|
63
|
+
renderOrgUnitDimension(props);
|
|
64
|
+
await user.click(screen.getByText('User organisation unit'));
|
|
65
|
+
expect(onSelect).toHaveBeenCalledWith({
|
|
40
66
|
dimensionId: 'ou',
|
|
41
67
|
items: [{
|
|
42
|
-
id: '
|
|
43
|
-
|
|
44
|
-
name: 'Test Org Unit'
|
|
68
|
+
id: 'USER_ORGUNIT',
|
|
69
|
+
displayName: 'User organisation unit'
|
|
45
70
|
}]
|
|
46
71
|
});
|
|
47
72
|
});
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
73
|
+
test('OrgUnitDimension calls onSelect with an empty array when selection is cleared', async () => {
|
|
74
|
+
const user = userEvent.setup();
|
|
75
|
+
renderOrgUnitDimension({
|
|
76
|
+
...props,
|
|
77
|
+
// make some selection to enable the deselect all button
|
|
78
|
+
selected: [{
|
|
79
|
+
id: 'USER_ORGUNIT_CHILDREN',
|
|
80
|
+
name: 'User sub-units'
|
|
81
|
+
}]
|
|
82
|
+
});
|
|
83
|
+
await user.click(screen.getByRole('button', {
|
|
84
|
+
name: 'Deselect all'
|
|
85
|
+
}));
|
|
86
|
+
expect(onSelect).toHaveBeenLastCalledWith({
|
|
53
87
|
dimensionId: 'ou',
|
|
54
88
|
items: []
|
|
55
89
|
});
|
|
@@ -18,6 +18,7 @@ const FixedPeriodFilter = ({
|
|
|
18
18
|
}) => {
|
|
19
19
|
const onlyAllowedTypeIsSelected = Array.isArray(allowedPeriodTypes) && allowedPeriodTypes.length === 1 && allowedPeriodTypes[0] === currentPeriodType;
|
|
20
20
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
21
|
+
"data-test": dataTest,
|
|
21
22
|
className: `jsx-${styles.__hash}` + " " + "leftSection"
|
|
22
23
|
}, /*#__PURE__*/React.createElement(SingleSelectField, {
|
|
23
24
|
label: i18n.t('Period type'),
|
|
@@ -12,6 +12,7 @@ const RelativePeriodFilter = ({
|
|
|
12
12
|
dataTest,
|
|
13
13
|
excludedPeriodTypes
|
|
14
14
|
}) => /*#__PURE__*/React.createElement("div", {
|
|
15
|
+
"data-test": dataTest,
|
|
15
16
|
className: `jsx-${styles.__hash}` + " " + "leftSection"
|
|
16
17
|
}, /*#__PURE__*/React.createElement(SingleSelectField, {
|
|
17
18
|
label: i18n.t('Period type'),
|
|
@@ -21,12 +22,12 @@ const RelativePeriodFilter = ({
|
|
|
21
22
|
dense: true,
|
|
22
23
|
selected: currentFilter,
|
|
23
24
|
className: "filterElement",
|
|
24
|
-
dataTest: dataTest
|
|
25
|
+
dataTest: `${dataTest}-period-type`
|
|
25
26
|
}, filterPeriodTypesById(getRelativePeriodsOptions(), excludedPeriodTypes).map(option => /*#__PURE__*/React.createElement(SingleSelectOption, {
|
|
26
27
|
key: option.id,
|
|
27
28
|
value: option.id,
|
|
28
29
|
label: option.name,
|
|
29
|
-
dataTest: `${dataTest}-option-${option.id}`
|
|
30
|
+
dataTest: `${dataTest}-period-type-option-${option.id}`
|
|
30
31
|
}))), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
31
32
|
id: styles.__hash
|
|
32
33
|
}, styles));
|
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import FixedPeriodSelect from '../FixedPeriodSelect.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (!shallowFixedPeriodSelect) {
|
|
9
|
-
shallowFixedPeriodSelect = shallow(/*#__PURE__*/React.createElement(FixedPeriodSelect, props));
|
|
10
|
-
}
|
|
11
|
-
return shallowFixedPeriodSelect;
|
|
4
|
+
test('FixedPeriodSelect renders correctly', () => {
|
|
5
|
+
const props = {
|
|
6
|
+
value: '201405',
|
|
7
|
+
onChange: () => {}
|
|
12
8
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const wrapper = getWrapper();
|
|
22
|
-
expect(wrapper).toMatchSnapshot();
|
|
23
|
-
});
|
|
9
|
+
render(/*#__PURE__*/React.createElement(FixedPeriodSelect, props));
|
|
10
|
+
expect(screen.getByTestId('dhis2-analytics-fixedperiodselect')).toBeInTheDocument();
|
|
11
|
+
expect(screen.getByText('Period type')).toBeInTheDocument();
|
|
12
|
+
expect(screen.getByText('Monthly')).toBeInTheDocument();
|
|
13
|
+
expect(screen.getByText('Year')).toBeInTheDocument();
|
|
14
|
+
const yearSelectEl = screen.getByPlaceholderText('Select year');
|
|
15
|
+
expect(yearSelectEl).toBeInTheDocument();
|
|
16
|
+
expect(yearSelectEl.value).toEqual('2014');
|
|
24
17
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import PeriodDimension from '../PeriodDimension.js';
|
|
4
5
|
jest.mock('@dhis2/app-runtime', () => ({
|
|
@@ -13,26 +14,29 @@ jest.mock('@dhis2/app-runtime', () => ({
|
|
|
13
14
|
}
|
|
14
15
|
})
|
|
15
16
|
}));
|
|
17
|
+
global.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
18
|
+
observe: jest.fn(),
|
|
19
|
+
unobserve: jest.fn(),
|
|
20
|
+
disconnect: jest.fn()
|
|
21
|
+
}));
|
|
16
22
|
afterEach(jest.clearAllMocks);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
expect(wrapper).toMatchSnapshot();
|
|
37
|
-
});
|
|
23
|
+
const props = {
|
|
24
|
+
selectedPeriods: [],
|
|
25
|
+
onSelect: jest.fn(),
|
|
26
|
+
rightFooter: /*#__PURE__*/React.createElement(React.Fragment, null)
|
|
27
|
+
};
|
|
28
|
+
test('PeriodDimension renders the tabs for relative/fixed with relative pre-selected', () => {
|
|
29
|
+
render(/*#__PURE__*/React.createElement(PeriodDimension, props));
|
|
30
|
+
expect(screen.getByText('Relative periods')).toBeInTheDocument();
|
|
31
|
+
expect(screen.getByTestId('period-dimension-relative-period-filter')).toBeInTheDocument();
|
|
32
|
+
expect(screen.getByText('Fixed periods')).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
test('PeriodDimension can toggle between relative and fixed period tab', async () => {
|
|
35
|
+
const user = userEvent.setup();
|
|
36
|
+
render(/*#__PURE__*/React.createElement(PeriodDimension, props));
|
|
37
|
+
expect(screen.getByText('Relative periods')).toBeInTheDocument();
|
|
38
|
+
const fixedPeriodButton = screen.getByText('Fixed periods');
|
|
39
|
+
expect(fixedPeriodButton).toBeInTheDocument();
|
|
40
|
+
await user.click(fixedPeriodButton);
|
|
41
|
+
expect(screen.getByTestId('period-dimension-fixed-period-filter')).toBeInTheDocument();
|
|
38
42
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import '@testing-library/
|
|
2
|
-
import
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Editor } from '../Editor.js';
|
|
5
5
|
const mockConvertCtrlKey = jest.fn();
|
|
@@ -20,16 +20,15 @@ describe('RichText: Editor component', () => {
|
|
|
20
20
|
const renderComponent = props => {
|
|
21
21
|
return render(/*#__PURE__*/React.createElement(Editor, props));
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
test('renders a result', () => {
|
|
24
24
|
renderComponent(componentProps);
|
|
25
25
|
expect(screen.getByTestId('@dhis2-analytics-richtexteditor')).toBeVisible();
|
|
26
26
|
});
|
|
27
|
-
|
|
27
|
+
test('calls convertCtrlKey on keydown', async () => {
|
|
28
|
+
const user = userEvent.setup();
|
|
28
29
|
renderComponent(componentProps);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
code: 'keyA'
|
|
32
|
-
});
|
|
30
|
+
await user.click(screen.getByRole('textbox'));
|
|
31
|
+
await user.keyboard('A');
|
|
33
32
|
expect(mockConvertCtrlKey).toHaveBeenCalled();
|
|
34
33
|
});
|
|
35
34
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MdParser } from '../MdParser.js';
|
|
2
2
|
const Parser = new MdParser();
|
|
3
3
|
describe('MdParser class', () => {
|
|
4
|
-
|
|
4
|
+
test('converts text into HTML', () => {
|
|
5
5
|
const inlineTests = [['_italic_', '<em>italic</em>'], ['*bold*', '<strong>bold</strong>'], ['_ not italic because there is a space _', '_ not italic because there is a space _'], [':-)', '<span>\u{1F642}</span>'], [':)', '<span>\u{1F642}</span>'], [':-(', '<span>\u{1F641}</span>'], [':(', '<span>\u{1F641}</span>'], [':+1', '<span>\u{1F44D}</span>'], [':-1', '<span>\u{1F44E}</span>'], ['mixed _italic_ *bold* and :+1', 'mixed <em>italic</em> <strong>bold</strong> and <span>\u{1F44D}</span>'], ['_italic with * inside_', '<em>italic with * inside</em>'], ['*bold with _ inside*', '<strong>bold with _ inside</strong>'],
|
|
6
6
|
// italic marker followed by : should work
|
|
7
7
|
['_italic_:', '<em>italic</em>:'], ['_italic_: some text, *bold*: some other text', '<em>italic</em>: some text, <strong>bold</strong>: some other text'],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Parser } from '../Parser.js';
|
|
4
4
|
jest.mock('../MdParser.js', () => ({
|
|
@@ -9,30 +9,29 @@ jest.mock('../MdParser.js', () => ({
|
|
|
9
9
|
})
|
|
10
10
|
}));
|
|
11
11
|
describe('RichText: Parser component', () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
style: {
|
|
12
|
+
test('should have rendered a result with the style prop', () => {
|
|
13
|
+
const style = {
|
|
15
14
|
color: 'blue',
|
|
16
15
|
whiteSpace: 'pre-line'
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
expect(
|
|
25
|
-
|
|
26
|
-
it('should have rendered a result with the style prop', () => {
|
|
27
|
-
richTextParser = renderComponent(defaultProps, 'test prop');
|
|
28
|
-
expect(richTextParser.props().style).toEqual(defaultProps.style);
|
|
16
|
+
};
|
|
17
|
+
const {
|
|
18
|
+
container
|
|
19
|
+
} = render(/*#__PURE__*/React.createElement(Parser, {
|
|
20
|
+
style: style
|
|
21
|
+
}, 'test prop'));
|
|
22
|
+
const divEl = container.querySelector('div');
|
|
23
|
+
expect(divEl.style.color).toBe(style.color);
|
|
24
|
+
expect(divEl.style.whiteSpace).toBe(style.whiteSpace);
|
|
29
25
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
expect(
|
|
26
|
+
test('should have rendered content', () => {
|
|
27
|
+
render(/*#__PURE__*/React.createElement(Parser, null, 'plain text'));
|
|
28
|
+
expect(screen.getByText('converted text')).toBeInTheDocument();
|
|
33
29
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
test('should return null if no children is passed', () => {
|
|
31
|
+
const {
|
|
32
|
+
container
|
|
33
|
+
} = render(/*#__PURE__*/React.createElement(Parser, null));
|
|
34
|
+
const divEl = container.querySelector('div');
|
|
35
|
+
expect(divEl).toBe(null);
|
|
37
36
|
});
|
|
38
37
|
});
|