From c70370b861603f46be53b4b83b566a9e75ee5f19 Mon Sep 17 00:00:00 2001 From: farmerpaul Date: Thu, 31 Oct 2024 20:04:41 -0300 Subject: [PATCH 1/2] fix: normalize self-report targetSubjectID In the web app, self-report assessments are identified and tracked using `targetSubjectId=null`. However, for past submissions, the BE returns the raw value of `targetSubjectId`, which is the subject ID of the respondent. These submissions needed to be normalized to have their `targetSubjectId` set to `null`, but to do so, needed to find out what the subject ID of the respondent (currently logged in user) is. So added a new `respondentMeta` property to the applet `base_info` endpoint on the BE, so that this value is now available to the FE to perform the needed equality comparison against `targetSubjectId`. --- .../lib/hooks/useTextVariablesReplacer.ts | 2 +- src/shared/api/types/applet.ts | 7 ++++- .../model/hooks/useEntitiesSync.ts | 26 +++++++++---------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/entities/activity/lib/hooks/useTextVariablesReplacer.ts b/src/entities/activity/lib/hooks/useTextVariablesReplacer.ts index 7059aa2e3..e0827c6f1 100644 --- a/src/entities/activity/lib/hooks/useTextVariablesReplacer.ts +++ b/src/entities/activity/lib/hooks/useTextVariablesReplacer.ts @@ -19,7 +19,7 @@ export const useTextVariablesReplacer = ({ }: Props) => { const replaceTextVariables = (text: string) => { if (items && answers) { - const nickname = respondentMeta?.nickname; + const nickname = respondentMeta?.nickname ?? ''; const replacer = new MarkdownVariableReplacer(items, answers, completedEntityTime, nickname); return replacer.process(text); diff --git a/src/shared/api/types/applet.ts b/src/shared/api/types/applet.ts index 90dda1d66..08401aa63 100644 --- a/src/shared/api/types/applet.ts +++ b/src/shared/api/types/applet.ts @@ -17,7 +17,11 @@ export type GetPublicAppletActivityByIdPayload = { activityId: string; }; -export type RespondentMetaDTO = { nickname: string }; +export type RespondentMetaDTO = { + subjectId: string | null; + nickname: string | null; + tag: string | null; +}; // API Responses - Success export type AppletListSuccessResponse = BaseSuccessListResponse; @@ -66,6 +70,7 @@ export type AppletBaseDTO = { activityFlows: Array; encryption: EncryptionDTO | null; integrations?: Integration[]; + respondentMeta?: RespondentMetaDTO; }; export type ActivityBaseDTO = { diff --git a/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts b/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts index a8ab2c511..6cc536da1 100644 --- a/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts +++ b/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts @@ -1,14 +1,17 @@ -import { useCallback, useEffect } from 'react'; +import { useCallback, useContext, useEffect } from 'react'; + +import { AppletDetailsContext } from '../../lib'; import { ActivityPipelineType } from '~/abstract/lib'; import { appletModel } from '~/entities/applet'; import { CompletedEntitiesDTO, CompletedEntityDTO } from '~/shared/api'; type FilterCompletedEntitiesProps = { - completedEntities: CompletedEntitiesDTO | undefined; + completedEntities?: CompletedEntitiesDTO; }; -export const useEntitiesSync = (props: FilterCompletedEntitiesProps) => { +export const useEntitiesSync = ({ completedEntities }: FilterCompletedEntitiesProps) => { + const { applet } = useContext(AppletDetailsContext); const { saveGroupProgress, getGroupProgress } = appletModel.hooks.useGroupProgressStateManager(); const syncEntity = useCallback( @@ -21,7 +24,9 @@ export const useEntitiesSync = (props: FilterCompletedEntitiesProps) => { const entityId = entity.id; const eventId = entity.scheduledEventId; - const targetSubjectId = entity.targetSubjectId; + // Normalize targetSubjectId to null for self-reports + const targetSubjectId = + entity.targetSubjectId === applet.respondentMeta?.subjectId ? null : entity.targetSubjectId; const groupProgress = getGroupProgress({ entityId, @@ -63,19 +68,14 @@ export const useEntitiesSync = (props: FilterCompletedEntitiesProps) => { }); } }, - [getGroupProgress, saveGroupProgress], + [applet.respondentMeta?.subjectId, getGroupProgress, saveGroupProgress], ); useEffect(() => { - if (!props.completedEntities) { + if (!completedEntities) { return; } - const completedEntities = [ - ...props.completedEntities.activities, - ...props.completedEntities.activityFlows, - ]; - - completedEntities.forEach(syncEntity); - }, [props.completedEntities, syncEntity]); + [...completedEntities.activities, ...completedEntities.activityFlows].forEach(syncEntity); + }, [completedEntities, syncEntity]); }; From 86b6d32d9dc1c08e82f274dd17a669f370658cdc Mon Sep 17 00:00:00 2001 From: farmerpaul Date: Tue, 5 Nov 2024 18:28:12 -0400 Subject: [PATCH 2/2] fix: use local time zone for existing submissions Depending on your time zone and the time of day, the date returned by the submissions endpoint could have been parsed incorrectly using the previous approach. As a result, previous same-day submissions were being interpreted as having occurred on the previous day and resulting in daily activities showing when they shouldn't be. Fixed this using a simpler and time zone-safe parsing method. --- .../ActivityGroups/model/hooks/useEntitiesSync.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts b/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts index 6cc536da1..b9469bd52 100644 --- a/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts +++ b/src/widgets/ActivityGroups/model/hooks/useEntitiesSync.ts @@ -16,11 +16,8 @@ export const useEntitiesSync = ({ completedEntities }: FilterCompletedEntitiesPr const syncEntity = useCallback( (entity: CompletedEntityDTO) => { - const hoursMinutes = entity.localEndTime.split(':'); - const endAtDate = new Date(entity.localEndDate).setHours( - Number(hoursMinutes[0]), - Number(hoursMinutes[1]), - ); + const endAtDate = new Date(`${entity.localEndDate}T${entity.localEndTime}`); + const endAtTimestamp = endAtDate.getTime(); const entityId = entity.id; const eventId = entity.scheduledEventId; @@ -42,7 +39,7 @@ export const useEntitiesSync = ({ completedEntities }: FilterCompletedEntitiesPr progressPayload: { type: ActivityPipelineType.Regular, startAt: null, - endAt: new Date(endAtDate).getTime(), + endAt: endAtTimestamp, context: { summaryData: {}, }, @@ -51,7 +48,7 @@ export const useEntitiesSync = ({ completedEntities }: FilterCompletedEntitiesPr } if (groupProgress.endAt) { - const isServerEndAtBigger = endAtDate > new Date(groupProgress.endAt).getTime(); + const isServerEndAtBigger = endAtTimestamp > new Date(groupProgress.endAt).getTime(); if (!isServerEndAtBigger) { return; @@ -63,7 +60,7 @@ export const useEntitiesSync = ({ completedEntities }: FilterCompletedEntitiesPr targetSubjectId, progressPayload: { ...groupProgress, - endAt: new Date(endAtDate).getTime(), + endAt: endAtTimestamp, }, }); }