From 665ca6eb59ff80d4da7344d47324263c1fff4a7e Mon Sep 17 00:00:00 2001 From: stefano bovio Date: Thu, 16 Dec 2021 13:49:57 +0100 Subject: [PATCH] add edit button to list of styles (#672) --- .../client/js/epics/visualstyleeditor.js | 8 +- .../client/js/plugins/LayerSettings.jsx | 27 +++++- .../client/js/plugins/VisualStyleEditor.jsx | 23 ++++- .../layersettings/GeoNodeStyleSelector.jsx | 94 +++++++++++++++++++ .../layersettings/WMSLayerSettings.jsx | 30 +----- .../client/js/utils/ResourceUtils.js | 6 +- .../js/utils/__tests__/ResourceUtils-test.js | 2 +- 7 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 geonode_mapstore_client/client/js/plugins/layersettings/GeoNodeStyleSelector.jsx diff --git a/geonode_mapstore_client/client/js/epics/visualstyleeditor.js b/geonode_mapstore_client/client/js/epics/visualstyleeditor.js index aee7bb08fa..52658af080 100644 --- a/geonode_mapstore_client/client/js/epics/visualstyleeditor.js +++ b/geonode_mapstore_client/client/js/epics/visualstyleeditor.js @@ -76,7 +76,7 @@ function getGnStyleQueryParams(style, styleService) { }).then(updatedStyles => { const { metadata = {}, code: updateStyleCode, format, languageVersion } = updatedStyles || {}; const metadataObj = parseMetadata(metadata); - return { msEditorType, msStyleJSON, ...metadataObj, code: updateStyleCode, format, languageVersion }; + return { msEditorType: metadataObj?.msEditorType, msStyleJSON: metadataObj?.msStyleJSON, code: updateStyleCode, format, languageVersion }; }).catch(() => ({ msEditorType, msStyleJSON, code})); } @@ -93,8 +93,8 @@ function getGeoNodeStyles({ layer, styleService }) { const metadata = { title: layerName, description: '', - msStyleJSON: msStyleJSON || null, - msEditorType: msEditorType || 'visual', + msStyleJSON: msStyleJSON, + msEditorType: msEditorType, gnDatasetPk: layer?.extendedParams?.mapLayer?.dataset?.pk }; return StylesAPI.createStyle({ @@ -121,7 +121,7 @@ export const gnRequestDatasetAvailableStyles = (action$, store) => const styleService = action?.options?.styleService || styleServiceSelector(state); return Observable.defer(() => getGeoNodeStyles({ layer: action.layer, styleService })) .switchMap(([styles, update]) => { - const style = styles?.[0]?.name; + const style = action?.options?.style || styles?.[0]?.name; return Observable.concat( Observable.of(setControlProperty('visualStyleEditor', 'enabled', true)), Observable.defer(() => StylesAPI.getStylesInfo({ diff --git a/geonode_mapstore_client/client/js/plugins/LayerSettings.jsx b/geonode_mapstore_client/client/js/plugins/LayerSettings.jsx index 691ef672d6..12c64bfc26 100644 --- a/geonode_mapstore_client/client/js/plugins/LayerSettings.jsx +++ b/geonode_mapstore_client/client/js/plugins/LayerSettings.jsx @@ -22,6 +22,8 @@ import { getTitle } from '@mapstore/framework/utils/TOCUtils'; import GroupSettings from '@js/plugins/layersettings/GroupSettings'; import BaseLayerSettings from '@js/plugins/layersettings/BaseLayerSettings'; import WMSLayerSettings from '@js/plugins/layersettings/WMSLayerSettings'; +import GeoNodeStyleSelector from '@js/plugins/layersettings/GeoNodeStyleSelector'; +import usePluginItems from '@js/hooks/usePluginItems'; const settingsForms = { group: GroupSettings, @@ -29,6 +31,11 @@ const settingsForms = { wms: WMSLayerSettings }; +const ConnectedGeoNodeStyleSelector = connect( + createSelector([], () => ({})), + {} +)(GeoNodeStyleSelector); + /** * @module plugins/LayerSettings */ @@ -47,8 +54,13 @@ function LayerSettings({ style, selectedNodes, onClose, + items = [], ...props -}) { +}, context) { + + + const { loadedPlugins } = context; + const configuredItems = usePluginItems({ items, loadedPlugins }); if (isEmpty(node)) { return null; @@ -61,6 +73,11 @@ function LayerSettings({ : settingsForms[node?.type] || settingsForms.baseLayer; const title = node?.title && getTitle(node.title, props.currentLocale) || node.name; + + function handleChange(properties) { + onChange(node.id, isGroup ? 'groups' : 'layers', properties); + } + return (
onChange(node.id, isGroup ? 'groups' : 'layers', properties)} + onChange={handleChange} + styleSelectorComponent={ target === 'style-button')} + />} />
diff --git a/geonode_mapstore_client/client/js/plugins/VisualStyleEditor.jsx b/geonode_mapstore_client/client/js/plugins/VisualStyleEditor.jsx index 1ef7bfe116..6a982810d0 100644 --- a/geonode_mapstore_client/client/js/plugins/VisualStyleEditor.jsx +++ b/geonode_mapstore_client/client/js/plugins/VisualStyleEditor.jsx @@ -383,22 +383,33 @@ function StyleEditorTocButton({ status, onClick = () => {}, enabled, - isNew + isNew, + btnProps = {}, + hide, + selectedStyle }) { - if (!(status === 'LAYER' && layer?.extendedParams?.mapLayer && (enabled || isNew))) { + if (!(!hide && status === 'LAYER' && layer?.extendedParams?.mapLayer && (enabled || isNew))) { return null; } - function handleClick() { - onClick(layer); + function handleClick(event) { + event.stopPropagation(); + event.preventDefault(); + onClick(layer, { style: selectedStyle }); + } + function handleMouseDown(event) { + event.stopPropagation(); + event.preventDefault(); } return ( @@ -427,6 +438,10 @@ export default createPlugin('VisualStyleEditor', { TOC: { target: 'toolbar', Component: ConnectedStyleEditorTocButton + }, + LayerSettings: { + target: 'style-button', + Component: ConnectedStyleEditorTocButton } }, reducers: { diff --git a/geonode_mapstore_client/client/js/plugins/layersettings/GeoNodeStyleSelector.jsx b/geonode_mapstore_client/client/js/plugins/layersettings/GeoNodeStyleSelector.jsx new file mode 100644 index 0000000000..7748821075 --- /dev/null +++ b/geonode_mapstore_client/client/js/plugins/layersettings/GeoNodeStyleSelector.jsx @@ -0,0 +1,94 @@ +/* + * Copyright 2021, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import { FormGroup, ControlLabel } from 'react-bootstrap'; +import Message from '@mapstore/framework/components/I18N/Message'; +import Select from 'react-select'; + +import { cleanStyles } from '@js/utils/ResourceUtils'; + +function getStyleOptions(layer) { + const mapLayerStyles = (layer?.extendedParams?.mapLayer?.extra_params?.styles || []) + .map((style) => ({ ...style, canEdit: true })); + const datasetStyles = layer?.extendedParams?.mapLayer?.dataset?.styles || []; + const defaultStyle = layer?.extendedParams?.mapLayer?.dataset?.default_style; + const availableStyles = layer?.availableStyles || []; + return cleanStyles([ + ...(defaultStyle ? [defaultStyle] : []), + ...datasetStyles, + ...mapLayerStyles, + ...availableStyles + ]).map(({ name, title, canEdit }) => ({ + value: name, + label: title, + canEdit + })); +} + +function OptionLabel({ + canEdit, + label, + style, + value, + buttons = [] +}) { + return ( +
+
{label}
+ {buttons.map(({ Component, name }) => + + )} +
+ ); +} + +function GeoNodeStyleSelector({ + node, + onChange, + buttons +}) { + + const options = getStyleOptions(node); + const currentStyle = options.find(({ value }) => value === node.style) || { }; + + if (!node?.extendedParams?.mapLayer) { + return null; + } + + return ( + + + + onChange({ style: value })}/> - } + {styleSelectorComponent} ({ + .map(({ name, sld_title: sldTitle, title, workspace, metadata, format, canEdit }) => ({ name: parseStyleName({ workspace, name }), title: sldTitle || title || name, metadata, - format + format, + canEdit })), 'name') .filter(({ name }) => !excluded.includes(name)); } @@ -401,6 +402,7 @@ export function getGeoNodeMapLayers(data) { extra_params: { msId: layer.id, styles: cleanStyles(layer?.availableStyles) + .map(({ canEdit, metadata, ...style }) => ({ ...style })) }, current_style: layer.style || '', name: layer.name diff --git a/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js b/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js index 7f93c7123f..ee040a28cf 100644 --- a/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js +++ b/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js @@ -113,7 +113,7 @@ describe('Test Resource Utils', () => { pk: 10, extra_params: { msId: '03', - styles: [{ name: 'custom:style', title: 'My Style', format: 'css', metadata: {} }] + styles: [{ name: 'custom:style', title: 'My Style', format: 'css' }] }, current_style: 'geonode:style', name: 'geonode:layer'