diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index e8ef18a3ca27..ad2b38707c7d 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -2352,6 +2352,7 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, iouRep if ( !report || !report.reportID || + report.isHidden || (_.isEmpty(report.participantAccountIDs) && !isChatThread(report) && !isPublicRoom(report) && !isArchivedRoom(report) && !isMoneyRequestReport(report) && !isTaskReport(report)) ) { return false; @@ -2903,6 +2904,123 @@ function shouldDisableRename(report, policy) { return !_.keys(loginList).includes(policy.owner) && policy.role !== CONST.POLICY.ROLE.ADMIN; } +/** + * Returns the onyx data needed for the task assignee chat + * @param {Number} accountID + * @param {String} assigneeEmail + * @param {Number} assigneeAccountID + * @param {String} taskReportID + * @param {String} assigneeChatReportID + * @param {String} parentReportID + * @param {String} title + * @param {Object} assigneeChatReport + * @returns {Object} + */ +function getTaskAssigneeChatOnyxData(accountID, assigneeEmail, assigneeAccountID, taskReportID, assigneeChatReportID, parentReportID, title, assigneeChatReport) { + // Set if we need to add a comment to the assignee chat notifying them that they have been assigned a task + let optimisticAssigneeAddComment; + // Set if this is a new chat that needs to be created for the assignee + let optimisticChatCreatedReportAction; + const currentTime = DateUtils.getDBTime(); + const optimisticData = []; + const successData = []; + const failureData = []; + + // You're able to assign a task to someone you haven't chatted with before - so we need to optimistically create the chat and the chat reportActions + // Only add the assignee chat report to onyx if we haven't already set it optimistically + if (assigneeChatReport.isOptimisticReport && lodashGet(assigneeChatReport, 'pendingFields.createChat') !== CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { + optimisticChatCreatedReportAction = buildOptimisticCreatedReportAction(assigneeChatReportID); + optimisticData.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${assigneeChatReportID}`, + value: { + pendingFields: { + createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + isHidden: false, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, + value: {[optimisticChatCreatedReportAction.reportActionID]: optimisticChatCreatedReportAction}, + }, + ); + + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${assigneeChatReportID}`, + value: { + pendingFields: { + createChat: null, + }, + isOptimisticReport: false, + }, + }); + + failureData.push( + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${assigneeChatReportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, + value: {[optimisticChatCreatedReportAction.reportActionID]: {pendingAction: null}}, + }, + // If we failed, we want to remove the optimistic personal details as it was likely due to an invalid login + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: { + [assigneeAccountID]: null, + }, + }, + ); + } + + // If you're choosing to share the task in the same DM as the assignee then we don't need to create another reportAction indicating that you've been assigned + if (assigneeChatReportID !== parentReportID) { + optimisticAssigneeAddComment = buildOptimisticTaskCommentReportAction(taskReportID, title, assigneeEmail, assigneeAccountID, `Assigned a task to you: ${title}`, parentReportID); + + const lastAssigneeCommentText = formatReportLastMessageText(optimisticAssigneeAddComment.reportAction.message[0].text); + const optimisticAssigneeReport = { + lastVisibleActionCreated: currentTime, + lastMessageText: lastAssigneeCommentText, + lastActorAccountID: accountID, + lastReadTime: currentTime, + }; + + optimisticData.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, + value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: optimisticAssigneeAddComment.reportAction}, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${assigneeChatReportID}`, + value: optimisticAssigneeReport, + }, + ); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, + value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: {pendingAction: null}}, + }); + } + + return { + optimisticData, + successData, + failureData, + optimisticAssigneeAddComment, + optimisticChatCreatedReportAction, + }; +} + export { getReportParticipantsTitle, isReportMessageAttachment, @@ -3024,4 +3142,5 @@ export { shouldDisableSettings, shouldDisableRename, hasSingleParticipant, + getTaskAssigneeChatOnyxData, }; diff --git a/src/libs/actions/Task.js b/src/libs/actions/Task.js index eeef8f479d97..6227686b3f45 100644 --- a/src/libs/actions/Task.js +++ b/src/libs/actions/Task.js @@ -4,7 +4,6 @@ import _ from 'underscore'; import ONYXKEYS from '../../ONYXKEYS'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; -import * as Report from './Report'; import Navigation from '../Navigation/Navigation'; import ROUTES from '../../ROUTES'; import CONST from '../../CONST'; @@ -25,6 +24,12 @@ Onyx.connect({ }, }); +let allPersonalDetails; +Onyx.connect({ + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + callback: (val) => (allPersonalDetails = val), +}); + /** * Clears out the task info from the store */ @@ -33,47 +38,42 @@ function clearOutTaskInfo() { } /** - * Assign a task to a user - * Function title is createTask for consistency with the rest of the actions - * and also because we can create a task without assigning it to anyone + * A task needs two things to be created - a title and a parent report + * When you create a task report, there are a few things that happen: + * A task report is created, along with a CreatedReportAction for that new task report + * A reportAction indicating that a task was created is added to the parent report (share destination) + * If you assign the task to someone, a reportAction is created in the chat between you and the assignee to inform them of the task + * + * So you have the following optimistic items potentially being created: + * 1. The task report + * 1a. The CreatedReportAction for the task report + * 2. The TaskReportAction on the parent report + * 3. The chat report between you and the assignee + * 3a. The CreatedReportAction for the assignee chat report + * 3b. The TaskReportAction on the assignee chat report + * * @param {String} parentReportID * @param {String} title * @param {String} description - * @param {String} assignee + * @param {String} assigneeEmail * @param {Number} assigneeAccountID - * + * @param {Object} assigneeChatReport - The chat report between you and the assignee */ - -function createTaskAndNavigate(parentReportID, title, description, assignee, assigneeAccountID = 0) { - // Create the task report +function createTaskAndNavigate(parentReportID, title, description, assigneeEmail, assigneeAccountID = 0, assigneeChatReport = null) { const optimisticTaskReport = ReportUtils.buildOptimisticTaskReport(currentUserAccountID, assigneeAccountID, parentReportID, title, description); - // Grab the assigneeChatReportID if there is an assignee and if it's not the same as the parentReportID - // then we create an optimistic add comment report action on the assignee's chat to notify them of the task - const assigneeChatReportID = lodashGet(ReportUtils.getChatByParticipants([assigneeAccountID]), 'reportID'); + const assigneeChatReportID = assigneeChatReport ? assigneeChatReport.reportID : 0; const taskReportID = optimisticTaskReport.reportID; - let optimisticAssigneeAddComment; - if (assigneeChatReportID && assigneeChatReportID !== parentReportID) { - optimisticAssigneeAddComment = ReportUtils.buildOptimisticTaskCommentReportAction( - taskReportID, - title, - assignee, - assigneeAccountID, - `Assigned a task to you: ${title}`, - parentReportID, - ); - } + let assigneeChatReportOnyxData; - // Create the CreatedReportAction on the task + // Parent ReportAction indicating that a task has been created const optimisticTaskCreatedAction = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); - const optimisticAddCommentReport = ReportUtils.buildOptimisticTaskCommentReportAction(taskReportID, title, assignee, assigneeAccountID, `Created a task: ${title}`, parentReportID); + const optimisticAddCommentReport = ReportUtils.buildOptimisticTaskCommentReportAction(taskReportID, title, assigneeEmail, assigneeAccountID, `Created a task: ${title}`, parentReportID); optimisticTaskReport.parentReportActionID = optimisticAddCommentReport.reportAction.reportActionID; const currentTime = DateUtils.getDBTime(); - const lastCommentText = ReportUtils.formatReportLastMessageText(optimisticAddCommentReport.reportAction.message[0].text); - - const optimisticReport = { + const optimisticParentReport = { lastVisibleActionCreated: currentTime, lastMessageText: lastCommentText, lastActorAccountID: currentUserAccountID, @@ -81,6 +81,9 @@ function createTaskAndNavigate(parentReportID, title, description, assignee, ass lastMessageTranslationKey: '', }; + // 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) + // So we don't want to set the parent report data until we've successfully created that chat report + // FOR TASK REPORT const optimisticData = [ { onyxMethod: Onyx.METHOD.SET, @@ -101,18 +104,9 @@ function createTaskAndNavigate(parentReportID, title, description, assignee, ass key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTaskReport.reportID}`, value: {[optimisticTaskCreatedAction.reportActionID]: optimisticTaskCreatedAction}, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, - value: {[optimisticAddCommentReport.reportAction.reportActionID]: optimisticAddCommentReport.reportAction}, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, - value: optimisticReport, - }, ]; + // FOR TASK REPORT const successData = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -132,13 +126,9 @@ function createTaskAndNavigate(parentReportID, title, description, assignee, ass key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTaskReport.reportID}`, value: {[optimisticTaskCreatedAction.reportActionID]: {pendingAction: null}}, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, - value: {[optimisticAddCommentReport.reportAction.reportActionID]: {pendingAction: null}}, - }, ]; + // FOR TASK REPORT const failureData = [ { onyxMethod: Onyx.METHOD.SET, @@ -150,48 +140,52 @@ function createTaskAndNavigate(parentReportID, title, description, assignee, ass key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTaskReport.reportID}`, value: {[optimisticTaskCreatedAction.reportActionID]: {pendingAction: null}}, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, - value: {[optimisticAddCommentReport.reportAction.reportActionID]: {pendingAction: null}}, - }, ]; - if (optimisticAssigneeAddComment) { - const lastAssigneeCommentText = ReportUtils.formatReportLastMessageText(optimisticAssigneeAddComment.reportAction.message[0].text); - - const optimisticAssigneeReport = { - lastVisibleActionCreated: currentTime, - lastMessageText: lastAssigneeCommentText, - lastActorAccountID: currentUserAccountID, - lastReadTime: currentTime, - }; - - optimisticData.push( - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, - value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: optimisticAssigneeAddComment.reportAction}, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${assigneeChatReportID}`, - value: optimisticAssigneeReport, - }, + if (assigneeChatReport) { + assigneeChatReportOnyxData = ReportUtils.getTaskAssigneeChatOnyxData( + currentUserAccountID, + assigneeEmail, + assigneeAccountID, + taskReportID, + assigneeChatReportID, + parentReportID, + title, + assigneeChatReport, ); + optimisticData.push(...assigneeChatReportOnyxData.optimisticData); + successData.push(...assigneeChatReportOnyxData.successData); + failureData.push(...assigneeChatReportOnyxData.failureData); + } - successData.push({ + // Now that we've created the optimistic chat report and chat reportActions, we can update the parent report data + // FOR PARENT REPORT (SHARE DESTINATION) + optimisticData.push( + { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, - value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: {pendingAction: null}}, - }); - - failureData.push({ + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, + value: optimisticParentReport, + }, + { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, - value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: {pendingAction: null}}, - }); - } + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, + value: {[optimisticAddCommentReport.reportAction.reportActionID]: optimisticAddCommentReport.reportAction}, + }, + ); + + // FOR PARENT REPORT (SHARE DESTINATION) + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, + value: {[optimisticAddCommentReport.reportAction.reportActionID]: {pendingAction: null}}, + }); + + // FOR PARENT REPORT (SHARE DESTINATION) + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, + value: {[optimisticAddCommentReport.reportAction.reportActionID]: {pendingAction: null}}, + }); API.write( 'CreateTask', @@ -200,13 +194,17 @@ function createTaskAndNavigate(parentReportID, title, description, assignee, ass parentReportID, taskReportID: optimisticTaskReport.reportID, createdTaskReportActionID: optimisticTaskCreatedAction.reportActionID, - reportName: optimisticTaskReport.reportName, title: optimisticTaskReport.reportName, description: optimisticTaskReport.description, - assignee, + assignee: assigneeEmail, assigneeAccountID, assigneeChatReportID, - assigneeChatReportActionID: optimisticAssigneeAddComment ? optimisticAssigneeAddComment.reportAction.reportActionID : 0, + assigneeChatReportActionID: + assigneeChatReportOnyxData && assigneeChatReportOnyxData.optimisticAssigneeAddComment + ? assigneeChatReportOnyxData.optimisticAssigneeAddComment.reportAction.reportActionID + : 0, + assigneeChatCreatedReportActionID: + assigneeChatReportOnyxData && assigneeChatReportOnyxData.optimisticChatCreatedReportAction ? assigneeChatReportOnyxData.optimisticChatCreatedReportAction.reportActionID : 0, }, {optimisticData, successData, failureData}, ); @@ -401,12 +399,9 @@ function reopenTask(taskReport, taskTitle) { * @param {object} report * @param {Number} ownerAccountID * @param {Object} editedTask - * @param {String} editedTask.title - * @param {String} editedTask.description - * @param {String} editedTask.assignee - * @param {Number} editedTask.assigneeAccountID + * @param {Object} assigneeChatReport - The chat report between you and the assignee */ -function editTaskAndNavigate(report, ownerAccountID, {title, description, assignee = '', assigneeAccountID = 0}) { +function editTaskAndNavigate(report, ownerAccountID, {title, description, assignee = '', assigneeAccountID = 0}, assigneeChatReport = null) { // Create the EditedReportAction on the task const editTaskReportAction = ReportUtils.buildOptimisticEditedTaskReportAction(currentUserEmail); @@ -416,22 +411,8 @@ function editTaskAndNavigate(report, ownerAccountID, {title, description, assign // Description can be unset, so we default to an empty string if so const reportDescription = (!_.isUndefined(description) ? description : lodashGet(report, 'description', '')).trim(); - // If we make a change to the assignee, we want to add a comment to the assignee's chat - let optimisticAssigneeAddComment; - let assigneeChatReportID; - if (assigneeAccountID && assigneeAccountID !== report.managerID && assigneeAccountID !== ownerAccountID) { - assigneeChatReportID = lodashGet(ReportUtils.getChatByParticipants([assigneeAccountID]), ['reportID'], undefined); - - if (assigneeChatReportID && assigneeChatReportID !== report.parentReportID.toString()) { - optimisticAssigneeAddComment = ReportUtils.buildOptimisticTaskCommentReportAction( - report.reportID, - reportName, - assignee, - assigneeAccountID, - `Assigned a task to you: ${reportName}`, - ); - } - } + let assigneeChatReportOnyxData; + const assigneeChatReportID = assigneeChatReport ? assigneeChatReport.reportID : 0; const optimisticData = [ { @@ -486,35 +467,22 @@ function editTaskAndNavigate(report, ownerAccountID, {title, description, assign }, ]; - if (optimisticAssigneeAddComment) { - const currentTime = DateUtils.getDBTime(); - const lastAssigneeCommentText = ReportUtils.formatReportLastMessageText(optimisticAssigneeAddComment.reportAction.message[0].text); - - const optimisticAssigneeReport = { - lastVisibleActionCreated: currentTime, - lastMessageText: lastAssigneeCommentText, - lastActorAccountID: ownerAccountID, - lastReadTime: currentTime, - }; - - optimisticData.push( - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, - value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: optimisticAssigneeAddComment.reportAction}, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${assigneeChatReportID}`, - value: optimisticAssigneeReport, - }, + // 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) { + assigneeChatReportOnyxData = ReportUtils.getTaskAssigneeChatOnyxData( + currentUserAccountID, + assignee, + assigneeAccountID, + report.reportID, + assigneeChatReportID, + report.parentReportID, + reportName, + assigneeChatReport, ); - - failureData.push({ - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${assigneeChatReportID}`, - value: {[optimisticAssigneeAddComment.reportAction.reportActionID]: {pendingAction: null}}, - }); + optimisticData.push(...assigneeChatReportOnyxData.optimisticData); + successData.push(...assigneeChatReportOnyxData.successData); + failureData.push(...assigneeChatReportOnyxData.failureData); } API.write( @@ -526,7 +494,90 @@ function editTaskAndNavigate(report, ownerAccountID, {title, description, assign assignee: assignee || report.managerEmail, assigneeAccountID: assigneeAccountID || report.managerID, editedTaskReportActionID: editTaskReportAction.reportActionID, - assigneeChatReportActionID: optimisticAssigneeAddComment ? optimisticAssigneeAddComment.reportAction.reportActionID : 0, + assigneeChatReportID, + assigneeChatReportActionID: + assigneeChatReportOnyxData && assigneeChatReportOnyxData.optimisticAssigneeAddComment + ? assigneeChatReportOnyxData.optimisticAssigneeAddComment.reportAction.reportActionID + : 0, + assigneeChatCreatedReportActionID: + assigneeChatReportOnyxData && assigneeChatReportOnyxData.optimisticChatCreatedReportAction ? assigneeChatReportOnyxData.optimisticChatCreatedReportAction.reportActionID : 0, + }, + {optimisticData, successData, failureData}, + ); + + Navigation.dismissModal(report.reportID); +} + +function editTaskAssigneeAndNavigate(report, ownerAccountID, assigneeEmail, assigneeAccountID = 0, assigneeChatReport = null) { + // Create the EditedReportAction on the task + const editTaskReportAction = ReportUtils.buildOptimisticEditedTaskReportAction(currentUserEmail); + const reportName = report.reportName.trim(); + + let assigneeChatReportOnyxData; + const assigneeChatReportID = assigneeChatReport ? assigneeChatReport.reportID : 0; + + const optimisticData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, + value: {[editTaskReportAction.reportActionID]: editTaskReportAction}, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + value: { + reportName, + managerID: assigneeAccountID || report.managerID, + managerEmail: assigneeEmail || report.managerEmail, + }, + }, + ]; + const successData = []; + const failureData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, + value: {[editTaskReportAction.reportActionID]: {pendingAction: null}}, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + value: {assignee: report.managerEmail, assigneeAccountID: report.managerID}, + }, + ]; + + // 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) { + assigneeChatReportOnyxData = ReportUtils.getTaskAssigneeChatOnyxData( + currentUserAccountID, + assigneeEmail, + assigneeAccountID, + report.reportID, + assigneeChatReportID, + report.parentReportID, + reportName, + assigneeChatReport, + ); + optimisticData.push(...assigneeChatReportOnyxData.optimisticData); + successData.push(...assigneeChatReportOnyxData.successData); + failureData.push(...assigneeChatReportOnyxData.failureData); + } + + API.write( + 'EditTaskAssignee', + { + taskReportID: report.reportID, + assignee: assigneeEmail || report.managerEmail, + assigneeAccountID: assigneeAccountID || report.managerID, + editedTaskReportActionID: editTaskReportAction.reportActionID, + assigneeChatReportID, + assigneeChatReportActionID: + assigneeChatReportOnyxData && assigneeChatReportOnyxData.optimisticAssigneeAddComment + ? assigneeChatReportOnyxData.optimisticAssigneeAddComment.reportAction.reportActionID + : 0, + assigneeChatCreatedReportActionID: + assigneeChatReportOnyxData && assigneeChatReportOnyxData.optimisticChatCreatedReportAction ? assigneeChatReportOnyxData.optimisticChatCreatedReportAction.reportActionID : 0, }, {optimisticData, successData, failureData}, ); @@ -578,40 +629,65 @@ function setShareDestinationValue(shareDestination) { Onyx.merge(ONYXKEYS.TASK, {shareDestination}); } +/* Sets the assigneeChatReport details for the task + * @param {Object} chatReport + */ +function setAssigneeChatReport(chatReport) { + Onyx.merge(ONYXKEYS.TASK, {assigneeChatReport: chatReport}); +} + /** * 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 * It also sets the shareDestination as that chat report if a share destination isn't already set - * @param {string} assignee + * @param {string} assigneeEmail * @param {Number} assigneeAccountID * @param {string} shareDestination * @param {boolean} isCurrentUser */ -function setAssigneeValue(assignee, assigneeAccountID, shareDestination, isCurrentUser = false) { - let newAssigneeAccountID = Number(assigneeAccountID); +function setAssigneeValue(assigneeEmail, assigneeAccountID, shareDestination, isCurrentUser = false) { + let chatReport; - // Generate optimistic accountID if this is a brand new user account that hasn't been created yet - if (!newAssigneeAccountID) { - newAssigneeAccountID = UserUtils.generateAccountID(assignee); - } if (!isCurrentUser) { - let newChat = {}; - const chat = ReportUtils.getChatByParticipants([newAssigneeAccountID]); - if (!chat) { - newChat = ReportUtils.buildOptimisticChatReport([newAssigneeAccountID]); + chatReport = ReportUtils.getChatByParticipantsByLoginList([assigneeEmail]) || ReportUtils.getChatByParticipants([assigneeAccountID]); + if (!chatReport) { + chatReport = ReportUtils.buildOptimisticChatReport([assigneeAccountID]); + chatReport.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 + chatReport.isHidden = true; + Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport); + + // 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: lodashGet(allPersonalDetails, [assigneeAccountID, 'avatar'], UserUtils.getDefaultAvatarURL(assigneeAccountID)), + displayName: lodashGet(allPersonalDetails, [assigneeAccountID, 'displayName'], assigneeEmail), + login: assigneeEmail, + }; + Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneeAccountID]: optimisticPersonalDetailsListAction}); } - const reportID = chat ? chat.reportID : newChat.reportID; + setAssigneeChatReport(chatReport); + + // If there is no share destination set, automatically set it to the assignee chat report + // This allows for a much quicker process when creating a new task and is likely the desired share destination most times if (!shareDestination) { - setShareDestinationValue(reportID); + setShareDestinationValue(chatReport.reportID); } - - Report.openReport(reportID, [assignee], newChat); } // This is only needed for creation of a new task and so it should only be stored locally - Onyx.merge(ONYXKEYS.TASK, {assignee, assigneeAccountID: newAssigneeAccountID}); + Onyx.merge(ONYXKEYS.TASK, {assignee: assigneeEmail, assigneeAccountID}); + + // When we're editing the assignee, we immediately call EditTaskAndNavigate. Since setting the assignee is async, + // the chatReport is not yet set when EditTaskAndNavigate is called. So we return the chatReport here so that + // EditTaskAndNavigate can use it. + return chatReport; } /** @@ -818,6 +894,7 @@ function clearEditTaskErrors(reportID) { export { createTaskAndNavigate, editTaskAndNavigate, + editTaskAssigneeAndNavigate, setTitleValue, setDescriptionValue, setTaskReport, diff --git a/src/pages/home/sidebar/SidebarLinksData.js b/src/pages/home/sidebar/SidebarLinksData.js index 58a7e676403a..6f5f96e2a050 100644 --- a/src/pages/home/sidebar/SidebarLinksData.js +++ b/src/pages/home/sidebar/SidebarLinksData.js @@ -114,6 +114,7 @@ const chatReportSelector = (report) => participantAccountIDs: report.participantAccountIDs, hasDraft: report.hasDraft, isPinned: report.isPinned, + isHidden: report.isHidden, errorFields: { addWorkspaceRoom: report.errorFields && report.errorFields.addWorkspaceRoom, }, diff --git a/src/pages/tasks/NewTaskPage.js b/src/pages/tasks/NewTaskPage.js index 4b1aa0c0101b..4c915db567c4 100644 --- a/src/pages/tasks/NewTaskPage.js +++ b/src/pages/tasks/NewTaskPage.js @@ -126,7 +126,7 @@ function NewTaskPage(props) { } shouldClearOutTaskInfoOnUnmount.current = true; - Task.createTaskAndNavigate(parentReport.reportID, props.task.title, props.task.description, props.task.assignee, props.task.assigneeAccountID); + Task.createTaskAndNavigate(parentReport.reportID, props.task.title, props.task.description, props.task.assignee, props.task.assigneeAccountID, props.task.assigneeChatReport); } if (!Permissions.canUseTasks(props.betas)) { diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.js b/src/pages/tasks/TaskAssigneeSelectorModal.js index 784c4c1a14df..245d00f3d0f7 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.js +++ b/src/pages/tasks/TaskAssigneeSelectorModal.js @@ -172,15 +172,10 @@ function TaskAssigneeSelectorModal(props) { // Check to see if we're editing a task and if so, update the assignee if (report) { - // There was an issue where sometimes a new assignee didn't have a DM thread - // This would cause the app to crash, so we need to make sure we have a DM thread - Task.setAssigneeValue(option.login, option.accountID, props.route.params.reportID, OptionsListUtils.isCurrentUser(option)); + const assigneeChatReport = Task.setAssigneeValue(option.login, option.accountID, props.route.params.reportID, OptionsListUtils.isCurrentUser(option)); // Pass through the selected assignee - Task.editTaskAndNavigate(report, props.session.accountID, { - assignee: option.login, - assigneeAccountID: option.accountID, - }); + Task.editTaskAssigneeAndNavigate(props.task.report, props.session.accountID, option.login, option.accountID, assigneeChatReport); } };