From 023cfc18110d6bf44939900ab00bd65b8501c074 Mon Sep 17 00:00:00 2001 From: Chad Burt Date: Thu, 11 Jan 2024 15:28:41 -0800 Subject: [PATCH] WIP --- .../client/src/admin/data/DataSettings.tsx | 22 +++++- packages/client/src/dataLayers/Legend.tsx | 47 ++++++------ .../src/dataLayers/MapContextManager.ts | 71 +++++++++++++++---- packages/client/tailwind.config.js | 1 + 4 files changed, 104 insertions(+), 37 deletions(-) diff --git a/packages/client/src/admin/data/DataSettings.tsx b/packages/client/src/admin/data/DataSettings.tsx index 6f8532431..69690509a 100644 --- a/packages/client/src/admin/data/DataSettings.tsx +++ b/packages/client/src/admin/data/DataSettings.tsx @@ -40,6 +40,16 @@ export default function DataSettings() { } }, [mapContext.legends, mapContext.layerStatesByTocStaticId]); + const hiddenItems = useMemo(() => { + const hiddenItems: string[] = []; + for (const id in mapContext.layerStatesByTocStaticId) { + if (mapContext.layerStatesByTocStaticId[id].hidden) { + hiddenItems.push(id); + } + } + return hiddenItems; + }, [mapContext.layerStatesByTocStaticId]); + return ( <> @@ -60,10 +70,20 @@ export default function DataSettings() { maxHeight={800} className="absolute ml-5 top-5 z-10" items={legendState.items} - hiddenItems={[]} + hiddenItems={hiddenItems} opacity={{}} zOrder={{}} map={mapContext.manager?.map} + onZOrderChange={() => {}} + onHiddenItemsChange={(id, hidden) => { + if (hidden) { + console.log("hide"); + mapContext.manager?.hideLayer(id); + } else { + console.log("show"); + mapContext.manager?.showLayer(id); + } + }} /> )} {data?.projectBySlug && ( diff --git a/packages/client/src/dataLayers/Legend.tsx b/packages/client/src/dataLayers/Legend.tsx index acfc6669d..f1e114109 100644 --- a/packages/client/src/dataLayers/Legend.tsx +++ b/packages/client/src/dataLayers/Legend.tsx @@ -6,8 +6,10 @@ import { GLLegendPanel, LegendForGLLayers } from "./legends/LegendDataModel"; import * as Accordion from "@radix-ui/react-accordion"; import { CaretDownIcon, + DotsHorizontalIcon, EyeClosedIcon, EyeOpenIcon, + HeightIcon, } from "@radix-ui/react-icons"; import { useTranslation } from "react-i18next"; import Spinner from "../components/Spinner"; @@ -57,6 +59,7 @@ export default function Legend({ maxHeight, backdropBlur: blur, persistedStateKey, + onZOrderChange, }: { backdropBlur?: boolean; items: LegendItem[]; @@ -124,6 +127,7 @@ export default function Legend({ visible={!hiddenItems || !hiddenItems.includes(item.id)} map={map} skipTopBorder={i === 0} + onZOrderChange={onZOrderChange} /> ); })} @@ -141,29 +145,28 @@ function LegendListItem({ map, onHiddenItemsChange, skipTopBorder, + onZOrderChange, }: { item: LegendItem; visible: boolean; map?: Map; onHiddenItemsChange?: (id: string, hidden: boolean) => void; skipTopBorder?: boolean; + onZOrderChange?: (id: string, zOrder: number) => void; }) { const isSingleSymbol = (item.type === "GLStyleLegendItem" && item.legend?.type === "SimpleGLLegend" && item.legend.symbol) || (item.type === "CustomGLSourceSymbolLegend" && item.symbols.length <= 1); - const [hovered, setHovered] = useState(false); return (
  • setHovered(true)} - onMouseOut={() => setHovered(false)} - className={`${ + className={`group ${ skipTopBorder ? "" : "border-t border-black border-opacity-5" - } p-2 max-w-full ${!visible ? "opacity-50" : "opacity-100"} group`} + } p-2 max-w-full ${!visible ? "opacity-50" : "opacity-100"}`} > -
    +
    {/* If single-symbol, show inline image */} {isSingleSymbol && (
    @@ -184,23 +187,23 @@ function LegendListItem({ {/* Buttons */}
    - {onHiddenItemsChange && ( - { - if (onHiddenItemsChange) { - onHiddenItemsChange(item.id, visible); - } - }} - visible={visible} - /> - )} - {/* */} +
    {!isSingleSymbol && ( diff --git a/packages/client/src/dataLayers/MapContextManager.ts b/packages/client/src/dataLayers/MapContextManager.ts index cf961e86b..7b32c1bf1 100644 --- a/packages/client/src/dataLayers/MapContextManager.ts +++ b/packages/client/src/dataLayers/MapContextManager.ts @@ -145,6 +145,12 @@ export interface LayerState { opacity?: number; loading: boolean; error?: Error; + /** + * If true, it means that while the layer may be "visible" as selected from + * the table of contents, the user may have temporarily hidden it in the + * legend. + */ + hidden?: boolean; } export interface SketchLayerState extends LayerState { @@ -1427,17 +1433,22 @@ class MapContextManager extends EventEmitter { } const layers = isUnderLabels ? underLabels : overLabels; if ( - layer.interactivitySettings && - layer.interactivitySettings.type === - InteractivityType.SidebarOverlay + !this.internalState.layerStatesByTocStaticId[layerId] + ?.hidden ) { - layers.push( - ...addInteractivityExpressions( - styleData.layers as AnyLayer[] - ) - ); - } else { - layers.push(...styleData.layers); + if ( + layer.interactivitySettings && + layer.interactivitySettings.type === + InteractivityType.SidebarOverlay + ) { + layers.push( + ...addInteractivityExpressions( + styleData.layers as AnyLayer[] + ) + ); + } else { + layers.push(...styleData.layers); + } } } else { setTimeout(() => { @@ -1481,12 +1492,16 @@ class MapContextManager extends EventEmitter { }); const layers = isUnderLabels ? underLabels : overLabels; if ( - layer.interactivitySettings?.type === - InteractivityType.SidebarOverlay + !this.internalState.layerStatesByTocStaticId[layerId]?.hidden ) { - glLayers = addInteractivityExpressions(glLayers); + if ( + layer.interactivitySettings?.type === + InteractivityType.SidebarOverlay + ) { + glLayers = addInteractivityExpressions(glLayers); + } + layers.push(...glLayers); } - layers.push(...glLayers); } else if (isCustomSourceType(source.type) && layer.sublayer) { // Add sublayer info if needed if (!Array.isArray(this.customSources[source.id].sublayers)) { @@ -2854,6 +2869,34 @@ class MapContextManager extends EventEmitter { } updateLegends = debounce(this._updateLegends, 20); + + hideLayer(stableId: string) { + this.setState((prev) => ({ + ...prev, + layerStatesByTocStaticId: { + ...prev.layerStatesByTocStaticId, + [stableId]: { + ...prev.layerStatesByTocStaticId[stableId], + hidden: true, + }, + }, + })); + this.updateStyle(); + } + + showLayer(stableId: string) { + this.setState((prev) => ({ + ...prev, + layerStatesByTocStaticId: { + ...prev.layerStatesByTocStaticId, + [stableId]: { + ...prev.layerStatesByTocStaticId[stableId], + hidden: false, + }, + }, + })); + this.updateStyle(); + } } export default MapContextManager; diff --git a/packages/client/tailwind.config.js b/packages/client/tailwind.config.js index 1976b4bd9..0583ee86e 100644 --- a/packages/client/tailwind.config.js +++ b/packages/client/tailwind.config.js @@ -85,6 +85,7 @@ module.exports = { extend: { scale: ["active"], padding: ["hover"], + display: ["group-hover"], }, space: ["responsive", "direction"], inset: ["responsive", "direction"],