55
66import type { TabsProps } from "antd" ;
77import { Avatar , Popover , Tabs , Tooltip } from "antd" ;
8- import { cloneElement , CSSProperties , useMemo , useState } from "react" ;
8+ import { CSSProperties , useMemo , useState } from "react" ;
99
1010import {
1111 CSS ,
@@ -17,8 +17,8 @@ import {
1717import { set_window_title } from "@cocalc/frontend/browser" ;
1818import { Icon , Loading } from "@cocalc/frontend/components" ;
1919import {
20- SortableTabs ,
2120 SortableTab ,
21+ SortableTabs ,
2222 useItemContext ,
2323 useSortable ,
2424} from "@cocalc/frontend/components/sortable-tabs" ;
@@ -31,7 +31,6 @@ import { COLORS } from "@cocalc/util/theme";
3131import { useProjectState } from "../project/page/project-state-hook" ;
3232import { useProjectHasInternetAccess } from "../project/settings/has-internet-access-hook" ;
3333import { BuyLicenseForProject } from "../site-licenses/purchase/buy-license-for-project" ;
34- import { blendBackgroundColor } from "./util" ;
3534
3635const PROJECT_NAME_STYLE : CSS = {
3736 whiteSpace : "nowrap" ,
@@ -176,15 +175,36 @@ function ProjectTab({ project_id }: ProjectTabProps) {
176175
177176 function renderAvatar ( ) {
178177 const avatar = project ?. get ( "avatar_image_tiny" ) ;
179- if ( ! avatar ) return ;
180- return (
181- < Avatar
182- style = { { marginTop : "-2px" } }
183- shape = "circle"
184- icon = { < img src = { project . get ( "avatar_image_tiny" ) } /> }
185- size = { 20 }
186- />
187- ) ;
178+ const color = project ?. get ( "color" ) ;
179+
180+ if ( avatar ) {
181+ // Avatar exists: show it with colored border
182+ return (
183+ < Avatar
184+ style = { {
185+ marginTop : "-2px" ,
186+ border : color ? `2px solid ${ color } ` : undefined ,
187+ } }
188+ shape = "circle"
189+ icon = { < img src = { project . get ( "avatar_image_tiny" ) } /> }
190+ size = { 20 }
191+ />
192+ ) ;
193+ } else if ( color ) {
194+ // No avatar but has color: show colored circle
195+ return (
196+ < Avatar
197+ style = { {
198+ marginTop : "-2px" ,
199+ backgroundColor : color ,
200+ } }
201+ shape = "circle"
202+ size = { 20 }
203+ />
204+ ) ;
205+ }
206+
207+ return undefined ;
188208 }
189209
190210 function onMouseUp ( e : React . MouseEvent ) {
@@ -242,7 +262,7 @@ export function ProjectsNav(props: ProjectsNavProps) {
242262 const projectActions = useActions ( "projects" ) ;
243263 const activeTopTab = useTypedRedux ( "page" , "active_top_tab" ) ;
244264 const openProjects = useTypedRedux ( "projects" , "open_projects" ) ;
245- const project_map = useTypedRedux ( "projects" , "project_map" ) ;
265+ // const project_map = useTypedRedux("projects", "project_map");
246266
247267 const items : TabsProps [ "items" ] = useMemo ( ( ) => {
248268 if ( openProjects == null ) return [ ] ;
@@ -259,14 +279,14 @@ export function ProjectsNav(props: ProjectsNavProps) {
259279 return openProjects . toJS ( ) . map ( ( project_id ) => project_id ) ;
260280 } , [ openProjects ] ) ;
261281
262- const onEdit = ( project_id : string , action : "add" | "remove" ) => {
263- if ( action == "add" ) {
282+ function onEdit ( project_id : string , action : "add" | "remove" ) {
283+ if ( action === "add" ) {
264284 actions . set_active_tab ( "projects" ) ;
265285 } else {
266286 // close given project
267287 actions . close_project_tab ( project_id ) ;
268288 }
269- } ;
289+ }
270290
271291 function onDragEnd ( event ) {
272292 const { active, over } = event ;
@@ -289,39 +309,25 @@ export function ProjectsNav(props: ProjectsNavProps) {
289309 { ( node ) => {
290310 const project_id = node . key ;
291311 const isActive = project_id === activeTopTab ;
292- const projectColor = project_map ?. getIn ( [ project_id , "color" ] ) as
293- | string
294- | undefined ;
295312
296313 const wrapperStyle : CSS = {
297314 border : isActive
298- ? `2px solid ${ projectColor ? projectColor : "#d3d3d3" } `
299- : `2px solid ${ projectColor ? projectColor : "transparent" } ` ,
315+ ? `2px solid ${ "#d3d3d3" } `
316+ : `2px solid ${ "transparent" } ` ,
300317 borderRadius : "8px" ,
301318 } ;
302319
303- // Add background color if project has a color
304- if ( projectColor ) {
305- // Active tab: lighter/brighter (less color), inactive: darker (more color)
306- wrapperStyle . backgroundColor = blendBackgroundColor (
307- projectColor ,
308- isActive ? "white" : COLORS . GRAY_LL ,
309- ! isActive ,
310- ) ;
311- }
312-
313- // Clone the node with additional style props to override Ant Design's background
314- const styledNode = cloneElement ( node , {
315- style : {
316- ...node . props . style ,
317- backgroundColor : wrapperStyle . backgroundColor ,
318- } ,
319- } ) ;
320-
321- // this is similar to the renderTabBar in sortable-tabs.tsx, but with the above, also styles the background
320+ // Kept for reference, this allows to tweak the node props directly
321+ // const styledNode = cloneElement(node, {
322+ // style: {
323+ // ...node.props.style,
324+ // backgroundColor: wrapperStyle.backgroundColor,
325+ // },
326+ // });
327+
322328 return (
323329 < SortableTab key = { node . key } id = { node . key } style = { wrapperStyle } >
324- { styledNode }
330+ { node }
325331 </ SortableTab >
326332 ) ;
327333 } }
0 commit comments