Skip to content

Commit bc95278

Browse files
aldbrclaude
andauthored
refactor(dashboard): immutable state updates, drag-drop hook, and granular contexts (#497)
* refactor(dashboard): immutable state updates, drag-drop hook, and granular contexts Split the monolithic ApplicationsContext tuple into three purpose-built contexts (AppListContext, DashboardContext, CurrentAppContext) so components subscribe only to the state they read, and rework the dashboard layout around them: - extract drag-and-drop monitoring into a useDashboardDragDrop hook and the context menu into a DrawerContextMenu component; DashboardDrawer now updates dashboard state immutably (no in-place mutation of groups) - rewrite hooks/application.tsx around the granular contexts (useAppList, useDashboard, useApplicationId, useCurrentApplication) and drop useApplicationTitle/useApplicationType - memoize NavigationProvider and OIDCConfigurationProvider values - ProfileButton loses the dead About entry; ThemeToggleButton, Import/ExportButton, ApplicationDialog and ApplicationSelector are adapted to the new contexts - contexts/index.ts now exports the granular contexts explicitly (ApplicationsContext is gone); Dashboard stories/tests updated * refactor(dashboard): resolve drag-drop groups inside the state updater useDashboardDragDrop no longer takes userDashboard or mirrors it in a ref. reorderSections receives the source/destination group titles from the drop event and looks the groups up inside the setUserDashboard functional updater, where React hands it the freshest state. This drops the ref, its sync effect, and the userDashboard parameter, and removes the (practically unreachable) window where a drop could read a stale dashboard between a state commit and the ref update. The destination index is copied into a local so the updater stays pure under StrictMode. Draft addressing review comment C6.1 — kept as its own commit for review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6cd3e80 commit bc95278

20 files changed

Lines changed: 535 additions & 467 deletions

packages/diracx-web-components/src/components/DashboardLayout/ApplicationDialog.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import {
1111
Icon,
1212
IconButton,
1313
} from "@mui/material";
14-
import { Close } from "@mui/icons-material";
15-
import { ApplicationsContext } from "../../contexts/ApplicationsProvider";
14+
import Close from "@mui/icons-material/Close";
15+
import { AppListContext } from "../../contexts/ApplicationsProvider";
1616

1717
interface AppDialogProps {
1818
/** Determines whether the dialog is open or not. */
@@ -34,7 +34,7 @@ export default function AppDialog({
3434
setAppDialogOpen,
3535
handleCreateApp,
3636
}: AppDialogProps) {
37-
const applicationList = use(ApplicationsContext)[2];
37+
const { appList: applicationList } = use(AppListContext);
3838
return (
3939
<Dialog
4040
open={appDialogOpen}

packages/diracx-web-components/src/components/DashboardLayout/Dashboard.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@ import { useState } from "react";
44
import AppBar from "@mui/material/AppBar";
55
import Box from "@mui/material/Box";
66
import IconButton from "@mui/material/IconButton";
7-
import { Menu } from "@mui/icons-material";
7+
import Menu from "@mui/icons-material/Menu";
88
import Toolbar from "@mui/material/Toolbar";
99
import Stack from "@mui/material/Stack";
1010
import { Typography, useMediaQuery, useTheme } from "@mui/material";
11-
import {
12-
useApplicationTitle,
13-
useApplicationType,
14-
} from "../../hooks/application";
11+
import { useCurrentApplication } from "../../hooks/application";
1512
import { ProfileButton } from "./ProfileButton";
1613
import { ThemeToggleButton } from "./ThemeToggleButton";
1714
import DashboardDrawer from "./DashboardDrawer";
@@ -42,8 +39,9 @@ export default function Dashboard({
4239
logoURL,
4340
documentationURL,
4441
}: DashboardProps) {
45-
const appTitle = useApplicationTitle();
46-
const appType = useApplicationType();
42+
const currentApp = useCurrentApplication();
43+
const appTitle = currentApp?.title ?? null;
44+
const appType = currentApp?.type ?? null;
4745

4846
/** Theme and media query */
4947
const theme = useTheme();
@@ -154,7 +152,8 @@ export default function Dashboard({
154152
flexGrow: 1,
155153
display: "flex",
156154
flexDirection: "column",
157-
width: { sm: `${drawerWidth}px` },
155+
width: { sm: `calc(100% - ${drawerWidth}px)` },
156+
minWidth: 0,
158157
}}
159158
>
160159
<Toolbar />

0 commit comments

Comments
 (0)