Skip to content

Commit b73f3bb

Browse files
authored
fix: show assigned user information in actionMenu when event is assigned to other (#10643)
* fix: show assigned user information in actionMenu when event is assigned to other * test: add a story
1 parent 6a0cf65 commit b73f3bb

File tree

2 files changed

+144
-2
lines changed

2 files changed

+144
-2
lines changed

packages/client/src/v2-events/features/workqueues/EventOverview/components/ActionMenu.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import { getOrThrow } from '@opencrvs/commons/client'
2020
import { useEvents } from '@client/v2-events/features/events/useEvents/useEvents'
2121
import { messages } from '@client/i18n/messages/views/action'
2222
import { useAuthentication } from '@client/utils/userUtils'
23+
import { useUsers } from '@client/v2-events/hooks/useUsers'
24+
import { getUsersFullName } from '@client/v2-events/utils'
25+
import { useLocations } from '@client/v2-events/hooks/useLocations'
2326
import { useAllowedActionConfigurations } from './useAllowedActionConfigurations'
2427

2528
export function ActionMenu({
@@ -30,6 +33,10 @@ export function ActionMenu({
3033
onAction?: () => void
3134
}) {
3235
const intl = useIntl()
36+
37+
const { getUser } = useUsers()
38+
const { getLocations } = useLocations()
39+
const [locations] = getLocations.useSuspenseQuery()
3340
const { searchEventById } = useEvents()
3441

3542
const maybeAuth = useAuthentication()
@@ -45,15 +52,26 @@ export function ActionMenu({
4552
if (eventResults.total === 0) {
4653
throw new Error(`Event ${eventId} not found`)
4754
}
48-
const eventIndex = eventResults.results[0]
55+
const eventState = eventResults.results[0]
4956

50-
const eventState = eventIndex
57+
const assignedToUser = getUser.useQuery(eventState.assignedTo || '', {
58+
enabled: !!eventState.assignedTo
59+
}).data
60+
const assignedUserFullName = assignedToUser
61+
? getUsersFullName(assignedToUser.name, intl.locale)
62+
: ''
63+
const assignedOffice = assignedToUser?.primaryOfficeId || ''
64+
const assignedOfficeName =
65+
locations.find((l) => l.id === assignedOffice)?.name || ''
5166

5267
const [modal, actionMenuItems] = useAllowedActionConfigurations(
5368
eventState,
5469
auth
5570
)
5671

72+
const assignedToOther =
73+
eventState.assignedTo && eventState.assignedTo !== auth.sub
74+
5775
return (
5876
<>
5977
<DropdownMenu id="action">
@@ -66,6 +84,17 @@ export function ActionMenu({
6684
</PrimaryButton>
6785
</DropdownMenu.Trigger>
6886
<DropdownMenu.Content>
87+
{assignedToOther && (
88+
<>
89+
<DropdownMenu.Label>
90+
{intl.formatMessage(messages.assignedTo, {
91+
name: assignedUserFullName,
92+
officeName: assignedOfficeName
93+
})}
94+
</DropdownMenu.Label>
95+
<DropdownMenu.Separator />
96+
</>
97+
)}
6998
{actionMenuItems.map((action) => {
7099
return (
71100
<DropdownMenu.Item
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*
6+
* OpenCRVS is also distributed under the terms of the Civil Registration
7+
* & Healthcare Disclaimer located at http://opencrvs.org/license.
8+
*
9+
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
10+
*/
11+
12+
import { userEvent, screen } from '@storybook/test'
13+
import React from 'react'
14+
import { createTRPCMsw, httpLink } from '@vafanassieff/msw-trpc'
15+
import superjson from 'superjson'
16+
import { Meta, StoryObj } from '@storybook/react'
17+
import {
18+
ActionType,
19+
getCurrentEventState,
20+
tennisClubMembershipEvent
21+
} from '@opencrvs/commons/client'
22+
import { AppRouter } from '@client/v2-events/trpc'
23+
import { AssignmentStatus } from '@client/v2-events/utils'
24+
import { tennisClubMembershipEventDocument } from '@client/v2-events/features/events/fixtures'
25+
import {
26+
addLocalEventConfig,
27+
setEventData
28+
} from '@client/v2-events/features/events/useEvents/api'
29+
import { testDataGenerator } from '@client/tests/test-data-generators'
30+
import { ActionMenu } from '../ActionMenu'
31+
import { getMockEvent, UserRoles } from './ActionMenu.common'
32+
33+
const event = getMockEvent(
34+
[
35+
ActionType.CREATE,
36+
AssignmentStatus.ASSIGNED_TO_SELF,
37+
ActionType.DECLARE,
38+
ActionType.UNASSIGN,
39+
AssignmentStatus.ASSIGNED_TO_OTHERS
40+
],
41+
UserRoles.LOCAL_REGISTRAR
42+
)
43+
44+
const tRPCMsw = createTRPCMsw<AppRouter>({
45+
links: [
46+
httpLink({
47+
url: '/api/events'
48+
})
49+
],
50+
transformer: { input: superjson, output: superjson }
51+
})
52+
53+
const generator = testDataGenerator()
54+
55+
const meta: Meta<typeof ActionMenu> = {
56+
title: 'ActionMenu/Assignment',
57+
component: ActionMenu
58+
}
59+
export default meta
60+
61+
type Story = StoryObj<typeof meta>
62+
63+
export const AssignedTo: Story = {
64+
loaders: [
65+
async () => {
66+
window.localStorage.setItem(
67+
'opencrvs',
68+
generator.user.token.localRegistrar
69+
)
70+
71+
// Tests are generated dynamically, and it causes intermittent failures when global state
72+
// gets out of whack. This is a workaround to ensure that the state is reset
73+
await new Promise((resolve) => setTimeout(resolve, 50))
74+
75+
return {}
76+
}
77+
],
78+
parameters: {
79+
layout: 'centered',
80+
chromatic: { disableSnapshot: true },
81+
msw: {
82+
handlers: {
83+
event: [
84+
tRPCMsw.event.search.query(() => ({
85+
total: 1,
86+
results: [getCurrentEventState(event, tennisClubMembershipEvent)]
87+
})),
88+
tRPCMsw.event.get.query(() => {
89+
return tennisClubMembershipEventDocument
90+
})
91+
]
92+
}
93+
}
94+
},
95+
render: () => (
96+
<React.Suspense fallback={<span>{'Loading…'}</span>}>
97+
<ActionMenu eventId={event.id} />
98+
</React.Suspense>
99+
),
100+
beforeEach: () => {
101+
/*
102+
* Ensure record is "downloaded offline" in the user's browser
103+
*/
104+
addLocalEventConfig(tennisClubMembershipEvent)
105+
setEventData(event.id, event)
106+
},
107+
play: async () => {
108+
const actionButton = await screen.findByRole('button', {
109+
name: 'Action'
110+
})
111+
await userEvent.click(actionButton)
112+
}
113+
}

0 commit comments

Comments
 (0)