Skip to content

Commit

Permalink
refactor: restructure modules/ui.js and add tests for the various parts
Browse files Browse the repository at this point in the history
  • Loading branch information
martinkrulltott committed Feb 27, 2024
1 parent 4f5bf68 commit 3e4b56c
Show file tree
Hide file tree
Showing 13 changed files with 340 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ import {
getDefaultOuMetadata,
getDynamicTimeDimensionsMetadata,
} from '../modules/metadata.js'
import { getParentGraphMapFromVisualization } from '../modules/parentGraphMap.js'
import { getProgramDimensions } from '../modules/programDimensions.js'
import { SYSTEM_SETTINGS_DIGIT_GROUP_SEPARATOR } from '../modules/systemSettings.js'
import { getParentGraphMapFromVisualization } from '../modules/ui.js'
import {
DERIVED_USER_SETTINGS_DISPLAY_NAME_PROPERTY,
USER_SETTINGS_DISPLAY_PROPERTY,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Dialogs/Conditions/RepeatableEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getDefaultUiRepetition,
PROP_MOST_RECENT,
PROP_OLDEST,
} from '../../../modules/ui.js'
} from '../../../modules/repetition.js'
import { sGetUiRepetitionByDimension } from '../../../reducers/ui.js'
import commonClasses from '../styles/Common.module.css'
import classes from './styles/ConditionsManager.module.css'
Expand Down
77 changes: 77 additions & 0 deletions src/modules/__tests__/conditions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import {
checkIsCaseSensitive,
addCaseSensitivePrefix,
removeCaseSensitivePrefix,
getConditionsFromVisualization,
} from '../conditions.js'
import {
OUTPUT_TYPE_EVENT,
OUTPUT_TYPE_TRACKED_ENTITY,
} from '../visualization.js'

test('Legend set chosen with no legends selected', () => {
const conditions = {
Expand Down Expand Up @@ -409,3 +414,75 @@ describe('removeCaseSensitivePrefix', () => {
})
})
})

describe('getConditionsFromVisualization', () => {
it('should return empty object if visualization has no columns, rows, or filters', () => {
const visualization = {
columns: [],
rows: [],
filters: [],
}
const conditions = getConditionsFromVisualization(visualization)
expect(conditions).toEqual({})
})

it('should return conditions for columns, rows, and filters with filter or legendSet defined', () => {
const visualization = {
columns: [{ dimension: 'dx1', filter: 'filter1' }],
rows: [{ dimension: 'dx2', legendSet: { id: 'legend1' } }],
filters: [
{
dimension: 'dx3',
filter: 'filter3',
legendSet: { id: 'legend2' },
},
],
}
const conditions = getConditionsFromVisualization(visualization)
expect(conditions).toEqual({
dx1: { condition: 'filter1', legendSet: undefined },
dx2: { condition: undefined, legendSet: 'legend1' },
dx3: { condition: 'filter3', legendSet: 'legend2' },
})
})

it('should return conditions with correct id for output type event', () => {
const visualization = {
columns: [
{
dimension: 'dx1',
programStage: { id: 'ps1' },
program: { id: 'p1' },
filter: 'filter1',
},
],
rows: [],
filters: [],
outputType: OUTPUT_TYPE_EVENT,
}
const conditions = getConditionsFromVisualization(visualization)
expect(conditions).toEqual({
'ps1.dx1': { condition: 'filter1', legendSet: undefined },
})
})

it('should return conditions with correct id for output type tracked entity', () => {
const visualization = {
columns: [
{
dimension: 'dx1',
programStage: { id: 'ps1' },
program: { id: 'p1' },
filter: 'filter1',
},
],
rows: [],
filters: [],
outputType: OUTPUT_TYPE_TRACKED_ENTITY,
}
const conditions = getConditionsFromVisualization(visualization)
expect(conditions).toEqual({
'p1.ps1.dx1': { condition: 'filter1', legendSet: undefined },
})
})
})
68 changes: 68 additions & 0 deletions src/modules/__tests__/options.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
LEGEND_DISPLAY_STRATEGY_BY_DATA_ITEM,
LEGEND_DISPLAY_STYLE_FILL,
} from '@dhis2/analytics'
import {
OPTION_LEGEND_DISPLAY_STRATEGY,
OPTION_LEGEND_DISPLAY_STYLE,
OPTION_LEGEND_SET,
OPTION_SHOW_LEGEND_KEY,
getOptionsFromVisualization,
} from '../options.js'

