@dhis2/analytics 26.4.0 → 26.5.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/__fixtures__/fixtures.js +1 -0
- package/build/cjs/__fixtures__/json/api/analytics/outlierDetection.json +213 -0
- package/build/cjs/api/analytics/AnalyticsAggregate.js +27 -1
- package/build/cjs/api/analytics/AnalyticsBase.js +8 -7
- package/build/cjs/api/analytics/AnalyticsRequestBase.js +9 -5
- package/build/cjs/api/analytics/AnalyticsResponse.js +42 -39
- package/build/cjs/api/analytics/__tests__/Analytics.spec.js +5 -0
- package/build/cjs/api/analytics/__tests__/AnalyticsAggregate.spec.js +29 -0
- package/build/cjs/api/analytics/__tests__/AnalyticsBase.spec.js +36 -2
- package/build/cjs/components/DataDimension/DataDimension.js +31 -7
- package/build/cjs/components/DataDimension/DataTypeSelector.js +29 -8
- package/build/cjs/components/DataDimension/GroupSelector.js +7 -7
- package/build/cjs/components/DataDimension/ItemSelector.js +79 -61
- package/build/cjs/components/Interpretations/InterpretationModal/InterpretationModal.js +13 -4
- package/build/cjs/components/Interpretations/InterpretationModal/InterpretationThread.js +3 -0
- package/build/cjs/components/Interpretations/InterpretationsUnit/InterpretationList.js +3 -0
- package/build/cjs/components/Interpretations/InterpretationsUnit/InterpretationsUnit.js +15 -4
- package/build/cjs/components/Interpretations/common/Interpretation/Interpretation.js +7 -2
- package/build/cjs/components/Interpretations/common/Interpretation/useLike.js +12 -2
- package/build/cjs/components/PeriodDimension/PeriodDimension.js +5 -2
- package/build/cjs/components/PeriodDimension/PeriodTransfer.js +64 -31
- package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +1 -1
- package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +1 -12
- package/build/cjs/components/VisTypeIcon.js +6 -1
- package/build/cjs/index.js +43 -1
- package/build/cjs/locales/en/translations.json +5 -1
- package/build/cjs/modules/__tests__/getAdaptedUiLayoutByType.spec.js +15 -0
- package/build/cjs/modules/axis.js +4 -0
- package/build/cjs/modules/getAdaptedUiLayoutByType.js +9 -0
- package/build/cjs/modules/layoutTypes.js +4 -2
- package/build/cjs/modules/layoutUiRules/__tests__/rules.spec.js +13 -1
- package/build/cjs/modules/layoutUiRules/index.js +12 -0
- package/build/cjs/modules/layoutUiRules/rules.js +22 -2
- package/build/cjs/modules/layoutUiRules/rulesHelper.js +4 -2
- package/build/cjs/modules/layoutUiRules/rulesUtils.js +7 -2
- package/build/cjs/modules/visTypeToLayoutType.js +2 -1
- package/build/cjs/modules/visTypes.js +9 -3
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/subtitle/index.js +3 -2
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/title/index.js +3 -2
- package/build/es/__fixtures__/fixtures.js +1 -0
- package/build/es/__fixtures__/json/api/analytics/outlierDetection.json +213 -0
- package/build/es/api/analytics/AnalyticsAggregate.js +27 -1
- package/build/es/api/analytics/AnalyticsBase.js +7 -7
- package/build/es/api/analytics/AnalyticsRequestBase.js +9 -5
- package/build/es/api/analytics/AnalyticsResponse.js +42 -39
- package/build/es/api/analytics/__tests__/Analytics.spec.js +5 -0
- package/build/es/api/analytics/__tests__/AnalyticsAggregate.spec.js +29 -0
- package/build/es/api/analytics/__tests__/AnalyticsBase.spec.js +34 -1
- package/build/es/components/DataDimension/DataDimension.js +27 -6
- package/build/es/components/DataDimension/DataTypeSelector.js +30 -9
- package/build/es/components/DataDimension/GroupSelector.js +7 -7
- package/build/es/components/DataDimension/ItemSelector.js +80 -62
- package/build/es/components/Interpretations/InterpretationModal/InterpretationModal.js +13 -4
- package/build/es/components/Interpretations/InterpretationModal/InterpretationThread.js +3 -0
- package/build/es/components/Interpretations/InterpretationsUnit/InterpretationList.js +3 -0
- package/build/es/components/Interpretations/InterpretationsUnit/InterpretationsUnit.js +15 -4
- package/build/es/components/Interpretations/common/Interpretation/Interpretation.js +7 -2
- package/build/es/components/Interpretations/common/Interpretation/useLike.js +12 -2
- package/build/es/components/PeriodDimension/PeriodDimension.js +5 -2
- package/build/es/components/PeriodDimension/PeriodTransfer.js +65 -32
- package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +1 -1
- package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +1 -12
- package/build/es/components/VisTypeIcon.js +8 -3
- package/build/es/index.js +4 -4
- package/build/es/locales/en/translations.json +5 -1
- package/build/es/modules/__tests__/getAdaptedUiLayoutByType.spec.js +16 -1
- package/build/es/modules/axis.js +5 -1
- package/build/es/modules/getAdaptedUiLayoutByType.js +10 -1
- package/build/es/modules/layoutTypes.js +2 -1
- package/build/es/modules/layoutUiRules/__tests__/rules.spec.js +14 -2
- package/build/es/modules/layoutUiRules/index.js +2 -2
- package/build/es/modules/layoutUiRules/rules.js +22 -3
- package/build/es/modules/layoutUiRules/rulesHelper.js +3 -2
- package/build/es/modules/layoutUiRules/rulesUtils.js +6 -2
- package/build/es/modules/visTypeToLayoutType.js +4 -3
- package/build/es/modules/visTypes.js +7 -3
- package/build/es/visualizations/config/adapters/dhis_highcharts/subtitle/index.js +3 -2
- package/build/es/visualizations/config/adapters/dhis_highcharts/title/index.js +3 -2
- package/package.json +6 -3
|
@@ -16,7 +16,8 @@ export const Interpretation = _ref => {
|
|
|
16
16
|
disabled,
|
|
17
17
|
onReplyIconClick,
|
|
18
18
|
dashboardRedirectUrl,
|
|
19
|
-
isInThread
|
|
19
|
+
isInThread,
|
|
20
|
+
onLikeToggled
|
|
20
21
|
} = _ref;
|
|
21
22
|
const [isUpdateMode, setIsUpdateMode] = useState(false);
|
|
22
23
|
const [showSharingDialog, setShowSharingDialog] = useState(false);
|
|
@@ -27,7 +28,10 @@ export const Interpretation = _ref => {
|
|
|
27
28
|
} = useLike({
|
|
28
29
|
interpretation,
|
|
29
30
|
currentUser,
|
|
30
|
-
onComplete:
|
|
31
|
+
onComplete: likedBy => onLikeToggled({
|
|
32
|
+
id: interpretation.id,
|
|
33
|
+
likedBy
|
|
34
|
+
})
|
|
31
35
|
});
|
|
32
36
|
const shouldShowButton = Boolean(!!onClick && !disabled & !dashboardRedirectUrl);
|
|
33
37
|
const interpretationAccess = getInterpretationAccess(interpretation, currentUser);
|
|
@@ -113,6 +117,7 @@ Interpretation.propTypes = {
|
|
|
113
117
|
currentUser: PropTypes.object.isRequired,
|
|
114
118
|
interpretation: PropTypes.object.isRequired,
|
|
115
119
|
onDeleted: PropTypes.func.isRequired,
|
|
120
|
+
onLikeToggled: PropTypes.func.isRequired,
|
|
116
121
|
onReplyIconClick: PropTypes.func.isRequired,
|
|
117
122
|
onUpdated: PropTypes.func.isRequired,
|
|
118
123
|
dashboardRedirectUrl: PropTypes.string,
|
|
@@ -18,12 +18,22 @@ const useLike = _ref => {
|
|
|
18
18
|
const [like, {
|
|
19
19
|
loading: likeLoading
|
|
20
20
|
}] = useDataMutation(likeMutationRef.current, {
|
|
21
|
-
onComplete
|
|
21
|
+
onComplete: () => {
|
|
22
|
+
const newLikedBy = interpretation.likedBy.concat({
|
|
23
|
+
id: currentUser.id
|
|
24
|
+
});
|
|
25
|
+
setIsLikedByCurrentUser(true);
|
|
26
|
+
onComplete(newLikedBy);
|
|
27
|
+
}
|
|
22
28
|
});
|
|
23
29
|
const [unlike, {
|
|
24
30
|
loading: unlikeLoading
|
|
25
31
|
}] = useDataMutation(unlikeMutationRef.current, {
|
|
26
|
-
onComplete
|
|
32
|
+
onComplete: () => {
|
|
33
|
+
const newLikedBy = interpretation.likedBy.filter(lb => lb.id !== currentUser.id);
|
|
34
|
+
setIsLikedByCurrentUser(false);
|
|
35
|
+
onComplete(newLikedBy);
|
|
36
|
+
}
|
|
27
37
|
});
|
|
28
38
|
const [isLikedByCurrentUser, setIsLikedByCurrentUser] = useState(false);
|
|
29
39
|
const toggleLike = () => {
|
|
@@ -16,7 +16,8 @@ const PeriodDimension = _ref => {
|
|
|
16
16
|
onSelect,
|
|
17
17
|
selectedPeriods,
|
|
18
18
|
rightFooter,
|
|
19
|
-
excludedPeriodTypes
|
|
19
|
+
excludedPeriodTypes,
|
|
20
|
+
infoBoxMessage
|
|
20
21
|
} = _ref;
|
|
21
22
|
const {
|
|
22
23
|
systemInfo
|
|
@@ -44,7 +45,8 @@ const PeriodDimension = _ref => {
|
|
|
44
45
|
};
|
|
45
46
|
return /*#__PURE__*/React.createElement(PeriodTransfer, {
|
|
46
47
|
onSelect: selectPeriods,
|
|
47
|
-
|
|
48
|
+
selectedItems: selectedPeriods,
|
|
49
|
+
infoBoxMessage: infoBoxMessage,
|
|
48
50
|
rightFooter: rightFooter,
|
|
49
51
|
dataTest: 'period-dimension',
|
|
50
52
|
excludedPeriodTypes: excludedPeriodTypes,
|
|
@@ -54,6 +56,7 @@ const PeriodDimension = _ref => {
|
|
|
54
56
|
PeriodDimension.propTypes = {
|
|
55
57
|
onSelect: PropTypes.func.isRequired,
|
|
56
58
|
excludedPeriodTypes: PropTypes.arrayOf(PropTypes.string),
|
|
59
|
+
infoBoxMessage: PropTypes.string,
|
|
57
60
|
rightFooter: PropTypes.node,
|
|
58
61
|
selectedPeriods: PropTypes.array
|
|
59
62
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _JSXStyle from "styled-jsx/style";
|
|
2
2
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
3
3
|
import { getNowInCalendar } from '@dhis2/multi-calendar-dates';
|
|
4
|
-
import { TabBar, Tab, Transfer } from '@dhis2/ui';
|
|
4
|
+
import { IconInfo16, TabBar, Tab, Transfer } from '@dhis2/ui';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import React, { useState } from 'react';
|
|
7
7
|
import PeriodIcon from '../../assets/DimensionItemIcons/PeriodIcon.js'; //TODO: Reimplement the icon.js
|
|
@@ -14,15 +14,35 @@ import RelativePeriodFilter from './RelativePeriodFilter.js';
|
|
|
14
14
|
import { getFixedPeriodsOptionsById } from './utils/fixedPeriods.js';
|
|
15
15
|
import { MONTHLY, QUARTERLY } from './utils/index.js';
|
|
16
16
|
import { getRelativePeriodsOptionsById } from './utils/relativePeriods.js';
|
|
17
|
-
const
|
|
17
|
+
const RightHeader = _ref => {
|
|
18
|
+
let {
|
|
19
|
+
infoBoxMessage
|
|
20
|
+
} = _ref;
|
|
21
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
|
|
22
|
+
className: `jsx-${styles.__hash}` + " " + "rightHeader"
|
|
23
|
+
}, i18n.t('Selected Periods')), infoBoxMessage && /*#__PURE__*/React.createElement("div", {
|
|
24
|
+
className: `jsx-${styles.__hash}` + " " + "info-container"
|
|
25
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
26
|
+
className: `jsx-${styles.__hash}`
|
|
27
|
+
}, /*#__PURE__*/React.createElement(IconInfo16, null)), /*#__PURE__*/React.createElement("span", {
|
|
28
|
+
className: `jsx-${styles.__hash}` + " " + "info-text"
|
|
29
|
+
}, infoBoxMessage)), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
30
|
+
id: styles.__hash
|
|
31
|
+
}, styles));
|
|
32
|
+
};
|
|
33
|
+
RightHeader.propTypes = {
|
|
34
|
+
infoBoxMessage: PropTypes.string
|
|
35
|
+
};
|
|
36
|
+
const PeriodTransfer = _ref2 => {
|
|
18
37
|
let {
|
|
19
38
|
onSelect,
|
|
20
39
|
dataTest,
|
|
21
|
-
|
|
40
|
+
selectedItems,
|
|
22
41
|
rightFooter,
|
|
23
42
|
excludedPeriodTypes,
|
|
24
|
-
periodsSettings
|
|
25
|
-
|
|
43
|
+
periodsSettings,
|
|
44
|
+
infoBoxMessage
|
|
45
|
+
} = _ref2;
|
|
26
46
|
const defaultRelativePeriodType = excludedPeriodTypes.includes(MONTHLY) ? getRelativePeriodsOptionsById(QUARTERLY) : getRelativePeriodsOptionsById(MONTHLY);
|
|
27
47
|
const defaultFixedPeriodType = excludedPeriodTypes.includes(MONTHLY) ? getFixedPeriodsOptionsById(QUARTERLY, periodsSettings) : getFixedPeriodsOptionsById(MONTHLY, periodsSettings);
|
|
28
48
|
const now = getNowInCalendar(periodsSettings.calendar);
|
|
@@ -35,7 +55,6 @@ const PeriodTransfer = _ref => {
|
|
|
35
55
|
reversePeriods: false
|
|
36
56
|
});
|
|
37
57
|
const [allPeriods, setAllPeriods] = useState(defaultRelativePeriodType.getPeriods());
|
|
38
|
-
const [selectedPeriods, setSelectedPeriods] = useState(initialSelectedPeriods);
|
|
39
58
|
const [isRelative, setIsRelative] = useState(true);
|
|
40
59
|
const [relativeFilter, setRelativeFilter] = useState({
|
|
41
60
|
periodType: defaultRelativePeriodType.id
|
|
@@ -44,6 +63,10 @@ const PeriodTransfer = _ref => {
|
|
|
44
63
|
periodType: defaultFixedPeriodType.id,
|
|
45
64
|
year: defaultFixedPeriodYear.toString()
|
|
46
65
|
});
|
|
66
|
+
const isActive = value => {
|
|
67
|
+
const item = selectedItems.find(item => item.id === value);
|
|
68
|
+
return !item || item.isActive;
|
|
69
|
+
};
|
|
47
70
|
const onIsRelativeClick = state => {
|
|
48
71
|
if (state !== isRelative) {
|
|
49
72
|
setIsRelative(state);
|
|
@@ -90,11 +113,6 @@ const PeriodTransfer = _ref => {
|
|
|
90
113
|
})), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
91
114
|
id: styles.__hash
|
|
92
115
|
}, styles));
|
|
93
|
-
const renderRightHeader = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
|
|
94
|
-
className: `jsx-${styles.__hash}` + " " + "rightHeader"
|
|
95
|
-
}, i18n.t('Selected Periods')), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
96
|
-
id: styles.__hash
|
|
97
|
-
}, styles));
|
|
98
116
|
const onSelectFixedPeriods = filter => {
|
|
99
117
|
setFixedFilter(filter);
|
|
100
118
|
setAllPeriods(getFixedPeriodsOptionsById(filter.periodType, periodsSettings).getPeriods(fixedPeriodConfig(Number(filter.year)), periodsSettings));
|
|
@@ -105,45 +123,58 @@ const PeriodTransfer = _ref => {
|
|
|
105
123
|
id: styles.__hash
|
|
106
124
|
}, styles));
|
|
107
125
|
return /*#__PURE__*/React.createElement(Transfer, {
|
|
108
|
-
onChange:
|
|
126
|
+
onChange: _ref3 => {
|
|
109
127
|
let {
|
|
110
128
|
selected
|
|
111
|
-
} =
|
|
112
|
-
const formattedItems = selected.map(id =>
|
|
113
|
-
id
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
129
|
+
} = _ref3;
|
|
130
|
+
const formattedItems = selected.map(id => {
|
|
131
|
+
const matchingItem = [...allPeriods, ...selectedItems].find(item => item.id === id);
|
|
132
|
+
return {
|
|
133
|
+
id,
|
|
134
|
+
name: matchingItem.name,
|
|
135
|
+
isActive: matchingItem.isActive
|
|
136
|
+
};
|
|
137
|
+
});
|
|
117
138
|
onSelect(formattedItems);
|
|
118
139
|
},
|
|
119
|
-
selected:
|
|
140
|
+
selected: selectedItems.map(period => period.id),
|
|
120
141
|
leftHeader: renderLeftHeader(),
|
|
121
142
|
enableOrderChange: true,
|
|
122
143
|
height: TRANSFER_HEIGHT,
|
|
123
144
|
optionsWidth: TRANSFER_OPTIONS_WIDTH,
|
|
124
145
|
selectedWidth: TRANSFER_SELECTED_WIDTH,
|
|
125
146
|
selectedEmptyComponent: renderEmptySelection(),
|
|
126
|
-
rightHeader:
|
|
147
|
+
rightHeader: /*#__PURE__*/React.createElement(RightHeader, {
|
|
148
|
+
infoBoxMessage: infoBoxMessage
|
|
149
|
+
}),
|
|
127
150
|
rightFooter: rightFooter,
|
|
128
|
-
options: [...allPeriods, ...
|
|
151
|
+
options: [...allPeriods, ...selectedItems].map(_ref4 => {
|
|
129
152
|
let {
|
|
130
153
|
id,
|
|
131
154
|
name
|
|
132
|
-
} =
|
|
155
|
+
} = _ref4;
|
|
133
156
|
return {
|
|
134
157
|
label: name,
|
|
135
158
|
value: id
|
|
136
159
|
};
|
|
137
160
|
}),
|
|
138
|
-
renderOption:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
161
|
+
renderOption: _ref5 => {
|
|
162
|
+
let {
|
|
163
|
+
value,
|
|
164
|
+
...props
|
|
165
|
+
} = _ref5;
|
|
166
|
+
return /*#__PURE__*/React.createElement(TransferOption, _extends({}, props, {
|
|
167
|
+
value: value,
|
|
168
|
+
active: isActive(value),
|
|
169
|
+
icon: PeriodIcon,
|
|
170
|
+
dataTest: `${dataTest}-transfer-option`
|
|
171
|
+
}));
|
|
172
|
+
},
|
|
142
173
|
dataTest: `${dataTest}-transfer`
|
|
143
174
|
});
|
|
144
175
|
};
|
|
145
176
|
PeriodTransfer.defaultProps = {
|
|
146
|
-
|
|
177
|
+
selectedItems: [],
|
|
147
178
|
excludedPeriodTypes: [],
|
|
148
179
|
periodsSettings: {
|
|
149
180
|
calendar: 'gregory',
|
|
@@ -154,14 +185,16 @@ PeriodTransfer.propTypes = {
|
|
|
154
185
|
onSelect: PropTypes.func.isRequired,
|
|
155
186
|
dataTest: PropTypes.string,
|
|
156
187
|
excludedPeriodTypes: PropTypes.arrayOf(PropTypes.string),
|
|
157
|
-
|
|
158
|
-
id: PropTypes.string,
|
|
159
|
-
name: PropTypes.string
|
|
160
|
-
})),
|
|
188
|
+
infoBoxMessage: PropTypes.string,
|
|
161
189
|
periodsSettings: PropTypes.shape({
|
|
162
190
|
calendar: PropTypes.string,
|
|
163
191
|
locale: PropTypes.string
|
|
164
192
|
}),
|
|
165
|
-
rightFooter: PropTypes.node
|
|
193
|
+
rightFooter: PropTypes.node,
|
|
194
|
+
selectedItems: PropTypes.arrayOf(PropTypes.shape({
|
|
195
|
+
id: PropTypes.string,
|
|
196
|
+
isActive: PropTypes.bool,
|
|
197
|
+
name: PropTypes.string
|
|
198
|
+
}))
|
|
166
199
|
};
|
|
167
200
|
export default PeriodTransfer;
|
package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap
CHANGED
|
@@ -4,7 +4,6 @@ exports[`The Period Dimension component matches the snapshot 1`] = `
|
|
|
4
4
|
<PeriodTransfer
|
|
5
5
|
dataTest="period-dimension"
|
|
6
6
|
excludedPeriodTypes={Array []}
|
|
7
|
-
initialSelectedPeriods={Array []}
|
|
8
7
|
onSelect={[Function]}
|
|
9
8
|
periodsSettings={
|
|
10
9
|
Object {
|
|
@@ -13,5 +12,6 @@ exports[`The Period Dimension component matches the snapshot 1`] = `
|
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
rightFooter={<React.Fragment />}
|
|
15
|
+
selectedItems={Array []}
|
|
16
16
|
/>
|
|
17
17
|
`;
|
package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap
CHANGED
|
@@ -77,18 +77,7 @@ exports[`The Period Selector component matches the snapshot 1`] = `
|
|
|
77
77
|
optionsWidth="420px"
|
|
78
78
|
renderOption={[Function]}
|
|
79
79
|
rightFooter={<React.Fragment />}
|
|
80
|
-
rightHeader={
|
|
81
|
-
<React.Fragment>
|
|
82
|
-
<p
|
|
83
|
-
className="rightHeader"
|
|
84
|
-
>
|
|
85
|
-
Selected Periods
|
|
86
|
-
</p>
|
|
87
|
-
<style>
|
|
88
|
-
|
|
89
|
-
</style>
|
|
90
|
-
</React.Fragment>
|
|
91
|
-
}
|
|
80
|
+
rightHeader={<RightHeader />}
|
|
92
81
|
selected={Array []}
|
|
93
82
|
selectedEmptyComponent={
|
|
94
83
|
<React.Fragment>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IconVisualizationArea16, IconVisualizationAreaStacked16, IconVisualizationBar16, IconVisualizationBarStacked16, IconVisualizationColumn16, IconVisualizationColumnMulti16, IconVisualizationColumnStacked16, IconVisualizationGauge16, IconVisualizationLine16, IconVisualizationLinelist16, IconVisualizationLineMulti16, IconVisualizationOutlierTable16, IconVisualizationPie16, IconVisualizationPivotTable16, IconVisualizationRadar16, IconVisualizationScatter16, IconVisualizationSingleValue16, IconVisualizationArea24, IconVisualizationAreaStacked24, IconVisualizationBar24, IconVisualizationBarStacked24, IconVisualizationColumn24, IconVisualizationLinelist24, IconVisualizationColumnMulti24, IconVisualizationColumnStacked24, IconVisualizationGauge24, IconVisualizationLine24, IconVisualizationLineMulti24, IconVisualizationOutlierTable24, IconVisualizationPie24, IconVisualizationPivotTable24, IconVisualizationRadar24, IconVisualizationScatter24, IconVisualizationSingleValue24 } from '@dhis2/ui';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { VIS_TYPE_LINE_LIST, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_SCATTER } from '../modules/visTypes.js';
|
|
4
|
+
import { VIS_TYPE_LINE_LIST, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_SCATTER, VIS_TYPE_OUTLIER_TABLE } from '../modules/visTypes.js';
|
|
5
5
|
export const VisTypeIcon = _ref => {
|
|
6
6
|
let {
|
|
7
7
|
type,
|
|
@@ -17,7 +17,7 @@ export const VisTypeIcon = _ref => {
|
|
|
17
17
|
}
|
|
18
18
|
case VIS_TYPE_PIVOT_TABLE:
|
|
19
19
|
{
|
|
20
|
-
VisIcon = useSmall ?
|
|
20
|
+
VisIcon = useSmall ? IconVisualizationPivotTable16 : IconVisualizationPivotTable24;
|
|
21
21
|
break;
|
|
22
22
|
}
|
|
23
23
|
case VIS_TYPE_BAR:
|
|
@@ -85,6 +85,11 @@ export const VisTypeIcon = _ref => {
|
|
|
85
85
|
VisIcon = useSmall ? IconVisualizationScatter16 : IconVisualizationScatter24;
|
|
86
86
|
break;
|
|
87
87
|
}
|
|
88
|
+
case VIS_TYPE_OUTLIER_TABLE:
|
|
89
|
+
{
|
|
90
|
+
VisIcon = useSmall ? IconVisualizationOutlierTable16 : IconVisualizationOutlierTable24;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
88
93
|
case VIS_TYPE_COLUMN:
|
|
89
94
|
default:
|
|
90
95
|
{
|
package/build/es/index.js
CHANGED
|
@@ -97,15 +97,15 @@ export { getLayoutTypeByVisType } from './modules/visTypeToLayoutType.js';
|
|
|
97
97
|
|
|
98
98
|
// Modules: visTypes
|
|
99
99
|
|
|
100
|
-
export { VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_BUBBLE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_LINE_LIST, visTypeDisplayNames, visTypeIcons, getDisplayNameByVisType, defaultVisType, isStacked, isMultiType, isYearOverYear, isDualAxisType, isSingleValue, isTwoCategoryChartType, isLegendSetType, isColumnBasedType, isVerticalType } from './modules/visTypes.js';
|
|
100
|
+
export { VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_BUBBLE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_LINE_LIST, VIS_TYPE_OUTLIER_TABLE, visTypeDisplayNames, visTypeIcons, getDisplayNameByVisType, defaultVisType, isStacked, isMultiType, isYearOverYear, isDualAxisType, isSingleValue, isOutlierTable, isTwoCategoryChartType, isLegendSetType, isColumnBasedType, isVerticalType } from './modules/visTypes.js';
|
|
101
101
|
|
|
102
102
|
// Modules: layoutTypes
|
|
103
103
|
|
|
104
|
-
export { LAYOUT_TYPE_DEFAULT, LAYOUT_TYPE_PIE, LAYOUT_TYPE_SINGLE_VALUE, LAYOUT_TYPE_YEAR_OVER_YEAR, LAYOUT_TYPE_PIVOT_TABLE, LAYOUT_TYPE_SCATTER, LAYOUT_TYPE_LINE_LIST } from './modules/layoutTypes.js';
|
|
104
|
+
export { LAYOUT_TYPE_DEFAULT, LAYOUT_TYPE_PIE, LAYOUT_TYPE_SINGLE_VALUE, LAYOUT_TYPE_YEAR_OVER_YEAR, LAYOUT_TYPE_PIVOT_TABLE, LAYOUT_TYPE_SCATTER, LAYOUT_TYPE_LINE_LIST, LAYOUT_TYPE_OUTLIER_TABLE } from './modules/layoutTypes.js';
|
|
105
105
|
|
|
106
106
|
// Modules: layoutUiRules
|
|
107
107
|
|
|
108
|
-
export { getAvailableAxes, getDisallowedDimensions, getAxisMaxNumberOfItems, getAxisMaxNumberOfDimensions, getAxisMinNumberOfDimensions, hasAxisTooManyItems, getAxisPerLockedDimension, getAllLockedDimensionIds, canDimensionBeAddedToAxis, isDimensionLocked, isAxisFull, getTransferableDimension } from './modules/layoutUiRules/index.js';
|
|
108
|
+
export { getAvailableAxes, getDisallowedDimensions, getDimensionMaxNumberOfItems, getAxisMaxNumberOfItems, getAxisMaxNumberOfDimensions, getAxisMinNumberOfDimensions, hasAxisTooManyItems, hasDimensionTooManyItems, getAxisPerLockedDimension, getAllLockedDimensionIds, canDimensionBeAddedToAxis, isDimensionLocked, isAxisFull, getTransferableDimension } from './modules/layoutUiRules/index.js';
|
|
109
109
|
|
|
110
110
|
// Visualizations
|
|
111
111
|
|
|
@@ -131,4 +131,4 @@ export { DAILY, WEEKLY, WEEKLYWED, WEEKLYTHU, WEEKLYSAT, WEEKLYSUN, WEEKS_THIS_Y
|
|
|
131
131
|
export { getRelativePeriodsOptionsById } from './components/PeriodDimension/utils/relativePeriods.js';
|
|
132
132
|
export { getFixedPeriodsOptionsById } from './components/PeriodDimension/utils/fixedPeriods.js';
|
|
133
133
|
export { default as VisualizationOptions } from './components/Options/VisualizationOptions.js';
|
|
134
|
-
export { DIMENSION_TYPE_INDICATOR, DIMENSION_TYPE_DATA_ELEMENT, DIMENSION_TYPE_DATA_SET, DIMENSION_TYPE_EVENT_DATA_ITEM, DIMENSION_TYPE_PROGRAM_INDICATOR, DIMENSION_TYPE_PROGRAM_DATA_ELEMENT, DIMENSION_TYPE_PROGRAM_ATTRIBUTE, DIMENSION_TYPE_DATA_ELEMENT_OPERAND, DIMENSION_TYPE_CATEGORY, DIMENSION_TYPE_CATEGORY_OPTION_GROUP_SET, DIMENSION_TYPE_ALL, DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET, DIMENSION_TYPE_ORGANISATION_UNIT, DIMENSION_TYPE_PERIOD, DIMENSION_TYPE_ORGANISATION_UNIT_GROUP_SET, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM } from './modules/dataTypes.js';
|
|
134
|
+
export { DIMENSION_TYPE_INDICATOR, DIMENSION_TYPE_DATA_ELEMENT, DIMENSION_TYPE_DATA_SET, DIMENSION_TYPE_EVENT_DATA_ITEM, DIMENSION_TYPE_PROGRAM_INDICATOR, DIMENSION_TYPE_PROGRAM_DATA_ELEMENT, DIMENSION_TYPE_PROGRAM_ATTRIBUTE, DIMENSION_TYPE_DATA_ELEMENT_OPERAND, DIMENSION_TYPE_CATEGORY, DIMENSION_TYPE_CATEGORY_OPTION_GROUP_SET, DIMENSION_TYPE_ALL, DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET, DIMENSION_TYPE_ORGANISATION_UNIT, DIMENSION_TYPE_PERIOD, DIMENSION_TYPE_ORGANISATION_UNIT_GROUP_SET, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM, dataTypeMap } from './modules/dataTypes.js';
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"Drag items here, or double click in the list, to start building a calculation formula": "Drag items here, or double click in the list, to start building a calculation formula",
|
|
45
45
|
"Math operators": "Math operators",
|
|
46
46
|
"Data Type": "Data Type",
|
|
47
|
+
"Only {{dataType}} can be used in {{visType}}": "Only {{dataType}} can be used in {{visType}}",
|
|
47
48
|
"All types": "All types",
|
|
48
49
|
"Disaggregation": "Disaggregation",
|
|
49
50
|
"No data": "No data",
|
|
@@ -54,10 +55,12 @@
|
|
|
54
55
|
"No data sets found": "No data sets found",
|
|
55
56
|
"No event data items found": "No event data items found",
|
|
56
57
|
"No program indicators found": "No program indicators found",
|
|
58
|
+
"No calculations found": "No calculations found",
|
|
57
59
|
"No indicators found for \"{{- searchTerm}}\"": "No indicators found for \"{{- searchTerm}}\"",
|
|
58
60
|
"No data sets found for \"{{- searchTerm}}\"": "No data sets found for \"{{- searchTerm}}\"",
|
|
59
61
|
"No event data items found for \"{{- searchTerm}}\"": "No event data items found for \"{{- searchTerm}}\"",
|
|
60
62
|
"No program indicators found for \"{{- searchTerm}}\"": "No program indicators found for \"{{- searchTerm}}\"",
|
|
63
|
+
"No calculations found for \"{{- searchTerm}}\"": "No calculations found for \"{{- searchTerm}}\"",
|
|
61
64
|
"Nothing found for \"{{- searchTerm}}\"": "Nothing found for \"{{- searchTerm}}\"",
|
|
62
65
|
"Calculation": "Calculation",
|
|
63
66
|
"Metric type": "Metric type",
|
|
@@ -201,9 +204,9 @@
|
|
|
201
204
|
"Year": "Year",
|
|
202
205
|
"Select year": "Select year",
|
|
203
206
|
"Period": "Period",
|
|
207
|
+
"Selected Periods": "Selected Periods",
|
|
204
208
|
"Relative periods": "Relative periods",
|
|
205
209
|
"Fixed periods": "Fixed periods",
|
|
206
|
-
"Selected Periods": "Selected Periods",
|
|
207
210
|
"No periods selected": "No periods selected",
|
|
208
211
|
"Daily": "Daily",
|
|
209
212
|
"Weekly": "Weekly",
|
|
@@ -371,6 +374,7 @@
|
|
|
371
374
|
"Radar": "Radar",
|
|
372
375
|
"Scatter": "Scatter",
|
|
373
376
|
"Single value": "Single value",
|
|
377
|
+
"Outlier table": "Outlier table",
|
|
374
378
|
"All charts": "All charts",
|
|
375
379
|
"{{seriesName}} (trend)": "{{seriesName}} (trend)",
|
|
376
380
|
"Trend": "Trend",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getAdaptedUiLayoutByType } from '../getAdaptedUiLayoutByType.js';
|
|
2
2
|
import { AXIS_ID_COLUMNS, AXIS_ID_ROWS, AXIS_ID_FILTERS } from '../layout/axis.js';
|
|
3
3
|
import { DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ORGUNIT } from '../predefinedDimensions.js';
|
|
4
|
-
import { VIS_TYPE_COLUMN, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_BAR, VIS_TYPE_PIE, VIS_TYPE_SINGLE_VALUE } from '../visTypes.js';
|
|
4
|
+
import { VIS_TYPE_COLUMN, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_BAR, VIS_TYPE_PIE, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_OUTLIER_TABLE } from '../visTypes.js';
|
|
5
5
|
const someId = 'someId';
|
|
6
6
|
const otherId = 'otherId';
|
|
7
|
+
const thirdId = 'thirdId';
|
|
7
8
|
describe('getAdaptedUiLayoutByType', () => {
|
|
8
9
|
it('column: moves all extra dimensions in columns and rows to filters', () => {
|
|
9
10
|
const initialState = {
|
|
@@ -107,6 +108,20 @@ describe('getAdaptedUiLayoutByType', () => {
|
|
|
107
108
|
};
|
|
108
109
|
expect(actualState).toEqual(expectedState);
|
|
109
110
|
});
|
|
111
|
+
it('outlier table: removes all dimensions but dx,pe,ou which are moved to columns', () => {
|
|
112
|
+
const initialState = {
|
|
113
|
+
[AXIS_ID_COLUMNS]: [DIMENSION_ID_DATA, someId],
|
|
114
|
+
[AXIS_ID_ROWS]: [DIMENSION_ID_PERIOD, otherId],
|
|
115
|
+
[AXIS_ID_FILTERS]: [DIMENSION_ID_ORGUNIT, thirdId]
|
|
116
|
+
};
|
|
117
|
+
const actualState = getAdaptedUiLayoutByType(initialState, VIS_TYPE_OUTLIER_TABLE);
|
|
118
|
+
const expectedState = {
|
|
119
|
+
[AXIS_ID_COLUMNS]: [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ORGUNIT],
|
|
120
|
+
[AXIS_ID_ROWS]: [],
|
|
121
|
+
[AXIS_ID_FILTERS]: []
|
|
122
|
+
};
|
|
123
|
+
expect(actualState).toEqual(expectedState);
|
|
124
|
+
});
|
|
110
125
|
it('pivot -> sv with dimension strings', () => {
|
|
111
126
|
const initialLayout = {
|
|
112
127
|
[AXIS_ID_COLUMNS]: [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD],
|
package/build/es/modules/axis.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import i18n from '../locales/index.js';
|
|
2
2
|
import { AXIS_ID_COLUMNS, AXIS_ID_ROWS, AXIS_ID_FILTERS } from './layout/axis.js';
|
|
3
|
-
import { LAYOUT_TYPE_DEFAULT, LAYOUT_TYPE_PIE, LAYOUT_TYPE_YEAR_OVER_YEAR, LAYOUT_TYPE_PIVOT_TABLE, LAYOUT_TYPE_SCATTER, LAYOUT_TYPE_LINE_LIST } from './layoutTypes.js';
|
|
3
|
+
import { LAYOUT_TYPE_DEFAULT, LAYOUT_TYPE_PIE, LAYOUT_TYPE_YEAR_OVER_YEAR, LAYOUT_TYPE_PIVOT_TABLE, LAYOUT_TYPE_SCATTER, LAYOUT_TYPE_LINE_LIST, LAYOUT_TYPE_OUTLIER_TABLE } from './layoutTypes.js';
|
|
4
4
|
const getAxisNamesByLayoutType = layoutType => {
|
|
5
5
|
switch (layoutType) {
|
|
6
6
|
case LAYOUT_TYPE_DEFAULT:
|
|
@@ -28,6 +28,10 @@ const getAxisNamesByLayoutType = layoutType => {
|
|
|
28
28
|
[AXIS_ID_ROWS]: i18n.t('Points'),
|
|
29
29
|
[AXIS_ID_FILTERS]: i18n.t('Filter')
|
|
30
30
|
};
|
|
31
|
+
case LAYOUT_TYPE_OUTLIER_TABLE:
|
|
32
|
+
return {
|
|
33
|
+
[AXIS_ID_COLUMNS]: i18n.t('Columns')
|
|
34
|
+
};
|
|
31
35
|
}
|
|
32
36
|
};
|
|
33
37
|
export const getAxisNameByLayoutType = (axisId, layoutType) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import isObject from 'lodash/isObject';
|
|
2
2
|
import { AXIS_ID_COLUMNS, AXIS_ID_ROWS, AXIS_ID_FILTERS } from './layout/axis.js';
|
|
3
3
|
import { DIMENSION_ID_DATA, DIMENSION_ID_ORGUNIT, DIMENSION_ID_PERIOD } from './predefinedDimensions.js';
|
|
4
|
-
import { VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_PIE, VIS_TYPE_GAUGE, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, isTwoCategoryChartType } from './visTypes.js';
|
|
4
|
+
import { VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_PIE, VIS_TYPE_GAUGE, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_OUTLIER_TABLE, isTwoCategoryChartType } from './visTypes.js';
|
|
5
5
|
export const getAdaptedUiLayoutByType = (layout, type) => {
|
|
6
6
|
var _layout$rows;
|
|
7
7
|
if (isTwoCategoryChartType(type) && ((_layout$rows = layout.rows) === null || _layout$rows === void 0 ? void 0 : _layout$rows.length) > 1) {
|
|
@@ -26,6 +26,8 @@ export const getAdaptedUiLayoutByType = (layout, type) => {
|
|
|
26
26
|
return layout;
|
|
27
27
|
case VIS_TYPE_SCATTER:
|
|
28
28
|
return getScatterLayout(layout);
|
|
29
|
+
case VIS_TYPE_OUTLIER_TABLE:
|
|
30
|
+
return getOutlierTableLayout(layout);
|
|
29
31
|
default:
|
|
30
32
|
return getDefaultLayout(layout);
|
|
31
33
|
}
|
|
@@ -99,6 +101,13 @@ const getSingleValueLayout = layout => {
|
|
|
99
101
|
};
|
|
100
102
|
};
|
|
101
103
|
|
|
104
|
+
// Transform from ui.layout to outlier table layout format
|
|
105
|
+
const getOutlierTableLayout = () => ({
|
|
106
|
+
[AXIS_ID_COLUMNS]: [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ORGUNIT],
|
|
107
|
+
[AXIS_ID_ROWS]: [],
|
|
108
|
+
[AXIS_ID_FILTERS]: []
|
|
109
|
+
});
|
|
110
|
+
|
|
102
111
|
/**
|
|
103
112
|
*
|
|
104
113
|
* @param {string|object} dimension
|
|
@@ -4,4 +4,5 @@ export const LAYOUT_TYPE_SINGLE_VALUE = 'LAYOUT_TYPE_SINGLE_VALUE';
|
|
|
4
4
|
export const LAYOUT_TYPE_YEAR_OVER_YEAR = 'LAYOUT_TYPE_YEAR_OVER_YEAR';
|
|
5
5
|
export const LAYOUT_TYPE_PIVOT_TABLE = 'LAYOUT_TYPE_PIVOT_TABLE';
|
|
6
6
|
export const LAYOUT_TYPE_SCATTER = 'LAYOUT_TYPE_SCATTER';
|
|
7
|
-
export const LAYOUT_TYPE_LINE_LIST = 'LAYOUT_TYPE_LINE_LIST';
|
|
7
|
+
export const LAYOUT_TYPE_LINE_LIST = 'LAYOUT_TYPE_LINE_LIST';
|
|
8
|
+
export const LAYOUT_TYPE_OUTLIER_TABLE = 'LAYOUT_TYPE_OUTLIER_TABLE';
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { ALL_AXIS_IDS } from '../../layout/axis.js';
|
|
2
|
-
import { DIMENSION_ID_DATA, DIMENSION_ID_ORGUNIT, DIMENSION_ID_PERIOD } from '../../predefinedDimensions.js';
|
|
2
|
+
import { DIMENSION_ID_DATA, DIMENSION_ID_ORGUNIT, DIMENSION_ID_PERIOD, DIMENSION_ID_ASSIGNED_CATEGORIES } from '../../predefinedDimensions.js';
|
|
3
3
|
import { testResourceRules, testResourceRequiredProps, testResourceAllRuleProps } from '../rules.js';
|
|
4
4
|
|
|
5
5
|
// Consts
|
|
6
|
+
const validDims = [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ORGUNIT];
|
|
6
7
|
const lockableDims = [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ORGUNIT];
|
|
7
|
-
const disallowableDims = [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD];
|
|
8
|
+
const disallowableDims = [DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ASSIGNED_CATEGORIES];
|
|
8
9
|
|
|
9
10
|
// Helper fns
|
|
10
11
|
const allArrayItemsAreValid = (allItems, validItems) => allItems.every(value => validItems.includes(value));
|
|
11
12
|
const allArrayItemsAreValidAxisIds = array => allArrayItemsAreValid(array, ALL_AXIS_IDS);
|
|
13
|
+
const allArrayItemsAreValidDimensionIds = array => allArrayItemsAreValid(array, validDims);
|
|
12
14
|
const onlyRulesWithProp = ruleProp => testResourceRules.filter(rule => rule[ruleProp]);
|
|
13
15
|
|
|
14
16
|
// Partial tests
|
|
@@ -18,6 +20,9 @@ const testPropHasKeysAndValues = ruleProp => it('has keys and values', () => {
|
|
|
18
20
|
const testPropIsArray = ruleProp => it('is an array', () => {
|
|
19
21
|
expect(onlyRulesWithProp(ruleProp).every(rule => Array.isArray(rule[ruleProp]))).toBe(true);
|
|
20
22
|
});
|
|
23
|
+
const testKeysAreValidDimensionIds = ruleProp => it('keys should be valid dimension ids', () => {
|
|
24
|
+
expect(onlyRulesWithProp(ruleProp).every(rule => allArrayItemsAreValidDimensionIds(Object.keys(rule[ruleProp])))).toBe(true);
|
|
25
|
+
});
|
|
21
26
|
const testKeysAreValidAxisIds = ruleProp => it('keys should be valid axis ids', () => {
|
|
22
27
|
expect(onlyRulesWithProp(ruleProp).every(rule => allArrayItemsAreValidAxisIds(Object.keys(rule[ruleProp])))).toBe(true);
|
|
23
28
|
});
|
|
@@ -56,6 +61,13 @@ describe("verify each rule's ", () => {
|
|
|
56
61
|
testNoValuesNegative(ruleProp);
|
|
57
62
|
});
|
|
58
63
|
});
|
|
64
|
+
describe('MAX_ITEMS_PER_DIM', () => {
|
|
65
|
+
const ruleProp = testResourceAllRuleProps['MAX_ITEMS_PER_DIM'];
|
|
66
|
+
testPropHasKeysAndValues(ruleProp);
|
|
67
|
+
testKeysAreValidDimensionIds(ruleProp);
|
|
68
|
+
testNoValuesZero(ruleProp);
|
|
69
|
+
testNoValuesNegative(ruleProp);
|
|
70
|
+
});
|
|
59
71
|
describe('AVAILABLE_AXES', () => {
|
|
60
72
|
const ruleProp = testResourceAllRuleProps['AVAILABLE_AXES'];
|
|
61
73
|
testPropIsArray(ruleProp);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { getAvailableAxesByVisType as getAvailableAxes, getDisallowedDimsByVisType as getDisallowedDimensions, getAxisMaxNumberOfItemsByVisType as getAxisMaxNumberOfItems, getAxisMaxNumberOfDimsByVisType as getAxisMaxNumberOfDimensions, getAxisMinNumberOfDimsByVisType as getAxisMinNumberOfDimensions, getAxisPerLockedDimByVisType as getAxisPerLockedDimension, getAllLockedDimIdsByVisType as getAllLockedDimensionIds } from './rulesHelper.js';
|
|
2
|
-
export { hasAxisTooManyItemsByVisType as hasAxisTooManyItems, isDimensionLockedByVisType as isDimensionLocked, isAxisFullByVisType as isAxisFull, canDimensionBeAddedToAxisByVisType as canDimensionBeAddedToAxis, getTransferableDimensionPerAxisByVisType as getTransferableDimension } from './rulesUtils.js';
|
|
1
|
+
export { getAvailableAxesByVisType as getAvailableAxes, getDisallowedDimsByVisType as getDisallowedDimensions, getAxisMaxNumberOfItemsByVisType as getAxisMaxNumberOfItems, getAxisMaxNumberOfDimsByVisType as getAxisMaxNumberOfDimensions, getAxisMinNumberOfDimsByVisType as getAxisMinNumberOfDimensions, getAxisPerLockedDimByVisType as getAxisPerLockedDimension, getAllLockedDimIdsByVisType as getAllLockedDimensionIds, getDimMaxNumberOfItemsByVisType as getDimensionMaxNumberOfItems } from './rulesHelper.js';
|
|
2
|
+
export { hasAxisTooManyItemsByVisType as hasAxisTooManyItems, hasDimensionTooManyItemsByVisType as hasDimensionTooManyItems, isDimensionLockedByVisType as isDimensionLocked, isAxisFullByVisType as isAxisFull, canDimensionBeAddedToAxisByVisType as canDimensionBeAddedToAxis, getTransferableDimensionPerAxisByVisType as getTransferableDimension } from './rulesUtils.js';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { AXIS_ID_COLUMNS, AXIS_ID_ROWS, AXIS_ID_FILTERS } from '../layout/axis.js';
|
|
2
|
-
import { DIMENSION_ID_PERIOD, DIMENSION_ID_DATA, DIMENSION_ID_ORGUNIT } from '../predefinedDimensions.js';
|
|
3
|
-
import { VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_PIE, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_LINE_LIST } from '../visTypes.js';
|
|
2
|
+
import { DIMENSION_ID_PERIOD, DIMENSION_ID_DATA, DIMENSION_ID_ORGUNIT, DIMENSION_ID_ASSIGNED_CATEGORIES } from '../predefinedDimensions.js';
|
|
3
|
+
import { VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_PIE, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_LINE_LIST, VIS_TYPE_OUTLIER_TABLE } from '../visTypes.js';
|
|
4
4
|
const RULE_PROP_AVAILABLE_AXES = 'availableAxes',
|
|
5
5
|
RULE_PROP_MAX_DIMS_PER_AXIS = 'maxNumberOfDimsPerAxis',
|
|
6
6
|
RULE_PROP_MIN_DIMS_PER_AXIS = 'minNumberOfDimsPerAxis',
|
|
7
7
|
RULE_PROP_MAX_ITEMS_PER_AXIS = 'maxNumberOfItemsPerAxis',
|
|
8
|
+
RULE_PROP_MAX_ITEMS_PER_DIM = 'maxNumberOfItemsPerDim',
|
|
8
9
|
RULE_PROP_DISALLOWED_DIMS = 'disallowedDims',
|
|
9
10
|
RULE_PROP_LOCKED_DIMS = 'lockedDims';
|
|
10
11
|
const defaultRules = {
|
|
@@ -82,6 +83,21 @@ const scatterRules = {
|
|
|
82
83
|
const lineListRules = {
|
|
83
84
|
[RULE_PROP_AVAILABLE_AXES]: [AXIS_ID_COLUMNS, AXIS_ID_FILTERS]
|
|
84
85
|
};
|
|
86
|
+
const outlierTableRules = {
|
|
87
|
+
[RULE_PROP_AVAILABLE_AXES]: [AXIS_ID_COLUMNS],
|
|
88
|
+
[RULE_PROP_MIN_DIMS_PER_AXIS]: {
|
|
89
|
+
[AXIS_ID_COLUMNS]: 3
|
|
90
|
+
},
|
|
91
|
+
[RULE_PROP_MAX_ITEMS_PER_DIM]: {
|
|
92
|
+
[DIMENSION_ID_PERIOD]: 1
|
|
93
|
+
},
|
|
94
|
+
[RULE_PROP_LOCKED_DIMS]: {
|
|
95
|
+
[DIMENSION_ID_DATA]: AXIS_ID_COLUMNS,
|
|
96
|
+
[DIMENSION_ID_PERIOD]: AXIS_ID_COLUMNS,
|
|
97
|
+
[DIMENSION_ID_ORGUNIT]: AXIS_ID_COLUMNS
|
|
98
|
+
},
|
|
99
|
+
[RULE_PROP_DISALLOWED_DIMS]: [DIMENSION_ID_ASSIGNED_CATEGORIES]
|
|
100
|
+
};
|
|
85
101
|
const visTypeToRules = {
|
|
86
102
|
[VIS_TYPE_COLUMN]: defaultRules,
|
|
87
103
|
[VIS_TYPE_STACKED_COLUMN]: defaultRules,
|
|
@@ -98,7 +114,8 @@ const visTypeToRules = {
|
|
|
98
114
|
[VIS_TYPE_YEAR_OVER_YEAR_COLUMN]: yearOverYearRules,
|
|
99
115
|
[VIS_TYPE_PIVOT_TABLE]: pivotTableRules,
|
|
100
116
|
[VIS_TYPE_SCATTER]: scatterRules,
|
|
101
|
-
[VIS_TYPE_LINE_LIST]: lineListRules
|
|
117
|
+
[VIS_TYPE_LINE_LIST]: lineListRules,
|
|
118
|
+
[VIS_TYPE_OUTLIER_TABLE]: outlierTableRules
|
|
102
119
|
};
|
|
103
120
|
const getRulesByVisType = visType => {
|
|
104
121
|
const rules = visTypeToRules[visType];
|
|
@@ -113,6 +130,7 @@ const getRulesByVisType = visType => {
|
|
|
113
130
|
export const getAvailableAxesByVisType = visType => getRulesByVisType(visType)[RULE_PROP_AVAILABLE_AXES] || [];
|
|
114
131
|
export const getMaxNumberOfDimsPerAxisByVisType = visType => getRulesByVisType(visType)[RULE_PROP_MAX_DIMS_PER_AXIS] || {};
|
|
115
132
|
export const getMinNumberOfDimsPerAxisByVisType = visType => getRulesByVisType(visType)[RULE_PROP_MIN_DIMS_PER_AXIS] || {};
|
|
133
|
+
export const getMaxNumberOfItemsPerDimByVisType = visType => getRulesByVisType(visType)[RULE_PROP_MAX_ITEMS_PER_DIM] || {};
|
|
116
134
|
export const getMaxNumberOfItemsPerAxisByVisType = visType => getRulesByVisType(visType)[RULE_PROP_MAX_ITEMS_PER_AXIS] || {};
|
|
117
135
|
export const getDisallowedDimsByVisType = visType => getRulesByVisType(visType)[RULE_PROP_DISALLOWED_DIMS] || [];
|
|
118
136
|
export const getLockedDimsByVisType = visType => getRulesByVisType(visType)[RULE_PROP_LOCKED_DIMS] || {};
|
|
@@ -126,6 +144,7 @@ export const testResourceAllRuleProps = {
|
|
|
126
144
|
MAX_DIMS_PER_AXIS: RULE_PROP_MAX_DIMS_PER_AXIS,
|
|
127
145
|
MIN_DIMS_PER_AXIS: RULE_PROP_MIN_DIMS_PER_AXIS,
|
|
128
146
|
MAX_ITEMS_PER_AXIS: RULE_PROP_MAX_ITEMS_PER_AXIS,
|
|
147
|
+
MAX_ITEMS_PER_DIM: RULE_PROP_MAX_ITEMS_PER_DIM,
|
|
129
148
|
DISALLOWED_DIMS: RULE_PROP_DISALLOWED_DIMS,
|
|
130
149
|
LOCKED_DIMS: RULE_PROP_LOCKED_DIMS
|
|
131
150
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMaxNumberOfItemsPerAxisByVisType, getMaxNumberOfDimsPerAxisByVisType, getMinNumberOfDimsPerAxisByVisType, getLockedDimsByVisType } from './rules.js';
|
|
1
|
+
import { getMaxNumberOfItemsPerDimByVisType, getMaxNumberOfItemsPerAxisByVisType, getMaxNumberOfDimsPerAxisByVisType, getMinNumberOfDimsPerAxisByVisType, getLockedDimsByVisType } from './rules.js';
|
|
2
2
|
|
|
3
3
|
// Selectors
|
|
4
4
|
|
|
@@ -7,4 +7,5 @@ export const getAxisMaxNumberOfItemsByVisType = (visType, axisId) => getMaxNumbe
|
|
|
7
7
|
export const getAxisMaxNumberOfDimsByVisType = (visType, axisId) => getMaxNumberOfDimsPerAxisByVisType(visType)[axisId];
|
|
8
8
|
export const getAxisMinNumberOfDimsByVisType = (visType, axisId) => getMinNumberOfDimsPerAxisByVisType(visType)[axisId];
|
|
9
9
|
export const getAxisPerLockedDimByVisType = (visType, dimensionId) => getLockedDimsByVisType(visType)[dimensionId];
|
|
10
|
-
export const getAllLockedDimIdsByVisType = visType => Object.keys(getLockedDimsByVisType(visType));
|
|
10
|
+
export const getAllLockedDimIdsByVisType = visType => Object.keys(getLockedDimsByVisType(visType));
|
|
11
|
+
export const getDimMaxNumberOfItemsByVisType = (visType, dimensionId) => getMaxNumberOfItemsPerDimByVisType(visType)[dimensionId];
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { getLockedDimsByVisType } from './rules.js';
|
|
2
|
-
import { getAxisMaxNumberOfDimsByVisType, getAxisMaxNumberOfItemsByVisType, getAllLockedDimIdsByVisType } from './rulesHelper.js';
|
|
2
|
+
import { getAxisMaxNumberOfDimsByVisType, getAxisMaxNumberOfItemsByVisType, getDimMaxNumberOfItemsByVisType, getAllLockedDimIdsByVisType } from './rulesHelper.js';
|
|
3
3
|
export const hasAxisTooManyItemsByVisType = (visType, axisId, numberOfItems) => {
|
|
4
4
|
const maxNumberOfItemsPerAxis = getAxisMaxNumberOfItemsByVisType(visType, axisId);
|
|
5
|
-
return maxNumberOfItemsPerAxis
|
|
5
|
+
return maxNumberOfItemsPerAxis && numberOfItems > maxNumberOfItemsPerAxis;
|
|
6
|
+
};
|
|
7
|
+
export const hasDimensionTooManyItemsByVisType = (visType, dimensionId, numberOfItems) => {
|
|
8
|
+
const maxNumberOfItemsPerDimension = getDimMaxNumberOfItemsByVisType(visType, dimensionId);
|
|
9
|
+
return maxNumberOfItemsPerDimension && numberOfItems > maxNumberOfItemsPerDimension;
|
|
6
10
|
};
|
|
7
11
|
export const isDimensionLockedByVisType = (visType, dimensionId) => getAllLockedDimIdsByVisType(visType).includes(dimensionId);
|
|
8
12
|
export const isAxisFullByVisType = (visType, axisId, axisDimensionsCount) => axisDimensionsCount >= getAxisMaxNumberOfDimsByVisType(visType, axisId);
|