From e7b36a6f7adaea9e285c66689439878cea1f5d8e Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Thu, 3 Apr 2025 19:29:34 -0300 Subject: [PATCH 01/12] chore: removed old i18n expressions --- packages/i18n/src/locales/en.i18n.json | 3 --- packages/i18n/src/locales/nb.i18n.json | 3 --- packages/i18n/src/locales/nn.i18n.json | 3 --- packages/i18n/src/locales/pt-BR.i18n.json | 3 --- 4 files changed, 12 deletions(-) diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 1a7ecd479baeb..27ef7e2108da4 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -6777,11 +6777,8 @@ "Advanced_contact_profile": "Advanced contact profile", "Advanced_contact_profile_description": "Manage multiple emails and phone numbers for a single contact, enabling a comprehensive multi-channel history that keeps you well-informed and improves communication efficiency.", "Add_contact": "Add contact", - "Add_to_contact_list_manually": "Add to contact list manually", - "Add_to_contact_and_enable_verification_description": "Add to contact list manually and <1>enable verification using multi-factor authentication.", "Ask_enable_advanced_contact_profile": "Ask your workspace admin to enable advanced contact profile", "close-blocked-room-comment": "This channel has been blocked", - "Contact_unknown": "Contact unknown", "Review_contact": "Review contact", "See_conflicts": "See conflicts", "Conflicts_found": "Conflicts found", diff --git a/packages/i18n/src/locales/nb.i18n.json b/packages/i18n/src/locales/nb.i18n.json index 6c425ba6327c9..dda09ad8d3dd7 100644 --- a/packages/i18n/src/locales/nb.i18n.json +++ b/packages/i18n/src/locales/nb.i18n.json @@ -6185,11 +6185,8 @@ "Advanced_contact_profile": "Avansert kontaktprofil", "Advanced_contact_profile_description": "Administrer flere e-poster og telefonnumre for en enkelt kontakt, noe som muliggjør en omfattende flerkanalshistorikk som holder deg godt informert og forbedrer kommunikasjonseffektiviteten.", "Add_contact": "Legg til kontakt", - "Add_to_contact_list_manually": "Legg til i kontaktlisten manuelt", - "Add_to_contact_and_enable_verification_description": "Legg til i kontaktlisten manuelt og <1>aktiver verifisering ved hjelp av multifaktorautentisering.", "Ask_enable_advanced_contact_profile": "Be arbeidsområdeadministratoren din om å aktivere avansert kontaktprofil", "close-blocked-room-comment": "Denne kanalen er blokkert", - "Contact_unknown": "Ukjent kontakt", "Review_contact": "Gjennomgå kontakt", "See_conflicts": "Se konflikter", "Conflicts_found": "Konflikter funnet", diff --git a/packages/i18n/src/locales/nn.i18n.json b/packages/i18n/src/locales/nn.i18n.json index 1e73ad4e738d2..14c86c4f6c25c 100644 --- a/packages/i18n/src/locales/nn.i18n.json +++ b/packages/i18n/src/locales/nn.i18n.json @@ -6185,11 +6185,8 @@ "Advanced_contact_profile": "Avansert kontaktprofil", "Advanced_contact_profile_description": "Administrer flere e-poster og telefonnumre for en enkelt kontakt, noe som muliggjør en omfattende flerkanalshistorikk som holder deg godt informert og forbedrer kommunikasjonseffektiviteten.", "Add_contact": "Legg til kontakt", - "Add_to_contact_list_manually": "Legg til i kontaktlisten manuelt", - "Add_to_contact_and_enable_verification_description": "Legg til i kontaktlisten manuelt og <1>aktiver verifisering ved hjelp av multifaktorautentisering.", "Ask_enable_advanced_contact_profile": "Be arbeidsområdeadministratoren din om å aktivere avansert kontaktprofil", "close-blocked-room-comment": "Denne kanalen er blokkert", - "Contact_unknown": "Ukjent kontakt", "Review_contact": "Gjennomgå kontakt", "See_conflicts": "Se konflikter", "Conflicts_found": "Konflikter funnet", diff --git a/packages/i18n/src/locales/pt-BR.i18n.json b/packages/i18n/src/locales/pt-BR.i18n.json index fed94c6851d0f..45a025eea68fb 100644 --- a/packages/i18n/src/locales/pt-BR.i18n.json +++ b/packages/i18n/src/locales/pt-BR.i18n.json @@ -324,8 +324,6 @@ "Add_members": "Adicionar membros", "Add_monitor": "Adicionar monitor", "Add_phone": "Adicionar número de telefone", - "Add_to_contact_and_enable_verification_description": "Adicione o contato na lista manualmente e <1>habilite a verificação usando autenticação de múltiplos fatores.", - "Add_to_contact_list_manually": "Adicione o contato na lista manualmente", "Add_user": "Adicionar usuário", "Add_users": "Adicionar usuários", "Added__username__to_team": "@{{user_added}} adicionado a esta equipe", @@ -927,7 +925,6 @@ "Contact_identification": "Identificação de contato", "Contact_not_found": "Contato não encontrado", "Contact_unblocked": "Contato desbloqueado", - "Contact_unknown": "Contato desconhecido", "Contacts": "Contatos", "Contains_Security_Fixes": "Contém correções de segurança", "Content": "Conteúdo", From 103d8586ba1a7113aafcdb774e74b404e094652e Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Thu, 3 Apr 2025 15:15:44 -0300 Subject: [PATCH 02/12] feat: updated unknown contact callout title and description --- .../ComposerOmnichannelCallout.tsx | 31 +++---------------- packages/i18n/src/locales/en.i18n.json | 1 + packages/i18n/src/locales/pt-BR.i18n.json | 1 + 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx index b1ce6cc244d3d..471117b1a125a 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx @@ -1,26 +1,16 @@ -import { Box, Button, ButtonGroup, Callout } from '@rocket.chat/fuselage'; -import { useAtLeastOnePermission, useEndpoint, useRouter, useSetting } from '@rocket.chat/ui-contexts'; +import { Button, ButtonGroup, Callout, IconButton } from '@rocket.chat/fuselage'; +import { useEndpoint, useRouter } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; -import { Trans, useTranslation } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; import { isSameChannel } from '../../../../../app/livechat/lib/isSameChannel'; -import { useHasLicenseModule } from '../../../../hooks/useHasLicenseModule'; import { useBlockChannel } from '../../../omnichannel/contactInfo/tabs/ContactInfoChannels/useBlockChannel'; import { useOmnichannelRoom } from '../../contexts/RoomContext'; const ComposerOmnichannelCallout = () => { const { t } = useTranslation(); const room = useOmnichannelRoom(); - const { navigate, buildRoutePath } = useRouter(); - const hasLicense = useHasLicenseModule('contact-id-verification'); - const securityPrivacyRoute = buildRoutePath('/omnichannel/security-privacy'); - const shouldShowSecurityRoute = useSetting('Livechat_Require_Contact_Verification') !== 'never' || !hasLicense; - - const canViewSecurityPrivacy = useAtLeastOnePermission([ - 'view-privileged-setting', - 'edit-privileged-setting', - 'manage-selected-settings', - ]); + const { navigate } = useRouter(); const { _id, @@ -44,7 +34,6 @@ const ComposerOmnichannelCallout = () => { return ( + setDismissed(true)} /> } > From 622c919659b66694142db3dd406aa5b9fd468940 Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Thu, 3 Apr 2025 17:13:51 -0300 Subject: [PATCH 04/12] test: added generics to createFakeRoom --- apps/meteor/tests/mocks/data.ts | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/apps/meteor/tests/mocks/data.ts b/apps/meteor/tests/mocks/data.ts index d059d941abd6f..21775e9a1fae8 100644 --- a/apps/meteor/tests/mocks/data.ts +++ b/apps/meteor/tests/mocks/data.ts @@ -21,21 +21,22 @@ export function createFakeUser(overrides?: Partial): IUser { }; } -export const createFakeRoom = (overrides?: Partial): IRoom => ({ - _id: faker.database.mongodbObjectId(), - _updatedAt: faker.date.recent(), - t: faker.helpers.arrayElement(['c', 'p', 'd']), - msgs: faker.number.int({ min: 0 }), - u: { +export const createFakeRoom = (overrides?: Partial): T => + ({ _id: faker.database.mongodbObjectId(), - username: faker.internet.userName(), - name: faker.person.fullName(), - ...overrides?.u, - }, - usersCount: faker.number.int({ min: 0 }), - autoTranslateLanguage: faker.helpers.arrayElement(['en', 'es', 'pt', 'ar', 'it', 'ru', 'fr']), - ...overrides, -}); + _updatedAt: faker.date.recent(), + t: faker.helpers.arrayElement(['c', 'p', 'd']), + msgs: faker.number.int({ min: 0 }), + u: { + _id: faker.database.mongodbObjectId(), + username: faker.internet.userName(), + name: faker.person.fullName(), + ...overrides?.u, + }, + usersCount: faker.number.int({ min: 0 }), + autoTranslateLanguage: faker.helpers.arrayElement(['en', 'es', 'pt', 'ar', 'it', 'ru', 'fr']), + ...overrides, + }) as T; export const createFakeSubscription = (overrides?: Partial): ISubscription => ({ _id: faker.database.mongodbObjectId(), From 7bd772f0f7b7c33e9dd6c7ab7388a1eb9f786e13 Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Thu, 3 Apr 2025 17:15:06 -0300 Subject: [PATCH 05/12] test: added mock functions createFakeContact & createFakeContactChannel --- apps/meteor/tests/mocks/data.ts | 49 +++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/apps/meteor/tests/mocks/data.ts b/apps/meteor/tests/mocks/data.ts index 21775e9a1fae8..a651c8494335b 100644 --- a/apps/meteor/tests/mocks/data.ts +++ b/apps/meteor/tests/mocks/data.ts @@ -1,7 +1,17 @@ import { faker } from '@faker-js/faker'; import type { IExternalComponentRoomInfo, IExternalComponentUserInfo } from '@rocket.chat/apps-engine/client/definition'; -import { AppSubscriptionStatus } from '@rocket.chat/core-typings'; -import type { LicenseInfo, App, IMessage, IRoom, ISubscription, IUser } from '@rocket.chat/core-typings'; +import type { ILivechatContact } from '@rocket.chat/apps-engine/definition/livechat'; +import { AppSubscriptionStatus, OmnichannelSourceType } from '@rocket.chat/core-typings'; +import type { + LicenseInfo, + App, + IMessage, + IRoom, + ISubscription, + IUser, + ILivechatContactChannel, + Serialized, +} from '@rocket.chat/core-typings'; import { parse } from '@rocket.chat/message-parser'; import type { MessageWithMdEnforced } from '../../client/lib/parseMessageTextToAstMarkdown'; @@ -285,3 +295,38 @@ export function createFakeVisitor() { email: faker.internet.email(), } as const; } + +export function createFakeContactChannel(overrides?: Partial>): Serialized { + return { + name: 'widget', + blocked: false, + verified: false, + ...overrides, + visitor: { + visitorId: faker.string.uuid(), + source: { + type: OmnichannelSourceType.WIDGET, + }, + ...overrides?.visitor, + }, + details: { + type: OmnichannelSourceType.WIDGET, + destination: '', + ...overrides?.details, + }, + }; +} + +export function createFakeContact(overrides?: Partial>): Serialized { + return { + _id: faker.string.uuid(), + _updatedAt: new Date().toISOString(), + name: pullNextVisitorName(), + phones: [{ phoneNumber: faker.phone.number() }], + emails: [{ address: faker.internet.email() }], + unknown: true, + channels: [createFakeContactChannel()], + createdAt: new Date().toISOString(), + ...overrides, + }; +} From dab8058d297b27ead84e029148e3cf26cd5127b4 Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Thu, 3 Apr 2025 17:15:50 -0300 Subject: [PATCH 06/12] test: added unit tests to ComposerOmnichannelCallout --- .../ComposerOmnichannelCallout.spec.tsx | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx new file mode 100644 index 0000000000000..0a870ed7fc55d --- /dev/null +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx @@ -0,0 +1,75 @@ +import { faker } from '@faker-js/faker/locale/af_ZA'; +import type { IOmnichannelRoom } from '@rocket.chat/core-typings'; +import { mockAppRoot } from '@rocket.chat/mock-providers'; +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import ComposerOmnichannelCallout from './ComposerOmnichannelCallout'; +import FakeRoomProvider from '../../../../../tests/mocks/client/FakeRoomProvider'; +import { createFakeContact, createFakeRoom } from '../../../../../tests/mocks/data'; + +jest.mock('../../../omnichannel/contactInfo/tabs/ContactInfoChannels/useBlockChannel', () => ({ + useBlockChannel: () => jest.fn(), +})); + +const fakeVisitor = { + _id: faker.string.uuid(), + token: faker.string.uuid(), + username: faker.internet.userName(), +}; + +const fakeRoom = createFakeRoom({ t: 'l', v: fakeVisitor }); +const fakeContact = createFakeContact(); + +it('should be displayed if contact is unknown', async () => { + const getContactMockFn = jest.fn().mockResolvedValue({ contact: fakeContact }); + const wrapper = mockAppRoot().withEndpoint('GET', '/v1/omnichannel/contacts.get', getContactMockFn).withRoom(fakeRoom); + + render( + + + , + { wrapper: wrapper.build() }, + ); + + await waitFor(() => expect(getContactMockFn).toHaveBeenCalled()); + expect(screen.getByText('Unknown_contact_callout_description')).toBeVisible(); + expect(screen.getByRole('button', { name: 'Add_contact' })).toBeVisible(); + expect(screen.getByRole('button', { name: 'Block' })).toBeVisible(); + expect(screen.getByRole('button', { name: 'Close' })).toBeVisible(); +}); + +it('should not be displayed if contact is known', async () => { + const getContactMockFn = jest.fn().mockResolvedValue({ contact: createFakeContact({ unknown: false }) }); + const wrapper = mockAppRoot().withEndpoint('GET', '/v1/omnichannel/contacts.get', getContactMockFn).withRoom(fakeRoom); + + render( + + + , + { wrapper: wrapper.build() }, + ); + + await waitFor(() => expect(getContactMockFn).toHaveBeenCalled()); + expect(screen.queryByText('Unknown_contact_callout_description')).not.toBeInTheDocument(); +}); + +it('should hide callout on dismiss', async () => { + const getContactMockFn = jest.fn().mockResolvedValue({ contact: fakeContact }); + const wrapper = mockAppRoot().withEndpoint('GET', '/v1/omnichannel/contacts.get', getContactMockFn).withRoom(fakeRoom); + + render( + + + , + { wrapper: wrapper.build() }, + ); + + await waitFor(() => expect(getContactMockFn).toHaveBeenCalled()); + expect(screen.getByText('Unknown_contact_callout_description')).toBeVisible(); + + const btnClose = screen.getByRole('button', { name: 'Close' }); + await userEvent.click(btnClose); + + expect(screen.queryByText('Unknown_contact_callout_description')).not.toBeInTheDocument(); +}); From 4ccc5835b336a7da6c97c122fd6cbf5e02669d41 Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Thu, 3 Apr 2025 18:54:02 -0300 Subject: [PATCH 07/12] test: added e2e tests to ComposerOmnichannelCallout --- .../ComposerOmnichannelCallout.tsx | 1 + ...mnichannel-contact-unknown-callout.spec.ts | 69 +++++++++++++++++++ .../page-objects/fragments/home-content.ts | 8 +++ 3 files changed, 78 insertions(+) create mode 100644 apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx index c92718b081c6c..f4b4583416102 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx @@ -36,6 +36,7 @@ const ComposerOmnichannelCallout = () => { return ( diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts new file mode 100644 index 0000000000000..b994964386dbd --- /dev/null +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts @@ -0,0 +1,69 @@ +import type { Page } from '@playwright/test'; + +import { createFakeVisitor } from '../../mocks/data'; +import { IS_EE } from '../config/constants'; +import { createAuxContext } from '../fixtures/createAuxContext'; +import { Users } from '../fixtures/userStates'; +import { OmnichannelLiveChat, HomeChannel } from '../page-objects'; +import { expect, test } from '../utils/test'; + +test.describe('OC - Contact Unknown Callout', () => { + test.skip(!IS_EE, 'Enterprise Only'); + + let poLiveChat: OmnichannelLiveChat; + let newVisitor: { email: string; name: string }; + + let agent: { page: Page; poHomeChannel: HomeChannel }; + + test.beforeAll(async ({ api, browser }) => { + newVisitor = createFakeVisitor(); + + await api.post('/livechat/users/agent', { username: 'user1' }); + await api.post('/livechat/users/manager', { username: 'user1' }); + + const { page } = await createAuxContext(browser, Users.user1); + agent = { page, poHomeChannel: new HomeChannel(page) }; + }); + test.beforeEach(async ({ page, api }) => { + poLiveChat = new OmnichannelLiveChat(page, api); + }); + + test.beforeEach('create livechat conversation', async ({ page }) => { + await page.goto('/livechat'); + await poLiveChat.openLiveChat(); + await poLiveChat.sendMessage(newVisitor, false); + await poLiveChat.onlineAgentMessage.type('this_a_test_message_from_visitor'); + await poLiveChat.btnSendMessageToOnlineAgent.click(); + }); + + test.afterEach('close livechat conversation', async () => { + await poLiveChat.closeChat(); + }); + + test.afterAll(async ({ api }) => { + await api.delete('/livechat/users/agent/user1'); + await api.delete('/livechat/users/manager/user1'); + await agent.page.close(); + }); + + test('OC - Contact Unknown Callout - Dismiss callout', async () => { + await test.step('expect to open conversation', async () => { + await agent.poHomeChannel.sidenav.openChat(newVisitor.name); + }); + + await test.step('expect contact unknown callout to be visible', async () => { + await expect(agent.poHomeChannel.content.contactUnknownCallout).toBeVisible(); + }); + + await test.step('expect to hide callout when close is clicked', async () => { + await agent.poHomeChannel.content.btnCloseContactUnknownCallout.click(); + await expect(agent.poHomeChannel.content.contactUnknownCallout).not.toBeVisible(); + }); + + await test.step('expect keep callout hidden after changing pages', async () => { + await agent.poHomeChannel.sidenav.sidebarHomeAction.click(); + await agent.poHomeChannel.sidenav.openChat(newVisitor.name); + await expect(agent.poHomeChannel.content.contactUnknownCallout).not.toBeVisible(); + }); + }); +}); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts index 08806275ef42e..b37d294908d62 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -463,4 +463,12 @@ export class HomeContent { get btnJoinChannel() { return this.page.getByRole('button', { name: 'Join channel' }); } + + get contactUnknownCallout() { + return this.page.locator('[data-qa-id="contact-unknown-callout"]'); + } + + get btnCloseContactUnknownCallout() { + return this.contactUnknownCallout.getByRole('button', { name: 'Close' }); + } } From b608783c46126f9dc787ede53290cbe0fa81d1cd Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Fri, 4 Apr 2025 11:19:54 -0300 Subject: [PATCH 08/12] chore: changeset --- .changeset/young-avocados-brake.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/young-avocados-brake.md diff --git a/.changeset/young-avocados-brake.md b/.changeset/young-avocados-brake.md new file mode 100644 index 0000000000000..a20df69c72426 --- /dev/null +++ b/.changeset/young-avocados-brake.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": minor +"@rocket.chat/i18n": minor +--- + +Adds close action to contact unknown callout displayed within Livechat rooms From 7e5a3d9172c39f6aab2902a58bb1e8ca97fff574 Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Tue, 8 Apr 2025 10:41:01 -0300 Subject: [PATCH 09/12] feat: improved callout's accessibility --- .../ComposerOmnichannel/ComposerOmnichannelCallout.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx index f4b4583416102..2469198ef81c8 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx @@ -2,6 +2,7 @@ import { Button, ButtonGroup, Callout, IconButton } from '@rocket.chat/fuselage' import { useLocalStorage } from '@rocket.chat/fuselage-hooks'; import { useEndpoint, useRouter } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; +import { useId } from 'react'; import { useTranslation } from 'react-i18next'; import { isSameChannel } from '../../../../../app/livechat/lib/isSameChannel'; @@ -20,6 +21,7 @@ const ComposerOmnichannelCallout = () => { contactId, } = room; + const calloutDescriptionId = useId(); const [dismissed, setDismissed] = useLocalStorage(`contact-unknown-callout-${contactId}`, false); const getContactById = useEndpoint('GET', '/v1/omnichannel/contacts.get'); @@ -36,7 +38,8 @@ const ComposerOmnichannelCallout = () => { return ( @@ -50,7 +53,7 @@ const ComposerOmnichannelCallout = () => { } > - {t('Unknown_contact_callout_description')} +

{t('Unknown_contact_callout_description')}

); }; From 6dc32cdd8505250a76e3732368123cf3c1ef9794 Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Tue, 8 Apr 2025 10:41:23 -0300 Subject: [PATCH 10/12] test: updated to a more semantic locator --- apps/meteor/tests/e2e/page-objects/fragments/home-content.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts index b37d294908d62..a565fdb56c003 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -465,7 +465,7 @@ export class HomeContent { } get contactUnknownCallout() { - return this.page.locator('[data-qa-id="contact-unknown-callout"]'); + return this.page.getByRole('status', { name: 'Unknown contact. This contact is not on the contact list.' }); } get btnCloseContactUnknownCallout() { From f555e622c619f39ba1bd5519ec0cfdb02a6a64ed Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Tue, 8 Apr 2025 11:08:21 -0300 Subject: [PATCH 11/12] refactor: changed from local storage to session storage --- .../ComposerOmnichannel/ComposerOmnichannelCallout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx index 2469198ef81c8..cb647964bced8 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx @@ -1,5 +1,5 @@ import { Button, ButtonGroup, Callout, IconButton } from '@rocket.chat/fuselage'; -import { useLocalStorage } from '@rocket.chat/fuselage-hooks'; +import { useSessionStorage } from '@rocket.chat/fuselage-hooks'; import { useEndpoint, useRouter } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import { useId } from 'react'; @@ -22,7 +22,7 @@ const ComposerOmnichannelCallout = () => { } = room; const calloutDescriptionId = useId(); - const [dismissed, setDismissed] = useLocalStorage(`contact-unknown-callout-${contactId}`, false); + const [dismissed, setDismissed] = useSessionStorage(`contact-unknown-callout-${contactId}`, false); const getContactById = useEndpoint('GET', '/v1/omnichannel/contacts.get'); const { data } = useQuery({ queryKey: ['getContactById', contactId], queryFn: () => getContactById({ contactId }) }); From b1c681bc501f40f4b3bff22a08ef7a29a585c0af Mon Sep 17 00:00:00 2001 From: Aleksander Nicacio da Silva Date: Tue, 8 Apr 2025 14:21:12 -0300 Subject: [PATCH 12/12] refactor: use dismiss instead of close --- .../ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx | 6 +++--- .../ComposerOmnichannel/ComposerOmnichannelCallout.tsx | 2 +- .../omnichannel/omnichannel-contact-unknown-callout.spec.ts | 4 ++-- .../meteor/tests/e2e/page-objects/fragments/home-content.ts | 4 ++-- packages/i18n/src/locales/en.i18n.json | 1 + packages/i18n/src/locales/pt-BR.i18n.json | 1 + 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx index 0a870ed7fc55d..f246478e3b4b8 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.spec.tsx @@ -36,7 +36,7 @@ it('should be displayed if contact is unknown', async () => { expect(screen.getByText('Unknown_contact_callout_description')).toBeVisible(); expect(screen.getByRole('button', { name: 'Add_contact' })).toBeVisible(); expect(screen.getByRole('button', { name: 'Block' })).toBeVisible(); - expect(screen.getByRole('button', { name: 'Close' })).toBeVisible(); + expect(screen.getByRole('button', { name: 'Dismiss' })).toBeVisible(); }); it('should not be displayed if contact is known', async () => { @@ -68,8 +68,8 @@ it('should hide callout on dismiss', async () => { await waitFor(() => expect(getContactMockFn).toHaveBeenCalled()); expect(screen.getByText('Unknown_contact_callout_description')).toBeVisible(); - const btnClose = screen.getByRole('button', { name: 'Close' }); - await userEvent.click(btnClose); + const btnDismiss = screen.getByRole('button', { name: 'Dismiss' }); + await userEvent.click(btnDismiss); expect(screen.queryByText('Unknown_contact_callout_description')).not.toBeInTheDocument(); }); diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx index cb647964bced8..23a42b0546ad3 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelCallout.tsx @@ -49,7 +49,7 @@ const ComposerOmnichannelCallout = () => { - setDismissed(true)} /> + setDismissed(true)} /> } > diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts index b994964386dbd..44335abad6cab 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-contact-unknown-callout.spec.ts @@ -55,8 +55,8 @@ test.describe('OC - Contact Unknown Callout', () => { await expect(agent.poHomeChannel.content.contactUnknownCallout).toBeVisible(); }); - await test.step('expect to hide callout when close is clicked', async () => { - await agent.poHomeChannel.content.btnCloseContactUnknownCallout.click(); + await test.step('expect to hide callout when dismiss is clicked', async () => { + await agent.poHomeChannel.content.btnDismissContactUnknownCallout.click(); await expect(agent.poHomeChannel.content.contactUnknownCallout).not.toBeVisible(); }); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts index a565fdb56c003..cab59e8430693 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -468,7 +468,7 @@ export class HomeContent { return this.page.getByRole('status', { name: 'Unknown contact. This contact is not on the contact list.' }); } - get btnCloseContactUnknownCallout() { - return this.contactUnknownCallout.getByRole('button', { name: 'Close' }); + get btnDismissContactUnknownCallout() { + return this.contactUnknownCallout.getByRole('button', { name: 'Dismiss' }); } } diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 3ce0f7cefd7fa..c9eb485ee4c33 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -1716,6 +1716,7 @@ "Daily_Active_Users": "Daily Active Users", "Display_unread_counter": "Display room as unread when there are unread messages", "Displays_action_text": "Displays action text", + "Dismiss": "Dismiss", "Data_modified": "Data Modified", "Do_not_display_unread_counter": "Do not display any counter of this channel", "Do_you_want_to_accept": "Do you want to accept?", diff --git a/packages/i18n/src/locales/pt-BR.i18n.json b/packages/i18n/src/locales/pt-BR.i18n.json index a48d357a2c5d5..67f050a51caba 100644 --- a/packages/i18n/src/locales/pt-BR.i18n.json +++ b/packages/i18n/src/locales/pt-BR.i18n.json @@ -1399,6 +1399,7 @@ "Display_setting_permissions": "Exibir permissões para alterar configurações", "Display_unread_counter": "Exibir número de mensagens não lidas", "Displays_action_text": "Exibe texto da ação", + "Dismiss": "Dispensar", "Do_It_Later": "Fazer depois", "Do_Nothing": "Não fazer nada", "Do_not_display_unread_counter": "Não exibir nenhum contador desse canal",