From 42565a7ca7027492601f43d196851a96d9371673 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sun, 28 Apr 2024 22:33:48 +0700 Subject: [PATCH 1/6] Fix cannot create task for new user via [] method --- src/libs/actions/Report.ts | 26 ++++++++++++++++++++++++++ src/pages/home/report/ReportFooter.tsx | 8 +++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 6fc51cd6b066..31b2dee5d2b6 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -8,6 +8,7 @@ import Onyx from 'react-native-onyx'; import type {PartialDeep, ValueOf} from 'type-fest'; import type {Emoji} from '@assets/emojis/types'; import type {FileObject} from '@components/AttachmentModal'; +import {FallbackAvatar} from '@components/Icon/Expensicons'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import * as API from '@libs/API'; import type { @@ -3714,6 +3715,30 @@ function setGroupDraft(newGroupDraft: Partial) { Onyx.merge(ONYXKEYS.NEW_GROUP_CHAT_DRAFT, newGroupDraft); } +function buildOptimisticTaskDataForNewAssingee(assigneeLogin: string) { + const assigneeAccountID = UserUtils.generateAccountID(assigneeLogin); + const report: OnyxEntry | undefined = ReportUtils.buildOptimisticChatReport([assigneeAccountID]); + report.isOptimisticReport = true; + + // When assigning a task to a new user, by default we share the task in their DM + // However, the DM doesn't exist yet - and will be created optimistically once the task is created + // We don't want to show the new DM yet, because if you select an assignee and then change the assignee, the previous DM will still be shown + // So here, we create it optimistically to share it with the assignee, but we have to hide it until the task is created + if (report) { + report.isHidden = true; + } + Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); + + const optimisticPersonalDetailsListAction = { + accountID: assigneeAccountID, + avatar: FallbackAvatar, + displayName: assigneeLogin, + login: assigneeLogin, + }; + Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneeAccountID]: optimisticPersonalDetailsListAction}); + return {assignee: optimisticPersonalDetailsListAction, assigneeReport: report}; +} + export { searchInServer, addComment, @@ -3797,4 +3822,5 @@ export { removeFromGroupChat, updateGroupChatMemberRoles, clearAddRoomMemberError, + buildOptimisticTaskDataForNewAssingee, }; diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 11d9a0a4871d..e69ba30df152 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -109,10 +109,16 @@ function ReportFooter({ const mentionWithDomain = ReportUtils.addDomainToShortMention(mention ?? '') ?? mention; let assignee: OnyxTypes.PersonalDetails | EmptyObject = {}; + let assigneeChatReport; if (mentionWithDomain) { assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? {}; + if (!Object.keys(assignee).length) { + const optimisticDataForNewAssignee = Report.buildOptimisticTaskDataForNewAssingee(mentionWithDomain); + assignee = optimisticDataForNewAssignee.assignee; + assigneeChatReport = optimisticDataForNewAssignee.assigneeReport; + } } - Task.createTaskAndNavigate(report.reportID, title, '', assignee?.login ?? '', assignee.accountID, undefined, report.policyID); + Task.createTaskAndNavigate(report.reportID, title, '', assignee?.login ?? '', assignee.accountID, assigneeChatReport, report.policyID); return true; }, [allPersonalDetails, report.policyID, report.reportID], From cd791c0852b9f27123e644adaab2a1f45fe5ef14 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 3 May 2024 11:10:50 +0700 Subject: [PATCH 2/6] use setTaskDataForNewAssingee in setAssignValue function --- src/libs/actions/Report.ts | 9 ++++----- src/libs/actions/Task.ts | 22 +--------------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index a1b54f372334..6792af2b14db 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -8,7 +8,6 @@ import Onyx from 'react-native-onyx'; import type {PartialDeep, ValueOf} from 'type-fest'; import type {Emoji} from '@assets/emojis/types'; import type {FileObject} from '@components/AttachmentModal'; -import {FallbackAvatar} from '@components/Icon/Expensicons'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import * as API from '@libs/API'; import type { @@ -3674,8 +3673,8 @@ function setGroupDraft(newGroupDraft: Partial) { Onyx.merge(ONYXKEYS.NEW_GROUP_CHAT_DRAFT, newGroupDraft); } -function setTaskDataForNewAssingee(assigneeLogin: string) { - const assigneeAccountID = UserUtils.generateAccountID(assigneeLogin); +function setTaskDataForNewAssingee(assigneeLogin: string, accountID: number | undefined = undefined) { + const assigneeAccountID = accountID ?? UserUtils.generateAccountID(assigneeLogin); const report: OnyxEntry | undefined = ReportUtils.buildOptimisticChatReport([assigneeAccountID]); report.isOptimisticReport = true; @@ -3690,8 +3689,8 @@ function setTaskDataForNewAssingee(assigneeLogin: string) { const optimisticPersonalDetailsListAction = { accountID: assigneeAccountID, - avatar: FallbackAvatar, - displayName: assigneeLogin, + avatar: allPersonalDetails?.[assigneeAccountID]?.avatar ?? UserUtils.getDefaultAvatarURL(assigneeAccountID), + displayName: allPersonalDetails?.[assigneeAccountID]?.displayName ?? assigneeLogin, login: assigneeLogin, }; Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneeAccountID]: optimisticPersonalDetailsListAction}); diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index fab1374ebea6..377e0b6deb79 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -14,7 +14,6 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; -import * as UserUtils from '@libs/UserUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -670,26 +669,7 @@ function setAssigneeValue( } // If chat report is still not found we need to build new optimistic chat report if (!report) { - report = ReportUtils.buildOptimisticChatReport([assigneeAccountID]); - report.isOptimisticReport = true; - - // When assigning a task to a new user, by default we share the task in their DM - // However, the DM doesn't exist yet - and will be created optimistically once the task is created - // We don't want to show the new DM yet, because if you select an assignee and then change the assignee, the previous DM will still be shown - // So here, we create it optimistically to share it with the assignee, but we have to hide it until the task is created - if (report) { - report.isHidden = true; - } - Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); - - // If this is an optimistic report, we likely don't have their personal details yet so we set it here optimistically as well - const optimisticPersonalDetailsListAction = { - accountID: assigneeAccountID, - avatar: allPersonalDetails?.[assigneeAccountID]?.avatar ?? UserUtils.getDefaultAvatarURL(assigneeAccountID), - displayName: allPersonalDetails?.[assigneeAccountID]?.displayName ?? assigneeEmail, - login: assigneeEmail, - }; - Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneeAccountID]: optimisticPersonalDetailsListAction}); + report = Report.setTaskDataForNewAssingee(assigneeEmail, assigneeAccountID).assigneeReport; } // The optimistic field may not exist in the existing report and it can be overridden by the optimistic field of previous report data when merging the assignee chat report From 44358c5491da5b1964f9ee7af173a5175a01e929 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 6 May 2024 12:30:27 +0700 Subject: [PATCH 3/6] move the function to Task.ts and refactor function --- src/libs/ReportUtils.ts | 1 + src/libs/actions/Report.ts | 25 ------------------------- src/libs/actions/Task.ts | 25 ++++++++++++++++++++++++- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 3451e14e388b..7da99d3ca8e6 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -293,6 +293,7 @@ type OptimisticChatReport = Pick< | 'writeCapability' | 'avatarUrl' | 'invoiceReceiver' + | 'isHidden' > & { isOptimisticReport: true; }; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 6792af2b14db..0172b137d8ca 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3673,30 +3673,6 @@ function setGroupDraft(newGroupDraft: Partial) { Onyx.merge(ONYXKEYS.NEW_GROUP_CHAT_DRAFT, newGroupDraft); } -function setTaskDataForNewAssingee(assigneeLogin: string, accountID: number | undefined = undefined) { - const assigneeAccountID = accountID ?? UserUtils.generateAccountID(assigneeLogin); - const report: OnyxEntry | undefined = ReportUtils.buildOptimisticChatReport([assigneeAccountID]); - report.isOptimisticReport = true; - - // When assigning a task to a new user, by default we share the task in their DM - // However, the DM doesn't exist yet - and will be created optimistically once the task is created - // We don't want to show the new DM yet, because if you select an assignee and then change the assignee, the previous DM will still be shown - // So here, we create it optimistically to share it with the assignee, but we have to hide it until the task is created - if (report) { - report.isHidden = true; - } - Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); - - const optimisticPersonalDetailsListAction = { - accountID: assigneeAccountID, - avatar: allPersonalDetails?.[assigneeAccountID]?.avatar ?? UserUtils.getDefaultAvatarURL(assigneeAccountID), - displayName: allPersonalDetails?.[assigneeAccountID]?.displayName ?? assigneeLogin, - login: assigneeLogin, - }; - Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneeAccountID]: optimisticPersonalDetailsListAction}); - return {assignee: optimisticPersonalDetailsListAction, assigneeReport: report}; -} - export { searchInServer, addComment, @@ -3777,6 +3753,5 @@ export { leaveGroupChat, removeFromGroupChat, updateGroupChatMemberRoles, - setTaskDataForNewAssingee, clearAvatarErrors, }; diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 377e0b6deb79..7456520e51f0 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -14,6 +14,7 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; +import * as UserUtils from '@libs/UserUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -649,6 +650,27 @@ function setAssigneeChatReport(chatReport: OnyxTypes.Report) { Onyx.merge(ONYXKEYS.TASK, {assigneeChatReport: chatReport}); } +function setOptimisticDataForNewAssingee(assigneeLogin: string, assigneeAccountID: number | undefined = undefined) { + const currentAssigneeAccountID = assigneeAccountID ?? UserUtils.generateAccountID(assigneeLogin); + const report: ReportUtils.OptimisticChatReport = ReportUtils.buildOptimisticChatReport([currentAssigneeAccountID]); + + // When assigning a task to a new user, by default we share the task in their DM + // However, the DM doesn't exist yet - and will be created optimistically once the task is created + // We don't want to show the new DM yet, because if you select an assignee and then change the assignee, the previous DM will still be shown + // So here, we create it optimistically to share it with the assignee, but we have to hide it until the task is created + report.isHidden = true; + Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); + + const optimisticPersonalDetailsListAction: OnyxTypes.PersonalDetails = { + accountID: currentAssigneeAccountID, + avatar: allPersonalDetails?.[currentAssigneeAccountID]?.avatar ?? UserUtils.getDefaultAvatarURL(currentAssigneeAccountID), + displayName: allPersonalDetails?.[currentAssigneeAccountID]?.displayName ?? assigneeLogin, + login: assigneeLogin, + }; + Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[currentAssigneeAccountID]: optimisticPersonalDetailsListAction}); + return {assignee: optimisticPersonalDetailsListAction, assigneeReport: report}; +} + /** * Sets the assignee value for the task and checks for an existing chat with the assignee * If there is no existing chat, it creates an optimistic chat report @@ -669,7 +691,7 @@ function setAssigneeValue( } // If chat report is still not found we need to build new optimistic chat report if (!report) { - report = Report.setTaskDataForNewAssingee(assigneeEmail, assigneeAccountID).assigneeReport; + report = setOptimisticDataForNewAssingee(assigneeEmail, assigneeAccountID).assigneeReport; } // The optimistic field may not exist in the existing report and it can be overridden by the optimistic field of previous report data when merging the assignee chat report @@ -1031,6 +1053,7 @@ export { getTaskAssigneeAccountID, clearTaskErrors, canModifyTask, + setOptimisticDataForNewAssingee, }; export type {PolicyValue, Assignee, ShareDestination}; From 9d27230d8457c0cb6d30d0f2e867409e94764616 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 6 May 2024 12:32:29 +0700 Subject: [PATCH 4/6] replace with new function --- src/pages/home/report/ReportFooter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 97e38b8935aa..8077d62a7f21 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -114,7 +114,7 @@ function ReportFooter({ if (mentionWithDomain) { assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? {}; if (!Object.keys(assignee).length) { - const optimisticDataForNewAssignee = Report.setTaskDataForNewAssingee(mentionWithDomain); + const optimisticDataForNewAssignee = Task.setOptimisticDataForNewAssingee(mentionWithDomain); assignee = optimisticDataForNewAssignee.assignee; assigneeChatReport = optimisticDataForNewAssignee.assigneeReport; } From 16282bd0ae3f62e7a81e8b2c0290f77fe3195ce3 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 6 May 2024 12:34:34 +0700 Subject: [PATCH 5/6] rename the function --- src/libs/actions/Task.ts | 6 +++--- src/pages/home/report/ReportFooter.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 7456520e51f0..e2eb504dd342 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -650,7 +650,7 @@ function setAssigneeChatReport(chatReport: OnyxTypes.Report) { Onyx.merge(ONYXKEYS.TASK, {assigneeChatReport: chatReport}); } -function setOptimisticDataForNewAssingee(assigneeLogin: string, assigneeAccountID: number | undefined = undefined) { +function setNewOptimisticAssignee(assigneeLogin: string, assigneeAccountID: number | undefined = undefined) { const currentAssigneeAccountID = assigneeAccountID ?? UserUtils.generateAccountID(assigneeLogin); const report: ReportUtils.OptimisticChatReport = ReportUtils.buildOptimisticChatReport([currentAssigneeAccountID]); @@ -691,7 +691,7 @@ function setAssigneeValue( } // If chat report is still not found we need to build new optimistic chat report if (!report) { - report = setOptimisticDataForNewAssingee(assigneeEmail, assigneeAccountID).assigneeReport; + report = setNewOptimisticAssignee(assigneeEmail, assigneeAccountID).assigneeReport; } // The optimistic field may not exist in the existing report and it can be overridden by the optimistic field of previous report data when merging the assignee chat report @@ -1053,7 +1053,7 @@ export { getTaskAssigneeAccountID, clearTaskErrors, canModifyTask, - setOptimisticDataForNewAssingee, + setNewOptimisticAssignee, }; export type {PolicyValue, Assignee, ShareDestination}; diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 8077d62a7f21..2d7c8142f9ac 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -114,7 +114,7 @@ function ReportFooter({ if (mentionWithDomain) { assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? {}; if (!Object.keys(assignee).length) { - const optimisticDataForNewAssignee = Task.setOptimisticDataForNewAssingee(mentionWithDomain); + const optimisticDataForNewAssignee = Task.setNewOptimisticAssignee(mentionWithDomain); assignee = optimisticDataForNewAssignee.assignee; assigneeChatReport = optimisticDataForNewAssignee.assigneeReport; } From 8620f6302f517e9d6416681ae2a0af65ff51e819 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 6 May 2024 16:01:20 +0700 Subject: [PATCH 6/6] change assigneeAccountID to require param --- src/libs/actions/Task.ts | 13 ++++++------- src/pages/home/report/ReportFooter.tsx | 4 +++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index e2eb504dd342..329119d688c9 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -650,9 +650,8 @@ function setAssigneeChatReport(chatReport: OnyxTypes.Report) { Onyx.merge(ONYXKEYS.TASK, {assigneeChatReport: chatReport}); } -function setNewOptimisticAssignee(assigneeLogin: string, assigneeAccountID: number | undefined = undefined) { - const currentAssigneeAccountID = assigneeAccountID ?? UserUtils.generateAccountID(assigneeLogin); - const report: ReportUtils.OptimisticChatReport = ReportUtils.buildOptimisticChatReport([currentAssigneeAccountID]); +function setNewOptimisticAssignee(assigneeLogin: string, assigneeAccountID: number) { + const report: ReportUtils.OptimisticChatReport = ReportUtils.buildOptimisticChatReport([assigneeAccountID]); // When assigning a task to a new user, by default we share the task in their DM // However, the DM doesn't exist yet - and will be created optimistically once the task is created @@ -662,12 +661,12 @@ function setNewOptimisticAssignee(assigneeLogin: string, assigneeAccountID: numb Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); const optimisticPersonalDetailsListAction: OnyxTypes.PersonalDetails = { - accountID: currentAssigneeAccountID, - avatar: allPersonalDetails?.[currentAssigneeAccountID]?.avatar ?? UserUtils.getDefaultAvatarURL(currentAssigneeAccountID), - displayName: allPersonalDetails?.[currentAssigneeAccountID]?.displayName ?? assigneeLogin, + accountID: assigneeAccountID, + avatar: allPersonalDetails?.[assigneeAccountID]?.avatar ?? UserUtils.getDefaultAvatarURL(assigneeAccountID), + displayName: allPersonalDetails?.[assigneeAccountID]?.displayName ?? assigneeLogin, login: assigneeLogin, }; - Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[currentAssigneeAccountID]: optimisticPersonalDetailsListAction}); + Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneeAccountID]: optimisticPersonalDetailsListAction}); return {assignee: optimisticPersonalDetailsListAction, assigneeReport: report}; } diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 2d7c8142f9ac..b128b83f88fc 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -12,6 +12,7 @@ import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as ReportUtils from '@libs/ReportUtils'; +import * as UserUtils from '@libs/UserUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import * as Task from '@userActions/Task'; @@ -114,7 +115,8 @@ function ReportFooter({ if (mentionWithDomain) { assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? {}; if (!Object.keys(assignee).length) { - const optimisticDataForNewAssignee = Task.setNewOptimisticAssignee(mentionWithDomain); + const assigneeAccountID = UserUtils.generateAccountID(mentionWithDomain); + const optimisticDataForNewAssignee = Task.setNewOptimisticAssignee(mentionWithDomain, assigneeAccountID); assignee = optimisticDataForNewAssignee.assignee; assigneeChatReport = optimisticDataForNewAssignee.assigneeReport; }