Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: TeamsInfo in favor of RoomInfo #32225

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { lazy, useMemo } from 'react';

import { useRoom } from '../../views/room/contexts/RoomContext';
import type { RoomToolboxActionConfig } from '../../views/room/contexts/RoomToolboxContext';

const Info = lazy(() => import('../../views/room/contextualBar/Info'));

export const useChannelSettingsRoomAction = () => {
const room = useRoom();

return useMemo(
(): RoomToolboxActionConfig => ({
id: 'channel-settings',
groups: ['channel', 'group'],
groups: ['channel', 'group', 'team'],
anonymous: true,
full: true,
title: 'Room_Info',
title: room.teamMain ? 'Team_Info' : 'Room_Info',
icon: 'info-circled',
tabComponent: Info,
order: 1,
}),
[],
[room.teamMain],
);
};
21 changes: 0 additions & 21 deletions apps/meteor/client/hooks/roomActions/useTeamInfoRoomAction.ts

This file was deleted.

2 changes: 0 additions & 2 deletions apps/meteor/client/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import { useRoomInfoRoomAction } from './hooks/roomActions/useRoomInfoRoomAction
import { useStarredMessagesRoomAction } from './hooks/roomActions/useStarredMessagesRoomAction';
import { useStartCallRoomAction } from './hooks/roomActions/useStartCallRoomAction';
import { useTeamChannelsRoomAction } from './hooks/roomActions/useTeamChannelsRoomAction';
import { useTeamInfoRoomAction } from './hooks/roomActions/useTeamInfoRoomAction';
import { useThreadRoomAction } from './hooks/roomActions/useThreadRoomAction';
import { useUploadedFilesListRoomAction } from './hooks/roomActions/useUploadedFilesListRoomAction';
import { useUserInfoGroupRoomAction } from './hooks/roomActions/useUserInfoGroupRoomAction';
Expand All @@ -39,7 +38,6 @@ import type { QuickActionsActionConfig } from './views/room/lib/quickActions';

export const roomActionHooks = [
useChannelSettingsRoomAction,
useTeamInfoRoomAction,
useUserInfoGroupRoomAction,
useUserInfoRoomAction,
useThreadRoomAction,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { Box, Callout, Menu, Option } from '@rocket.chat/fuselage';
import { Box, Button, Callout, Menu, Option } from '@rocket.chat/fuselage';
import { RoomAvatar } from '@rocket.chat/ui-avatar';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { useMemo } from 'react';
Expand All @@ -22,19 +22,18 @@ import { useRoomActions } from '../hooks/useRoomActions';

type RoomInfoProps = {
room: IRoom;
icon: string;
onClickBack?: () => void;
onClickClose?: () => void;
onClickEnterRoom?: () => void;
onClickEdit?: () => void;
resetState?: () => void;
onClickViewChannels?: () => void;
};

const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onClickEdit, resetState }: RoomInfoProps) => {
const RoomInfo = ({ room, onClickBack, onClickClose, onClickEnterRoom, onClickEdit, resetState, onClickViewChannels }: RoomInfoProps) => {
const t = useTranslation();
const { name, fname, description, topic, archived, broadcast, announcement } = room;
const roomTitle = fname || name;
const isDiscussion = 'prid' in room;
const roomName = fname || name;

const retentionPolicy = useRetentionPolicy(room);
const memoizedActions = useRoomActions(room, { onClickEnterRoom, onClickEdit }, resetState);
Expand Down Expand Up @@ -67,14 +66,25 @@ const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onC
return [...actionsDefinition.map(mapAction), menu].filter(Boolean);
}, [actionsDefinition, menu]);

const getRoomTitle = useMemo(() => {
if (room.teamMain) {
return t('Teams_Info');
}

if ('prid' in room) {
return t('Discussion_info');
}

return t('Channel_info');
}, [room, t]);

return (
<>
<ContextualbarHeader>
{onClickBack ? <ContextualbarBack onClick={onClickBack} /> : <ContextualbarIcon name='info-circled' />}
<ContextualbarTitle>{isDiscussion ? t('Discussion_info') : t('Channel_info')}</ContextualbarTitle>
<ContextualbarTitle>{getRoomTitle}</ContextualbarTitle>
{onClickClose && <ContextualbarClose onClick={onClickClose} />}
</ContextualbarHeader>

<ContextualbarScrollableContent p={24}>
<InfoPanel>
<InfoPanel.Section maxWidth='x332' mi='auto'>
Expand All @@ -93,9 +103,10 @@ const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onC
</InfoPanel.Section>
)}

