Merge branch 'fix/edit-mode-scope' into 'main'

Fix/edit mode scope

See merge request vkuchenik/website-framework!34
This commit is contained in:
Dan Hansen
2025-07-29 19:23:52 +00:00
5 changed files with 75 additions and 15 deletions
@@ -8,19 +8,24 @@ import RegionalMapCanvas from "./views/RegionalMapCanvas";
import VolcanoCanvas from "./views/VolcanoCanvas";
import AdminCanvas from "./views/AdminCanvas";
import { DashboardCanvas } from "./views/DashboardCanvas";
import { DASHBOARD_VIEWS } from "@/constants/viewKeys";
export default function Canvas({ view, layout, setLayout, onLayoutChange }) {
export default function Canvas({ view, setView, layout, setLayout, onLayoutChange }) {
const recipe = useRecipe({ key: "canvas" });
const styles = recipe();
return (
<Box height="100%" width="100%">
{view === "widget" &&
{/* Check if view is a tab inside the Canvas Header */}
{ DASHBOARD_VIEWS.includes(view) && (
<DashboardCanvas
view={ view }
setView={ setView }
layout={ layout }
setLayout={ setLayout }
onLayoutChange={ onLayoutChange }
/>}
/>
)}
{view === "global" && <GlobalMapCanvas />}
{view === "regional" && <RegionalMapCanvas />}
{view === "volcano" && <VolcanoCanvas />}
@@ -10,7 +10,7 @@ import { useState, useEffect, useDebugValue } from "react";
import { CancelButton } from "../components/CancelButton";
import { SaveButton } from "../components/SaveButton";
export function DashboardCanvas({ layout, setLayout, onLayoutChange }) {
export function DashboardCanvas({ view, setView, layout, setLayout, onLayoutChange }) {
const [isEditable, setIsEditable] = useState(false); // editable=true means static=false (vice versa)
const [isDelete, setIsDelete] = useState(false);
const [newCounter, setNewCounter] = useState(3);
@@ -81,7 +81,24 @@ export function DashboardCanvas({ layout, setLayout, onLayoutChange }) {
return (
/* HEADER */
<Tabs.Root lazyMount defaultValue="my dashboard" size="lg">
<Tabs.Root
lazyMount
value={ view }
// Prevent navigation away from 'My Dashboard' while in Edit mode
onValueChange={(e) => {
const nextView = e.value;
if (view === "widget" && isEditable && nextView !== "widget") {
const confirmed = window.confirm(
"You have unsaved changes. Do you wish to discard them and continue?"
);
if (!confirmed) return;
onCancel();
}
setView(nextView);
}}
>
<Flex
as="header"
position="sticky"
@@ -94,7 +111,7 @@ export function DashboardCanvas({ layout, setLayout, onLayoutChange }) {
justify="space-between"
>
<Tabs.List>
<Tabs.Trigger value="my dashboard" >
<Tabs.Trigger value="widget">
My Dashboard
</Tabs.Trigger>
<Tabs.Trigger value="gas" >
@@ -103,10 +120,10 @@ export function DashboardCanvas({ layout, setLayout, onLayoutChange }) {
<Tabs.Trigger value="seismic" >
Seismic
</Tabs.Trigger>
<Tabs.Trigger value="remote sensing" >
<Tabs.Trigger value="remote">
Remote Sensing
</Tabs.Trigger>
<Tabs.Trigger value="daily activity" >
<Tabs.Trigger value="daily">
Daily Activity
</Tabs.Trigger>
</Tabs.List>
@@ -131,7 +148,7 @@ export function DashboardCanvas({ layout, setLayout, onLayoutChange }) {
</Flex>
{/* CANVAS */}
<Tabs.Content value="my dashboard">
<Tabs.Content value="widget">
<WidgetCanvas
layout={layout}
onLayoutChange={onLayoutChange}
@@ -146,10 +163,10 @@ export function DashboardCanvas({ layout, setLayout, onLayoutChange }) {
<Tabs.Content value="seismic">
<Seismic />
</Tabs.Content>
<Tabs.Content value="remote sensing">
<Tabs.Content value="remote">
<RemoteSensing />
</Tabs.Content>
<Tabs.Content value="daily activity">
<Tabs.Content value="daily">
<DailyActivity />
</Tabs.Content>
</Tabs.Root>
+4 -1
View File
@@ -64,11 +64,14 @@ export default function Dashboard() {
<Header />
</GridItem>
<GridItem colSpan={1}>
<Sidebar onChangeView={ setView }/>
<Sidebar
view={ view }
onChangeView={ setView }/>
</GridItem>
<GridItem colSpan={1} width="100%" overflow="auto">
<Canvas
view={ view }
setView={ setView }
layout={ layout }
setLayout={ setLayout }
onLayoutChange={( newLayout ) => setLayout( newLayout )}
@@ -8,9 +8,11 @@ import { FaGlobeAmericas } from "react-icons/fa";
import { FaMapMarkerAlt } from "react-icons/fa";
import { HiUsers } from "react-icons/hi2";
import { VscThreeBars } from "react-icons/vsc";
import { useState } from "react";
import { useState, useEffect } from "react";
import { Seismic } from "../Canvas/views/DashboardCanvasNav/Seismic";
import { DASHBOARD_VIEWS } from "@/constants/viewKeys";
export default function Sidebar({ onChangeView }) {
export default function Sidebar({ view, onChangeView }) {
const [isOpen, setIsOpen] = useState(true);
const [activeButton, setActiveButton] = useState(0)
const recipe = useSlotRecipe({ key: "sidebar" });
@@ -30,6 +32,24 @@ export default function Sidebar({ onChangeView }) {
else setIsOpen(true);
};
// Track currrent view from both Sidebar and Canvas when 'view' changes
useEffect(() => {
console.log("typeof view =", typeof view);
console.log("Current view = ", view);
// const dashboardViews = ["widget", "gas", "seismic", "remote", "daily"];
const newIndex = buttons.findIndex((btn) => {
if (btn.view === "widget") {
return DASHBOARD_VIEWS.includes(view); // Group match
}
return btn.view === view; // Exact match
});
if (newIndex !== -1 ) {
setActiveButton(newIndex);
}
}, [view]);
return (
<Box
css={styles.root}
+15
View File
@@ -0,0 +1,15 @@
// Main views called from Sidebar
export const DASHBOARD_VIEWS = ["widget", "gas", "seismic", "remote", "daily"]
// Sub views called from inside DashboardCanvas
export const VIEW_LABELS = {
widget: "My Dashboard",
gas: "Gas",
seismic: "Seismic",
remote: "Remote Sensing",
daily: "Daily Activity",
global: "Global Map",
regional: "Regional Map",
volcano: "Volcano",
admin: "Admin",
};