From ea60890615583c912b45a7706e98c9349ca4425d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1rbara=20Chaves?= Date: Wed, 3 Apr 2024 16:46:08 +0200 Subject: [PATCH 01/14] Client/feature/adapt story 1 (#53) * Add bubble chart default options * Fix story content size --- client/src/components/chart/index.tsx | 23 ++-- client/src/components/chart/utils.ts | 117 +++++++++++++----- client/src/containers/story/steps/index.tsx | 6 +- .../story/steps/layouts/map-step.tsx | 110 ++++++++-------- 4 files changed, 159 insertions(+), 97 deletions(-) diff --git a/client/src/components/chart/index.tsx b/client/src/components/chart/index.tsx index f83169f..ff44b8f 100644 --- a/client/src/components/chart/index.tsx +++ b/client/src/components/chart/index.tsx @@ -12,11 +12,11 @@ import { Filler, registerables, } from 'chart.js'; -import { ChartJSOrUndefined } from 'react-chartjs-2/dist/types'; +import { ChartJSOrUndefined, ChartProps } from 'react-chartjs-2/dist/types'; import { WidgetWidgetComponent } from '@/types/generated/strapi.schemas'; -import { getChartDefaultData, getChartDefaultOptions } from './utils'; +import { bubbleDefaultOptions, getChartDefaultData, getChartDefaultOptions } from './utils'; type ChartJsProps = { widget: WidgetWidgetComponent; @@ -49,19 +49,24 @@ const ChartJs = ({ widget, ...props }: ChartJsProps) => { () => getChartDefaultData(data, chartRef), [data, chartRef.current] ); - const optionsWithDefaults = useMemo(() => getChartDefaultOptions(options), [options]); const chartType = type as ChartType; + const optionsWithDefaults: Partial = getChartDefaultOptions(options); + + const OPTIONS = { + ...optionsWithDefaults, + datasets: { + ...(chartType === 'bubble' + ? { bubble: { ...bubbleDefaultOptions, ...optionsWithDefaults?.datasets?.bubble } } + : {}), + }, + }; + return (
{!chartTypes.includes(chartType) || !data || !(data as ChartData).datasets ? null : ( - + )}
); diff --git a/client/src/components/chart/utils.ts b/client/src/components/chart/utils.ts index 89613cd..00f6e56 100644 --- a/client/src/components/chart/utils.ts +++ b/client/src/components/chart/utils.ts @@ -1,41 +1,85 @@ import { MutableRefObject } from 'react'; -import { BubbleDataPoint, ChartTypeRegistry, Point } from 'chart.js'; +import { BubbleDataPoint, ChartTypeRegistry, Point, ScriptableContext } from 'chart.js'; import { ChartJSOrUndefined } from 'react-chartjs-2/dist/types'; -export const getChartDefaultOptions = (options: any) => { +export const PluginCallbacks = { + PredictedTravelDemandDhakaTooltopTitle: (context: any) => { + return `${context[0].raw.y} in ${context[0].raw.x}`; + }, + PredictedTravelDemandDhakaTooltopLabel: (context: any) => { + return `${context.raw.value?.toLocaleString()} ${context.raw.scale}`; + }, +}; + +export const bubbleDefaultOptions = { + radius: (context: ScriptableContext<'bubble'>) => { + const maxRadius = 20; + const minRadius = 10; + const max = Math.max(...context.dataset.data.map((d: any) => d.value || 0)); + const min = Math.min(...context.dataset.data.map((d: any) => d.value || 0)); + const value = (context.dataset.data[context.dataIndex] as any).value || 0; + const normalized = minRadius + ((value - min) * (maxRadius - minRadius)) / (max - min); + context.dataset.data[context.dataIndex].r = normalized; + return normalized; + }, +}; + +const extractPluginCallbackFunction = (options: Record) => { + const plugins = options?.plugins || {}; + if (!plugins) return options; + for (const key in plugins) { + const plugin = plugins[key]; + if (plugin?.callbacks) { + for (const callback in plugin.callbacks) { + const pluginCallback = plugin.callbacks[callback]; + if (typeof pluginCallback === 'string' && pluginCallback in PluginCallbacks) { + plugins[key].callbacks[callback] = + PluginCallbacks[pluginCallback as keyof typeof PluginCallbacks]; + } + } + } + } + return { + ...options, + plugins, + }; +}; + +export const getChartDefaultOptions = (a: unknown) => { + const options = !!a && typeof a === 'object' ? extractPluginCallbackFunction(a) : {}; return { borderColor: '#fff', interaction: { intersect: false, - mode: 'index', - ...options.interaction, + mode: 'point', + ...options?.interaction, }, scales: { x: { grid: { display: false, color: '#fff', - ...options.scales?.x?.grid, + ...options?.scales?.x?.grid, }, ticks: { maxTicksLimit: 5, color: '#fff', padding: 10, - ...options.scales?.x?.ticks, + ...options?.scales?.x?.ticks, }, - ...options.scales?.x, + ...options?.scales?.x, }, y: { border: { dash: [4, 4], display: false, - ...options.scales?.y?.border, + ...(options?.scales?.y as any)?.border, }, grid: { color: '#fff', drawTicks: false, - ...options.scales?.y?.grid, + ...options?.scales?.y?.grid, }, ticks: { padding: 0, @@ -47,18 +91,34 @@ export const getChartDefaultOptions = (options: any) => { return label; }, maxTicksLimit: 5, - ...options.scales?.y?.ticks, + ...options?.scales?.y?.ticks, }, - ...options.scales?.y, + ...options?.scales?.y, }, - ...options.scales, + ...options?.scales, }, plugins: { legend: { display: false, - ...options.plugins?.legend, + ...options?.plugins?.legend, + }, + tooltip: { + mode: 'point', + bodyFont: { + size: 14, + weight: 'bold', + }, + bodyColor: '#003247', + titleFont: { + size: 14, + weight: 'bold', + }, + titleColor: '#9AABB5', + displayColors: false, + backgroundColor: '#fff', + ...options?.plugins?.tooltip, }, - ...options.plugins, + ...options?.plugins, }, ...options, }; @@ -74,19 +134,18 @@ export const getChartDefaultData = ( ) => { if (!chartRef.current) return data; - const gradient = chartRef.current.ctx.createLinearGradient(0, 0, 400, 200); - gradient.addColorStop(0, 'rgba(0, 174, 157, 1)'); - gradient.addColorStop(1, 'rgba(0, 174, 157, 0)'); - return { - ...data, - datasets: data.datasets.map((dataset: any) => ({ - ...dataset, - backgroundColor: gradient, - borderColor: 'rgb(0, 174, 157)', - borderWidth: 2, - pointRadius: 0, - pointHoverRadius: 0, - pointHoverBorderWidth: 0, - })), - }; + if (data.datasets?.some((dataset: any) => dataset.backgroundColor === 'GRADIENT')) { + const gradient = chartRef.current.ctx.createLinearGradient(0, 0, 400, 200); + gradient.addColorStop(0, 'rgba(0, 174, 157, 1)'); + gradient.addColorStop(1, 'rgba(0, 174, 157, 0)'); + return { + ...data, + datasets: data.datasets.map((dataset: any) => ({ + ...dataset, + backgroundColor: dataset.backgroundColor === 'GRADIENT' && gradient, + })), + }; + } + + return data; }; diff --git a/client/src/containers/story/steps/index.tsx b/client/src/containers/story/steps/index.tsx index bb48475..7937b57 100644 --- a/client/src/containers/story/steps/index.tsx +++ b/client/src/containers/story/steps/index.tsx @@ -56,8 +56,10 @@ const Step = ({ step, category, index }: StepProps) => { }, [step, type, currentStep, index, category?.data?.id, category?.data?.attributes]); return ( -
-
{STEP_COMPONENT}
+
+ {STEP_COMPONENT}
); }; diff --git a/client/src/containers/story/steps/layouts/map-step.tsx b/client/src/containers/story/steps/layouts/map-step.tsx index 06d8822..574e773 100644 --- a/client/src/containers/story/steps/layouts/map-step.tsx +++ b/client/src/containers/story/steps/layouts/map-step.tsx @@ -36,68 +36,64 @@ const MapStepLayout = ({ step, category, showContent, stepIndex }: MapStepLayout }; return ( -
-
-
- {!!story_summary?.length && ( -
-
- - {category?.name} -
+
+
+ {!!story_summary?.length && ( +
+
+ + {category?.name} +
-
- {story_summary?.map((item) => ( -
-
-

{item.title}

- - - - - {item.info} - -
-

{item.content}

+
+ {story_summary?.map((item) => ( +
+
+

{item.title}

+ + + + + {item.info} +
- ))} -
+

{item.content}

+
+ ))}
- )} -
-
-
- {[card, widget]?.map((item, index) => { - if (!item) return null; - return ( -
+ )} +
+
+
+ {[card, widget]?.map((item, index) => { + if (!item) return null; + return ( +
+
+ {item?.title &&

{item?.title}

} + {index === 0 ? ( +
+ {(item as MapLayerCardComponent)?.content?.split('\n').map((p, i) => ( +

+ {p} +

+ ))} +
+ ) : ( + )} - > -
- {item?.title && ( -

{item?.title}

- )} - {index === 0 ? ( -
- {(item as MapLayerCardComponent)?.content?.split('\n').map((p, i) => ( -

- {p} -

- ))} -
- ) : ( - - )} -
- ); - })} -
+
+ ); + })}
From c64031ad776f9b34d6181ef61a6e1e226c5a1d2c Mon Sep 17 00:00:00 2001 From: barbara-chaves Date: Tue, 19 Mar 2024 12:49:28 +0100 Subject: [PATCH 02/14] add production link to images in next config --- client/next.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/next.config.mjs b/client/next.config.mjs index be9cdb6..d1e32ca 100644 --- a/client/next.config.mjs +++ b/client/next.config.mjs @@ -13,7 +13,7 @@ const nextConfig = { 'esa-gda-comms-staging-cms.fra1.digitaloceanspaces.com', 'fra1.digitaloceanspaces.com', 'esa-gda-comms-staging-mfafc.ondigitalocean.app', - 'impact-sphere-gda.esa.int', + 'https://impact-sphere-gda.esa.int', ], }, env: { From 26cd61c74b6798748484910951738aa2594153c6 Mon Sep 17 00:00:00 2001 From: barbara-chaves Date: Tue, 9 Apr 2024 10:07:45 +0200 Subject: [PATCH 03/14] Fix no map error --- client/src/containers/story/steps/layouts/map-step.tsx | 2 +- client/src/containers/story/utils.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/containers/story/steps/layouts/map-step.tsx b/client/src/containers/story/steps/layouts/map-step.tsx index 574e773..b5616f9 100644 --- a/client/src/containers/story/steps/layouts/map-step.tsx +++ b/client/src/containers/story/steps/layouts/map-step.tsx @@ -65,7 +65,7 @@ const MapStepLayout = ({ step, category, showContent, stepIndex }: MapStepLayout )}
-
+
{[card, widget]?.map((item, index) => { if (!item) return null; return ( diff --git a/client/src/containers/story/utils.ts b/client/src/containers/story/utils.ts index ee9ab1d..a68437a 100644 --- a/client/src/containers/story/utils.ts +++ b/client/src/containers/story/utils.ts @@ -6,5 +6,7 @@ export const isMapStep = (step: StoryStepsItem): step is StepLayoutMapStepCompon }; export const isMapNotEmpty = (map: StoryStepsItem['map']): map is StoryStepMap => { - return Object.values((map as StoryStepMap)?.location).length > 0; + return ( + !!map && typeof map === 'object' && Object.values((map as StoryStepMap)?.location).length > 0 + ); }; From 88a0f5a71ebd06fc047ba484c1999768c1890790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1rbara=20Chaves?= Date: Thu, 11 Apr 2024 17:40:26 +0200 Subject: [PATCH 04/14] Update legend logic (#54) * Update legend logic --- client/package.json | 1 + client/src/components/map/legend/index.tsx | 32 ++-- .../map/legend/item-types/gradient/index.tsx | 2 +- .../map/legend/item-types/switch/index.tsx | 18 +- .../map/legend/item-types/timeline/index.tsx | 159 +++++++++--------- .../src/components/map/legend/item/index.tsx | 105 ++++++------ .../map/legend/item/toolbar/index.tsx | 40 +---- client/src/components/map/legend/types.ts | 7 +- client/src/components/ui/collapsible.tsx | 11 ++ client/src/containers/map/legend/index.tsx | 2 +- client/src/containers/map/legend/item.tsx | 65 ++++--- .../map/markers/story-markers/carousel.tsx | 10 +- .../story/steps/layouts/map-step.tsx | 27 ++- client/src/types/generated/strapi.schemas.ts | 10 +- .../api/layer/content-types/layer/schema.json | 3 +- cms/src/components/map-layer/summary.json | 3 + yarn.lock | 3 +- 17 files changed, 261 insertions(+), 237 deletions(-) create mode 100644 client/src/components/ui/collapsible.tsx diff --git a/client/package.json b/client/package.json index 3e0e359..7786cf9 100644 --- a/client/package.json +++ b/client/package.json @@ -22,6 +22,7 @@ "@hookform/resolvers": "^3.1.1", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.6", diff --git a/client/src/components/map/legend/index.tsx b/client/src/components/map/legend/index.tsx index 75ea66f..5c6d049 100644 --- a/client/src/components/map/legend/index.tsx +++ b/client/src/components/map/legend/index.tsx @@ -1,7 +1,11 @@ import React, { useMemo, Children, isValidElement } from 'react'; +import { ChevronDown } from 'lucide-react'; + import { cn } from '@/lib/classnames'; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; + import SortableList from './sortable/list'; import { LegendProps } from './types'; @@ -18,22 +22,30 @@ export const Legend: React.FC = ({ return (
{isChildren && ( -
-
- {!!sortable.enabled && !!onChangeOrder && ( - +
+ {!!sortable?.enabled && !!onChangeOrder ? ( + + {children} + + ) : Array.isArray(children) && children.length > 1 ? ( + + + Legends + + {children} - - )} - - {children} -
+ + + ) : ( + children + )}
)}
diff --git a/client/src/components/map/legend/item-types/gradient/index.tsx b/client/src/components/map/legend/item-types/gradient/index.tsx index 3aed33a..a812f1b 100644 --- a/client/src/components/map/legend/item-types/gradient/index.tsx +++ b/client/src/components/map/legend/item-types/gradient/index.tsx @@ -12,7 +12,7 @@ export const LegendTypeGradient: React.FC = ({ className = '', })} >
i.color).join(',')})`, }} diff --git a/client/src/components/map/legend/item-types/switch/index.tsx b/client/src/components/map/legend/item-types/switch/index.tsx index e1d2883..0facdee 100644 --- a/client/src/components/map/legend/item-types/switch/index.tsx +++ b/client/src/components/map/legend/item-types/switch/index.tsx @@ -8,7 +8,7 @@ import { Switch } from '@/components/ui/switch'; import { LegendTypeSwitchProps } from '../../types'; -const LegendTypeSwitch = ({ layerId, param, layerTitle }: LegendTypeSwitchProps) => { +const LegendTypeSwitch = ({ layerId, param, layerTitle, ...props }: LegendTypeSwitchProps) => { const layersSettings = useAtomValue(layersSettingsAtom); const checked = useMemo(() => layersSettings[layerId]?.[param], [layerId, layersSettings, param]); @@ -28,7 +28,18 @@ const LegendTypeSwitch = ({ layerId, param, layerTitle }: LegendTypeSwitchProps) ); return ( -
+
+
+ +
handleChangeVisibility(c)} value={layerId} @@ -36,9 +47,6 @@ const LegendTypeSwitch = ({ layerId, param, layerTitle }: LegendTypeSwitchProps) defaultChecked={!!checked} id={`${layerId}-switch`} /> -
); }; diff --git a/client/src/components/map/legend/item-types/timeline/index.tsx b/client/src/components/map/legend/item-types/timeline/index.tsx index 8c53607..cf3b1c5 100644 --- a/client/src/components/map/legend/item-types/timeline/index.tsx +++ b/client/src/components/map/legend/item-types/timeline/index.tsx @@ -33,8 +33,8 @@ export const LegendTypeTimeline: React.FC = ({ interval = 1, format, layerId, - description, animationInterval = 1000, + ...props }) => { const intervalRef = useRef(); @@ -189,84 +189,85 @@ export const LegendTypeTimeline: React.FC = ({ const maxYearX = width - Math.min(firstTextSize / 2, 25) - 5; return ( -
-
- - - onChangeFrame(v)} - className="relative flex w-full -translate-x-3 translate-y-3 touch-none select-none items-center" - > - - - {/* Min value text */} - firstTextSize ? 'opacity-100' : 'opacity-25' - )} - ref={firstValueText} - > - {TIMELINE[0]?.label} - - - {/* Years lines */} - {TIMELINE?.map(({ value }) => { - const position = value % 10 === 0 ? 0 : 4; - return ( - - ); - })} - - {/* Max value text */} - firstTextSize ? 'opacity-100' : 'opacity-25' - )} - x={maxYearX} - y={textMarginY} - ref={currValueText} - > - {TIMELINE?.[TIMELINE.length - 1]?.label} - - {/* Current value text */} - - {TIMELINE?.[value]?.label} - - - - - -
+
+ + + onChangeFrame(v)} + className="relative flex w-full -translate-x-3 translate-y-3 touch-none select-none items-center" + > + + + {/* Min value text */} + firstTextSize ? 'opacity-100' : 'opacity-25' + )} + ref={firstValueText} + > + {TIMELINE[0]?.label} + + + {/* Years lines */} + {TIMELINE?.map(({ value }) => { + const position = value % 10 === 0 ? 0 : 4; + return ( + + ); + })} + + {/* Max value text */} + firstTextSize ? 'opacity-100' : 'opacity-25' + )} + x={maxYearX} + y={textMarginY} + ref={currValueText} + > + {TIMELINE?.[TIMELINE.length - 1]?.label} + + {/* Current value text */} + + {TIMELINE?.[value]?.label} + + + + +
); }; diff --git a/client/src/components/map/legend/item/index.tsx b/client/src/components/map/legend/item/index.tsx index cc1e5fb..b9e3d5b 100644 --- a/client/src/components/map/legend/item/index.tsx +++ b/client/src/components/map/legend/item/index.tsx @@ -2,13 +2,12 @@ import React, { Children, PropsWithChildren, isValidElement, useMemo } from 'react'; -import { GripVertical } from 'lucide-react'; +import { ChevronDown, GripVertical } from 'lucide-react'; import { cn } from '@/lib/classnames'; import { LegendItemProps } from '@/components/map/legend/types'; -import { Accordion, AccordionContent, AccordionItem } from '@/components/ui/accordion'; -import Card from '@/components/ui/card'; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; import LegendItemToolbar from './toolbar'; @@ -31,8 +30,6 @@ export const LegendItem: React.FC = ({ onChangeVisibility, onChangeExpand, }) => { - const { expand } = settings || {}; - const validChildren = useMemo(() => { const chldn = Children.map(children, (Child) => { return isValidElement(Child); @@ -40,63 +37,63 @@ export const LegendItem: React.FC = ({ return chldn && chldn.some((c) => !!c); }, [children]); - const acordionState = expand ? `${id}` : undefined; - return ( - - - -
+ +
+
+
+ {sortable?.handle && ( + + )} +
- {sortable?.handle && ( - - )} - -
- {name} -
+ {name}
+
- {/* TOOLBAR */} - -
+ {/* TOOLBAR */} + + + + +
- {validChildren && ( - -
{children}
-
- )} -
-
-
+ {validChildren && ( + +
{children}
+
+ )} +
+ ); }; diff --git a/client/src/components/map/legend/item/toolbar/index.tsx b/client/src/components/map/legend/item/toolbar/index.tsx index 203163d..532ac6e 100644 --- a/client/src/components/map/legend/item/toolbar/index.tsx +++ b/client/src/components/map/legend/item/toolbar/index.tsx @@ -3,7 +3,7 @@ import { useState } from 'react'; import { PopoverArrow } from '@radix-ui/react-popover'; -import { Eye, Info, EyeOff, Droplet, ChevronDown } from 'lucide-react'; +import { Eye, Info, EyeOff, Droplet } from 'lucide-react'; import { cn } from '@/lib/classnames'; @@ -21,10 +21,9 @@ export const LegendItemToolbar: React.FC = ({ settingsManager, onChangeOpacity, onChangeVisibility, - onChangeExpand, }: LegendItemToolbarProps) => { const [popoverOpen, setPopoverOpen] = useState(false); - const { opacity = 1, visibility = true, expand = true } = settings || {}; + const { opacity = 1, visibility = true } = settings || {}; return (
@@ -138,41 +137,6 @@ export const LegendItemToolbar: React.FC = ({
)}
- - {settingsManager?.expand && ( -
-
- - {/* */} - { - if (onChangeExpand) onChangeExpand(!expand); - }} - > - - - {/* */} - - -
{expand ? 'Collapse layer' : 'Expand layer'}
- - -
-
-
-
- )}
); }; diff --git a/client/src/components/map/legend/types.ts b/client/src/components/map/legend/types.ts index 609cce1..d085319 100644 --- a/client/src/components/map/legend/types.ts +++ b/client/src/components/map/legend/types.ts @@ -1,4 +1,4 @@ -import { PropsWithChildren, ReactNode } from 'react'; +import { CSSProperties, PropsWithChildren, ReactNode } from 'react'; import { DraggableAttributes } from '@dnd-kit/core'; import { SyntheticListeners } from '@dnd-kit/core/dist/hooks/utilities'; @@ -55,7 +55,7 @@ export interface LegendItemProps extends LegendItemEvents { InfoContent?: ReactNode; // sortable - sortable: Sortable; + sortable?: Sortable; listeners?: SyntheticListeners; attributes?: DraggableAttributes; @@ -114,6 +114,7 @@ export interface LegendTypeTimelineProps { dateType?: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'; format?: string; animationInterval?: number; + style?: CSSProperties; } export interface LegendMatrixIntersectionsProps { @@ -127,6 +128,8 @@ export interface LegendTypeSwitchProps { layerId: number; param: string; layerTitle: string; + style?: CSSProperties; + color?: string; } type ItemLegends = Extract; diff --git a/client/src/components/ui/collapsible.tsx b/client/src/components/ui/collapsible.tsx new file mode 100644 index 0000000..86ab87d --- /dev/null +++ b/client/src/components/ui/collapsible.tsx @@ -0,0 +1,11 @@ +'use client'; + +import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'; + +const Collapsible = CollapsiblePrimitive.Root; + +const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger; + +const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent; + +export { Collapsible, CollapsibleTrigger, CollapsibleContent }; diff --git a/client/src/containers/map/legend/index.tsx b/client/src/containers/map/legend/index.tsx index 5f47991..4822a96 100644 --- a/client/src/containers/map/legend/index.tsx +++ b/client/src/containers/map/legend/index.tsx @@ -97,7 +97,7 @@ const MapLegends = ({ className = '' }) => {
{ +const MapLegendItem = ({ id, ...legendProps }: MapLegendItemProps) => { const { data, isError, isFetched, isFetching, isPlaceholderData } = useGetLayersId(id, { populate: 'metadata', }); @@ -97,41 +97,50 @@ const MapLegendItem = ({ id, ...props }: MapLegendItemProps) => { if (typeof type !== 'string' || !LEGEND_TYPE.includes(type as LegendType)) return; // TODO: Fix this type const LEGEND = LEGEND_TYPES[type as LegendType] as React.FC; - - legends.push(
{createElement(LEGEND, props)}
); - }); - - return legends; - }, [legend_config, id, attributes?.title, params_config, layersSettings]); - - return LEGEND_COMPONENTS?.map((LEGEND_COMPONENT, i) => { - const useLegendItem = legend_config?.[i]?.displayControllers !== false; - return ( - - {useLegendItem ? ( + const LegendElement = createElement(LEGEND, props); + if (!isValidElement(LegendElement)) return; + if (props.displayControllers) { + legends.push( } > - {LEGEND_COMPONENT} + {LegendElement} - ) : ( - LEGEND_COMPONENT - )} - - ); - }); + ); + return; + } + legends.push(LegendElement); + }); + + return legends; + }, [ + legend_config, + id, + attributes, + params_config, + layersSettings, + settingsManager, + legendProps, + metadata, + ]); + + return ( + + {LEGEND_COMPONENTS} + + ); }; export default MapLegendItem; diff --git a/client/src/containers/map/markers/story-markers/carousel.tsx b/client/src/containers/map/markers/story-markers/carousel.tsx index 3632cd4..db1d8db 100644 --- a/client/src/containers/map/markers/story-markers/carousel.tsx +++ b/client/src/containers/map/markers/story-markers/carousel.tsx @@ -38,7 +38,10 @@ const CarouselMedia = ({ media, isCurrentMedia }: CarouselMediaProps) => { loop controls={isCurrentMedia} autoPlay={isCurrentMedia} - className="h-full max-h-[calc(100vh-152px)] w-full object-cover" + className={cn( + 'h-full max-h-[calc(100vh-152px)] w-full', + isCurrentMedia ? 'object-contain' : 'object-cover' + )} > @@ -47,7 +50,10 @@ const CarouselMedia = ({ media, isCurrentMedia }: CarouselMediaProps) => { return ( {media.title}

{item.title}

- - - - - {item.info} - + {item.info && ( + + + + + {item.info} + + )}
-

{item.content}

+ {item.link ? ( + + {item.content} + + ) : ( +

{item.content}

+ )}
))}
diff --git a/client/src/types/generated/strapi.schemas.ts b/client/src/types/generated/strapi.schemas.ts index acbd32b..24d3412 100644 --- a/client/src/types/generated/strapi.schemas.ts +++ b/client/src/types/generated/strapi.schemas.ts @@ -565,6 +565,7 @@ export interface MapLayerSummaryComponent { content?: string; id?: number; info?: string; + link?: string; title?: string; } @@ -1117,6 +1118,7 @@ export type StoryCategoryDataAttributesStoriesDataItemAttributesStepsItemAnyOfSt content?: string; id?: number; info?: string; + link?: string; title?: string; }; @@ -1180,7 +1182,6 @@ export const StoryCategoryDataAttributesStoriesDataItemAttributesStepsItemAnyOfL deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type StoryCategoryDataAttributesStoriesDataItemAttributesStepsItemAnyOfLayersDataItemAttributesMetadata = @@ -1670,7 +1671,6 @@ export const LayerType = { deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type LayerDataset = { @@ -1745,7 +1745,6 @@ export const LayerDatasetDataAttributesLayersDataItemAttributesType = { deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type LayerDatasetDataAttributesLayersDataItemAttributesMetadata = { @@ -2078,7 +2077,6 @@ export const LayerRequestDataType = { deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type LayerRequestDataDataset = number | string; @@ -2185,7 +2183,6 @@ export const DatasetGroupDatasetsDataItemAttributesLayersDataItemAttributesType deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type DatasetGroupDatasetsDataItemAttributesLayersDataItemAttributesMetadata = { @@ -2702,7 +2699,6 @@ export const DatasetDatasetGroupDataAttributesDatasetsDataItemAttributesLayersDa deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type DatasetDatasetGroupDataAttributesDatasetsDataItemAttributesLayersDataItemAttributesMetadata = @@ -3483,6 +3479,7 @@ export type CategoryStoriesDataItemAttributesStepsItemAnyOfStorySummaryItem = { content?: string; id?: number; info?: string; + link?: string; title?: string; }; @@ -3517,7 +3514,6 @@ export const CategoryStoriesDataItemAttributesStepsItemAnyOfLayersDataItemAttrib deckgl: 'deckgl', mapbox: 'mapbox', carto: 'carto', - 'animated-tiles': 'animated-tiles', } as const; export type CategoryStoriesDataItemAttributesStepsItemAnyOfLayersDataItemAttributesMetadata = { diff --git a/cms/src/api/layer/content-types/layer/schema.json b/cms/src/api/layer/content-types/layer/schema.json index f95e68e..6d97208 100644 --- a/cms/src/api/layer/content-types/layer/schema.json +++ b/cms/src/api/layer/content-types/layer/schema.json @@ -20,8 +20,7 @@ "type": "enumeration", "enum": [ "deckgl", - "mapbox", - "carto" + "mapbox" ], "required": true, "default": "mapbox" diff --git a/cms/src/components/map-layer/summary.json b/cms/src/components/map-layer/summary.json index 6c224af..629477a 100644 --- a/cms/src/components/map-layer/summary.json +++ b/cms/src/components/map-layer/summary.json @@ -16,6 +16,9 @@ }, "info": { "type": "string" + }, + "link": { + "type": "string" } } } diff --git a/yarn.lock b/yarn.lock index c247245..277ef35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2823,6 +2823,7 @@ __metadata: "@playwright/test": ^1.35.1 "@radix-ui/react-accordion": ^1.1.2 "@radix-ui/react-checkbox": ^1.0.4 + "@radix-ui/react-collapsible": ^1.0.3 "@radix-ui/react-dialog": ^1.0.4 "@radix-ui/react-label": ^2.0.2 "@radix-ui/react-popover": ^1.0.6 @@ -4579,7 +4580,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-collapsible@npm:1.0.3": +"@radix-ui/react-collapsible@npm:1.0.3, @radix-ui/react-collapsible@npm:^1.0.3": version: 1.0.3 resolution: "@radix-ui/react-collapsible@npm:1.0.3" dependencies: From b9373aa76e5006d69b6a3bc51c337904317df2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1rbara=20Chaves?= Date: Mon, 15 Apr 2024 17:23:32 +0200 Subject: [PATCH 05/14] Fix outro step disclaimer (#55) * Fix disclaimer --- .../story/steps/layouts/outro-step.tsx | 44 +- client/src/lib/image-src/index.ts | 2 +- client/src/types/generated/strapi.schemas.ts | 1309 +++++++++-------- cms/src/components/disclaimer/discalimer.json | 27 - .../disclaimer/outro-step-disclaimer.json | 25 + cms/src/components/disclaimer/partners.json | 25 + .../components/step-layout/outro-step.json | 6 +- .../story-outro-disclaimer/disclaimer.json | 19 + .../story-disclaimer.json | 21 + 9 files changed, 762 insertions(+), 716 deletions(-) delete mode 100644 cms/src/components/disclaimer/discalimer.json create mode 100644 cms/src/components/disclaimer/outro-step-disclaimer.json create mode 100644 cms/src/components/disclaimer/partners.json create mode 100644 cms/src/components/story-outro-disclaimer/disclaimer.json create mode 100644 cms/src/components/story-outro-disclaimer/story-disclaimer.json diff --git a/client/src/containers/story/steps/layouts/outro-step.tsx b/client/src/containers/story/steps/layouts/outro-step.tsx index 3e8aaa1..b21d967 100644 --- a/client/src/containers/story/steps/layouts/outro-step.tsx +++ b/client/src/containers/story/steps/layouts/outro-step.tsx @@ -20,19 +20,6 @@ type MediaStepLayoutProps = { showContent: boolean; }; -const links = [ - [ - 'https://www.gaf.de/', - '', - 'https://site.tre-altamira.com/', - 'http://www.gisat.cz/', - 'https://www.ait.ac.at/en/', - 'https://www.caribou.space/', - ], - ['https://www.adb.org/'], - ['https://www.esa.int/'], -]; - const OutroStepLayout = ({ step, showContent }: MediaStepLayoutProps) => { const { push } = useRouter(); @@ -81,14 +68,6 @@ const OutroStepLayout = ({ step, showContent }: MediaStepLayoutProps) => { const isVideo = mediaType?.includes('video'); - // const handlePlayVideo = useCallback( - // (e: React.MouseEvent, action: 'play' | 'pause') => { - // if (action === 'play') e.currentTarget.play(); - // else e.currentTarget.pause(); - // }, - // [] - // ); - const scale = useTransform(scrollYProgress, [0.5, 0.7], ['1', '2']); const scaleContent = useTransform(scrollYProgress, [0.5, 0.7], ['1', '0.75']); @@ -155,25 +134,20 @@ const OutroStepLayout = ({ step, showContent }: MediaStepLayoutProps) => { >

Continue scrolling to explore more stories

- {showContent && show && step.disclaimer && ( + {showContent && show && step.story_disclaimer?.length && (