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;