@dhis2/analytics 22.0.0-alpha.1 → 22.0.1
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/CHANGELOG.md +2997 -0
- package/build/cjs/__demo__/FileMenu.stories.js +9 -17
- package/build/cjs/__fixtures__/fixtures.js +1 -0
- package/build/cjs/__fixtures__/json/api/analytics/enrollments.json +206 -0
- package/build/cjs/api/analytics/Analytics.js +6 -0
- package/build/cjs/api/analytics/AnalyticsEnrollments.js +48 -0
- package/build/cjs/api/analytics/__tests__/AnalyticsEnrollments.spec.js +50 -0
- package/build/cjs/api/analytics/__tests__/__snapshots__/AnalyticsEnrollments.spec.js.snap +3 -0
- package/build/cjs/components/CachedDataQueryProvider.js +70 -0
- package/build/cjs/components/FileMenu/FileMenu.js +3 -10
- package/build/cjs/components/FileMenu/__tests__/FileMenu.spec.js +3 -5
- package/build/cjs/components/FileMenu/utils.js +1 -1
- package/build/cjs/components/OpenFileDialog/CustomSelectOption.js +4 -18
- package/build/cjs/components/OpenFileDialog/FileList.js +5 -5
- package/build/cjs/components/OpenFileDialog/OpenFileDialog.js +30 -31
- package/build/cjs/components/OpenFileDialog/OpenFileDialog.styles.js +2 -2
- package/build/cjs/components/OpenFileDialog/VisTypeFilter.js +16 -17
- package/build/cjs/components/OpenFileDialog/utils.js +20 -1
- package/build/cjs/index.js +18 -16
- package/build/cjs/locales/ar/translations.json +9 -0
- package/build/cjs/locales/ar_EG/translations.json +9 -0
- package/build/cjs/locales/ar_IQ/translations.json +9 -0
- package/build/cjs/locales/ckb/translations.json +9 -0
- package/build/cjs/locales/cs/translations.json +17 -8
- package/build/cjs/locales/da/translations.json +9 -0
- package/build/cjs/locales/en/translations.json +23 -3
- package/build/cjs/locales/es/translations.json +9 -0
- package/build/cjs/locales/fr/translations.json +9 -0
- package/build/cjs/locales/id/translations.json +9 -0
- package/build/cjs/locales/km/translations.json +9 -0
- package/build/cjs/locales/lo/translations.json +9 -0
- package/build/cjs/locales/my/translations.json +9 -0
- package/build/cjs/locales/nb/translations.json +9 -0
- package/build/cjs/locales/nl/translations.json +9 -0
- package/build/cjs/locales/prs/translations.json +9 -0
- package/build/cjs/locales/ps/translations.json +9 -0
- package/build/cjs/locales/pt/translations.json +9 -0
- package/build/cjs/locales/pt_BR/translations.json +9 -0
- package/build/cjs/locales/ru/translations.json +9 -0
- package/build/cjs/locales/sv/translations.json +9 -0
- package/build/cjs/locales/tet/translations.json +9 -0
- package/build/cjs/locales/tg/translations.json +9 -0
- package/build/cjs/locales/uk/translations.json +9 -0
- package/build/cjs/locales/ur/translations.json +9 -0
- package/build/cjs/locales/uz/translations.json +9 -0
- package/build/cjs/locales/uz_Latn/translations.json +9 -0
- package/build/cjs/locales/vi/translations.json +9 -0
- package/build/cjs/locales/zh/translations.json +10 -1
- package/build/cjs/locales/zh_CN/translations.json +9 -0
- package/build/cjs/modules/layoutUiRules/rules.js +5 -1
- package/build/cjs/modules/visTypes.js +21 -12
- package/build/es/__demo__/FileMenu.stories.js +9 -17
- package/build/es/__fixtures__/fixtures.js +1 -0
- package/build/es/__fixtures__/json/api/analytics/enrollments.json +206 -0
- package/build/es/api/analytics/Analytics.js +5 -0
- package/build/es/api/analytics/AnalyticsEnrollments.js +38 -0
- package/build/es/api/analytics/__tests__/AnalyticsEnrollments.spec.js +40 -0
- package/build/es/api/analytics/__tests__/__snapshots__/AnalyticsEnrollments.spec.js.snap +3 -0
- package/build/es/components/CachedDataQueryProvider.js +50 -0
- package/build/es/components/FileMenu/FileMenu.js +3 -10
- package/build/es/components/FileMenu/__tests__/FileMenu.spec.js +3 -5
- package/build/es/components/FileMenu/utils.js +1 -1
- package/build/es/components/OpenFileDialog/CustomSelectOption.js +4 -17
- package/build/es/components/OpenFileDialog/FileList.js +5 -5
- package/build/es/components/OpenFileDialog/OpenFileDialog.js +32 -32
- package/build/es/components/OpenFileDialog/OpenFileDialog.styles.js +2 -2
- package/build/es/components/OpenFileDialog/VisTypeFilter.js +14 -18
- package/build/es/components/OpenFileDialog/utils.js +18 -0
- package/build/es/index.js +3 -2
- package/build/es/locales/ar/translations.json +9 -0
- package/build/es/locales/ar_EG/translations.json +9 -0
- package/build/es/locales/ar_IQ/translations.json +9 -0
- package/build/es/locales/ckb/translations.json +9 -0
- package/build/es/locales/cs/translations.json +17 -8
- package/build/es/locales/da/translations.json +9 -0
- package/build/es/locales/en/translations.json +23 -3
- package/build/es/locales/es/translations.json +9 -0
- package/build/es/locales/fr/translations.json +9 -0
- package/build/es/locales/id/translations.json +9 -0
- package/build/es/locales/km/translations.json +9 -0
- package/build/es/locales/lo/translations.json +9 -0
- package/build/es/locales/my/translations.json +9 -0
- package/build/es/locales/nb/translations.json +9 -0
- package/build/es/locales/nl/translations.json +9 -0
- package/build/es/locales/prs/translations.json +9 -0
- package/build/es/locales/ps/translations.json +9 -0
- package/build/es/locales/pt/translations.json +9 -0
- package/build/es/locales/pt_BR/translations.json +9 -0
- package/build/es/locales/ru/translations.json +9 -0
- package/build/es/locales/sv/translations.json +9 -0
- package/build/es/locales/tet/translations.json +9 -0
- package/build/es/locales/tg/translations.json +9 -0
- package/build/es/locales/uk/translations.json +9 -0
- package/build/es/locales/ur/translations.json +9 -0
- package/build/es/locales/uz/translations.json +9 -0
- package/build/es/locales/uz_Latn/translations.json +9 -0
- package/build/es/locales/vi/translations.json +9 -0
- package/build/es/locales/zh/translations.json +10 -1
- package/build/es/locales/zh_CN/translations.json +9 -0
- package/build/es/modules/layoutUiRules/rules.js +6 -2
- package/build/es/modules/visTypes.js +19 -9
- package/package.json +2 -2
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
{
|
|
2
|
+
"headers": [
|
|
3
|
+
{
|
|
4
|
+
"name": "pi",
|
|
5
|
+
"column": "Enrollment",
|
|
6
|
+
"valueType": "TEXT",
|
|
7
|
+
"type": "java.lang.String",
|
|
8
|
+
"hidden": false,
|
|
9
|
+
"meta": true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "tei",
|
|
13
|
+
"column": "Tracked entity instance",
|
|
14
|
+
"valueType": "TEXT",
|
|
15
|
+
"type": "java.lang.String",
|
|
16
|
+
"hidden": false,
|
|
17
|
+
"meta": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "enrollmentdate",
|
|
21
|
+
"column": "Enrollment date",
|
|
22
|
+
"valueType": "DATE",
|
|
23
|
+
"type": "java.util.Date",
|
|
24
|
+
"hidden": false,
|
|
25
|
+
"meta": true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "incidentdate",
|
|
29
|
+
"column": "Incident date",
|
|
30
|
+
"valueType": "DATE",
|
|
31
|
+
"type": "java.util.Date",
|
|
32
|
+
"hidden": false,
|
|
33
|
+
"meta": true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "geometry",
|
|
37
|
+
"column": "Geometry",
|
|
38
|
+
"valueType": "TEXT",
|
|
39
|
+
"type": "java.lang.String",
|
|
40
|
+
"hidden": false,
|
|
41
|
+
"meta": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "longitude",
|
|
45
|
+
"column": "Longitude",
|
|
46
|
+
"valueType": "NUMBER",
|
|
47
|
+
"type": "java.lang.Double",
|
|
48
|
+
"hidden": false,
|
|
49
|
+
"meta": true
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "latitude",
|
|
53
|
+
"column": "Latitude",
|
|
54
|
+
"valueType": "NUMBER",
|
|
55
|
+
"type": "java.lang.Double",
|
|
56
|
+
"hidden": false,
|
|
57
|
+
"meta": true
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "ouname",
|
|
61
|
+
"column": "Organisation unit name",
|
|
62
|
+
"valueType": "TEXT",
|
|
63
|
+
"type": "java.lang.String",
|
|
64
|
+
"hidden": false,
|
|
65
|
+
"meta": true
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "oucode",
|
|
69
|
+
"column": "Organisation unit code",
|
|
70
|
+
"valueType": "TEXT",
|
|
71
|
+
"type": "java.lang.String",
|
|
72
|
+
"hidden": false,
|
|
73
|
+
"meta": true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "ou",
|
|
77
|
+
"column": "Organisation unit",
|
|
78
|
+
"valueType": "TEXT",
|
|
79
|
+
"type": "java.lang.String",
|
|
80
|
+
"hidden": false,
|
|
81
|
+
"meta": true
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "de0FEHSIoxh",
|
|
85
|
+
"column": "WHOMCH Chronic conditions",
|
|
86
|
+
"valueType": "BOOLEAN",
|
|
87
|
+
"type": "java.lang.Boolean",
|
|
88
|
+
"hidden": false,
|
|
89
|
+
"meta": true
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "sWoqcoByYmD",
|
|
93
|
+
"column": "WHOMCH Smoking",
|
|
94
|
+
"valueType": "BOOLEAN",
|
|
95
|
+
"type": "java.lang.Boolean",
|
|
96
|
+
"hidden": false,
|
|
97
|
+
"meta": true
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"metaData": {
|
|
101
|
+
"pager": {
|
|
102
|
+
"page": 2,
|
|
103
|
+
"total": 163,
|
|
104
|
+
"pageSize": 4,
|
|
105
|
+
"pageCount": 41
|
|
106
|
+
},
|
|
107
|
+
"items": {
|
|
108
|
+
"ImspTQPwCqd": {
|
|
109
|
+
"name": "Sierra Leone"
|
|
110
|
+
},
|
|
111
|
+
"PFDfvmGpsR3": {
|
|
112
|
+
"name": "Care at birth"
|
|
113
|
+
},
|
|
114
|
+
"bbKtnxRZKEP": {
|
|
115
|
+
"name": "Postpartum care visit"
|
|
116
|
+
},
|
|
117
|
+
"ou": {
|
|
118
|
+
"name": "Organisation unit"
|
|
119
|
+
},
|
|
120
|
+
"PUZaKR0Jh2k": {
|
|
121
|
+
"name": "Previous deliveries"
|
|
122
|
+
},
|
|
123
|
+
"edqlbukwRfQ": {
|
|
124
|
+
"name": "Antenatal care visit"
|
|
125
|
+
},
|
|
126
|
+
"WZbXY0S00lP": {
|
|
127
|
+
"name": "First antenatal care visit"
|
|
128
|
+
},
|
|
129
|
+
"sWoqcoByYmD": {
|
|
130
|
+
"name": "WHOMCH Smoking"
|
|
131
|
+
},
|
|
132
|
+
"WSGAb5XwJ3Y": {
|
|
133
|
+
"name": "WHO RMNCH Tracker"
|
|
134
|
+
},
|
|
135
|
+
"de0FEHSIoxh": {
|
|
136
|
+
"name": "WHOMCH Chronic conditions"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"dimensions": {
|
|
140
|
+
"pe": [],
|
|
141
|
+
"ou": ["ImspTQPwCqd"],
|
|
142
|
+
"sWoqcoByYmD": [],
|
|
143
|
+
"de0FEHSIoxh": []
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"width": 12,
|
|
147
|
+
"rows": [
|
|
148
|
+
[
|
|
149
|
+
"A0cP533hIQv",
|
|
150
|
+
"to8G9jAprnx",
|
|
151
|
+
"2019-02-02 12:05:00.0",
|
|
152
|
+
"2019-02-02 12:05:00.0",
|
|
153
|
+
"",
|
|
154
|
+
"0.0",
|
|
155
|
+
"0.0",
|
|
156
|
+
"Tonkomba MCHP",
|
|
157
|
+
"OU_193264",
|
|
158
|
+
"xIMxph4NMP1",
|
|
159
|
+
"0",
|
|
160
|
+
"1"
|
|
161
|
+
],
|
|
162
|
+
[
|
|
163
|
+
"ZqiUn2uXmBi",
|
|
164
|
+
"SJtv0WzoYki",
|
|
165
|
+
"2019-02-02 12:05:00.0",
|
|
166
|
+
"2019-02-02 12:05:00.0",
|
|
167
|
+
"",
|
|
168
|
+
"0.0",
|
|
169
|
+
"0.0",
|
|
170
|
+
"Mawoma MCHP",
|
|
171
|
+
"OU_254973",
|
|
172
|
+
"Srnpwq8jKbp",
|
|
173
|
+
"0",
|
|
174
|
+
"0"
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
"lE747mUAtbz",
|
|
178
|
+
"PGzTv2A1xzn",
|
|
179
|
+
"2019-02-02 12:05:00.0",
|
|
180
|
+
"2019-02-02 12:05:00.0",
|
|
181
|
+
"",
|
|
182
|
+
"0.0",
|
|
183
|
+
"0.0",
|
|
184
|
+
"Kunsho CHP",
|
|
185
|
+
"OU_193254",
|
|
186
|
+
"tdhB1JXYBx2",
|
|
187
|
+
"",
|
|
188
|
+
"0"
|
|
189
|
+
],
|
|
190
|
+
[
|
|
191
|
+
"nmcqu9QF8ow",
|
|
192
|
+
"pav3tGLjYuq",
|
|
193
|
+
"2019-02-03 12:05:00.0",
|
|
194
|
+
"2019-02-03 12:05:00.0",
|
|
195
|
+
"",
|
|
196
|
+
"0.0",
|
|
197
|
+
"0.0",
|
|
198
|
+
"Korbu MCHP",
|
|
199
|
+
"OU_678893",
|
|
200
|
+
"m73lWmo5BDG",
|
|
201
|
+
"",
|
|
202
|
+
"1"
|
|
203
|
+
]
|
|
204
|
+
],
|
|
205
|
+
"height": 4
|
|
206
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @module analytics
|
|
3
3
|
*/
|
|
4
4
|
import AnalyticsAggregate from './AnalyticsAggregate.js';
|
|
5
|
+
import AnalyticsEnrollments from './AnalyticsEnrollments.js';
|
|
5
6
|
import AnalyticsEvents from './AnalyticsEvents.js';
|
|
6
7
|
import AnalyticsRequest from './AnalyticsRequest.js';
|
|
7
8
|
import AnalyticsResponse from './AnalyticsResponse.js';
|
|
@@ -30,17 +31,20 @@ import AnalyticsResponse from './AnalyticsResponse.js';
|
|
|
30
31
|
class Analytics {
|
|
31
32
|
/**
|
|
32
33
|
* @param {!module:analytics.AnalyticsAggregate} analyticsAggregate The AnalyticsAggregate instance
|
|
34
|
+
* @param {!module:analytics.AnalyticsEnrollments} analyticsEnrollments The AnalyticsEnrollments instance
|
|
33
35
|
* @param {!module:analytics.AnalyticsEvents} analyticsEvents The AnalyticsEvents instance
|
|
34
36
|
* @param {!module:analytics.AnalyticsRequest} analyticsRequest The AnalyticsRequest class
|
|
35
37
|
* @param {!module:analytics.AnalyticsResponse} analyticsResponse The AnalyticsResponse class
|
|
36
38
|
*/
|
|
37
39
|
constructor({
|
|
38
40
|
aggregate,
|
|
41
|
+
enrollments,
|
|
39
42
|
events,
|
|
40
43
|
request,
|
|
41
44
|
response
|
|
42
45
|
}) {
|
|
43
46
|
this.aggregate = aggregate;
|
|
47
|
+
this.enrollments = enrollments;
|
|
44
48
|
this.events = events;
|
|
45
49
|
this.request = request;
|
|
46
50
|
this.response = response;
|
|
@@ -63,6 +67,7 @@ class Analytics {
|
|
|
63
67
|
if (!Analytics.getAnalytics.analytics) {
|
|
64
68
|
Analytics.getAnalytics.analytics = new Analytics({
|
|
65
69
|
aggregate: new AnalyticsAggregate(dataEngine),
|
|
70
|
+
enrollments: new AnalyticsEnrollments(dataEngine),
|
|
66
71
|
events: new AnalyticsEvents(dataEngine),
|
|
67
72
|
request: AnalyticsRequest,
|
|
68
73
|
response: AnalyticsResponse
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import AnalyticsBase from './AnalyticsBase.js';
|
|
2
|
+
/**
|
|
3
|
+
* @extends module:analytics.AnalyticsBase
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* Analytics enrollments class used to request analytics enrollments data from Web API.
|
|
7
|
+
*
|
|
8
|
+
* @memberof module:analytics
|
|
9
|
+
*
|
|
10
|
+
* @see https://docs.dhis2.org/en/develop/using-the-api/dhis-core-version-236/analytics.html#webapi_enrollment_analytics
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
class AnalyticsEnrollments extends AnalyticsBase {
|
|
14
|
+
/**
|
|
15
|
+
* @param {!AnalyticsRequest} req Request object
|
|
16
|
+
*
|
|
17
|
+
* @returns {Promise} Promise that resolves with the analytics query data from the api.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const req = new analytics.request()
|
|
21
|
+
* .withProgram('eBAyeGv0exc')
|
|
22
|
+
* .addDataDimension(['Uvn6LCg7dVU','OdiHJayrsKo'])
|
|
23
|
+
* .addPeriodDimension('LAST_4_QUARTERS')
|
|
24
|
+
* .addOrgUnitDimension(['lc3eMKXaEfw','PMa2VCrupOd'])
|
|
25
|
+
* .addOrgUnitFilter('O6uvpzGd5pu')
|
|
26
|
+
* .withStartDate('2017-10-01')
|
|
27
|
+
* .withEndDate('2017-10-31');
|
|
28
|
+
*
|
|
29
|
+
* analytics.enrollments.getQuery(req)
|
|
30
|
+
* .then(console.log);
|
|
31
|
+
*/
|
|
32
|
+
getQuery(req) {
|
|
33
|
+
return this.fetch(req.withPath('enrollments/query'));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default AnalyticsEnrollments;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fixtures from '../../../__fixtures__/fixtures.js';
|
|
2
|
+
import DataEngineMock from '../__mocks__/DataEngine.js';
|
|
3
|
+
import AnalyticsEnrollments from '../AnalyticsEnrollments.js';
|
|
4
|
+
import AnalyticsRequest from '../AnalyticsRequest.js';
|
|
5
|
+
describe('analytics.enrollments', () => {
|
|
6
|
+
let enrollments;
|
|
7
|
+
let request;
|
|
8
|
+
let dataEngineMock;
|
|
9
|
+
let fixture;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
dataEngineMock = new DataEngineMock();
|
|
12
|
+
DataEngineMock.mockClear();
|
|
13
|
+
enrollments = new AnalyticsEnrollments();
|
|
14
|
+
});
|
|
15
|
+
it('should not be allowed to be called without new', () => {
|
|
16
|
+
expect(() => AnalyticsEnrollments()).toThrowErrorMatchingSnapshot();
|
|
17
|
+
});
|
|
18
|
+
it('should use the dataEngine object when it is passed', () => {
|
|
19
|
+
const dataEngineMockObject = {};
|
|
20
|
+
enrollments = new AnalyticsEnrollments(dataEngineMockObject);
|
|
21
|
+
expect(enrollments.dataEngine).toBe(dataEngineMockObject);
|
|
22
|
+
});
|
|
23
|
+
describe('.getQuery()', () => {
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
enrollments = new AnalyticsEnrollments(new DataEngineMock());
|
|
26
|
+
request = new AnalyticsRequest().addOrgUnitDimension('ImspTQPwCqd').addDimension('WZbXY0S00lP.de0FEHSIoxh').addDimension('WZbXY0S00lP.sWoqcoByYmD').addPeriodFilter('LAST_MONTH').withProgram('WSGAb5XwJ3Y').withStage('WZbXY0S00lP').withAsc('ENROLLMENTDATE').withOuMode('DESCENDANTS').withColumns('w75KJ2mc4zz').withPage(1).withPageSize(10);
|
|
27
|
+
fixture = fixtures.get('/api/analytics/enrollments');
|
|
28
|
+
dataEngineMock.query.mockReturnValue(Promise.resolve({
|
|
29
|
+
data: fixture
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
32
|
+
it('should be a function', () => {
|
|
33
|
+
expect(enrollments.getQuery).toBeInstanceOf(Function);
|
|
34
|
+
});
|
|
35
|
+
it('should resolve a promise with data', () => enrollments.getQuery(request).then(data => {
|
|
36
|
+
expect(data.width).toEqual(fixture.width);
|
|
37
|
+
expect(data.height).toEqual(fixture.height);
|
|
38
|
+
}));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useDataQuery } from '@dhis2/app-runtime';
|
|
2
|
+
import i18n from '@dhis2/d2-i18n';
|
|
3
|
+
import { Layer, CenteredContent, CircularLoader, NoticeBox } from '@dhis2/ui';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import React, { createContext, useContext } from 'react';
|
|
6
|
+
const CachedDataQueryCtx = /*#__PURE__*/createContext({});
|
|
7
|
+
|
|
8
|
+
const CachedDataQueryProvider = ({
|
|
9
|
+
query,
|
|
10
|
+
dataTransformation,
|
|
11
|
+
children
|
|
12
|
+
}) => {
|
|
13
|
+
const {
|
|
14
|
+
data: rawData,
|
|
15
|
+
...rest
|
|
16
|
+
} = useDataQuery(query);
|
|
17
|
+
const {
|
|
18
|
+
error,
|
|
19
|
+
loading
|
|
20
|
+
} = rest;
|
|
21
|
+
const data = rawData && dataTransformation ? dataTransformation(rawData) : rawData;
|
|
22
|
+
|
|
23
|
+
if (loading) {
|
|
24
|
+
return /*#__PURE__*/React.createElement(Layer, {
|
|
25
|
+
translucent: true
|
|
26
|
+
}, /*#__PURE__*/React.createElement(CenteredContent, null, /*#__PURE__*/React.createElement(CircularLoader, null)));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (error) {
|
|
30
|
+
const fallbackMsg = i18n.t('This app could not retrieve required data.');
|
|
31
|
+
return /*#__PURE__*/React.createElement(NoticeBox, {
|
|
32
|
+
error: true,
|
|
33
|
+
title: i18n.t('Network error')
|
|
34
|
+
}, error.message || fallbackMsg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return /*#__PURE__*/React.createElement(CachedDataQueryCtx.Provider, {
|
|
38
|
+
value: data
|
|
39
|
+
}, children);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
CachedDataQueryProvider.propTypes = {
|
|
43
|
+
children: PropTypes.node.isRequired,
|
|
44
|
+
query: PropTypes.object.isRequired,
|
|
45
|
+
dataTransformation: PropTypes.func
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const useCachedDataQuery = () => useContext(CachedDataQueryCtx);
|
|
49
|
+
|
|
50
|
+
export { CachedDataQueryProvider, useCachedDataQuery };
|
|
@@ -12,12 +12,9 @@ import { RenameDialog } from './RenameDialog.js';
|
|
|
12
12
|
import { SaveAsDialog } from './SaveAsDialog.js';
|
|
13
13
|
import { supportedFileTypes } from './utils.js';
|
|
14
14
|
export const FileMenu = ({
|
|
15
|
-
|
|
16
|
-
// to be removed as soon as TranslateDialog and FavoritesDialog are rewritten
|
|
17
|
-
defaultFilterVisType,
|
|
15
|
+
currentUser,
|
|
18
16
|
fileType,
|
|
19
17
|
fileObject,
|
|
20
|
-
filterVisTypes,
|
|
21
18
|
onNew,
|
|
22
19
|
onOpen,
|
|
23
20
|
onSave,
|
|
@@ -132,15 +129,13 @@ export const FileMenu = ({
|
|
|
132
129
|
}, i18n.t('File'))), /*#__PURE__*/React.createElement(OpenFileDialog, {
|
|
133
130
|
open: currentDialog === 'open',
|
|
134
131
|
type: fileType,
|
|
135
|
-
filterVisTypes: filterVisTypes,
|
|
136
|
-
defaultFilterVisType: defaultFilterVisType,
|
|
137
132
|
onClose: onDialogClose,
|
|
138
133
|
onFileSelect: id => {
|
|
139
134
|
onOpen(id);
|
|
140
135
|
onDialogClose();
|
|
141
136
|
},
|
|
142
137
|
onNew: onNew,
|
|
143
|
-
currentUser:
|
|
138
|
+
currentUser: currentUser
|
|
144
139
|
}), menuIsOpen && /*#__PURE__*/React.createElement(Layer, {
|
|
145
140
|
onClick: toggleMenu,
|
|
146
141
|
position: "fixed",
|
|
@@ -241,11 +236,9 @@ FileMenu.defaultProps = {
|
|
|
241
236
|
onTranslate: Function.prototype
|
|
242
237
|
};
|
|
243
238
|
FileMenu.propTypes = {
|
|
244
|
-
|
|
245
|
-
defaultFilterVisType: PropTypes.string,
|
|
239
|
+
currentUser: PropTypes.object,
|
|
246
240
|
fileObject: PropTypes.object,
|
|
247
241
|
fileType: PropTypes.oneOf(supportedFileTypes),
|
|
248
|
-
filterVisTypes: PropTypes.array,
|
|
249
242
|
onDelete: PropTypes.func,
|
|
250
243
|
onError: PropTypes.func,
|
|
251
244
|
onNew: PropTypes.func,
|
|
@@ -32,11 +32,9 @@ describe('The FileMenu component ', () => {
|
|
|
32
32
|
beforeEach(() => {
|
|
33
33
|
shallowFileMenu = undefined;
|
|
34
34
|
props = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
displayName: 'Test user'
|
|
39
|
-
}
|
|
35
|
+
currentUser: {
|
|
36
|
+
id: 'u1',
|
|
37
|
+
displayName: 'Test user'
|
|
40
38
|
},
|
|
41
39
|
fileType: 'visualization',
|
|
42
40
|
fileObject: undefined,
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import _JSXStyle from "styled-jsx/style";
|
|
2
|
-
import i18n from '@dhis2/d2-i18n';
|
|
3
|
-
import { MenuDivider, Tooltip } from '@dhis2/ui';
|
|
4
2
|
import cx from 'classnames';
|
|
5
3
|
import PropTypes from 'prop-types';
|
|
6
4
|
import React from 'react';
|
|
7
5
|
import styles from './styles/CustomSelectOption.style.js';
|
|
8
|
-
|
|
9
|
-
const CustomSelectOptionItem = ({
|
|
6
|
+
export const CustomSelectOption = ({
|
|
10
7
|
value,
|
|
11
8
|
label,
|
|
12
9
|
icon,
|
|
13
|
-
insertDivider,
|
|
14
10
|
onClick,
|
|
15
11
|
active,
|
|
16
12
|
disabled
|
|
17
|
-
}) => /*#__PURE__*/React.createElement(
|
|
13
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
18
14
|
onClick: e => onClick({}, e),
|
|
19
15
|
"data-value": value,
|
|
20
16
|
"data-label": label,
|
|
@@ -23,18 +19,10 @@ const CustomSelectOptionItem = ({
|
|
|
23
19
|
disabled
|
|
24
20
|
}) || "")
|
|
25
21
|
}, icon, /*#__PURE__*/React.createElement("span", {
|
|
26
|
-
className: "jsx-".concat(styles.__hash) + " " +
|
|
27
|
-
label: icon
|
|
28
|
-
}) || "")
|
|
22
|
+
className: "jsx-".concat(styles.__hash) + " " + "label"
|
|
29
23
|
}, label), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
30
24
|
id: styles.__hash
|
|
31
|
-
}, styles))
|
|
32
|
-
dense: true
|
|
33
|
-
}) : null);
|
|
34
|
-
|
|
35
|
-
export const CustomSelectOption = props => props.disabled ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
36
|
-
content: i18n.t('Not supported by this app yet')
|
|
37
|
-
}, /*#__PURE__*/React.createElement(CustomSelectOptionItem, props)) : /*#__PURE__*/React.createElement(CustomSelectOptionItem, props);
|
|
25
|
+
}, styles));
|
|
38
26
|
CustomSelectOption.propTypes = {
|
|
39
27
|
icon: PropTypes.element.isRequired,
|
|
40
28
|
label: PropTypes.string.isRequired,
|
|
@@ -43,5 +31,4 @@ CustomSelectOption.propTypes = {
|
|
|
43
31
|
disabled: PropTypes.bool,
|
|
44
32
|
onClick: PropTypes.func
|
|
45
33
|
};
|
|
46
|
-
CustomSelectOptionItem.propTypes = CustomSelectOption.propTypes;
|
|
47
34
|
export default CustomSelectOption;
|
|
@@ -4,14 +4,14 @@ import React from 'react';
|
|
|
4
4
|
import { VisTypeIcon } from '../VisTypeIcon.js';
|
|
5
5
|
import { DateField } from './DateField.js';
|
|
6
6
|
export const FileList = ({
|
|
7
|
+
type,
|
|
7
8
|
data,
|
|
8
|
-
onSelect
|
|
9
|
-
showVisTypeColumn
|
|
9
|
+
onSelect
|
|
10
10
|
}) => /*#__PURE__*/React.createElement(React.Fragment, null, data.map(visualization => /*#__PURE__*/React.createElement(DataTableRow, {
|
|
11
11
|
key: visualization.id
|
|
12
12
|
}, /*#__PURE__*/React.createElement(DataTableCell, {
|
|
13
13
|
onClick: () => onSelect(visualization.id)
|
|
14
|
-
}, visualization.displayName),
|
|
14
|
+
}, visualization.displayName), type === 'visualization' && /*#__PURE__*/React.createElement(DataTableCell, {
|
|
15
15
|
align: "center"
|
|
16
16
|
}, /*#__PURE__*/React.createElement(VisTypeIcon, {
|
|
17
17
|
type: visualization.type,
|
|
@@ -30,7 +30,7 @@ FileList.propTypes = {
|
|
|
30
30
|
lastUpdated: PropTypes.string.isRequired,
|
|
31
31
|
type: PropTypes.string
|
|
32
32
|
})).isRequired,
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
type: PropTypes.string.isRequired,
|
|
34
|
+
onSelect: PropTypes.func.isRequired
|
|
35
35
|
};
|
|
36
36
|
export default FileList;
|
|
@@ -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, { useEffect, useMemo, useState } from 'react';
|
|
8
|
-
import { VIS_TYPE_ALL, VIS_TYPE_CHARTS } from '../../modules/visTypes.js';
|
|
9
8
|
import { CreatedByFilter, CREATED_BY_ALL, CREATED_BY_ALL_BUT_CURRENT_USER, CREATED_BY_CURRENT_USER } 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
|
-
import { getTranslatedString, AOTypeMap } from './utils.js';
|
|
15
|
-
import { VisTypeFilter } from './VisTypeFilter.js';
|
|
13
|
+
import { getTranslatedString, AO_TYPE_VISUALIZATION, AO_TYPE_EVENT_REPORT, AO_TYPE_EVENT_VISUALIZATION, AOTypeMap } from './utils.js';
|
|
14
|
+
import { VisTypeFilter, VIS_TYPE_ALL, VIS_TYPE_CHARTS } from './VisTypeFilter.js';
|
|
16
15
|
|
|
17
16
|
const getQuery = type => ({
|
|
18
17
|
files: {
|
|
@@ -43,8 +42,6 @@ const getQuery = type => ({
|
|
|
43
42
|
export const OpenFileDialog = ({
|
|
44
43
|
type,
|
|
45
44
|
open,
|
|
46
|
-
filterVisTypes,
|
|
47
|
-
defaultFilterVisType,
|
|
48
45
|
onClose,
|
|
49
46
|
onFileSelect,
|
|
50
47
|
onNew,
|
|
@@ -54,7 +51,7 @@ export const OpenFileDialog = ({
|
|
|
54
51
|
const defaultFilters = {
|
|
55
52
|
searchTerm: '',
|
|
56
53
|
createdBy: CREATED_BY_ALL,
|
|
57
|
-
visType:
|
|
54
|
+
visType: VIS_TYPE_ALL
|
|
58
55
|
};
|
|
59
56
|
const [{
|
|
60
57
|
sortField,
|
|
@@ -85,23 +82,26 @@ export const OpenFileDialog = ({
|
|
|
85
82
|
break;
|
|
86
83
|
}
|
|
87
84
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
break;
|
|
85
|
+
switch (filters.visType) {
|
|
86
|
+
case VIS_TYPE_ALL:
|
|
87
|
+
break;
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
case VIS_TYPE_CHARTS:
|
|
90
|
+
queryFilters.push('type:!eq:PIVOT_TABLE');
|
|
91
|
+
break;
|
|
96
92
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
93
|
+
default:
|
|
94
|
+
queryFilters.push("type:eq:".concat(filters.visType));
|
|
95
|
+
break;
|
|
101
96
|
}
|
|
102
97
|
|
|
103
98
|
if (filters.searchTerm) {
|
|
104
99
|
queryFilters.push("name:ilike:".concat(filters.searchTerm));
|
|
100
|
+
} // for ER 2.38 only show line list ER types
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if (type === AO_TYPE_EVENT_REPORT || type === AO_TYPE_EVENT_VISUALIZATION) {
|
|
104
|
+
queryFilters.push('dataType:eq:EVENTS');
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
return queryFilters;
|
|
@@ -132,13 +132,16 @@ export const OpenFileDialog = ({
|
|
|
132
132
|
}
|
|
133
133
|
}, [open, page, sortField, sortDirection]);
|
|
134
134
|
useEffect(() => {
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
135
|
+
// avoid fetching data when the dialog is first rendered (hidden)
|
|
136
|
+
if (open) {
|
|
137
|
+
// reset pagination when filters are applied/changed
|
|
138
|
+
setPage(1);
|
|
139
|
+
refetch({
|
|
140
|
+
sortField,
|
|
141
|
+
sortDirection,
|
|
142
|
+
filters: formatFilters()
|
|
143
|
+
});
|
|
144
|
+
}
|
|
142
145
|
}, [filters]);
|
|
143
146
|
const headers = [{
|
|
144
147
|
field: 'displayName',
|
|
@@ -154,7 +157,7 @@ export const OpenFileDialog = ({
|
|
|
154
157
|
width: '110px'
|
|
155
158
|
}];
|
|
156
159
|
|
|
157
|
-
if (
|
|
160
|
+
if (type === AO_TYPE_VISUALIZATION) {
|
|
158
161
|
headers.splice(1, 0, {
|
|
159
162
|
field: 'type',
|
|
160
163
|
label: i18n.t('Type'),
|
|
@@ -187,10 +190,9 @@ export const OpenFileDialog = ({
|
|
|
187
190
|
searchTerm: value
|
|
188
191
|
}), 200));
|
|
189
192
|
}
|
|
190
|
-
})),
|
|
193
|
+
})), type === AO_TYPE_VISUALIZATION && /*#__PURE__*/React.createElement("div", {
|
|
191
194
|
className: "jsx-".concat(styles.__hash) + " " + "type-field-container"
|
|
192
195
|
}, /*#__PURE__*/React.createElement(VisTypeFilter, {
|
|
193
|
-
visTypes: filterVisTypes,
|
|
194
196
|
selected: filters.visType,
|
|
195
197
|
onChange: value => setFilters({ ...filters,
|
|
196
198
|
visType: value
|
|
@@ -259,9 +261,9 @@ export const OpenFileDialog = ({
|
|
|
259
261
|
onClose();
|
|
260
262
|
}
|
|
261
263
|
}, getTranslatedString(type, 'newButtonLabel'))))))))), (data === null || data === void 0 ? void 0 : data.files[AOTypeMap[type].apiEndpoint].length) > 0 && /*#__PURE__*/React.createElement(FileList, {
|
|
264
|
+
type: type,
|
|
262
265
|
data: data.files[AOTypeMap[type].apiEndpoint],
|
|
263
|
-
onSelect: onFileSelect
|
|
264
|
-
showVisTypeColumn: Boolean(filterVisTypes === null || filterVisTypes === void 0 ? void 0 : filterVisTypes.length)
|
|
266
|
+
onSelect: onFileSelect
|
|
265
267
|
}))), (data === null || data === void 0 ? void 0 : data.files[AOTypeMap[type].apiEndpoint].length) > 0 && /*#__PURE__*/React.createElement(DataTableToolbar, {
|
|
266
268
|
position: "bottom"
|
|
267
269
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -280,8 +282,6 @@ OpenFileDialog.propTypes = {
|
|
|
280
282
|
type: PropTypes.oneOf(Object.keys(AOTypeMap)).isRequired,
|
|
281
283
|
onClose: PropTypes.func.isRequired,
|
|
282
284
|
onFileSelect: PropTypes.func.isRequired,
|
|
283
|
-
onNew: PropTypes.func.isRequired
|
|
284
|
-
defaultFilterVisType: PropTypes.string,
|
|
285
|
-
filterVisTypes: PropTypes.array
|
|
285
|
+
onNew: PropTypes.func.isRequired
|
|
286
286
|
};
|
|
287
287
|
export default OpenFileDialog;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { colors, spacers } from '@dhis2/ui';
|
|
2
|
-
export const styles = [".data-table-body.jsx-
|
|
3
|
-
styles.__hash = "
|
|
2
|
+
export const styles = [".data-table-body.jsx-1047699013{min-height:465px;}", ".pagination-controls.jsx-1047699013{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;}", ".search-and-filter-bar.jsx-1047699013{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:".concat(spacers.dp4, ";-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:").concat(spacers.dp8, ";}"), ".search-field-container.jsx-1047699013{min-width:220px;}", ".type-field-container.jsx-1047699013,.created-by-field-container.jsx-1047699013{min-width:180px;}", ".info-cell.jsx-1047699013{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;margin:".concat(spacers.dp32, " 0;}"), ".info-container.jsx-1047699013{max-width:400px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}", ".info-text.jsx-1047699013{text-align:center;font-size:14px;line-height:19px;color:".concat(colors.grey700, ";}"), ".info-button.jsx-1047699013{margin-top:".concat(spacers.dp12, ";}")];
|
|
3
|
+
styles.__hash = "1047699013";
|