Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/drawer+layers #16

Merged
merged 10 commits into from
May 2, 2024
4 changes: 3 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React, { Fragment } from 'react';
import { Map } from '@components/map';
import { Sidebar } from '@components/sidebar';

export const App = () => {
return (
<Fragment>
<Map />
<Map/>
<Sidebar />
</Fragment>
);
};
7 changes: 6 additions & 1 deletion src/components/map/default-layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ export const DefaultLayers = () => {
data.workbench.forEach(function (layer_id) {
const layer = getCatalogEntry(data.catalog, layer_id);
if (layer)
layer_list.push(layer);
layer_list.push({
...layer,
state: {
visible: true,
}
});

// TODO: do we really need to do this here??!
// if this is an obs layer, need to retrieve
Expand Down
1 change: 0 additions & 1 deletion src/components/sidebar/menu-item.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';

import {
IconButton,
ListItem,
Expand Down
5 changes: 3 additions & 2 deletions src/components/sidebar/sidebar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Fragment, useCallback, useState } from 'react';
import React from 'react';
import { Fragment, useCallback, useState } from 'react';
import {
List,
Sheet,
Expand All @@ -17,7 +18,7 @@ export const Sidebar = () => {
setActiveIndex(-1);
return;
}
// otherwise, open the desired tray.
// otherwise, open desired tray.
setActiveIndex(newIndex);
}, [activeIndex]);

Expand Down
3 changes: 2 additions & 1 deletion src/components/sidebar/toggler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { IconButton } from '@mui/joy';
import React from 'react';
import { IconButton } from '@mui/joy';
import {
Menu as HamburgerIcon,
Close as CloseMenuIcon,
Expand Down
1 change: 0 additions & 1 deletion src/components/sidebar/tray.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';

import {
DialogContent,
DialogTitle,
Expand Down
86 changes: 46 additions & 40 deletions src/components/trays/layers/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Accordion,
AccordionGroup,
AccordionDetails,
Box,
Divider,
IconButton,
ListItemContent,
Expand All @@ -11,30 +12,28 @@ import {
Typography,
} from '@mui/joy';
import {
DragIndicator as DragHandleIcon,
KeyboardArrowDown as ExpandIcon,
} from '@mui/icons-material';
import { DragIndicator as DragHandleIcon } from '@mui/icons-material';

const dummyLayers = [
{
id: '234567',
name: 'Ullamco anim ad',
},
{
id: '0987654',
name: 'In ad tempor',
},
{
id: '9846351',
name: 'Eu in laborum',
},
];
import { useLayers } from '@context';

export const LayersList = () => {
const { defaultModelLayers, toggleLayerVisibility } = useLayers();
const layers = [...defaultModelLayers];

// convert the product type to a readable layer name
const layer_names = {
obs: "Observations",
maxwvel63: "Maximum Wind Velocity",
maxele63: "Maximum Water Level",
swan_HS_max63: "Maximum Wave Height",
maxele_level_downscaled_epsg4326: "Hi-Res Maximum Water Level",
hec_ras_water_surface: "HEC/RAS Water Surface",
};

console.table(layers[0]);

const [expandedIds, setExpandedIds] = useState(new Set());
// of course, this is dummy state.
// real state will be maintained in some higher-up context.
const [visibleIds, setVisibleIds] = useState(new Set());

const handleToggleExpansion = id => () => {
const _expandedIds = new Set([...expandedIds]);
Expand All @@ -47,29 +46,22 @@ export const LayersList = () => {
setExpandedIds(_expandedIds);
};

const handleToggleVisibilitySwitch = id => () => {
const _visibleIds = new Set([...visibleIds]);
if (_visibleIds.has(id)) {
_visibleIds.delete(id);
setVisibleIds(_visibleIds);
return;
}
_visibleIds.add(id);
setVisibleIds(_visibleIds);
};

return (
<AccordionGroup variant="soft">
{
dummyLayers.map(layer => {
layers.map(layer => {
const isExpanded = expandedIds.has(layer.id);
const isVisible = visibleIds.has(layer.id);
const isVisible = layer.state.visible;
const layerTitle = layer_names[layer.properties.product_type] + " " +
layer.properties.run_date + " " +
layer.properties.cycle;


return (
<Accordion
key={ `layer-${ layer.id }-${ isVisible ? 'visible' : 'hidden' }` }
expanded={ isExpanded }
onChange={ handleToggleVisibilitySwitch }
onChange={ handleToggleExpansion }
sx={{ p: 0 }}
>
{/*
Expand Down Expand Up @@ -107,18 +99,25 @@ export const LayersList = () => {

<ListItemContent>
<Typography level="title-md">
{ layer.name }
{layerTitle}
</Typography>
<Typography level="body-sm">
some details.
some details.
<Typography
component="div"
level="body-sm"
sx={{
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{ layer.layers }
</Typography>
</ListItemContent>

<Switch
size="sm"
onChange={ handleToggleVisibilitySwitch(layer.id) }
checked={ isVisible }
onChange={ () => toggleLayerVisibility(layer.id) }
/>

<IconButton onClick={ handleToggleExpansion(layer.id) }>
Expand All @@ -131,11 +130,18 @@ export const LayersList = () => {
/>
</IconButton>
</Stack>
<AccordionDetails variant="soft" sx={{
<AccordionDetails variant="solid" sx={{
// remove default margin that doesn't work well in our situation.
marginInline: 0,
}}>
Lorem ipsum ad deserunt adipisicing deserunt sint deserunt qui occaecat consequat aliquip.
<Box component="pre" sx={{
fontSize: '75%',
color: '#def',
backgroundColor: 'transparent',
overflowX: 'auto',
}}>
{ JSON.stringify(layer.properties, null, 2) }
</Box>
</AccordionDetails>
</Accordion>
);
Expand Down
25 changes: 21 additions & 4 deletions src/context/map-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,25 @@ export const LayersContext = createContext({});
export const useLayers = () => useContext(LayersContext);

export const LayersProvider = ({ children }) => {
const [defaultModelLayers, setDefaultModelLayers] = useState([]);
const [filteredModelLayers, setFilteredModelLayers] = useState([]);
const [map, setMap] = useState(null);
const [defaultModelLayers, setDefaultModelLayers] = useState([]);
const [filteredModelLayers, setFilteredModelLayers] = useState([]);
const [map, setMap] = useState(null);

const toggleLayerVisibility = id => {
const newLayers = [...defaultModelLayers];
const index = newLayers.findIndex(l => l.id === id);
if (index === -1) {
new Error('Could not locate layer', id);
return;
}
const alteredLayer = newLayers[index];
alteredLayer.state.visible = !alteredLayer.state.visible;
setDefaultModelLayers([
...newLayers.slice(0, index),
{ ...alteredLayer },
...newLayers.slice(index + 1),
]);
};

return (
<LayersContext.Provider
Expand All @@ -17,7 +33,8 @@ export const LayersProvider = ({ children }) => {
defaultModelLayers,
setDefaultModelLayers,
filteredModelLayers,
setFilteredModelLayers
setFilteredModelLayers,
toggleLayerVisibility,
}}
>
{children}
Expand Down
14 changes: 9 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React from 'react';
import { App } from './app';
import { createRoot } from 'react-dom/client';
import { LayersProvider } from '@context';
import { LayersProvider, SettingsProvider } from '@context';
import './index.css';

const container = document.getElementById('root');
const root = createRoot(container);

root.render(
<LayersProvider>
<App />
</LayersProvider>
const ProvisionedApp = () => (
<SettingsProvider>
<LayersProvider>
<App />
</LayersProvider>
</SettingsProvider>
);

root.render(<ProvisionedApp />);