{roomTitle && (
{roomName && (
<InfoPanel.Section>
<InfoPanel.Title title={roomTitle} icon={icon} />
<InfoPanel.Title title={roomName} icon={room.t === 'p' ? 'lock' : 'hashtag'} />
{/* <InfoPanel.Title title={room.fname || room.name || ''} icon='team' /> */}
</InfoPanel.Section>
)}

Expand All @@ -108,7 +119,7 @@ const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onC
</InfoPanel.Field>
)}

{description && description !== '' && (
{description && (
<InfoPanel.Field>
<InfoPanel.Label>{t('Description')}</InfoPanel.Label>
<InfoPanel.Text withTruncatedText={false}>
Expand All @@ -117,7 +128,7 @@ const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onC
</InfoPanel.Field>
)}

{announcement && announcement !== '' && (
{announcement && (
<InfoPanel.Field>
<InfoPanel.Label>{t('Announcement')}</InfoPanel.Label>
<InfoPanel.Text withTruncatedText={false}>
Expand All @@ -126,7 +137,7 @@ const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onC
</InfoPanel.Field>
)}

{topic && topic !== '' && (
{topic && (
<InfoPanel.Field>
<InfoPanel.Label>{t('Topic')}</InfoPanel.Label>
<InfoPanel.Text withTruncatedText={false}>
Expand All @@ -135,6 +146,17 @@ const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onC
</InfoPanel.Field>
)}

{onClickViewChannels && (
<InfoPanel.Field>
<InfoPanel.Label>{t('Teams_channels')}</InfoPanel.Label>
<InfoPanel.Text>
<Button onClick={onClickViewChannels} small>
{t('View_channels')}
</Button>
</InfoPanel.Text>
</InfoPanel.Field>
)}

{retentionPolicy && (
<RetentionPolicyCallout
filesOnlyDefault={retentionPolicy.filesOnly}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import React, { useState } from 'react';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import React, { useCallback, useState } from 'react';

import { useRoom } from '../../contexts/RoomContext';
import { useRoomToolbox } from '../../contexts/RoomToolboxContext';
Expand All @@ -17,11 +17,12 @@ type RoomInfoRouterProps = {
const RoomInfoRouter = ({ onClickBack, onEnterRoom, resetState }: RoomInfoRouterProps) => {
const [isEditing, setIsEditing] = useState(false);

const { closeTab } = useRoomToolbox();
const { openTab, closeTab } = useRoomToolbox();
const room = useRoom();

const canEdit = useCanEditRoom(room);
const onClickEnterRoom = useMutableCallback(() => onEnterRoom?.(room));
const onClickEnterRoom = useEffectEvent(() => onEnterRoom?.(room));
const onClickViewChannels = useCallback(() => openTab('team-channels'), [openTab]);

if (isEditing) {
return <EditRoomInfoWithData onClickBack={() => setIsEditing(false)} />;
Expand All @@ -30,13 +31,13 @@ const RoomInfoRouter = ({ onClickBack, onEnterRoom, resetState }: RoomInfoRouter
return (
<RoomInfo
room={room}
icon={room.t === 'p' ? 'lock' : 'hashtag'}
onClickBack={onClickBack}
onClickEdit={canEdit ? () => setIsEditing(true) : undefined}
onClickClose={closeTab}
{...(Boolean(onEnterRoom) && {
onClickEnterRoom,
})}
onClickViewChannels={room.teamMain ? onClickViewChannels : undefined}
resetState={resetState}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { IRoom, Serialized } from '@rocket.chat/core-typings';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useEndpoint, useSetModal, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';

import ConvertToChannelModal from '../../../../../teams/contextualBar/info/ConvertToChannel';

export const useConvertToChannel = (room: IRoom) => {
const t = useTranslation();
const setModal = useSetModal();
const dispatchToastMessage = useToastMessageDispatch();
const convertTeamToChannel = useEndpoint('POST', '/v1/teams.convertToChannel');

const onClickConvertToChannel = useEffectEvent(() => {
if (!room.teamId) {
return;
}

const onConfirm = async (roomsToRemove: { [key: string]: Serialized<IRoom> }) => {
if (!room.teamId) {
return;
}

try {
await convertTeamToChannel({
teamId: room.teamId,
roomsToRemove: Object.keys(roomsToRemove),
});

dispatchToastMessage({ type: 'success', message: t('Success') });
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
} finally {
setModal(null);
}
};

setModal(<ConvertToChannelModal onCancel={() => setModal(null)} onConfirm={onConfirm} teamId={room.teamId} />);
});

return room.teamMain ? onClickConvertToChannel : undefined;
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useSetModal, useToastMessageDispatch, useMethod, useTranslation, useRouter } from '@rocket.chat/ui-contexts';
import React from 'react';

import { UiTextContext } from '../../../../../../../definition/IRoomTypeConfig';
import WarningModal from '../../../../../../components/WarningModal';
import { GenericModalDoNotAskAgain } from '../../../../../../components/GenericModal';
import { useDontAskAgain } from '../../../../../../hooks/useDontAskAgain';
import { roomCoordinator } from '../../../../../../lib/rooms/roomCoordinator';

export const useRoomHide = (room: IRoom) => {
Expand All @@ -15,7 +16,9 @@ export const useRoomHide = (room: IRoom) => {
const hideRoom = useMethod('hideRoom');
const router = useRouter();

const handleHide = useMutableCallback(async () => {
const dontAskHideRoom = useDontAskAgain('hideRoom');

const handleHide = useEffectEvent(async () => {
const hide = async () => {
try {
await hideRoom(room._id);
Expand All @@ -28,15 +31,24 @@ export const useRoomHide = (room: IRoom) => {

const warnText = roomCoordinator.getRoomDirectives(room.t).getUiText(UiTextContext.HIDE_WARNING);

if (dontAskHideRoom) {
return hide();
}

setModal(
<WarningModal
text={t(warnText as TranslationKey, room.fname || room.name)}
<GenericModalDoNotAskAgain
variant='danger'
confirmText={t('Yes_hide_it')}
close={() => setModal(null)}
cancel={() => setModal(null)}
cancelText={t('Cancel')}
confirm={hide}
/>,
onCancel={() => setModal(null)}
onConfirm={hide}
dontAskAgain={{
action: 'hideRoom',
label: t('Hide_room'),
}}
>
{t(warnText as TranslationKey, room.fname)}
</GenericModalDoNotAskAgain>,
);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import type { IRoom, Serialized } from '@rocket.chat/core-typings';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useRouter, useSetModal, useToastMessageDispatch, useMethod, useTranslation, usePermission } from '@rocket.chat/ui-contexts';
import {
useRouter,
useSetModal,
useToastMessageDispatch,
useMethod,
useTranslation,
usePermission,
useEndpoint,
} from '@rocket.chat/ui-contexts';
import React from 'react';

import { LegacyRoomManager } from '../../../../../../../app/ui-utils/client';
import { UiTextContext } from '../../../../../../../definition/IRoomTypeConfig';
import WarningModal from '../../../../../../components/WarningModal';
import { roomCoordinator } from '../../../../../../lib/rooms/roomCoordinator';
import LeaveTeam from '../../../../../teams/contextualBar/info/LeaveTeam';

// TODO implement joined
export const useRoomLeave = (room: IRoom, joined = true) => {
const t = useTranslation();
const setModal = useSetModal();
const dispatchToastMessage = useToastMessageDispatch();
const leaveRoom = useMethod('leaveRoom');
const leaveTeam = useEndpoint('POST', '/v1/teams.leave');

const router = useRouter();

const canLeave = usePermission(room.t === 'c' ? 'leave-c' : 'leave-p') && room.cl !== false && joined;

const handleLeave = useMutableCallback(() => {
const handleLeave = useEffectEvent(() => {
if (room.teamMain && room.teamId) {
const onConfirm = async (selectedRooms?: { [key: string]: Serialized<IRoom> & { isLastOwner?: boolean } }) => {
if (!room.teamId) {
return;
}

const roomsToLeave = selectedRooms?.length ? Object.keys(selectedRooms) : [];

try {
await leaveTeam({
teamId: room.teamId,
...(roomsToLeave.length && { rooms: roomsToLeave }),
});
dispatchToastMessage({ type: 'success', message: t('Teams_left_team_successfully') });
router.navigate('/home');
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
} finally {
setModal(null);
}
};

setModal(<LeaveTeam onConfirm={onConfirm} onCancel={() => setModal(null)} teamId={room.teamId} />);
}

const leaveAction = async () => {
try {
await leaveRoom(room._id);
Expand Down