describe('getOptionsFromVisualization', () => {
it('should return default options if visualization is empty', () => {
const visualization = {}
const result = getOptionsFromVisualization(visualization)
expect(result).toEqual({
digitGroupSeparator: 'SPACE',
displayDensity: 'NORMAL',
fontSize: 'NORMAL',
showHierarchy: false,
skipRounding: false,
})
})

it('should return options from visualization', () => {
const visualization = {
digitGroupSeparator: 'COMMA',
displayDensity: 'COMPACT',
fontSize: 'SMALL',
showHierarchy: true,
skipRounding: true,
}

const result = getOptionsFromVisualization(visualization)
expect(result).toEqual({
digitGroupSeparator: 'COMMA',
displayDensity: 'COMPACT',
fontSize: 'SMALL',
showHierarchy: true,
skipRounding: true,
})
})

it('should include legend options if present in visualization', () => {
const visualization = {
legend: {
strategy: LEGEND_DISPLAY_STRATEGY_BY_DATA_ITEM,
style: LEGEND_DISPLAY_STYLE_FILL,
set: 'legendSet1',
showKey: true,
},
}
const result = getOptionsFromVisualization(visualization)
expect(result).toEqual({
digitGroupSeparator: 'SPACE',
displayDensity: 'NORMAL',
fontSize: 'NORMAL',
showHierarchy: false,
skipRounding: false,
[OPTION_LEGEND_DISPLAY_STRATEGY]:
LEGEND_DISPLAY_STRATEGY_BY_DATA_ITEM,
[OPTION_LEGEND_DISPLAY_STYLE]: LEGEND_DISPLAY_STYLE_FILL,
[OPTION_LEGEND_SET]: 'legendSet1',
[OPTION_SHOW_LEGEND_KEY]: true,
})
})
})
62 changes: 62 additions & 0 deletions src/modules/__tests__/parentGraphMap.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { getParentGraphMapFromVisualization } from '../parentGraphMap.js'

