diff --git a/CHANGELOG.md b/CHANGELOG.md index 9109daa25..8574f7292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Not released +- fix LegendWidget update logic for multiple legends case [#889](https://github.com/CartoDB/carto-react/pull/889) - onStateChange callback for all widgets [#886](https://github.com/CartoDB/carto-react/pull/886) ## 3.0.0 diff --git a/packages/react-redux/src/slices/cartoSlice.js b/packages/react-redux/src/slices/cartoSlice.js index 74fe4d323..ceaea8f9c 100644 --- a/packages/react-redux/src/slices/cartoSlice.js +++ b/packages/react-redux/src/slices/cartoSlice.js @@ -81,14 +81,15 @@ export const createCartoSlice = (initialState) => { const layer = state.layers[action.payload.id]; if (layer) { const newLayer = { ...layer, ...action.payload.layerAttributes }; + const hasLegendUpdate = layer.legend && newLayer.legend; + // Merge legend object if it's not an array (for the case of multiple legend objects per layer) + if (hasLegendUpdate && !Array.isArray(newLayer.legend)) { + newLayer.legend = { ...layer.legend, ...newLayer.legend }; + } // TODO: Study if we should use a deepmerge fn state.layers[action.payload.id] = { - ...newLayer, - ...(layer.legend && - newLayer.legend && { - legend: { ...layer.legend, ...newLayer.legend } - }) + ...newLayer }; } }, diff --git a/packages/react-widgets/src/widgets/LegendWidget.js b/packages/react-widgets/src/widgets/LegendWidget.js index b13faef27..085fd9832 100644 --- a/packages/react-widgets/src/widgets/LegendWidget.js +++ b/packages/react-widgets/src/widgets/LegendWidget.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { updateLayer } from '@carto/react-redux/'; import { LegendWidgetUI } from '@carto/react-ui'; import { useDispatch, useSelector } from 'react-redux'; @@ -17,12 +17,13 @@ import { useMediaQuery } from '@mui/material'; */ function LegendWidget({ customLegendTypes, initialCollapsed, layerOrder = [], title }) { const dispatch = useDispatch(); - const layers = useSelector((state) => + const reduxLayers = useSelector((state) => state.carto.layers); + const layers = useMemo(() => { sortLayers( - Object.values(state.carto.layers).filter((layer) => !!layer.legend), + Object.values(reduxLayers).filter((layer) => !!layer.legend), layerOrder - ).filter((l) => !!l.legend) - ); + ).filter((l) => !!l.legend); + }, [reduxLayers, layerOrder]); const [collapsed, setCollapsed] = useState(initialCollapsed); const isMobile = useMediaQuery((theme) => theme.breakpoints.down('sm'));