From b16d864a8d1bc1f458c188acebff8ef0f2b09977 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 18 Jun 2024 23:05:27 +0700 Subject: [PATCH 1/8] mark GRB on task at highest --- src/libs/ReportUtils.ts | 12 +++- src/libs/SidebarUtils.ts | 4 ++ src/libs/actions/Report.ts | 2 + src/libs/actions/Task.ts | 110 ++++++++++++++++++++++++++++++++++++- src/types/onyx/Report.ts | 3 + 5 files changed, 128 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a02b24c20e35..9af1c13bf5e0 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -335,6 +335,7 @@ type OptimisticTaskReport = Pick< | 'notificationPreference' | 'parentReportActionID' | 'lastVisibleActionCreated' + | 'hasParentAccess' >; type TransactionDetails = { @@ -2267,7 +2268,15 @@ function getLastVisibleMessage(reportID: string | undefined, actionsToMerge: Rep * @param [parentReportAction] - The parent report action of the report (Used to check if the task has been canceled) */ function isWaitingForAssigneeToCompleteTask(report: OnyxEntry, parentReportAction: OnyxEntry | EmptyObject = {}): boolean { - return isTaskReport(report) && isReportManager(report) && isOpenTaskReport(report, parentReportAction); + if (report?.hasOutstandingChildTask) { + return true; + } + + if (isOpenTaskReport(report, parentReportAction) && !report?.hasParentAccess && isReportManager(report)) { + return true; + } + + return false; } function isUnreadWithMention(reportOrOption: OnyxEntry | OptionData): boolean { @@ -5056,6 +5065,7 @@ function buildOptimisticTaskReport( statusNum: CONST.REPORT.STATUS_NUM.OPEN, notificationPreference, lastVisibleActionCreated: DateUtils.getDBTime(), + hasParentAccess: true, }; } diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index c96d3c511320..06daa2d34e01 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -246,6 +246,8 @@ function getOptionData({ searchText: undefined, isPinned: false, hasOutstandingChildRequest: false, + hasOutstandingChildTask: false, + hasParentAccess: undefined, isIOUReportOwner: null, isChatRoom: false, isArchivedRoom: false, @@ -307,6 +309,8 @@ function getOptionData({ result.isSelfDM = ReportUtils.isSelfDM(report); result.isOneOnOneChat = isOneOnOneChat; result.tooltipText = ReportUtils.getReportParticipantsTitle(visibleParticipantAccountIDs); + result.hasOutstandingChildTask = report.hasOutstandingChildTask; + result.hasParentAccess = report.hasParentAccess; const hasMultipleParticipants = participantPersonalDetailList.length > 1 || result.isChatRoom || result.isPolicyExpenseChat || ReportUtils.isExpenseReport(report); const subtitle = ReportUtils.getChatRoomSubtitle(report); diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 192c6f720b5f..cfa058eb4c64 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3238,6 +3238,7 @@ function completeOnboarding( managerID: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, isOptimisticReport: true, + managerID: currentUserAccountID, }, }, { @@ -3264,6 +3265,7 @@ function completeOnboarding( value: { stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.APPROVED, + managerID: currentUserAccountID, }, }); } diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 51fcbb53bc5f..2efb27d0d3f9 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -133,12 +133,14 @@ function createTaskAndNavigate( const currentTime = DateUtils.getDBTimeWithSkew(); const lastCommentText = ReportUtils.formatReportLastMessageText(optimisticAddCommentReport?.reportAction?.message?.[0]?.text ?? ''); + const parentReport = ReportUtils.getReport(parentReportID); const optimisticParentReport = { lastVisibleActionCreated: optimisticAddCommentReport.reportAction.created, lastMessageText: lastCommentText, lastActorAccountID: currentUserAccountID, lastReadTime: currentTime, lastMessageTranslationKey: '', + hasOutstandingChildTask: assigneeAccountID === currentUserAccountID ? true : parentReport?.hasOutstandingChildTask, }; // We're only setting onyx data for the task report here because it's possible for the parent report to not exist yet (if you're assigning a task to someone you haven't chatted with before) @@ -274,7 +276,14 @@ function createTaskAndNavigate( }, }); - clearOutTaskInfo(); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, + value: { + hasOutstandingChildTask: parentReport?.hasOutstandingChildTask, + }, + }), + clearOutTaskInfo(); const parameters: CreateTaskParams = { parentReportActionID: optimisticAddCommentReport.reportAction.reportActionID, @@ -296,6 +305,27 @@ function createTaskAndNavigate( Report.notifyNewAction(parentReportID, currentUserAccountID); } +/** + * @returns the object to update `report.hasOutstandingChildTask` + */ +function getOutstandingChildTask(taskReport: OnyxEntry) { + const parentReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${taskReport?.parentReportID}`] ?? {}; + return Object.values(parentReportActions).some((reportAction) => { + if (reportAction.childReportID === taskReport?.reportID) { + return false; + } + + if ( + reportAction.childType === CONST.REPORT.TYPE.TASK && + reportAction?.childStateNum === CONST.REPORT.STATE_NUM.OPEN && + reportAction?.childStatusNum === CONST.REPORT.STATUS_NUM.OPEN && + !reportAction?.message?.[0]?.isDeletedParentAction + ) { + return true; + } + }); +} + /** * Complete a task */ @@ -303,7 +333,7 @@ function completeTask(taskReport: OnyxEntry) { const taskReportID = taskReport?.reportID ?? '-1'; const message = `marked as complete`; const completedTaskReportAction = ReportUtils.buildOptimisticTaskReportAction(taskReportID, CONST.REPORT.ACTIONS.TYPE.TASK_COMPLETED, message); - + const parentReport = getParentReport(taskReport); const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -353,6 +383,24 @@ function completeTask(taskReport: OnyxEntry) { }, ]; + if (parentReport?.hasOutstandingChildTask) { + const hasOutstandingChildTask = getOutstandingChildTask(taskReport); + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${taskReport?.parentReportID}`, + value: { + hasOutstandingChildTask, + }, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${taskReport?.parentReportID}`, + value: { + hasOutstandingChildTask: parentReport?.hasOutstandingChildTask, + }, + }); + } + const parameters: CompleteTaskParams = { taskReportID, completedTaskReportActionID: completedTaskReportAction.reportActionID, @@ -370,6 +418,8 @@ function reopenTask(taskReport: OnyxEntry) { const taskReportID = taskReport?.reportID ?? '-1'; const message = `marked as incomplete`; const reopenedTaskReportAction = ReportUtils.buildOptimisticTaskReportAction(taskReportID, CONST.REPORT.ACTIONS.TYPE.TASK_REOPENED, message); + const parentReport = getParentReport(taskReport); + const hasOutstandingChildTask = taskReport?.managerID === currentUserAccountID ? true : parentReport?.hasOutstandingChildTask; const optimisticData: OnyxUpdate[] = [ { @@ -384,6 +434,13 @@ function reopenTask(taskReport: OnyxEntry) { lastReadTime: reopenedTaskReportAction.created, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${taskReport?.parentReportID}`, + value: { + hasOutstandingChildTask, + }, + }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${taskReportID}`, @@ -411,6 +468,13 @@ function reopenTask(taskReport: OnyxEntry) { statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${taskReport?.parentReportID}`, + value: { + hasOutstandingChildTask: taskReport?.hasOutstandingChildTask, + }, + }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${taskReportID}`, @@ -566,6 +630,39 @@ function editTaskAssignee(report: OnyxTypes.Report, ownerAccountID: number, assi }, ]; + if (currentUserAccountID === assigneeAccountID) { + const parentReport = getParentReport(report); + if (!isEmptyObject(parentReport)) { + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`, + value: {hasOutstandingChildTask: true}, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`, + value: {hasOutstandingChildTask: parentReport?.hasOutstandingChildTask}, + }); + } + } + + if (report.managerID === currentUserAccountID) { + const hasOutstandingChildTask = getOutstandingChildTask(report); + const parentReport = getParentReport(report); + if (!isEmptyObject(parentReport)) { + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`, + value: {hasOutstandingChildTask}, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`, + value: {hasOutstandingChildTask: parentReport?.hasOutstandingChildTask}, + }); + } + } + // If we make a change to the assignee, we want to add a comment to the assignee's chat // Check if the assignee actually changed if (assigneeAccountID && assigneeAccountID !== report.managerID && assigneeAccountID !== ownerAccountID && assigneeChatReport) { @@ -849,6 +946,7 @@ function deleteTask(report: OnyxEntry) { const optimisticReportActions = { [parentReportAction.reportActionID]: optimisticReportAction, }; + const hasOutstandingChildTask = getOutstandingChildTask(report); const optimisticData: OnyxUpdate[] = [ { @@ -867,6 +965,7 @@ function deleteTask(report: OnyxEntry) { value: { lastMessageText: ReportActionsUtils.getLastVisibleMessage(parentReport?.reportID ?? '-1', optimisticReportActions as OnyxTypes.ReportActions).lastMessageText ?? '', lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(parentReport?.reportID ?? '-1', optimisticReportActions as OnyxTypes.ReportActions)?.created, + hasOutstandingChildTask, }, }, { @@ -929,6 +1028,13 @@ function deleteTask(report: OnyxEntry) { statusNum: report.statusNum ?? '', } as OnyxTypes.Report, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport?.reportID}`, + value: { + hasOutstandingChildTask: parentReport?.hasOutstandingChildTask, + }, + }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index 9b0b35a6da7c..b5d0a0a15d13 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -77,6 +77,9 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback< /** Whether the report has a child that is an outstanding expense that is awaiting action from the current user */ hasOutstandingChildRequest?: boolean; + /** Whether the report has a child task that is awaiting action from the current user */ + hasOutstandingChildTask?: boolean; + /** List of icons for report participants */ icons?: OnyxCommon.Icon[]; From 6fdaf2dcd258b43567065c4e46be9a670d76edef Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 18 Jun 2024 23:21:24 +0700 Subject: [PATCH 2/8] address some lint errors --- src/libs/actions/Task.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 2efb27d0d3f9..6a7a34bf7ec1 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -275,15 +275,15 @@ function createTaskAndNavigate( }, }, }); - failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, value: { hasOutstandingChildTask: parentReport?.hasOutstandingChildTask, }, - }), - clearOutTaskInfo(); + }); + + clearOutTaskInfo(); const parameters: CreateTaskParams = { parentReportActionID: optimisticAddCommentReport.reportAction.reportActionID, @@ -323,6 +323,8 @@ function getOutstandingChildTask(taskReport: OnyxEntry) { ) { return true; } + + return false; }); } From 2aacaf36872261c413e37bfbf256a66653b51e5f Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 19 Jun 2024 00:04:10 +0700 Subject: [PATCH 3/8] force type to compare correctly --- src/libs/actions/Task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 6a7a34bf7ec1..35521945218a 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -311,7 +311,7 @@ function createTaskAndNavigate( function getOutstandingChildTask(taskReport: OnyxEntry) { const parentReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${taskReport?.parentReportID}`] ?? {}; return Object.values(parentReportActions).some((reportAction) => { - if (reportAction.childReportID === taskReport?.reportID) { + if (String(reportAction.childReportID) === String(taskReport?.reportID)) { return false; } From 142a46a03c99e5225e5aef6e9d3647099336825b Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Fri, 21 Jun 2024 14:48:09 +0700 Subject: [PATCH 4/8] solve lint error after merging main --- src/libs/actions/Task.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index d4280eb07109..d2635e483d9d 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -133,7 +133,7 @@ function createTaskAndNavigate( const currentTime = DateUtils.getDBTimeWithSkew(); const lastCommentText = ReportUtils.formatReportLastMessageText(optimisticAddCommentReport?.reportAction?.message?.[0]?.text ?? ''); - const parentReport = ReportUtils.getReport(parentReportID); + const parentReport = getReport(parentReportID); const optimisticParentReport = { lastVisibleActionCreated: optimisticAddCommentReport.reportAction.created, lastMessageText: lastCommentText, @@ -912,6 +912,13 @@ function getParentReport(report: OnyxEntry | EmptyObject): Ony return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? {}; } +/** + * Returns the report + */ +function getReport(reportID: string): OnyxEntry | EmptyObject { + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? {}; +} + /** * Cancels a task by setting the report state to SUBMITTED and status to CLOSED */ From f56f2e13c38963db06fbd27f64390c3a62be37aa Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Fri, 21 Jun 2024 15:07:49 +0700 Subject: [PATCH 5/8] chore --- src/libs/actions/Report.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 7edb0a6259a3..d842b1caca6b 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3225,6 +3225,8 @@ function completeOnboarding( description: taskDescription ?? '', })); + const hasOutstandingChildTask = tasksData.some((task) => !task.completedTaskReportAction); + const tasksForOptimisticData = tasksData.reduce((acc, {currentTask, taskCreatedAction, taskReportAction, taskDescription, completedTaskReportAction}) => { acc.push( { @@ -3359,6 +3361,7 @@ function completeOnboarding( key: `${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`, value: { lastMentionedTime: DateUtils.getDBTime(), + hasOutstandingChildTask, }, }, { @@ -3390,6 +3393,7 @@ function completeOnboarding( lastMessageTranslationKey: '', lastMessageText: '', lastVisibleActionCreated: '', + hasOutstandingChildTask: false, }; const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportActionsUtils.getLastVisibleMessage(targetChatReportID); if (lastMessageText || lastMessageTranslationKey) { From bdbd9c3e824c2f050b3c5d43eebb445d53a0dd77 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Sat, 22 Jun 2024 05:06:36 +0700 Subject: [PATCH 6/8] update after merging main --- src/libs/actions/Task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index cc2a6530cbb8..ebd00ee1f5e3 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -319,7 +319,7 @@ function getOutstandingChildTask(taskReport: OnyxEntry) { reportAction.childType === CONST.REPORT.TYPE.TASK && reportAction?.childStateNum === CONST.REPORT.STATE_NUM.OPEN && reportAction?.childStatusNum === CONST.REPORT.STATUS_NUM.OPEN && - !reportAction?.message?.[0]?.isDeletedParentAction + ReportActionsUtils.getReportActionMessage(reportAction)?.isDeletedParentAction ) { return true; } From 74a1400217de9e60c7b2fbf19cabf07830269a15 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 26 Jun 2024 22:29:26 +0700 Subject: [PATCH 7/8] handle conflict --- src/libs/actions/Task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index dcb4c19b8ed8..a42813fc185b 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -914,7 +914,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry | EmptyObject { +function getReport(reportID: string): OnyxEntry { return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? {}; } From 65c260ef8b7a295092097a90fd93487a1fa5afbc Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 26 Jun 2024 22:36:52 +0700 Subject: [PATCH 8/8] handle conflict --- src/libs/actions/Task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index a42813fc185b..81c9e98a5284 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -915,7 +915,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry { - return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? {}; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; } /**