Skip to content

Commit 199a543

Browse files
authored
Merge pull request #137 from Pewillia/136-resizeconfig-map-windows
add resizable panels
2 parents e88fb23 + b086813 commit 199a543

File tree

8 files changed

+492
-274
lines changed

8 files changed

+492
-274
lines changed

package-lock.json

Lines changed: 278 additions & 106 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"react-dom": "^18.3.1",
2424
"react-highlight": "^0.15.0",
2525
"react-router-dom": "^6.26.1",
26-
"uuid": "^10.0.0"
26+
"uuid": "^10.0.0",
27+
"react-resizable-panels":"3.0.6"
2728
},
2829
"devDependencies": {
2930
"@eslint/js": "^9.9.0",

src/components/DrawerTabs.tsx

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { EventsLog } from './EventsLog';
1111
import { LegendLayerStatusTable } from './LegendLayerStatusTable';
1212
import { CGPVContext } from '@/providers/cgpvContextProvider/CGPVContextProvider';
1313

14-
1514
export default function DrawerTabs() {
1615
const cgpvContext = useContext(CGPVContext);
1716

@@ -26,38 +25,35 @@ export default function DrawerTabs() {
2625
setSelectedTab(newValue);
2726
};
2827

29-
3028
if (isLoading) {
3129
return <Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
3230
<CircularProgress />
3331
</Box>;
3432
}
3533

36-
3734
return (
38-
<Box sx={{ width: '100%', typography: 'body1', minHeight: {md: '100vh'} }}>
39-
<TabContext value={selectedTab}>
40-
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
41-
<TabList onChange={handleTabChange} aria-label="handling tabs change" variant="scrollable" scrollButtons="auto">
42-
<Tab icon={<ListAltIcon />} label="Map Builder" value="config-builder" />
43-
<Tab icon={<SettingsIcon />} label="API Functions" value="interactive-map" />
44-
<Tab icon={<BallotIcon />} label="Layers Status" value="layers-status" />
45-
<Tab icon={<RunCircleIcon />} label="Events Log" value="events-log" />
46-
</TabList>
47-
</Box>
48-
<TabPanel value="interactive-map" >
49-
<ApiFunctionsTab />
50-
</TabPanel>
51-
<TabPanel value="config-builder">
52-
<MapBuilder />
53-
</TabPanel>
54-
<TabPanel value="layers-status">
55-
<LegendLayerStatusTable />
56-
</TabPanel>
57-
<TabPanel value="events-log">
58-
<EventsLog />
59-
</TabPanel>
60-
</TabContext>
35+
36+
<TabContext value={selectedTab}>
37+
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
38+
<TabList onChange={handleTabChange} aria-label="handling tabs change" variant="scrollable" scrollButtons="auto">
39+
<Tab icon={<ListAltIcon />} label="Map Builder" value="config-builder" />
40+
<Tab icon={<SettingsIcon />} label="API Functions" value="interactive-map" />
41+
<Tab icon={<BallotIcon />} label="Layers Status" value="layers-status" />
42+
<Tab icon={<RunCircleIcon />} label="Events Log" value="events-log" />
43+
</TabList>
6144
</Box>
45+
<TabPanel value="interactive-map" >
46+
<ApiFunctionsTab />
47+
</TabPanel>
48+
<TabPanel value="config-builder">
49+
<MapBuilder />
50+
</TabPanel>
51+
<TabPanel value="layers-status">
52+
<LegendLayerStatusTable />
53+
</TabPanel>
54+
<TabPanel value="events-log">
55+
<EventsLog />
56+
</TabPanel>
57+
</TabContext>
6258
);
6359
}

src/components/GeoViewMap.tsx

Lines changed: 92 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
import React, { useContext, useEffect } from 'react';
2-
import { AppBar, Box, CssBaseline, Drawer, IconButton, Toolbar } from '@mui/material';
2+
import { AppBar, CssBaseline,
3+
IconButton, Toolbar, Typography , Menu , MenuItem, Link} from '@mui/material';
34
import MenuIcon from '@mui/icons-material/Menu';
4-
import DrawerTabs from './DrawerTabs';
55
import { CGPVContext } from '../providers/cgpvContextProvider/CGPVContextProvider';
66
import { MapRenderer } from './MapRenderer';
7-
import { AppToolbar } from './AppToolbar';
87
import { useSearchParams } from "react-router-dom";
9-
import { DEFAULT_CONFIG_FILE } from '@/constants';
8+
import { DEFAULT_CONFIG_FILE, DEFAULT_LEFT_PANEL_MIN_WIDTH, DEFAULT_LEFT_PANEL_MAX_WIDTH, DEFAULT_LEFT_PANEL_WIDTH ,
9+
DEFAULT_RIGHT_PANEL_MIN_WIDTH, DEFAULT_RIGHT_PANEL_MAX_WIDTH, DEFAULT_RIGHT_PANEL_WIDTH
10+
} from '@/constants';
11+
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
12+
import { useState } from 'react';
13+
import SettingsIcon from '@mui/icons-material/Settings';
14+
import DrawerTabs from './DrawerTabs';
15+
import { GEOVIEW_CORE_URL } from "@/constants";
16+
import {panelSize} from '@/constants';
1017

1118
interface GeoViewMapProps {
1219
showConfigEditor?: boolean;
@@ -17,24 +24,32 @@ interface GeoViewMapProps {
1724
}
1825

1926
function GeoViewMap(props: GeoViewMapProps) {
20-
const cgpvContext = useContext(CGPVContext);
21-
const [searchParams, setSearchParams] = useSearchParams();
2227

28+
const cgpvContext = useContext(CGPVContext);
29+
const [searchParams, setSearchParams] = useSearchParams();
30+
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
31+
32+
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
33+
setAnchorEl(event.currentTarget);
34+
};
35+
36+
const handleClose = () => {
37+
setAnchorEl(null);
38+
};
2339

2440
if (!cgpvContext) {
2541
throw new Error('CGPVContent must be used within a CGPVProvider');
2642
}
2743

2844
const { configFilePath, initializeMap, isInitialized } = cgpvContext;
29-
3045
const [mobileOpen, setMobileOpen] = React.useState(false);
31-
const [isClosing, setIsClosing] = React.useState(false);
32-
33-
const {
34-
children
35-
} = props;
46+
const [isClosing, ] = React.useState(false);
47+
const {children} = props;
3648

37-
const DRAWER_WIDTH = 440;
49+
const handlePanel1Resize = (size : any) => { //called on right panel resize always called on resize
50+
panelSize.current = (window.innerWidth - (435 +7))* (size*.01);
51+
console.log("right panel resize");
52+
};
3853

3954
useEffect(() => {
4055
if(!isInitialized) {
@@ -51,84 +66,88 @@ function GeoViewMap(props: GeoViewMapProps) {
5166
}
5267
}, [configFilePath]);
5368

54-
55-
const handleDrawerClose = () => {
56-
setIsClosing(true);
57-
setMobileOpen(false);
58-
};
59-
60-
const handleDrawerTransitionEnd = () => {
61-
setIsClosing(false);
62-
};
63-
6469
const handleDrawerToggle = () => {
6570
if (!isClosing) {
6671
setMobileOpen(!mobileOpen);
6772
}
6873
};
6974

7075
return (
71-
<Box sx={{ display: 'flex' }}>
72-
<CssBaseline />
73-
<AppBar
74-
position="fixed"
75-
sx={{
76-
width: { sm: `calc(100% - ${DRAWER_WIDTH}px)` },
77-
ml: { sm: `${DRAWER_WIDTH}px` },
78-
}}
79-
>
80-
<AppToolbar>
76+
77+
<PanelGroup direction = "horizontal">
78+
<Panel style={{overflowY: 'auto', height: '119vh' } }
79+
collapsible
80+
minSize={DEFAULT_LEFT_PANEL_MIN_WIDTH}
81+
maxSize={DEFAULT_LEFT_PANEL_MAX_WIDTH}
82+
defaultSize={DEFAULT_LEFT_PANEL_WIDTH}>
83+
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
84+
85+
<DrawerTabs />
86+
<CssBaseline />
87+
<AppBar >
8188
<IconButton
8289
color="inherit"
8390
aria-label="open drawer"
8491
edge="start"
8592
onClick={handleDrawerToggle}
86-
sx={{ mr: 2, display: { sm: 'none' } }}
87-
>
93+
sx={{ mr: 2, display: { sm: 'none' } }}>
8894
<MenuIcon />
8995
</IconButton>
90-
</AppToolbar>
91-
</AppBar>
92-
<Box component="nav" sx={{ width: { sm: DRAWER_WIDTH }, flexShrink: { sm: 0 } }} aria-label="settings panel">
93-
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
94-
<Drawer
95-
variant="temporary"
96-
open={mobileOpen}
97-
onTransitionEnd={handleDrawerTransitionEnd}
98-
onClose={handleDrawerClose}
99-
ModalProps={{
100-
keepMounted: true, // Better open performance on mobile.
101-
}}
102-
sx={{
103-
bgcolor: '#f4f4f4',
104-
display: { xs: 'block', sm: 'none' },
105-
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: DRAWER_WIDTH },
106-
}}
107-
>
108-
<DrawerTabs />
109-
</Drawer>
110-
<Drawer
111-
variant="permanent"
112-
sx={{
113-
display: { xs: 'none', sm: 'block' },
114-
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: DRAWER_WIDTH, borderRight: '5px solid lightgray', },
115-
}}
116-
open
117-
>
118-
<DrawerTabs />
119-
</Drawer>
120-
</Box>
121-
<Box component="main" sx={{ flexGrow: 1, pt: 1, width: { sm: `calc(100% - ${DRAWER_WIDTH}px)` } }}>
122-
<Toolbar />
96+
</AppBar>
97+
</Panel>
98+
99+
<PanelResizeHandle style={{ display: 'flex', flexDirection: 'column', gap: 2, border: "1px solid #141313ff",width : 5 }}/>
100+
<Panel
101+
collapsible
102+
minSize={DEFAULT_RIGHT_PANEL_MIN_WIDTH }
103+
maxSize={DEFAULT_RIGHT_PANEL_MAX_WIDTH}
104+
onResize={handlePanel1Resize}
105+
defaultSize= {DEFAULT_RIGHT_PANEL_WIDTH}>
106+
<Toolbar sx= {{ backgroundColor: 'rgb(25, 118, 210 )' }}>
107+
{children}
108+
109+
<img src={`${GEOVIEW_CORE_URL}/img/Logo.png`} alt="GeoView"
110+
style= {{ height: 0, marginRight: 16 }} />
111+
<Typography variant="h6" component = "div" sx={{ flexGrow: 1, color: 'white' }}>
112+
Canadian Geospatial Platform (CGP) - GeoView
113+
</Typography>
114+
<IconButton
115+
size="large"
116+
aria-label="account of current user"
117+
aria-controls="menu-appbar"
118+
aria-haspopup="true"
119+
onClick={handleMenu}
120+
color="inherit">
121+
<SettingsIcon />
122+
</IconButton>
123+
<Menu
124+
id="menu-appbar"
125+
anchorEl={anchorEl}
126+
anchorOrigin={{
127+
vertical: 'top',
128+
horizontal: 'right'
129+
}}
130+
keepMounted
131+
transformOrigin={{
132+
vertical: 'top',
133+
horizontal: 'right'
134+
}}
135+
open={Boolean(anchorEl)}
136+
onClose={handleClose}
137+
>
138+
<MenuItem component={Link} href="https://github.com/Canadian-Geospatial-Platform/geoview-demo" target="_blank"> GitHub</MenuItem>
139+
<MenuItem component={Link} href="https://canadian-geospatial-platform.github.io/geoview-demo/" target="_blank"> Demo</MenuItem>
140+
<MenuItem component={Link} href="https://github.com/Canadian-Geospatial-Platform/geoview" target="_blank"> Geoview Github</MenuItem>
141+
</Menu>
142+
143+
</Toolbar>
123144
{props.top}
124145
{children}
125-
<Box sx={{ width: '100%', typography: 'body1' }}>
126146
<MapRenderer />
127-
</Box>
128147
{props.bottom}
129-
</Box>
130-
</Box>
148+
</Panel>
149+
</PanelGroup>
131150
);
132151
}
133152

134-
export default GeoViewMap;
153+
export default GeoViewMap

0 commit comments

Comments
 (0)