diff --git a/.gitignore b/.gitignore index 45daa54557bf..4d868ec96b3a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,4 @@ yarn-error.log* .nvmrc .idea/ .exrc -.envrc +.envrc \ No newline at end of file diff --git a/apps/meteor/client/views/room/components/body/composer/ComposerContainer.tsx b/apps/meteor/client/views/room/components/body/composer/ComposerContainer.tsx index d124a2e7f92c..6abd2e1867da 100644 --- a/apps/meteor/client/views/room/components/body/composer/ComposerContainer.tsx +++ b/apps/meteor/client/views/room/components/body/composer/ComposerContainer.tsx @@ -55,11 +55,7 @@ const ComposerContainer = ({ children, ...props }: ComposerMessageProps): ReactE } if (isReadOnly) { - return ( - - ); + return ; } if (isBlockedOrBlocker) { diff --git a/apps/meteor/client/views/room/components/body/composer/ComposerReadOnly.tsx b/apps/meteor/client/views/room/components/body/composer/ComposerReadOnly.tsx index 5a97cffca506..92466f682c4a 100644 --- a/apps/meteor/client/views/room/components/body/composer/ComposerReadOnly.tsx +++ b/apps/meteor/client/views/room/components/body/composer/ComposerReadOnly.tsx @@ -1,9 +1,35 @@ -import { MessageFooterCallout } from '@rocket.chat/ui-composer'; -import { useTranslation } from '@rocket.chat/ui-contexts'; +import { Button } from '@rocket.chat/fuselage'; +import { MessageFooterCallout, MessageFooterCalloutContent } from '@rocket.chat/ui-composer'; +import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; +import { useMutation } from '@tanstack/react-query'; import type { ReactElement } from 'react'; import React from 'react'; +import { dispatchToastMessage } from '../../../../../lib/toast'; +import { useRoom, useUserIsSubscribed } from '../../../contexts/RoomContext'; + export const ComposerReadOnly = (): ReactElement => { const t = useTranslation(); - return {t('room_is_read_only')}; + const room = useRoom(); + const isSubscribed = useUserIsSubscribed(); + const joinChannel = useEndpoint('POST', '/v1/channels.join'); + + const join = useMutation(() => joinChannel({ roomId: room._id }), { + onError: (error: unknown) => { + dispatchToastMessage({ type: 'error', message: error }); + }, + }); + + return ( + + ); }; diff --git a/apps/meteor/tests/e2e/channel-management.spec.ts b/apps/meteor/tests/e2e/channel-management.spec.ts index 025c277eb140..61d6c9a2ced2 100644 --- a/apps/meteor/tests/e2e/channel-management.spec.ts +++ b/apps/meteor/tests/e2e/channel-management.spec.ts @@ -1,3 +1,6 @@ +import type { Page } from '@playwright/test'; +import faker from '@faker-js/faker'; + import { test, expect } from './utils/test'; import { HomeChannel } from './page-objects'; import { createTargetChannel } from './utils'; @@ -7,9 +10,13 @@ test.use({ storageState: 'admin-session.json' }); test.describe.serial('channel-management', () => { let poHomeChannel: HomeChannel; let targetChannel: string; + let regularUserPage: Page; - test.beforeAll(async ({ api }) => { + test.beforeAll(async ({ api, browser }) => { targetChannel = await createTargetChannel(api); + regularUserPage = await browser.newPage({ storageState: 'user2-session.json' }); + await regularUserPage.goto('/home'); + await regularUserPage.waitForSelector('[data-qa-id="home-header"]'); }); test.beforeEach(async ({ page }) => { @@ -101,6 +108,19 @@ test.describe.serial('channel-management', () => { await expect(poHomeChannel.toastSuccess).toBeVisible(); }); + test('expect "readOnlyChannel" to show join button', async () => { + const channelName = faker.datatype.uuid(); + + await poHomeChannel.sidenav.openNewByLabel('Channel'); + await poHomeChannel.sidenav.inputChannelName.type(channelName); + await poHomeChannel.sidenav.checkboxPrivateChannel.click(); + await poHomeChannel.sidenav.checkboxReadOnly.click(); + await poHomeChannel.sidenav.btnCreate.click(); + + await regularUserPage.goto(`/channel/${channelName}`); + await expect(regularUserPage.locator('button', { hasText: 'Join' })).toBeVisible(); + }); + test.skip('expect all notification preferences of "targetChannel" to be "Mentions"', async () => { await poHomeChannel.sidenav.openChat(targetChannel); await poHomeChannel.tabs.kebab.click({ force: true }); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts index 7d27109a1d1d..e74ca487e595 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts @@ -17,6 +17,12 @@ export class HomeSidenav { return this.page.locator('role=dialog[name="Create Channel"] >> role=checkbox[name="Encrypted"]'); } + get checkboxReadOnly(): Locator { + return this.page.locator( + '//*[@id="modal-root"]//*[contains(@class, "rcx-field") and contains(text(), "Read Only")]/../following-sibling::label/i', + ); + } + get inputChannelName(): Locator { return this.page.locator('#modal-root [data-qa="create-channel-modal"] [data-qa-type="channel-name-input"]'); } diff --git a/packages/ui-composer/src/MessageFooterCallout/MessageFooterCalloutContent.tsx b/packages/ui-composer/src/MessageFooterCallout/MessageFooterCalloutContent.tsx index 939002a30dab..026797146c0b 100644 --- a/packages/ui-composer/src/MessageFooterCallout/MessageFooterCalloutContent.tsx +++ b/packages/ui-composer/src/MessageFooterCallout/MessageFooterCalloutContent.tsx @@ -7,6 +7,10 @@ const MessageFooterCalloutContent = forwardRef< { children: ReactNode; } ->((props, ref): ReactElement => ); +>( + (props, ref): ReactElement => ( + + ), +); export default MessageFooterCalloutContent;