@dhis2/analytics 26.2.0 → 26.3.0-alpha.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.
@@ -9,6 +9,7 @@ var _AnalyticsEnrollments = _interopRequireDefault(require("./AnalyticsEnrollmen
9
9
  var _AnalyticsEvents = _interopRequireDefault(require("./AnalyticsEvents.js"));
10
10
  var _AnalyticsRequest = _interopRequireDefault(require("./AnalyticsRequest.js"));
11
11
  var _AnalyticsResponse = _interopRequireDefault(require("./AnalyticsResponse.js"));
12
+ var _AnalyticsTrackedEntities = _interopRequireDefault(require("./AnalyticsTrackedEntities.js"));
12
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14
  /**
14
15
  * @module analytics
@@ -19,6 +20,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
20
  * Analytics class used to request analytics data from Web API.
20
21
  *
21
22
  * @requires analytics.AnalyticsAggregate
23
+ * @requires analytics.AnalyticsTrackedEntities
24
+ * @requires analytics.AnalyticsEnrollments
22
25
  * @requires analytics.AnalyticsEvents
23
26
  * @requires analytics.AnalyticsRequest
24
27
  * @requires analytics.AnalyticsResponse
@@ -38,6 +41,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
38
41
  class Analytics {
39
42
  /**
40
43
  * @param {!module:analytics.AnalyticsAggregate} analyticsAggregate The AnalyticsAggregate instance
44
+ * @param {!module:analytics.AnalyticsTrackedEntities} analyticsTrackedEntities The AnalyticsTrackedEntities instance
41
45
  * @param {!module:analytics.AnalyticsEnrollments} analyticsEnrollments The AnalyticsEnrollments instance
42
46
  * @param {!module:analytics.AnalyticsEvents} analyticsEvents The AnalyticsEvents instance
43
47
  * @param {!module:analytics.AnalyticsRequest} analyticsRequest The AnalyticsRequest class
@@ -46,12 +50,14 @@ class Analytics {
46
50
  constructor(_ref) {
47
51
  let {
48
52
  aggregate,
53
+ trackedEntities,
49
54
  enrollments,
50
55
  events,
51
56
  request,
52
57
  response
53
58
  } = _ref;
54
59
  this.aggregate = aggregate;
60
+ this.trackedEntities = trackedEntities;
55
61
  this.enrollments = enrollments;
56
62
  this.events = events;
57
63
  this.request = request;
@@ -74,6 +80,7 @@ class Analytics {
74
80
  if (!Analytics.getAnalytics.analytics) {
75
81
  Analytics.getAnalytics.analytics = new Analytics({
76
82
  aggregate: new _AnalyticsAggregate.default(dataEngine),
83
+ trackedEntities: new _AnalyticsTrackedEntities.default(dataEngine),
77
84
  enrollments: new _AnalyticsEnrollments.default(dataEngine),
78
85
  events: new _AnalyticsEvents.default(dataEngine),
79
86
  request: _AnalyticsRequest.default,
@@ -6,15 +6,21 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _sortBy = _interopRequireDefault(require("lodash/sortBy"));
8
8
  var _AnalyticsRequest = _interopRequireDefault(require("./AnalyticsRequest.js"));
9
+ var _utils = require("./utils.js");
9
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
11
  const analyticsQuery = {
11
12
  resource: 'analytics',
12
13
  id: _ref => {
13
14
  let {
14
15
  path,
15
- program
16
+ program,
17
+ trackedEntityType
16
18
  } = _ref;
17
- return [path, program].filter(Boolean).join('/');
19
+ return (0, _utils.formatRequestPath)({
20
+ path,
21
+ program,
22
+ trackedEntityType
23
+ });
18
24
  },
19
25
  params: _ref2 => {
20
26
  let {
@@ -34,9 +40,14 @@ const analyticsDataQuery = {
34
40
  id: _ref3 => {
35
41
  let {
36
42
  path,
37
- program
43
+ program,
44
+ trackedEntityType
38
45
  } = _ref3;
39
- return [path, program].filter(Boolean).join('/');
46
+ return (0, _utils.formatRequestPath)({
47
+ path,
48
+ program,
49
+ trackedEntityType
50
+ });
40
51
  },
41
52
  params: _ref4 => {
42
53
  let {
@@ -58,9 +69,14 @@ const analyticsMetaDataQuery = {
58
69
  id: _ref5 => {
59
70
  let {
60
71
  path,
61
- program
72
+ program,
73
+ trackedEntityType
62
74
  } = _ref5;
63
- return [path, program].filter(Boolean).join('/');
75
+ return (0, _utils.formatRequestPath)({
76
+ path,
77
+ program,
78
+ trackedEntityType
79
+ });
64
80
  },
65
81
  params: _ref6 => {
66
82
  let {
@@ -152,6 +168,7 @@ class AnalyticsBase {
152
168
  variables: {
153
169
  path: req.path,
154
170
  program: req.program,
171
+ trackedEntityType: req.trackedEntityType,
155
172
  dimensions: generateDimensionStrings(req.dimensions),
156
173
  filters: generateDimensionStrings(req.filters),
157
174
  parameters: req.parameters,
@@ -194,6 +211,7 @@ class AnalyticsBase {
194
211
  variables: {
195
212
  path: req.path,
196
213
  program: req.program,
214
+ trackedEntityType: req.trackedEntityType,
197
215
  dimensions: generateDimensionStrings(req.dimensions, options),
198
216
  filters: generateDimensionStrings(req.filters, options),
199
217
  parameters: req.parameters
@@ -10,6 +10,7 @@ var _AnalyticsRequestBase = _interopRequireDefault(require("./AnalyticsRequestBa
10
10
  var _AnalyticsRequestDimensionsMixin = _interopRequireDefault(require("./AnalyticsRequestDimensionsMixin.js"));
11
11
  var _AnalyticsRequestFiltersMixin = _interopRequireDefault(require("./AnalyticsRequestFiltersMixin.js"));
12
12
  var _AnalyticsRequestPropertiesMixin = _interopRequireDefault(require("./AnalyticsRequestPropertiesMixin.js"));
13
+ var _utils = require("./utils.js");
13
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
15
  /**
15
16
  * @description
@@ -47,6 +48,7 @@ class AnalyticsRequest extends (0, _AnalyticsRequestDimensionsMixin.default)((0,
47
48
  fromVisualization(visualization) {
48
49
  let passFilterAsDimension = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
49
50
  let request = this;
51
+ const outputType = visualization.outputType;
50
52
 
51
53
  // extract dimensions from visualization
52
54
  const columns = visualization.columns || [];
@@ -57,19 +59,28 @@ class AnalyticsRequest extends (0, _AnalyticsRequestDimensionsMixin.default)((0,
57
59
  if ((_d$legendSet = d.legendSet) !== null && _d$legendSet !== void 0 && _d$legendSet.id) {
58
60
  dimension += `-${d.legendSet.id}`;
59
61
  }
60
- if ((_d$programStage = d.programStage) !== null && _d$programStage !== void 0 && _d$programStage.id) {
61
- dimension = `${d.programStage.id}.${dimension}`;
62
- }
63
62
  if (d.filter) {
64
63
  dimension += `:${d.filter}`;
65
64
  }
65
+ const programStageId = (_d$programStage = d.programStage) === null || _d$programStage === void 0 ? void 0 : _d$programStage.id;
66
66
  if ((_d$repetition = d.repetition) !== null && _d$repetition !== void 0 && (_d$repetition$indexes = _d$repetition.indexes) !== null && _d$repetition$indexes !== void 0 && _d$repetition$indexes.length) {
67
67
  d.repetition.indexes.forEach(index => {
68
- request = request.addDimension(dimension.replace(/\./, `[${index}].`));
68
+ var _d$program;
69
+ request = request.addDimension((0, _utils.formatDimension)({
70
+ programId: (_d$program = d.program) === null || _d$program === void 0 ? void 0 : _d$program.id,
71
+ programStageId: `${programStageId}[${index}]`,
72
+ dimension,
73
+ outputType
74
+ }));
69
75
  });
70
76
  } else {
71
- var _d$items;
72
- request = request.addDimension(dimension, (_d$items = d.items) === null || _d$items === void 0 ? void 0 : _d$items.map(item => item.id));
77
+ var _d$program2, _d$items;
78
+ request = request.addDimension((0, _utils.formatDimension)({
79
+ programId: (_d$program2 = d.program) === null || _d$program2 === void 0 ? void 0 : _d$program2.id,
80
+ programStageId,
81
+ dimension,
82
+ outputType
83
+ }), (_d$items = d.items) === null || _d$items === void 0 ? void 0 : _d$items.map(item => item.id));
73
84
  }
74
85
  });
75
86
 
@@ -84,17 +95,29 @@ class AnalyticsRequest extends (0, _AnalyticsRequestDimensionsMixin.default)((0,
84
95
  request = request.addDimension(f.dimension, (_f$items = f.items) === null || _f$items === void 0 ? void 0 : _f$items.map(item => item.id));
85
96
  } else {
86
97
  var _f$programStage, _f$repetition, _f$repetition$indexes;
87
- let filterString = (_f$programStage = f.programStage) !== null && _f$programStage !== void 0 && _f$programStage.id ? `${f.programStage.id}.${f.dimension}` : f.dimension;
98
+ let filterString = f.dimension;
88
99
  if (f.filter) {
89
100
  filterString += `:${f.filter}`;
90
101
  }
102
+ const programStageId = (_f$programStage = f.programStage) === null || _f$programStage === void 0 ? void 0 : _f$programStage.id;
91
103
  if ((_f$repetition = f.repetition) !== null && _f$repetition !== void 0 && (_f$repetition$indexes = _f$repetition.indexes) !== null && _f$repetition$indexes !== void 0 && _f$repetition$indexes.length) {
92
104
  f.repetition.indexes.forEach(index => {
93
- request = request.addFilter(filterString.replace(/\./, `[${index}].`));
105
+ var _f$program;
106
+ request = request.addFilter((0, _utils.formatDimension)({
107
+ programId: (_f$program = f.program) === null || _f$program === void 0 ? void 0 : _f$program.id,
108
+ programStageId: `${programStageId}[${index}]`,
109
+ dimension: filterString,
110
+ outputType
111
+ }));
94
112
  });
95
113
  } else {
96
- var _f$items2;
97
- request = request.addFilter(filterString, (_f$items2 = f.items) === null || _f$items2 === void 0 ? void 0 : _f$items2.map(item => item.id));
114
+ var _f$program2, _f$items2;
115
+ request = request.addFilter((0, _utils.formatDimension)({
116
+ programId: (_f$program2 = f.program) === null || _f$program2 === void 0 ? void 0 : _f$program2.id,
117
+ programStageId,
118
+ dimension: filterString,
119
+ outputType
120
+ }), (_f$items2 = f.items) === null || _f$items2 === void 0 ? void 0 : _f$items2.map(item => item.id));
98
121
  }
99
122
  }
100
123
  });
@@ -24,6 +24,7 @@ class AnalyticsRequestBase {
24
24
  format = 'json',
25
25
  path,
26
26
  program,
27
+ trackedEntityType,
27
28
  dimensions = [],
28
29
  filters = [],
29
30
  parameters = {}
@@ -32,6 +33,7 @@ class AnalyticsRequestBase {
32
33
  this.format = format.toLowerCase();
33
34
  this.path = path;
34
35
  this.program = program;
36
+ this.trackedEntityType = trackedEntityType;
35
37
  this.dimensions = dimensions;
36
38
  this.filters = filters;
37
39
  this.parameters = {
@@ -70,7 +72,7 @@ class AnalyticsRequestBase {
70
72
  }
71
73
  return dimension;
72
74
  });
73
- const endPoint = [this.endPoint, this.path, this.program].filter(e => !!e).join('/');
75
+ const endPoint = [this.endPoint, this.path, this.program, this.trackedEntityType].filter(Boolean).join('/');
74
76
  return `${endPoint}.${this.format}?dimension=${encodedDimensions.join('&dimension=')}`;
75
77
  }
76
78
 
@@ -497,6 +497,25 @@ class extends base {
497
497
  return new _AnalyticsRequest.default(this);
498
498
  }
499
499
 
500
+ /**
501
+ * Sets the tracked entity type for the request.
502
+ * It appends the tracked entity type id to the request's path.
503
+ *
504
+ * @param {!String} trackedEntityType The tracked entity type id
505
+ *
506
+ * @returns {AnalyticsRequest} A new instance of the class for chaining purposes
507
+ *
508
+ * @example
509
+ * const req = new analytics.request()
510
+ * .withTrackedEntityType('nEenWmSyUEp');
511
+ */
512
+ withTrackedEntityType(trackedEntityType) {
513
+ if (trackedEntityType) {
514
+ this.trackedEntityType = trackedEntityType;
515
+ }
516
+ return new _AnalyticsRequest.default(this);
517
+ }
518
+
500
519
  /**
501
520
  * Sets the program for the request.
502
521
  * It appends the program id to the request's path.
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _AnalyticsBase = _interopRequireDefault(require("./AnalyticsBase.js"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ /**
10
+ * @extends module:analytics.AnalyticsBase
11
+ *
12
+ * @description
13
+ * Analytics tracked entities class used to request analytics tracked entities data from Web API.
14
+ *
15
+ * @memberof module:analytics
16
+ */
17
+ class AnalyticsTrackedEntities extends _AnalyticsBase.default {
18
+ /**
19
+ * @param {!AnalyticsRequest} req Request object
20
+ *
21
+ * @returns {Promise} Promise that resolves with the analytics query data from the api.
22
+ *
23
+ * @example
24
+ // TODO: provide working example
25
+ */
26
+ getQuery(req) {
27
+ return this.fetch(req.withPath('trackedEntities/query'));
28
+ }
29
+ }
30
+ var _default = AnalyticsTrackedEntities;
31
+ exports.default = _default;
@@ -3,10 +3,31 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.customEncodeURIComponent = void 0;
6
+ exports.formatRequestPath = exports.formatDimension = exports.customEncodeURIComponent = void 0;
7
7
  // Define our very own special list of characters that we don't want to encode in the URI
8
8
  const whitelistURI = ',&$=/;:';
9
9
  const whitelistURICodes = whitelistURI.split('').map(c => encodeURIComponent(c));
10
10
  const whitelistRegExp = new RegExp(`(?:${whitelistURICodes.join('|')})`, 'g');
11
11
  const customEncodeURIComponent = uri => encodeURIComponent(uri).replace(whitelistRegExp, decodeURIComponent);
12
- exports.customEncodeURIComponent = customEncodeURIComponent;
12
+ exports.customEncodeURIComponent = customEncodeURIComponent;
13
+ const formatRequestPath = _ref => {
14
+ let {
15
+ path,
16
+ program,
17
+ trackedEntityType
18
+ } = _ref;
19
+ return [path, program, trackedEntityType].filter(Boolean).join('/');
20
+ };
21
+ exports.formatRequestPath = formatRequestPath;
22
+ const formatDimension = _ref2 => {
23
+ let {
24
+ outputType,
25
+ programId,
26
+ programStageId,
27
+ dimension
28
+ } = _ref2;
29
+ return [
30
+ // XXX it would be clearer to have this consistent with what is sent in the request as for EVENT/ENROLLMENT
31
+ outputType === 'TRACKED_ENTITY' ? programId : undefined, programStageId, dimension].filter(Boolean).join('.');
32
+ };
33
+ exports.formatDimension = formatDimension;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.DIMENSION_PROP_REPETITION = exports.DIMENSION_PROP_PROGRAM_STAGE = exports.DIMENSION_PROP_LEGEND_SET = exports.DIMENSION_PROP_ITEMS = exports.DIMENSION_PROP_ID = exports.DIMENSION_PROP_FILTER = exports.DIMENSION_PROPS = exports.DIMENSION = void 0;
6
+ exports.DIMENSION_PROP_REPETITION = exports.DIMENSION_PROP_PROGRAM_STAGE = exports.DIMENSION_PROP_PROGRAM = exports.DIMENSION_PROP_LEGEND_SET = exports.DIMENSION_PROP_ITEMS = exports.DIMENSION_PROP_ID = exports.DIMENSION_PROP_FILTER = exports.DIMENSION_PROPS = exports.DIMENSION = void 0;
7
7
  var _isObject = _interopRequireDefault(require("lodash/isObject"));
8
8
  var _isString = _interopRequireDefault(require("lodash/isString"));
9
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -43,6 +43,13 @@ const DIMENSION_PROP_LEGEND_SET = {
43
43
  isValid: prop => (0, _isString.default)(prop)
44
44
  };
45
45
  exports.DIMENSION_PROP_LEGEND_SET = DIMENSION_PROP_LEGEND_SET;
46
+ const DIMENSION_PROP_PROGRAM = {
47
+ name: 'program',
48
+ defaultValue: {},
49
+ required: false,
50
+ isValid: prop => (0, _isObject.default)(prop)
51
+ };
52
+ exports.DIMENSION_PROP_PROGRAM = DIMENSION_PROP_PROGRAM;
46
53
  const DIMENSION_PROP_PROGRAM_STAGE = {
47
54
  name: 'programStage',
48
55
  defaultValue: {},
@@ -57,5 +64,5 @@ const DIMENSION_PROP_REPETITION = {
57
64
  isValid: prop => Array.isArray(prop)
58
65
  };
59
66
  exports.DIMENSION_PROP_REPETITION = DIMENSION_PROP_REPETITION;
60
- const DIMENSION_PROPS = [DIMENSION_PROP_ID, DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION];
67
+ const DIMENSION_PROPS = [DIMENSION_PROP_ID, DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, DIMENSION_PROP_PROGRAM, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION];
61
68
  exports.DIMENSION_PROPS = DIMENSION_PROPS;
@@ -21,6 +21,9 @@ const dimensionCreate = function (dimensionId) {
21
21
  ...(args.legendSet && {
22
22
  [_dimension.DIMENSION_PROP_LEGEND_SET.name]: args.legendSet
23
23
  }),
24
+ ...(args.program && {
25
+ [_dimension.DIMENSION_PROP_PROGRAM.name]: args.program
26
+ }),
24
27
  ...(args.programStage && {
25
28
  [_dimension.DIMENSION_PROP_PROGRAM_STAGE.name]: args.programStage
26
29
  }),
@@ -6,12 +6,15 @@ import AnalyticsEnrollments from './AnalyticsEnrollments.js';
6
6
  import AnalyticsEvents from './AnalyticsEvents.js';
7
7
  import AnalyticsRequest from './AnalyticsRequest.js';
8
8
  import AnalyticsResponse from './AnalyticsResponse.js';
9
+ import AnalyticsTrackedEntities from './AnalyticsTrackedEntities.js';
9
10
 
10
11
  /**
11
12
  * @description
12
13
  * Analytics class used to request analytics data from Web API.
13
14
  *
14
15
  * @requires analytics.AnalyticsAggregate
16
+ * @requires analytics.AnalyticsTrackedEntities
17
+ * @requires analytics.AnalyticsEnrollments
15
18
  * @requires analytics.AnalyticsEvents
16
19
  * @requires analytics.AnalyticsRequest
17
20
  * @requires analytics.AnalyticsResponse
@@ -31,6 +34,7 @@ import AnalyticsResponse from './AnalyticsResponse.js';
31
34
  class Analytics {
32
35
  /**
33
36
  * @param {!module:analytics.AnalyticsAggregate} analyticsAggregate The AnalyticsAggregate instance
37
+ * @param {!module:analytics.AnalyticsTrackedEntities} analyticsTrackedEntities The AnalyticsTrackedEntities instance
34
38
  * @param {!module:analytics.AnalyticsEnrollments} analyticsEnrollments The AnalyticsEnrollments instance
35
39
  * @param {!module:analytics.AnalyticsEvents} analyticsEvents The AnalyticsEvents instance
36
40
  * @param {!module:analytics.AnalyticsRequest} analyticsRequest The AnalyticsRequest class
@@ -39,12 +43,14 @@ class Analytics {
39
43
  constructor(_ref) {
40
44
  let {
41
45
  aggregate,
46
+ trackedEntities,
42
47
  enrollments,
43
48
  events,
44
49
  request,
45
50
  response
46
51
  } = _ref;
47
52
  this.aggregate = aggregate;
53
+ this.trackedEntities = trackedEntities;
48
54
  this.enrollments = enrollments;
49
55
  this.events = events;
50
56
  this.request = request;
@@ -67,6 +73,7 @@ class Analytics {
67
73
  if (!Analytics.getAnalytics.analytics) {
68
74
  Analytics.getAnalytics.analytics = new Analytics({
69
75
  aggregate: new AnalyticsAggregate(dataEngine),
76
+ trackedEntities: new AnalyticsTrackedEntities(dataEngine),
70
77
  enrollments: new AnalyticsEnrollments(dataEngine),
71
78
  events: new AnalyticsEvents(dataEngine),
72
79
  request: AnalyticsRequest,
@@ -1,13 +1,19 @@
1
1
  import sortBy from 'lodash/sortBy';
2
2
  import AnalyticsRequest from './AnalyticsRequest.js';
3
+ import { formatRequestPath } from './utils.js';
3
4
  const analyticsQuery = {
4
5
  resource: 'analytics',
5
6
  id: _ref => {
6
7
  let {
7
8
  path,
8
- program
9
+ program,
10
+ trackedEntityType
9
11
  } = _ref;
10
- return [path, program].filter(Boolean).join('/');
12
+ return formatRequestPath({
13
+ path,
14
+ program,
15
+ trackedEntityType
16
+ });
11
17
  },
12
18
  params: _ref2 => {
13
19
  let {
@@ -27,9 +33,14 @@ const analyticsDataQuery = {
27
33
  id: _ref3 => {
28
34
  let {
29
35
  path,
30
- program
36
+ program,
37
+ trackedEntityType
31
38
  } = _ref3;
32
- return [path, program].filter(Boolean).join('/');
39
+ return formatRequestPath({
40
+ path,
41
+ program,
42
+ trackedEntityType
43
+ });
33
44
  },
34
45
  params: _ref4 => {
35
46
  let {
@@ -51,9 +62,14 @@ const analyticsMetaDataQuery = {
51
62
  id: _ref5 => {
52
63
  let {
53
64
  path,
54
- program
65
+ program,
66
+ trackedEntityType
55
67
  } = _ref5;
56
- return [path, program].filter(Boolean).join('/');
68
+ return formatRequestPath({
69
+ path,
70
+ program,
71
+ trackedEntityType
72
+ });
57
73
  },
58
74
  params: _ref6 => {
59
75
  let {
@@ -145,6 +161,7 @@ class AnalyticsBase {
145
161
  variables: {
146
162
  path: req.path,
147
163
  program: req.program,
164
+ trackedEntityType: req.trackedEntityType,
148
165
  dimensions: generateDimensionStrings(req.dimensions),
149
166
  filters: generateDimensionStrings(req.filters),
150
167
  parameters: req.parameters,
@@ -187,6 +204,7 @@ class AnalyticsBase {
187
204
  variables: {
188
205
  path: req.path,
189
206
  program: req.program,
207
+ trackedEntityType: req.trackedEntityType,
190
208
  dimensions: generateDimensionStrings(req.dimensions, options),
191
209
  filters: generateDimensionStrings(req.filters, options),
192
210
  parameters: req.parameters
@@ -4,6 +4,7 @@ import AnalyticsRequestBase from './AnalyticsRequestBase.js';
4
4
  import AnalyticsRequestDimensionsMixin from './AnalyticsRequestDimensionsMixin.js';
5
5
  import AnalyticsRequestFiltersMixin from './AnalyticsRequestFiltersMixin.js';
6
6
  import AnalyticsRequestPropertiesMixin from './AnalyticsRequestPropertiesMixin.js';
7
+ import { formatDimension } from './utils.js';
7
8
 
8
9
  /**
9
10
  * @description
@@ -41,6 +42,7 @@ class AnalyticsRequest extends AnalyticsRequestDimensionsMixin(AnalyticsRequestF
41
42
  fromVisualization(visualization) {
42
43
  let passFilterAsDimension = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
43
44
  let request = this;
45
+ const outputType = visualization.outputType;
44
46
 
45
47
  // extract dimensions from visualization
46
48
  const columns = visualization.columns || [];
@@ -51,19 +53,28 @@ class AnalyticsRequest extends AnalyticsRequestDimensionsMixin(AnalyticsRequestF
51
53
  if ((_d$legendSet = d.legendSet) !== null && _d$legendSet !== void 0 && _d$legendSet.id) {
52
54
  dimension += `-${d.legendSet.id}`;
53
55
  }
54
- if ((_d$programStage = d.programStage) !== null && _d$programStage !== void 0 && _d$programStage.id) {
55
- dimension = `${d.programStage.id}.${dimension}`;
56
- }
57
56
  if (d.filter) {
58
57
  dimension += `:${d.filter}`;
59
58
  }
59
+ const programStageId = (_d$programStage = d.programStage) === null || _d$programStage === void 0 ? void 0 : _d$programStage.id;
60
60
  if ((_d$repetition = d.repetition) !== null && _d$repetition !== void 0 && (_d$repetition$indexes = _d$repetition.indexes) !== null && _d$repetition$indexes !== void 0 && _d$repetition$indexes.length) {
61
61
  d.repetition.indexes.forEach(index => {
62
- request = request.addDimension(dimension.replace(/\./, `[${index}].`));
62
+ var _d$program;
63
+ request = request.addDimension(formatDimension({
64
+ programId: (_d$program = d.program) === null || _d$program === void 0 ? void 0 : _d$program.id,
65
+ programStageId: `${programStageId}[${index}]`,
66
+ dimension,
67
+ outputType
68
+ }));
63
69
  });
64
70
  } else {
65
- var _d$items;
66
- request = request.addDimension(dimension, (_d$items = d.items) === null || _d$items === void 0 ? void 0 : _d$items.map(item => item.id));
71
+ var _d$program2, _d$items;
72
+ request = request.addDimension(formatDimension({
73
+ programId: (_d$program2 = d.program) === null || _d$program2 === void 0 ? void 0 : _d$program2.id,
74
+ programStageId,
75
+ dimension,
76
+ outputType
77
+ }), (_d$items = d.items) === null || _d$items === void 0 ? void 0 : _d$items.map(item => item.id));
67
78
  }
68
79
  });
69
80
 
@@ -78,17 +89,29 @@ class AnalyticsRequest extends AnalyticsRequestDimensionsMixin(AnalyticsRequestF
78
89
  request = request.addDimension(f.dimension, (_f$items = f.items) === null || _f$items === void 0 ? void 0 : _f$items.map(item => item.id));
79
90
  } else {
80
91
  var _f$programStage, _f$repetition, _f$repetition$indexes;
81
- let filterString = (_f$programStage = f.programStage) !== null && _f$programStage !== void 0 && _f$programStage.id ? `${f.programStage.id}.${f.dimension}` : f.dimension;
92
+ let filterString = f.dimension;
82
93
  if (f.filter) {
83
94
  filterString += `:${f.filter}`;
84
95
  }
96
+ const programStageId = (_f$programStage = f.programStage) === null || _f$programStage === void 0 ? void 0 : _f$programStage.id;
85
97
  if ((_f$repetition = f.repetition) !== null && _f$repetition !== void 0 && (_f$repetition$indexes = _f$repetition.indexes) !== null && _f$repetition$indexes !== void 0 && _f$repetition$indexes.length) {
86
98
  f.repetition.indexes.forEach(index => {
87
- request = request.addFilter(filterString.replace(/\./, `[${index}].`));
99
+ var _f$program;
100
+ request = request.addFilter(formatDimension({
101
+ programId: (_f$program = f.program) === null || _f$program === void 0 ? void 0 : _f$program.id,
102
+ programStageId: `${programStageId}[${index}]`,
103
+ dimension: filterString,
104
+ outputType
105
+ }));
88
106
  });
89
107
  } else {
90
- var _f$items2;
91
- request = request.addFilter(filterString, (_f$items2 = f.items) === null || _f$items2 === void 0 ? void 0 : _f$items2.map(item => item.id));
108
+ var _f$program2, _f$items2;
109
+ request = request.addFilter(formatDimension({
110
+ programId: (_f$program2 = f.program) === null || _f$program2 === void 0 ? void 0 : _f$program2.id,
111
+ programStageId,
112
+ dimension: filterString,
113
+ outputType
114
+ }), (_f$items2 = f.items) === null || _f$items2 === void 0 ? void 0 : _f$items2.map(item => item.id));
92
115
  }
93
116
  }
94
117
  });
@@ -18,6 +18,7 @@ class AnalyticsRequestBase {
18
18
  format = 'json',
19
19
  path,
20
20
  program,
21
+ trackedEntityType,
21
22
  dimensions = [],
22
23
  filters = [],
23
24
  parameters = {}
@@ -26,6 +27,7 @@ class AnalyticsRequestBase {
26
27
  this.format = format.toLowerCase();
27
28
  this.path = path;
28
29
  this.program = program;
30
+ this.trackedEntityType = trackedEntityType;
29
31
  this.dimensions = dimensions;
30
32
  this.filters = filters;
31
33
  this.parameters = {
@@ -64,7 +66,7 @@ class AnalyticsRequestBase {
64
66
  }
65
67
  return dimension;
66
68
  });
67
- const endPoint = [this.endPoint, this.path, this.program].filter(e => !!e).join('/');
69
+ const endPoint = [this.endPoint, this.path, this.program, this.trackedEntityType].filter(Boolean).join('/');
68
70
  return `${endPoint}.${this.format}?dimension=${encodedDimensions.join('&dimension=')}`;
69
71
  }
70
72
 
@@ -491,6 +491,25 @@ class extends base {
491
491
  return new AnalyticsRequest(this);
492
492
  }
493
493
 
494
+ /**
495
+ * Sets the tracked entity type for the request.
496
+ * It appends the tracked entity type id to the request's path.
497
+ *
498
+ * @param {!String} trackedEntityType The tracked entity type id
499
+ *
500
+ * @returns {AnalyticsRequest} A new instance of the class for chaining purposes
501
+ *
502
+ * @example
503
+ * const req = new analytics.request()
504
+ * .withTrackedEntityType('nEenWmSyUEp');
505
+ */
506
+ withTrackedEntityType(trackedEntityType) {
507
+ if (trackedEntityType) {
508
+ this.trackedEntityType = trackedEntityType;
509
+ }
510
+ return new AnalyticsRequest(this);
511
+ }
512
+
494
513
  /**
495
514
  * Sets the program for the request.
496
515
  * It appends the program id to the request's path.
@@ -0,0 +1,24 @@
1
+ import AnalyticsBase from './AnalyticsBase.js';
2
+
3
+ /**
4
+ * @extends module:analytics.AnalyticsBase
5
+ *
6
+ * @description
7
+ * Analytics tracked entities class used to request analytics tracked entities data from Web API.
8
+ *
9
+ * @memberof module:analytics
10
+ */
11
+ class AnalyticsTrackedEntities extends AnalyticsBase {
12
+ /**
13
+ * @param {!AnalyticsRequest} req Request object
14
+ *
15
+ * @returns {Promise} Promise that resolves with the analytics query data from the api.
16
+ *
17
+ * @example
18
+ // TODO: provide working example
19
+ */
20
+ getQuery(req) {
21
+ return this.fetch(req.withPath('trackedEntities/query'));
22
+ }
23
+ }
24
+ export default AnalyticsTrackedEntities;
@@ -2,4 +2,23 @@
2
2
  const whitelistURI = ',&$=/;:';
3
3
  const whitelistURICodes = whitelistURI.split('').map(c => encodeURIComponent(c));
4
4
  const whitelistRegExp = new RegExp(`(?:${whitelistURICodes.join('|')})`, 'g');
5
- export const customEncodeURIComponent = uri => encodeURIComponent(uri).replace(whitelistRegExp, decodeURIComponent);
5
+ export const customEncodeURIComponent = uri => encodeURIComponent(uri).replace(whitelistRegExp, decodeURIComponent);
6
+ export const formatRequestPath = _ref => {
7
+ let {
8
+ path,
9
+ program,
10
+ trackedEntityType
11
+ } = _ref;
12
+ return [path, program, trackedEntityType].filter(Boolean).join('/');
13
+ };
14
+ export const formatDimension = _ref2 => {
15
+ let {
16
+ outputType,
17
+ programId,
18
+ programStageId,
19
+ dimension
20
+ } = _ref2;
21
+ return [
22
+ // XXX it would be clearer to have this consistent with what is sent in the request as for EVENT/ENROLLMENT
23
+ outputType === 'TRACKED_ENTITY' ? programId : undefined, programStageId, dimension].filter(Boolean).join('.');
24
+ };
@@ -33,6 +33,12 @@ export const DIMENSION_PROP_LEGEND_SET = {
33
33
  required: false,
34
34
  isValid: prop => isString(prop)
35
35
  };
36
+ export const DIMENSION_PROP_PROGRAM = {
37
+ name: 'program',
38
+ defaultValue: {},
39
+ required: false,
40
+ isValid: prop => isObject(prop)
41
+ };
36
42
  export const DIMENSION_PROP_PROGRAM_STAGE = {
37
43
  name: 'programStage',
38
44
  defaultValue: {},
@@ -45,4 +51,4 @@ export const DIMENSION_PROP_REPETITION = {
45
51
  required: false,
46
52
  isValid: prop => Array.isArray(prop)
47
53
  };
48
- export const DIMENSION_PROPS = [DIMENSION_PROP_ID, DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION];
54
+ export const DIMENSION_PROPS = [DIMENSION_PROP_ID, DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, DIMENSION_PROP_PROGRAM, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION];
@@ -1,4 +1,4 @@
1
- import { DIMENSION_PROP_ID, DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION } from './dimension.js';
1
+ import { DIMENSION_PROP_ID, DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, DIMENSION_PROP_PROGRAM, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION } from './dimension.js';
2
2
  export const dimensionCreate = function (dimensionId) {
3
3
  let itemIds = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
4
4
  let args = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
@@ -15,6 +15,9 @@ export const dimensionCreate = function (dimensionId) {
15
15
  ...(args.legendSet && {
16
16
  [DIMENSION_PROP_LEGEND_SET.name]: args.legendSet
17
17
  }),
18
+ ...(args.program && {
19
+ [DIMENSION_PROP_PROGRAM.name]: args.program
20
+ }),
18
21
  ...(args.programStage && {
19
22
  [DIMENSION_PROP_PROGRAM_STAGE.name]: args.programStage
20
23
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhis2/analytics",
3
- "version": "26.2.0",
3
+ "version": "26.3.0-alpha.1",
4
4
  "main": "./build/cjs/index.js",
5
5
  "module": "./build/es/index.js",
6
6
  "exports": {