diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx
index cfbce4358eb5..3c8c79422965 100644
--- a/src/components/ReportWelcomeText.tsx
+++ b/src/components/ReportWelcomeText.tsx
@@ -40,10 +40,11 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
const isSelfDM = ReportUtils.isSelfDM(report);
const isInvoiceRoom = ReportUtils.isInvoiceRoom(report);
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
- const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom);
+ const isSystemChat = ReportUtils.isSystemChat(report);
+ const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat);
const participantAccountIDs = Object.keys(report?.participants ?? {})
.map(Number)
- .filter((accountID) => accountID !== session?.accountID || !isOneOnOneChat);
+ .filter((accountID) => accountID !== session?.accountID || (!isOneOnOneChat && !isSystemChat));
const isMultipleParticipant = participantAccountIDs.length > 1;
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails), isMultipleParticipant);
const isUserPolicyAdmin = PolicyUtils.isPolicyAdmin(policy);
@@ -77,8 +78,12 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
return translate('reportActionsView.yourSpace');
}
+ if (isSystemChat) {
+ return reportName;
+ }
+
return translate('reportActionsView.sayHello');
- }, [isChatRoom, isInvoiceRoom, isSelfDM, translate, reportName]);
+ }, [isChatRoom, isInvoiceRoom, isSelfDM, isSystemChat, translate, reportName]);
return (
<>
@@ -144,6 +149,11 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
{translate('reportActionsView.beginningOfChatHistorySelfDM')}
)}
+ {isSystemChat && (
+
+ {translate('reportActionsView.beginningOfChatHistorySystemDM')}
+
+ )}
{isDefault && (
{translate('reportActionsView.beginningOfChatHistory')}
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 3ed590a4fe0c..332e64c8e2ff 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -519,6 +519,7 @@ export default {
beginningOfChatHistoryPolicyExpenseChatPartTwo: ' and ',
beginningOfChatHistoryPolicyExpenseChatPartThree: ' starts here! š This is the place to chat, submit expenses and settle up.',
beginningOfChatHistorySelfDM: 'This is your personal space. Use it for notes, tasks, drafts, and reminders.',
+ beginningOfChatHistorySystemDM: "Welcome! Let's get you set up.",
chatWithAccountManager: 'Chat with your account manager here',
sayHello: 'Say hello!',
yourSpace: 'Your space',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 8e1827647abb..7029d23e3a66 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -512,6 +512,7 @@ export default {
beginningOfChatHistoryPolicyExpenseChatPartTwo: ' y ',
beginningOfChatHistoryPolicyExpenseChatPartThree: ' empieza aquĆ! š Este es el lugar donde chatear y presentar o pagar gastos.',
beginningOfChatHistorySelfDM: 'Este es tu espacio personal. Ćsalo para notas, tareas, borradores y recordatorios.',
+ beginningOfChatHistorySystemDM: 'Ā”Bienvenido! Vamos a configurar tu cuenta.',
chatWithAccountManager: 'Chatea con tu gestor de cuenta aquĆ',
sayHello: 'Ā”Saluda!',
yourSpace: 'Tu espacio',
diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts
index f321c10c686e..13c1527c6dc2 100644
--- a/src/libs/OptionsListUtils.ts
+++ b/src/libs/OptionsListUtils.ts
@@ -1867,7 +1867,7 @@ function getOptions(
allPersonalDetailsOptions = lodashOrderBy(allPersonalDetailsOptions, [(personalDetail) => personalDetail.text?.toLowerCase()], 'asc');
}
- const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}];
+ const optionsToExclude: Option[] = [];
// If we're including selected options from the search results, we only want to exclude them if the search input is empty
// This is because on certain pages, we show the selected options at the top when the search input is empty
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 690cfdafd92d..db1e9e19858c 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -1200,6 +1200,8 @@ function findLastAccessedReport(
}
if (isFirstTimeNewExpensifyUser) {
+ // Filter out the systemChat report from the reports list, as we don't want to drop the user into that report over Concierge when they first log in
+ sortedReports = sortedReports.filter((report) => !isSystemChat(report)) ?? [];
if (sortedReports.length === 1) {
return sortedReports[0];
}
@@ -1207,6 +1209,13 @@ function findLastAccessedReport(
return adminReport ?? sortedReports.find((report) => !isConciergeChatReport(report)) ?? null;
}
+ // If we only have two reports and one of them is the system chat, filter it out so we don't
+ // overwrite showing the concierge chat
+ const hasSystemChat = sortedReports.find((report) => isSystemChat(report)) ?? false;
+ if (sortedReports.length === 2 && hasSystemChat) {
+ sortedReports = sortedReports.filter((report) => !isSystemChat(report)) ?? [];
+ }
+
return adminReport ?? sortedReports.at(-1) ?? null;
}
@@ -2052,6 +2061,10 @@ function getIcons(
return getIconsForParticipants([currentUserAccountID ?? 0], personalDetails);
}
+ if (isSystemChat(report)) {
+ return getIconsForParticipants([CONST.ACCOUNT_ID.NOTIFICATIONS ?? 0], personalDetails);
+ }
+
if (isGroupChat(report)) {
const groupChatIcon = {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
@@ -3229,6 +3242,10 @@ function getReportName(report: OnyxEntry, policy: OnyxEntry = nu
formattedName = getDisplayNameForParticipant(currentUserAccountID, undefined, undefined, true);
}
+ if (isInvoiceRoom(report)) {
+ formattedName = getInvoicesChatName(report);
+ }
+
if (formattedName) {
return formattedName;
}
@@ -5200,11 +5217,13 @@ function shouldReportBeInOptionList({
!isMoneyRequestReport(report) &&
!isTaskReport(report) &&
!isSelfDM(report) &&
+ !isSystemChat(report) &&
!isGroupChat(report) &&
!isInvoiceRoom(report))
) {
return false;
}
+
if (!canAccessReport(report, policies, betas)) {
return false;
}
@@ -5267,7 +5286,7 @@ function shouldReportBeInOptionList({
}
// Hide chats between two users that haven't been commented on from the LNH
- if (excludeEmptyChats && isEmptyChat && isChatReport(report) && !isChatRoom(report) && !isPolicyExpenseChat(report) && !isGroupChat(report) && canHideReport) {
+ if (excludeEmptyChats && isEmptyChat && isChatReport(report) && !isChatRoom(report) && !isPolicyExpenseChat(report) && !isSystemChat(report) && !isGroupChat(report) && canHideReport) {
return false;
}
@@ -5599,7 +5618,7 @@ function isGroupChatAdmin(report: OnyxEntry, accountID: number) {
*/
function getMoneyRequestOptions(report: OnyxEntry, policy: OnyxEntry, reportParticipants: number[], filterDeprecatedTypes = false): IOUType[] {
// In any thread or task report, we do not allow any new expenses yet
- if (isChatThread(report) || isTaskReport(report) || isInvoiceReport(report)) {
+ if (isChatThread(report) || isTaskReport(report) || isInvoiceReport(report) || isSystemChat(report)) {
return [];
}
@@ -6614,7 +6633,7 @@ function canJoinChat(report: OnyxEntry, parentReportAction: OnyxEntry error?.[0] !== 'report.genericSmartscanFailureMessage');
- const shouldOverrideHidden = hasErrorsOtherThanFailedReceipt || isFocused || report.isPinned;
+ const isSystemChat = ReportUtils.isSystemChat(report);
+ const shouldOverrideHidden = hasErrorsOtherThanFailedReceipt || isFocused || isSystemChat || report.isPinned;
if (isHidden && !shouldOverrideHidden) {
return false;
}
diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx
index 1436aba4e3ce..02f97397e4cd 100644
--- a/src/pages/ReportDetailsPage.tsx
+++ b/src/pages/ReportDetailsPage.tsx
@@ -88,15 +88,17 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
// eslint-disable-next-line react-hooks/exhaustive-deps -- policy is a dependency because `getChatRoomSubtitle` calls `getPolicyName` which in turn retrieves the value from the `policy` value stored in Onyx
const chatRoomSubtitle = useMemo(() => ReportUtils.getChatRoomSubtitle(report), [report, policy]);
const parentNavigationSubtitleData = ReportUtils.getParentNavigationSubtitle(report);
+ const isSystemChat = useMemo(() => ReportUtils.isSystemChat(report), [report]);
const isGroupChat = useMemo(() => ReportUtils.isGroupChat(report), [report]);
const isThread = useMemo(() => ReportUtils.isThread(report), [report]);
const participants = useMemo(() => {
- if (isGroupChat) {
- return ReportUtils.getParticipantAccountIDs(report.reportID ?? '');
+ if (isGroupChat || isSystemChat) {
+ // Filter out the current user from the particpants of the systemChat
+ return ReportUtils.getParticipantAccountIDs(report.reportID ?? '').filter((accountID) => accountID !== session?.accountID && isSystemChat);
}
return ReportUtils.getVisibleChatMemberAccountIDs(report.reportID ?? '');
- }, [report, isGroupChat]);
+ }, [report, session, isGroupChat, isSystemChat]);
// Get the active chat members by filtering out the pending members with delete action
const activeChatMembers = participants.flatMap((accountID) => {
@@ -148,7 +150,8 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
(isDefaultRoom && isChatThread && isPolicyEmployee) ||
(!isUserCreatedPolicyRoom && participants.length) ||
(isUserCreatedPolicyRoom && (isPolicyEmployee || (isChatThread && !ReportUtils.isPublicRoom(report))))) &&
- !ReportUtils.isConciergeChatReport(report)
+ !ReportUtils.isConciergeChatReport(report) &&
+ !isSystemChat
) {
items.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.MEMBERS,
@@ -222,6 +225,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
return items;
}, [
isSelfDM,
+ isSystemChat,
isArchivedRoom,
isGroupChat,
isDefaultRoom,
diff --git a/src/pages/home/HeaderView.tsx b/src/pages/home/HeaderView.tsx
index b16fb86f9b21..70597a25ceb3 100644
--- a/src/pages/home/HeaderView.tsx
+++ b/src/pages/home/HeaderView.tsx
@@ -90,11 +90,12 @@ function HeaderView({
const isSelfDM = ReportUtils.isSelfDM(report);
const isGroupChat = ReportUtils.isGroupChat(report) || ReportUtils.isDeprecatedGroupDM(report);
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
+ const isSystemChat = ReportUtils.isSystemChat(report);
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
const participants = Object.keys(report?.participants ?? {})
.map(Number)
- .filter((accountID) => accountID !== session?.accountID || !isOneOnOneChat)
+ .filter((accountID) => accountID !== session?.accountID || (!isOneOnOneChat && !isSystemChat))
.slice(0, 5);
const isMultipleParticipant = participants.length > 1;