Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v1.6.3 #8574

Open
wants to merge 17 commits into
base: release-v1.6.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

## [1.6.3](https://github.com/opencrvs/opencrvs-core/compare/v1.6.1...v1.6.3)

## [1.6.2](https://github.com/opencrvs/opencrvs-core/compare/v1.6.1...v1.6.2)

### Bug fixes
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ services:
- GATEWAY_URL=http://gateway:7070/
- DOCUMENTS_URL=http://documents:9050
- CHECK_INVALID_TOKEN=true
- HEARTH_MONGO_URL=mongodb://mongo1/hearth-dev
migration:
image: opencrvs/ocrvs-migration:${VERSION}
#platform: linux/amd64
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"description": "OpenCRVS core workspace",
"license": "MPL-2.0",
"version": "1.6.2",
"version": "1.6.3",
"private": true,
"os": [
"darwin",
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opencrvs/auth",
"version": "1.6.2",
"version": "1.6.3",
"description": "OpenCRVS authentication service",
"license": "MPL-2.0",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opencrvs/client",
"version": "1.6.2",
"version": "1.6.3",
"description": "OpenCRVS client application",
"license": "MPL-2.0",
"private": true,
Expand Down
2 changes: 2 additions & 0 deletions packages/client/src/components/form/FormFieldGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ class FormSectionComponent extends React.Component<Props> {
...field,
type: SELECT_WITH_OPTIONS,
options: getFieldOptions(
sectionName,
field,
values,
offlineCountryConfig,
Expand All @@ -1050,6 +1051,7 @@ class FormSectionComponent extends React.Component<Props> {
? ({
...field,
options: getFieldOptions(
sectionName,
field,
values,
offlineCountryConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,12 @@ export function questionnaireToTemplateFieldTransformer(
if (!offlineCountryConfig) {
return
}
const options = getFieldOptions(field, queryData, offlineCountryConfig)
const options = getFieldOptions(
sectionId,
field,
queryData,
offlineCountryConfig
)
transformedData[sectionId][field.name] =
options
.find((option) => option.value === selectedQuestion.value)
Expand Down
47 changes: 45 additions & 2 deletions packages/client/src/forms/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ import {
BUTTON,
Ii18nButtonFormField,
IRedirectFormField,
REDIRECT
REDIRECT,
SELECT_WITH_DYNAMIC_OPTIONS
} from '@client/forms'
import { IntlShape, MessageDescriptor } from 'react-intl'
import {
Expand Down Expand Up @@ -83,6 +84,7 @@ import { PhoneNumberUtil, PhoneNumberFormat } from 'google-libphonenumber'
import { Conditional } from './conditionals'
import { UserDetails } from '@client/utils/userUtils'
import * as SupportedIcons from '@opencrvs/components/lib/Icon/all-icons'
import { memoize } from 'lodash'

export const VIEW_TYPE = {
FORM: 'form',
Expand Down Expand Up @@ -365,7 +367,8 @@ export function getNextSectionIds(
export const getVisibleGroupFields = (group: IFormSectionGroup) => {
return group.fields.filter((field) => !field.hidden)
}
export const getFieldOptions = (
export const getFieldOptionsSlow = (
_sectionName: string,
field:
| ISelectFormFieldWithOptions
| ISelectFormFieldWithDynamicOptions
Expand Down Expand Up @@ -443,6 +446,46 @@ export const getFieldOptions = (
}
}

export const getFieldOptions = (
_sectionName: string,
field:
| ISelectFormFieldWithOptions
| ISelectFormFieldWithDynamicOptions
| IDocumentUploaderWithOptionsFormField,
values: IFormSectionData,
offlineCountryConfig: IOfflineData,
declaration?: IFormData
) => {
if (field.type === SELECT_WITH_DYNAMIC_OPTIONS) {
return getMemoisedFieldOptions(
_sectionName,
field,
values,
offlineCountryConfig
)
}

return getFieldOptionsSlow(
_sectionName,
field,
values,
offlineCountryConfig,
declaration
)
}

/** Due to the large location trees with dependencies, generating options for them can be slow. We fix this by memoizing the options */
const getMemoisedFieldOptions = memoize(
getFieldOptionsSlow,
(sectionName, field, values) => {
const dynamicField = field as ISelectFormFieldWithDynamicOptions
const dependencyVal = values[
dynamicField.dynamicOptions.dependency!
] as string
return `field:${sectionName}.${field.name},dependency:${dynamicField.dynamicOptions.dependency},dependencyValue:${dependencyVal}`
}
)

interface INested {
[key: string]: any
}
Expand Down
2 changes: 1 addition & 1 deletion packages/commons/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opencrvs/commons",
"version": "1.6.2",
"version": "1.6.3",
"description": "OpenCRVS common modules and utils",
"license": "MPL-2.0",
"main": "./build/dist/index.js",
Expand Down
4 changes: 4 additions & 0 deletions packages/commons/src/fhir/location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export function isHealthFacility(
return location.type?.coding?.[0].code === 'HEALTH_FACILITY'
}

export function isOffice(location: Location): location is Office {
return location.type?.coding?.[0].code === 'CRVS_OFFICE'
}

export function getLocationType(location: Location): string | undefined {
return location.type?.coding?.[0].code
}
2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@opencrvs/components",
"main": "lib/index",
"version": "1.6.2",
"version": "1.6.3",
"description": "OpenCRVS UI Component library",
"license": "MPL-2.0",
"private": true,
Expand Down
4 changes: 3 additions & 1 deletion packages/config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opencrvs/config",
"version": "1.6.2",
"version": "1.6.3",
"description": "OpenCRVS public configuration microservice",
"license": "MPL-2.0",
"scripts": {
Expand Down Expand Up @@ -30,6 +30,7 @@
"jsonwebtoken": "^9.0.0",
"jwt-decode": "^2.2.0",
"lodash": "^4.17.21",
"mongodb": "^6.13.0",
"mongoose": "^6.11.3",
"pino": "^7.0.0",
"tsconfig-paths": "^3.13.0",
Expand All @@ -50,6 +51,7 @@
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-prettier": "^4.0.0",
"mockingoose": "^2.15.2",
"mongodb-memory-server": "^10.1.3",
"nodemon": "^3.0.0",
"prettier": "^2.5.0",
"ts-node": "^6.1.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/config/src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const CERT_PUBLIC_KEY_PATH =
export const PRODUCTION = process.env.NODE_ENV === 'production'
export const QA_ENV = process.env.QA_ENV || false
export const FHIR_URL = process.env.FHIR_URL || 'http://localhost:3447/fhir'
export const HEARTH_MONGO_URL =
process.env.HEARTH_MONGO_URL || 'mongodb://localhost/hearth-dev'

// Check if the token has been invalided in the auth service before it has expired
// This needs to be a string to make it easy to pass as an ENV var.
Expand Down
93 changes: 49 additions & 44 deletions packages/config/src/handlers/locations/children.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,58 +9,63 @@
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
*/
import { UUID } from '@opencrvs/commons'
import { resolveLocationChildren } from './locationTreeSolver'
import * as fixtures from '@opencrvs/commons/fixtures'
import { resolveChildren } from './children'
import { fetchFromHearth } from '@config/services/hearth'
import { resolveLocationChildren } from './locationTreeSolver'

describe('resolveLocationChildren', () => {
test('empty locations', () => {
const uuid1 = fixtures.savedLocation({
id: 'uuid1' as UUID,
partOf: undefined
})
const result = resolveLocationChildren(uuid1, [])
expect(result).toEqual([])
})
jest.mock('@config/services/hearth', () => ({
fetchFromHearth: jest.fn()
}))

jest.mock('./locationTreeSolver', () => ({
resolveLocationChildren: jest.fn()
}))

const fetchFromHearthMock = fetchFromHearth as jest.Mock
const resolveLocationChildrenMock = resolveLocationChildren as jest.Mock

// Cast handler to make it callable
const handler = resolveChildren as unknown as (req: Request) => Promise<any>

describe('resolveChildren', () => {
describe('given a location of type office', () => {
test('does not fetch location hierarchy', async () => {
const office = fixtures.savedLocation({
id: 'uuid1' as UUID,
type: { coding: [{ code: 'CRVS_OFFICE' }] }
})

fetchFromHearthMock.mockResolvedValue(office)

const req = { params: { locationId: office.id } } as any

const res = await handler(req)

test('parent with no children', () => {
const uuid1 = fixtures.savedLocation({
id: 'uuid1' as UUID,
partOf: undefined
expect(resolveLocationChildrenMock).not.toHaveBeenCalled()
expect(res).toEqual([office])
})
const result = resolveLocationChildren(uuid1, [uuid1])
expect(result).toEqual([])
})

test('single level hierarchy', () => {
const uuid1 = fixtures.savedLocation({
id: 'uuid1' as UUID,
partOf: undefined
})
const uuid2 = fixtures.savedLocation({
id: 'uuid2' as UUID,
partOf: { reference: 'Location/uuid1' }
})
const result = resolveLocationChildren(uuid1, [uuid1, uuid2])
describe('given a location with children', () => {
test('should return location and children', async () => {
const parent = fixtures.savedLocation({
id: 'uuid1' as UUID,
type: { coding: [{ code: 'ADMIN_STRUCTURE' }] }
})

expect(result).toContainEqual(uuid2)
expect(result).toHaveLength(1)
})
fetchFromHearthMock.mockResolvedValue(parent)

test('multi-level hierarchy', () => {
const uuid1 = fixtures.savedLocation({
id: 'uuid1' as UUID,
partOf: undefined
})
const uuid2 = fixtures.savedLocation({
id: 'uuid2' as UUID,
partOf: { reference: 'Location/uuid1' }
})
const uuid3 = fixtures.savedLocation({
id: 'uuid3' as UUID,
partOf: { reference: 'Location/uuid2' }
})
const child1 = fixtures.savedLocation({ id: 'uuid2' as UUID })
const child2 = fixtures.savedLocation({ id: 'uuid3' as UUID })

resolveLocationChildrenMock.mockResolvedValue([child1, child2])

const req = { params: { locationId: parent.id } } as any

const result = resolveLocationChildren(uuid1, [uuid1, uuid2, uuid3])
expect(result).toEqual([uuid2, uuid3])
const res = await handler(req)

expect(res).toEqual([parent, child1, child2])
})
})
})
19 changes: 11 additions & 8 deletions packages/config/src/handlers/locations/children.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
*/
import { UUID } from '@opencrvs/commons'

import { ServerRoute } from '@hapi/hapi'
import { fetchFromHearth } from '@config/services/hearth'
import { SavedLocation, isOffice } from '@opencrvs/commons/types'
import { resolveLocationChildren } from './locationTreeSolver'
import { fetchLocations } from '@config/services/hearth'
import { find } from 'lodash'
import { notFound } from '@hapi/boom'

export const resolveChildren: ServerRoute['handler'] = async (req) => {
const { locationId } = req.params as { locationId: UUID }
const locations = await fetchLocations()
const location = find(locations, { id: locationId })

if (!location) {
return notFound()
const location = await fetchFromHearth<SavedLocation>(
`Location/${locationId}`
)
if (isOffice(location)) {
return [location]
}

return [location, ...resolveLocationChildren(location, locations)]
const children = await resolveLocationChildren(locationId)

return [location, ...children]
}
Loading
Loading