diff --git a/src/abstract/lib/types/multiInformant.ts b/src/abstract/lib/types/multiInformant.ts index fe85157d5..8d0db46fb 100644 --- a/src/abstract/lib/types/multiInformant.ts +++ b/src/abstract/lib/types/multiInformant.ts @@ -1,4 +1,10 @@ +export type MultiInformantSubject = { + id: string; + secretId: string | null; + nickname: string | null; +}; + export type MultiInformantState = { - sourceSubjectId?: string; - targetSubjectId?: string; + sourceSubject?: MultiInformantSubject; + targetSubject?: MultiInformantSubject; }; diff --git a/src/entities/applet/model/hooks/useMultiInformantState.ts b/src/entities/applet/model/hooks/useMultiInformantState.ts index 24b340add..d1a52b998 100644 --- a/src/entities/applet/model/hooks/useMultiInformantState.ts +++ b/src/entities/applet/model/hooks/useMultiInformantState.ts @@ -21,7 +21,7 @@ export const useMultiInformantState = (): Return => { const getMultiInformantState = useCallback(() => multiInformantState, [multiInformantState]); const isInMultiInformantFlow = useCallback(() => { - return !!multiInformantState.sourceSubjectId && !!multiInformantState.targetSubjectId; + return !!multiInformantState.sourceSubject?.id && !!multiInformantState.targetSubject?.id; }, [multiInformantState]); const initiateTakeNow = useCallback( diff --git a/src/entities/applet/model/types.ts b/src/entities/applet/model/types.ts index 25ecfee2b..6f2136d06 100644 --- a/src/entities/applet/model/types.ts +++ b/src/entities/applet/model/types.ts @@ -1,4 +1,5 @@ import { GroupProgress } from '~/abstract/lib'; +import { MultiInformantState } from '~/abstract/lib/types/multiInformant'; import { Answer, AudioPlayerItem, @@ -174,7 +175,4 @@ export type InProgressFlow = { pipelineActivityOrder: number; }; -export type MultiInformantPayload = { - sourceSubjectId: string; - targetSubjectId: string; -}; +export type MultiInformantPayload = Required; diff --git a/src/features/TakeNow/lib/useTakeNowValidation.tsx b/src/features/TakeNow/lib/useTakeNowValidation.tsx index ce8040a75..8fb08ea89 100644 --- a/src/features/TakeNow/lib/useTakeNowValidation.tsx +++ b/src/features/TakeNow/lib/useTakeNowValidation.tsx @@ -121,6 +121,9 @@ export const useTakeNowValidation = ({ return errorState(t('takeNow.invalidSubject')); } + const { nickname: targetSubjectNickname, secretUserId: targetSecretUserId } = + subjectData.data.result; + if (isActivityError) { return errorState(t('takeNow.invalidActivity')); } @@ -161,15 +164,27 @@ export const useTakeNowValidation = ({ return errorState(null); } - const { subjectId: sourceSubjectId } = respondentData.data.result; + const { + subjectId: sourceSubjectId, + nickname: sourceSubjectNickname, + secretUserId: sourceSecretUserId, + } = respondentData.data.result; return { isLoading: false, isError: false, isSuccess: true, data: { - sourceSubjectId, - targetSubjectId, + sourceSubject: { + id: sourceSubjectId, + nickname: sourceSubjectNickname, + secretId: sourceSecretUserId, + }, + targetSubject: { + id: targetSubjectId, + nickname: targetSubjectNickname, + secretId: targetSecretUserId, + }, }, }; }; diff --git a/src/features/TakeNow/ui/MultiInformantBadge.tsx b/src/features/TakeNow/ui/MultiInformantBadge.tsx new file mode 100644 index 000000000..cc3b2da6a --- /dev/null +++ b/src/features/TakeNow/ui/MultiInformantBadge.tsx @@ -0,0 +1,37 @@ +import { useMultiInformantState } from '~/entities/applet/model/hooks'; +import { MultiInformantBadgeTile } from '~/features/TakeNow/ui/MultiInformantBadgeTile'; +import { Theme } from '~/shared/constants'; +import { Box } from '~/shared/ui'; +import { useLaunchDarkly } from '~/shared/utils/hooks/useLaunchDarkly'; + +const borderSize = 1; + +export const MultiInformantBadge = () => { + const { getMultiInformantState, isInMultiInformantFlow } = useMultiInformantState(); + const { flags: featureFlags } = useLaunchDarkly(); + + if (!isInMultiInformantFlow() || !featureFlags.enableMultiInformant) { + return null; + } + + const { sourceSubject, targetSubject } = getMultiInformantState(); + + if (!sourceSubject || !targetSubject) { + return null; + } + + return ( + + + + + ); +}; diff --git a/src/features/TakeNow/ui/MultiInformantBadgeTile.tsx b/src/features/TakeNow/ui/MultiInformantBadgeTile.tsx new file mode 100644 index 000000000..172e9c069 --- /dev/null +++ b/src/features/TakeNow/ui/MultiInformantBadgeTile.tsx @@ -0,0 +1,55 @@ +import Tooltip from '@mui/material/Tooltip'; + +import { MultiInformantSubject } from '~/abstract/lib/types/multiInformant'; +import { Theme } from '~/shared/constants'; +import { Box } from '~/shared/ui'; + +type MultiInformantBadgeTileProps = { + type: 'Subject' | 'Respondent'; + subject: MultiInformantSubject; +}; + +export const MultiInformantBadgeTile = ({ subject, type }: MultiInformantBadgeTileProps) => { + const { id, secretId, nickname } = subject; + let text = secretId ?? id; + if (nickname) { + text += `, ${nickname}`; + } + + const tooltipText = `${type}: ${text}`; + + const backgroundColor = type === 'Subject' ? Theme.colors.light.inverseOnSurface : 'transparent'; + + return ( + + +

+ {text} +

+
+
+ ); +}; diff --git a/src/features/TakeNow/ui/ValidateTakeNowParams.tsx b/src/features/TakeNow/ui/ValidateTakeNowParams.tsx index e41d1f5ff..9a959c4a1 100644 --- a/src/features/TakeNow/ui/ValidateTakeNowParams.tsx +++ b/src/features/TakeNow/ui/ValidateTakeNowParams.tsx @@ -26,15 +26,15 @@ function ValidateTakeNowParams({ useEffect(() => { if (isSuccess && data) { - const { sourceSubjectId, targetSubjectId } = data; + const { sourceSubject, targetSubject } = data; const multiInformantState = getMultiInformantState(); if ( !isInMultiInformantFlow() || - sourceSubjectId !== multiInformantState.sourceSubjectId || - targetSubjectId !== multiInformantState.targetSubjectId + sourceSubject.id !== multiInformantState.sourceSubject?.id || + targetSubject.id !== multiInformantState.targetSubject?.id ) { - initiateTakeNow({ sourceSubjectId, targetSubjectId }); + initiateTakeNow({ sourceSubject, targetSubject }); } } }, [data, initiateTakeNow, isInMultiInformantFlow, isSuccess]); diff --git a/src/features/TakeNow/ui/index.ts b/src/features/TakeNow/ui/index.ts index 1e2d4a03a..29bfbde01 100644 --- a/src/features/TakeNow/ui/index.ts +++ b/src/features/TakeNow/ui/index.ts @@ -1 +1,3 @@ export * from './ValidateTakeNowParams'; +export * from './MultiInformantBadge'; +export * from './MultiInformantBadgeTile'; diff --git a/src/widgets/ActivityDetails/model/hooks/useAnswers.ts b/src/widgets/ActivityDetails/model/hooks/useAnswers.ts index 0ea38fae8..e0d6b9067 100644 --- a/src/widgets/ActivityDetails/model/hooks/useAnswers.ts +++ b/src/widgets/ActivityDetails/model/hooks/useAnswers.ts @@ -142,8 +142,8 @@ export const useAnswer = (props: Props) => { if (featureFlags.enableMultiInformant) { const multiInformantState = getMultiInformantState(); if (isInMultiInformantFlow()) { - answer.sourceSubjectId = multiInformantState.sourceSubjectId; - answer.targetSubjectId = multiInformantState.targetSubjectId; + answer.sourceSubjectId = multiInformantState.sourceSubject?.id; + answer.targetSubjectId = multiInformantState.targetSubject?.id; } } diff --git a/src/widgets/ActivityDetails/ui/AssessmentLayoutHeader.tsx b/src/widgets/ActivityDetails/ui/AssessmentLayoutHeader.tsx index 3afc6ce0e..83a02eed7 100644 --- a/src/widgets/ActivityDetails/ui/AssessmentLayoutHeader.tsx +++ b/src/widgets/ActivityDetails/ui/AssessmentLayoutHeader.tsx @@ -1,7 +1,7 @@ import { SaveAndExitButton } from '~/features/SaveAssessmentAndExit'; +import { MultiInformantBadge } from '~/features/TakeNow'; import { ROUTES, Theme } from '~/shared/constants'; -import { Box } from '~/shared/ui'; -import { BaseProgressBar, Text } from '~/shared/ui'; +import { BaseProgressBar, Box, Text } from '~/shared/ui'; import { useCustomMediaQuery, useCustomNavigation } from '~/shared/utils'; type Props = { @@ -40,12 +40,15 @@ export const AssessmentLayoutHeader = (props: Props) => { justifyContent="center" gridTemplateColumns="1fr minmax(300px, 900px) 1fr" padding={greaterThanSM ? '19px 24px' : '15px 16px'} + height={87} gap={1.5} sx={{ backgroundColor: Theme.colors.light.surface, borderBottom: `1px solid ${Theme.colors.light.surfaceVariant}`, }} > + +