From 47e58b2b21379c3abacccb04bb7e96cc81e25c60 Mon Sep 17 00:00:00 2001 From: Vismayak Mohanarajan Date: Thu, 15 Jun 2023 12:17:53 -0500 Subject: [PATCH 1/2] Update SourcesControl.jsx --- .../core/src/components/ol/SourcesControl.jsx | 703 +++++++++--------- 1 file changed, 372 insertions(+), 331 deletions(-) diff --git a/packages/core/src/components/ol/SourcesControl.jsx b/packages/core/src/components/ol/SourcesControl.jsx index 3ea09ad8..03f54b80 100644 --- a/packages/core/src/components/ol/SourcesControl.jsx +++ b/packages/core/src/components/ol/SourcesControl.jsx @@ -1,144 +1,144 @@ // @flow -import React from "react"; -import ReactDOM from "react-dom"; -import { interpolateRgb } from "d3"; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { interpolateRgb } from 'd3'; import { - Box, - Button, - Checkbox, - Grid, - Typography, - IconButton, - makeStyles, - Card, - CardContent, - List, -} from "@material-ui/core"; -import CircleCheckedFilledIcon from "@material-ui/icons/CheckCircle"; -import CircleUncheckedIcon from "@material-ui/icons/RadioButtonUnchecked"; -import InfoOutlinedIcon from "@material-ui/icons/InfoOutlined"; -import { Skeleton } from "@material-ui/lab"; -import BaseSidebar from "@geostreams/core/src/components/theme/BaseSidebar"; -import SidebarCategory from "@geostreams/core/src/components/theme/SidebarCategory"; -import { entries } from "@geostreams/core/src/utils/array"; -import { getSourceColor } from "../../utils/sensors"; -import type { SensorType, SourceConfig } from "../../utils/flowtype"; -import InfoDialog from "./InfoDialog"; -import CloseIcon from "@material-ui/icons/Close"; + Box, + Button, + Checkbox, + Grid, + Typography, + IconButton, + makeStyles, + Card, + CardContent, + List +} from '@material-ui/core'; +import CircleCheckedFilledIcon from '@material-ui/icons/CheckCircle'; +import CircleUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked'; +import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined'; +import { Skeleton } from '@material-ui/lab'; +import BaseSidebar from '@geostreams/core/src/components/theme/BaseSidebar'; +import SidebarCategory from '@geostreams/core/src/components/theme/SidebarCategory'; +import { entries } from '@geostreams/core/src/utils/array'; +import CloseIcon from '@material-ui/icons/Close'; +import { getSourceColor } from '../../utils/sensors'; +import type { SensorType, SourceConfig } from '../../utils/flowtype'; +import InfoDialog from './InfoDialog'; const useStyles = makeStyles((theme) => ({ - button: { - width: "10em !important", - height: "2em !important", - display: "block", - margin: "1px", - padding: "0", - color: "white", - fontSize: "1.14em", - fontWeight: "bold", - textDecoration: "none", - textAlign: "center", - lineHeight: ".4em", - backgroundColor: "rgba(0,60,136,0.5)", - border: "none", - borderRadius: "2px", + button: { + width: '10em !important', + height: '2em !important', + display: 'block', + margin: '1px', + padding: '0', + color: 'white', + fontSize: '1.14em', + fontWeight: 'bold', + textDecoration: 'none', + textAlign: 'center', + lineHeight: '.4em', + backgroundColor: 'rgba(0,60,136,0.5)', + border: 'none', + borderRadius: '2px' - }, - card: { - width: 320, - }, - cardContent: { - padding: 6, - height: "calc(100vh - 12em)", - overflowY: "auto", - }, - cardHeader: { - background: "#467a9e", - color: "#fff", - padding: 6, - }, - closeButton: { - position: "absolute", - right: theme.spacing(1.5), - top: theme.spacing(1), - background: "none !important", - }, - checkbox: { - minWidth: 0, - }, - legendLabelRoot: { - minHeight: 0, - flexDirection: "row-reverse", - }, - legendLabelContent: { - margin: 0, - padding: 0, - }, - legendImage: { - width: "90%", - }, - opacitySlider: { - width: "80%", - margin: "auto", - }, - divider: { - width: "80%", - margin: "auto", - "&:last-child": { - display: "none", }, - }, - categoryHeader: { - background: "#5f99c1", - color: "#ffff", - lineHeight: 2, - fontSize: "x-large !important", - fontWeight: 700, - paddingLeft: 5, - }, - categoryDropDown: { - alignSelf: "center", - position: "initial", - }, - sourceHeader: { - background: "#e6ecf1", - justifyContent: "space-between", - overflow: "hidden", - paddingRight: 2, - }, - headerPlaceholder: { - borderRadius: 4, - marginBottom: 6, - marginTop: 6, - }, - sourceCheckbox: { - background: "transparent", - height: "100%", - minHeight: 60, - display: "flex", - justifyContent: "center", - }, - sourceLabel: { - fontWeight: "500", - padding: "1em", - fontSize: "15px !important", - lineHeight: "24px", - }, - regionHeader: { - paddingLeft: "10px !important", - marginTop: 1, - marginBottom: 1, - height: 38, - borderRadius: 4, - alignItems: "stretch", - alignContent: "center", - }, - sensorButton: { - margin: 5, - }, - sourceContent: { - marginRight: 5, - }, + card: { + width: 320 + }, + cardContent: { + padding: 6, + height: 'calc(100vh - 12em)', + overflowY: 'auto' + }, + cardHeader: { + background: '#467a9e', + color: '#fff', + padding: 6 + }, + closeButton: { + position: 'absolute', + right: theme.spacing(1.5), + top: theme.spacing(1), + background: 'none !important' + }, + checkbox: { + minWidth: 0 + }, + legendLabelRoot: { + minHeight: 0, + flexDirection: 'row-reverse' + }, + legendLabelContent: { + margin: 0, + padding: 0 + }, + legendImage: { + width: '90%' + }, + opacitySlider: { + width: '80%', + margin: 'auto' + }, + divider: { + 'width': '80%', + 'margin': 'auto', + '&:last-child': { + display: 'none' + } + }, + categoryHeader: { + background: '#5f99c1', + color: '#ffff', + lineHeight: 2, + fontSize: 'x-large !important', + fontWeight: 700, + paddingLeft: 5 + }, + categoryDropDown: { + alignSelf: 'center', + position: 'initial' + }, + sourceHeader: { + background: '#e6ecf1', + justifyContent: 'space-between', + overflow: 'hidden', + paddingRight: 2 + }, + headerPlaceholder: { + borderRadius: 4, + marginBottom: 6, + marginTop: 6 + }, + sourceCheckbox: { + background: 'transparent', + height: '100%', + minHeight: 60, + display: 'flex', + justifyContent: 'center' + }, + sourceLabel: { + fontWeight: '500', + padding: '1em', + fontSize: '15px !important', + lineHeight: '24px' + }, + regionHeader: { + paddingLeft: '10px !important', + marginTop: 1, + marginBottom: 1, + height: 38, + borderRadius: 4, + alignItems: 'stretch', + alignContent: 'center' + }, + sensorButton: { + margin: 5 + }, + sourceContent: { + marginRight: 5 + } })); type Props = { @@ -160,217 +160,258 @@ type Props = { }; const SourcesControl = ({ - el, - data, - sourcesConfig, - sources, - selectedFeature, - toggleRegions, - handlePopupOpen, - handlePopupClose, + el, + data, + sourcesConfig, + sources, + selectedFeature, + toggleRegions, + handlePopupOpen, + handlePopupClose }: Props) => { - const classes = useStyles(); + const classes = useStyles(); - const [sourcesVisibility, updateSourcesVisibility] = React.useState<{ + const [sourcesVisibility, updateSourcesVisibility] = React.useState<{ [sourceId: string]: boolean, }>({}); - const [isSidebarOpen, toggleSidebar] = React.useState(true); - const [infoDialogControl, toggleInfoDialog] = React.useState(false); - const [selectedSourceId, setSourceId] = React.useState(""); - const [showSensors, updateShowSensors] = React.useState(false); + const [allSourcesVisibility, updateAllSourcesVisibility] = React.useState(true); + const [isSidebarOpen, toggleSidebar] = React.useState(true); + const [infoDialogControl, toggleInfoDialog] = React.useState(false); + const [selectedSourceId, setSourceId] = React.useState(''); + const [showSensors, updateShowSensors] = React.useState(false); - React.useEffect(() => { + React.useEffect(() => { // When new data comes in, make all sources visible. - if (data) { - const updatedSourcesVisibility = Object.keys(data).reduce( - (regionsVisibility, sourceId) => { - regionsVisibility[sourceId] = true; - return regionsVisibility; - }, - {} - ); - updateSourcesVisibility(updatedSourcesVisibility); - toggleRegions(updatedSourcesVisibility); - } - }, [data]); + if (data) { + const updatedSourcesVisibility = Object.keys(data).reduce( + (regionsVisibility, sourceId) => { + regionsVisibility[sourceId] = true; + return regionsVisibility; + }, + {} + ); + updateSourcesVisibility(updatedSourcesVisibility); + toggleRegions(updatedSourcesVisibility); + } + }, [data]); - const handleInfoDialog = (e, id) => { - e.stopPropagation(); - setSourceId(id); - toggleInfoDialog(true); - }; + const handleInfoDialog = (e, id) => { + e.stopPropagation(); + setSourceId(id); + toggleInfoDialog(true); + }; - const toggleSource = (e, sourceId) => { - e.stopPropagation(); - if (data) { - const updatedSourcesVisibility = { - ...sourcesVisibility, - [sourceId]: !sourcesVisibility[sourceId], - }; - updateSourcesVisibility(updatedSourcesVisibility); - toggleRegions(updatedSourcesVisibility); - } - }; + const toggleSource = (e, sourceId) => { + e.stopPropagation(); + if (data) { + const updatedSourcesVisibility = { + ...sourcesVisibility, + [sourceId]: !sourcesVisibility[sourceId] + }; + updateSourcesVisibility(updatedSourcesVisibility); + toggleRegions(updatedSourcesVisibility); + } + }; - const handleSensorClick = (sensorIdx) => { - if (selectedFeature && selectedFeature.idx === sensorIdx) { - handlePopupClose(); - } else { - handlePopupOpen(sensorIdx); - } - }; + const toggleAllSources = () => { + if (data) { + const updatedSourcesVisibility = Object.keys(data).reduce( + (regionsVisibility, sourceId) => { + regionsVisibility[sourceId] = !allSourcesVisibility; + return regionsVisibility; + }, + {} + ); + updateSourcesVisibility(updatedSourcesVisibility); + toggleRegions(updatedSourcesVisibility); + updateAllSourcesVisibility(!allSourcesVisibility); + } + }; - const getStatusStyle = (sensor) => { - switch (sensor.properties.online_status) { - case "online": - return ".15rem solid green"; - case "offline": - return ".15rem dashed red"; - default: - return "none"; - } - }; + const handleSensorClick = (sensorIdx) => { + if (selectedFeature && selectedFeature.idx === sensorIdx) { + handlePopupClose(); + } else { + handlePopupOpen(sensorIdx); + } + }; + + const getStatusStyle = (sensor) => { + switch (sensor.properties.online_status) { + case 'online': + return '.15rem solid green'; + case 'offline': + return '.15rem dashed red'; + default: + return 'none'; + } + }; - return ReactDOM.createPortal( - <> - - - - + + + + Explore Sources - - updateShowSensors(false)} - > - - - - - - {sources.map((source) => { - const primaryColor = getSourceColor(sourcesConfig[source.id]); - const secondaryColor = interpolateRgb(primaryColor, "#fff")(0.8); - if (!data) - return ( - - ); - return ( - + updateShowSensors(false)} > - toggleSource(e, source.id)} - > - } - checkedIcon={ - - } - /> - - <> - - {source.label} - - - {data[source.id].sensorCount} - - handleInfoDialog(e, source.id)} - edge="end" - size="small" - id={`info-icon-${classes.sourceCheckbox} `} - color="primary" - > - - - - - } - > - {data ? ( - entries(data[source.id].regions) - .sort() - .map(([region, sensors]) => ( - - {region} ({sensors.length}) - - } - > - - {sensors.map((sensor) => ( - - ))} - - - )) - ) : ( - - )} - - ); - })} - - - - , el - ); + selectedFeature.idx === sensor.idx ? + primaryColor : + secondaryColor, + border: getStatusStyle(sensor) + }} + size="small" + disabled={!sourcesVisibility[source.id]} + onClick={() => handleSensorClick(sensor.idx)} + > + {sensor.name} + + ))} + + + )) + ) : ( + + )} + + ); + })} + + + + , el + ); }; export default SourcesControl; From 8e15d3242cfd110c977b6895c02440ffcc0372d5 Mon Sep 17 00:00:00 2001 From: Vismayak Mohanarajan Date: Thu, 15 Jun 2023 13:09:39 -0500 Subject: [PATCH 2/2] Update SourcesControl.jsx Testing also done --- .../core/src/components/ol/SourcesControl.jsx | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/packages/core/src/components/ol/SourcesControl.jsx b/packages/core/src/components/ol/SourcesControl.jsx index 03f54b80..6bb94efa 100644 --- a/packages/core/src/components/ol/SourcesControl.jsx +++ b/packages/core/src/components/ol/SourcesControl.jsx @@ -270,31 +270,33 @@ const SourcesControl = ({ + toggleAllSources(e)} > - toggleAllSources(e)} - > - } - checkedIcon={ - - } - /> - - + } + checkedIcon={ + + } + /> + + + Switch on/off all sources - + + {sources.map((source) => { const primaryColor = getSourceColor(sourcesConfig[source.id]); const secondaryColor = interpolateRgb(primaryColor, '#FFF')(0.8);