262 lines
7.7 KiB
TypeScript
262 lines
7.7 KiB
TypeScript
import React from 'react';
|
||
import TopNavbar, { MenuItem } from 'shared/components/TopNavbar';
|
||
import LoggedOutNavbar from 'shared/components/TopNavbar/LoggedOut';
|
||
import { ProfileMenu } from 'shared/components/DropdownMenu';
|
||
import { useHistory } from 'react-router';
|
||
import { useCurrentUser } from 'App/context';
|
||
import { RoleCode, useTopNavbarQuery } from 'shared/generated/graphql';
|
||
import { usePopup, Popup } from 'shared/components/PopupMenu';
|
||
import MiniProfile from 'shared/components/MiniProfile';
|
||
import cache from 'App/cache';
|
||
import NotificationPopup, { NotificationItem } from 'shared/components/NotifcationPopup';
|
||
import theme from 'App/ThemeStyles';
|
||
import ProjectFinder from './ProjectFinder';
|
||
|
||
// TODO: Move to context based navbar?
|
||
|
||
type GlobalTopNavbarProps = {
|
||
nameOnly?: boolean;
|
||
projectID: string | null;
|
||
teamID?: string | null;
|
||
onChangeProjectOwner?: (userID: string) => void;
|
||
name: string | null;
|
||
currentTab?: number;
|
||
popupContent?: JSX.Element;
|
||
menuType?: Array<MenuItem>;
|
||
onChangeRole?: (userID: string, roleCode: RoleCode) => void;
|
||
projectMembers?: null | Array<TaskUser>;
|
||
projectInvitedMembers?: null | Array<InvitedUser>;
|
||
onSaveProjectName?: (projectName: string) => void;
|
||
onInviteUser?: ($target: React.RefObject<HTMLElement>) => void;
|
||
onSetTab?: (tab: number) => void;
|
||
onRemoveFromBoard?: (userID: string) => void;
|
||
onRemoveInvitedFromBoard?: (email: string) => void;
|
||
};
|
||
|
||
const LoggedInNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||
currentTab,
|
||
onSetTab,
|
||
menuType,
|
||
teamID,
|
||
onChangeProjectOwner,
|
||
onChangeRole,
|
||
name,
|
||
popupContent,
|
||
projectMembers,
|
||
projectInvitedMembers,
|
||
onInviteUser,
|
||
onSaveProjectName,
|
||
onRemoveInvitedFromBoard,
|
||
onRemoveFromBoard,
|
||
}) => {
|
||
const { data } = useTopNavbarQuery();
|
||
const { showPopup, hidePopup } = usePopup();
|
||
const { setUser } = useCurrentUser();
|
||
const history = useHistory();
|
||
const onLogout = () => {
|
||
fetch('/auth/logout', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
}).then(async x => {
|
||
const { status } = x;
|
||
if (status === 200) {
|
||
cache.reset();
|
||
history.replace('/login');
|
||
setUser(null);
|
||
hidePopup();
|
||
}
|
||
});
|
||
};
|
||
const onProfileClick = ($target: React.RefObject<HTMLElement>) => {
|
||
showPopup(
|
||
$target,
|
||
<Popup title={null} tab={0}>
|
||
<ProfileMenu
|
||
onLogout={onLogout}
|
||
showAdminConsole // TODO: add permision check
|
||
onAdminConsole={() => {
|
||
history.push('/admin');
|
||
hidePopup();
|
||
}}
|
||
onProfile={() => {
|
||
history.push('/profile');
|
||
hidePopup();
|
||
}}
|
||
/>
|
||
</Popup>,
|
||
{ width: 195 },
|
||
);
|
||
};
|
||
|
||
const onOpenSettings = ($target: React.RefObject<HTMLElement>) => {
|
||
if (popupContent) {
|
||
showPopup($target, popupContent, { width: 185 });
|
||
}
|
||
};
|
||
|
||
const onNotificationClick = ($target: React.RefObject<HTMLElement>) => {
|
||
if (data) {
|
||
showPopup(
|
||
$target,
|
||
<NotificationPopup>
|
||
{data.notifications.map(notification => (
|
||
<NotificationItem
|
||
title={notification.entity.name}
|
||
description={`${notification.actor.name} added you as a meber to the task "${notification.entity.name}"`}
|
||
createdAt={notification.createdAt}
|
||
/>
|
||
))}
|
||
</NotificationPopup>,
|
||
{ width: 415, borders: false, diamondColor: theme.colors.primary },
|
||
);
|
||
}
|
||
};
|
||
|
||
// TODO: readd permision check
|
||
// const userIsTeamOrProjectAdmin = user.isAdmin(PermissionLevel.TEAM, PermissionObjectType.TEAM, teamID);
|
||
const userIsTeamOrProjectAdmin = true;
|
||
const onInvitedMemberProfile = ($targetRef: React.RefObject<HTMLElement>, email: string) => {
|
||
const member = projectInvitedMembers ? projectInvitedMembers.find(u => u.email === email) : null;
|
||
if (member) {
|
||
showPopup(
|
||
$targetRef,
|
||
<MiniProfile
|
||
onRemoveFromBoard={() => {
|
||
if (onRemoveInvitedFromBoard) {
|
||
onRemoveInvitedFromBoard(member.email);
|
||
}
|
||
}}
|
||
invited
|
||
user={{
|
||
id: member.email,
|
||
fullName: member.email,
|
||
bio: 'Invited',
|
||
profileIcon: {
|
||
bgColor: '#000',
|
||
url: null,
|
||
initials: member.email.charAt(0),
|
||
},
|
||
}}
|
||
bio=""
|
||
/>,
|
||
);
|
||
}
|
||
};
|
||
|
||
const onMemberProfile = ($targetRef: React.RefObject<HTMLElement>, memberID: string) => {
|
||
const member = projectMembers ? projectMembers.find(u => u.id === memberID) : null;
|
||
const warning =
|
||
'You can’t leave because you are the only admin. To make another user an admin, click their avatar, select “Change permissions…”, and select “Admin”.';
|
||
if (member) {
|
||
showPopup(
|
||
$targetRef,
|
||
<MiniProfile
|
||
warning={member.role && member.role.code === 'owner' ? warning : null}
|
||
canChangeRole={userIsTeamOrProjectAdmin}
|
||
onChangeRole={roleCode => {
|
||
if (onChangeRole) {
|
||
onChangeRole(member.id, roleCode);
|
||
}
|
||
}}
|
||
onRemoveFromBoard={
|
||
member.role && member.role.code === 'owner'
|
||
? undefined
|
||
: () => {
|
||
if (onRemoveFromBoard) {
|
||
onRemoveFromBoard(member.id);
|
||
}
|
||
}
|
||
}
|
||
user={member}
|
||
bio=""
|
||
/>,
|
||
);
|
||
}
|
||
};
|
||
|
||
const user = data ? data.me?.user : null;
|
||
|
||
return (
|
||
<>
|
||
<TopNavbar
|
||
name={name}
|
||
menuType={menuType}
|
||
onOpenProjectFinder={$target => {
|
||
showPopup(
|
||
$target,
|
||
<Popup tab={0} title={null}>
|
||
<ProjectFinder />
|
||
</Popup>,
|
||
);
|
||
}}
|
||
currentTab={currentTab}
|
||
user={user ?? null}
|
||
canEditProjectName={userIsTeamOrProjectAdmin}
|
||
canInviteUser={userIsTeamOrProjectAdmin}
|
||
onMemberProfile={onMemberProfile}
|
||
onInvitedMemberProfile={onInvitedMemberProfile}
|
||
onInviteUser={onInviteUser}
|
||
onChangeRole={onChangeRole}
|
||
onChangeProjectOwner={onChangeProjectOwner}
|
||
onNotificationClick={onNotificationClick}
|
||
onSetTab={onSetTab}
|
||
onRemoveFromBoard={onRemoveFromBoard}
|
||
onDashboardClick={() => {
|
||
history.push('/');
|
||
}}
|
||
onMyTasksClick={() => {
|
||
history.push('/tasks');
|
||
}}
|
||
projectMembers={projectMembers}
|
||
projectInvitedMembers={projectInvitedMembers}
|
||
onProfileClick={onProfileClick}
|
||
onSaveName={onSaveProjectName}
|
||
onOpenSettings={onOpenSettings}
|
||
/>
|
||
</>
|
||
);
|
||
};
|
||
|
||
const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||
currentTab,
|
||
onSetTab,
|
||
menuType,
|
||
teamID,
|
||
onChangeProjectOwner,
|
||
onChangeRole,
|
||
name,
|
||
popupContent,
|
||
projectMembers,
|
||
projectInvitedMembers,
|
||
onInviteUser,
|
||
onSaveProjectName,
|
||
onRemoveInvitedFromBoard,
|
||
onRemoveFromBoard,
|
||
}) => {
|
||
const { user } = useCurrentUser();
|
||
if (user) {
|
||
return (
|
||
<LoggedInNavbar
|
||
currentTab={currentTab}
|
||
projectID={null}
|
||
onSetTab={onSetTab}
|
||
menuType={menuType}
|
||
teamID={teamID}
|
||
onChangeRole={onChangeRole}
|
||
onChangeProjectOwner={onChangeProjectOwner}
|
||
name={name}
|
||
popupContent={popupContent}
|
||
projectMembers={projectMembers}
|
||
projectInvitedMembers={projectInvitedMembers}
|
||
onInviteUser={onInviteUser}
|
||
onSaveProjectName={onSaveProjectName}
|
||
onRemoveInvitedFromBoard={onRemoveInvitedFromBoard}
|
||
onRemoveFromBoard={onRemoveFromBoard}
|
||
/>
|
||
);
|
||
}
|
||
return <LoggedOutNavbar name={name} menuType={menuType} />;
|
||
};
|
||
|
||
export default GlobalTopNavbar;
|