From f8c6733260fc7385494b0c52c0811fb2d39028e8 Mon Sep 17 00:00:00 2001 From: Jin Igarashi Date: Fri, 27 Dec 2024 20:14:38 +0900 Subject: [PATCH] migrate CEEI dashboard to svelte 5 --- .../routes/(map)/dashboards/ceei/+page.svelte | 124 ++-- .../ceei/components/DropdownSearch.svelte | 34 +- .../ceei/components/LayerControl.svelte | 561 ++++++++++-------- .../components/UploadDataErrorToast.svelte | 6 +- .../dashboards/ceei/utils/layerHelper.ts | 18 - sites/geohub/svelte.config.js | 7 + 6 files changed, 397 insertions(+), 353 deletions(-) diff --git a/sites/geohub/src/routes/(map)/dashboards/ceei/+page.svelte b/sites/geohub/src/routes/(map)/dashboards/ceei/+page.svelte index 96a69cade6..98068cbc4f 100644 --- a/sites/geohub/src/routes/(map)/dashboards/ceei/+page.svelte +++ b/sites/geohub/src/routes/(map)/dashboards/ceei/+page.svelte @@ -1,7 +1,5 @@ @@ -41,7 +49,7 @@ placeholder="Select a country..." use:clickOutside={() => (showResults = false)} bind:value={inputValue} - on:focusin={() => (showResults = true)} + onfocusin={() => (showResults = true)} />
@@ -49,7 +57,7 @@ diff --git a/sites/geohub/src/routes/(map)/dashboards/ceei/components/LayerControl.svelte b/sites/geohub/src/routes/(map)/dashboards/ceei/components/LayerControl.svelte index 15ee6e6f43..7de7e62540 100644 --- a/sites/geohub/src/routes/(map)/dashboards/ceei/components/LayerControl.svelte +++ b/sites/geohub/src/routes/(map)/dashboards/ceei/components/LayerControl.svelte @@ -11,37 +11,43 @@ import { MAPSTORE_CONTEXT_KEY, Slider, type MapStore } from '@undp-data/svelte-undp-components'; import chroma from 'chroma-js'; import { getContext } from 'svelte'; - import type { Layer } from '../stores'; + import { get } from 'svelte/store'; + import { layers as layersStore, type Layer } from '../stores'; import { applyDataSimulation, deleteLayer, downloadData, duplicateLayer, editLayerName, - toggleLayerVisibility, updatePaintOfLayer, uploadData } from '../utils/layerHelper'; const mapStore: MapStore = getContext(MAPSTORE_CONTEXT_KEY); - export let layerDetails: Layer; - export let index: number; + interface Props { + layerDetails: Layer; + index: number; + } + + let { layerDetails = $bindable(), index = $bindable() }: Props = $props(); - let showCustomizeDataModal = false; - let showSimulateModal = false; - let showEditLayerNameModal = false; - let showEditColorScaleModel = false; + let showCustomizeDataModal = $state(false); + let showSimulateModal = $state(false); + let showEditLayerNameModal = $state(false); + let showEditColorScaleModel = $state(false); - let editLayerNameValue = layerDetails.name; + let editLayerNameValue = $state(layerDetails.name); let groupCount = 10; - let colorMapName = 'rdylbu'; - let colorGroups = chroma.scale(layerDetails.colorMap).colors(groupCount); - $: { + let colorMapName = $state('rdylbu'); + + const getColorGroups = () => { const isReverse = layerDetails.colorMap.indexOf('_r') !== -1; - colorGroups = chroma.scale(layerDetails.colorMap.replace('_r', '')).colors(groupCount); - if (isReverse) colorGroups.reverse(); - } + const colors = chroma.scale(layerDetails.colorMap.replace('_r', '')).colors(groupCount); + if (isReverse) colors.reverse(); + return colors; + }; + let colorGroups = $state(getColorGroups()); const openSimulateModal = () => { showSimulateModal = true; @@ -72,7 +78,7 @@ const tippyTooltip = initTooltipTippy(); - let sliders = [ + let sliders = $state([ { id: 1, percentage: 7.1429, label: 'Solar Power Potential', locked: false }, { id: 2, percentage: 7.1429, label: 'Wind Speed', locked: false }, { id: 3, percentage: 7.1429, label: 'Geothermal Power Potential', locked: false }, @@ -102,13 +108,13 @@ label: 'Fossil Fuel Share on Energy Capacity and Generation', locked: false } - ]; + ]); - let pillarSliders = [ + let pillarSliders = $state([ { id: 1, percentage: 28.57, label: 'Potential', locked: false }, { id: 2, percentage: 50, label: 'Means and Resources', locked: false }, { id: 3, percentage: 21.43, label: 'Urgent', locked: false } - ]; + ]); const pillarTotal = (ids) => { let total = 0; @@ -326,6 +332,24 @@ callback(index); } }; + + const toggleLayerVisibility = (index: number) => { + if (!$mapStore || !get(layersStore)) return true; + + const layers = get(layersStore); + + const mapVisibility = $mapStore.getLayoutProperty(layers[index].layerId, 'visibility'); + if (mapVisibility === 'visible') { + $mapStore.setLayoutProperty(layers[index].layerId, 'visibility', 'none'); + layers[index].isVisible = false; + } else { + $mapStore.setLayoutProperty(layers[index].layerId, 'visibility', 'visible'); + layers[index].isVisible = true; + } + + layersStore.set(layers); + layerDetails = layerDetails; + }; {#if index !== 0} - + { + onclick={() => { deleteLayer($mapStore, index); }} - on:keydown={handleEnterKey} + onkeydown={handleEnterKey} class:disabled={!layerDetails.isDataLoaded} > @@ -460,98 +483,178 @@
-
-

Adjust indicator weights in the CEEI for automatic recalculation.

-
-
-
-
-
-
Potential
-
{pillarSliders[0].percentage.toFixed(2)}%
+ {#snippet content()} +
+

+ Adjust indicator weights in the CEEI for automatic recalculation. +

+
+
+
+
+
+
Potential
+
{pillarSliders[0].percentage.toFixed(2)}%
+
+
+ value.toFixed(2)} + disabled={pillarSliders[0].locked} + on:change={(event) => { + let newValue = 0; + if (event?.detail?.values[0]) { + newValue = event?.detail?.values[0]; + } + handlePillarSlider(1, newValue); + }} + /> +
-
- value.toFixed(2)} - disabled={pillarSliders[0].locked} - on:change={(event) => { - let newValue = 0; - if (event?.detail?.values[0]) { - newValue = event?.detail?.values[0]; - } - handlePillarSlider(1, newValue); - }} - /> +
+ {#each sliders as { id, percentage, label, locked }} + {#if [1, 2, 3, 4].includes(id)} +
+
+
{label}
+
+ {percentage.toFixed(2)}% + + +
+
+ value.toFixed(2)} + disabled={locked} + on:change={(event) => { + let newValue = 0; + if (event?.detail?.values[0]) { + newValue = event?.detail?.values[0]; + } + handleSlider(id, newValue); + }} + /> +
+ {/if} + {/each}
-
- {#each sliders as { id, percentage, label, locked }} - {#if [1, 2, 3, 4].includes(id)} -
-
-
{label}
-
- {percentage.toFixed(2)}% - +
+
+
+
Urgent
+
{pillarSliders[2].percentage.toFixed(2)}%
+
+
+ value.toFixed(2)} + disabled={pillarSliders[2].locked} + on:change={(event) => { + let newValue = 0; + if (event?.detail?.values[0]) { + newValue = event?.detail?.values[0]; + } + handlePillarSlider(3, newValue); + }} + /> +
+
+
+ {#each sliders as { id, percentage, label, locked }} + {#if [12, 13, 14, 15].includes(id)} +
+
+
{label}
+
+ {percentage.toFixed(2)}% + + +
+ value.toFixed(2)} + disabled={locked} + on:change={(event) => { + let newValue = 0; + if (event?.detail?.values[0]) { + newValue = event?.detail?.values[0]; + } + handleSlider(id, newValue); + }} + />
- value.toFixed(2)} - disabled={locked} - on:change={(event) => { - let newValue = 0; - if (event?.detail?.values[0]) { - newValue = event?.detail?.values[0]; - } - handleSlider(id, newValue); - }} - /> -
- {/if} - {/each} + {/if} + {/each} +
- -
+
-
Urgent
-
{pillarSliders[2].percentage.toFixed(2)}%
+
Means and Resources
+
{pillarSliders[1].percentage.toFixed(2)}%
value.toFixed(2)} - disabled={pillarSliders[2].locked} + disabled={pillarSliders[1].locked} on:change={(event) => { let newValue = 0; if (event?.detail?.values[0]) { newValue = event?.detail?.values[0]; } - handlePillarSlider(3, newValue); + handlePillarSlider(2, newValue); }} />
{#each sliders as { id, percentage, label, locked }} - {#if [12, 13, 14, 15].includes(id)} + {#if [5, 6, 7, 8, 9, 10, 11].includes(id)}
{label}
{percentage.toFixed(2)}% -
-
-
-
-
Means and Resources
-
{pillarSliders[1].percentage.toFixed(2)}%
-
-
- value.toFixed(2)} - disabled={pillarSliders[1].locked} - on:change={(event) => { - let newValue = 0; - if (event?.detail?.values[0]) { - newValue = event?.detail?.values[0]; - } - handlePillarSlider(2, newValue); - }} - /> -
-
-
- {#each sliders as { id, percentage, label, locked }} - {#if [5, 6, 7, 8, 9, 10, 11].includes(id)} -
-
-
{label}
-
- {percentage.toFixed(2)}% - - -
-
- value.toFixed(2)} - disabled={locked} - on:change={(event) => { - let newValue = 0; - if (event?.detail?.values[0]) { - newValue = event?.detail?.values[0]; - } - handleSlider(id, newValue); - }} - /> -
- {/if} - {/each} -
-
-
-
- - -
- - - -
-
-

Download {layerDetails.name} data as a .csv file to customise it on your device.

+ {/snippet} + {#snippet buttons()} +
-
-
-

Upload your adjusted .csv file.

- {#if !layerDetails.isDataLoaded} -
- -
- {/if}
-
+ {/snippet} + + + + {#snippet content()} +
+
+

Download {layerDetails.name} data as a .csv file to customise it on your device.

+ +
+
+

Upload your adjusted .csv file.

+ + {#if !layerDetails.isDataLoaded} +
+ +
+ {/if} +
+
+ {/snippet}
-
- -
-
- -
+ {#snippet content()} +
+ +
+ {/snippet} + {#snippet buttons()} +
+ +
+ {/snippet}
-
-
- -
+ {#snippet content()} +
+ {/snippet} + {#snippet buttons()} +
+ +
+ {/snippet}