From 9c26a6a1fe2bbc7df4670d76a2157dfb83746e9f Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 17 Oct 2024 10:44:00 +0600 Subject: [PATCH 01/11] fix: return first child "location" from query The query only needs to consider the locations under the given parent & not the offices/addresses. The country level query also needed to be separately handled. --- .../src/features/location/root-resolvers.ts | 33 ++++++++++++++++--- packages/gateway/src/location.ts | 20 ++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/gateway/src/features/location/root-resolvers.ts b/packages/gateway/src/features/location/root-resolvers.ts index 34cd38d95b7..2889fd54330 100644 --- a/packages/gateway/src/features/location/root-resolvers.ts +++ b/packages/gateway/src/features/location/root-resolvers.ts @@ -9,15 +9,40 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { + resourceIdentifierToUUID, + SavedLocation +} from '@opencrvs/commons/types' import { GQLResolver } from '@gateway/graphql/schema' -import { fetchLocationChildren } from '@gateway/location' +import { fetchAllLocations, fetchLocationChildren } from '@gateway/location' import { UUID } from '@opencrvs/commons' export const resolvers: GQLResolver = { Query: { - async hasChildLocation(_, { parentId }, { headers: authHeader }) { - const children = await fetchLocationChildren(parentId as UUID) - const [childLocation] = children + async hasChildLocation(_, { parentId }) { + let children: SavedLocation[] + /* + * This is because of a tech debt we have that + * there is no location resource created for the + * country so we have a bunch of places where we + * need to manually check if the id equals '0' + */ + if (parentId === '0') { + children = await fetchAllLocations() + } else { + children = await fetchLocationChildren(parentId as UUID) + } + /* + * We want to consider only the admin structure locations + * here & not the offices or addresses that might have the + * given location as a parent + */ + const [childLocation] = children.filter( + (child) => + child.type?.coding?.some(({ code }) => code === 'ADMIN_STRUCTURE') && + child.partOf && + resourceIdentifierToUUID(child.partOf.reference) === parentId + ) return childLocation } } diff --git a/packages/gateway/src/location.ts b/packages/gateway/src/location.ts index bccc75d440c..87df278b06b 100644 --- a/packages/gateway/src/location.ts +++ b/packages/gateway/src/location.ts @@ -10,7 +10,7 @@ */ import { UUID } from '@opencrvs/commons' -import { Location, SavedLocation } from '@opencrvs/commons/types' +import { Location, SavedBundle, SavedLocation } from '@opencrvs/commons/types' import { APPLICATION_CONFIG_URL } from './constants' import fetch from 'node-fetch' @@ -28,6 +28,24 @@ export const fetchLocation = async (id: UUID) => { return response.json() as Promise } +const FETCH_ALL_LOCATIONS = new URL( + '/locations?type=ADMIN_STRUCTURE', + APPLICATION_CONFIG_URL +) + +export const fetchAllLocations = async () => { + const response = await fetch(FETCH_ALL_LOCATIONS) + + if (!response.ok) { + throw new Error( + `Couldn't fetch the locations from config: ${await response.text()}` + ) + } + const locationsBundle: SavedBundle = await response.json() + + return locationsBundle.entry.map(({ resource }) => resource) +} + const FETCH_ALL_LOCATION_CHILDREN = (id: UUID) => new URL(`/locations/${id}/children`, APPLICATION_CONFIG_URL) From b93c843375d21090eaade2b914d84492b4724ece Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Wed, 23 Oct 2024 17:15:14 +0600 Subject: [PATCH 02/11] chore: include _count param to get all locations --- packages/gateway/src/location.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gateway/src/location.ts b/packages/gateway/src/location.ts index 87df278b06b..71bc4e2d341 100644 --- a/packages/gateway/src/location.ts +++ b/packages/gateway/src/location.ts @@ -29,7 +29,7 @@ export const fetchLocation = async (id: UUID) => { } const FETCH_ALL_LOCATIONS = new URL( - '/locations?type=ADMIN_STRUCTURE', + '/locations?type=ADMIN_STRUCTURE&_count=0', APPLICATION_CONFIG_URL ) From 47474786eb2589c703ebfdded1653ef8fec4dc3a Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 14:00:21 +0600 Subject: [PATCH 03/11] feat: define isLeafLevelLocation query in client --- packages/client/graphql.schema.json | 33 ++++ packages/client/src/utils/gateway.ts | 154 +++++++++--------- .../src/views/SysAdmin/Performance/queries.ts | 6 + 3 files changed, 120 insertions(+), 73 deletions(-) diff --git a/packages/client/graphql.schema.json b/packages/client/graphql.schema.json index feba952fa5d..9c34546401d 100644 --- a/packages/client/graphql.schema.json +++ b/packages/client/graphql.schema.json @@ -14025,6 +14025,39 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "isLeafLevelLocation", + "description": null, + "args": [ + { + "name": "locationId", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "listBirthRegistrations", "description": null, diff --git a/packages/client/src/utils/gateway.ts b/packages/client/src/utils/gateway.ts index d2eafb76a35..7b645632414 100644 --- a/packages/client/src/utils/gateway.ts +++ b/packages/client/src/utils/gateway.ts @@ -1409,6 +1409,7 @@ export type Query = { getUserByMobile?: Maybe getVSExports?: Maybe hasChildLocation?: Maybe + isLeafLevelLocation: Scalars['Boolean'] listBirthRegistrations?: Maybe queryPersonByIdentifier?: Maybe queryPersonByNidIdentifier?: Maybe @@ -1571,6 +1572,10 @@ export type QueryHasChildLocationArgs = { parentId: Scalars['String'] } +export type QueryIsLeafLevelLocationArgs = { + locationId: Scalars['String'] +} + export type QueryListBirthRegistrationsArgs = { count?: InputMaybe from?: InputMaybe @@ -7324,6 +7329,15 @@ export type HasChildLocationQuery = { } | null } +export type IsLeafLevelLocationQueryVariables = Exact<{ + locationId: Scalars['String'] +}> + +export type IsLeafLevelLocationQuery = { + __typename?: 'Query' + isLeafLevelLocation: boolean +} + export type FetchMonthWiseEventMetricsQueryVariables = Exact<{ timeStart: Scalars['String'] timeEnd: Scalars['String'] @@ -7449,82 +7463,76 @@ export type GetRegistrationsListByFilterQueryVariables = Exact<{ size: Scalars['Int'] }> -export type RegistrationsListByLocationFilter = { - __typename: 'TotalMetricsByLocation' - total?: number | null - results: Array<{ - __typename?: 'EventMetricsByLocation' - total: number - late: number - delayed: number - home: number - healthFacility: number - location: { __typename?: 'Location'; name?: string | null } - }> -} - -export type RegistrationsListByRegistrarFilter = { - __typename: 'TotalMetricsByRegistrar' - total?: number | null - results: Array<{ - __typename?: 'EventMetricsByRegistrar' - total: number - late: number - delayed: number - registrarPractitioner?: { - __typename?: 'User' - id: string - systemRole: SystemRoleType - role: { - __typename?: 'Role' - _id: string - labels: Array<{ - __typename?: 'RoleLabel' - lang: string - label: string - }> - } - primaryOffice?: { - __typename?: 'Location' - name?: string | null - id: string - } | null - name: Array<{ - __typename?: 'HumanName' - firstNames?: string | null - familyName?: string | null - use?: string | null - }> - avatar?: { - __typename?: 'Avatar' - type: string - data: string - } | null - } | null - }> -} - -export type RegistrationsListByTimeFilter = { - __typename: 'TotalMetricsByTime' - total?: number | null - results: Array<{ - __typename?: 'EventMetricsByTime' - total: number - delayed: number - late: number - home: number - healthFacility: number - month: string - time: string - }> -} - export type GetRegistrationsListByFilterQuery = { __typename?: 'Query' getRegistrationsListByFilter?: - | RegistrationsListByLocationFilter - | RegistrationsListByRegistrarFilter - | RegistrationsListByTimeFilter + | { + __typename: 'TotalMetricsByLocation' + total?: number | null + results: Array<{ + __typename?: 'EventMetricsByLocation' + total: number + late: number + delayed: number + home: number + healthFacility: number + location: { __typename?: 'Location'; name?: string | null } + }> + } + | { + __typename: 'TotalMetricsByRegistrar' + total?: number | null + results: Array<{ + __typename?: 'EventMetricsByRegistrar' + total: number + late: number + delayed: number + registrarPractitioner?: { + __typename?: 'User' + id: string + systemRole: SystemRoleType + role: { + __typename?: 'Role' + _id: string + labels: Array<{ + __typename?: 'RoleLabel' + lang: string + label: string + }> + } + primaryOffice?: { + __typename?: 'Location' + name?: string | null + id: string + } | null + name: Array<{ + __typename?: 'HumanName' + firstNames?: string | null + familyName?: string | null + use?: string | null + }> + avatar?: { + __typename?: 'Avatar' + type: string + data: string + } | null + } | null + }> + } + | { + __typename: 'TotalMetricsByTime' + total?: number | null + results: Array<{ + __typename?: 'EventMetricsByTime' + total: number + delayed: number + late: number + home: number + healthFacility: number + month: string + time: string + }> + } | null } diff --git a/packages/client/src/views/SysAdmin/Performance/queries.ts b/packages/client/src/views/SysAdmin/Performance/queries.ts index 8bad0574eb3..9c4f7992a38 100644 --- a/packages/client/src/views/SysAdmin/Performance/queries.ts +++ b/packages/client/src/views/SysAdmin/Performance/queries.ts @@ -23,6 +23,12 @@ export const HAS_CHILD_LOCATION = gql` } ` +export const IS_LEAF_LEVEL_LOCATION = gql` + query isLeafLevelLocation($locationId: String!) { + isLeafLevelLocation(locationId: $locationId) + } +` + export const FETCH_MONTH_WISE_EVENT_ESTIMATIONS = gql` query fetchMonthWiseEventMetrics( $timeStart: String! From e356076fb170bb55871d2afa89b515f331327c84 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 14:58:41 +0600 Subject: [PATCH 04/11] refactor: use the new isLeafLevelLocation query --- .../Performance/CompletenessRates.tsx | 288 +++++++++--------- 1 file changed, 148 insertions(+), 140 deletions(-) diff --git a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx index e8aba47901e..bb7f5594879 100644 --- a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx +++ b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx @@ -13,12 +13,15 @@ import { DateRangePicker } from '@client/components/DateRangePicker' import { GenericErrorToast } from '@client/components/GenericErrorToast' import { LocationPicker } from '@client/components/LocationPicker' import { Query } from '@client/components/Query' -import { Event } from '@client/utils/gateway' +import { + Event, + IsLeafLevelLocationQuery, + QueryIsLeafLevelLocationArgs +} from '@client/utils/gateway' import { messages } from '@client/i18n/messages/views/performance' import { goToCompletenessRates } from '@client/navigation' import { - getJurisidictionType, CompletenessRateTime, getAdditionalLocations, NATIONAL_ADMINISTRATIVE_LEVEL @@ -27,8 +30,8 @@ import { SysAdminContentWrapper } from '@client/views/SysAdmin/SysAdminContentWr import type { GQLMonthWiseEstimationMetric } from '@client/utils/gateway-deprecated-do-not-use' import { parse } from 'query-string' import * as React from 'react' -import { injectIntl, WrappedComponentProps } from 'react-intl' -import { connect } from 'react-redux' +import { injectIntl, useIntl, WrappedComponentProps } from 'react-intl' +import { connect, useDispatch } from 'react-redux' import { RouteComponentProps } from 'react-router' import { IPerformanceSelectOption, @@ -37,14 +40,14 @@ import { import { FETCH_LOCATION_WISE_EVENT_ESTIMATIONS, FETCH_MONTH_WISE_EVENT_ESTIMATIONS, - HAS_CHILD_LOCATION + IS_LEAF_LEVEL_LOCATION } from './queries' import { CompletenessDataTable } from './reports/completenessRates/CompletenessDataTable' -import { useCallback } from 'react' import { Content, ContentSize } from '@opencrvs/components/lib/Content' import { navigationMessages } from '@client/i18n/messages/views/navigation' import format from '@client/utils/date-formatting' import { SegmentedControl } from '@client/components/SegmentedControl' +import { useQuery } from '@apollo/client' const { useState } = React export enum COMPLETENESS_RATE_REPORT_BASE { @@ -77,7 +80,7 @@ function prepareChartData( return ( data && data.reduce( - (chartData: any[], dataDetails: GQLMonthWiseEstimationMetric, index) => { + (chartData: any[], dataDetails: GQLMonthWiseEstimationMetric) => { if (dataDetails !== null) { chartData.push({ label: @@ -102,6 +105,131 @@ function prepareChartData( ) } +function Filter({ + locationId, + event, + dateStart, + dateEnd, + base, + time, + onBaseChange +}: { + locationId: string + event: Event + dateStart: Date + dateEnd: Date + base: COMPLETENESS_RATE_REPORT_BASE + time: CompletenessRateTime + onBaseChange: (base: COMPLETENESS_RATE_REPORT_BASE) => void +}) { + const intl = useIntl() + const { data } = useQuery< + IsLeafLevelLocationQuery, + QueryIsLeafLevelLocationArgs + >(IS_LEAF_LEVEL_LOCATION, { + variables: { + locationId: + locationId === NATIONAL_ADMINISTRATIVE_LEVEL ? '0' : locationId + } + }) + const dispatch = useDispatch() + + const options: (IPerformanceSelectOption & { disabled?: boolean })[] = [ + { + label: intl.formatMessage(messages.overTime), + value: COMPLETENESS_RATE_REPORT_BASE.TIME + }, + { + label: intl.formatMessage(messages.byLocation), + value: COMPLETENESS_RATE_REPORT_BASE.LOCATION, + disabled: data?.isLeafLevelLocation ?? true + } + ] + + return ( + <> + + onBaseChange(option.value as COMPLETENESS_RATE_REPORT_BASE) + } + /> + { + dispatch( + goToCompletenessRates( + event, + newLocationId, + dateStart, + dateEnd, + time + ) + ) + }} + /> + { + startDate.setDate(startDate.getDate() + 1) + dispatch( + goToCompletenessRates( + event, + locationId as string, + startDate, + endDate, + time + ) + ) + }} + /> + + dispatch( + goToCompletenessRates( + event, + locationId, + dateStart, + dateEnd, + option.value as CompletenessRateTime + ) + ) + } + id="completenessRateTimeSelect" + withLightTheme={true} + value={time} + options={[ + { + label: intl.formatMessage( + messages.performanceWithinTargetDaysLabel, + { + target: + window.config[event.toUpperCase() as Uppercase] + .REGISTRATION_TARGET, + withPrefix: false + } + ), + value: CompletenessRateTime.WithinTarget + }, + { + label: intl.formatMessage(messages.performanceWithin1YearLabel), + value: CompletenessRateTime.Within1Year + }, + { + label: intl.formatMessage(messages.performanceWithin5YearsLabel), + value: CompletenessRateTime.Within5Years + } + ]} + /> + + ) +} + function CompletenessRatesComponent(props: ICompletenessRateProps) { const [base, setBase] = useState({ baseType: COMPLETENESS_RATE_REPORT_BASE.TIME @@ -118,138 +246,8 @@ function CompletenessRatesComponent(props: ICompletenessRateProps) { search ) as unknown as ISearchParams - const getFilter = useCallback(() => { - const dateStart = new Date(timeStart) - const dateEnd = new Date(timeEnd) - return ( - { - const childJurisdictionType = getJurisidictionType(hasChildLocation) - if ( - !childJurisdictionType && - base.baseType === COMPLETENESS_RATE_REPORT_BASE.LOCATION - ) { - setBase({ baseType: COMPLETENESS_RATE_REPORT_BASE.TIME }) - } - }} - > - {({ data, loading, error }) => { - const childJurisdictionType = - data && - data.hasChildLocation && - getJurisidictionType(data.hasChildLocation) - - const options: (IPerformanceSelectOption & { disabled?: boolean })[] = - [ - { - label: intl.formatMessage(messages.overTime), - value: COMPLETENESS_RATE_REPORT_BASE.TIME - }, - { - label: intl.formatMessage(messages.byLocation, { - childJurisdictionType - }), - value: COMPLETENESS_RATE_REPORT_BASE.LOCATION, - type: childJurisdictionType || '', - disabled: !childJurisdictionType - } - ] - - return ( - <> - - setBase({ - baseType: option.value as COMPLETENESS_RATE_REPORT_BASE, - locationJurisdictionType: option.type - }) - } - /> - { - props.goToCompletenessRates( - eventType as Event, - newLocationId, - dateStart, - dateEnd, - time - ) - }} - /> - { - startDate.setDate(startDate.getDate() + 1) - props.goToCompletenessRates( - eventType as Event, - locationId as string, - startDate, - endDate, - time - ) - }} - /> - - props.goToCompletenessRates( - eventType as Event, - locationId, - dateStart, - dateEnd, - option.value as CompletenessRateTime - ) - } - id="completenessRateTimeSelect" - withLightTheme={true} - value={time} - options={[ - { - label: intl.formatMessage( - messages.performanceWithinTargetDaysLabel, - { - target: - window.config[ - (eventType.toUpperCase() as 'BIRTH') || 'DEATH' - ].REGISTRATION_TARGET, - withPrefix: false - } - ), - value: CompletenessRateTime.WithinTarget - }, - { - label: intl.formatMessage( - messages.performanceWithin1YearLabel - ), - value: CompletenessRateTime.Within1Year - }, - { - label: intl.formatMessage( - messages.performanceWithin5YearsLabel - ), - value: CompletenessRateTime.Within5Years - } - ]} - /> - - ) - }} - - ) - }, [base, props, timeStart, timeEnd, eventType, intl, locationId, time]) + const dateStart = new Date(timeStart) + const dateEnd = new Date(timeEnd) return ( setBase({ baseType: base })} + /> + } > Date: Thu, 24 Oct 2024 15:13:41 +0600 Subject: [PATCH 05/11] feat: create isLeafLevelLocation query --- .../src/features/location/root-resolvers.ts | 15 ++++++++++----- .../src/features/location/schema.graphql | 1 + packages/gateway/src/graphql/schema.d.ts | 17 +++++++++++++++++ packages/gateway/src/graphql/schema.graphql | 1 + 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/gateway/src/features/location/root-resolvers.ts b/packages/gateway/src/features/location/root-resolvers.ts index 2889fd54330..55eb6d59b28 100644 --- a/packages/gateway/src/features/location/root-resolvers.ts +++ b/packages/gateway/src/features/location/root-resolvers.ts @@ -20,6 +20,11 @@ import { UUID } from '@opencrvs/commons' export const resolvers: GQLResolver = { Query: { async hasChildLocation(_, { parentId }) { + const children = await fetchLocationChildren(parentId as UUID) + const [childLocation] = children + return childLocation + }, + async isLeafLevelLocation(_, { locationId }) { let children: SavedLocation[] /* * This is because of a tech debt we have that @@ -27,23 +32,23 @@ export const resolvers: GQLResolver = { * country so we have a bunch of places where we * need to manually check if the id equals '0' */ - if (parentId === '0') { + if (locationId === '0') { children = await fetchAllLocations() } else { - children = await fetchLocationChildren(parentId as UUID) + children = await fetchLocationChildren(locationId as UUID) } /* * We want to consider only the admin structure locations * here & not the offices or addresses that might have the * given location as a parent */ - const [childLocation] = children.filter( + const administrativeChildLocation = children.filter( (child) => child.type?.coding?.some(({ code }) => code === 'ADMIN_STRUCTURE') && child.partOf && - resourceIdentifierToUUID(child.partOf.reference) === parentId + resourceIdentifierToUUID(child.partOf.reference) === locationId ) - return childLocation + return administrativeChildLocation.length == 0 } } } diff --git a/packages/gateway/src/features/location/schema.graphql b/packages/gateway/src/features/location/schema.graphql index db6e0e46e5f..06aacd48ab0 100644 --- a/packages/gateway/src/features/location/schema.graphql +++ b/packages/gateway/src/features/location/schema.graphql @@ -44,4 +44,5 @@ type Location { # -> Location (mostly the same property name except:) type Query { hasChildLocation(parentId: String!): Location + isLeafLevelLocation(locationId: String!): Boolean! } diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index fcccf865fb4..512f38175c9 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -29,6 +29,7 @@ export interface GQLQuery { fetchMarriageRegistration?: GQLMarriageRegistration fetchRecordDetailsForVerification?: GQLRecordDetails hasChildLocation?: GQLLocation + isLeafLevelLocation: boolean getUser?: GQLUser getUserByMobile?: GQLUser getUserByEmail?: GQLUser @@ -1837,6 +1838,7 @@ export interface GQLQueryTypeResolver { fetchMarriageRegistration?: QueryToFetchMarriageRegistrationResolver fetchRecordDetailsForVerification?: QueryToFetchRecordDetailsForVerificationResolver hasChildLocation?: QueryToHasChildLocationResolver + isLeafLevelLocation?: QueryToIsLeafLevelLocationResolver getUser?: QueryToGetUserResolver getUserByMobile?: QueryToGetUserByMobileResolver getUserByEmail?: QueryToGetUserByEmailResolver @@ -2113,6 +2115,21 @@ export interface QueryToHasChildLocationResolver { ): TResult } +export interface QueryToIsLeafLevelLocationArgs { + locationId: string +} +export interface QueryToIsLeafLevelLocationResolver< + TParent = any, + TResult = any +> { + ( + parent: TParent, + args: QueryToIsLeafLevelLocationArgs, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + export interface QueryToGetUserArgs { userId?: string } diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index 67280c6e576..3cb5d7a8e45 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -32,6 +32,7 @@ type Query { fetchMarriageRegistration(id: ID!): MarriageRegistration fetchRecordDetailsForVerification(id: String!): RecordDetails hasChildLocation(parentId: String!): Location + isLeafLevelLocation(locationId: String!): Boolean! getUser(userId: String): User getUserByMobile(mobile: String): User getUserByEmail(email: String): User From df5163949aa14a45e598820fad0798bc485a15f6 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 15:20:13 +0600 Subject: [PATCH 06/11] fix: prevent disabled filter from being selected --- .../src/views/SysAdmin/Performance/CompletenessRates.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx index bb7f5594879..3ba146ab060 100644 --- a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx +++ b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.tsx @@ -56,7 +56,7 @@ export enum COMPLETENESS_RATE_REPORT_BASE { } interface ISearchParams { - locationId: string + locationId?: string timeStart: string timeEnd: string time: CompletenessRateTime @@ -134,6 +134,13 @@ function Filter({ }) const dispatch = useDispatch() + if ( + data?.isLeafLevelLocation === true && + base === COMPLETENESS_RATE_REPORT_BASE.LOCATION + ) { + onBaseChange(COMPLETENESS_RATE_REPORT_BASE.TIME) + } + const options: (IPerformanceSelectOption & { disabled?: boolean })[] = [ { label: intl.formatMessage(messages.overTime), From 9f65a8b717cf2b4d23c5670e0d78f1a2aafcb5f5 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 16:05:45 +0600 Subject: [PATCH 07/11] test: update mocks to use new query --- .../Performance/CompletenessRates.test.tsx | 54 +++---------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx index 4576df441e7..537aa5e9d8b 100644 --- a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx +++ b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx @@ -17,8 +17,8 @@ import { AppStore } from '@client/store' import { CompletenessRates } from '@client/views/SysAdmin/Performance/CompletenessRates' import { EVENT_COMPLETENESS_RATES } from '@client/navigation/routes' import { - HAS_CHILD_LOCATION, - FETCH_MONTH_WISE_EVENT_ESTIMATIONS + FETCH_MONTH_WISE_EVENT_ESTIMATIONS, + IS_LEAF_LEVEL_LOCATION } from '@client/views/SysAdmin/Performance/queries' import { waitForElement } from '@client/tests/wait-for-element' import { stringify, parse } from 'query-string' @@ -37,33 +37,12 @@ describe('Registraion Rates tests', () => { const graphqlMocks = [ { request: { - query: HAS_CHILD_LOCATION, + query: IS_LEAF_LEVEL_LOCATION, variables: { parentId: '6e1f3bce-7bcb-4bf6-8e35-0d9facdf158b' } }, result: { data: { - hasChildLocation: { - id: 'd70fbec1-2b26-474b-adbc-bb83783bdf29', - type: 'ADMIN_STRUCTURE', - identifier: [ - { - system: 'http://opencrvs.org/specs/id/geo-id', - value: '4194' - }, - { - system: 'http://opencrvs.org/specs/id/bbs-code', - value: '11' - }, - { - system: 'http://opencrvs.org/specs/id/jurisdiction-type', - value: 'UNION' - }, - { - system: 'http://opencrvs.org/specs/id/a2i-internal-reference', - value: 'division=9&district=30&upazila=233&union=4194' - } - ] - } + hasChildLocation: true } } }, @@ -233,33 +212,12 @@ describe('Registraion Rates error state tests', () => { const graphqlMocks = [ { request: { - query: HAS_CHILD_LOCATION, + query: IS_LEAF_LEVEL_LOCATION, variables: { parentId: '6e1f3bce-7bcb-4bf6-8e35-0d9facdf158b' } }, result: { data: { - hasChildLocation: { - id: 'd70fbec1-2b26-474b-adbc-bb83783bdf29', - type: 'ADMIN_STRUCTURE', - identifier: [ - { - system: 'http://opencrvs.org/specs/id/geo-id', - value: '4194' - }, - { - system: 'http://opencrvs.org/specs/id/bbs-code', - value: '11' - }, - { - system: 'http://opencrvs.org/specs/id/jurisdiction-type', - value: 'UNION' - }, - { - system: 'http://opencrvs.org/specs/id/a2i-internal-reference', - value: 'division=9&district=30&upazila=233&union=4194' - } - ] - } + hasChildLocation: true } } }, From 152c24aad5185b1e943e3bdad6d3862e0e384da9 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 16:29:21 +0600 Subject: [PATCH 08/11] test: add tests for isLeafLevelLocation query --- .../features/location/root-resolvers.test.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/gateway/src/features/location/root-resolvers.test.ts b/packages/gateway/src/features/location/root-resolvers.test.ts index 059bd1de287..acec9a25a1d 100644 --- a/packages/gateway/src/features/location/root-resolvers.test.ts +++ b/packages/gateway/src/features/location/root-resolvers.test.ts @@ -8,6 +8,10 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { + savedAdministrativeLocation, + savedLocation +} from '@opencrvs/commons/fixtures' import { resolvers } from '@gateway/features/location/root-resolvers' import * as fetchAny from 'jest-fetch-mock' @@ -27,4 +31,36 @@ describe('Location root resolvers', () => { expect(composition).toBeDefined() }) }) + describe('isLeafLevelLocation', () => { + it('returns false if a location has administrative locations as its children', async () => { + fetch.mockResponseOnce( + JSON.stringify([ + savedAdministrativeLocation({ partOf: { reference: 'Location/1' } }) + ]) + ) + // @ts-ignore + const isLeafLevelLocation = await resolvers.Query!.isLeafLevelLocation( + {}, + { locationId: '1' }, + { headers: undefined } + ) + expect(isLeafLevelLocation).toBe(false) + }) + + it('returns true if a location has no administrative locations as its children', async () => { + fetch.mockResponseOnce( + JSON.stringify([ + savedLocation({ partOf: { reference: 'Location/1' } }), + savedAdministrativeLocation({ partOf: { reference: 'Location/2' } }) + ]) + ) + // @ts-ignore + const isLeafLevelLocation = await resolvers.Query!.isLeafLevelLocation( + {}, + { locationId: '1' }, + { headers: undefined } + ) + expect(isLeafLevelLocation).toBe(true) + }) + }) }) From 7597b60a2c8e60a64ce5540fda4ee442fc581447 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 18:05:19 +0600 Subject: [PATCH 09/11] chore!: remove hasChildLocation query --- packages/client/graphql.schema.json | 29 -- packages/client/src/tests/schema.graphql | 1 - .../utils/gateway-deprecated-do-not-use.d.ts | 2 - packages/client/src/utils/gateway.ts | 23 - .../Performance/CompletenessRates.test.tsx | 4 +- .../src/views/SysAdmin/Performance/queries.ts | 13 - .../features/location/root-resolvers.test.ts | 13 - .../src/features/location/root-resolvers.ts | 5 - .../src/features/location/schema.graphql | 1 - packages/gateway/src/graphql/schema.d.ts | 436 +++++++++--------- packages/gateway/src/graphql/schema.graphql | 49 +- packages/gateway/src/rate-limit.test.ts | 13 +- 12 files changed, 246 insertions(+), 343 deletions(-) diff --git a/packages/client/graphql.schema.json b/packages/client/graphql.schema.json index 9c34546401d..5b801c9a2d1 100644 --- a/packages/client/graphql.schema.json +++ b/packages/client/graphql.schema.json @@ -13996,35 +13996,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "hasChildLocation", - "description": null, - "args": [ - { - "name": "parentId", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "Location", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "isLeafLevelLocation", "description": null, diff --git a/packages/client/src/tests/schema.graphql b/packages/client/src/tests/schema.graphql index ade59b35fd7..429a10ed9d4 100644 --- a/packages/client/src/tests/schema.graphql +++ b/packages/client/src/tests/schema.graphql @@ -1338,7 +1338,6 @@ type Query { ): RegistrationCountResult fetchMarriageRegistration(id: ID!): MarriageRegistration fetchRecordDetailsForVerification(id: String!): RecordDetails - hasChildLocation(parentId: String!): Location getUser(userId: String): User getUserByMobile(mobile: String): User getUserByEmail(email: String): User diff --git a/packages/client/src/utils/gateway-deprecated-do-not-use.d.ts b/packages/client/src/utils/gateway-deprecated-do-not-use.d.ts index db4c85123ac..65ba841ca1e 100644 --- a/packages/client/src/utils/gateway-deprecated-do-not-use.d.ts +++ b/packages/client/src/utils/gateway-deprecated-do-not-use.d.ts @@ -38,7 +38,6 @@ export interface GQLQuery { fetchRecordDetailsForVerification?: GQLRecordDetails locationsByParent?: Array locationById?: GQLLocation - hasChildLocation?: GQLLocation getUser?: GQLUser getUserByMobile?: GQLUser getUserByEmail?: GQLUser @@ -2053,7 +2052,6 @@ export interface GQLQueryTypeResolver { fetchRecordDetailsForVerification?: QueryToFetchRecordDetailsForVerificationResolver locationsByParent?: QueryToLocationsByParentResolver locationById?: QueryToLocationByIdResolver - hasChildLocation?: QueryToHasChildLocationResolver getUser?: QueryToGetUserResolver getUserByMobile?: QueryToGetUserByMobileResolver getUserByEmail?: QueryToGetUserByEmailResolver diff --git a/packages/client/src/utils/gateway.ts b/packages/client/src/utils/gateway.ts index 7b645632414..689cffe3d2b 100644 --- a/packages/client/src/utils/gateway.ts +++ b/packages/client/src/utils/gateway.ts @@ -1408,7 +1408,6 @@ export type Query = { getUserByEmail?: Maybe getUserByMobile?: Maybe getVSExports?: Maybe - hasChildLocation?: Maybe isLeafLevelLocation: Scalars['Boolean'] listBirthRegistrations?: Maybe queryPersonByIdentifier?: Maybe @@ -1568,10 +1567,6 @@ export type QueryGetUserByMobileArgs = { mobile?: InputMaybe } -export type QueryHasChildLocationArgs = { - parentId: Scalars['String'] -} - export type QueryIsLeafLevelLocationArgs = { locationId: Scalars['String'] } @@ -7311,24 +7306,6 @@ export type GetLocationStatisticsQuery = { } | null } -export type HasChildLocationQueryVariables = Exact<{ - parentId: Scalars['String'] -}> - -export type HasChildLocationQuery = { - __typename?: 'Query' - hasChildLocation?: { - __typename?: 'Location' - id: string - type?: string | null - identifier?: Array<{ - __typename?: 'Identifier' - system?: string | null - value?: string | null - }> | null - } | null -} - export type IsLeafLevelLocationQueryVariables = Exact<{ locationId: Scalars['String'] }> diff --git a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx index 537aa5e9d8b..989630c1c97 100644 --- a/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx +++ b/packages/client/src/views/SysAdmin/Performance/CompletenessRates.test.tsx @@ -42,7 +42,7 @@ describe('Registraion Rates tests', () => { }, result: { data: { - hasChildLocation: true + isLeafLevelLocation: true } } }, @@ -217,7 +217,7 @@ describe('Registraion Rates error state tests', () => { }, result: { data: { - hasChildLocation: true + isLeafLevelLocation: true } } }, diff --git a/packages/client/src/views/SysAdmin/Performance/queries.ts b/packages/client/src/views/SysAdmin/Performance/queries.ts index 9c4f7992a38..150081ebfb5 100644 --- a/packages/client/src/views/SysAdmin/Performance/queries.ts +++ b/packages/client/src/views/SysAdmin/Performance/queries.ts @@ -10,19 +10,6 @@ */ import { gql } from '@apollo/client' -export const HAS_CHILD_LOCATION = gql` - query hasChildLocation($parentId: String!) { - hasChildLocation(parentId: $parentId) { - id - type - identifier { - system - value - } - } - } -` - export const IS_LEAF_LEVEL_LOCATION = gql` query isLeafLevelLocation($locationId: String!) { isLeafLevelLocation(locationId: $locationId) diff --git a/packages/gateway/src/features/location/root-resolvers.test.ts b/packages/gateway/src/features/location/root-resolvers.test.ts index acec9a25a1d..1375f8d1fcc 100644 --- a/packages/gateway/src/features/location/root-resolvers.test.ts +++ b/packages/gateway/src/features/location/root-resolvers.test.ts @@ -18,19 +18,6 @@ import * as fetchAny from 'jest-fetch-mock' const fetch = fetchAny as any describe('Location root resolvers', () => { - describe('hasChildLocation()', () => { - it('returns a location object if found', async () => { - fetch.mockResponseOnce(JSON.stringify([{ id: 'woohoo' }])) - // @ts-ignore - const composition = await resolvers.Query!.hasChildLocation( - {}, - { parentId: '1' }, - { headers: undefined } - ) - - expect(composition).toBeDefined() - }) - }) describe('isLeafLevelLocation', () => { it('returns false if a location has administrative locations as its children', async () => { fetch.mockResponseOnce( diff --git a/packages/gateway/src/features/location/root-resolvers.ts b/packages/gateway/src/features/location/root-resolvers.ts index 55eb6d59b28..64b6cb3c13b 100644 --- a/packages/gateway/src/features/location/root-resolvers.ts +++ b/packages/gateway/src/features/location/root-resolvers.ts @@ -19,11 +19,6 @@ import { UUID } from '@opencrvs/commons' export const resolvers: GQLResolver = { Query: { - async hasChildLocation(_, { parentId }) { - const children = await fetchLocationChildren(parentId as UUID) - const [childLocation] = children - return childLocation - }, async isLeafLevelLocation(_, { locationId }) { let children: SavedLocation[] /* diff --git a/packages/gateway/src/features/location/schema.graphql b/packages/gateway/src/features/location/schema.graphql index 06aacd48ab0..3491f2ec784 100644 --- a/packages/gateway/src/features/location/schema.graphql +++ b/packages/gateway/src/features/location/schema.graphql @@ -43,6 +43,5 @@ type Location { # -> Location (mostly the same property name except:) } type Query { - hasChildLocation(parentId: String!): Location isLeafLevelLocation(locationId: String!): Boolean! } diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index 512f38175c9..fbd9ed9e882 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -28,7 +28,6 @@ export interface GQLQuery { fetchRegistrationCountByStatus?: GQLRegistrationCountResult fetchMarriageRegistration?: GQLMarriageRegistration fetchRecordDetailsForVerification?: GQLRecordDetails - hasChildLocation?: GQLLocation isLeafLevelLocation: boolean getUser?: GQLUser getUserByMobile?: GQLUser @@ -253,25 +252,6 @@ export interface GQLRecordDetailsNameMap { DeathRegistration: GQLDeathRegistration } -export interface GQLLocation { - id: string - _fhirID?: string - identifier?: Array - status?: string - name?: string - alias?: Array - description?: string - partOf?: string - type?: string - telecom?: Array - address?: GQLAddress - longitude?: number - latitude?: number - altitude?: number - geoData?: string - hierarchy?: Array -} - export interface GQLUser { id: string userMgntUserID: string @@ -736,6 +716,25 @@ export interface GQLRelatedPerson { exactDateOfBirthUnknown?: boolean } +export interface GQLLocation { + id: string + _fhirID?: string + identifier?: Array + status?: string + name?: string + alias?: Array + description?: string + partOf?: string + type?: string + telecom?: Array + address?: GQLAddress + longitude?: number + latitude?: number + altitude?: number + geoData?: string + hierarchy?: Array +} + export interface GQLQuestionnaireQuestion { fieldId?: string value?: string @@ -842,11 +841,6 @@ export interface GQLStatusWiseRegistrationCount { count: number } -export interface GQLIdentifier { - system?: string - value?: string -} - export const enum GQLSystemRoleType { FIELD_AGENT = 'FIELD_AGENT', REGISTRATION_AGENT = 'REGISTRATION_AGENT', @@ -875,6 +869,11 @@ export interface GQLLocalRegistrar { signature?: GQLSignature } +export interface GQLIdentifier { + system?: string + value?: string +} + export interface GQLSignature { data?: string type?: string @@ -1723,7 +1722,6 @@ export interface GQLResolver { __resolveType: GQLRecordDetailsTypeResolver } - Location?: GQLLocationTypeResolver User?: GQLUserTypeResolver SearchUserResult?: GQLSearchUserResultTypeResolver SearchFieldAgentResult?: GQLSearchFieldAgentResultTypeResolver @@ -1756,6 +1754,7 @@ export interface GQLResolver { Map?: GraphQLScalarType Registration?: GQLRegistrationTypeResolver RelatedPerson?: GQLRelatedPersonTypeResolver + Location?: GQLLocationTypeResolver QuestionnaireQuestion?: GQLQuestionnaireQuestionTypeResolver History?: GQLHistoryTypeResolver MedicalPractitioner?: GQLMedicalPractitionerTypeResolver @@ -1767,9 +1766,9 @@ export interface GQLResolver { Attachment?: GQLAttachmentTypeResolver Deceased?: GQLDeceasedTypeResolver StatusWiseRegistrationCount?: GQLStatusWiseRegistrationCountTypeResolver - Identifier?: GQLIdentifierTypeResolver Role?: GQLRoleTypeResolver LocalRegistrar?: GQLLocalRegistrarTypeResolver + Identifier?: GQLIdentifierTypeResolver Signature?: GQLSignatureTypeResolver BookmarkedSeachItem?: GQLBookmarkedSeachItemTypeResolver SearchFieldAgentResponse?: GQLSearchFieldAgentResponseTypeResolver @@ -1837,7 +1836,6 @@ export interface GQLQueryTypeResolver { fetchRegistrationCountByStatus?: QueryToFetchRegistrationCountByStatusResolver fetchMarriageRegistration?: QueryToFetchMarriageRegistrationResolver fetchRecordDetailsForVerification?: QueryToFetchRecordDetailsForVerificationResolver - hasChildLocation?: QueryToHasChildLocationResolver isLeafLevelLocation?: QueryToIsLeafLevelLocationResolver getUser?: QueryToGetUserResolver getUserByMobile?: QueryToGetUserByMobileResolver @@ -2103,18 +2101,6 @@ export interface QueryToFetchRecordDetailsForVerificationResolver< ): TResult } -export interface QueryToHasChildLocationArgs { - parentId: string -} -export interface QueryToHasChildLocationResolver { - ( - parent: TParent, - args: QueryToHasChildLocationArgs, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - export interface QueryToIsLeafLevelLocationArgs { locationId: string } @@ -4361,169 +4347,6 @@ export interface GQLRecordDetailsTypeResolver { | 'DeathRegistration' | Promise<'BirthRegistration' | 'DeathRegistration'> } -export interface GQLLocationTypeResolver { - id?: LocationToIdResolver - _fhirID?: LocationTo_fhirIDResolver - identifier?: LocationToIdentifierResolver - status?: LocationToStatusResolver - name?: LocationToNameResolver - alias?: LocationToAliasResolver - description?: LocationToDescriptionResolver - partOf?: LocationToPartOfResolver - type?: LocationToTypeResolver - telecom?: LocationToTelecomResolver - address?: LocationToAddressResolver - longitude?: LocationToLongitudeResolver - latitude?: LocationToLatitudeResolver - altitude?: LocationToAltitudeResolver - geoData?: LocationToGeoDataResolver - hierarchy?: LocationToHierarchyResolver -} - -export interface LocationToIdResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationTo_fhirIDResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToIdentifierResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToStatusResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToNameResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToAliasResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToDescriptionResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToPartOfResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToTypeResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToTelecomResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToAddressResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToLongitudeResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToLatitudeResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToAltitudeResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToGeoDataResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - -export interface LocationToHierarchyResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - export interface GQLUserTypeResolver { id?: UserToIdResolver userMgntUserID?: UserToUserMgntUserIDResolver @@ -6291,6 +6114,169 @@ export interface RelatedPersonToExactDateOfBirthUnknownResolver< ): TResult } +export interface GQLLocationTypeResolver { + id?: LocationToIdResolver + _fhirID?: LocationTo_fhirIDResolver + identifier?: LocationToIdentifierResolver + status?: LocationToStatusResolver + name?: LocationToNameResolver + alias?: LocationToAliasResolver + description?: LocationToDescriptionResolver + partOf?: LocationToPartOfResolver + type?: LocationToTypeResolver + telecom?: LocationToTelecomResolver + address?: LocationToAddressResolver + longitude?: LocationToLongitudeResolver + latitude?: LocationToLatitudeResolver + altitude?: LocationToAltitudeResolver + geoData?: LocationToGeoDataResolver + hierarchy?: LocationToHierarchyResolver +} + +export interface LocationToIdResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationTo_fhirIDResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToIdentifierResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToStatusResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToNameResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToAliasResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToDescriptionResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToPartOfResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToTypeResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToTelecomResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToAddressResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToLongitudeResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToLatitudeResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToAltitudeResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToGeoDataResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface LocationToHierarchyResolver { + ( + parent: TParent, + args: {}, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + export interface GQLQuestionnaireQuestionTypeResolver { fieldId?: QuestionnaireQuestionToFieldIdResolver value?: QuestionnaireQuestionToValueResolver @@ -7106,12 +7092,12 @@ export interface StatusWiseRegistrationCountToCountResolver< ): TResult } -export interface GQLIdentifierTypeResolver { - system?: IdentifierToSystemResolver - value?: IdentifierToValueResolver +export interface GQLRoleTypeResolver { + _id?: RoleTo_idResolver + labels?: RoleToLabelsResolver } -export interface IdentifierToSystemResolver { +export interface RoleTo_idResolver { ( parent: TParent, args: {}, @@ -7120,7 +7106,7 @@ export interface IdentifierToSystemResolver { ): TResult } -export interface IdentifierToValueResolver { +export interface RoleToLabelsResolver { ( parent: TParent, args: {}, @@ -7129,12 +7115,13 @@ export interface IdentifierToValueResolver { ): TResult } -export interface GQLRoleTypeResolver { - _id?: RoleTo_idResolver - labels?: RoleToLabelsResolver +export interface GQLLocalRegistrarTypeResolver { + name?: LocalRegistrarToNameResolver + role?: LocalRegistrarToRoleResolver + signature?: LocalRegistrarToSignatureResolver } -export interface RoleTo_idResolver { +export interface LocalRegistrarToNameResolver { ( parent: TParent, args: {}, @@ -7143,7 +7130,7 @@ export interface RoleTo_idResolver { ): TResult } -export interface RoleToLabelsResolver { +export interface LocalRegistrarToRoleResolver { ( parent: TParent, args: {}, @@ -7152,13 +7139,10 @@ export interface RoleToLabelsResolver { ): TResult } -export interface GQLLocalRegistrarTypeResolver { - name?: LocalRegistrarToNameResolver - role?: LocalRegistrarToRoleResolver - signature?: LocalRegistrarToSignatureResolver -} - -export interface LocalRegistrarToNameResolver { +export interface LocalRegistrarToSignatureResolver< + TParent = any, + TResult = any +> { ( parent: TParent, args: {}, @@ -7167,7 +7151,12 @@ export interface LocalRegistrarToNameResolver { ): TResult } -export interface LocalRegistrarToRoleResolver { +export interface GQLIdentifierTypeResolver { + system?: IdentifierToSystemResolver + value?: IdentifierToValueResolver +} + +export interface IdentifierToSystemResolver { ( parent: TParent, args: {}, @@ -7176,10 +7165,7 @@ export interface LocalRegistrarToRoleResolver { ): TResult } -export interface LocalRegistrarToSignatureResolver< - TParent = any, - TResult = any -> { +export interface IdentifierToValueResolver { ( parent: TParent, args: {}, diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index 3cb5d7a8e45..49721f5e20c 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -31,7 +31,6 @@ type Query { ): RegistrationCountResult fetchMarriageRegistration(id: ID!): MarriageRegistration fetchRecordDetailsForVerification(id: String!): RecordDetails - hasChildLocation(parentId: String!): Location isLeafLevelLocation(locationId: String!): Boolean! getUser(userId: String): User getUserByMobile(mobile: String): User @@ -392,25 +391,6 @@ type MarriageRegistration implements EventRegistration { union RecordDetails = BirthRegistration | DeathRegistration -type Location { - id: ID! - _fhirID: ID - identifier: [Identifier!] - status: String - name: String - alias: [String!] - description: String - partOf: String - type: String - telecom: [ContactPoint] - address: Address - longitude: Float - latitude: Float - altitude: Float - geoData: String - hierarchy: [Location!] -} - type User { id: ID! userMgntUserID: ID! @@ -862,6 +842,25 @@ type RelatedPerson { exactDateOfBirthUnknown: Boolean } +type Location { + id: ID! + _fhirID: ID + identifier: [Identifier!] + status: String + name: String + alias: [String!] + description: String + partOf: String + type: String + telecom: [ContactPoint] + address: Address + longitude: Float + latitude: Float + altitude: Float + geoData: String + hierarchy: [Location!] +} + type QuestionnaireQuestion { fieldId: String value: String @@ -968,11 +967,6 @@ type StatusWiseRegistrationCount { count: Int! } -type Identifier { - system: String - value: String -} - enum SystemRoleType { FIELD_AGENT REGISTRATION_AGENT @@ -1001,6 +995,11 @@ type LocalRegistrar { signature: Signature } +type Identifier { + system: String + value: String +} + type Signature { data: String type: String diff --git a/packages/gateway/src/rate-limit.test.ts b/packages/gateway/src/rate-limit.test.ts index b1d8e02a5ee..684e2320d0e 100644 --- a/packages/gateway/src/rate-limit.test.ts +++ b/packages/gateway/src/rate-limit.test.ts @@ -21,6 +21,7 @@ import { flushAll } from './utils/redis-test-utils' import { StartedTestContainer } from 'testcontainers' +import { savedAdministrativeLocation } from '@opencrvs/commons/fixtures' const fetch = fetchAny as any const resolvers = rootResolvers as any @@ -144,12 +145,16 @@ describe('Rate limit', () => { it('does not throw RateLimitError when a non-rate-limited route is being called 20 times', async () => { const resolverCalls = Array.from({ length: 20 }, async () => { - fetch.mockResponseOnce(JSON.stringify([{ resourceType: 'Location' }])) - await locationResolvers.Query.hasChildLocation( + fetch.mockResponseOnce( + JSON.stringify([ + savedAdministrativeLocation({ partOf: { reference: 'Location/1' } }) + ]) + ) + await locationResolvers.Query!.isLeafLevelLocation( {}, - { parentId: '1' }, + { locationId: '1' }, { headers: authHeaderRegAgent }, - { fieldName: 'hasChildLocation' } + { fieldName: 'isLeafLevelLocation' } ) }) From 692cdb537cdcf331664a57048d3e379d974a0133 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Thu, 24 Oct 2024 18:21:05 +0600 Subject: [PATCH 10/11] docs: add entry about the deleted & new query --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c50a4ecb1a3..07b7b5b0f40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,9 +50,9 @@ - Remove informant notification configuration from the UI and read notification configuration settings from `record-notification` endpoint in countryconfig - Remove `DEL /elasticIndex` endpoint due reindexing changes. -- Gateways searchEvents `operationHistories` only returns `operationType` & `operatedOn` due to the other fields being unused in OpenCRVS -- Core used to provide review/preview section by default which are now removed and need to be provided from countryconfig. The signature field definitions (e.g. informant signature, bride signature etc.) were hard coded in core which also have now been removed. The signatures can now be added through the review/preview sections defined in countryconfig just like any other field. You can use the following section definition as the default which is without any additional fields. We highly recommend checking out our reference country repository which has the signature fields in it's review/preview sections - +- **Gateways searchEvents API updated** `operationHistories` only returns `operationType` & `operatedOn` due to the other fields being unused in OpenCRVS +- **Config changes to review/preview and signatures** Core used to provide review/preview section by default which are now removed and need to be provided from countryconfig. The signature field definitions (e.g. informant signature, bride signature etc.) were hard coded in core which also have now been removed. The signatures can now be added through the review/preview sections defined in countryconfig just like any other field. You can use the following section definition as the default which is without any additional fields. We highly recommend checking out our reference country repository which has the signature fields in its review/preview sections +- `hasChildLocation` query has been removed from gateway. We have created the query `isLeafLevelLocation` instead which is more descriptive on its intended use. ``` { id: 'preview', From b914c603b064bae48c6af54869935057bcf554f9 Mon Sep 17 00:00:00 2001 From: Tameem Bin Haider Date: Wed, 30 Oct 2024 17:16:27 +0600 Subject: [PATCH 11/11] fix: extract type from available query type --- .../views/Performance/RegistrationsList.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/client/src/views/Performance/RegistrationsList.tsx b/packages/client/src/views/Performance/RegistrationsList.tsx index 943cf5d868a..9c48497965a 100644 --- a/packages/client/src/views/Performance/RegistrationsList.tsx +++ b/packages/client/src/views/Performance/RegistrationsList.tsx @@ -30,9 +30,6 @@ import { IStoreState } from '@client/store' import { GetRegistrationsListByFilterQuery, QueryGetRegistrationsListByFilterArgs, - RegistrationsListByLocationFilter, - RegistrationsListByRegistrarFilter, - RegistrationsListByTimeFilter, RegistrationType } from '@client/utils/gateway' import { generateLocations } from '@client/utils/locationUtils' @@ -398,7 +395,10 @@ function RegistrationListComponent(props: IProps) { } const getTableContentByRegistrar = ( - result: RegistrationsListByRegistrarFilter['results'][0], + result: Extract< + GetRegistrationsListByFilterQuery['getRegistrationsListByFilter'], + { __typename: 'TotalMetricsByRegistrar' } + >['results'][0], index: number ) => ({ ...result, @@ -463,7 +463,10 @@ function RegistrationListComponent(props: IProps) { }) const getTableContentByLocation = ( - result: RegistrationsListByLocationFilter['results'][0], + result: Extract< + GetRegistrationsListByFilterQuery['getRegistrationsListByFilter'], + { __typename: 'TotalMetricsByLocation' } + >['results'][0], index: number ) => ({ ...result, @@ -485,7 +488,10 @@ function RegistrationListComponent(props: IProps) { }) const getTableContentByTime = ( - result: RegistrationsListByTimeFilter['results'][0], + result: Extract< + GetRegistrationsListByFilterQuery['getRegistrationsListByFilter'], + { __typename: 'TotalMetricsByTime' } + >['results'][0], index: number ) => { return {