diff --git a/src/languages/en.ts b/src/languages/en.ts index a3dc0e4c2ed3..ae5a9314d72d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -4273,6 +4273,7 @@ const translations = { addEmployee: ({email, role}: AddEmployeeParams) => `added ${email} as ${role === 'user' ? 'member' : 'admin'}`, updateRole: ({email, currentRole, newRole}: UpdateRoleParams) => `updated the role of ${email} from ${currentRole} to ${newRole}`, removeMember: ({email, role}: AddEmployeeParams) => `removed ${role} ${email}`, + removedConnection: ({connectionName}: ConnectionNameParams) => `removed connection to ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]}`, }, }, }, diff --git a/src/languages/es.ts b/src/languages/es.ts index de333859cdf3..71cb5037029d 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4319,6 +4319,7 @@ const translations = { updateRole: ({email, currentRole, newRole}: UpdateRoleParams) => `actualicé el rol ${email} de ${currentRole === 'user' ? 'miembro' : 'administrador'} a ${newRole === 'user' ? 'miembro' : 'administrador'}`, removeMember: ({email, role}: AddEmployeeParams) => `eliminado ${role === 'user' ? 'miembro' : 'administrador'} ${email}`, + removedConnection: ({connectionName}: ConnectionNameParams) => `eliminó la conexión a ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]}`, }, }, }, diff --git a/src/languages/params.ts b/src/languages/params.ts index d51bb2d20e03..bf47401c2cf0 100644 --- a/src/languages/params.ts +++ b/src/languages/params.ts @@ -1,6 +1,6 @@ import type {OnyxInputOrEntry, ReportAction} from '@src/types/onyx'; import type {DelegateRole} from '@src/types/onyx/Account'; -import type {ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName, Unit} from '@src/types/onyx/Policy'; +import type {AllConnectionName, ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName, Unit} from '@src/types/onyx/Policy'; import type {ViolationDataType} from '@src/types/onyx/TransactionViolation'; type AddressLineParams = { @@ -338,7 +338,7 @@ type ApprovalWorkflowErrorParams = { }; type ConnectionNameParams = { - connectionName: ConnectionName; + connectionName: AllConnectionName; }; type LastSyncDateParams = { diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index eac0ac4fe438..bd49e1bb60ac 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1692,6 +1692,15 @@ function getPolicyChangeLogDeleteMemberMessage(reportAction: OnyxInputOrEntry): string { + if (!isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_INTEGRATION)) { + return ''; + } + const originalMessage = getOriginalMessage(reportAction); + const connectionName = originalMessage?.connectionName; + return connectionName ? Localize.translateLocal('report.actions.type.removedConnection', {connectionName}) : ''; +} + function getRenamedAction(reportAction: OnyxEntry>) { const originalMessage = getOriginalMessage(reportAction); return Localize.translateLocal('newRoomPage.renamedRoomAction', { @@ -1851,6 +1860,7 @@ export { getRenamedAction, isCardIssuedAction, getCardIssuedMessage, + getRemovedConnectionMessage, }; export type {LastVisibleMessage}; diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index e120f7026fce..a36b8d828473 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -448,6 +448,8 @@ function getOptionData({ result.alternateText = ReportActionsUtils.getPolicyChangeLogDeleteMemberMessage(lastAction); } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_CUSTOM_UNIT_RATE) { result.alternateText = ReportActionsUtils.getReportActionMessageText(lastAction) ?? ''; + } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_INTEGRATION) { + result.alternateText = ReportActionsUtils.getRemovedConnectionMessage(lastAction); } else { result.alternateText = lastMessageTextFromReport.length > 0 diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 371df4db2b3c..8b1dd967c1c0 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -478,6 +478,8 @@ const ContextMenuActions: ContextMenuAction[] = [ setClipboardMessage(Localize.translateLocal('report.actions.type.integrationSyncFailed', {label, errorMessage})); } else if (ReportActionsUtils.isCardIssuedAction(reportAction)) { setClipboardMessage(ReportActionsUtils.getCardIssuedMessage(reportAction, true)); + } else if (ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_INTEGRATION)) { + setClipboardMessage(ReportActionsUtils.getRemovedConnectionMessage(reportAction)); } else if (content) { setClipboardMessage( content.replace(/()(.*?)(<\/mention-user>)/gi, (match, openTag: string, innerContent: string, closeTag: string): string => { diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index 33664e2a4162..3ed0841686a1 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -683,6 +683,8 @@ function ReportActionItem({ } else if (ReportActionsUtils.isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.INTEGRATION_SYNC_FAILED)) { const {label, errorMessage} = ReportActionsUtils.getOriginalMessage(action) ?? {label: '', errorMessage: ''}; children = ; + } else if (ReportActionsUtils.isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_INTEGRATION)) { + children = ; } else { const hasBeenFlagged = ![CONST.MODERATION.MODERATOR_DECISION_APPROVED, CONST.MODERATION.MODERATOR_DECISION_PENDING].some((item) => item === moderationDecision) && diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 857406dd128e..33d2cf6e6866 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -2,6 +2,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {OldDotOriginalMessageMap} from './OldDotAction'; +import type {AllConnectionName} from './Policy'; import type ReportActionName from './ReportActionName'; /** Types of join workspace resolutions */ @@ -274,6 +275,9 @@ type OriginalMessageChangeLog = { /** Old role of user */ oldValue?: string; + + /** Name of connection */ + connectionName?: AllConnectionName; }; /** Model of `join policy changelog` report action */ diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index aae6486c8130..1560847e3ed8 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1232,9 +1232,19 @@ type Connections = { [CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT]: Connection; }; +/** All integration connections, including unsupported ones */ +type AllConnections = Connections & { + /** Quickbooks Desktop integration connection */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + quickbooksDesktop: any; +}; + /** Names of integration connections */ type ConnectionName = keyof Connections; +/** Names of all integration connections */ +type AllConnectionName = keyof AllConnections; + /** Merchant Category Code. This is a way to identify the type of merchant (and type of spend) when a credit card is swiped. */ type MccGroup = { /** Default category for provided MCC Group */ @@ -1728,6 +1738,7 @@ export type { Connections, SageIntacctOfflineStateKeys, ConnectionName, + AllConnectionName, Tenant, Account, QBONonReimbursableExportAccountType,