diff --git a/src/CONST.js b/src/CONST.js index 72ca7712d962..8b380ae2beef 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -412,6 +412,7 @@ const CONST = { RENAMED: 'RENAMED', CHRONOSOOOLIST: 'CHRONOSOOOLIST', TASKCOMPLETED: 'TASKCOMPLETED', + TASKREOPENED: 'TASKREOPENED', POLICYCHANGELOG: { ADD_APPROVER_RULE: 'POLICYCHANGELOG_ADD_APPROVER_RULE', ADD_CATEGORY: 'POLICYCHANGELOG_ADD_CATEGORY', diff --git a/src/components/ReportActionItem/TaskAction.js b/src/components/ReportActionItem/TaskAction.js index 265b92c92512..f1e94b0b5ed9 100644 --- a/src/components/ReportActionItem/TaskAction.js +++ b/src/components/ReportActionItem/TaskAction.js @@ -49,7 +49,18 @@ const TaskAction = (props) => { const taskReportID = props.taskReportID; const taskReportName = props.taskReport.reportName || ''; - const messageLinkText = props.actionName === CONST.REPORT.ACTIONS.TYPE.TASKCOMPLETED ? props.translate('task.messages.completed') : props.translate('newTaskPage.task'); + let messageLinkText = ''; + switch (props.actionName) { + case CONST.REPORT.ACTIONS.TYPE.TASKCOMPLETED: + messageLinkText = props.translate('task.messages.completed'); + break; + case CONST.REPORT.ACTIONS.TYPE.TASKREOPENED: + messageLinkText = props.translate('task.messages.reopened'); + break; + default: + messageLinkText = props.translate('newTaskPage.task'); + } + return ( Navigation.navigate(ROUTES.getReportRoute(taskReportID))} diff --git a/src/components/ReportActionItem/TaskPreview.js b/src/components/ReportActionItem/TaskPreview.js index 3059be499f91..394ca5d9e366 100644 --- a/src/components/ReportActionItem/TaskPreview.js +++ b/src/components/ReportActionItem/TaskPreview.js @@ -71,9 +71,10 @@ const TaskPreview = (props) => { isChecked={isTaskCompleted} onPress={() => { if (isTaskCompleted) { - return; + TaskUtils.reopenTask(props.taskReportID, parentReportID, taskTitle); + } else { + TaskUtils.completeTask(props.taskReportID, parentReportID, taskTitle); } - TaskUtils.completeTask(props.taskReportID, parentReportID, taskTitle); }} /> {taskTitle} diff --git a/src/languages/en.js b/src/languages/en.js index 5726a5a9089f..ddad4a64e532 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1197,6 +1197,7 @@ export default { completed: 'Completed', messages: { completed: 'Completed task', + reopened: 'Reopened task', }, }, statementPage: { diff --git a/src/languages/es.js b/src/languages/es.js index 0d04dea828a5..ed3ca1ba0e04 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -1201,7 +1201,8 @@ export default { task: { completed: 'Completada', messages: { - completed: 'tarea completada', + completed: 'Tarea completada', + reopened: 'Tarea reabrir', }, }, statementPage: { diff --git a/src/libs/actions/Task.js b/src/libs/actions/Task.js index 00c2fa4766a0..1dfa8cfc7393 100644 --- a/src/libs/actions/Task.js +++ b/src/libs/actions/Task.js @@ -208,6 +208,68 @@ function completeTask(taskReportID, parentReportID, taskTitle) { ); } +/** + * Reopens a closed task + * @param {string} taskReportID ReportID of the task + * @param {string} parentReportID ReportID of the linked parent report of the task so we can add the action + * @param {string} taskTitle Title of the task + */ +function reopenTask(taskReportID, parentReportID, taskTitle) { + const message = `Reopened task: ${taskTitle}`; + const reopenedTaskReportAction = ReportUtils.buildOptimisticTaskReportAction(taskReportID, CONST.REPORT.ACTIONS.TYPE.TASKREOPENED, message); + + const optimisticData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, + value: { + stateNum: CONST.REPORT.STATE_NUM.OPEN, + statusNum: CONST.REPORT.STATUS.OPEN, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, + value: { + lastVisibleActionCreated: reopenedTaskReportAction.created, + lastMessageText: message, + lastActorEmail: reopenedTaskReportAction.actorEmail, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, + value: {[reopenedTaskReportAction.reportActionID]: reopenedTaskReportAction}, + }, + ]; + + const successData = []; + const failureData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, + value: { + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS.APPROVED, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, + value: {[reopenedTaskReportAction.reportActionID]: {pendingAction: null}}, + }, + ]; + + API.write( + 'ReopenTask', + { + taskReportID, + reopenedTaskReportActionID: reopenedTaskReportAction.reportActionID, + }, + {optimisticData, successData, failureData}, + ); +} + /** * @function editTask * @param {object} report @@ -450,6 +512,7 @@ export { setAssigneeValue, setShareDestinationValue, clearOutTaskInfo, + reopenTask, completeTask, clearOutTaskInfoAndNavigate, getAssignee, diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index 1f78b28fa125..2ed0b337aaae 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -103,9 +103,7 @@ const HeaderView = (props) => { threeDotMenuItems.push({ icon: Expensicons.Checkmark, text: props.translate('newTaskPage.markAsIncomplete'), - - // Implementing in https://github.com/Expensify/App/issues/16858 - onSelected: () => {}, + onSelected: () => TaskUtils.reopenTask(props.report.reportID, props.report.parentReportID, title), }); }