diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index 97e611f0bafe..12708a7acbfa 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -1,29 +1,25 @@ import React, {useMemo} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import {getPolicy} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import SidebarUtils from '@libs/SidebarUtils'; import CONST from '@src/CONST'; import type {IOUType} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {PersonalDetailsList, Policy, Report} from '@src/types/onyx'; +import type {Policy, Report} from '@src/types/onyx'; import {PressableWithoutFeedback} from './Pressable'; import RenderHTML from './RenderHTML'; import Text from './Text'; import UserDetailsTooltip from './UserDetailsTooltip'; -type ReportWelcomeTextOnyxProps = { - /** All of the personal details for everyone */ - personalDetails: OnyxEntry; -}; - -type ReportWelcomeTextProps = ReportWelcomeTextOnyxProps & { +type ReportWelcomeTextProps = { /** The report currently being looked at */ report: OnyxEntry; @@ -31,29 +27,39 @@ type ReportWelcomeTextProps = ReportWelcomeTextOnyxProps & { policy: OnyxEntry; }; -function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextProps) { +function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID || -1}`); + const isArchivedRoom = ReportUtils.isArchivedRoom(report, reportNameValuePairs); const isChatRoom = ReportUtils.isChatRoom(report); const isSelfDM = ReportUtils.isSelfDM(report); const isInvoiceRoom = ReportUtils.isInvoiceRoom(report); const isSystemChat = ReportUtils.isSystemChat(report); const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat); - const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); + const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, undefined, undefined, true); const isMultipleParticipant = participantAccountIDs.length > 1; const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails), isMultipleParticipant); const welcomeMessage = SidebarUtils.getWelcomeMessage(report, policy); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); - const additionalText = moneyRequestOptions - .filter( - (item): item is Exclude => - item !== CONST.IOU.TYPE.INVOICE, - ) - .map((item) => translate(`reportActionsView.iouTypes.${item}`)) + const filteredOptions = moneyRequestOptions.filter( + (item): item is Exclude => + item !== CONST.IOU.TYPE.INVOICE, + ); + const additionalText = filteredOptions + .map((item, index) => `${index === filteredOptions.length - 1 ? `${translate('common.or')} ` : ''}${translate(`reportActionsView.iouTypes.${item}`)}`) .join(', '); const canEditPolicyDescription = ReportUtils.canEditPolicyDescription(policy); const reportName = ReportUtils.getReportName(report); + const shouldShowUsePlusButtonText = + (moneyRequestOptions.includes(CONST.IOU.TYPE.PAY) || + moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT) || + moneyRequestOptions.includes(CONST.IOU.TYPE.TRACK) || + moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT)) && + !isPolicyExpenseChat; const navigateToReport = () => { if (!report?.reportID) { @@ -112,7 +118,38 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP {welcomeMessage.phrase3} ))} + {isInvoiceRoom && + !isArchivedRoom && + (welcomeMessage?.messageHtml ? ( + { + if (!canEditPolicyDescription) { + return; + } + Navigation.navigate(ROUTES.WORKSPACE_PROFILE_DESCRIPTION.getRoute(policy?.id ?? '-1')); + }} + style={[styles.renderHTML, canEditPolicyDescription ? styles.cursorPointer : styles.cursorText]} + accessibilityLabel={translate('reportDescriptionPage.roomDescription')} + > + + + ) : ( + + {welcomeMessage.phrase1} + + {report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL ? ( + {ReportUtils.getDisplayNameForParticipant(report?.invoiceReceiver?.accountID)} + ) : ( + {getPolicy(report?.invoiceReceiver?.policyID)?.name} + )} + + {` ${translate('common.and')} `} + {ReportUtils.getPolicyName(report)} + {welcomeMessage.phrase2} + + ))} {isChatRoom && + (!isInvoiceRoom || isArchivedRoom) && (welcomeMessage?.messageHtml ? ( { @@ -179,9 +216,8 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP ))} )} - {(moneyRequestOptions.includes(CONST.IOU.TYPE.PAY) || moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT) || moneyRequestOptions.includes(CONST.IOU.TYPE.TRACK)) && ( - {translate('reportActionsView.usePlusButton', {additionalText})} - )} + {shouldShowUsePlusButtonText && {translate('reportActionsView.usePlusButton', {additionalText})}} + {ReportUtils.isConciergeChatReport(report) && {translate('reportActionsView.askConcierge')}} ); @@ -189,8 +225,4 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP ReportWelcomeText.displayName = 'ReportWelcomeText'; -export default withOnyx({ - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, -})(ReportWelcomeText); +export default ReportWelcomeText; diff --git a/src/languages/en.ts b/src/languages/en.ts index f15e5c97d037..0863b0f8db9e 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -19,7 +19,6 @@ import type { BadgeFreeTrialParams, BeginningOfChatHistoryAdminRoomPartOneParams, BeginningOfChatHistoryAnnounceRoomPartOneParams, - BeginningOfChatHistoryAnnounceRoomPartTwo, BeginningOfChatHistoryDomainRoomPartOneParams, BillingBannerCardAuthenticationRequiredParams, BillingBannerCardExpiredParams, @@ -265,6 +264,7 @@ const translations = { phoneNumberPlaceholder: '(xxx) xxx-xxxx', email: 'Email', and: 'and', + or: 'or', details: 'Details', privacy: 'Privacy', privacyPolicy: 'Privacy Policy', @@ -658,33 +658,34 @@ const translations = { reportActionsView: { beginningOfArchivedRoomPartOne: 'You missed the party in ', beginningOfArchivedRoomPartTwo: ", there's nothing to see here.", - beginningOfChatHistoryDomainRoomPartOne: ({domainRoom}: BeginningOfChatHistoryDomainRoomPartOneParams) => `Collaboration with everyone at ${domainRoom} starts here! 🎉\nUse `, - beginningOfChatHistoryDomainRoomPartTwo: ' to chat with colleagues, share tips, and ask questions.', - beginningOfChatHistoryAdminRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAdminRoomPartOneParams) => `Collaboration among ${workspaceName} admins starts here! 🎉\nUse `, - beginningOfChatHistoryAdminRoomPartTwo: ' to chat about topics such as workspace configurations and more.', - beginningOfChatHistoryAnnounceRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAnnounceRoomPartOneParams) => - `Collaboration between all ${workspaceName} members starts here! 🎉\nUse `, - beginningOfChatHistoryAnnounceRoomPartTwo: ({workspaceName}: BeginningOfChatHistoryAnnounceRoomPartTwo) => ` to chat about anything ${workspaceName} related.`, - beginningOfChatHistoryUserRoomPartOne: 'Collaboration starts here! 🎉\nUse this space to chat about anything ', + beginningOfChatHistoryDomainRoomPartOne: ({domainRoom}: BeginningOfChatHistoryDomainRoomPartOneParams) => `This chat is with all Expensify members on the ${domainRoom} domain.`, + beginningOfChatHistoryDomainRoomPartTwo: ' Use it to chat with colleagues, share tips, and ask questions.', + beginningOfChatHistoryAdminRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAdminRoomPartOneParams) => `This chat is with ${workspaceName} admins.`, + beginningOfChatHistoryAdminRoomPartTwo: ' Use it to chat about workspace setup and more.', + beginningOfChatHistoryAnnounceRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAnnounceRoomPartOneParams) => `This chat is with everyone in ${workspaceName} workspace.`, + beginningOfChatHistoryAnnounceRoomPartTwo: ` Use it for the most important announcements.`, + beginningOfChatHistoryUserRoomPartOne: 'This chat room is for anything ', beginningOfChatHistoryUserRoomPartTwo: ' related.', - beginningOfChatHistoryInvoiceRoom: 'Collaboration starts here! 🎉 Use this room to view, discuss, and pay invoices.', - beginningOfChatHistory: 'This is the beginning of your chat with ', - beginningOfChatHistoryPolicyExpenseChatPartOne: 'Collaboration between ', - beginningOfChatHistoryPolicyExpenseChatPartTwo: ' and ', - beginningOfChatHistoryPolicyExpenseChatPartThree: ' starts here! 🎉 This is the place to chat, submit expenses and settle up.', + beginningOfChatHistoryInvoiceRoomPartOne: `This chat is for invoices between `, + beginningOfChatHistoryInvoiceRoomPartTwo: `. Use the + button to send an invoice.`, + beginningOfChatHistory: 'This chat is with ', + beginningOfChatHistoryPolicyExpenseChatPartOne: 'This is where ', + beginningOfChatHistoryPolicyExpenseChatPartTwo: ' will submit expenses to ', + beginningOfChatHistoryPolicyExpenseChatPartThree: ' workspace. Just use the + button.', 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', welcomeToRoom: ({roomName}: WelcomeToRoomParams) => `Welcome to ${roomName}!`, - usePlusButton: ({additionalText}: UsePlusButtonParams) => `\nYou can also use the + button to ${additionalText}, or assign a task!`, + usePlusButton: ({additionalText}: UsePlusButtonParams) => `\nUse the + button to ${additionalText} an expense.`, + askConcierge: '\nAsk questions and get 24/7 realtime support.', iouTypes: { - pay: 'pay expenses', - split: 'split an expense', - submit: 'submit an expense', - track: 'track an expense', - invoice: 'invoice an expense', + pay: 'pay', + split: 'split', + submit: 'submit', + track: 'track', + invoice: 'invoice', }, }, adminOnlyCanPost: 'Only admins can send messages in this room.', diff --git a/src/languages/es.ts b/src/languages/es.ts index 413084aa8286..a9a904cdcc27 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -17,7 +17,6 @@ import type { BadgeFreeTrialParams, BeginningOfChatHistoryAdminRoomPartOneParams, BeginningOfChatHistoryAnnounceRoomPartOneParams, - BeginningOfChatHistoryAnnounceRoomPartTwo, BeginningOfChatHistoryDomainRoomPartOneParams, BillingBannerCardAuthenticationRequiredParams, BillingBannerCardExpiredParams, @@ -256,6 +255,7 @@ const translations = { phoneNumberPlaceholder: '(xxx) xxx-xxxx', email: 'Email', and: 'y', + or: 'o', details: 'Detalles', privacy: 'Privacidad', hidden: 'Oculto', @@ -650,34 +650,36 @@ const translations = { reportActionsView: { beginningOfArchivedRoomPartOne: 'Te perdiste la fiesta en ', beginningOfArchivedRoomPartTwo: ', no hay nada que ver aquí.', - beginningOfChatHistoryDomainRoomPartOne: ({domainRoom}: BeginningOfChatHistoryDomainRoomPartOneParams) => `¡Colabora aquí con todos los participantes de ${domainRoom}! 🎉\nUtiliza `, - beginningOfChatHistoryDomainRoomPartTwo: ' para chatear con compañeros, compartir consejos o hacer una pregunta.', + beginningOfChatHistoryDomainRoomPartOne: ({domainRoom}: BeginningOfChatHistoryDomainRoomPartOneParams) => + `Este chat es con todos los miembros de Expensify en el dominio ${domainRoom}.`, + beginningOfChatHistoryDomainRoomPartTwo: ' Úsalo para chatear con colegas, compartir consejos y hacer preguntas.', beginningOfChatHistoryAdminRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAdminRoomPartOneParams) => - `¡Este es el lugar para que los administradores de ${workspaceName} colaboren! 🎉\nUsa `, - beginningOfChatHistoryAdminRoomPartTwo: ' para chatear sobre temas como la configuración del espacio de trabajo y mas.', - beginningOfChatHistoryAnnounceRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAnnounceRoomPartOneParams) => - `¡Este es el lugar para que todos los miembros de ${workspaceName} colaboren! 🎉\nUsa `, - beginningOfChatHistoryAnnounceRoomPartTwo: ({workspaceName}: BeginningOfChatHistoryAnnounceRoomPartTwo) => ` para chatear sobre cualquier cosa relacionada con ${workspaceName}.`, - beginningOfChatHistoryUserRoomPartOne: '¡Este es el lugar para colaborar! 🎉\nUsa este espacio para chatear sobre cualquier cosa relacionada con ', - beginningOfChatHistoryUserRoomPartTwo: '.', - beginningOfChatHistoryInvoiceRoom: '¡Este es el lugar para colaborar! 🎉 Utilice esta sala para ver, discutir y pagar facturas.', - beginningOfChatHistory: 'Aquí comienzan tus conversaciones con ', - beginningOfChatHistoryPolicyExpenseChatPartOne: '¡La colaboración entre ', - beginningOfChatHistoryPolicyExpenseChatPartTwo: ' y ', - beginningOfChatHistoryPolicyExpenseChatPartThree: ' empieza aquí! 🎉 Este es el lugar donde chatear y presentar o pagar gastos.', + `Este chat es con los administradores del espacio de trabajo ${workspaceName}.`, + beginningOfChatHistoryAdminRoomPartTwo: ' Use it to chat about workspace setup and more.', + beginningOfChatHistoryAnnounceRoomPartOne: ({workspaceName}: BeginningOfChatHistoryAnnounceRoomPartOneParams) => `Este chat es con todos en el espacio de trabajo ${workspaceName}.`, + beginningOfChatHistoryAnnounceRoomPartTwo: ` Úsalo para hablar sobre la configuración del espacio de trabajo y más.`, + beginningOfChatHistoryUserRoomPartOne: 'ste chat es para todo lo relacionado con ', + beginningOfChatHistoryUserRoomPartTwo: ' Fue creado por.', + beginningOfChatHistoryInvoiceRoomPartOne: `Este chat es para facturas entre `, + beginningOfChatHistoryInvoiceRoomPartTwo: `. Usa el botón + para enviar una factura.`, + beginningOfChatHistory: 'Este chat es con', + beginningOfChatHistoryPolicyExpenseChatPartOne: 'Aquí es donde ', + beginningOfChatHistoryPolicyExpenseChatPartTwo: ' enviará los gastos al espacio de trabajo ', + beginningOfChatHistoryPolicyExpenseChatPartThree: '. Solo usa el botón +.', 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', welcomeToRoom: ({roomName}: WelcomeToRoomParams) => `¡Bienvenido a ${roomName}!`, - usePlusButton: ({additionalText}: UsePlusButtonParams) => `\n¡También puedes usar el botón + de abajo para ${additionalText}, o asignar una tarea!`, + usePlusButton: ({additionalText}: UsePlusButtonParams) => `\nUsa el botón + para ${additionalText} un gasto`, + askConcierge: 'Haz preguntas y obtén soporte en tiempo real las 24/7.', iouTypes: { - pay: 'pagar gastos', - split: 'dividir un gasto', - submit: 'presentar un gasto', - track: 'rastrear un gasto', - invoice: 'facturar un gasto', + pay: 'pagar', + split: 'dividir', + submit: 'presentar', + track: 'rastrear', + invoice: 'facturar', }, }, adminOnlyCanPost: 'Solo los administradores pueden enviar mensajes en esta sala.', diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 785d76648b22..10802a197080 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2099,7 +2099,7 @@ function getDisplayNameForParticipant( return shouldUseShortForm ? shortName : longName; } -function getParticipantsAccountIDsForDisplay(report: OnyxEntry, shouldExcludeHidden = false, shouldExcludeDeleted = false): number[] { +function getParticipantsAccountIDsForDisplay(report: OnyxEntry, shouldExcludeHidden = false, shouldExcludeDeleted = false, shouldForceExcludeCurrentUser = false): number[] { const reportParticipants = report?.participants ?? {}; let participantsEntries = Object.entries(reportParticipants); @@ -2126,7 +2126,7 @@ function getParticipantsAccountIDsForDisplay(report: OnyxEntry, shouldEx // For 1:1 chat, we don't want to include the current user as a participant in order to not mark 1:1 chats as having multiple participants // For system chat, we want to display Expensify as the only participant - const shouldExcludeCurrentUser = isOneOnOneChat(report) || isSystemChat(report); + const shouldExcludeCurrentUser = isOneOnOneChat(report) || isSystemChat(report) || shouldForceExcludeCurrentUser; if (shouldExcludeCurrentUser || shouldExcludeHidden || shouldExcludeDeleted) { participantsIds = participantsIds.filter((accountID) => { diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 0496bc66fe5b..46af583aad87 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -543,7 +543,7 @@ function getWelcomeMessage(report: OnyxEntry, policy: OnyxEntry) } welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); - const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); + const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, undefined, undefined, true); const isMultipleParticipant = participantAccountIDs.length > 1; const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips( OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, allPersonalDetails), @@ -588,17 +588,28 @@ function getRoomWelcomeMessage(report: OnyxEntry): WelcomeMessage { welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfArchivedRoomPartOne'); welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfArchivedRoomPartTwo'); } else if (ReportUtils.isDomainRoom(report)) { + welcomeMessage.showReportName = false; welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryDomainRoomPartOne', {domainRoom: report?.reportName ?? ''}); welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryDomainRoomPartTwo'); } else if (ReportUtils.isAdminRoom(report)) { + welcomeMessage.showReportName = false; welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartOne', {workspaceName}); welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartTwo'); } else if (ReportUtils.isAnnounceRoom(report)) { + welcomeMessage.showReportName = false; welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartOne', {workspaceName}); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartTwo', {workspaceName}); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartTwo'); } else if (ReportUtils.isInvoiceRoom(report)) { welcomeMessage.showReportName = false; - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryInvoiceRoom'); + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryInvoiceRoomPartOne'); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryInvoiceRoomPartTwo'); + const payer = + report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL + ? ReportUtils.getDisplayNameForParticipant(report?.invoiceReceiver?.accountID) + : PolicyUtils.getPolicy(report?.invoiceReceiver?.policyID)?.name; + const receiver = ReportUtils.getPolicyName(report); + welcomeMessage.messageText = `${welcomeMessage.phrase1}${payer} ${Localize.translateLocal('common.and')} ${receiver}${welcomeMessage.phrase2}`; + return welcomeMessage; } else { // Message for user created rooms or other room types. welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryUserRoomPartOne');