Skip to content

Commit

Permalink
Merge branch 'main' into fix-18558
Browse files Browse the repository at this point in the history
  • Loading branch information
allroundexperts committed May 16, 2023
2 parents 460cf29 + dd5fbb6 commit f14f57e
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
2 changes: 1 addition & 1 deletion src/components/AvatarWithDisplayName.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const defaultProps = {

const AvatarWithDisplayName = (props) => {
const title = ReportUtils.getDisplayNameForParticipant(props.report.ownerEmail, true);
const subtitle = ReportUtils.getChatRoomSubtitle(props.report, props.policies);
const subtitle = ReportUtils.getChatRoomSubtitle(props.report);
const isExpenseReport = ReportUtils.isExpenseReport(props.report);
const icons = ReportUtils.getIcons(props.report, props.personalDetails, props.policies);
const ownerPersonalDetails = OptionsListUtils.getPersonalDetailsForLogins([props.report.ownerEmail], props.personalDetails);
Expand Down
10 changes: 6 additions & 4 deletions src/components/ReportActionItem/IOUPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ const IOUPreview = (props) => {
const sessionEmail = lodashGet(props.session, 'email', null);
const managerEmail = props.iouReport.managerEmail || '';
const ownerEmail = props.iouReport.ownerEmail || '';
const comment = Str.htmlDecode(lodashGet(props.action, 'originalMessage.comment', '')).trim();

// When displaying within a IOUDetailsModal we cannot guarantee that participants are included in the originalMessage data
// Because an IOUPreview of type split can never be rendered within the IOUDetailsModal, manually building the email array is only needed for non-billSplit ious
Expand All @@ -144,9 +143,12 @@ const IOUPreview = (props) => {
// Pay button should only be visible to the manager of the report.
const isCurrentUserManager = managerEmail === sessionEmail;

const moneyRequestAction = ReportUtils.getMoneyRequestAction(props.action);

// If props.action is undefined then we are displaying within IOUDetailsModal and should use the full report amount
const requestAmount = props.isIOUAction ? lodashGet(props.action, 'originalMessage.amount', 0) : ReportUtils.getMoneyRequestTotal(props.iouReport);
const requestCurrency = props.isIOUAction ? lodashGet(props.action, 'originalMessage.currency', CONST.CURRENCY.USD) : props.iouReport.currency;
const requestAmount = props.isIOUAction ? moneyRequestAction.total : ReportUtils.getMoneyRequestTotal(props.iouReport);
const requestCurrency = props.isIOUAction ? moneyRequestAction.currency : props.iouReport.currency;
const requestComment = Str.htmlDecode(moneyRequestAction.comment).trim();

const getSettledMessage = () => {
switch (lodashGet(props.action, 'originalMessage.paymentType', '')) {
Expand Down Expand Up @@ -228,7 +230,7 @@ const IOUPreview = (props) => {
{!isCurrentUserManager && props.shouldShowPendingConversionMessage && (
<Text style={[styles.textLabel, styles.colorMuted]}>{props.translate('iou.pendingConversionMessage')}</Text>
)}
{!_.isEmpty(comment) && <Text style={[styles.colorMuted]}>{comment}</Text>}
{!_.isEmpty(requestComment) && <Text style={[styles.colorMuted]}>{requestComment}</Text>}
</View>
{props.isBillSplit && !_.isEmpty(participantEmails) && (
<Text style={[styles.textLabel, styles.colorMuted, styles.ml1]}>
Expand Down
13 changes: 12 additions & 1 deletion src/components/ReportActionItem/TaskAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<Pressable
onPress={() => Navigation.navigate(ROUTES.getReportRoute(taskReportID))}
Expand Down
5 changes: 3 additions & 2 deletions src/components/ReportActionItem/TaskPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}}
/>
<Text>{taskTitle}</Text>
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,7 @@ export default {
completed: 'Completed',
messages: {
completed: 'Completed task',
reopened: 'Reopened task',
},
},
statementPage: {
Expand Down
3 changes: 2 additions & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,8 @@ export default {
task: {
completed: 'Completada',
messages: {
completed: 'tarea completada',
completed: 'Tarea completada',
reopened: 'Tarea reabrir',
},
},
statementPage: {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportActionsUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function getLastVisibleMessageText(reportID, actionsToMerge = {}) {
const htmlText = lodashGet(lastVisibleAction, 'message[0].html', '');
const parser = new ExpensiMark();
const messageText = parser.htmlToText(htmlText);
return String(messageText).replace(CONST.REGEX.AFTER_FIRST_LINE_BREAK, '').substring(0, CONST.REPORT.LAST_MESSAGE_TEXT_MAX_LENGTH);
return String(messageText).replace(CONST.REGEX.AFTER_FIRST_LINE_BREAK, '').substring(0, CONST.REPORT.LAST_MESSAGE_TEXT_MAX_LENGTH).trim();
}

/**
Expand Down
44 changes: 40 additions & 4 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,17 +461,26 @@ function isThreadFirstChat(reportAction, reportID) {
/**
* Get either the policyName or domainName the chat is tied to
* @param {Object} report
* @param {Object} parentReport
* @returns {String}
*/
function getChatRoomSubtitle(report) {
function getChatRoomSubtitle(report, parentReport = null) {
if (isThread(report)) {
if (!getChatType(report)) {
return '';
}

// If thread is not from a DM or group chat, the subtitle will follow the pattern 'Workspace Name • #roomName'
const workspaceName = getPolicyName(report);
const roomName = isChatRoom(report) ? lodashGet(report, 'displayName') : '';
let roomName = '';
if (isChatRoom(report)) {
if (parentReport) {
roomName = lodashGet(parentReport, 'displayName', '');
} else {
roomName = lodashGet(report, 'displayName', '');
}
}

return [workspaceName, roomName].join(' • ');
}
if (!isDefaultRoom(report) && !isUserCreatedPolicyRoom(report) && !isPolicyExpenseChat(report)) {
Expand Down Expand Up @@ -574,12 +583,12 @@ function canShowReportRecipientLocalTime(personalDetails, report) {
}

/**
* Trim the last message text to a fixed limit.
* Html decode, shorten last message text to fixed length and trim spaces.
* @param {String} lastMessageText
* @returns {String}
*/
function formatReportLastMessageText(lastMessageText) {
return String(lastMessageText).replace(CONST.REGEX.AFTER_FIRST_LINE_BREAK, '').substring(0, CONST.REPORT.LAST_MESSAGE_TEXT_MAX_LENGTH);
return Str.htmlDecode(String(lastMessageText)).replace(CONST.REGEX.AFTER_FIRST_LINE_BREAK, '').substring(0, CONST.REPORT.LAST_MESSAGE_TEXT_MAX_LENGTH).trim();
}

/**
Expand Down Expand Up @@ -937,6 +946,32 @@ function getDisplayNamesWithTooltips(participants, isMultipleParticipantReport)
});
}

/**
* We get the amount, currency and comment money request value from the action.originalMessage.
* But for the send money action, the above value is put in the IOUDetails object.
*
* @param {Object} reportAction
* @param {Number} reportAction.amount
* @param {String} reportAction.currency
* @param {String} reportAction.comment
* @param {Object} [reportAction.IOUDetails]
* @returns {Object}
*/
function getMoneyRequestAction(reportAction = {}) {
const originalMessage = lodashGet(reportAction, 'originalMessage', {});
let total = originalMessage.amount || 0;
let currency = originalMessage.currency || CONST.CURRENCY.USD;
let comment = originalMessage.comment || '';

if (_.has(originalMessage, 'IOUDetails')) {
total = lodashGet(originalMessage, 'IOUDetails.amount', 0);
currency = lodashGet(originalMessage, 'IOUDetails.currency', CONST.CURRENCY.USD);
comment = lodashGet(originalMessage, 'IOUDetails.comment', '');
}

return {total, currency, comment};
}

/**
* @param {Object} report
* @param {String} report.iouReportID
Expand Down Expand Up @@ -2203,4 +2238,5 @@ export {
shouldReportShowSubscript,
isReportDataReady,
isSettled,
getMoneyRequestAction,
};
2 changes: 1 addition & 1 deletion src/libs/SidebarUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ function getOptionData(reportID) {

const parentReport = result.parentReportID ? chatReports[`${ONYXKEYS.COLLECTION.REPORT}${result.parentReportID}`] : null;
const hasMultipleParticipants = participantPersonalDetailList.length > 1 || result.isChatRoom || result.isPolicyExpenseChat;
const subtitle = ReportUtils.getChatRoomSubtitle(report);
const subtitle = ReportUtils.getChatRoomSubtitle(report, parentReport);

const login = Str.removeSMSDomain(lodashGet(personalDetail, 'login', ''));
const formattedLogin = Str.isSMSLogin(login) ? LocalePhoneNumber.formatPhoneNumber(login) : login;
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ function addActions(reportID, text = '', file) {

const optimisticReport = {
lastVisibleActionCreated: currentTime,
lastMessageText: Str.htmlDecode(lastCommentText),
lastMessageText: lastCommentText,
lastActorEmail: currentUserEmail,
lastReadTime: currentTime,
};
Expand Down Expand Up @@ -1032,7 +1032,7 @@ function editReportComment(reportID, originalReportAction, textForNewComment) {
const reportComment = parser.htmlToText(htmlForNewComment);
const lastMessageText = ReportUtils.formatReportLastMessageText(reportComment);
const optimisticReport = {
lastMessageText: Str.htmlDecode(lastMessageText),
lastMessageText,
};
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
Expand Down
63 changes: 63 additions & 0 deletions src/libs/actions/Task.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -450,6 +512,7 @@ export {
setAssigneeValue,
setShareDestinationValue,
clearOutTaskInfo,
reopenTask,
completeTask,
clearOutTaskInfoAndNavigate,
getAssignee,
Expand Down
8 changes: 3 additions & 5 deletions src/pages/home/HeaderView.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ const HeaderView = (props) => {
const isChatRoom = ReportUtils.isChatRoom(props.report);
const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report);
const isTaskReport = ReportUtils.isTaskReport(props.report);
const reportHeaderData = isTaskReport && !_.isEmpty(props.parentReport) && (!isThread || isTaskReport) ? props.parentReport : props.report;
const reportHeaderData = (isTaskReport || !isThread) && !_.isEmpty(props.parentReport) ? props.parentReport : props.report;
const title = ReportUtils.getReportName(reportHeaderData);
const subtitle = ReportUtils.getChatRoomSubtitle(reportHeaderData);
const subtitle = ReportUtils.getChatRoomSubtitle(reportHeaderData, props.parentReport);
const isConcierge = participants.length === 1 && _.contains(participants, CONST.EMAIL.CONCIERGE);
const isAutomatedExpensifyAccount = participants.length === 1 && ReportUtils.hasAutomatedExpensifyEmails(participants);
const guideCalendarLink = lodashGet(props.account, 'guideCalendarLink');
Expand All @@ -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),
});
}

Expand Down

0 comments on commit f14f57e

Please sign in to comment.