// Copyright 2024, Command Line
// SPDX-License-Identifier: Apache-2.0
import { Button } from "@/element/button";
import {
ExpandableMenu,
ExpandableMenuItem,
ExpandableMenuItemData,
ExpandableMenuItemGroup,
ExpandableMenuItemGroupTitle,
ExpandableMenuItemGroupTitleType,
ExpandableMenuItemLeftElement,
ExpandableMenuItemRightElement,
} from "@/element/expandablemenu";
import { Input } from "@/element/input";
import { Popover, PopoverButton, PopoverContent } from "@/element/popover";
import { makeIconClass } from "@/util/util";
import clsx from "clsx";
import { colord } from "colord";
import { atom, useAtom } from "jotai";
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
import { memo, useEffect, useRef } from "react";
import WorkspaceSVG from "../asset/workspace.svg";
import "./workspaceswitcher.less";
interface ColorSelectorProps {
colors: string[];
selectedColor?: string;
onSelect: (color: string) => void;
className?: string;
}
const ColorSelector = memo(({ colors, selectedColor, onSelect, className }: ColorSelectorProps) => {
const handleColorClick = (color: string) => {
onSelect(color);
};
return (
{colors.map((color) => (
handleColorClick(color)}
/>
))}
);
});
interface IconSelectorProps {
icons: string[];
selectedIcon?: string;
onSelect: (icon: string) => void;
className?: string;
}
const IconSelector = memo(({ icons, selectedIcon, onSelect, className }: IconSelectorProps) => {
const handleIconClick = (icon: string) => {
onSelect(icon);
};
return (
{icons.map((icon) => {
const iconClass = makeIconClass(icon, false);
return (
handleIconClick(icon)}
/>
);
})}
);
});
interface ColorAndIconSelectorProps {
title: string;
icon: string;
color: string;
focusInput: boolean;
onTitleChange: (newTitle: string) => void;
onColorChange: (newColor: string) => void;
onIconChange: (newIcon: string) => void;
onDeleteWorkspace: () => void;
}
const ColorAndIconSelector = memo(
({
title,
icon,
color,
focusInput,
onTitleChange,
onColorChange,
onIconChange,
onDeleteWorkspace,
}: ColorAndIconSelectorProps) => {
const inputRef = useRef
(null);
useEffect(() => {
if (focusInput && inputRef.current) {
inputRef.current.focus();
}
}, [focusInput]);
return (
);
}
);
interface WorkspaceDataType {
id: string;
icon: string;
label: string;
color: string;
isActive: boolean;
}
// Define the global Jotai atom for menuData
const workspaceData: WorkspaceDataType[] = [
{
id: "596e76eb-d87d-425e-9f6e-1519069ee446",
icon: "",
label: "Default",
color: "",
isActive: false,
},
{
id: "596e76eb-d87d-425e-9f6e-1519069ee447",
icon: "shield-cat",
label: "Cat Space",
color: "#e91e63",
isActive: true,
},
{
id: "596e76eb-d87d-425e-9f6e-1519069ee448",
icon: "paw-simple",
label: "Bear Space",
color: "#ffc107",
isActive: false,
},
];
export const menuDataAtom = atom(workspaceData);
const WorkspaceSwitcher = () => {
const [menuData, setMenuData] = useAtom(menuDataAtom);
const handleTitleChange = (id: string, newTitle: string) => {
// This should call a service
setMenuData((prevMenuData) =>
prevMenuData.map((item) => {
if (item.id === id) {
return {
...item,
label: newTitle,
};
}
return item;
})
);
};
const handleColorChange = (id: string, newColor: string) => {
// This should call a service
setMenuData((prevMenuData) =>
prevMenuData.map((item) => {
if (item.id === id) {
return {
...item,
color: newColor,
};
}
return item;
})
);
};
const handleIconChange = (id: string, newIcon: string) => {
// This should call a service
setMenuData((prevMenuData) =>
prevMenuData.map((item) => {
if (item.id === id) {
return {
...item,
icon: newIcon,
};
}
return item;
})
);
};
const setActiveWorkspace = (id: string) => {
// This should call a service
setMenuData((prevMenuData) =>
prevMenuData.map((item) => {
if (item.id === id) {
return {
...item,
isActive: true,
};
}
return {
...item,
isActive: false,
};
})
);
};
const handleAddNewWorkspace = () => {
// This should call a service
const id = `group-${Math.random().toString(36).substr(2, 9)}`;
setMenuData((prevMenuData) => {
const updatedMenuData = prevMenuData.map((item) => ({
...item,
isActive: false,
}));
const newWorkspace = {
id,
icon: "circle",
label: "New Workspace",
color: "#8bc34a",
isActive: true,
};
return [...updatedMenuData, newWorkspace];
});
};
const handleDeleteWorkspace = (id: string) => {
console.log("got here!!!");
// This should call a service
setMenuData((prevMenuData) => {
const updatedMenuData = prevMenuData.filter((item) => item.id !== id);
console.log("updatedMenuData", updatedMenuData);
const isAnyActive = updatedMenuData.some((item) => item.isActive);
if (!isAnyActive && updatedMenuData.length > 0) {
updatedMenuData[0] = { ...updatedMenuData[0], isActive: true };
}
return updatedMenuData;
});
};
const activeWorkspace = menuData.find((workspace) => workspace.isActive);
const data = menuData.map((item): ExpandableMenuItemData => {
const { id, icon, label, color, isActive } = item;
const title: ExpandableMenuItemGroupTitleType = { label };
const leftElement = icon ? (
) : null;
title.leftElement = leftElement;
title.rightElement = isActive ? : null;
if (label === "Default") {
return {
id,
type: "group",
title: {
leftElement: ,
label: "Default",
rightElement: isActive ? : null,
},
};
}
return {
id,
type: "group",
title,
isOpen: isActive,
children: [
{
type: "item",
content: ({ isOpen }: { isOpen: boolean }) => (
handleTitleChange(id, title)}
onColorChange={(color) => handleColorChange(id, color)}
onIconChange={(icon) => handleIconChange(id, icon)}
onDeleteWorkspace={() => handleDeleteWorkspace(id)}
/>
),
},
],
};
});
const modWorkspaceColor =
activeWorkspace.label === "Default"
? "rgba(0, 0, 0, .2)"
: colord(activeWorkspace.color).alpha(0.1).toRgbString();
const renderExpandableMenu = (menuItems: ExpandableMenuItemData[], parentIsOpen?: boolean) => {
return menuItems.map((item, index) => {
if (item.type === "item") {
let contentElement;
if (typeof item.content === "function") {
contentElement = item.content({ isOpen: parentIsOpen });
} else {
contentElement = item.content;
}
return (
{item.leftElement && (
{item.leftElement}
)}
{contentElement}
{item.rightElement && (
{item.rightElement}
)}
);
} else if (item.type === "group") {
return (
setActiveWorkspace(item.id)}>
{item.title.leftElement && (
{item.title.leftElement}
)}
{item.title.label}
{item.title.rightElement && (
{item.title.rightElement}
)}
{item.children && item.children.length > 0 && renderExpandableMenu(item.children, item.isOpen)}
);
}
return null;
});
};
let workspaceIcon = (
);
if (activeWorkspace.label == "Default") {
workspaceIcon = ;
}
return (
{workspaceIcon}
{/*
*/}
Switch workspace
{renderExpandableMenu(data)}
handleAddNewWorkspace()}>
New workspace
);
};
export { WorkspaceSwitcher };