diff --git a/src/components/ReportActionItem/TaskPreview.js b/src/components/ReportActionItem/TaskPreview.js
index ca4103624440..d0181e3d736a 100644
--- a/src/components/ReportActionItem/TaskPreview.js
+++ b/src/components/ReportActionItem/TaskPreview.js
@@ -72,6 +72,11 @@ function TaskPreview(props) {
const assigneeDisplayName = lodashGet(props.personalDetailsList, [taskAssigneeAccountID, 'displayName'], '');
const taskAssignee = assigneeLogin || assigneeDisplayName;
const htmlForTaskPreview = taskAssignee ? `@${taskAssignee} ${taskTitle}` : `${taskTitle}`;
+ const isDeletedParentAction = ReportUtils.isCanceledTaskReport(props.taskReport, props.action);
+
+ if (isDeletedParentAction) {
+ return ${props.translate('parentReportAction.deletedTask')}`} />;
+ }
return (
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 03adaa1e66b1..bc5ac9d63b92 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -1520,7 +1520,7 @@ export default {
completed: 'Completed',
messages: {
completed: 'completed task',
- canceled: 'canceled task',
+ canceled: 'deleted task',
reopened: 'reopened task',
error: 'You do not have the permission to do the requested action.',
},
@@ -1692,6 +1692,7 @@ export default {
parentReportAction: {
deletedMessage: '[Deleted message]',
deletedRequest: '[Deleted request]',
+ deletedTask: '[Deleted task]',
hiddenMessage: '[Hidden message]',
},
threads: {
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 7315c42cebab..42faf6e6c9a1 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -1542,7 +1542,7 @@ export default {
completed: 'Completada',
messages: {
completed: 'tarea completada',
- canceled: 'tarea cancelada',
+ canceled: 'tarea eliminado',
reopened: 'tarea reabrir',
error: 'No tiene permiso para realizar la acción solicitada.',
},
@@ -2174,6 +2174,7 @@ export default {
parentReportAction: {
deletedMessage: '[Mensaje eliminado]',
deletedRequest: '[Pedido eliminado]',
+ deletedTask: '[Tarea eliminado]',
hiddenMessage: '[Mensaje oculto]',
},
threads: {
diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js
index f24959c4bac2..00a0a0dcbcba 100644
--- a/src/libs/ReportUtils.js
+++ b/src/libs/ReportUtils.js
@@ -187,23 +187,37 @@ function isTaskReport(report) {
}
/**
- * Checks if a report is an open task report.
+ * Checks if a task has been cancelled
+ * When a task is deleted, the parentReportAction is updated to have a isDeletedParentAction deleted flag
+ * This is because when you delete a task, we still allow you to chat on the report itself
+ * There's another situation where you don't have access to the parentReportAction (because it was created in a chat you don't have access to)
+ * In this case, we have added the key to the report itself
*
* @param {Object} report
+ * @param {Object} parentReportAction
* @returns {Boolean}
*/
-function isOpenTaskReport(report) {
- return isTaskReport(report) && report.stateNum === CONST.REPORT.STATE_NUM.OPEN && report.statusNum === CONST.REPORT.STATUS.OPEN;
+function isCanceledTaskReport(report = {}, parentReportAction = {}) {
+ if (!_.isEmpty(parentReportAction) && lodashGet(parentReportAction, ['message', 0, 'isDeletedParentAction'], false)) {
+ return true;
+ }
+
+ if (!_.isEmpty(report) && report.isDeletedParentAction) {
+ return true;
+ }
+
+ return false;
}
/**
- * Checks if the current user is assigned to the task report
+ * Checks if a report is an open task report.
*
* @param {Object} report
+ * @param {Object} parentReportAction - The parent report action of the report (Used to check if the task has been canceled)
* @returns {Boolean}
*/
-function isCanceledTaskReport(report) {
- return isTaskReport(report) && report.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && report.statusNum === CONST.REPORT.STATUS.CLOSED;
+function isOpenTaskReport(report, parentReportAction = {}) {
+ return isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report.stateNum === CONST.REPORT.STATE_NUM.OPEN && report.statusNum === CONST.REPORT.STATUS.OPEN;
}
/**
@@ -1600,8 +1614,8 @@ function getParentReport(report) {
*/
function getReportName(report, policy = undefined) {
let formattedName;
+ const parentReportAction = ReportActionsUtils.getParentReportAction(report);
if (isChatThread(report)) {
- const parentReportAction = ReportActionsUtils.getParentReportAction(report);
if (ReportActionsUtils.isTransactionThread(parentReportAction)) {
return getTransactionReportName(parentReportAction);
}
@@ -1619,6 +1633,11 @@ function getReportName(report, policy = undefined) {
}
return parentReportActionMessage || Localize.translateLocal('parentReportAction.deletedMessage');
}
+
+ if (isTaskReport(report) && isCanceledTaskReport(report, parentReportAction)) {
+ return Localize.translateLocal('parentReportAction.deletedTask');
+ }
+
if (isChatRoom(report) || isTaskReport(report)) {
formattedName = report.reportName;
}
diff --git a/src/libs/actions/Task.js b/src/libs/actions/Task.js
index 2d599053ea51..a5e8ac325217 100644
--- a/src/libs/actions/Task.js
+++ b/src/libs/actions/Task.js
@@ -755,26 +755,50 @@ function getShareDestination(reportID, reports, personalDetails) {
* @param {number} originalStatusNum
*/
function cancelTask(taskReportID, taskTitle, originalStateNum, originalStatusNum) {
- const message = `canceled task: ${taskTitle}`;
+ const message = `deleted task: ${taskTitle}`;
const optimisticCancelReportAction = ReportUtils.buildOptimisticTaskReportAction(taskReportID, CONST.REPORT.ACTIONS.TYPE.TASKCANCELLED, message);
const optimisticReportActionID = optimisticCancelReportAction.reportActionID;
+ const taskReport = ReportUtils.getReport(taskReportID);
+ const parentReportAction = ReportActionsUtils.getParentReportAction(taskReport);
+ const parentReport = ReportUtils.getParentReport(taskReport);
+
+ const optimisticReportActions = {
+ [parentReportAction.reportActionID]: {
+ pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ previousMessage: parentReportAction.message,
+ message: [
+ {
+ translationKey: '',
+ type: 'COMMENT',
+ html: '',
+ text: '',
+ isEdited: true,
+ isDeletedParentAction: true,
+ },
+ ],
+ errors: null,
+ linkMetaData: [],
+ },
+ };
const optimisticData = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`,
value: {
- stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
- statusNum: CONST.REPORT.STATUS.CLOSED,
+ lastVisibleActionCreated: optimisticCancelReportAction.created,
+ lastMessageText: message,
+ lastActorAccountID: optimisticCancelReportAction.actorAccountID,
+ updateReportInLHN: true,
+ isDeletedParentAction: true,
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`,
value: {
- lastVisibleActionCreated: optimisticCancelReportAction.created,
- lastMessageText: message,
- lastActorAccountID: optimisticCancelReportAction.actorAccountID,
+ lastMessageText: ReportActionsUtils.getLastVisibleMessage(parentReport.reportID, {[parentReportAction.reportActionID]: null}).lastMessageText,
+ lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(parentReport.reportID, {[parentReportAction.reportActionID]: null}).created,
},
},
{
@@ -784,6 +808,11 @@ function cancelTask(taskReportID, taskTitle, originalStateNum, originalStatusNum
[optimisticReportActionID]: optimisticCancelReportAction,
},
},
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport.reportID}`,
+ value: optimisticReportActions,
+ },
];
const successData = [
diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js
index 8d389a8c8581..477d063c1747 100644
--- a/src/pages/home/HeaderView.js
+++ b/src/pages/home/HeaderView.js
@@ -29,6 +29,7 @@ import reportActionPropTypes from './report/reportActionPropTypes';
import PressableWithoutFeedback from '../../components/Pressable/PressableWithoutFeedback';
import PinButton from '../../components/PinButton';
import TaskHeaderActionButton from '../../components/TaskHeaderActionButton';
+import * as ReportActionsUtils from '../../libs/ReportActionsUtils';
import ParentNavigationSubtitle from '../../components/ParentNavigationSubtitle';
const propTypes = {
@@ -93,12 +94,14 @@ function HeaderView(props) {
const isConcierge = ReportUtils.hasSingleParticipant(props.report) && _.contains(participants, CONST.ACCOUNT_ID.CONCIERGE);
const isAutomatedExpensifyAccount = ReportUtils.hasSingleParticipant(props.report) && ReportUtils.hasAutomatedExpensifyAccountIDs(participants);
const guideCalendarLink = lodashGet(props.account, 'guideCalendarLink');
+ const parentReportAction = ReportActionsUtils.getParentReportAction(props.report);
+ const isCanceledTaskReport = ReportUtils.isCanceledTaskReport(props.report, parentReportAction);
// We hide the button when we are chatting with an automated Expensify account since it's not possible to contact
// these users via alternative means. It is possible to request a call with Concierge so we leave the option for them.
const shouldShowCallButton = (isConcierge && guideCalendarLink) || (!isAutomatedExpensifyAccount && !isTaskReport);
const threeDotMenuItems = [];
- if (isTaskReport) {
+ if (isTaskReport && !isCanceledTaskReport) {
const canModifyTask = Task.canModifyTask(props.report, props.session.accountID);
if (ReportUtils.isOpenTaskReport(props.report) && canModifyTask) {
threeDotMenuItems.push({
diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js
index 004087c22308..36063aa5c72d 100644
--- a/src/pages/home/ReportScreen.js
+++ b/src/pages/home/ReportScreen.js
@@ -316,7 +316,7 @@ function ReportScreen({
needsOffscreenAlphaCompositing
>
{headerView}
- {ReportUtils.isTaskReport(report) && isSmallScreenWidth && ReportUtils.isOpenTaskReport(report) && (
+ {ReportUtils.isTaskReport(report) && isSmallScreenWidth && ReportUtils.isOpenTaskReport(report, parentReportAction) && (
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index a5c412e17a50..2f4545b6e1d5 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -67,6 +67,7 @@ import * as BankAccounts from '../../../libs/actions/BankAccounts';
import usePrevious from '../../../hooks/usePrevious';
import ReportScreenContext from '../ReportScreenContext';
import Permissions from '../../../libs/Permissions';
+import RenderHTML from '../../../components/RenderHTML';
import ReportAttachmentsContext from './ReportAttachmentsContext';
const propTypes = {
@@ -514,6 +515,22 @@ function ReportActionItem(props) {
);
}
if (ReportUtils.isTaskReport(props.report)) {
+ if (ReportUtils.isCanceledTaskReport(props.report, parentReportAction)) {
+ return (
+ <>
+
+ ${props.translate('parentReportAction.deletedTask')}`} />
+
+
+ >
+ );
+ }
+
return (
{
const reports = {};
_.keys(props.reports).forEach((reportKey) => {
- if (ReportUtils.shouldDisableWriteActions(props.reports[reportKey]) || ReportUtils.isExpensifyOnlyParticipantInReport(props.reports[reportKey])) {
+ if (
+ ReportUtils.shouldDisableWriteActions(props.reports[reportKey]) ||
+ ReportUtils.isExpensifyOnlyParticipantInReport(props.reports[reportKey]) ||
+ ReportUtils.isCanceledTaskReport(props.reports[reportKey])
+ ) {
return;
}
reports[reportKey] = props.reports[reportKey];