From 67fb751f89422f37f2f5d88c10649db46ba92049 Mon Sep 17 00:00:00 2001 From: mluena Date: Wed, 10 Apr 2024 12:28:53 +0200 Subject: [PATCH 1/3] dynamic legends --- client/src/components/map/legend/types.ts | 2 + .../src/containers/datasets/layers/index.tsx | 23 +-------- .../layers/net-forest-carbon-flux/legend.tsx | 50 ------------------ .../datasets/layers/projects/legend.tsx | 22 -------- .../layers/soil-carbon-density/legend.tsx | 50 ------------------ .../layers/tree-cover-loss/legend.tsx | 22 -------- .../datasets/layers/tree-cover/legend.tsx | 22 -------- client/src/containers/map/legend/index.tsx | 4 +- client/src/containers/map/legend/item.tsx | 22 -------- .../map/legend/legend-item/basic.tsx | 51 +++++++++++++++++++ .../legend/legend-item/choropleth.tsx} | 27 ++++++---- .../legend/legend-item/gradient.tsx} | 27 ++++++---- .../map/legend/legend-item/index.tsx | 34 +++++++++++++ client/src/types/map.ts | 5 +- 14 files changed, 125 insertions(+), 236 deletions(-) delete mode 100644 client/src/containers/datasets/layers/net-forest-carbon-flux/legend.tsx delete mode 100644 client/src/containers/datasets/layers/projects/legend.tsx delete mode 100644 client/src/containers/datasets/layers/soil-carbon-density/legend.tsx delete mode 100644 client/src/containers/datasets/layers/tree-cover-loss/legend.tsx delete mode 100644 client/src/containers/datasets/layers/tree-cover/legend.tsx delete mode 100644 client/src/containers/map/legend/item.tsx create mode 100644 client/src/containers/map/legend/legend-item/basic.tsx rename client/src/containers/{datasets/layers/land-degradation/legend.tsx => map/legend/legend-item/choropleth.tsx} (72%) rename client/src/containers/{datasets/layers/biomass-density/legend.tsx => map/legend/legend-item/gradient.tsx} (73%) create mode 100644 client/src/containers/map/legend/legend-item/index.tsx diff --git a/client/src/components/map/legend/types.ts b/client/src/components/map/legend/types.ts index 3c92daa2..321063d5 100644 --- a/client/src/components/map/legend/types.ts +++ b/client/src/components/map/legend/types.ts @@ -96,9 +96,11 @@ export interface SortableItemProps extends PropsWithChildren { export interface LegendTypeProps { className?: string; + type: 'choropleth' | 'gradient' | 'basic'; items: Array<{ value: string; color: string; + label?: string; }>; } diff --git a/client/src/containers/datasets/layers/index.tsx b/client/src/containers/datasets/layers/index.tsx index 9d1a386b..d3c3e962 100644 --- a/client/src/containers/datasets/layers/index.tsx +++ b/client/src/containers/datasets/layers/index.tsx @@ -1,22 +1,15 @@ -import type { LayerProps, DeckGLLayerProps, LayerSettings } from '@/types/layers'; +import type { LayerProps, DeckGLLayerProps } from '@/types/layers'; import BiomassDensity from '@/containers/datasets/layers/biomass-density/layer'; -import BiomassDensityLegend from '@/containers/datasets/layers/biomass-density/legend'; import BiomassDensityInfo from '@/containers/datasets/layers/constants/biomass-density'; import NetForestCarbonFluxInfo from '@/containers/datasets/layers/constants/net-flux-carbon'; import SoilCarbonDensityInfo from '@/containers/datasets/layers/constants/soil-carbon-density'; import { LandDegradationLayer } from '@/containers/datasets/layers/land-degradation/layer'; -import LandDegradationLegend from '@/containers/datasets/layers/land-degradation/legend'; import NetForestCarbonFluxLayer from '@/containers/datasets/layers/net-forest-carbon-flux/layer'; -import NetForestCarbonFluxLegend from '@/containers/datasets/layers/net-forest-carbon-flux/legend'; import { ProjectsLayer } from '@/containers/datasets/layers/projects/layer'; -import ProjectsLegend from '@/containers/datasets/layers/projects/legend'; import SoilCarbonDensityLayer from '@/containers/datasets/layers/soil-carbon-density/layer'; -import SoilCarbonDensityLegend from '@/containers/datasets/layers/soil-carbon-density/legend'; import TreeCoverLayer from '@/containers/datasets/layers/tree-cover/layer'; -import TreeCoverLegend from '@/containers/datasets/layers/tree-cover/legend'; import TreeCoverLossLayer from '@/containers/datasets/layers/tree-cover-loss/layer'; -import TreeCoverLossLegend from '@/containers/datasets/layers/tree-cover-loss/legend'; import LandDegradationInfo from './constants/land-degradation'; import TreeCoverInfo from './constants/tree-cover'; @@ -29,10 +22,6 @@ type SimpleLayerIndex = { [key: number]: React.ComponentType; }; -type LegendIndex = { - [key: string]: React.ComponentType<{ settings: LayerSettings }>; -}; - type InfoIndex = { [key: number]: React.ComponentType; }; @@ -51,16 +40,6 @@ const SIMPLE_LAYERS: SimpleLayerIndex = { 6: LandDegradationLayer, }; -export const LEGENDS: LegendIndex = { - 5: ProjectsLegend, - 1: TreeCoverLegend, - 3: NetForestCarbonFluxLegend, - 2: BiomassDensityLegend, - 4: SoilCarbonDensityLegend, - 6: LandDegradationLegend, - 7: TreeCoverLossLegend, -}; - export const INFO: InfoIndex = { 1: TreeCoverInfo, 2: BiomassDensityInfo, diff --git a/client/src/containers/datasets/layers/net-forest-carbon-flux/legend.tsx b/client/src/containers/datasets/layers/net-forest-carbon-flux/legend.tsx deleted file mode 100644 index c23eb453..00000000 --- a/client/src/containers/datasets/layers/net-forest-carbon-flux/legend.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { cn } from '@/lib/classnames'; - -import { useGetLayersId } from '@/types/generated/layer'; -import { LayerSettings, LegendType } from '@/types/layers'; - -import LegendSettings from '@/containers/legend-settings'; - -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; - - const { legend_config, name } = data.data.attributes; - const { items } = legend_config as LegendType; - - return ( -
-
-

{name}

- -
- -
-
i.color).join(',')})`, - }} - /> - -
    - {items - .filter(({ value }) => typeof value !== 'undefined' && value !== null) - .map(({ value }) => ( -
  • - {value} -
  • - ))} -
-
-
- ); -} diff --git a/client/src/containers/datasets/layers/projects/legend.tsx b/client/src/containers/datasets/layers/projects/legend.tsx deleted file mode 100644 index e36f1e66..00000000 --- a/client/src/containers/datasets/layers/projects/legend.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useGetLayersId } from '@/types/generated/layer'; -import { LayerSettings } from '@/types/layers'; - -import LegendSettings from '@/containers/legend-settings'; - -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; - - const { name } = data.data.attributes; - - return ( -
-
-
-

{name}

-
- -
- ); -} diff --git a/client/src/containers/datasets/layers/soil-carbon-density/legend.tsx b/client/src/containers/datasets/layers/soil-carbon-density/legend.tsx deleted file mode 100644 index c23eb453..00000000 --- a/client/src/containers/datasets/layers/soil-carbon-density/legend.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { cn } from '@/lib/classnames'; - -import { useGetLayersId } from '@/types/generated/layer'; -import { LayerSettings, LegendType } from '@/types/layers'; - -import LegendSettings from '@/containers/legend-settings'; - -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; - - const { legend_config, name } = data.data.attributes; - const { items } = legend_config as LegendType; - - return ( -
-
-

{name}

- -
- -
-
i.color).join(',')})`, - }} - /> - -
    - {items - .filter(({ value }) => typeof value !== 'undefined' && value !== null) - .map(({ value }) => ( -
  • - {value} -
  • - ))} -
