2020-05-31 06:11:19 +02:00
import React , { useRef , useState , useEffect } from 'react' ;
2020-06-23 22:20:53 +02:00
import { Home , Star , Bell , AngleDown , BarChart , CheckCircle } from 'shared/icons' ;
import styled from 'styled-components' ;
2020-06-13 00:21:58 +02:00
import ProfileIcon from 'shared/components/ProfileIcon' ;
2020-06-23 22:20:53 +02:00
import TaskAssignee from 'shared/components/TaskAssignee' ;
import { usePopup , Popup } from 'shared/components/PopupMenu' ;
2020-07-05 01:02:57 +02:00
import { RoleCode } from 'shared/generated/graphql' ;
2020-06-23 22:20:53 +02:00
import MiniProfile from 'shared/components/MiniProfile' ;
2020-04-10 04:40:22 +02:00
import {
2020-06-23 22:20:53 +02:00
CitadelLogo ,
CitadelTitle ,
ProjectFinder ,
LogoContainer ,
NavSeparator ,
IconContainer ,
2020-05-31 06:11:19 +02:00
ProjectNameTextarea ,
2020-05-27 23:18:50 +02:00
InviteButton ,
2020-04-10 04:40:22 +02:00
GlobalActions ,
ProjectActions ,
2020-04-21 01:04:27 +02:00
ProjectMeta ,
ProjectName ,
ProjectTabs ,
ProjectTab ,
2020-04-10 04:40:22 +02:00
NavbarWrapper ,
NavbarHeader ,
2020-05-27 02:53:31 +02:00
ProjectSettingsButton ,
2020-04-10 04:40:22 +02:00
ProfileContainer ,
ProfileNameWrapper ,
ProfileNamePrimary ,
ProfileNameSecondary ,
2020-07-05 01:02:57 +02:00
ProjectMember ,
2020-05-27 23:18:50 +02:00
ProjectMembers ,
2020-04-10 04:40:22 +02:00
} from './Styles' ;
2020-06-23 22:20:53 +02:00
import { Link } from 'react-router-dom' ;
const HomeDashboard = styled ( Home ) ` ` ;
2020-04-10 04:40:22 +02:00
2020-05-31 06:11:19 +02:00
type ProjectHeadingProps = {
2020-06-23 22:20:53 +02:00
onFavorite ? : ( ) = > void ;
name : string ;
2020-05-31 06:11:19 +02:00
onSaveProjectName ? : ( projectName : string ) = > void ;
2020-06-01 04:20:03 +02:00
onOpenSettings : ( $target : React.RefObject < HTMLElement > ) = > void ;
2020-05-31 06:11:19 +02:00
} ;
2020-06-01 04:20:03 +02:00
const ProjectHeading : React.FC < ProjectHeadingProps > = ( {
2020-06-23 22:20:53 +02:00
onFavorite ,
name : initialProjectName ,
2020-06-01 04:20:03 +02:00
onSaveProjectName ,
onOpenSettings ,
} ) = > {
2020-05-31 06:11:19 +02:00
const [ isEditProjectName , setEditProjectName ] = useState ( false ) ;
const [ projectName , setProjectName ] = useState ( initialProjectName ) ;
const $projectName = useRef < HTMLTextAreaElement > ( null ) ;
useEffect ( ( ) = > {
if ( isEditProjectName && $projectName && $projectName . current ) {
$projectName . current . focus ( ) ;
$projectName . current . select ( ) ;
}
} , [ isEditProjectName ] ) ;
useEffect ( ( ) = > {
setProjectName ( initialProjectName ) ;
} , [ initialProjectName ] ) ;
const onProjectNameChange = ( event : React.FormEvent < HTMLTextAreaElement > ) : void = > {
setProjectName ( event . currentTarget . value ) ;
} ;
const onProjectNameBlur = ( ) = > {
if ( onSaveProjectName ) {
onSaveProjectName ( projectName ) ;
}
setEditProjectName ( false ) ;
} ;
const onProjectNameKeyDown = ( e : React.KeyboardEvent ) = > {
if ( e . key === 'Enter' ) {
e . preventDefault ( ) ;
if ( $projectName && $projectName . current ) {
$projectName . current . blur ( ) ;
}
}
} ;
2020-06-01 04:20:03 +02:00
const $settings = useRef < HTMLButtonElement > ( null ) ;
2020-05-31 06:11:19 +02:00
return (
< >
{ isEditProjectName ? (
< ProjectNameTextarea
ref = { $projectName }
onChange = { onProjectNameChange }
onKeyDown = { onProjectNameKeyDown }
onBlur = { onProjectNameBlur }
spellCheck = { false }
value = { projectName }
/ >
) : (
< ProjectName
onClick = { ( ) = > {
setEditProjectName ( true ) ;
} }
>
{ projectName }
< / ProjectName >
) }
2020-06-01 04:20:03 +02:00
< ProjectSettingsButton
onClick = { ( ) = > {
onOpenSettings ( $settings ) ;
} }
ref = { $settings }
>
2020-05-31 07:15:10 +02:00
< AngleDown color = "#c2c6dc" / >
< / ProjectSettingsButton >
2020-06-23 22:20:53 +02:00
{ onFavorite && (
< ProjectSettingsButton onClick = { ( ) = > onFavorite ( ) } >
< Star width = { 16 } height = { 16 } color = "#c2c6dc" / >
< / ProjectSettingsButton >
) }
2020-05-31 06:11:19 +02:00
< / >
) ;
} ;
2020-07-05 01:02:57 +02:00
export type MenuItem = {
name : string ;
link : string ;
2020-06-23 22:20:53 +02:00
} ;
type MenuTypes = {
[ key : string ] : Array < string > ;
} ;
export const MENU_TYPES : MenuTypes = {
PROJECT_MENU : [ 'Board' , 'Timeline' , 'Calender' ] ,
TEAM_MENU : [ 'Projects' , 'Members' , 'Settings' ] ,
} ;
2020-04-10 04:40:22 +02:00
type NavBarProps = {
2020-07-05 01:02:57 +02:00
menuType? : Array < MenuItem > | null ;
2020-06-23 22:20:53 +02:00
name : string | null ;
currentTab? : number ;
2020-07-05 01:02:57 +02:00
onSetTab ? : ( tab : number ) = > void ;
2020-06-23 22:20:53 +02:00
onOpenProjectFinder : ( $target : React.RefObject < HTMLElement > ) = > void ;
2020-07-05 01:02:57 +02:00
onChangeProjectOwner ? : ( userID : string ) = > void ;
onChangeRole ? : ( userID : string , roleCode : RoleCode ) = > void ;
2020-06-23 22:20:53 +02:00
onFavorite ? : ( ) = > void ;
2020-06-13 00:21:58 +02:00
onProfileClick : ( $target : React.RefObject < HTMLElement > ) = > void ;
2020-06-23 22:20:53 +02:00
onSaveName ? : ( name : string ) = > void ;
2020-04-10 04:40:22 +02:00
onNotificationClick : ( ) = > void ;
2020-07-05 01:02:57 +02:00
onInviteUser ? : ( $target : React.RefObject < HTMLElement > ) = > void ;
2020-06-23 22:20:53 +02:00
onDashboardClick : ( ) = > void ;
2020-06-13 00:21:58 +02:00
user : TaskUser | null ;
2020-06-01 04:20:03 +02:00
onOpenSettings : ( $target : React.RefObject < HTMLElement > ) = > void ;
2020-05-27 23:18:50 +02:00
projectMembers? : Array < TaskUser > | null ;
2020-07-05 01:02:57 +02:00
onRemoveFromBoard ? : ( userID : string ) = > void ;
2020-04-10 04:40:22 +02:00
} ;
2020-05-31 06:11:19 +02:00
2020-04-21 01:04:27 +02:00
const NavBar : React.FC < NavBarProps > = ( {
2020-06-23 22:20:53 +02:00
menuType ,
2020-07-05 01:02:57 +02:00
onInviteUser ,
onChangeProjectOwner ,
2020-06-23 22:20:53 +02:00
currentTab ,
onOpenProjectFinder ,
onFavorite ,
2020-07-05 01:02:57 +02:00
onSetTab ,
onChangeRole ,
2020-06-23 22:20:53 +02:00
name ,
2020-07-05 01:02:57 +02:00
onRemoveFromBoard ,
2020-06-23 22:20:53 +02:00
onSaveName ,
2020-04-21 01:04:27 +02:00
onProfileClick ,
onNotificationClick ,
2020-06-23 22:20:53 +02:00
onDashboardClick ,
2020-06-13 00:21:58 +02:00
user ,
2020-05-27 23:18:50 +02:00
projectMembers ,
2020-06-01 04:20:03 +02:00
onOpenSettings ,
2020-04-21 01:04:27 +02:00
} ) = > {
2020-06-13 00:21:58 +02:00
const handleProfileClick = ( $target : React.RefObject < HTMLElement > ) = > {
if ( $target && $target . current ) {
onProfileClick ( $target ) ;
}
2020-04-10 04:40:22 +02:00
} ;
2020-05-27 23:18:50 +02:00
const { showPopup } = usePopup ( ) ;
const onMemberProfile = ( $targetRef : React.RefObject < HTMLElement > , memberID : string ) = > {
2020-07-05 01:02:57 +02:00
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 ) {
console . log ( member ) ;
showPopup (
$targetRef ,
2020-05-27 23:18:50 +02:00
< MiniProfile
2020-07-05 01:02:57 +02:00
warning = { member . role && member . role . code === 'owner' ? warning : null }
onChangeProjectOwner = {
member . role && member . role . code !== 'owner'
? ( userID : string ) = > {
if ( user && onChangeProjectOwner ) {
onChangeProjectOwner ( userID ) ;
}
}
: undefined
}
canChangeRole = { member . role && member . role . code !== 'owner' }
onChangeRole = { roleCode = > {
if ( onChangeRole ) {
onChangeRole ( member . id , roleCode ) ;
}
} }
onRemoveFromBoard = {
member . role && member . role . code === 'owner'
? undefined
: ( ) = > {
if ( onRemoveFromBoard ) {
onRemoveFromBoard ( member . id ) ;
}
}
}
user = { member }
bio = ""
/ > ,
) ;
}
2020-05-27 23:18:50 +02:00
} ;
2020-05-31 06:11:19 +02:00
2020-04-10 04:40:22 +02:00
return (
< NavbarWrapper >
< NavbarHeader >
< ProjectActions >
2020-04-21 01:04:27 +02:00
< ProjectMeta >
2020-06-23 22:20:53 +02:00
{ name && (
2020-06-01 04:20:03 +02:00
< ProjectHeading
2020-06-23 22:20:53 +02:00
onFavorite = { onFavorite }
2020-06-01 04:20:03 +02:00
onOpenSettings = { onOpenSettings }
2020-06-23 22:20:53 +02:00
name = { name }
onSaveProjectName = { onSaveName }
2020-06-01 04:20:03 +02:00
/ >
) }
2020-04-21 01:04:27 +02:00
< / ProjectMeta >
2020-06-23 22:20:53 +02:00
{ name && (
2020-05-31 07:15:10 +02:00
< ProjectTabs >
2020-06-23 22:20:53 +02:00
{ menuType &&
2020-07-05 01:02:57 +02:00
menuType . map ( ( menu , idx ) = > {
2020-06-23 23:55:17 +02:00
return (
2020-07-05 01:02:57 +02:00
< ProjectTab
key = { menu . name }
to = { menu . link }
exact
onClick = { ( ) = > {
// TODO
} }
>
{ menu . name }
2020-06-23 23:55:17 +02:00
< / ProjectTab >
) ;
2020-06-23 22:20:53 +02:00
} ) }
2020-05-31 07:15:10 +02:00
< / ProjectTabs >
) }
2020-04-10 04:40:22 +02:00
< / ProjectActions >
2020-06-23 22:20:53 +02:00
< LogoContainer to = "/" >
< CitadelLogo width = { 24 } height = { 24 } / >
< CitadelTitle > Citadel < / CitadelTitle >
< / LogoContainer >
2020-04-10 04:40:22 +02:00
< GlobalActions >
2020-05-27 23:18:50 +02:00
{ projectMembers && (
2020-06-23 22:20:53 +02:00
< >
< ProjectMembers >
2020-07-05 01:02:57 +02:00
{ projectMembers . map ( ( member , idx ) = > (
< ProjectMember
showRoleIcons
zIndex = { projectMembers . length - idx }
key = { member . id }
size = { 28 }
member = { member }
onMemberProfile = { onMemberProfile }
/ >
2020-06-23 22:20:53 +02:00
) ) }
2020-07-05 01:02:57 +02:00
< InviteButton
onClick = { $target = > {
if ( onInviteUser ) {
onInviteUser ( $target ) ;
}
} }
variant = "outline"
>
Invite
< / InviteButton >
2020-06-23 22:20:53 +02:00
< / ProjectMembers >
< NavSeparator / >
< / >
2020-05-27 23:18:50 +02:00
) }
2020-06-23 22:20:53 +02:00
< ProjectFinder onClick = { onOpenProjectFinder } variant = "gradient" >
Projects
< / ProjectFinder >
< IconContainer onClick = { onDashboardClick } >
< HomeDashboard width = { 20 } height = { 20 } / >
< / IconContainer >
2020-06-24 03:46:45 +02:00
< IconContainer disabled >
2020-06-23 22:20:53 +02:00
< CheckCircle width = { 20 } height = { 20 } / >
< / IconContainer >
< IconContainer onClick = { onNotificationClick } >
2020-04-10 04:40:22 +02:00
< Bell color = "#c2c6dc" size = { 20 } / >
2020-06-23 22:20:53 +02:00
< / IconContainer >
2020-06-24 03:46:45 +02:00
< IconContainer disabled >
2020-06-23 22:20:53 +02:00
< BarChart width = { 20 } height = { 20 } / >
< / IconContainer >
2020-06-13 00:21:58 +02:00
{ user && (
2020-06-23 22:20:53 +02:00
< IconContainer >
< ProfileIcon user = { user } size = { 30 } onProfileClick = { handleProfileClick } / >
< / IconContainer >
2020-06-13 00:21:58 +02:00
) }
2020-04-10 04:40:22 +02:00
< / GlobalActions >
< / NavbarHeader >
< / NavbarWrapper >
) ;
} ;
export default NavBar ;