From cdb036da31e17b74c5f21151ddf93504dd51608f Mon Sep 17 00:00:00 2001 From: Loris Van Katwijk Date: Tue, 16 Apr 2024 15:20:44 +0200 Subject: [PATCH] feat: useState for Groups --- src/components/ui/DashboardDrawer.tsx | 123 ++++++++++++++++---------- src/components/ui/DrawerItemGroup.tsx | 55 ++++++++++-- 2 files changed, 123 insertions(+), 55 deletions(-) diff --git a/src/components/ui/DashboardDrawer.tsx b/src/components/ui/DashboardDrawer.tsx index 8ffd50c7..375c6343 100644 --- a/src/components/ui/DashboardDrawer.tsx +++ b/src/components/ui/DashboardDrawer.tsx @@ -12,32 +12,11 @@ import { import { Dashboard, FolderCopy } from "@mui/icons-material"; import MonitorIcon from "@mui/icons-material/Monitor"; import MenuBookIcon from "@mui/icons-material/MenuBook"; -import React, { ComponentType, ReactEventHandler } from "react"; +import React, { ComponentType, ReactEventHandler, useState } from "react"; import { DragDropContext, Droppable } from "react-beautiful-dnd"; import DrawerItemGroup from "./DrawerItemGroup"; import { DiracLogo } from "./DiracLogo"; -// Define the sections that are accessible to users. -// Each section has an associated icon and path. -let userSections: { - title: string; - items: { title: string; id: number; icon: ComponentType; path: string }[]; -}[] = [ - { - title: "Dashboard", - items: [ - { title: "Dashboard", id: 0, icon: Dashboard, path: "/" }, - { title: "Job Monitor", id: 1, icon: MonitorIcon, path: "/jobmonitor" }, - ], - }, - { - title: "Other", - items: [ - { title: "File Catalog", id: 2, icon: FolderCopy, path: "/filecatalog" }, - ], - }, -]; - interface DashboardDrawerProps { variant: "permanent" | "temporary"; mobileOpen: boolean; @@ -45,27 +24,6 @@ interface DashboardDrawerProps { handleDrawerToggle: ReactEventHandler; } -function onDragEnd(result: any) { - // Reorder the list of items in the group. - if (!result.destination) { - return; - } - const source = result.source; - const destination = result.destination; - - const sourceGroup = userSections.find( - (group) => group.title == source.droppableId, - ); - const destinationGroup = userSections.find( - (group) => group.title == destination.droppableId, - ); - - if (sourceGroup && destinationGroup) { - const [removed] = sourceGroup.items.splice(source.index, 1); - destinationGroup.items.splice(destination.index, 0, removed); - } -} - export default function DashboardDrawer(props: DashboardDrawerProps) { // Get the current URL const pathname = usePathname(); @@ -75,6 +33,79 @@ export default function DashboardDrawer(props: DashboardDrawerProps) { // Check if the drawer is in "temporary" mode. const isTemporary = props.variant === "temporary"; + // Define the sections that are accessible to users. + // Each section has an associated icon and path. + const [userSections, setSections] = useState([ + { + title: "Dashboard", + extended: true, + items: [ + { title: "Dashboard", id: 0, icon: Dashboard, path: "/" }, + { title: "Job Monitor", id: 1, icon: MonitorIcon, path: "/jobmonitor" }, + ], + }, + { + title: "Other", + extended: false, + items: [ + { + title: "File Catalog", + id: 2, + icon: FolderCopy, + path: "/filecatalog", + }, + ], + }, + { + title: "Other2", + extended: false, + items: [], + }, + ] as { + title: string; + extended: boolean; + items: { title: string; id: number; icon: ComponentType; path: string }[]; + }[]); + + /** + * Handles the drag end event for reordering items in the group. + * + * @param result - The result object containing information about the drag event. + */ + function onDragEnd(result: any) { + // Reorder the list of items in the group. + if (!result.destination) { + return; + } + const source = result.source; + const destination = result.destination; + + const sourceGroup = userSections.find( + (group) => group.title == source.droppableId, + ); + const destinationGroup = userSections.find( + (group) => group.title == destination.droppableId, + ); + + if (sourceGroup && destinationGroup) { + const sourceItems = [...sourceGroup.items]; + const destinationItems = [...destinationGroup.items]; + + const [removed] = sourceItems.splice(source.index, 1); + destinationItems.splice(destination.index, 0, removed); + + setSections((sections) => + sections.map((section) => + section.title === sourceGroup.title + ? { ...section, items: sourceItems } + : section.title === destinationGroup.title + ? { ...section, items: destinationItems } + : section, + ), + ); + } + } + return ( - {userSections.map(({ title, items }, index: number) => ( - - + {userSections.map((group) => ( + + ))} diff --git a/src/components/ui/DrawerItemGroup.tsx b/src/components/ui/DrawerItemGroup.tsx index 14cc2bba..74eb4368 100644 --- a/src/components/ui/DrawerItemGroup.tsx +++ b/src/components/ui/DrawerItemGroup.tsx @@ -15,19 +15,56 @@ import DragIndicatorIcon from "@mui/icons-material/DragIndicator"; import { StrictModeDroppable } from "./StrictModeDroppable"; export default function DrawerItemGroup({ - title, - items, + group: { title, extended: expanded, items }, + setSections, }: { - title: string; - items: { + group: { title: string; - id: number; - icon: React.ComponentType; - path: string; - }[]; + extended: boolean; + items: { + title: string; + id: number; + icon: React.ComponentType; + path: string; + }[]; + }; + setSections: React.Dispatch< + React.SetStateAction< + { + title: string; + extended: boolean; + items: { + title: string; + id: number; + icon: React.ComponentType; + path: string; + }[]; + }[] + > + >; }) { + const handleChange = (title: string) => (event: any, isExpanded: any) => { + // Set the extended state of the accordion group. + setSections((sections) => + sections.map((section) => + section.title === title + ? { ...section, extended: isExpanded } + : section, + ), + ); + }; + return ( - + {/* Accordion summary */} }> {title}