Skip to content

Commit

Permalink
Merge pull request #24137 from Expensify/jack-updateCancelledTaskUI
Browse files Browse the repository at this point in the history
Update Canceled task flow
  • Loading branch information
tylerkaraszewski authored Sep 18, 2023
2 parents d848eab + b4604fb commit 949a7d7
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 19 deletions.
5 changes: 5 additions & 0 deletions src/components/ReportActionItem/TaskPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ function TaskPreview(props) {
const assigneeDisplayName = lodashGet(props.personalDetailsList, [taskAssigneeAccountID, 'displayName'], '');
const taskAssignee = assigneeLogin || assigneeDisplayName;
const htmlForTaskPreview = taskAssignee ? `<comment><mention-user>@${taskAssignee}</mention-user> ${taskTitle}</comment>` : `<comment>${taskTitle}</comment>`;
const isDeletedParentAction = ReportUtils.isCanceledTaskReport(props.taskReport, props.action);

if (isDeletedParentAction) {
return <RenderHTML html={`<comment>${props.translate('parentReportAction.deletedTask')}</comment>`} />;
}

return (
<View style={[styles.chatItemMessage]}>
Expand Down
3 changes: 2 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,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.',
},
Expand Down Expand Up @@ -1697,6 +1697,7 @@ export default {
parentReportAction: {
deletedMessage: '[Deleted message]',
deletedRequest: '[Deleted request]',
deletedTask: '[Deleted task]',
hiddenMessage: '[Hidden message]',
},
threads: {
Expand Down
3 changes: 2 additions & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1547,7 +1547,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.',
},
Expand Down Expand Up @@ -2179,6 +2179,7 @@ export default {
parentReportAction: {
deletedMessage: '[Mensaje eliminado]',
deletedRequest: '[Pedido eliminado]',
deletedTask: '[Tarea eliminado]',
hiddenMessage: '[Mensaje oculto]',
},
threads: {
Expand Down
33 changes: 26 additions & 7 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -1610,8 +1624,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);
}
Expand All @@ -1629,6 +1643,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;
}
Expand Down
43 changes: 36 additions & 7 deletions src/libs/actions/Task.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
},
{
Expand All @@ -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 = [
Expand Down
5 changes: 4 additions & 1 deletion src/pages/home/HeaderView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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({
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/ReportScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ function ReportScreen({
needsOffscreenAlphaCompositing
>
{headerView}
{ReportUtils.isTaskReport(report) && isSmallScreenWidth && ReportUtils.isOpenTaskReport(report) && (
{ReportUtils.isTaskReport(report) && isSmallScreenWidth && ReportUtils.isOpenTaskReport(report, parentReportAction) && (
<View style={[styles.borderBottom]}>
<View style={[styles.appBG, styles.pl0]}>
<View style={[styles.ph5, styles.pb3]}>
Expand Down
17 changes: 17 additions & 0 deletions src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -520,6 +521,22 @@ function ReportActionItem(props) {
);
}
if (ReportUtils.isTaskReport(props.report)) {
if (ReportUtils.isCanceledTaskReport(props.report, parentReportAction)) {
return (
<>
<ReportActionItemSingle
action={parentReportAction}
showHeader={!props.draftMessage}
wrapperStyles={[styles.chatItem]}
report={props.report}
>
<RenderHTML html={`<comment>${props.translate('parentReportAction.deletedTask')}</comment>`} />
</ReportActionItemSingle>
<View style={styles.reportHorizontalRule} />
</>
);
}

return (
<OfflineWithFeedback pendingAction={props.action.pendingAction}>
<TaskView
Expand Down
6 changes: 5 additions & 1 deletion src/pages/tasks/TaskShareDestinationSelectorModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ function TaskShareDestinationSelectorModal(props) {
const filteredReports = useMemo(() => {
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];
Expand Down

0 comments on commit 949a7d7

Please sign in to comment.