Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions client/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC } from 'react';
import React, { FC, isValidElement, ReactElement } from 'react';
import { css } from '@rocket.chat/css-in-js';
import colors from '@rocket.chat/fuselage-tokens/colors';
import {
Expand All @@ -12,14 +12,19 @@ import {
Tag,
TagProps,
BoxProps,
Skeleton,
} from '@rocket.chat/fuselage';

type HeaderIconProps = {icon: ReactElement | { name: string; color?: string } | null};

const Title: FC = (props: any) => <Box color='default' mi='x4' fontScale='s2' withTruncatedText {...props}/>;
const Subtitle: FC = (props: any) => <Box color='hint' fontScale='p1' withTruncatedText {...props}/>;

const Row: FC = (props: any) => <Box alignItems='center' flexShrink={1} flexGrow={1} display='flex' {...props}/>;

const HeaderIcon: FC<{ icon: JSX.Element | { name: string; color?: string } | null}> = ({ icon }) => icon && <Box display='flex' flexShrink={0} alignItems='center' size={18} overflow='hidden' justifyContent='center'>{React.isValidElement(icon) ? icon : <Icon color='info' size='x18' { ...{ name: (icon as any).name }} />}</Box>;
const HeaderIcon: FC<HeaderIconProps> = ({ icon }) => icon && <Box display='flex' flexShrink={0} alignItems='center' size={18} overflow='hidden' justifyContent='center'>
{React.isValidElement(icon) ? icon : <Icon color='info' size='x18' { ...{ name: (icon as any).name }} />}
</Box>;

const ToolBox: FC = (props: any) => <ButtonGroup mi='x4' medium {...props}/>;

Expand All @@ -41,6 +46,12 @@ const HeaderLink: FC = (props: BoxProps) => <Box

const HeaderTag: FC = ({ children, ...props }: TagProps) => <Box mi='x4'><Tag {...props}><Box alignItems='center' fontScale='c2' display='flex'>{children}</Box></Tag></Box>;

const HeaderTagIcon: FC<HeaderIconProps> = ({ icon }) => (icon ? <Box w='x20' mi='x2' display='inline-flex' justifyContent='center'>
{isValidElement(icon) ? icon : <Icon size='x20' {...icon}/>}
</Box> : null);

const HeaderTagSkeleton: FC = () => <Skeleton width='x48'/>;

const ToolBoxAction: FC = ({ id, icon, color, title, action, className, tabId, index, ...props }: any) => <ActionButton
className={className}
primary={tabId === id}
Expand Down Expand Up @@ -86,6 +97,11 @@ Object.assign(ToolBoxAction, {
Badge: ToolBoxActionBadge,
});

Object.assign(HeaderTag, {
Icon: HeaderTagIcon,
Skeleton: HeaderTagSkeleton,
});

Object.assign(Header, {
Button,
State,
Expand Down
50 changes: 27 additions & 23 deletions client/views/room/Header/Header.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useMemo, useEffect } from 'react';
import { Meteor } from 'meteor/meteor';
import { Box, Skeleton, Icon } from '@rocket.chat/fuselage';
import { Box } from '@rocket.chat/fuselage';

import Header from '../../../components/Header';
import { useRoomIcon } from '../../../hooks/useRoomIcon';
Expand Down Expand Up @@ -34,16 +33,14 @@ export default React.memo(({ room }) => {
return <RoomHeader room={room} topic={room.topic} />;
});

const HeaderIcon = ({ room }) => {
const HeaderIconWithRoom = ({ room }) => {
const icon = useRoomIcon(room);

return <Box w='x20' mi='x2' display='inline-flex' justifyContent='center'>
{icon.name ? <Icon size='x20' {...icon}/> : icon}
</Box>;
return <Header.Tag.Icon icon={icon} />;
};

const RoomTitle = ({ room }) => <>
<HeaderIcon room={room}/>
<HeaderIconWithRoom room={room}/>
<Header.Title>{room.name}</Header.Title>
</>;

Expand Down Expand Up @@ -73,7 +70,7 @@ const ParentRoomWithEndpointData = ({ rid }) => {
}, [reset, getData, rid, resolve, reject]);

if (AsyncStatePhase.LOADING === phase) {
return <Skeleton width='x48'/>;
return <Header.Tag.Skeleton />;
}

if (AsyncStatePhase.ERROR === phase || !value?.room) {
Expand All @@ -87,34 +84,41 @@ const ParentRoom = ({ room }) => {
const href = roomTypes.getRouteLink(room.t, room);

return <Header.Tag>
<HeaderIcon room={room}/>
<HeaderIconWithRoom room={room}/>
<Header.Link href={href}>
{roomTypes.getRoomName(room.t, room)}
</Header.Link>
</Header.Tag>;
};

const ParentTeam = ({ room }) => {
const query = useMemo(() => ({ teamId: room.teamId }), [room.teamId]);
const userTeamQuery = useMemo(() => ({ userId: Meteor.userId() }), []);
const userId = useUserId();

const { value, phase } = useEndpointData('teams.info', query);
const { value: userTeams, phase: userTeamsPhase } = useEndpointData('users.listTeams', userTeamQuery);
const { value, phase } = useEndpointData('teams.info', useMemo(() => ({ teamId: room.teamId }), [room.teamId]));
const { value: userTeams, phase: userTeamsPhase } = useEndpointData('users.listTeams', useMemo(() => ({ userId }), [userId]));

const teamLoading = phase === AsyncStatePhase.LOADING;
const userTeamsLoading = userTeamsPhase === AsyncStatePhase.LOADING;
const belongsToTeam = userTeams?.teams?.find((team) => team._id === room.teamId);

const teamMainRoom = useUserSubscription(value?.teamInfo?.roomId);
const teamMainRoomHref = teamMainRoom ? roomTypes.getRouteLink(teamMainRoom.t, teamMainRoom) : null;

return teamLoading || userTeamsLoading || room.teamMain ? null : <Header.Tag>
<HeaderIcon room={teamMainRoom}/>
{belongsToTeam
? <Header.Link href={teamMainRoomHref}>{teamMainRoom?.name}</Header.Link>
: teamMainRoom?.name
}
</Header.Tag>;
if (phase === AsyncStatePhase.LOADING || userTeamsPhase === AsyncStatePhase.LOADING) {
return <Header.Tag.Skeleton />;
}

if (phase === AsyncStatePhase.REJECTED || !value.teamInfo) {
return null;
}

return (
<Header.Tag>
<Header.Tag.Icon icon={{ name: 'team' }} />
{belongsToTeam && teamMainRoom
? <Header.Link href={teamMainRoomHref}>{teamMainRoom?.name}</Header.Link>
: value.teamInfo.name
}
</Header.Tag>
);
};
const DirectRoomHeader = ({ room }) => {
const userId = useUserId();
Expand All @@ -138,7 +142,7 @@ const RoomHeader = ({ room, topic }) => {
<RoomTitle room={room}/>
<Favorite room={room} />
{room.prid && <ParentRoomWithData room={room} />}
{room.teamId && <ParentTeam room={room} />}
{room.teamId && !room.teamMain && <ParentTeam room={room} />}
<Encrypted room={room} />
<Translate room={room} />
{ showQuickActions && <Box mis='x20' display='flex'>
Expand Down