, policy: OnyxEntry): boolean {
+ return reportField?.type === 'formula' && reportField?.fieldID === CONST.REPORT_FIELD_TITLE_FIELD_ID;
+}
+
+/**
+ * Given a report field, check if the field can be edited or not.
+ * For title fields, its considered disabled if `deletable` prop is `true` (https://github.com/Expensify/App/issues/35043#issuecomment-1911275433)
+ * For non title fields, its considered disabled if:
+ * 1. The user is not admin of the report
+ * 2. Report is settled or it is closed
+ */
+function isReportFieldDisabled(report: OnyxEntry, reportField: OnyxEntry, policy: OnyxEntry): boolean {
+ const isReportSettled = isSettled(report?.reportID);
+ const isReportClosed = report?.statusNum === CONST.REPORT.STATUS_NUM.CLOSED;
+ const isTitleField = isReportFieldOfTypeTitle(reportField);
+ const isAdmin = isPolicyAdmin(report?.policyID ?? '', {[`${ONYXKEYS.COLLECTION.POLICY}${policy?.id ?? ''}`]: policy});
+ return isTitleField ? !reportField?.deletable : !isAdmin && (isReportSettled || isReportClosed);
+}
+
+/**
+ * Given a set of report fields, return the field of type formula
+ */
+function getFormulaTypeReportField(reportFields: PolicyReportFields) {
+ return Object.values(reportFields).find((field) => field.type === 'formula');
+}
+
+/**
+ * Get the report fields attached to the policy given policyID
+ */
+function getReportFieldsByPolicyID(policyID: string) {
+ return Object.entries(allPolicyReportFields ?? {}).find(([key]) => key.replace(ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS, '') === policyID)?.[1];
+}
+
+/**
+ * Get the report fields that we should display a MoneyReportView gets opened
+ */
+
+function getAvailableReportFields(report: Report, policyReportFields: PolicyReportField[]): PolicyReportField[] {
+ // Get the report fields that are attached to a report. These will persist even if a field is deleted from the policy.
+ const reportFields = Object.values(report.reportFields ?? {});
+ const reportIsSettled = isSettled(report.reportID);
+
+ // If the report is settled, we don't want to show any new field that gets added to the policy.
+ if (reportIsSettled) {
+ return reportFields;
+ }
+
+ // If the report is unsettled, we want to merge the new fields that get added to the policy with the fields that
+ // are attached to the report.
+ const mergedFieldIds = Array.from(new Set([...policyReportFields.map(({fieldID}) => fieldID), ...reportFields.map(({fieldID}) => fieldID)]));
+ return mergedFieldIds.map((id) => report?.reportFields?.[id] ?? policyReportFields.find(({fieldID}) => fieldID === id)) as PolicyReportField[];
+}
+
/**
* Get the title for an IOU or expense chat which will be showing the payer and the amount
*/
function getMoneyRequestReportName(report: OnyxEntry, policy: OnyxEntry | undefined = undefined): string {
+ const isReportSettled = isSettled(report?.reportID ?? '');
+ const reportFields = isReportSettled ? report?.reportFields : getReportFieldsByPolicyID(report?.policyID ?? '');
+ const titleReportField = getFormulaTypeReportField(reportFields ?? {});
+
+ if (titleReportField && report?.reportName && Permissions.canUseReportFields(allBetas ?? [])) {
+ return report.reportName;
+ }
+
const moneyRequestTotal = getMoneyRequestSpendBreakdown(report).totalDisplaySpend;
const formattedAmount = CurrencyUtils.convertToDisplayString(moneyRequestTotal, report?.currency, hasOnlyDistanceRequestTransactions(report?.reportID));
const payerOrApproverName = isExpenseReport(report) ? getPolicyName(report, false, policy) : getDisplayNameForParticipant(report?.managerID) ?? '';
@@ -4540,32 +4630,6 @@ function navigateToPrivateNotes(report: Report, session: Session) {
Navigation.navigate(ROUTES.PRIVATE_NOTES_LIST.getRoute(report.reportID));
}
-/**
- * Given a report field and a report, get the title of the field.
- * This is specially useful when we have a report field of type formula.
- */
-function getReportFieldTitle(report: OnyxEntry, reportField: PolicyReportField): string {
- const value = report?.reportFields?.[reportField.fieldID] ?? reportField.defaultValue;
-
- if (reportField.type !== 'formula') {
- return value;
- }
-
- return value.replaceAll(CONST.REGEX.REPORT_FIELD_TITLE, (match, property) => {
- if (report && property in report) {
- return report[property as keyof Report]?.toString() ?? match;
- }
- return match;
- });
-}
-
-/**
- * Given a report field, check if the field is for the report title.
- */
-function isReportFieldOfTypeTitle(reportField: PolicyReportField): boolean {
- return reportField.type === 'formula' && reportField.fieldID === CONST.REPORT_FIELD_TITLE_FIELD_ID;
-}
-
/**
* Checks if thread replies should be displayed
*/
@@ -4792,7 +4856,6 @@ export {
canEditWriteCapability,
hasSmartscanError,
shouldAutoFocusOnKeyPress,
- getReportFieldTitle,
shouldDisplayThreadReplies,
shouldDisableThread,
doesReportBelongToWorkspace,
@@ -4800,6 +4863,8 @@ export {
isReportParticipant,
isValidReport,
isReportFieldOfTypeTitle,
+ isReportFieldDisabled,
+ getAvailableReportFields,
};
export type {
diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts
index 01d157a4cf3c..02c32e089016 100644
--- a/src/libs/SidebarUtils.ts
+++ b/src/libs/SidebarUtils.ts
@@ -373,7 +373,7 @@ function getOptionData({
? Localize.translate(preferredLocale, 'workspace.invite.invited')
: Localize.translate(preferredLocale, 'workspace.invite.removed');
const users = Localize.translate(preferredLocale, targetAccountIDs.length > 1 ? 'workspace.invite.users' : 'workspace.invite.user');
- result.alternateText = `${verb} ${targetAccountIDs.length} ${users}`;
+ result.alternateText = `${lastActorDisplayName} ${verb} ${targetAccountIDs.length} ${users}`.trim();
const roomName = lastAction?.originalMessage?.roomName ?? '';
if (roomName) {
diff --git a/src/libs/WorkspacesUtils.ts b/src/libs/WorkspacesUtils.ts
index f0d93183e480..c41393cb75f7 100644
--- a/src/libs/WorkspacesUtils.ts
+++ b/src/libs/WorkspacesUtils.ts
@@ -13,7 +13,7 @@ type CheckingMethod = () => boolean;
let allReports: OnyxCollection;
-type BrickRoad = ValueOf | undefined;
+type BrickRoad = ValueOf | undefined;
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT,
@@ -57,7 +57,7 @@ const getBrickRoadForPolicy = (report: Report): BrickRoad => {
const reportErrors = OptionsListUtils.getAllReportErrors(report, reportActions);
const doesReportContainErrors = Object.keys(reportErrors ?? {}).length !== 0 ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined;
if (doesReportContainErrors) {
- return CONST.BRICK_ROAD.RBR;
+ return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
}
// To determine if the report requires attention from the current user, we need to load the parent report action
@@ -68,7 +68,7 @@ const getBrickRoadForPolicy = (report: Report): BrickRoad => {
}
const reportOption = {...report, isUnread: ReportUtils.isUnread(report), isUnreadWithMention: ReportUtils.isUnreadWithMention(report)};
const shouldShowGreenDotIndicator = ReportUtils.requiresAttentionFromCurrentUser(reportOption, itemParentReportAction);
- return shouldShowGreenDotIndicator ? CONST.BRICK_ROAD.GBR : undefined;
+ return shouldShowGreenDotIndicator ? CONST.BRICK_ROAD_INDICATOR_STATUS.INFO : undefined;
};
function hasGlobalWorkspaceSettingsRBR(policies: OnyxCollection, policyMembers: OnyxCollection) {
@@ -96,36 +96,28 @@ function getChatTabBrickRoad(policyID?: string): BrickRoad | undefined {
return undefined;
}
- let brickRoad: BrickRoad | undefined;
+ // If policyID is undefined, then all reports are checked whether they contain any brick road
+ const policyReports = policyID ? Object.values(allReports).filter((report) => report?.policyID === policyID) : Object.values(allReports);
- Object.keys(allReports).forEach((report) => {
- if (brickRoad === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR) {
- return;
- }
+ let hasChatTabGBR = false;
- if (policyID && policyID !== allReports?.[report]?.policyID) {
- return;
+ const hasChatTabRBR = policyReports.some((report) => {
+ const brickRoad = report ? getBrickRoadForPolicy(report) : undefined;
+ if (!hasChatTabGBR && brickRoad === CONST.BRICK_ROAD_INDICATOR_STATUS.INFO) {
+ hasChatTabGBR = true;
}
+ return brickRoad === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
+ });
- const policyReport = allReports ? allReports[report] : null;
-
- if (!policyReport) {
- return;
- }
-
- const workspaceBrickRoad = getBrickRoadForPolicy(policyReport);
-
- if (workspaceBrickRoad === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR) {
- brickRoad = CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
- return;
- }
+ if (hasChatTabRBR) {
+ return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
+ }
- if (!brickRoad && workspaceBrickRoad) {
- brickRoad = workspaceBrickRoad;
- }
- });
+ if (hasChatTabGBR) {
+ return CONST.BRICK_ROAD_INDICATOR_STATUS.INFO;
+ }
- return brickRoad;
+ return undefined;
}
function checkIfWorkspaceSettingsTabHasRBR(policyID?: string) {
@@ -152,25 +144,22 @@ function getWorkspacesBrickRoads(): Record {
// The key in this map is the workspace id
const workspacesBrickRoadsMap: Record = {};
- const cleanPolicies = Object.fromEntries(Object.entries(allPolicies ?? {}).filter(([, policy]) => !!policy));
-
- Object.values(cleanPolicies).forEach((policy) => {
+ Object.values(allPolicies ?? {}).forEach((policy) => {
if (!policy) {
return;
}
if (hasWorkspaceSettingsRBR(policy)) {
- workspacesBrickRoadsMap[policy.id] = CONST.BRICK_ROAD.RBR;
+ workspacesBrickRoadsMap[policy.id] = CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
}
});
- Object.keys(allReports).forEach((report) => {
- const policyID = allReports?.[report]?.policyID ?? CONST.POLICY.EMPTY;
- const policyReport = allReports ? allReports[report] : null;
- if (!policyReport || workspacesBrickRoadsMap[policyID] === CONST.BRICK_ROAD.RBR) {
+ Object.values(allReports).forEach((report) => {
+ const policyID = report?.policyID ?? CONST.POLICY.EMPTY;
+ if (!report || workspacesBrickRoadsMap[policyID] === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR) {
return;
}
- const workspaceBrickRoad = getBrickRoadForPolicy(policyReport);
+ const workspaceBrickRoad = getBrickRoadForPolicy(report);
if (!workspaceBrickRoad && !!workspacesBrickRoadsMap[policyID]) {
return;
@@ -192,20 +181,13 @@ function getWorkspacesUnreadStatuses(): Record {
const workspacesUnreadStatuses: Record = {};
- Object.keys(allReports).forEach((report) => {
- const policyID = allReports?.[report]?.policyID;
- const policyReport = allReports ? allReports[report] : null;
- if (!policyID || !policyReport) {
+ Object.values(allReports).forEach((report) => {
+ const policyID = report?.policyID;
+ if (!policyID || workspacesUnreadStatuses[policyID]) {
return;
}
- const unreadStatus = ReportUtils.isUnread(policyReport);
-
- if (unreadStatus) {
- workspacesUnreadStatuses[policyID] = true;
- } else {
- workspacesUnreadStatuses[policyID] = false;
- }
+ workspacesUnreadStatuses[policyID] = ReportUtils.isUnread(report);
});
return workspacesUnreadStatuses;
diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js
index 5e7396e5cd8f..f2bdb097497e 100644
--- a/src/libs/actions/IOU.js
+++ b/src/libs/actions/IOU.js
@@ -349,7 +349,7 @@ function getOutstandingChildRequest(policy, needsToBeManuallySubmitted) {
* @param {Array} optimisticPolicyRecentlyUsedCategories
* @param {Array} optimisticPolicyRecentlyUsedTags
* @param {boolean} isNewChatReport
- * @param {boolean} isNewIOUReport
+ * @param {boolean} shouldCreateNewMoneyRequestReport
* @param {Object} policy - May be undefined, an empty object, or an object matching the Policy type (src/types/onyx/Policy.ts)
* @param {Array} policyTags
* @param {Array} policyCategories
@@ -368,7 +368,7 @@ function buildOnyxDataForMoneyRequest(
optimisticPolicyRecentlyUsedCategories,
optimisticPolicyRecentlyUsedTags,
isNewChatReport,
- isNewIOUReport,
+ shouldCreateNewMoneyRequestReport,
policy,
policyTags,
policyCategories,
@@ -391,14 +391,14 @@ function buildOnyxDataForMoneyRequest(
},
},
{
- onyxMethod: isNewIOUReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
+ onyxMethod: shouldCreateNewMoneyRequestReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`,
value: {
...iouReport,
lastMessageText: iouAction.message[0].text,
lastMessageHtml: iouAction.message[0].html,
pendingFields: {
- ...(isNewIOUReport ? {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : {preview: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}),
+ ...(shouldCreateNewMoneyRequestReport ? {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : {preview: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}),
},
},
},
@@ -416,10 +416,10 @@ function buildOnyxDataForMoneyRequest(
},
},
{
- onyxMethod: isNewIOUReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
+ onyxMethod: shouldCreateNewMoneyRequestReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
value: {
- ...(isNewIOUReport ? {[iouCreatedAction.reportActionID]: iouCreatedAction} : {}),
+ ...(shouldCreateNewMoneyRequestReport ? {[iouCreatedAction.reportActionID]: iouCreatedAction} : {}),
[iouAction.reportActionID]: iouAction,
},
},
@@ -507,7 +507,7 @@ function buildOnyxDataForMoneyRequest(
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
value: {
- ...(isNewIOUReport
+ ...(shouldCreateNewMoneyRequestReport
? {
[iouCreatedAction.reportActionID]: {
pendingAction: null,
@@ -547,7 +547,7 @@ function buildOnyxDataForMoneyRequest(
value: {
pendingFields: null,
errorFields: {
- ...(isNewIOUReport ? {createChat: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage')} : {}),
+ ...(shouldCreateNewMoneyRequestReport ? {createChat: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage')} : {}),
},
},
},
@@ -593,7 +593,7 @@ function buildOnyxDataForMoneyRequest(
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
value: {
- ...(isNewIOUReport
+ ...(shouldCreateNewMoneyRequestReport
? {
[iouCreatedAction.reportActionID]: {
errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt.filename, isScanRequest),
@@ -634,7 +634,7 @@ function buildOnyxDataForMoneyRequest(
* Gathers all the data needed to make a money request. It attempts to find existing reports, iouReports, and receipts. If it doesn't find them, then
* it creates optimistic versions of them and uses those instead
*
- * @param {Object} report
+ * @param {Object} parentChatReport
* @param {Object} participant
* @param {String} comment
* @param {Number} amount
@@ -651,6 +651,7 @@ function buildOnyxDataForMoneyRequest(
* @param {Object} [policy]
* @param {Object} [policyTags]
* @param {Object} [policyCategories]
+ * @param {Number} [moneyRequestReportID] - If user requests money via the report composer on some money request report, we always add a request to that specific report.
* @returns {Object} data
* @returns {String} data.payerEmail
* @returns {Object} data.iouReport
@@ -666,7 +667,7 @@ function buildOnyxDataForMoneyRequest(
* @returns {Object} data.onyxData.failureData
*/
function getMoneyRequestInformation(
- report,
+ parentChatReport,
participant,
comment,
amount,
@@ -683,6 +684,7 @@ function getMoneyRequestInformation(
policy = undefined,
policyTags = undefined,
policyCategories = undefined,
+ moneyRequestReportID = 0,
) {
const payerEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login);
const payerAccountID = Number(participant.accountID);
@@ -690,7 +692,7 @@ function getMoneyRequestInformation(
// STEP 1: Get existing chat report OR build a new optimistic one
let isNewChatReport = false;
- let chatReport = lodashGet(report, 'reportID', null) ? report : null;
+ let chatReport = lodashGet(parentChatReport, 'reportID', null) ? parentChatReport : null;
// If this is a policyExpenseChat, the chatReport must exist and we can get it from Onyx.
// report is null if the flow is initiated from the global create menu. However, participant always stores the reportID if it exists, which is the case for policyExpenseChats
@@ -708,9 +710,15 @@ function getMoneyRequestInformation(
chatReport = ReportUtils.buildOptimisticChatReport([payerAccountID]);
}
- // STEP 2: Get existing IOU report and update its total OR build a new optimistic one
- const isNewIOUReport = !chatReport.iouReportID || ReportUtils.hasIOUWaitingOnCurrentUserBankAccount(chatReport);
- let iouReport = isNewIOUReport ? null : allReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`];
+ // STEP 2: Get the money request report. If the moneyRequestReportID has been provided, we want to add the transaction to this specific report.
+ // If no such reportID has been provided, let's use the chatReport.iouReportID property. In case that is not present, build a new optimistic money request report.
+ let iouReport = null;
+ const shouldCreateNewMoneyRequestReport = !moneyRequestReportID && (!chatReport.iouReportID || ReportUtils.hasIOUWaitingOnCurrentUserBankAccount(chatReport));
+ if (moneyRequestReportID > 0) {
+ iouReport = allReports[`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReportID}`];
+ } else if (!shouldCreateNewMoneyRequestReport) {
+ iouReport = allReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`];
+ }
// Check if the Scheduled Submit is enabled in case of expense report
let needsToBeManuallySubmitted = true;
@@ -719,7 +727,7 @@ function getMoneyRequestInformation(
isFromPaidPolicy = PolicyUtils.isPaidGroupPolicy(policy);
// If the scheduled submit is turned off on the policy, user needs to manually submit the report which is indicated by GBR in LHN
- needsToBeManuallySubmitted = isFromPaidPolicy && !(policy.isHarvestingEnabled || false);
+ needsToBeManuallySubmitted = isFromPaidPolicy && !(lodashGet(policy, 'harvesting.enabled', policy.isHarvestingEnabled) || false);
// If the linked expense report on paid policy is not draft, we need to create a new draft expense report
if (iouReport && isFromPaidPolicy && !ReportUtils.isDraftExpenseReport(iouReport)) {
@@ -807,7 +815,7 @@ function getMoneyRequestInformation(
currentTime,
);
- let reportPreviewAction = isNewIOUReport ? null : ReportActionsUtils.getReportPreviewAction(chatReport.reportID, iouReport.reportID);
+ let reportPreviewAction = shouldCreateNewMoneyRequestReport ? null : ReportActionsUtils.getReportPreviewAction(chatReport.reportID, iouReport.reportID);
if (reportPreviewAction) {
reportPreviewAction = ReportUtils.updateReportPreview(iouReport, reportPreviewAction, false, comment, optimisticTransaction);
} else {
@@ -845,7 +853,7 @@ function getMoneyRequestInformation(
optimisticPolicyRecentlyUsedCategories,
optimisticPolicyRecentlyUsedTags,
isNewChatReport,
- isNewIOUReport,
+ shouldCreateNewMoneyRequestReport,
policy,
policyTags,
policyCategories,
@@ -860,7 +868,7 @@ function getMoneyRequestInformation(
transaction: optimisticTransaction,
iouAction,
createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : 0,
- createdIOUReportActionID: isNewIOUReport ? optimisticCreatedActionForIOU.reportActionID : 0,
+ createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOU.reportActionID : 0,
reportPreviewAction,
onyxData: {
optimisticData,
@@ -892,6 +900,7 @@ function createDistanceRequest(report, participant, comment, created, category,
// If the report is an iou or expense report, we should get the linked chat report to be passed to the getMoneyRequestInformation function
const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
const currentChatReport = isMoneyRequestReport ? ReportUtils.getReport(report.chatReportID) : report;
+ const moneyRequestReportID = isMoneyRequestReport ? report.reportID : 0;
const currentCreated = DateUtils.enrichMoneyRequestTimestamp(created);
const optimisticReceipt = {
@@ -916,6 +925,7 @@ function createDistanceRequest(report, participant, comment, created, category,
policy,
policyTags,
policyCategories,
+ moneyRequestReportID,
);
API.write(
'CreateDistanceRequest',
@@ -1313,6 +1323,7 @@ function requestMoney(
// If the report is iou or expense report, we should get the linked chat report to be passed to the getMoneyRequestInformation function
const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
const currentChatReport = isMoneyRequestReport ? ReportUtils.getReport(report.chatReportID) : report;
+ const moneyRequestReportID = isMoneyRequestReport ? report.reportID : 0;
const currentCreated = DateUtils.enrichMoneyRequestTimestamp(created);
const {payerAccountID, payerEmail, iouReport, chatReport, transaction, iouAction, createdChatReportActionID, createdIOUReportActionID, reportPreviewAction, onyxData} =
getMoneyRequestInformation(
@@ -1333,6 +1344,7 @@ function requestMoney(
policy,
policyTags,
policyCategories,
+ moneyRequestReportID,
);
const activeReportID = isMoneyRequestReport ? report.reportID : chatReport.reportID;
@@ -1389,10 +1401,11 @@ function requestMoney(
* @param {String} category
* @param {String} tag
* @param {String} existingSplitChatReportID - the report ID where the split bill happens, could be a group chat or a workspace chat
+ * @param {Boolean} billable
*
* @return {Object}
*/
-function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag, existingSplitChatReportID = '') {
+function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag, existingSplitChatReportID = '', billable = false) {
const currentUserEmailForIOUSplit = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin);
const participantAccountIDs = _.map(participants, (participant) => Number(participant.accountID));
const existingSplitChatReport =
@@ -1416,6 +1429,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
undefined,
category,
tag,
+ billable,
);
// Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat
@@ -1617,6 +1631,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
undefined,
category,
tag,
+ billable,
);
// STEP 4: Build optimistic reportActions. We need:
@@ -1734,8 +1749,9 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
* @param {String} category
* @param {String} tag
* @param {String} existingSplitChatReportID - Either a group DM or a workspace chat
+ * @param {Boolean} billable
*/
-function splitBill(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag, existingSplitChatReportID = '') {
+function splitBill(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag, existingSplitChatReportID = '', billable = false) {
const {splitData, splits, onyxData} = createSplitsAndOnyxData(
participants,
currentUserLogin,
@@ -1747,6 +1763,7 @@ function splitBill(participants, currentUserLogin, currentUserAccountID, amount,
category,
tag,
existingSplitChatReportID,
+ billable,
);
API.write(
'SplitBill',
@@ -1759,6 +1776,7 @@ function splitBill(participants, currentUserLogin, currentUserAccountID, amount,
category,
merchant,
tag,
+ billable,
transactionID: splitData.transactionID,
reportActionID: splitData.reportActionID,
createdReportActionID: splitData.createdReportActionID,
@@ -1782,9 +1800,10 @@ function splitBill(participants, currentUserLogin, currentUserAccountID, amount,
* @param {String} merchant
* @param {String} category
* @param {String} tag
+ * @param {Boolean} billable
*/
-function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag) {
- const {splitData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag);
+function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag, billable) {
+ const {splitData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, merchant, category, tag, billable);
API.write(
'SplitBillAndOpenReport',
@@ -1797,6 +1816,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccou
comment,
category,
tag,
+ billable,
transactionID: splitData.transactionID,
reportActionID: splitData.reportActionID,
createdReportActionID: splitData.createdReportActionID,
@@ -1821,8 +1841,9 @@ function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccou
* @param {String} tag
* @param {Object} receipt
* @param {String} existingSplitChatReportID - Either a group DM or a workspace chat
+ * @param {Boolean} billable
*/
-function startSplitBill(participants, currentUserLogin, currentUserAccountID, comment, category, tag, receipt, existingSplitChatReportID = '') {
+function startSplitBill(participants, currentUserLogin, currentUserAccountID, comment, category, tag, receipt, existingSplitChatReportID = '', billable = false) {
const currentUserEmailForIOUSplit = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin);
const participantAccountIDs = _.map(participants, (participant) => Number(participant.accountID));
const existingSplitChatReport =
@@ -1850,6 +1871,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co
undefined,
category,
tag,
+ billable,
);
// Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat
@@ -2063,6 +2085,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co
category,
tag,
isFromGroupDM: !existingSplitChatReport,
+ billable,
...(existingSplitChatReport ? {} : {createdReportActionID: splitChatCreatedReportAction.reportActionID}),
},
{optimisticData, successData, failureData},
@@ -3752,6 +3775,15 @@ function navigateToStartStepIfScanFileCannotBeRead(receiptFilename, receiptPath,
FileUtils.readFileAsync(receiptPath, receiptFilename, onSuccess, onFailure);
}
+/**
+ * Save the preferred payment method for a policy
+ * @param {String} policyID
+ * @param {String} paymentMethod
+ */
+function savePreferredPaymentMethod(policyID, paymentMethod) {
+ Onyx.merge(`${ONYXKEYS.NVP_LAST_PAYMENT_METHOD}`, {[policyID]: paymentMethod});
+}
+
export {
setMoneyRequestParticipants,
createDistanceRequest,
@@ -3812,4 +3844,5 @@ export {
getIOUReportID,
editMoneyRequest,
navigateToStartStepIfScanFileCannotBeRead,
+ savePreferredPaymentMethod,
};
diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts
index 028c409ee8fa..b4a7a12ccfca 100644
--- a/src/libs/actions/Report.ts
+++ b/src/libs/actions/Report.ts
@@ -66,7 +66,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Route} from '@src/ROUTES';
import ROUTES from '@src/ROUTES';
-import type {PersonalDetails, PersonalDetailsList, ReportActionReactions, ReportMetadata, ReportUserIsTyping} from '@src/types/onyx';
+import type {PersonalDetails, PersonalDetailsList, PolicyReportField, RecentlyUsedReportFields, ReportActionReactions, ReportMetadata, ReportUserIsTyping} from '@src/types/onyx';
import type {Decision, OriginalMessageIOU} from '@src/types/onyx/OriginalMessage';
import type {NotificationPreference, WriteCapability} from '@src/types/onyx/Report';
import type Report from '@src/types/onyx/Report';
@@ -189,6 +189,12 @@ Onyx.connect({
},
});
+let allRecentlyUsedReportFields: OnyxEntry = {};
+Onyx.connect({
+ key: ONYXKEYS.RECENTLY_USED_REPORT_FIELDS,
+ callback: (val) => (allRecentlyUsedReportFields = val),
+});
+
/** Get the private pusher channel name for a Report. */
function getReportChannelName(reportID: string): string {
return `${CONST.PUSHER.PRIVATE_REPORT_CHANNEL_PREFIX}${reportID}${CONFIG.PUSHER.SUFFIX}`;
@@ -1477,6 +1483,137 @@ function toggleSubscribeToChildReport(childReportID = '0', parentReportAction: P
}
}
+function updateReportName(reportID: string, value: string, previousValue: string) {
+ const optimisticData: OnyxUpdate[] = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ reportName: value,
+ pendingFields: {
+ reportName: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ },
+ },
+ ];
+ const failureData: OnyxUpdate[] = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ reportName: previousValue,
+ pendingFields: {
+ reportName: null,
+ },
+ errorFields: {
+ reportName: ErrorUtils.getMicroSecondOnyxError('report.genericUpdateReporNameEditFailureMessage'),
+ },
+ },
+ },
+ ];
+
+ const successData: OnyxUpdate[] = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ pendingFields: {
+ reportName: null,
+ },
+ errorFields: {
+ reportName: null,
+ },
+ },
+ },
+ ];
+
+ const parameters = {
+ reportID,
+ reportName: value,
+ };
+
+ API.write(WRITE_COMMANDS.SET_REPORT_NAME, parameters, {optimisticData, failureData, successData});
+}
+
+function updateReportField(reportID: string, reportField: PolicyReportField, previousReportField: PolicyReportField) {
+ const recentlyUsedValues = allRecentlyUsedReportFields?.[reportField.fieldID] ?? [];
+
+ const optimisticData: OnyxUpdate[] = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ reportFields: {
+ [reportField.fieldID]: reportField,
+ },
+ pendingFields: {
+ [reportField.fieldID]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ },
+ },
+ ];
+
+ if (reportField.type === 'dropdown') {
+ optimisticData.push({
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: ONYXKEYS.RECENTLY_USED_REPORT_FIELDS,
+ value: {
+ [reportField.fieldID]: [...new Set([...recentlyUsedValues, reportField.value])],
+ },
+ });
+ }
+
+ const failureData: OnyxUpdate[] = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ reportFields: {
+ [reportField.fieldID]: previousReportField,
+ },
+ pendingFields: {
+ [reportField.fieldID]: null,
+ },
+ errorFields: {
+ [reportField.fieldID]: ErrorUtils.getMicroSecondOnyxError('report.genericUpdateReportFieldFailureMessage'),
+ },
+ },
+ },
+ ];
+
+ if (reportField.type === 'dropdown') {
+ failureData.push({
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: ONYXKEYS.RECENTLY_USED_REPORT_FIELDS,
+ value: {
+ [reportField.fieldID]: recentlyUsedValues,
+ },
+ });
+ }
+
+ const successData: OnyxUpdate[] = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ pendingFields: {
+ [reportField.fieldID]: null,
+ },
+ errorFields: {
+ [reportField.fieldID]: null,
+ },
+ },
+ },
+ ];
+
+ const parameters = {
+ reportID,
+ reportFields: JSON.stringify({[reportField.fieldID]: reportField}),
+ };
+
+ API.write(WRITE_COMMANDS.SET_REPORT_FIELD, parameters, {optimisticData, failureData, successData});
+}
+
function updateWelcomeMessage(reportID: string, previousValue: string, newValue: string) {
// No change needed, navigate back
if (previousValue === newValue) {
@@ -1830,7 +1967,7 @@ function showReportActionNotification(reportID: string, reportAction: ReportActi
Modal.close(() => {
const policyID = lastVisitedPath && extractPolicyIDFromPath(lastVisitedPath);
const policyMembersAccountIDs = policyID ? getPolicyMemberAccountIDs(policyID) : [];
- const reportBelongsToWorkspace = policyID ? doesReportBelongToWorkspace(report, policyMembersAccountIDs, policyID) : true;
+ const reportBelongsToWorkspace = policyID ? doesReportBelongToWorkspace(report, policyMembersAccountIDs, policyID) : false;
if (!reportBelongsToWorkspace) {
Navigation.navigateWithSwitchPolicyID({policyID: undefined, route: ROUTES.HOME});
}
@@ -2745,5 +2882,7 @@ export {
getDraftPrivateNote,
updateLastVisitTime,
clearNewRoomFormError,
+ updateReportField,
+ updateReportName,
resolveActionableMentionWhisper,
};
diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts
index a7aab98f02c6..60c05d0cb677 100644
--- a/src/libs/actions/Task.ts
+++ b/src/libs/actions/Task.ts
@@ -729,7 +729,6 @@ function deleteTask(taskReportID: string, taskTitle: string, originalStateNum: n
],
errors: undefined,
linkMetadata: [],
- reportActionID: '',
};
const optimisticReportActions = {
[parentReportAction.reportActionID]: optimisticReportAction,
@@ -751,8 +750,7 @@ function deleteTask(taskReportID: string, taskTitle: string, originalStateNum: n
key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport?.reportID}`,
value: {
lastMessageText: ReportActionsUtils.getLastVisibleMessage(parentReport?.reportID ?? '', optimisticReportActions as OnyxTypes.ReportActions).lastMessageText ?? '',
- lastVisibleActionCreated:
- ReportActionsUtils.getLastVisibleAction(parentReport?.reportID ?? '', optimisticReportActions as OnyxTypes.ReportActions)?.childLastVisibleActionCreated ?? 'created',
+ lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(parentReport?.reportID ?? '', optimisticReportActions as OnyxTypes.ReportActions)?.created,
},
},
{
diff --git a/src/pages/DetailsPage.js b/src/pages/DetailsPage.js
index 99db8b420d33..cdf5dc5a0502 100755
--- a/src/pages/DetailsPage.js
+++ b/src/pages/DetailsPage.js
@@ -136,8 +136,8 @@ function DetailsPage(props) {
{({show}) => (
void;
+ onSubmit: (form: OnyxFormValuesFields) => void;
};
-function EditReportFieldDatePage({fieldName, onSubmit, fieldValue, fieldID}: EditReportFieldDatePageProps) {
+function EditReportFieldDatePage({fieldName, isRequired, onSubmit, fieldValue, fieldID}: EditReportFieldDatePageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const inputRef = useRef(null);
const validate = useCallback(
- (values: OnyxFormValuesFields) => {
+ (value: OnyxFormValuesFields) => {
const errors: Errors = {};
- const value = values[fieldID];
- if (typeof value === 'string' && value.trim() === '') {
+ if (isRequired && value[fieldID].trim() === '') {
errors[fieldID] = 'common.error.fieldRequired';
}
return errors;
},
- [fieldID],
+ [fieldID, isRequired],
);
return (
inputRef.current?.focus()}
+ onEntryTransitionEnd={() => {
+ inputRef.current?.focus();
+ }}
testID={EditReportFieldDatePage.displayName}
>
void;
+ onSubmit: (form: Record) => void;
+};
+
+type EditReportFieldDropdownPageOnyxProps = {
+ recentlyUsedReportFields: OnyxEntry;
};
-function EditReportFieldDropdownPage({fieldName, onSubmit, fieldValue, fieldOptions}: EditReportFieldDropdownPageProps) {
+type EditReportFieldDropdownPageProps = EditReportFieldDropdownPageComponentProps & EditReportFieldDropdownPageOnyxProps;
+
+function EditReportFieldDropdownPage({fieldName, onSubmit, fieldID, fieldValue, fieldOptions, recentlyUsedReportFields}: EditReportFieldDropdownPageProps) {
const [searchValue, setSearchValue] = useState('');
const styles = useThemeStyles();
const {getSafeAreaMargins} = useStyleUtils();
const {translate} = useLocalize();
+ const recentlyUsedOptions = useMemo(() => recentlyUsedReportFields?.[fieldID] ?? [], [recentlyUsedReportFields, fieldID]);
const sections = useMemo(() => {
- const filteredOptions = fieldOptions.filter((option) => option.toLowerCase().includes(searchValue.toLowerCase()));
+ const filteredRecentOptions = recentlyUsedOptions.filter((option) => option.toLowerCase().includes(searchValue.toLowerCase()));
+ const filteredRestOfOptions = fieldOptions.filter((option) => !filteredRecentOptions.includes(option) && option.toLowerCase().includes(searchValue.toLowerCase()));
+
return [
{
title: translate('common.recents'),
shouldShow: true,
- data: [],
+ data: filteredRecentOptions.map((option) => ({
+ text: option,
+ keyForList: option,
+ searchText: option,
+ tooltipText: option,
+ })),
},
{
title: translate('common.all'),
shouldShow: true,
- data: filteredOptions.map((option) => ({
+ data: filteredRestOfOptions.map((option) => ({
text: option,
keyForList: option,
searchText: option,
@@ -45,7 +70,7 @@ function EditReportFieldDropdownPage({fieldName, onSubmit, fieldValue, fieldOpti
})),
},
];
- }, [fieldOptions, searchValue, translate]);
+ }, [fieldOptions, recentlyUsedOptions, searchValue, translate]);
return (
) => onSubmit({[fieldID]: option.text})}
onChangeText={setSearchValue}
highlightSelectedOptions
isRowMultilineSupported
@@ -79,4 +104,8 @@ function EditReportFieldDropdownPage({fieldName, onSubmit, fieldValue, fieldOpti
EditReportFieldDropdownPage.displayName = 'EditReportFieldDropdownPage';
-export default EditReportFieldDropdownPage;
+export default withOnyx({
+ recentlyUsedReportFields: {
+ key: () => ONYXKEYS.RECENTLY_USED_REPORT_FIELDS,
+ },
+})(EditReportFieldDropdownPage);
diff --git a/src/pages/EditReportFieldPage.tsx b/src/pages/EditReportFieldPage.tsx
index d74582708995..5bb53ef9122e 100644
--- a/src/pages/EditReportFieldPage.tsx
+++ b/src/pages/EditReportFieldPage.tsx
@@ -1,10 +1,15 @@
-import React, {useEffect} from 'react';
+import Str from 'expensify-common/lib/str';
+import React from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
+import type {OnyxFormValuesFields} from '@components/Form/types';
import ScreenWrapper from '@components/ScreenWrapper';
+import Navigation from '@libs/Navigation/Navigation';
+import * as ReportUtils from '@libs/ReportUtils';
+import * as ReportActions from '@src/libs/actions/Report';
import ONYXKEYS from '@src/ONYXKEYS';
-import type {PolicyReportFields, Report} from '@src/types/onyx';
+import type {Policy, PolicyReportFields, Report} from '@src/types/onyx';
import EditReportFieldDatePage from './EditReportFieldDatePage';
import EditReportFieldDropdownPage from './EditReportFieldDropdownPage';
import EditReportFieldTextPage from './EditReportFieldTextPage';
@@ -15,6 +20,9 @@ type EditReportFieldPageOnyxProps = {
/** Policy report fields */
policyReportFields: OnyxEntry;
+
+ /** Policy to which the report belongs to */
+ policy: OnyxEntry;
};
type EditReportFieldPageProps = EditReportFieldPageOnyxProps & {
@@ -34,61 +42,77 @@ type EditReportFieldPageProps = EditReportFieldPageOnyxProps & {
};
};
-function EditReportFieldPage({route, report, policyReportFields}: EditReportFieldPageProps) {
- const policyReportField = policyReportFields?.[route.params.fieldID];
- const reportFieldValue = report?.reportFields?.[policyReportField?.fieldID ?? ''];
-
- // Decides whether to allow or disallow editing a money request
- useEffect(() => {}, []);
-
- if (policyReportField) {
- if (policyReportField.type === 'text' || policyReportField.type === 'formula') {
- return (
- {}}
- />
- );
- }
+function EditReportFieldPage({route, policy, report, policyReportFields}: EditReportFieldPageProps) {
+ const reportField = report?.reportFields?.[route.params.fieldID] ?? policyReportFields?.[route.params.fieldID];
+ const isDisabled = ReportUtils.isReportFieldDisabled(report, reportField ?? null, policy);
- if (policyReportField.type === 'date') {
- return (
- {}}
+ if (!reportField || !report || isDisabled) {
+ return (
+
+ {}}
+ onLinkPress={() => {}}
/>
- );
- }
+
+ );
+ }
- if (policyReportField.type === 'dropdown') {
- return (
- {}}
- />
- );
+ const isReportFieldTitle = ReportUtils.isReportFieldOfTypeTitle(reportField);
+
+ const handleReportFieldChange = (form: OnyxFormValuesFields) => {
+ const value = form[reportField.fieldID] || '';
+ if (isReportFieldTitle) {
+ ReportActions.updateReportName(report.reportID, value, report.reportName ?? '');
+ } else {
+ ReportActions.updateReportField(report.reportID, {...reportField, value}, reportField);
}
+
+ Navigation.dismissModal(report?.reportID);
+ };
+
+ const fieldValue = isReportFieldTitle ? report.reportName ?? '' : reportField.value ?? reportField.defaultValue;
+
+ if (reportField.type === 'text' || isReportFieldTitle) {
+ return (
+
+ );
+ }
+
+ if (reportField.type === 'date') {
+ return (
+
+ );
}
- return (
-
- {}}
- onLinkPress={() => {}}
+ if (reportField.type === 'dropdown') {
+ return (
+
-
- );
+ );
+ }
}
EditReportFieldPage.displayName = 'EditReportFieldPage';
@@ -100,4 +124,7 @@ export default withOnyx(
policyReportFields: {
key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS}${route.params.policyID}`,
},
+ policy: {
+ key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID}`,
+ },
})(EditReportFieldPage);
diff --git a/src/pages/EditReportFieldTextPage.tsx b/src/pages/EditReportFieldTextPage.tsx
index 733bfd6e5fee..ea9d2d3bed6d 100644
--- a/src/pages/EditReportFieldTextPage.tsx
+++ b/src/pages/EditReportFieldTextPage.tsx
@@ -23,38 +23,42 @@ type EditReportFieldTextPageProps = {
/** ID of the policy report field */
fieldID: string;
+ /** Flag to indicate if the field can be left blank */
+ isRequired: boolean;
+
/** Callback to fire when the Save button is pressed */
- onSubmit: () => void;
+ onSubmit: (form: OnyxFormValuesFields) => void;
};
-function EditReportFieldTextPage({fieldName, onSubmit, fieldValue, fieldID}: EditReportFieldTextPageProps) {
+function EditReportFieldTextPage({fieldName, onSubmit, fieldValue, isRequired, fieldID}: EditReportFieldTextPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const inputRef = useRef(null);
const validate = useCallback(
- (values: OnyxFormValuesFields) => {
+ (values: OnyxFormValuesFields) => {
const errors: Errors = {};
- const value = values[fieldID];
- if (typeof value === 'string' && value.trim() === '') {
+ if (isRequired && values[fieldID].trim() === '') {
errors[fieldID] = 'common.error.fieldRequired';
}
return errors;
},
- [fieldID],
+ [fieldID, isRequired],
);
return (
inputRef.current?.focus()}
+ onEntryTransitionEnd={() => {
+ inputRef.current?.focus();
+ }}
testID={EditReportFieldTextPage.displayName}
>
{
- Report.searchInServer(text);
- setSearchTerm(text);
- }, []);
-
const {inputCallbackRef} = useAutoFocusInput();
return (
diff --git a/src/pages/ReportAvatar.tsx b/src/pages/ReportAvatar.tsx
index c61a0a748f7d..29142294084c 100644
--- a/src/pages/ReportAvatar.tsx
+++ b/src/pages/ReportAvatar.tsx
@@ -35,6 +35,7 @@ function ReportAvatar({report = {} as Report, policies, isLoadingApp = true}: Re
Navigation.goBack(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? ''));
}}
isWorkspaceAvatar
+ maybeIcon
originalFileName={policy?.originalFileName ?? policyName}
shouldShowNotFoundPage={!report?.reportID && !isLoadingApp}
isLoading={(!report?.reportID || !policy?.id) && !!isLoadingApp}
diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js
index 3e682d592370..513ccbbe307c 100644
--- a/src/pages/ReportDetailsPage.js
+++ b/src/pages/ReportDetailsPage.js
@@ -165,7 +165,7 @@ function ReportDetailsPage(props) {
return ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participants, props.personalDetails), hasMultipleParticipants);
}, [participants, props.personalDetails]);
- const icons = useMemo(() => ReportUtils.getIcons(props.report, props.personalDetails, props.policies), [props.report, props.personalDetails, props.policies]);
+ const icons = useMemo(() => ReportUtils.getIcons(props.report, props.personalDetails, null, '', -1, policy), [props.report, props.personalDetails, policy]);
const chatRoomSubtitleText = chatRoomSubtitle ? (
(undefined);
- const [searchTerm, setSearchTerm] = useState();
+ const [selectedOption, setSelectedOption] = useState();
+ const [searchTerm, setSearchTerm] = useState('');
const {inputCallbackRef} = useAutoFocusInput();
const {translate} = useLocalize();
const {activeWorkspaceID, setActiveWorkspaceID} = useActiveWorkspace();
@@ -70,12 +70,12 @@ function WorkspaceSwitcherPage({policies}: WorkspaceSwitcherPageProps) {
return brickRoadsForPolicies[policyId];
}
- if (Object.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.RBR)) {
- return CONST.BRICK_ROAD.RBR;
+ if (Object.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR)) {
+ return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
}
- if (Object.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.GBR)) {
- return CONST.BRICK_ROAD.GBR;
+ if (Object.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD_INDICATOR_STATUS.INFO)) {
+ return CONST.BRICK_ROAD_INDICATOR_STATUS.INFO;
}
return undefined;
@@ -161,6 +161,7 @@ function WorkspaceSwitcherPage({policies}: WorkspaceSwitcherPageProps) {
const everythingSection = useMemo(() => {
const option = {
+ reportID: '',
text: CONST.WORKSPACE_SWITCHER.NAME,
icons: [
{
@@ -185,7 +186,7 @@ function WorkspaceSwitcherPage({policies}: WorkspaceSwitcherPageProps) {