-
-
- ); -} diff --git a/client/src/containers/datasets/layers/tree-cover-loss/legend.tsx b/client/src/containers/datasets/layers/tree-cover-loss/legend.tsx deleted file mode 100644 index 5b67a236..00000000 --- a/client/src/containers/datasets/layers/tree-cover-loss/legend.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useGetLayersId } from '@/types/generated/layer'; -import { LayerSettings } from '@/types/layers'; - -import LegendSettings from '@/containers/legend-settings'; - -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; - - const { name } = data.data.attributes; - - return ( -
-
-
-

{name}

-
- -
- ); -} diff --git a/client/src/containers/datasets/layers/tree-cover/legend.tsx b/client/src/containers/datasets/layers/tree-cover/legend.tsx deleted file mode 100644 index 39e9a37c..00000000 --- a/client/src/containers/datasets/layers/tree-cover/legend.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useGetLayersId } from '@/types/generated/layer'; -import { LayerSettings } from '@/types/layers'; - -import LegendSettings from '@/containers/legend-settings'; - -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; - - const { name } = data.data.attributes; - - return ( -
-
-
-

{name}

-
- -
- ); -} diff --git a/client/src/containers/map/legend/index.tsx b/client/src/containers/map/legend/index.tsx index d8a42217..41827298 100644 --- a/client/src/containers/map/legend/index.tsx +++ b/client/src/containers/map/legend/index.tsx @@ -6,11 +6,11 @@ import { cn } from '@/lib/classnames'; import { useSyncLayers } from '@/hooks/datasets/sync-query'; +import MapLegendItem from '@/containers/map/legend/legend-item'; + import Legend from '@/components/map/legend'; import { Button } from '@/components/ui/button'; -import MapLegendItem from './item'; - const MapLegends = ({ className = '' }) => { const [layers] = useSyncLayers(); diff --git a/client/src/containers/map/legend/item.tsx b/client/src/containers/map/legend/item.tsx deleted file mode 100644 index db97d310..00000000 --- a/client/src/containers/map/legend/item.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use-client'; - -import type { LayerSettings } from '@/types/layers'; - -import { LEGENDS } from '@/containers/datasets/layers'; - -const MapLegendItem = ({ settings }: { settings: LayerSettings }) => { - const { id } = settings; - const LegendDetailComponent = LEGENDS[id]; - return ( - LegendDetailComponent && ( -
- -
- ) - ); -}; - -export default MapLegendItem; diff --git a/client/src/containers/map/legend/legend-item/basic.tsx b/client/src/containers/map/legend/legend-item/basic.tsx new file mode 100644 index 00000000..9ff490e1 --- /dev/null +++ b/client/src/containers/map/legend/legend-item/basic.tsx @@ -0,0 +1,51 @@ +'use-client'; + +import type { LayerSettings } from '@/types/layers'; +import type { Legend } from '@/types/map'; + +import LegendSettings from '@/containers/legend-settings'; + +const BasicLegendItem = ({ + name, + settings, + items, + notes, +}: { + name: Legend['name']; + settings: LayerSettings; + items: Legend['items']; + notes?: Legend['notes']; +}) => ( +
+ {items.length === 1 ? ( +
+
+
+
+

{name}

+
+ +
+ {items[0]?.notes &&

{items[0]?.notes}

} +
+ ) : ( +
+
+
+

{name}

+ +
+
+ {items.map((item) => ( +
+
+

{item.value}

+
+ ))} + {notes &&

{notes}

} +
+ )} +
+); + +export default BasicLegendItem; diff --git a/client/src/containers/datasets/layers/land-degradation/legend.tsx b/client/src/containers/map/legend/legend-item/choropleth.tsx similarity index 72% rename from client/src/containers/datasets/layers/land-degradation/legend.tsx rename to client/src/containers/map/legend/legend-item/choropleth.tsx index f7207603..aa0abd30 100644 --- a/client/src/containers/datasets/layers/land-degradation/legend.tsx +++ b/client/src/containers/map/legend/legend-item/choropleth.tsx @@ -1,16 +1,19 @@ -import { useGetLayersId } from '@/types/generated/layer'; -import type { LayerSettings, LegendType } from '@/types/layers'; +'use-client'; -import LegendSettings from '@/containers/legend-settings'; - -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; +import type { LayerSettings } from '@/types/layers'; +import type { Legend } from '@/types/map'; - const { legend_config, name } = data.data.attributes; - const { items } = legend_config as LegendType; +import LegendSettings from '@/containers/legend-settings'; +const ChoroplethLegendItem = ({ + name, + settings, + items, +}: { + name: Legend['name']; + settings: LayerSettings; + items: Legend['items']; +}) => { return (
@@ -47,4 +50,6 @@ export default function Legend({ settings }: { settings: LayerSettings }) {
); -} +}; + +export default ChoroplethLegendItem; diff --git a/client/src/containers/datasets/layers/biomass-density/legend.tsx b/client/src/containers/map/legend/legend-item/gradient.tsx similarity index 73% rename from client/src/containers/datasets/layers/biomass-density/legend.tsx rename to client/src/containers/map/legend/legend-item/gradient.tsx index c23eb453..36720791 100644 --- a/client/src/containers/datasets/layers/biomass-density/legend.tsx +++ b/client/src/containers/map/legend/legend-item/gradient.tsx @@ -1,18 +1,21 @@ +'use-client'; + import { cn } from '@/lib/classnames'; -import { useGetLayersId } from '@/types/generated/layer'; -import { LayerSettings, LegendType } from '@/types/layers'; +import type { LayerSettings } from '@/types/layers'; +import type { Legend } from '@/types/map'; import LegendSettings from '@/containers/legend-settings'; -export default function Legend({ settings }: { settings: LayerSettings }) { - const { data } = useGetLayersId(Number(settings.id)); - - if (!data?.data?.attributes) return null; - - const { legend_config, name } = data.data.attributes; - const { items } = legend_config as LegendType; - +const GradientLegendItem = ({ + name, + items, + settings, +}: { + name: Legend['name']; + items: Legend['items']; + settings: LayerSettings; +}) => { return (
@@ -47,4 +50,6 @@ export default function Legend({ settings }: { settings: LayerSettings }) {
); -} +}; + +export default GradientLegendItem; diff --git a/client/src/containers/map/legend/legend-item/index.tsx b/client/src/containers/map/legend/legend-item/index.tsx new file mode 100644 index 00000000..5de80316 --- /dev/null +++ b/client/src/containers/map/legend/legend-item/index.tsx @@ -0,0 +1,34 @@ +'use-client'; + +import { useGetLayersId } from '@/types/generated/layer'; +import type { LayerSettings } from '@/types/layers'; + +import BasicLegendItem from './basic'; +import ChoroplethLegendItem from './choropleth'; +import GradientLegendItem from './gradient'; + +const MapLegendItem = ({ settings }: { settings: LayerSettings }) => { + const { id } = settings; + + const { data } = useGetLayersId(Number(id)); + + if (!data?.data?.attributes) return null; + + const { legend_config, name } = data.data.attributes; + const { type, items } = legend_config; + + return ( +
+ {type === 'gradient' && } + {type === 'choropleth' && ( + + )} + {type === 'basic' && } +
+ ); +}; + +export default MapLegendItem; diff --git a/client/src/types/map.ts b/client/src/types/map.ts index 4f1d4d93..a2997e17 100644 --- a/client/src/types/map.ts +++ b/client/src/types/map.ts @@ -6,11 +6,12 @@ export type LegendType = (typeof LEGEND_TYPE)[number]; export type Legend = { type: LegendType; - title: string; + name?: string; info?: string; description?: string; - items?: { color: string; value: string }[]; + items: { color: string; value: string; notes?: string }[]; intersections?: { id: number; color: string }[]; + notes?: string; }; export type MapSettings = { From d7ee3f1f05e3d85a9774814994995216e4f4b49d Mon Sep 17 00:00:00 2001 From: mluena Date: Wed, 10 Apr 2024 13:04:12 +0200 Subject: [PATCH 2/3] legend types --- client/src/containers/datasets/item.tsx | 2 +- client/src/containers/datasets/list.tsx | 2 + .../map/legend/legend-item/basic.tsx | 67 +++++++++---------- .../map/legend/legend-item/choropleth.tsx | 10 ++- .../map/legend/legend-item/gradient.tsx | 10 ++- .../map/legend/legend-item/index.tsx | 13 ++-- client/src/types/generated/strapi.schemas.ts | 8 +-- 7 files changed, 57 insertions(+), 55 deletions(-) diff --git a/client/src/containers/datasets/item.tsx b/client/src/containers/datasets/item.tsx index 599bbd5b..c37a678f 100644 --- a/client/src/containers/datasets/item.tsx +++ b/client/src/containers/datasets/item.tsx @@ -15,7 +15,7 @@ import { INFO } from '@/containers/datasets/layers'; import { Button } from '@/components/ui/button'; import { Dialog, DialogClose, DialogContent, DialogTrigger } from '@/components/ui/dialog'; import { Switch } from '@/components/ui/switch'; -// TODO: replace with real type DatasetItemResonseDataItem + export default function DatasetsItem(props: LayerListResponseDataItem) { const [layers, setLayersToURL] = useSyncLayers(); diff --git a/client/src/containers/datasets/list.tsx b/client/src/containers/datasets/list.tsx index 9a88c9a4..7543186d 100644 --- a/client/src/containers/datasets/list.tsx +++ b/client/src/containers/datasets/list.tsx @@ -13,6 +13,8 @@ export default function DatasetsList() { const layers = data?.data || []; + if (!layers.length) return null; + return ( ( -
- {items.length === 1 ? ( -
-
-
-
-

{name}

-
- -
- {items[0]?.notes &&

{items[0]?.notes}

} -
- ) : ( -
-
+}: Layer & { settings: LayerSettings }) => { + const { items, notes } = legend_config as Legend; + + return ( +
+ {items.length === 1 ? ( +
-

{name}

+
+
+

{name}

+
+ {items[0]?.notes &&

{items[0]?.notes}

}
- {items.map((item) => ( -
-
-

{item.value}

+ ) : ( +
+
+
+

{name}

+ +
- ))} - {notes &&

{notes}

} -
- )} -
-); + {items.map((item) => ( +
+
+

{item.value}

+
+ ))} + {notes &&

{notes}

} +
+ )} +
+ ); +}; export default BasicLegendItem; diff --git a/client/src/containers/map/legend/legend-item/choropleth.tsx b/client/src/containers/map/legend/legend-item/choropleth.tsx index aa0abd30..a0d92534 100644 --- a/client/src/containers/map/legend/legend-item/choropleth.tsx +++ b/client/src/containers/map/legend/legend-item/choropleth.tsx @@ -1,5 +1,6 @@ 'use-client'; +import type { Layer } from '@/types/generated/strapi.schemas'; import type { LayerSettings } from '@/types/layers'; import type { Legend } from '@/types/map'; @@ -7,13 +8,10 @@ import LegendSettings from '@/containers/legend-settings'; const ChoroplethLegendItem = ({ name, + legend_config, settings, - items, -}: { - name: Legend['name']; - settings: LayerSettings; - items: Legend['items']; -}) => { +}: Layer & { settings: LayerSettings }) => { + const { items } = legend_config as Legend; return (
diff --git a/client/src/containers/map/legend/legend-item/gradient.tsx b/client/src/containers/map/legend/legend-item/gradient.tsx index 36720791..2fbe0206 100644 --- a/client/src/containers/map/legend/legend-item/gradient.tsx +++ b/client/src/containers/map/legend/legend-item/gradient.tsx @@ -2,6 +2,7 @@ import { cn } from '@/lib/classnames'; +import type { Layer } from '@/types/generated/strapi.schemas'; import type { LayerSettings } from '@/types/layers'; import type { Legend } from '@/types/map'; @@ -9,13 +10,10 @@ import LegendSettings from '@/containers/legend-settings'; const GradientLegendItem = ({ name, - items, + legend_config, settings, -}: { - name: Legend['name']; - items: Legend['items']; - settings: LayerSettings; -}) => { +}: Layer & { settings: LayerSettings }) => { + const { items } = legend_config as Legend; return (
diff --git a/client/src/containers/map/legend/legend-item/index.tsx b/client/src/containers/map/legend/legend-item/index.tsx index 5de80316..fd15a498 100644 --- a/client/src/containers/map/legend/legend-item/index.tsx +++ b/client/src/containers/map/legend/legend-item/index.tsx @@ -2,6 +2,7 @@ import { useGetLayersId } from '@/types/generated/layer'; import type { LayerSettings } from '@/types/layers'; +import type { Legend } from '@/types/map'; import BasicLegendItem from './basic'; import ChoroplethLegendItem from './choropleth'; @@ -15,18 +16,22 @@ const MapLegendItem = ({ settings }: { settings: LayerSettings }) => { if (!data?.data?.attributes) return null; const { legend_config, name } = data.data.attributes; - const { type, items } = legend_config; + const { type } = legend_config as Legend; return (
- {type === 'gradient' && } + {type === 'gradient' && ( + + )} {type === 'choropleth' && ( - + + )} + {type === 'basic' && ( + )} - {type === 'basic' && }
); }; diff --git a/client/src/types/generated/strapi.schemas.ts b/client/src/types/generated/strapi.schemas.ts index abe9b631..b572584b 100644 --- a/client/src/types/generated/strapi.schemas.ts +++ b/client/src/types/generated/strapi.schemas.ts @@ -1484,9 +1484,9 @@ export interface Layer { params_config?: unknown; decode_function?: string; legend_config?: unknown; - description?: string; - info?: string; slug?: string; + description?: string; + dialog?: string; createdAt?: string; updatedAt?: string; publishedAt?: string; @@ -1687,9 +1687,9 @@ export type LayerRequestData = { params_config?: unknown; decode_function?: string; legend_config?: unknown; - description?: string; - info?: unknown; slug?: string; + description?: string; + dialog?: string; }; export interface LayerRequest { From 39c55ca7a363a178075e3561997a32e5541183a9 Mon Sep 17 00:00:00 2001 From: mluena Date: Wed, 10 Apr 2024 13:42:57 +0200 Subject: [PATCH 3/3] shrink in legend btn --- client/src/containers/map/legend/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/containers/map/legend/index.tsx b/client/src/containers/map/legend/index.tsx index 41827298..c9acb05e 100644 --- a/client/src/containers/map/legend/index.tsx +++ b/client/src/containers/map/legend/index.tsx @@ -56,7 +56,7 @@ const MapLegends = ({ className = '' }) => {