describe('getParentGraphMapFromVisualization', () => {
it('returns an empty object when no org unit axis exists', () => {
const visualization = {
columns: [{ dimension: 'dx' }],
filters: [],
}
const parentGraphMap = getParentGraphMapFromVisualization(visualization)
expect(parentGraphMap).toEqual({})
})

it('returns parent graph map correctly for org units', () => {
const visualization = {
columns: [
{ dimension: 'dx' },
{
dimension: 'ou',
items: [
{ id: 'orgUnit1', path: '/orgUnit1' },
{ id: 'orgUnit2', path: '/orgUnit1/orgUnit2' },
{ id: 'orgUnit3', path: '/orgUnit1/orgUnit3' },
],
},
],
}
const parentGraphMap = getParentGraphMapFromVisualization(visualization)
expect(parentGraphMap).toEqual({
orgUnit1: '',
orgUnit2: 'orgUnit1',
orgUnit3: 'orgUnit1',
})
})

it('handles root org unit case correctly', () => {
const visualization = {
columns: [
{ dimension: 'dx' },
{
dimension: 'ou',
items: [{ id: 'rootOrgUnit', path: '/rootOrgUnit' }],
},
],
}
const parentGraphMap = getParentGraphMapFromVisualization(visualization)
expect(parentGraphMap).toEqual({ rootOrgUnit: '' })
})

it('handles org unit paths with trailing slashes correctly', () => {
const visualization = {
columns: [
{ dimension: 'dx' },
{
dimension: 'ou',
items: [{ id: 'orgUnit', path: '/orgUnit/' }],
},
],
}
const parentGraphMap = getParentGraphMapFromVisualization(visualization)
expect(parentGraphMap).toEqual({ orgUnit: 'orgUnit' })
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import {
getDefaultCurrentRepetition,
parseCurrentRepetition,
parseUiRepetition,
PARSE_CURRENT_REPETITION_ERROR,
PROP_OLDEST,
PROP_MOST_RECENT,
PARSE_UI_REPETITION_ERROR,
} from '../ui.js'
} from '../repetition.js'

describe('parseCurrentRepetition', () => {
const defaultUiRepetition = getDefaultUiRepetition()
Expand Down Expand Up @@ -38,7 +37,7 @@ describe('parseCurrentRepetition', () => {

invalidInputs.forEach((input) => {
expect(() => parseCurrentRepetition(input)).toThrow(
PARSE_CURRENT_REPETITION_ERROR
'parseCurrentRepetition: Invalid input'
)
})

Expand Down
20 changes: 20 additions & 0 deletions src/modules/conditions.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
DIMENSION_TYPE_PROGRAM_INDICATOR,
} from '@dhis2/analytics'
import i18n from '@dhis2/d2-i18n'
import { formatDimensionId } from './dimensionId.js'

// parse e.g. 'LT:25:GT:15' to ['LT:25', 'GT:15']
export const parseConditionsStringToArray = (conditionsString) =>
Expand Down Expand Up @@ -271,3 +272,22 @@ export const getConditionsTexts = ({

return parsedConditions
}

export const getConditionsFromVisualization = (vis) =>
[...vis.columns, ...vis.rows, ...vis.filters]
.filter((item) => item.filter || item.legendSet)
.reduce(
(acc, key) => ({
...acc,
[formatDimensionId({
dimensionId: key.dimension,
programStageId: key.programStage?.id,
programId: key.program?.id,
outputType: vis.outputType,
})]: {
condition: key.filter,
legendSet: key.legendSet?.id,
},
}),
{}
)
2 changes: 1 addition & 1 deletion src/modules/current.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
OPTION_LEGEND_SET,
OPTION_SHOW_LEGEND_KEY,
} from './options.js'
import { parseUiRepetition } from './ui.js'
import { parseUiRepetition } from './repetition.js'
import { OUTPUT_TYPE_TRACKED_ENTITY } from './visualization.js'

export const getDefaultFromUi = (current, ui) => {
Expand Down
3 changes: 0 additions & 3 deletions src/modules/input.js

This file was deleted.

36 changes: 36 additions & 0 deletions src/modules/parentGraphMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
DIMENSION_ID_ORGUNIT,
layoutGetAxisIdDimensionIdsObject,
} from '@dhis2/analytics'
import { getInverseLayout } from './layout.js'
import { removeLastPathSegment } from './orgUnit.js'

export const getParentGraphMapFromVisualization = (vis) => {
const dimensionIdsByAxis = layoutGetAxisIdDimensionIdsObject(vis)
const inverseLayout = getInverseLayout(dimensionIdsByAxis)
const ouAxis = inverseLayout[DIMENSION_ID_ORGUNIT]

if (!ouAxis) {
return {}
}

const parentGraphMap = {}
const ouDimension = vis[ouAxis].find(
(dimension) => dimension.dimension === DIMENSION_ID_ORGUNIT
)

ouDimension.items
.filter((orgUnit) => orgUnit.path)
.forEach((orgUnit) => {
if ('/' + orgUnit.id === orgUnit.path) {
// root org unit case
parentGraphMap[orgUnit.id] = ''
} else {
const path = removeLastPathSegment(orgUnit.path)
parentGraphMap[orgUnit.id] =
path[0] === '/' ? path.substr(1) : path
}
})

return parentGraphMap
}
6 changes: 0 additions & 6 deletions src/modules/program.js

This file was deleted.

Loading

0 comments on commit 3e4b56c

Please sign in to comment.