diff --git a/src/features/PassSurvey/hooks/useStartSurvey.ts b/src/features/PassSurvey/hooks/useStartSurvey.ts index be8747547..fbcb3cdc2 100644 --- a/src/features/PassSurvey/hooks/useStartSurvey.ts +++ b/src/features/PassSurvey/hooks/useStartSurvey.ts @@ -1,4 +1,4 @@ -import { ActivityStatus, EntityType } from '~/abstract/lib/GroupBuilder'; +import { EntityType } from '~/abstract/lib/GroupBuilder'; import { appletModel } from '~/entities/applet'; import { AppletBaseDTO } from '~/shared/api'; import ROUTES from '~/shared/constants/routes'; @@ -23,21 +23,19 @@ type OnActivityCardClickProps = { eventId: string; targetSubjectId: string | null; flowId: string | null; - status: ActivityStatus; shouldRestart: boolean; }; type Props = { - applet: AppletBaseDTO; + applet?: AppletBaseDTO; isPublic: boolean; publicAppletKey: string | null; }; export const useStartSurvey = (props: Props) => { const navigator = useCustomNavigation(); - - const appletId = props.applet.id; - const flows = props.applet.activityFlows; + const appletId = props.applet?.id; + const flows = props.applet?.activityFlows; const { removeGroupProgress } = appletModel.hooks.useGroupProgressStateManager(); @@ -47,6 +45,10 @@ export const useStartSurvey = (props: Props) => { appletModel.hooks.useMultiInformantState(); function navigateToEntity(params: NavigateToEntityProps) { + if (!appletId) { + return; + } + const { activityId, flowId, eventId, targetSubjectId, entityType } = params; if (props.isPublic && props.publicAppletKey) { @@ -82,7 +84,7 @@ export const useStartSurvey = (props: Props) => { shouldRestart, }: OnActivityCardClickProps) { const analyticsPayload: MixpanelPayload = { - [MixpanelProps.AppletId]: props.applet.id, + [MixpanelProps.AppletId]: appletId, [MixpanelProps.ActivityId]: activityId, }; @@ -102,7 +104,7 @@ export const useStartSurvey = (props: Props) => { Mixpanel.track(MixpanelEvents.AssessmentStarted, analyticsPayload); if (flowId) { - const flow = flows.find((x) => x.id === flowId); + const flow = flows?.find((x) => x.id === flowId); const firstActivityId: string | null = flow?.activityIds[0] ?? null; if (!firstActivityId) { diff --git a/src/widgets/ActivityGroups/model/hooks/useTakeNowRedirect.ts b/src/widgets/ActivityGroups/model/hooks/useTakeNowRedirect.ts new file mode 100644 index 000000000..bf3fe33eb --- /dev/null +++ b/src/widgets/ActivityGroups/model/hooks/useTakeNowRedirect.ts @@ -0,0 +1,80 @@ +import { useMemo } from 'react'; + +import { openStoreLink } from '~/abstract/lib'; +import { isSupportedActivity } from '~/entities/activity'; +import { useStartSurvey } from '~/features/PassSurvey'; +import { AppletBaseDTO, AppletEventsResponse, HydratedAssignmentDTO } from '~/shared/api'; + +export function useTakeNowRedirect({ + activityOrFlowId, + applet, + assignments = [], + events = [], + isPublic = false, + publicAppletKey = null, +}: { + activityOrFlowId?: string | null; + applet?: AppletBaseDTO; + assignments?: HydratedAssignmentDTO[] | null; + events?: AppletEventsResponse['events']; + isPublic?: boolean; + publicAppletKey?: string | null; +}) { + const { startSurvey } = useStartSurvey({ applet, isPublic, publicAppletKey }); + + const handleTakeNowRedirect = useMemo( + () => + ({ + activityId, + eventId, + flowId = null, + isSupported = true, + }: { + activityId: string; + eventId: string; + flowId?: string | null; + isSupported?: boolean; + }) => { + if (!isSupported) { + openStoreLink(); + return; + } + + startSurvey({ activityId, eventId, flowId, shouldRestart: true, targetSubjectId: null }); + }, + [startSurvey], + ); + + if (assignments && applet && events && activityOrFlowId) { + const activity = applet.activities.find(({ id }) => id === activityOrFlowId); + const flow = applet.activityFlows.find(({ id }) => id === activityOrFlowId); + const event = events.find(({ entityId }) => entityId === (activity?.id || flow?.id)); + + if (!event) { + return; + } + + if (activity) { + return handleTakeNowRedirect({ + activityId: activity.id, + isSupported: isSupportedActivity(activity.containsResponseTypes), + eventId: event.id, + }); + } + + if (flow) { + const flowActivities = flow.activityIds.map((activityId) => + applet.activities.find(({ id }) => activityId === id), + ); + + return handleTakeNowRedirect({ + activityId: flow.activityIds[0], + isSupported: flowActivities.every( + (activity) => !!activity && isSupportedActivity(activity.containsResponseTypes), + ), + eventId: event.id, + flowId: flow.id, + }); + } + } +} diff --git a/src/widgets/ActivityGroups/ui/ActivityCard/index.tsx b/src/widgets/ActivityGroups/ui/ActivityCard/index.tsx index b8222a4de..dc08c19f3 100644 --- a/src/widgets/ActivityGroups/ui/ActivityCard/index.tsx +++ b/src/widgets/ActivityGroups/ui/ActivityCard/index.tsx @@ -24,7 +24,6 @@ import { useAppSelector, useCustomMediaQuery, MixpanelPayload, - useOnceLayoutEffect, } from '~/shared/utils'; import { TargetSubjectLabel } from '~/widgets/TargetSubjectLabel'; @@ -107,7 +106,6 @@ export const ActivityCard = ({ activityListItem }: Props) => { activityId: activityListItem.activityId, eventId: activityListItem.eventId, targetSubjectId: activityListItem.targetSubject?.id ?? null, - status: activityListItem.status, flowId: activityListItem.flowId, shouldRestart, }); @@ -143,24 +141,6 @@ export const ActivityCard = ({ activityListItem }: Props) => { Mixpanel.track(MixpanelEvents.ActivityResumed, analyticsPayload); }; - // Start activity on mount if doing Take Now on this activity. - useOnceLayoutEffect(() => { - if ( - context.startActivityOrFlow && - // TODO: This `!activityListItem.targetSubject` check is added to ensure that Take Now is - // only triggered once, on the singular self-report instance of ActivityCard. However, this - // causes Take Now to fail when there is no self-report card, which is a possible scenario - // with the introduction of MI assignments. Remove this check when Take Now is refactored in - // https://mindlogger.atlassian.net/browse/M2-7796 - !activityListItem.targetSubject && - ((!isFlow && context.startActivityOrFlow === activityListItem.activityId) || - (isFlow && context.startActivityOrFlow === activityListItem.flowId)) - ) { - // Pass `true` to ensure activity doesn't resume from a previous progress state. - onStartActivity(true); - } - }); - return ( { + const { appletId, isPublic, publicAppletKey, startActivityOrFlow } = props; const { t } = useCustomTranslation(); const navigate = useNavigate(); const location = useLocation(); @@ -39,8 +43,7 @@ export const ActivityGroups = (props: Props) => { isOpen: false, }); const { featureFlag } = useFeatureFlags(); - const isAssignmentsEnabled = - featureFlag(FeatureFlag.EnableActivityAssign, false) && !props.isPublic; + const isAssignmentsEnabled = featureFlag(FeatureFlag.EnableActivityAssign, false) && !isPublic; const { isError: isAppletError, @@ -60,7 +63,7 @@ export const ActivityGroups = (props: Props) => { isError: isAssignmentsError, isLoading: isAssignmentsLoading, data: assignments = null, - } = useMyAssignmentsQuery(isAssignmentsEnabled ? props.appletId : undefined, { + } = useMyAssignmentsQuery(isAssignmentsEnabled ? appletId : undefined, { select: (data) => data.data.result.assignments, enabled: isAssignmentsEnabled, }); @@ -74,7 +77,8 @@ export const ActivityGroups = (props: Props) => { useOnceEffect(() => { ensureMultiInformantStateExists(); - if (isInMultiInformantFlow() && !props.startActivityOrFlow) { + + if (isInMultiInformantFlow() && !startActivityOrFlow) { resetMultiInformantState(); } @@ -92,6 +96,15 @@ export const ActivityGroups = (props: Props) => { } }); + useTakeNowRedirect({ + activityOrFlowId: startActivityOrFlow, + applet, + assignments, + events: events?.events, + isPublic, + publicAppletKey, + }); + if (isAppletLoading || isEventsLoading || (isAssignmentsEnabled && isAssignmentsLoading)) { return ; }