diff --git a/src/api/analytics/AnalyticsRequest.js b/src/api/analytics/AnalyticsRequest.js index 5b7d4b70e..b3ff28ce4 100644 --- a/src/api/analytics/AnalyticsRequest.js +++ b/src/api/analytics/AnalyticsRequest.js @@ -4,6 +4,7 @@ import AnalyticsRequestBase from './AnalyticsRequestBase.js' import AnalyticsRequestDimensionsMixin from './AnalyticsRequestDimensionsMixin.js' import AnalyticsRequestFiltersMixin from './AnalyticsRequestFiltersMixin.js' import AnalyticsRequestPropertiesMixin from './AnalyticsRequestPropertiesMixin.js' +import { formatDimension } from './utils.js' /** * @description @@ -45,6 +46,8 @@ class AnalyticsRequest extends AnalyticsRequestDimensionsMixin( fromVisualization(visualization, passFilterAsDimension = false) { let request = this + const outputType = visualization.outputType + // extract dimensions from visualization const columns = visualization.columns || [] const rows = visualization.rows || [] @@ -56,23 +59,31 @@ class AnalyticsRequest extends AnalyticsRequestDimensionsMixin( dimension += `-${d.legendSet.id}` } - if (d.programStage?.id) { - dimension = `${d.programStage.id}.${dimension}` - } - if (d.filter) { dimension += `:${d.filter}` } + const programStageId = d.programStage?.id + if (d.repetition?.indexes?.length) { d.repetition.indexes.forEach((index) => { request = request.addDimension( - dimension.replace(/\./, `[${index}].`) + formatDimension({ + programId: d.program?.id, + programStageId: `${programStageId}[${index}]`, + dimension, + outputType, + }) ) }) } else { request = request.addDimension( - dimension, + formatDimension({ + programId: d.program?.id, + programStageId, + dimension, + outputType, + }), d.items?.map((item) => item.id) ) } @@ -91,23 +102,33 @@ class AnalyticsRequest extends AnalyticsRequestDimensionsMixin( f.items?.map((item) => item.id) ) } else { - let filterString = f.programStage?.id - ? `${f.programStage.id}.${f.dimension}` - : f.dimension + let filterString = f.dimension if (f.filter) { filterString += `:${f.filter}` } + const programStageId = f.programStage?.id + if (f.repetition?.indexes?.length) { f.repetition.indexes.forEach((index) => { request = request.addFilter( - filterString.replace(/\./, `[${index}].`) + formatDimension({ + programId: f.program?.id, + programStageId: `${programStageId}[${index}]`, + dimension: filterString, + outputType, + }) ) }) } else { request = request.addFilter( - filterString, + formatDimension({ + programId: f.program?.id, + programStageId, + dimension: filterString, + outputType, + }), f.items?.map((item) => item.id) ) } diff --git a/src/api/analytics/utils.js b/src/api/analytics/utils.js index 4b8d1d579..574cd2ea5 100644 --- a/src/api/analytics/utils.js +++ b/src/api/analytics/utils.js @@ -10,3 +10,18 @@ export const customEncodeURIComponent = (uri) => export const formatRequestPath = ({ path, program, trackedEntityType }) => [path, program, trackedEntityType].filter(Boolean).join('/') + +export const formatDimension = ({ + outputType, + programId, + programStageId, + dimension, +}) => + [ + // XXX it would be clearer to have this consistent with what is sent in the request as for EVENT/ENROLLMENT + outputType === 'TRACKED_ENTITY' ? programId : undefined, + programStageId, + dimension, + ] + .filter(Boolean) + .join('.') diff --git a/src/modules/layout/dimension.js b/src/modules/layout/dimension.js index 5133b4759..fb6454467 100644 --- a/src/modules/layout/dimension.js +++ b/src/modules/layout/dimension.js @@ -37,6 +37,13 @@ export const DIMENSION_PROP_LEGEND_SET = { isValid: (prop) => isString(prop), } +export const DIMENSION_PROP_PROGRAM = { + name: 'program', + defaultValue: {}, + required: false, + isValid: (prop) => isObject(prop), +} + export const DIMENSION_PROP_PROGRAM_STAGE = { name: 'programStage', defaultValue: {}, @@ -56,6 +63,7 @@ export const DIMENSION_PROPS = [ DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, + DIMENSION_PROP_PROGRAM, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION, ] diff --git a/src/modules/layout/dimensionCreate.js b/src/modules/layout/dimensionCreate.js index 7fb11b39c..261edeb3b 100644 --- a/src/modules/layout/dimensionCreate.js +++ b/src/modules/layout/dimensionCreate.js @@ -3,6 +3,7 @@ import { DIMENSION_PROP_ITEMS, DIMENSION_PROP_FILTER, DIMENSION_PROP_LEGEND_SET, + DIMENSION_PROP_PROGRAM, DIMENSION_PROP_PROGRAM_STAGE, DIMENSION_PROP_REPETITION, } from './dimension.js' @@ -17,6 +18,9 @@ export const dimensionCreate = (dimensionId, itemIds = [], args = {}) => { ...(args.legendSet && { [DIMENSION_PROP_LEGEND_SET.name]: args.legendSet, }), + ...(args.program && { + [DIMENSION_PROP_PROGRAM.name]: args.program, + }), ...(args.programStage && { [DIMENSION_PROP_PROGRAM_STAGE.name]: args.programStage, }),