Skip to content

Commit 5785601

Browse files
authored
Merge pull request #11253 from opencrvs/merge-v1.9.1-to-develop
Merge v1.9.1 to develop
2 parents 7fcc722 + de3d3db commit 5785601

File tree

16 files changed

+189
-95
lines changed

16 files changed

+189
-95
lines changed

CHANGELOG.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ HTTP input now accepts `field('..')` references in the HTTP body definition.
1212

1313
- Elasticsearch now stores location IDs as a full administrative hierarchy, with the leaf representing the actual event location. This enables searching events by any jurisdiction level (district, province, office, health facility etc.).
1414

15-
## 1.9.1
15+
## [1.9.1](https://github.com/opencrvs/opencrvs-core/compare/v1.9.0...v1.9.1)
1616

1717
### Breaking changes
1818

@@ -41,6 +41,19 @@ HTTP input now accepts `field('..')` references in the HTTP body definition.
4141
- `RECORD_REGISTRATION_VERIFY_CERTIFIED_COPIES`
4242
- `PROFILE_UPDATE`
4343

44+
### New features
45+
46+
- Add multi-field search with a single component [#10617](https://github.com/opencrvs/opencrvs-core/issues/10617)
47+
- **Search Field**: A new form field that allows searching previous records and using the data to pre-fill the current form. [#10131](https://github.com/opencrvs/opencrvs-core/issues/10131)
48+
- HTTP input now accepts `field('..')` references in the HTTP body definition.
49+
- **Searchable Select**: A new select component that allows searching through options. Useful for selects with a large number of options. Currently being used in address fields. [#10749](https://github.com/opencrvs/opencrvs-core/issues/10749)
50+
51+
### Bug fixes
52+
- During user password reset, email address lookup is now case insensitive [#9869](https://github.com/opencrvs/opencrvs-core/issues/9869)
53+
- Users cannot activate or reactivate users with roles not specified in the `user.edit` scope [#9933](https://github.com/opencrvs/opencrvs-core/issues/9933)
54+
- Login page no longer show "Farajaland CRVS" before showing the correct title [#10958](https://github.com/opencrvs/opencrvs-core/issues/10958)
55+
- `ALPHA_PRINT_BUTTON` does not get disabled after first print [#10953](https://github.com/opencrvs/opencrvs-core/issues/10953)
56+
4457
## [1.9.0](https://github.com/opencrvs/opencrvs-core/compare/v1.8.1...v1.9.0)
4558

4659
### Breaking changes
@@ -319,7 +332,6 @@ To see Events V2 in action, check out the example configurations in the **countr
319332
- Add Import/Export system client and `record.export` scope to enable data migrations [#10415](https://github.com/opencrvs/opencrvs-core/issues/10415)
320333
- Add an Alpha version of configurable "Print" button that will be refactored in a later release - this button can be used to print certificates during declaration/correction flow. [#10039](https://github.com/opencrvs/opencrvs-core/issues/10039)
321334
- Add bulk import endpoint [#10590](https://github.com/opencrvs/opencrvs-core/pull/10590)
322-
- Add multi-field search with a single component [#10617](https://github.com/opencrvs/opencrvs-core/issues/10617)
323335

324336
### Improvements
325337

development-environment/reindex.sh

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,31 @@ get_reindexing_token() {
1818
}
1919

2020
trigger_reindex() {
21-
local token
21+
local token raw status body
2222
token=$(get_reindexing_token)
23-
curl -s -f -X POST \
23+
24+
raw=$(curl -X POST \
2425
-H "Authorization: Bearer ${token}" \
2526
-H "Content-Type: application/json" \
26-
"${EVENTS_URL%/}/events/reindex"
27+
-w "\n%{http_code}" \
28+
"${EVENTS_URL%/}/events/reindex" 2>&1)
29+
30+
status=$(echo "$raw" | tail -n1)
31+
body=$(echo "$raw" | sed '$d')
32+
33+
if [[ "$status" == "000" ]]; then
34+
echo "curl failed (connection or TLS error)"
35+
echo "$body"
36+
return 1
37+
fi
38+
39+
if (( status >= 200 && status < 300 )); then
40+
return 0
41+
fi
42+
43+
echo "curl failed with status $status"
44+
echo "$body"
45+
return 1
2746
}
2847

2948
reindexing_attempts=0

packages/client/.storybook/preview.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { useApolloClient } from '@client/utils/apolloClient'
2222
import { ApolloProvider } from '@client/utils/ApolloProvider'
2323
import { queryClient, TRPCProvider } from '@client/v2-events/trpc'
2424
import { Provider, useSelector } from 'react-redux'
25-
import { clear } from 'idb-keyval'
2625
import {
2726
createMemoryRouter,
2827
Outlet,
@@ -55,6 +54,7 @@ import {
5554
} from '@client/v2-events/features/events/fixtures'
5655
import { EventConfig } from '@opencrvs/commons/client'
5756
import { getUserDetails } from '@client/profile/profileSelectors'
57+
import { storage } from '@client/storage'
5858

5959
WebFont.load({
6060
google: {
@@ -167,15 +167,6 @@ export const parameters = {
167167

168168
const generator = testDataGenerator()
169169

170-
/*
171-
* Clear all indexedDB databases before each story
172-
*/
173-
export async function clearStorage() {
174-
clear()
175-
}
176-
177-
clearStorage()
178-
179170
const tennisClubMembershipEventWithCustomAction = {
180171
...tennisClubMembershipEvent,
181172
actions: tennisClubMembershipEvent.actions.concat([
@@ -229,7 +220,7 @@ const preview: Preview = {
229220
}
230221
},
231222
async (options) => {
232-
await clearStorage()
223+
await storage.clearStorage()
233224
queryClient.clear()
234225
const primaryOfficeId = '028d2c85-ca31-426d-b5d1-2cef545a4902' as UUID
235226

packages/client/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ WebFont.load({
2929
}
3030
})
3131

32-
storage.configStorage('OpenCRVS')
32+
storage.configStorage()
3333

3434
const { store } = createStore()
3535

packages/client/src/storage.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,37 @@
88
*
99
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
1010
*/
11-
import { createStore, get, set, del, UseStore } from 'idb-keyval'
11+
import { createStore, get, set, del, entries, clear } from 'idb-keyval'
1212
import { validateApplicationVersion } from '@client/utils'
1313

14-
let store: UseStore | undefined
15-
function configStorage(dbName: string) {
16-
store = createStore(dbName, 'keyvaluepairs')
14+
const DATABASE_NAME = 'OpenCRVS'
15+
const STORE_NAME = 'keyvaluepairs'
16+
17+
/**
18+
* Create store when module is first loaded.
19+
*
20+
* Previously store was created on-demand, initiated at application root. (index.tsx).
21+
* However, files are executed during import. React renders after everything is imported.
22+
*
23+
* There is no guarantee that application root is executed before other files that might use storage (e.g. useDrafts).
24+
*/
25+
let store = createStore(DATABASE_NAME, STORE_NAME)
26+
27+
function configStorage() {
28+
if (!store) {
29+
store = createStore(DATABASE_NAME, STORE_NAME)
30+
}
1731

1832
validateApplicationVersion()
1933
}
2034

2135
async function getItem<T = string>(key: string): Promise<T | null> {
36+
if (!store) {
37+
// eslint-disable-next-line no-console
38+
console.error('IDB store not initialized before getItem:', key)
39+
return null
40+
}
41+
2242
return (await get<T>(key, store)) || null
2343
}
2444

@@ -30,8 +50,13 @@ async function removeItem(key: string) {
3050
return await del(key, store)
3151
}
3252

53+
async function clearStorage() {
54+
return clear(store)
55+
}
56+
3357
export const storage = {
3458
configStorage,
59+
clearStorage,
3560
getItem,
3661
setItem,
3762
removeItem

packages/client/src/v2-events/features/drafts/useDrafts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export function useDrafts() {
231231

232232
createDraft.mutate({
233233
eventId: localDraft.eventId,
234-
declaration: deepDropNulls(localDraft.action.declaration),
234+
declaration: localDraft.action.declaration,
235235
annotation: deepDropNulls(localDraft.action.annotation),
236236
transactionId: localDraft.transactionId,
237237
type: localDraft.action.type,

packages/client/src/v2-events/features/events/ReadOnlyView.stories.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import {
2020
generateEventDraftDocument,
2121
generateWorkqueues,
2222
getCurrentEventState,
23-
tennisClubMembershipEvent
23+
tennisClubMembershipEvent,
24+
TestUserRole
2425
} from '@opencrvs/commons/client'
2526
import { AppRouter } from '@client/v2-events/trpc'
2627
import { ROUTES, routesConfig } from '@client/v2-events/routes'
@@ -70,17 +71,6 @@ const modifiedDraft = generateEventDraftDocument({
7071
})
7172

7273
export const ViewRecordMenuItemInsideActionMenus: Story = {
73-
loaders: [
74-
async () => {
75-
window.localStorage.setItem(
76-
'opencrvs',
77-
generator.user.token.localRegistrar
78-
)
79-
// Intermittent failures starts to happen when global state gets out of whack.
80-
// // This is a workaround to ensure that the state is reset when similar tests are run in parallel.
81-
await new Promise((resolve) => setTimeout(resolve, 50))
82-
}
83-
],
8474
play: async ({ canvasElement, step }) => {
8575
const canvas = within(canvasElement)
8676

@@ -91,6 +81,7 @@ export const ViewRecordMenuItemInsideActionMenus: Story = {
9181
)
9282
},
9383
parameters: {
84+
userRole: TestUserRole.enum.LOCAL_REGISTRAR,
9485
reactRouter: {
9586
router: routesConfig,
9687
initialPath: ROUTES.V2.EVENTS.EVENT.RECORD.buildPath({

packages/client/src/v2-events/features/events/components/Action/DeclarationAction.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
Draft,
1717
createEmptyDraft,
1818
findActiveDraftForEvent,
19-
dangerouslyGetCurrentEventStateWithDrafts,
2019
getActionAnnotation,
2120
ActionType,
2221
deepMerge,
@@ -26,7 +25,8 @@ import {
2625
EventDocument,
2726
EventConfig,
2827
getAvailableActionsForEvent,
29-
getCurrentEventState
28+
getCurrentEventState,
29+
applyDraftToEventIndex
3030
} from '@opencrvs/commons/client'
3131
import { withSuspense } from '@client/v2-events/components/withSuspense'
3232
import { useEventFormData } from '@client/v2-events/features/events/useEventFormData'
@@ -190,14 +190,10 @@ function DeclarationActionComponent({
190190
? mergeDrafts(activeRemoteDraft, localDraftWithAdjustedTimestamp)
191191
: localDraftWithAdjustedTimestamp
192192

193-
const eventStateWithDrafts = useMemo(
194-
() =>
195-
dangerouslyGetCurrentEventStateWithDrafts({
196-
event,
197-
draft: mergedDraft,
198-
configuration
199-
}),
200-
[mergedDraft, event, configuration]
193+
const eventStateWithDraftApplied = applyDraftToEventIndex(
194+
getCurrentEventState(event, configuration),
195+
mergedDraft,
196+
configuration
201197
)
202198

203199
const actionAnnotation = useMemo(() => {
@@ -249,7 +245,7 @@ function DeclarationActionComponent({
249245
// Then use form values from drafts.
250246
const initialFormValues = deepMerge(
251247
currentDeclaration || {},
252-
eventStateWithDrafts.declaration
248+
eventStateWithDraftApplied.declaration
253249
)
254250

255251
setFormValues(initialFormValues)

packages/client/src/v2-events/features/events/components/Output.stories.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,63 @@ export const DataOutput: Story = {
324324
} satisfies FieldValue
325325
}
326326
}
327+
328+
export const VerificationStatusOutputWhenStatusIsVerified: Story = {
329+
args: {
330+
value: 'verified',
331+
field: {
332+
type: FieldType.VERIFICATION_STATUS,
333+
id: 'applicant.verificationStatus',
334+
label: {
335+
id: 'applicant.verificationStatus',
336+
defaultMessage: 'Verification Status',
337+
description: 'The verification status of the applicant'
338+
},
339+
configuration: {
340+
status: {
341+
id: 'verified.status.text',
342+
defaultMessage:
343+
'{value, select, authenticated {ID Authenticated} verified {ID Verified} failed {Unverified ID} pending {Pending verification} other {Invalid value}}',
344+
description:
345+
'Status text shown on the pill on both form declaration and review page'
346+
},
347+
description: {
348+
id: 'verified.status.description',
349+
defaultMessage:
350+
"{value, select, authenticated {This identity has been successfully authenticated with the Farajaland’s National ID System. To make edits, please remove the authentication first.} verified {This identity data has been successfully verified with the Farajaland’s National ID System. Please note that their identity has not been authenticated using the individual's biometrics. To make edits, please remove the verification first.} pending {Identity pending verification with Farajaland’s National ID system} failed {The identity data does not match an entry in Farajaland’s National ID System} other {Invalid value}}",
351+
description: 'Description text of the status'
352+
}
353+
}
354+
}
355+
}
356+
}
357+
358+
export const VerificationStatusOutputWhenStatusIsNull: Story = {
359+
args: {
360+
value: null,
361+
field: {
362+
type: FieldType.VERIFICATION_STATUS,
363+
id: 'applicant.verificationStatus',
364+
label: {
365+
id: 'applicant.verificationStatus',
366+
defaultMessage: 'Verification Status',
367+
description: 'The verification status of the applicant'
368+
},
369+
configuration: {
370+
status: {
371+
id: 'verified.status.text',
372+
defaultMessage:
373+
'{value, select, authenticated {ID Authenticated} verified {ID Verified} failed {Unverified ID} pending {Pending verification} other {Invalid value}}',
374+
description:
375+
'Status text shown on the pill on both form declaration and review page'
376+
},
377+
description: {
378+
id: 'verified.status.description',
379+
defaultMessage:
380+
"{value, select, authenticated {This identity has been successfully authenticated with the Farajaland’s National ID System. To make edits, please remove the authentication first.} verified {This identity data has been successfully verified with the Farajaland’s National ID System. Please note that their identity has not been authenticated using the individual's biometrics. To make edits, please remove the verification first.} pending {Identity pending verification with Farajaland’s National ID system} failed {The identity data does not match an entry in Farajaland’s National ID System} other {Invalid value}}",
381+
description: 'Description text of the status'
382+
}
383+
}
384+
}
385+
}
386+
}

packages/client/src/v2-events/features/events/registered-fields/LinkButton.tsx

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,7 @@ function LinkButtonInput({
3535
}) {
3636
const intl = useIntl()
3737
const url = setRedirectURI(configuration.url)
38-
const { submitLocalDraft, isLocalDraftSubmitted } = useDrafts()
3938

40-
useEffect(() => {
41-
if (isLocalDraftSubmitted) {
42-
window.location.href = url
43-
}
44-
}, [isLocalDraftSubmitted, url])
45-
46-
const handleClick = (e: React.MouseEvent) => {
47-
e.preventDefault()
48-
try {
49-
submitLocalDraft()
50-
} catch (err) {
51-
// eslint-disable-next-line no-console
52-
console.error('Error submitting local draft:', err)
53-
}
54-
}
5539
return (
5640
<Button
5741
fullWidth
@@ -61,7 +45,6 @@ function LinkButtonInput({
6145
id={id}
6246
size="large"
6347
type="secondary"
64-
onClick={handleClick}
6548
>
6649
{configuration.icon && (
6750
<Icon

0 commit comments

Comments
 (0)