fixed widget state saving bug

+ decluttered props by using prop forwarding
+ renamed DashboardCanvas to HomeCanvas
This commit is contained in:
2025-08-04 15:38:19 -07:00
parent f250f11d8d
commit 9b8f7ea4d4
4 changed files with 32 additions and 72 deletions
+5 -23
View File
@@ -1,38 +1,20 @@
// This Canvas component will be used to dynamically populate import { Box } from "@chakra-ui/react";
// the main canvas section of the web App with a default state
// of 'WidgetCanvas'
import { Box, useRecipe } from "@chakra-ui/react";
import GlobalMapCanvas from "./views/GlobalMapCanvas"; import GlobalMapCanvas from "./views/GlobalMapCanvas";
import RegionalMapCanvas from "./views/RegionalMapCanvas"; import RegionalMapCanvas from "./views/RegionalMapCanvas";
import VolcanoCanvas from "./views/VolcanoCanvas"; import VolcanoCanvas from "./views/VolcanoCanvas";
import AdminCanvas from "./views/AdminCanvas"; import AdminCanvas from "./views/AdminCanvas";
import AccountCanvas from "./views/AccountCanvas" import AccountCanvas from "./views/AccountCanvas"
import SettingsCanvas from "./views/SettingsCanvas" import SettingsCanvas from "./views/SettingsCanvas"
import { DashboardCanvas } from "./views/DashboardCanvas"; import { HomeCanvas } from "./views/HomeCanvas";
import { DASHBOARD_VIEWS } from "@/constants/viewKeys"; import { DASHBOARD_VIEWS } from "@/constants/viewKeys";
export default function Canvas({ onCancel, isEditable, setIsEditable, isDelete, setIsDelete, view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView }) { export default function Canvas({...props}) {
const recipe = useRecipe({ key: "canvas" }); const { view } = props;
const styles = recipe();
return ( return (
<Box height="100%" width="100%"> <Box height="100%" width="100%">
{/* Check if view is a tab inside the Canvas Header */} {/* Check if view is a tab inside the Canvas Header */}
{ DASHBOARD_VIEWS.includes(view) && ( { DASHBOARD_VIEWS.includes(view) && (
<DashboardCanvas <HomeCanvas {...props}/>
view={ view }
layout={ layout }
setLayout={ setLayout }
setOriginalLayout={ setOriginalLayout }
onLayoutChange={ onLayoutChange }
onChangeView={ onChangeView }
onCancel={ onCancel }
isEditable={ isEditable }
setIsEditable={ setIsEditable }
isDelete={ isDelete }
setIsDelete={ setIsDelete }
/>
)} )}
{view === "global" && <GlobalMapCanvas />} {view === "global" && <GlobalMapCanvas />}
{view === "regional" && <RegionalMapCanvas />} {view === "regional" && <RegionalMapCanvas />}
@@ -11,8 +11,10 @@ import { CancelButton } from "../components/CancelButton";
import { SaveButton } from "../components/SaveButton"; import { SaveButton } from "../components/SaveButton";
import DeleteAllButton from "../components/DeleteAllButton"; import DeleteAllButton from "../components/DeleteAllButton";
export function DashboardCanvas({ view, layout, setLayout, onLayoutChange, onCancel, isDelete, setIsDelete, isEditable, setIsEditable, onChangeView, setOriginalLayout }) { export function HomeCanvas({...props}) {
const [widgetArray, setWidgetArray] = useState([]); // deconstructing props
const { view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView, onCancel,
isDelete, setIsDelete, isEditable, setIsEditable, widgetArray, setWidgetArray } = props;
const onAddWidget = (ID) => { const onAddWidget = (ID) => {
setLayout(prev => [ setLayout(prev => [
@@ -63,9 +65,9 @@ export function DashboardCanvas({ view, layout, setLayout, onLayoutChange, onCan
setIsDelete(true); setIsDelete(true);
} }
const DeleteWidget = (id) => { const DeleteWidget = (ID) => {
console.log("Deleting widget with id: ", id); console.log("Deleting widget with id: ", ID);
setLayout(layout => layout.filter(w => w.i !== id)); setLayout(layout => layout.filter(w => w.i !== ID));
// add removal for widgetArray here // add removal for widgetArray here
} }
@@ -81,12 +83,16 @@ export function DashboardCanvas({ view, layout, setLayout, onLayoutChange, onCan
else return; else return;
} }
// Prop Forwarding
const widgetCanvasProps = { layout, onLayoutChange, isEditable, isDelete, DeleteWidget, widgetArray };
const settingsButtonProps = { onAddWidget, onEditWidgets, onDeleteWidgets, setWidgetArray, widgetArray };
return ( return (
/* HEADER */ /* HEADER */
<Tabs.Root <Tabs.Root
lazyMount lazyMount
value={ view } value={ view }
variant="line"
// Prevent navigation away from 'My Dashboard' while in Edit mode // Prevent navigation away from 'My Dashboard' while in Edit mode
onValueChange={(e) => { onValueChange={(e) => {
const nextView = e.value; const nextView = e.value;
@@ -135,13 +141,7 @@ export function DashboardCanvas({ view, layout, setLayout, onLayoutChange, onCan
):( ):(
<> <>
<SearchBar /> <SearchBar />
<SettingsButton <SettingsButton {...settingsButtonProps}/>
onAddWidget={ onAddWidget }
onEditWidgets={ onEditWidgets }
onDeleteWidgets={ onDeleteWidgets }
setWidgetArray={ setWidgetArray }
widgetArray={ widgetArray }
/>
</> </>
)} )}
</HStack> </HStack>
@@ -149,15 +149,7 @@ export function DashboardCanvas({ view, layout, setLayout, onLayoutChange, onCan
{/* CANVAS */} {/* CANVAS */}
<Tabs.Content value="widget"> <Tabs.Content value="widget">
<WidgetCanvas <WidgetCanvas {...widgetCanvasProps}/>
layout={ layout }
onLayoutChange={ onLayoutChange }
isEditable={ isEditable }
isDelete={ isDelete }
DeleteWidget={ DeleteWidget }
setWidgetArray={ setWidgetArray }
widgetArray={ widgetArray }
/>
</Tabs.Content> </Tabs.Content>
<Tabs.Content value="gas"> <Tabs.Content value="gas">
<Gas /> <Gas />
+13 -25
View File
@@ -14,6 +14,7 @@ export default function Dashboard() {
const [originalLayout, setOriginalLayout] = useState([]); const [originalLayout, setOriginalLayout] = useState([]);
const [view, setView] = useState("widget"); const [view, setView] = useState("widget");
const [layout, setLayout] = useState([]); const [layout, setLayout] = useState([]);
const [widgetArray, setWidgetArray] = useState([]);
const onCancel = () => { const onCancel = () => {
console.log("canceling changes..."); console.log("canceling changes...");
@@ -40,6 +41,15 @@ export default function Dashboard() {
setView(nextView); setView(nextView);
}; };
const onLayoutChange = (newLayout) => setLayout(newLayout);
// Prop Forwarding
const canvasProps = { view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView: handleViewChange,
onCancel, isEditable, setIsEditable, isDelete, setIsDelete, widgetArray, setWidgetArray
};
const sidebarProps = { view, onChangeView: handleViewChange, darkMode, setDarkMode };
const headerProps = { onChangeView: handleViewChange };
return ( return (
<> <>
<Grid css={styles} <Grid css={styles}
@@ -50,35 +60,13 @@ export default function Dashboard() {
width="100vw" width="100vw"
> >
<GridItem rowSpan={1} colSpan={2}> <GridItem rowSpan={1} colSpan={2}>
<Header <Header {...headerProps}/>
view={ view }
setView={ setView }
onChangeView={ handleViewChange }
/>
</GridItem> </GridItem>
<GridItem colSpan={1}> <GridItem colSpan={1}>
<Sidebar <Sidebar {...sidebarProps}/>
darkMode={ darkMode }
setDarkMode={ setDarkMode }
view={ view }
onChangeView={ handleViewChange }
isEditabe={ isEditable }
/>
</GridItem> </GridItem>
<GridItem colSpan={1} width="100%" overflow="auto"> <GridItem colSpan={1} width="100%" overflow="auto">
<Canvas <Canvas {...canvasProps}/>
view={ view }
layout={ layout }
setLayout={ setLayout }
setOriginalLayout={ setOriginalLayout }
onLayoutChange={( newLayout ) => setLayout( newLayout )}
onChangeView={ handleViewChange }
onCancel={ onCancel }
isEditable={ isEditable }
setIsEditable={ setIsEditable }
isDelete={ isDelete }
setIsDelete={ setIsDelete }
/>
</GridItem> </GridItem>
</Grid> </Grid>
</> </>
@@ -34,14 +34,12 @@ export default function Sidebar({ view, onChangeView, darkMode, setDarkMode }) {
// Track currrent view from both Sidebar and Canvas when 'view' changes // Track currrent view from both Sidebar and Canvas when 'view' changes
useEffect(() => { useEffect(() => {
console.log("Current view = ", view); console.log("Current view = ", view);
const newIndex = buttons.findIndex((btn) => { const newIndex = buttons.findIndex((btn) => {
if (btn.view === "widget") { if (btn.view === "widget") {
return DASHBOARD_VIEWS.includes(view); return DASHBOARD_VIEWS.includes(view);
} }
return btn.view === view; return btn.view === view;
}); });
if (newIndex !== -1 ) { if (newIndex !== -1 ) {
setActiveButton(newIndex); setActiveButton(newIndex);
} }