diff --git a/package.json b/package.json index 1f2313c502..ab9b95346c 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "capture-app", "homepage": ".", - "version": "35.0.0", - "cacheVersion": "2", + "version": "36.0.0", + "cacheVersion": "1", "private": false, "dependencies": { "@dhis2/app-runtime": "^2.6.1", diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js index e815ec140c..9b96f0bfc7 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js @@ -9,6 +9,8 @@ import { type TrackedEntityType, type Category, } from '../../../../metaData'; +import { getUserStorageController } from '../../../../storageControllers'; +import { userStores } from '../../../../storageControllers/stores'; import getProgramIconAsync from './getProgramIcon'; import { SearchGroupFactory } from '../../../common/factory'; @@ -137,7 +139,6 @@ class ProgramFactory { o.access = cachedProgram.access; o.name = cachedProgram.displayName; o.shortName = cachedProgram.displayShortName; - o.organisationUnits = cachedProgram.organisationUnits; o.categoryCombination = this._buildCategoryCombination(cachedProgram.categoryCombo); }); const d2Stage = cachedProgram.programStages && cachedProgram.programStages[0]; @@ -152,7 +153,6 @@ class ProgramFactory { o.access = cachedProgram.access; o.name = cachedProgram.displayName; o.shortName = cachedProgram.displayShortName; - o.organisationUnits = cachedProgram.organisationUnits; // $FlowFixMe o.trackedEntityType = this.trackedEntityTypeCollection.get(cachedProgram.trackedEntityTypeId); }); @@ -181,6 +181,7 @@ class ProgramFactory { } // $FlowFixMe program.icon = await ProgramFactory._buildProgramIcon(cachedProgram.style); + program.organisationUnits = (await getUserStorageController().get(userStores.ORGANISATION_UNITS_BY_PROGRAM, program.id)).organisationUnits; return program; } diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/context/context.types.js b/src/core_modules/capture-core/metaDataStoreLoaders/context/context.types.js index 8c27c5b22c..ac27e5fc7a 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/context/context.types.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/context/context.types.js @@ -9,6 +9,7 @@ type StoreNames = { RELATIONSHIP_TYPES: string, TRACKED_ENTITY_TYPES: string, PROGRAMS: string, + ORGANISATION_UNITS_BY_PROGRAM: string, PROGRAM_RULES: string, PROGRAM_RULES_VARIABLES: string, PROGRAM_INDICATORS: string, diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/loadPrograms.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/loadPrograms.js index acddde7e58..793f642710 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/loadPrograms.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/loadPrograms.js @@ -4,6 +4,7 @@ import { getContext } from '../context'; import { queryProgramsOutline } from './queries'; import { storePrograms, + storeOrganisationUnitsByProgram, } from './quickStoreOperations'; import { loadRulesCentricMetadata } from './loadRulesCentricMetadata'; @@ -37,6 +38,7 @@ const removeUnavailablePrograms = async (apiPrograms, cachedPrograms) => { if (unavailableProgramIds.length > 0) { const { storageController, storeNames } = getContext(); await storageController.remove(storeNames.PROGRAMS, unavailableProgramIds); + await storageController.remove(storeNames.ORGANISATION_UNITS_BY_PROGRAM, unavailableProgramIds); } }; @@ -66,6 +68,7 @@ const getStaleProgramIds = (apiPrograms, cachedPrograms) => { * The side effects data is used later when determining what other metadata to load. */ const loadProgramBatch = async (programIds) => { + await storeOrganisationUnitsByProgram(programIds); const { convertedData: programs = [] } = await storePrograms(programIds); await loadRulesCentricMetadata(programIds); return programs diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/queries/queryProgramsOutline.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/queries/queryProgramsOutline.js index 60e6b4b5a1..ff71348c3b 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/queries/queryProgramsOutline.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/queries/queryProgramsOutline.js @@ -5,7 +5,6 @@ export const queryProgramsOutline = async (): Promise> => { const specification = { resource: 'programs', params: { - restrictToCaptureScope: true, fields: 'id,version,programTrackedEntityAttributes[trackedEntityAttribute[id,optionSet[id,version]]],' + 'programStages[id,programStageDataElements[dataElement[id,optionSet[id,version]]]]', }, diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/index.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/index.js index 6491946ff2..21220b5162 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/index.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/index.js @@ -1,5 +1,6 @@ // @flow export { storePrograms } from './storePrograms'; +export { storeOrganisationUnitsByProgram } from './storeOrganisationUnitsByProgram'; export { storeProgramRules } from './storeProgramRules'; export { storeProgramRulesVariables } from './storeProgramRulesVariables'; export { storeProgramIndicators } from './storeProgramIndicators'; diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storeOrganisationUnitsByProgram.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storeOrganisationUnitsByProgram.js new file mode 100644 index 0000000000..a5a9dfac0f --- /dev/null +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storeOrganisationUnitsByProgram.js @@ -0,0 +1,30 @@ +// @flow +import { quickStore } from '../../IOUtils'; +import { getContext } from '../../context'; +import type { ApiOrganisationUnitsByProgram } from './types'; + +const convert = (response: ApiOrganisationUnitsByProgram) => + Object + .keys(response) + .map(id => ({ + id, + organisationUnits: response[id].reduce((acc, orgUnitId) => { + acc[orgUnitId] = true; + return acc; + }, {}), + })); + +export const storeOrganisationUnitsByProgram = (programIds: Array) => { + const query = { + resource: 'programs/orgUnits', + params: { + programs: programIds.join(','), + }, + }; + + return quickStore({ + query, + storeName: getContext().storeNames.ORGANISATION_UNITS_BY_PROGRAM, + convertQueryResponse: convert, + }); +}; diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js index 6368779dac..096bd47360 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js @@ -50,13 +50,6 @@ const convert = (() => { return programStages; }; - const getOrganisationUnits = apiOrganisationUnits => - (apiOrganisationUnits || []) - .reduce((accOrganisationUnits, organisationUnit) => { - accOrganisationUnits[organisationUnit.id] = organisationUnit; - return accOrganisationUnits; - }, {}); - const getProgramTrackedEntityAttribute = programAttribute => ({ ...programAttribute, trackedEntityAttribute: undefined, @@ -76,7 +69,6 @@ const convert = (() => { trackedEntityType: undefined, trackedEntityTypeId: apiProgram.trackedEntityType && apiProgram.trackedEntityType.id, programStages: getProgramStages(apiProgram.programStages), - organisationUnits: getOrganisationUnits(apiProgram.organisationUnits), programTrackedEntityAttributes: getProgramTrackedEntityAttributes(apiProgram.programTrackedEntityAttributes), })); @@ -90,7 +82,6 @@ const fieldsParam = 'id,version,displayName,displayShortName,description,program 'access[*],' + 'trackedEntityType[id],' + 'categoryCombo[id,displayName,isDefault,categories[id,displayName]],' + -'organisationUnits[id,displayName],' + 'userRoles[id,displayName],' + 'programStages[id,access,autoGenerateEvent,openAfterEnrollment,generatedByEnrollmentDate,reportDateToUse,standardInterval,displayName,description,executionDateLabel,formType,featureType,validationStrategy,enableUserAssignment,dataEntryForm[id,htmlCode],' + 'programStageSections[id,displayName,sortOrder,dataElements[id]],programStageDataElements[compulsory,displayInReports,renderOptionsAsRadio,allowFutureDate,renderType[*],' + @@ -101,7 +92,6 @@ export const storePrograms = (programIds: Array) => { const query = { resource: 'programs', params: { - restrictToCaptureScope: true, fields: fieldsParam, filter: `id:in:[${programIds.join(',')}]`, pageSize: programIds.length, diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiOrganisationUnitsByProgram.types.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiOrganisationUnitsByProgram.types.js new file mode 100644 index 0000000000..93efaf5dca --- /dev/null +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiOrganisationUnitsByProgram.types.js @@ -0,0 +1,5 @@ +// @flow + +export type ApiOrganisationUnitsByProgram = { + [programId: string]: Array, +}; diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/index.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/index.js index 9e1a348515..e4a2a061c1 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/index.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/index.js @@ -1,2 +1,3 @@ // @flow -export type { apiProgramsResponse } from './apiPrograms.types'; +export * from './apiPrograms.types'; +export * from './apiOrganisationUnitsByProgram.types'; diff --git a/src/core_modules/capture-core/storageControllers/stores/userStores.const.js b/src/core_modules/capture-core/storageControllers/stores/userStores.const.js index fde54a9a02..15a3d77b21 100644 --- a/src/core_modules/capture-core/storageControllers/stores/userStores.const.js +++ b/src/core_modules/capture-core/storageControllers/stores/userStores.const.js @@ -7,6 +7,7 @@ export default { RELATIONSHIP_TYPES: 'relationshipTypes', TRACKED_ENTITY_TYPES: 'trackedEntityTypes', PROGRAMS: 'programs', + ORGANISATION_UNITS_BY_PROGRAM: 'organisationUnitsByProgram', PROGRAM_RULES: 'programRules', PROGRAM_RULES_VARIABLES: 'programRulesVariables', PROGRAM_INDICATORS: 'programIndicators',