Skip to content

Commit

Permalink
Events v2: implement delete action for action menu, make sure delete …
Browse files Browse the repository at this point in the history
…works in the form three dot menu (#8297)
  • Loading branch information
rikukissa authored Jan 7, 2025
1 parent 22816d5 commit 4ed93eb
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* OpenCRVS is also distributed under the terms of the Civil Registration
* & Healthcare Disclaimer located at http://opencrvs.org/license.
*
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
*/

import React, { useEffect } from 'react'
import { useTypedParams } from 'react-router-typesafe-routes/dom'
import { useNavigate } from 'react-router-dom'
import { ROUTES } from '@client/v2-events/routes'
import { useEvents } from '@client/v2-events/features/events/useEvents/useEvents'

export function DeleteEvent() {
const { eventId } = useTypedParams(ROUTES.V2.EVENTS.DELETE)
const navigate = useNavigate()
const events = useEvents()
const deleteEvent = events.deleteEvent

useEffect(() => {
deleteEvent.mutate({ eventId })
navigate(ROUTES.V2.path)
}, [deleteEvent, eventId, navigate])

return <div />
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export function useEventFormNavigation() {

if (deleteConfirm) {
deleteEvent.mutate({ eventId })
goToHome()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ import { useMutation } from '@tanstack/react-query'
import { getMutationKey } from '@trpc/react-query'
import { api, utils } from '@client/v2-events/trpc'

function isTemporaryId(id: string) {
return id.startsWith('tmp-')
}

function waitUntilEventIsCreated<R>(
canonicalMutationFn: (params: { eventId: string }) => Promise<R>
): (params: { eventId: string }) => Promise<R> {
return async ({ eventId }) => {
if (!isTemporaryId(eventId)) {
return canonicalMutationFn({ eventId: eventId })
}

const localVersion = utils.event.get.getData(eventId)
if (!localVersion || localVersion.id === localVersion.transactionId) {
throw new Error('Event that has not been stored yet cannot be deleted')
Expand All @@ -27,7 +35,12 @@ function waitUntilEventIsCreated<R>(
}

utils.event.delete.setMutationDefaults(({ canonicalMutationFn }) => ({
retry: true,
retry: (_, error) => {
if (error.data?.httpStatus === 404 || error.data?.httpStatus === 400) {
return false
}
return true
},
retryDelay: 10000,
onSuccess: ({ id }) => {
void utils.events.get.invalidate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import React from 'react'
import { useIntl } from 'react-intl'

import { useNavigate } from 'react-router-dom'
import { validate } from '@opencrvs/commons/client'
import { validate, ActionType } from '@opencrvs/commons/client'
import { type ActionConfig } from '@opencrvs/commons'
import { CaretDown } from '@opencrvs/components/lib/Icon/all-icons'
import { PrimaryButton } from '@opencrvs/components/lib/buttons'
Expand Down Expand Up @@ -57,21 +57,26 @@ export function ActionMenu({ eventId }: { eventId: string }) {
</PrimaryButton>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
{configuration.actions.filter(isActionVisible).map((action) => (
<DropdownMenu.Item
key={action.type}
onClick={() => {
if (action.type === 'CREATE' || action.type === 'CUSTOM') {
alert(`Action ${action.type} is not implemented yet.`)
return
}
{configuration.actions.filter(isActionVisible).map((action) => {
return (
<DropdownMenu.Item
key={action.type}
onClick={() => {
if (
action.type === ActionType.CREATE ||
action.type === ActionType.CUSTOM
) {
alert(`Action ${action.type} is not implemented yet.`)
return
}

navigate(ROUTES.V2.EVENTS[action.type].buildPath({ eventId }))
}}
>
{intl.formatMessage(action.label)}
</DropdownMenu.Item>
))}
navigate(ROUTES.V2.EVENTS[action.type].buildPath({ eventId }))
}}
>
{intl.formatMessage(action.label)}
</DropdownMenu.Item>
)
})}
</DropdownMenu.Content>
</DropdownMenu>
</>
Expand Down
5 changes: 5 additions & 0 deletions packages/client/src/v2-events/routes/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Debug } from '@client/v2-events/features/debug/debug'
import * as Declare from '@client/v2-events/features/events/actions/declare'
import * as Register from '@client/v2-events/features/events/actions/register'
import { WorkqueueLayout, FormLayout } from '@client/v2-events/layouts'
import { DeleteEvent } from '@client/v2-events/features/events/actions/delete'
import { ROUTES } from './routes'

/**
Expand Down Expand Up @@ -63,6 +64,10 @@ export const routesConfig = {
path: ROUTES.V2.EVENTS.CREATE.path,
element: <EventSelection />
},
{
path: ROUTES.V2.EVENTS.DELETE.path,
element: <DeleteEvent />
},
{
path: ROUTES.V2.EVENTS.DECLARE.path,
element: (
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/v2-events/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const ROUTES = {
params: { eventId: string().defined() }
}),
CREATE: route('create'),
DELETE: route('delete/:eventId'),
DECLARE: route(
'declare/:eventId',
{
Expand Down
17 changes: 13 additions & 4 deletions packages/client/src/v2-events/trpc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import {
type PersistedClient,
type Persister
} from '@tanstack/react-query-persist-client'
import { httpLink, loggerLink } from '@trpc/client'
import { httpLink, loggerLink, TRPCClientError } from '@trpc/client'
import { createTRPCQueryUtils, createTRPCReact } from '@trpc/react-query'
import React from 'react'
import superjson from 'superjson'
import { getToken } from '@client/utils/authUtils'

import { storage } from '@client/storage'
import { getToken } from '@client/utils/authUtils'

export const api = createTRPCReact<AppRouter>()

Expand Down Expand Up @@ -89,8 +90,16 @@ export function TRPCProvider({ children }: { children: React.ReactNode }) {
maxAge: undefined,
buster: 'persisted-indexed-db',
dehydrateOptions: {
shouldDehydrateMutation: (mut) => {
return mut.state.status !== 'success'
shouldDehydrateMutation: (mutation) => {
if (mutation.state.status === 'error') {
const error = mutation.state.error
if (error instanceof TRPCClientError && error.data?.httpStatus) {
return !error.data.httpStatus.toString().startsWith('4')
}
return true
}

return mutation.state.status !== 'success'
}
}
}}
Expand Down
8 changes: 8 additions & 0 deletions packages/commons/src/events/ActionConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const ActionType = {
DETECT_DUPLICATE: 'DETECT_DUPLICATE',
NOTIFY: 'NOTIFY',
DECLARE: 'DECLARE',
DELETE: 'DELETE',
CUSTOM: 'CUSTOM'
} as const

Expand Down Expand Up @@ -60,6 +61,12 @@ const RegisterConfig = ActionConfigBase.merge(
})
)

const DeleteConfig = ActionConfigBase.merge(
z.object({
type: z.literal(ActionType.DELETE)
})
)

const CustomConfig = ActionConfigBase.merge(
z.object({
type: z.literal(ActionType.CUSTOM)
Expand All @@ -71,6 +78,7 @@ export const ActionConfig = z.discriminatedUnion('type', [
DeclareConfig,
ValidateConfig,
RegisterConfig,
DeleteConfig,
CustomConfig
])

Expand Down
8 changes: 5 additions & 3 deletions packages/events/src/service/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ async function getEventByTransactionId(transactionId: string) {

return document
}
class EventNotFoundError extends Error {
class EventNotFoundError extends TRPCError {
constructor(id: string) {
super('Event not found with ID: ' + id)
super({
code: 'NOT_FOUND',
message: `Event not found with ID: ${id}`
})
}
}

export async function getEventById(id: string) {
const db = await getClient()

Expand Down

0 comments on commit 4ed93eb

Please sign in to comment.