From 19b47814ff2f86e7a2719d4bbd581a6b83f2a762 Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:44:28 -0400 Subject: [PATCH 1/7] adding method to remove an entire model run/layers from state --- src/context/map-context.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/context/map-context.js b/src/context/map-context.js index d70a8fb5..d83add86 100644 --- a/src/context/map-context.js +++ b/src/context/map-context.js @@ -134,6 +134,15 @@ export const LayersProvider = ({ children }) => { setDefaultModelLayers(newLayers); }; + const removeModelRun = groupId => { + const index = defaultModelLayers.findIndex(l => l.group === groupId); + if (index === -1) { + return; + } + const newLayers = defaultModelLayers.filter(l => l.group !== groupId); + setDefaultModelLayers(newLayers); + }; + const setLayerOpacity = (id, newOpacity) => { const newLayers = [...defaultModelLayers]; const index = newLayers.findIndex(l => l.id === id); @@ -166,6 +175,7 @@ export const LayersProvider = ({ children }) => { showShareComment, setShowShareComment, swapLayers, removeLayer, + removeModelRun, layerTypes, baseMap, setBaseMap, From cb8c61f6e55b0595b831cfcf23e60ea4b2ca583c Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:45:58 -0400 Subject: [PATCH 2/7] removing unused code --- src/components/trays/model-selection/catalogItems.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/trays/model-selection/catalogItems.js b/src/components/trays/model-selection/catalogItems.js index 4f50366c..5160d59f 100644 --- a/src/components/trays/model-selection/catalogItems.js +++ b/src/components/trays/model-selection/catalogItems.js @@ -21,7 +21,6 @@ export default function CatalogItems(data) { const [accordianDateIndex, setAccordianDateIndex] = useState(-1); // variables for the display of checkbox labels - let stormOrModelName = null; let stormOrModelEle = null; let numberName = null; let numberEle = null; @@ -137,14 +136,12 @@ export default function CatalogItems(data) { else { // save the name of the element for tropical storms and advisory numbers if (data.isTropical) { - stormOrModelName = ''; stormOrModelEle = 'storm_name'; numberName = ' Adv: '; numberEle = 'advisory_number'; } // save the name of the synoptic ADCIRC models and cycle numbers else if (!data.isTropical) { - stormOrModelName = ''; stormOrModelEle = 'model'; numberName = ' Cycle: '; numberEle = 'cycle'; @@ -185,7 +182,6 @@ export default function CatalogItems(data) { key={ mbrIdx } checked={ getCheckedState(mbr.group) } label={ - stormOrModelName + ((mbr['properties'][stormOrModelEle] === undefined) ? 'Data error' : mbr['properties'][stormOrModelEle].toUpperCase()) + ', ' + numberName + mbr['properties'][numberEle] + ', Type: ' + mbr['properties']['event_type'] + From b5a93db0200b4dd8698439c99e82c49ba3e74dea Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:46:46 -0400 Subject: [PATCH 3/7] adding the grouping of model runs --- src/components/trays/layers/list.js | 160 ++++++++++++++++++++++++++-- 1 file changed, 149 insertions(+), 11 deletions(-) diff --git a/src/components/trays/layers/list.js b/src/components/trays/layers/list.js index 94b5c01c..1d57bd36 100644 --- a/src/components/trays/layers/list.js +++ b/src/components/trays/layers/list.js @@ -1,27 +1,165 @@ -import React from 'react'; +import React, {Fragment} from 'react'; import { - AccordionGroup, - Divider, + AccordionGroup, Box, + Divider, Accordion, AccordionSummary, AccordionDetails } from '@mui/joy'; import { useLayers } from '@context'; import { LayerCard } from './layer-card'; +import { DeleteModelRunButton } from "@components/trays/layers/delete-layer-button"; +/** + * gets the header data property name index + * This takes into account the two types of runs (tropical, synoptic) + * + * @param layerProps + * @param type + * @returns {string} + */ +const getPropertyName = (layerProps, type) => { + // init the return + let ret_val = undefined; + + // capture the name of the element for tropical storms and advisory numbers + if (layerProps['met_class'] === 'tropical') { + switch (type) { + case 'stormOrModelEle': + ret_val = layerProps['storm_name']; + break; + case 'numberName': + ret_val = ' Adv: '; + break; + case 'numberEle': + ret_val = layerProps['advisory_number']; + break; + } + } + // capture the name of the synoptic ADCIRC models and cycle numbers + else { + switch (type) { + case 'stormOrModelEle': + ret_val = layerProps['model']; + break; + case 'numberName': + ret_val = ' Cycle: '; + break; + case 'numberEle': + ret_val = layerProps['cycle']; + break; + } + } + + // return to the caller + return ret_val; +}; + + +/** + * gets the summary header text for the layer groups. + * This takes into account the two types of runs (tropical, synoptic) + * + * @param layerProps + * @returns {string} + */ +const getHeaderSummary = (layerProps) => { + // get the full accordian summary text + return layerProps['run_date'] + ': ' + + ((getPropertyName(layerProps, 'stormOrModelEle') === undefined) ? 'Data error' : getPropertyName(layerProps, 'stormOrModelEle').toUpperCase()) + + ', ' + getPropertyName(layerProps, 'numberName') + getPropertyName(layerProps, 'numberEle') + + ', Type: ' + layerProps['event_type'] + + ', Grid: ' + layerProps['grid_type'] + + ((layerProps['meteorological_model'] === 'None') ? '' : ', ' + layerProps['meteorological_model']); +}; + +/** + * renders the layer cards for a model run + * + * @param layers + * @param group + * @returns {*[]} + */ +const renderLayerCards = (layers, group) => { + // init the return + const layerCards = []; + + // filter/map the layers to create/return the layer card list + layers + // capture the layers for this group + .filter(layer => ( layer['group'] === group) ) + // at this point we have the distinct runs + .map((layer, idx) => { + layerCards.push( ); + }); + + // return to the caller + return layerCards; +}; + +/** + * collect the list of unique layer groups + * + * @param layers + * @returns {*[]} + */ +const getGroupList = (layers) => { + // init the group list + const groupList = []; + + // loop through the layers and get the unique groups + layers + // filter by the group name + .filter((groups, idx, self) => + ( idx === self.findIndex((t)=> ( t['group'] === groups['group']) ))) + .sort((a, b) => + a['run_date'] < b['run_date'] ? 1 : -1) + // at this point we have the distinct runs + .map((layer) => { + groupList.push(layer); + }); + + // return the list of groups + return groupList; +}; + +/** + * render the layers for the selected run groups + * + * @returns {JSX.Element} + * @constructor + */ export const LayersList = () => { + // get a handle to the layer state const { defaultModelLayers } = useLayers(); + + // get the default layers const layers = [...defaultModelLayers]; + // get the unique groups in the selected run groups + const groupList = getGroupList(layers); + + // loop through the layers and put them away return ( { - layers - .sort((a, b) => a.state.order - b.state.order) - .map((layer, index) => { + // loop through the layer groups and put them away + groupList + // filter by the group name + .filter((groups, idx, self) => + ( idx === self.findIndex((t)=> ( t['group'] === groups['group']) ))) + // at this point we have the distinct runs + .map((groups, idx) => { return ( - + + + + + { getHeaderSummary(groups['properties']) } + + + + + { renderLayerCards( layers, groups['group'] ) } + + ); }) } From 98fb07fe6d40ee0f69b3491a5c87e6166de83f39 Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:47:06 -0400 Subject: [PATCH 4/7] simplifying the import location --- src/components/trays/layers/form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/trays/layers/form.js b/src/components/trays/layers/form.js index e2a9c1a8..c618443b 100644 --- a/src/components/trays/layers/form.js +++ b/src/components/trays/layers/form.js @@ -1,5 +1,5 @@ import React from 'react'; -import { ModelSelection } from '../model-selection/model-selection'; +import { ModelSelection } from '@model-selection/model-selection'; export const AddLayerForm = () => { return ( From ad861cdaa1da61365d045efd156e3265934e30d3 Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:47:34 -0400 Subject: [PATCH 5/7] adding a button to remove an entire model run from state --- .../trays/layers/delete-layer-button.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/components/trays/layers/delete-layer-button.js b/src/components/trays/layers/delete-layer-button.js index 6349f07e..bca856fc 100644 --- a/src/components/trays/layers/delete-layer-button.js +++ b/src/components/trays/layers/delete-layer-button.js @@ -31,3 +31,30 @@ export const DeleteLayerButton = ({ layerId }) => { DeleteLayerButton.propTypes = { layerId: PropTypes.string.isRequired }; + +export const DeleteModelRunButton = ({ groupId }) => { + const { removeModelRun } = useLayers(); + + return ( + removeModelRun(groupId) } + sx={{ + alignContent: 'right', + m: 1, + 'filter': 'opacity(0.3)', + transition: 'filter 250ms', + '&:hover': { + 'filter': 'opacity(1.0)', + }, + }} + > + + + ); +}; + +DeleteModelRunButton.propTypes = { + groupId: PropTypes.string.isRequired +}; From d5e8eb6b157ea8e075b6938c0ba2eb1032034072 Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:02:12 -0400 Subject: [PATCH 6/7] tidying up --- src/components/trays/layers/list.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/trays/layers/list.js b/src/components/trays/layers/list.js index 1d57bd36..98be158e 100644 --- a/src/components/trays/layers/list.js +++ b/src/components/trays/layers/list.js @@ -1,4 +1,4 @@ -import React, {Fragment} from 'react'; +import React from 'react'; import { AccordionGroup, Box, Divider, Accordion, AccordionSummary, AccordionDetails @@ -148,18 +148,18 @@ export const LayersList = () => { // at this point we have the distinct runs .map((groups, idx) => { return ( - - - - - { getHeaderSummary(groups['properties']) } - + + + + + { getHeaderSummary(groups['properties']) } + - - { renderLayerCards( layers, groups['group'] ) } - - + + { renderLayerCards( layers, groups['group'] ) } + + ); }) } From eff16ef750644badb12b0315964d22c6fb0f7b18 Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:57:48 -0400 Subject: [PATCH 7/7] removing sort --- src/components/trays/layers/list.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/trays/layers/list.js b/src/components/trays/layers/list.js index 98be158e..d5757be8 100644 --- a/src/components/trays/layers/list.js +++ b/src/components/trays/layers/list.js @@ -109,8 +109,8 @@ const getGroupList = (layers) => { // filter by the group name .filter((groups, idx, self) => ( idx === self.findIndex((t)=> ( t['group'] === groups['group']) ))) - .sort((a, b) => - a['run_date'] < b['run_date'] ? 1 : -1) + // .sort((a, b) => + // a['run_date'] < b['run_date'] ? 1 : -1) // at this point we have the distinct runs .map((layer) => { groupList.push(layer); @@ -152,7 +152,7 @@ export const LayersList = () => { - { getHeaderSummary(groups['properties']) } + { getHeaderSummary(groups['properties']) }