From 50c18da8306f30c612053dfc9bc933ae3ccd99e9 Mon Sep 17 00:00:00 2001 From: mbarto Date: Wed, 29 May 2019 09:18:17 +0200 Subject: [PATCH] #2215: add group in TOC toolbar (#3797) * #2215: add group in TOC toolbar * #2215: fixed some tooltips, fixed removing groups on layer removed, fixed problem with dot in group name --- web/client/actions/__tests__/controls-test.js | 35 ++++++ web/client/actions/__tests__/layers-test.js | 29 ++++- web/client/actions/controls.js | 26 +++- web/client/actions/layers.js | 16 ++- web/client/components/TOC/DefaultGroup.jsx | 1 + .../components/TOC/TOCItemsSettings.jsx | 4 +- web/client/components/TOC/Toolbar.jsx | 53 ++++++-- .../components/TOC/__tests__/Toolbar-test.jsx | 60 +++++++++- .../TOC/fragments/settings/General.jsx | 11 +- web/client/components/catalog/Catalog.jsx | 7 +- web/client/components/catalog/RecordGrid.jsx | 10 +- web/client/components/catalog/RecordItem.jsx | 16 +-- .../catalog/__tests__/RecordItem-test.jsx | 62 ++++++++++ web/client/epics/__tests__/maplayout-test.js | 25 +++- web/client/epics/maplayout.js | 4 +- web/client/localConfig.json | 6 +- web/client/plugins/AddGroup.jsx | 101 ++++++++++++++++ web/client/plugins/MetadataExplorer.jsx | 25 ++-- web/client/plugins/TOC.jsx | 19 ++- .../plugins/__tests__/AddGroup-test.jsx | 113 ++++++++++++++++++ .../plugins/__tests__/pluginsTestUtils.js | 2 +- web/client/product/plugins.js | 1 + .../reducers/__tests__/controls-test.js | 16 ++- web/client/reducers/__tests__/layers-test.js | 54 ++++++++- web/client/reducers/controls.js | 7 +- web/client/reducers/layers.js | 36 +++++- .../selectors/__tests__/catalog-test.js | 10 +- web/client/selectors/catalog.js | 1 + web/client/themes/default/icons.less | 4 + web/client/themes/default/icons/icons.eot | Bin 78256 -> 78464 bytes web/client/themes/default/icons/icons.svg | 30 ++--- web/client/themes/default/icons/icons.ttf | Bin 78092 -> 78300 bytes web/client/themes/default/icons/icons.woff | Bin 45880 -> 45988 bytes web/client/themes/default/less/toc.less | 4 + web/client/translations/data.de-DE | 8 ++ web/client/translations/data.en-US | 8 ++ web/client/translations/data.es-ES | 8 ++ web/client/translations/data.fr-FR | 8 ++ web/client/translations/data.it-IT | 8 ++ web/client/utils/CatalogUtils.js | 10 +- 40 files changed, 757 insertions(+), 81 deletions(-) create mode 100644 web/client/plugins/AddGroup.jsx create mode 100644 web/client/plugins/__tests__/AddGroup-test.jsx diff --git a/web/client/actions/__tests__/controls-test.js b/web/client/actions/__tests__/controls-test.js index eedb9e3cc1..810fdf5e3d 100644 --- a/web/client/actions/__tests__/controls-test.js +++ b/web/client/actions/__tests__/controls-test.js @@ -10,6 +10,7 @@ var expect = require('expect'); var { TOGGLE_CONTROL, toggleControl, SET_CONTROL_PROPERTY, setControlProperty, + SET_CONTROL_PROPERTIES, setControlProperties, RESET_CONTROLS, resetControls, on } = require('../controls'); @@ -69,4 +70,38 @@ describe('Test correctness of the controls actions', () => { expect(retval.property).toBe(testProperty); expect(retval.value).toBe(testValue); }); + + it('setControlProperties', () => { + const testControl = 'test'; + const testProperty1 = 'prop1'; + const testValue1 = 'val1'; + const testProperty2 = 'prop2'; + const testValue2 = 'val2'; + var retval = setControlProperties(testControl, testProperty1, testValue1, testProperty2, testValue2); + + expect(retval).toExist(); + expect(retval.type).toBe(SET_CONTROL_PROPERTIES); + expect(retval.control).toBe(testControl); + expect(retval.properties).toExist(); + expect(retval.properties[testProperty1]).toBe(testValue1); + expect(retval.properties[testProperty2]).toBe(testValue2); + }); + + it('setControlProperties wrong params ignored', () => { + const testControl = 'test'; + const testProperty1 = 'prop1'; + const testValue1 = 'val1'; + const testProperty2 = 'prop2'; + const testValue2 = 'val2'; + const testProperty3 = 'prop3'; + var retval = setControlProperties(testControl, testProperty1, testValue1, testProperty2, testValue2, testProperty3); + + expect(retval).toExist(); + expect(retval.type).toBe(SET_CONTROL_PROPERTIES); + expect(retval.control).toBe(testControl); + expect(retval.properties).toExist(); + expect(retval.properties[testProperty1]).toBe(testValue1); + expect(retval.properties[testProperty2]).toBe(testValue2); + expect(retval.properties[testProperty3]).toNotExist(); + }); }); diff --git a/web/client/actions/__tests__/layers-test.js b/web/client/actions/__tests__/layers-test.js index 48bf237be4..ed23ec5152 100644 --- a/web/client/actions/__tests__/layers-test.js +++ b/web/client/actions/__tests__/layers-test.js @@ -32,6 +32,7 @@ var { SHOW_LAYER_METADATA, HIDE_LAYER_METADATA, UPDATE_SETTINGS_PARAMS, + ADD_GROUP, changeLayerProperties, toggleNode, sortNode, @@ -55,7 +56,8 @@ var { filterLayers, showLayerMetadata, hideLayerMetadata, - updateSettingsParams + updateSettingsParams, + addGroup } = require('../layers'); var {getLayerCapabilities} = require('../layerCapabilities'); @@ -140,6 +142,17 @@ describe('Test correctness of the layers actions', () => { expect(retval.type).toBe(REMOVE_NODE); expect(retval.node).toBe('sampleNode'); expect(retval.nodeType).toBe('sampleType'); + expect(retval.removeEmpty).toBe(false); + }); + + it('removeNode with removeEmpty', () => { + var retval = removeNode('sampleNode', 'sampleType', true); + + expect(retval).toExist(); + expect(retval.type).toBe(REMOVE_NODE); + expect(retval.node).toBe('sampleNode'); + expect(retval.nodeType).toBe('sampleType'); + expect(retval.removeEmpty).toBe(true); }); it('updateNode', () => { @@ -304,4 +317,18 @@ describe('Test correctness of the layers actions', () => { expect(action.newParams).toBe(newParams); expect(action.update).toBe(update); }); + + it('add root group', () => { + const action = addGroup('newgroup'); + expect(action.type).toBe(ADD_GROUP); + expect(action.group).toBe('newgroup'); + expect(action.parent).toNotExist(); + }); + + it('add nested group', () => { + const action = addGroup('newgroup', 'group1.group2'); + expect(action.type).toBe(ADD_GROUP); + expect(action.group).toBe('newgroup'); + expect(action.parent).toBe('group1.group2'); + }); }); diff --git a/web/client/actions/controls.js b/web/client/actions/controls.js index 75482b5d75..4d8bbbc877 100644 --- a/web/client/actions/controls.js +++ b/web/client/actions/controls.js @@ -7,8 +7,11 @@ */ const TOGGLE_CONTROL = 'TOGGLE_CONTROL'; const SET_CONTROL_PROPERTY = 'SET_CONTROL_PROPERTY'; +const SET_CONTROL_PROPERTIES = 'SET_CONTROL_PROPERTIES'; const RESET_CONTROLS = 'RESET_CONTROLS'; +const { fromPairs, chunk } = require('lodash'); + /** * Toggle a control property * @memberof actions.controls @@ -52,6 +55,24 @@ function setControlProperty(control, property, value, toggle) { }; } +/** + * Sets a list of properties at once + * @memberof actions.controls + * @param {string} control control name + * @param {array} properties the properties to set, pairs of keys and related values + * @return {object} of type `SET_CONTROL_PROPERTIES` with control and properties + * + * @example + * setControlProperties('metadataexplorer', 'enabled', true, 'group', 'newgroup') + */ +function setControlProperties(control, ...properties) { + return { + type: SET_CONTROL_PROPERTIES, + control, + properties: fromPairs(chunk(properties, 2)) + }; +} + /** * Reset all the controls * @memberof actions.controls @@ -69,5 +90,6 @@ function resetControls(skip = []) { * control property. * @name actions.controls */ -module.exports = {TOGGLE_CONTROL, SET_CONTROL_PROPERTY, RESET_CONTROLS, - toggleControl, on, setControlProperty, resetControls}; +module.exports = { + TOGGLE_CONTROL, SET_CONTROL_PROPERTY, SET_CONTROL_PROPERTIES, RESET_CONTROLS, + toggleControl, on, setControlProperty, setControlProperties, resetControls}; diff --git a/web/client/actions/layers.js b/web/client/actions/layers.js index 949ef50124..c5a37e1666 100644 --- a/web/client/actions/layers.js +++ b/web/client/actions/layers.js @@ -18,6 +18,7 @@ const LAYER_LOADING = 'LAYER_LOADING'; const LAYER_LOAD = 'LAYER_LOAD'; const LAYER_ERROR = 'LAYER_ERROR'; const ADD_LAYER = 'ADD_LAYER'; +const ADD_GROUP = 'ADD_GROUP'; const REMOVE_LAYER = 'REMOVE_LAYER'; const SHOW_SETTINGS = 'SHOW_SETTINGS'; const HIDE_SETTINGS = 'HIDE_SETTINGS'; @@ -114,12 +115,12 @@ function sortNode(node, order, sortLayers = null) { }; } -function removeNode(node, type, properties) { +function removeNode(node, type, removeEmpty = false) { return { type: REMOVE_NODE, node: node, nodeType: type, - properties + removeEmpty }; } @@ -164,6 +165,14 @@ function addLayer(layer, foreground = true) { }; } +function addGroup(group, parent) { + return { + type: ADD_GROUP, + group, + parent + }; +} + function removeLayer(layerId) { return { type: REMOVE_LAYER, @@ -270,9 +279,10 @@ module.exports = { changeLayerProperties, changeLayerParams, changeGroupProperties, toggleNode, sortNode, removeNode, contextNode, updateNode, layerLoading, layerLoad, layerError, addLayer, removeLayer, showSettings, hideSettings, updateSettings, refreshLayers, layersRefreshed, layersRefreshError, refreshLayerVersion, updateLayerDimension, browseData, clearLayers, selectNode, filterLayers, showLayerMetadata, - hideLayerMetadata, download, updateSettingsParams, + hideLayerMetadata, download, updateSettingsParams, addGroup, CHANGE_LAYER_PROPERTIES, CHANGE_LAYER_PARAMS, CHANGE_GROUP_PROPERTIES, TOGGLE_NODE, SORT_NODE, REMOVE_NODE, UPDATE_NODE, LAYER_LOADING, LAYER_LOAD, LAYER_ERROR, ADD_LAYER, REMOVE_LAYER, + ADD_GROUP, SHOW_SETTINGS, HIDE_SETTINGS, UPDATE_SETTINGS, CONTEXT_NODE, REFRESH_LAYERS, LAYERS_REFRESHED, LAYERS_REFRESH_ERROR, UPDATE_LAYERS_DIMENSION, BROWSE_DATA, DOWNLOAD, CLEAR_LAYERS, SELECT_NODE, FILTER_LAYERS, SHOW_LAYER_METADATA, HIDE_LAYER_METADATA, UPDATE_SETTINGS_PARAMS }; diff --git a/web/client/components/TOC/DefaultGroup.jsx b/web/client/components/TOC/DefaultGroup.jsx index 019a5bf3f1..5ba50dcfe4 100644 --- a/web/client/components/TOC/DefaultGroup.jsx +++ b/web/client/components/TOC/DefaultGroup.jsx @@ -56,6 +56,7 @@ class DefaultGroup extends React.Component { () : diff --git a/web/client/components/TOC/TOCItemsSettings.jsx b/web/client/components/TOC/TOCItemsSettings.jsx index 1743f1f29a..d67076b4c5 100644 --- a/web/client/components/TOC/TOCItemsSettings.jsx +++ b/web/client/components/TOC/TOCItemsSettings.jsx @@ -52,7 +52,8 @@ const TOCItemSettings = (props, context) => { dock = true, showFullscreen, draggable, - position = 'left' + position = 'left', + tabsConfig = {} } = props; const tabs = getTabs(props, context); @@ -122,6 +123,7 @@ const TOCItemSettings = (props, context) => { {tabs.filter(tab => tab.id && tab.id === activeTab).filter(tab => tab.Component).map(tab => ( {}, onReload: () => {}, onAddLayer: () => {}, + onAddGroup: () => { }, onDownload: () => {}, onGetMetadataRecord: () => {}, onHideLayerMetadata: () => {}, onShow: () => {} }, + maxDepth: 3, text: { settingsText: '', opacityText: '', @@ -67,6 +70,10 @@ class Toolbar extends React.Component { confirmDeleteMessage: '', confirmDeleteCancelText: '', createWidgetTooltip: '', + addLayerTooltip: '', + addLayerToGroupTooltip: '', + addGroupTooltip: '', + addSubGroupTooltip: '', zoomToTooltip: { LAYER: '', LAYERS: '' @@ -96,6 +103,7 @@ class Toolbar extends React.Component { activateDownloadTool: true, activateSettingsTool: true, activateAddLayer: true, + activateAddGroup: true, includeDeleteButtonInSettings: false, activateMetedataTool: true }, @@ -145,7 +153,23 @@ class Toolbar extends React.Component { status = this.props.selectedLayers.length > 0 && this.props.selectedLayers.filter(l => l.loadingError === 'Error').length === this.props.selectedLayers.length ? `${status}_LOAD_ERROR` : status; return status; } - + getSelectedGroup = () => { + return this.props.selectedGroups.length > 0 && this.props.selectedGroups[this.props.selectedGroups.length - 1]; + }; + getSelectedNodeDepth = () => { + if (this.getStatus() === 'DESELECT') { + return 0; + } + return this.getSelectedGroup().id.split('.').length + 1; + }; + addLayer = () => { + const group = this.getSelectedGroup(); + this.props.onToolsActions.onAddLayer(group && group.id); + }; + addGroup = () => { + const group = this.getSelectedGroup(); + this.props.onToolsActions.onAddGroup(group && group.id); + }; render() { const status = this.getStatus(); const currentEPSG = this.checkBbox(); @@ -163,11 +187,26 @@ class Toolbar extends React.Component { transitionName="toc-toolbar-btn-transition" transitionEnterTimeout={300} transitionLeaveTimeout={300}> - {this.props.activateTool.activateAddLayer && status === 'DESELECT' ? - + {this.props.activateTool.activateAddLayer && (status === 'DESELECT' || status === 'GROUP') ? + {status === 'GROUP' ? this.props.text.addLayerToGroupTooltip : this.props.text.addLayerTooltip}}> + + : null} + {this.props.activateTool.activateAddGroup && (status === 'DESELECT' || status === 'GROUP') && this.getSelectedNodeDepth() <= this.props.maxDepth ? + {status === 'GROUP' ? this.props.text.addSubGroupTooltip : this.props.text.addGroupTooltip}}> + + + : null} {this.props.activateTool.activateZoomTool && (status === 'LAYER' || status === 'GROUP' || status === 'LAYERS' || status === 'GROUPS') && currentEPSG ? {this.props.text.settingsTooltip[status ? 'LAYER_LOAD_ERROR' && 'LAYER' : status]}}> + overlay={{this.props.text.settingsTooltip[status === 'LAYER_LOAD_ERROR' ? 'LAYER' : status]}}> @@ -328,7 +367,7 @@ class Toolbar extends React.Component { removeNodes = () => { this.props.selectedLayers.forEach((layer) => { - this.props.onToolsActions.onRemove(layer.id, 'layers', layer); + this.props.onToolsActions.onRemove(layer.id, 'layers'); }); this.props.onToolsActions.onClear(); this.closeDeleteDialog(); diff --git a/web/client/components/TOC/__tests__/Toolbar-test.jsx b/web/client/components/TOC/__tests__/Toolbar-test.jsx index d22d4ab00c..f8ffeabb4b 100644 --- a/web/client/components/TOC/__tests__/Toolbar-test.jsx +++ b/web/client/components/TOC/__tests__/Toolbar-test.jsx @@ -26,6 +26,7 @@ const onToolsActions = { onHideSettings: () => {}, onReload: () => {}, onAddLayer: () => {}, + onAddGroup: () => {}, onGetMetadataRecord: () => {}, onHideLayerMetadata: () => {}, onShow: () => {} @@ -45,14 +46,18 @@ describe('TOC Toolbar', () => { it('deselected element', () => { const spyAddLayer = expect.spyOn(onToolsActions, 'onAddLayer'); - ReactDOM.render(, document.getElementById("container")); + const spyAddGroup = expect.spyOn(onToolsActions, 'onAddGroup'); + ReactDOM.render(, document.getElementById("container")); const el = document.getElementsByClassName("btn-group").item(0); expect(el).toExist(); const btn = el.getElementsByClassName("btn"); - expect(btn.length).toBe(1); - expect(btn[0].innerHTML).toBe('ADD LAYER'); + expect(btn.length).toBe(2); + expect(btn[0].innerHTML).toContain('add-layer'); + expect(btn[1].innerHTML).toContain('add-folder'); TestUtils.Simulate.click(btn[0]); expect(spyAddLayer).toHaveBeenCalled(); + TestUtils.Simulate.click(btn[1]); + expect(spyAddGroup).toHaveBeenCalled(); }); it('layer single selection', () => { @@ -289,6 +294,8 @@ describe('TOC Toolbar', () => { }); it('group single selection', () => { + const spyAddLayer = expect.spyOn(onToolsActions, 'onAddLayer'); + const spyAddGroup = expect.spyOn(onToolsActions, 'onAddGroup'); const spyZoom = expect.spyOn(onToolsActions, 'onZoom'); const spySettings = expect.spyOn(onToolsActions, 'onSettings'); @@ -339,8 +346,12 @@ describe('TOC Toolbar', () => { const el = ReactDOM.findDOMNode(cmp); expect(el).toExist(); const btn = el.getElementsByClassName("btn"); - expect(btn.length).toBe(3); + expect(btn.length).toBe(5); TestUtils.Simulate.click(btn[0]); + expect(spyAddLayer).toHaveBeenCalled(); + TestUtils.Simulate.click(btn[1]); + expect(spyAddGroup).toHaveBeenCalled(); + TestUtils.Simulate.click(btn[2]); expect(spyZoom).toHaveBeenCalledWith({ maxx: 30, maxy: 29, @@ -348,14 +359,51 @@ describe('TOC Toolbar', () => { miny: -9 }, 'EPSG:4326'); - TestUtils.Simulate.click(btn[1]); + TestUtils.Simulate.click(btn[3]); expect(spySettings).toHaveBeenCalledWith('g001', 'groups', {}); - TestUtils.Simulate.click(btn[2]); + TestUtils.Simulate.click(btn[4]); const removeModal = document.getElementsByClassName('modal-dialog').item(0); expect(removeModal).toExist(); }); + it('add group max depth ok', () => { + const selectedGroups = [{ + id: 'g001', + title: 'group001', + name: 'group001name', + nodes: [] + }]; + + const cmp = ReactDOM.render(, document.getElementById("container")); + + const modal = document.getElementsByClassName('modal-dialog').item(0); + expect(modal).toNotExist(); + + const el = ReactDOM.findDOMNode(cmp); + expect(el).toExist(); + const btn = el.getElementsByClassName("btn"); + expect(btn.length).toBe(3); + }); + + it('add group max depth reached', () => { + const selectedGroups = [{ + id: 'g001.g002', + title: 'group001', + name: 'group001name', + nodes: [] + }]; + const cmp = ReactDOM.render(, document.getElementById("container")); + + const modal = document.getElementsByClassName('modal-dialog').item(0); + expect(modal).toNotExist(); + + const el = ReactDOM.findDOMNode(cmp); + expect(el).toExist(); + const btn = el.getElementsByClassName("btn"); + expect(btn.length).toBe(2); + }); + it('group multiple selections', () => { const selectedLayers = [{ id: 'l001', diff --git a/web/client/components/TOC/fragments/settings/General.jsx b/web/client/components/TOC/fragments/settings/General.jsx index 8a3f0a6518..3ac41c0dbf 100644 --- a/web/client/components/TOC/fragments/settings/General.jsx +++ b/web/client/components/TOC/fragments/settings/General.jsx @@ -30,7 +30,8 @@ class General extends React.Component { groups: PropTypes.array, nodeType: PropTypes.string, pluginCfg: PropTypes.object, - showTooltipOptions: PropTypes.bool + showTooltipOptions: PropTypes.bool, + allowNew: PropTypes.bool }; static contextTypes = { messages: PropTypes.object @@ -41,7 +42,8 @@ class General extends React.Component { onChange: () => {}, nodeType: 'layers', showTooltipOptions: true, - pluginCfg: {} + pluginCfg: {}, + allowNew: false }; @@ -135,8 +137,9 @@ class General extends React.Component { this.updateEntry("group", {target: {value: value || "Default"}}); }} theme = "bootstrap3" - createFromSearch={createFromSearch} - + createFromSearch={this.props.allowNew ? createFromSearch : undefined} + hideResetButton={!this.props.allowNew} + editable={this.props.allowNew} onValueChange={function(item) { // here, we add the selected item to the options array, the "new-option" // property, added to items created by the "create-from-search" function above, diff --git a/web/client/components/catalog/Catalog.jsx b/web/client/components/catalog/Catalog.jsx index 3f2f5ac95d..18dae7f4ed 100644 --- a/web/client/components/catalog/Catalog.jsx +++ b/web/client/components/catalog/Catalog.jsx @@ -63,7 +63,8 @@ class Catalog extends React.Component { zoomToLayer: PropTypes.bool, hideThumbnail: PropTypes.bool, hideIdentifier: PropTypes.bool, - hideExpand: PropTypes.bool + hideExpand: PropTypes.bool, + layerBaseConfig: PropTypes.object }; static contextTypes = { @@ -107,7 +108,8 @@ class Catalog extends React.Component { saving: false, services: {}, wrapOptions: false, - zoomToLayer: true + zoomToLayer: true, + layerBaseConfig: {} }; state = { @@ -223,6 +225,7 @@ class Catalog extends React.Component { hideThumbnail={this.props.hideThumbnail} hideIdentifier={this.props.hideIdentifier} hideExpand={this.props.hideExpand} + layerBaseConfig={this.props.layerBaseConfig} /> ); }; diff --git a/web/client/components/catalog/RecordGrid.jsx b/web/client/components/catalog/RecordGrid.jsx index 98ec9c8ae0..4741299c7c 100644 --- a/web/client/components/catalog/RecordGrid.jsx +++ b/web/client/components/catalog/RecordGrid.jsx @@ -31,7 +31,8 @@ class RecordGrid extends React.Component { currentLocale: PropTypes.string, hideThumbnail: PropTypes.bool, hideIdentifier: PropTypes.bool, - hideExpand: PropTypes.bool + hideExpand: PropTypes.bool, + layerBaseConfig: PropTypes.object }; static defaultProps = { @@ -40,7 +41,8 @@ class RecordGrid extends React.Component { onLayerAdd: () => {}, onError: () => {}, records: [], - zoomToLayer: true + zoomToLayer: true, + layerBaseConfig: {} }; renderRecordItem = (record) => { @@ -62,7 +64,9 @@ class RecordGrid extends React.Component { style={{height: "215px", maxHeight: "215px"}} showGetCapLinks={this.props.showGetCapLinks} addAuthentication={this.props.addAuthentication} - currentLocale={this.props.currentLocale}/> + currentLocale={this.props.currentLocale} + layerBaseConfig={this.props.layerBaseConfig} + /> ); }; diff --git a/web/client/components/catalog/RecordItem.jsx b/web/client/components/catalog/RecordItem.jsx index 27de8fe62a..d154e53511 100644 --- a/web/client/components/catalog/RecordItem.jsx +++ b/web/client/components/catalog/RecordItem.jsx @@ -38,7 +38,8 @@ class RecordItem extends React.Component { catalogType: PropTypes.string, hideThumbnail: PropTypes.bool, hideIdentifier: PropTypes.bool, - hideExpand: PropTypes.bool + hideExpand: PropTypes.bool, + layerBaseConfig: PropTypes.object }; static defaultProps = { @@ -54,7 +55,8 @@ class RecordItem extends React.Component { zoomToLayer: true, hideThumbnail: false, hideIdentifier: false, - hideExpand: true + hideExpand: true, + layerBaseConfig: {} }; state = {}; @@ -98,7 +100,7 @@ class RecordItem extends React.Component { className="record-button" bsStyle="primary" bsSize={this.props.buttonSize} - onClick={() => { this.addLayer(wms); }} + onClick={() => { this.addWmsLayer(wms); }} key="addlayer">   @@ -202,7 +204,7 @@ class RecordItem extends React.Component { this.setState({[key]: status}); }; - addLayer = (wms) => { + addWmsLayer = (wms) => { const allowedSRS = buildSRSMap(wms.SRS); if (wms.SRS.length > 0 && !CoordinatesUtils.isAllowedSRS(this.props.crs, allowedSRS)) { this.props.onError('catalog.srs_not_allowed'); @@ -211,7 +213,7 @@ class RecordItem extends React.Component { recordToLayer(this.props.record, "wms", { removeParams: this.props.authkeyParamNames, catalogURL: this.props.catalogType === 'csw' && this.props.catalogURL ? this.props.catalogURL + "?request=GetRecordById&service=CSW&version=2.0.2&elementSetName=full&id=" + this.props.record.identifier : null - })); + }, this.props.layerBaseConfig)); if (this.props.record.boundingBox && this.props.zoomToLayer) { let extent = this.props.record.boundingBox.extent; let crs = this.props.record.boundingBox.crs; @@ -227,7 +229,7 @@ class RecordItem extends React.Component { } else { this.props.onLayerAdd(recordToLayer(this.props.record, "wmts", { removeParams: this.props.authkeyParamNames - })); + }, this.props.layerBaseConfig)); if (this.props.record.boundingBox && this.props.zoomToLayer) { let extent = this.props.record.boundingBox.extent; let crs = this.props.record.boundingBox.crs; @@ -236,7 +238,7 @@ class RecordItem extends React.Component { } }; addEsriLayer = () => { - this.props.onLayerAdd(esriToLayer(this.props.record)); + this.props.onLayerAdd(esriToLayer(this.props.record, this.props.layerBaseConfig)); if (this.props.record.boundingBox && this.props.zoomToLayer) { let extent = this.props.record.boundingBox.extent; let crs = this.props.record.boundingBox.crs; diff --git a/web/client/components/catalog/__tests__/RecordItem-test.jsx b/web/client/components/catalog/__tests__/RecordItem-test.jsx index c7fa8be7f8..e381985b0e 100644 --- a/web/client/components/catalog/__tests__/RecordItem-test.jsx +++ b/web/client/components/catalog/__tests__/RecordItem-test.jsx @@ -402,6 +402,68 @@ describe('This test for RecordItem', () => { expect(actionsSpy.calls[0].arguments[0].params["ms2-authkey"]).toNotExist("auth param is passed in params list but it shouldn't"); }); + it('check event handlers with layerBaseConfig and csw service', () => { + let actions = { + onLayerAdd: () => { + + } + }; + let actionsSpy = expect.spyOn(actions, "onLayerAdd"); + const item = ReactDOM.render(, document.getElementById("container")); + expect(item).toExist(); + + const itemDom = ReactDOM.findDOMNode(item); + expect(itemDom).toExist(); + expect(itemDom.className).toBe('record-item panel panel-default'); + let button = TestUtils.findRenderedDOMComponentWithTag( + item, 'button' + ); + expect(button).toExist(); + button.click(); + expect(actionsSpy.calls.length).toBe(1); + expect(actionsSpy.calls[0].arguments.length).toBe(1); + expect(actionsSpy.calls[0].arguments[0].extraProp).toBe('val1'); + }); + + it('check event handlers with layerBaseConfig and wms service', () => { + let actions = { + onLayerAdd: () => { + + } + }; + let actionsSpy = expect.spyOn(actions, "onLayerAdd"); + const item = ReactDOM.render(, document.getElementById("container")); + expect(item).toExist(); + + const itemDom = ReactDOM.findDOMNode(item); + expect(itemDom).toExist(); + expect(itemDom.className).toBe('record-item panel panel-default'); + let button = TestUtils.findRenderedDOMComponentWithTag( + item, 'button' + ); + expect(button).toExist(); + button.click(); + expect(actionsSpy.calls.length).toBe(1); + expect(actionsSpy.calls[0].arguments.length).toBe(1); + expect(actionsSpy.calls[0].arguments[0].extraProp).toBe('val1'); + }); + it('test create record item with no get capabilities links', () => { // instanciating a record item component const component = ReactDOM.render(, diff --git a/web/client/epics/__tests__/maplayout-test.js b/web/client/epics/__tests__/maplayout-test.js index a6de204845..2eaffeefb4 100644 --- a/web/client/epics/__tests__/maplayout-test.js +++ b/web/client/epics/__tests__/maplayout-test.js @@ -8,7 +8,7 @@ const expect = require('expect'); -const { toggleControl, setControlProperty } = require('../../actions/controls'); +const { toggleControl, setControlProperty, setControlProperties } = require('../../actions/controls'); const {UPDATE_MAP_LAYOUT} = require('../../actions/maplayout'); const {closeIdentify, purgeMapInfoResults} = require('../../actions/mapInfo'); @@ -111,4 +111,27 @@ describe('map layout epics', () => { const state = { controls: { drawer: { enabled: true, resizedWidth: 512} } }; testEpic(updateMapLayoutEpic, 1, setControlProperty("drawer", "resizedWidth", 512), epicResult, state); }); + + it('tests layout updated on setControlProperties', (done) => { + const epicResult = actions => { + try { + expect(actions.length).toBe(1); + actions.map((action) => { + expect(action.type).toBe(UPDATE_MAP_LAYOUT); + expect(action.layout).toEqual({ + left: 0, right: 658, bottom: 30, transform: 'none', height: 'calc(100% - 30px)', boundingMapRect: { + left: 0, + right: 658, + bottom: 30 + } + }); + }); + } catch (e) { + done(e); + } + done(); + }; + const state = { controls: { metadataexplorer: { enabled: true, group: "parent" } } }; + testEpic(updateMapLayoutEpic, 1, setControlProperties("metadataexplorer", "enabled", true, "group", "parent"), epicResult, state); + }); }); diff --git a/web/client/epics/maplayout.js b/web/client/epics/maplayout.js index 855f2ff5e0..4a94f2b07b 100644 --- a/web/client/epics/maplayout.js +++ b/web/client/epics/maplayout.js @@ -7,7 +7,7 @@ */ const Rx = require('rxjs'); const {updateMapLayout} = require('../actions/maplayout'); -const {TOGGLE_CONTROL, SET_CONTROL_PROPERTY} = require('../actions/controls'); +const {TOGGLE_CONTROL, SET_CONTROL_PROPERTY, SET_CONTROL_PROPERTIES} = require('../actions/controls'); const {MAP_CONFIG_LOADED} = require('../actions/config'); const {SIZE_CHANGE, CLOSE_FEATURE_GRID, OPEN_FEATURE_GRID} = require('../actions/featuregrid'); const {CLOSE_IDENTIFY, ERROR_FEATURE_INFO, TOGGLE_MAPINFO_STATE, LOAD_FEATURE_INFO, EXCEPTIONS_FEATURE_INFO} = require('../actions/mapInfo'); @@ -32,7 +32,7 @@ const {isFeatureGridOpen, getDockSize} = require('../selectors/featuregrid'); */ const updateMapLayoutEpic = (action$, store) => - action$.ofType(MAP_CONFIG_LOADED, SIZE_CHANGE, CLOSE_FEATURE_GRID, OPEN_FEATURE_GRID, CLOSE_IDENTIFY, TOGGLE_MAPINFO_STATE, LOAD_FEATURE_INFO, EXCEPTIONS_FEATURE_INFO, TOGGLE_CONTROL, SET_CONTROL_PROPERTY, SHOW_SETTINGS, HIDE_SETTINGS, ERROR_FEATURE_INFO) + action$.ofType(MAP_CONFIG_LOADED, SIZE_CHANGE, CLOSE_FEATURE_GRID, OPEN_FEATURE_GRID, CLOSE_IDENTIFY, TOGGLE_MAPINFO_STATE, LOAD_FEATURE_INFO, EXCEPTIONS_FEATURE_INFO, TOGGLE_CONTROL, SET_CONTROL_PROPERTY, SET_CONTROL_PROPERTIES, SHOW_SETTINGS, HIDE_SETTINGS, ERROR_FEATURE_INFO) .switchMap(() => { const state = store.getState(); diff --git a/web/client/localConfig.json b/web/client/localConfig.json index 92022662cc..eb10a76c4b 100644 --- a/web/client/localConfig.json +++ b/web/client/localConfig.json @@ -151,7 +151,7 @@ "activateMapTitle": false, "activateSortLayer": false } - }, { + }, "AddGroup", { "name": "TOCItemsSettings", "cfg": { "width": 300 @@ -272,9 +272,11 @@ "cfg": { "activateQueryTool": true, "activateAddLayerButton": true, + "activateAddGroupButton": true, "activateMetedataTool": false } }, + "AddGroup", "TOCItemsSettings", "Tutorial", "MapFooter", { "name": "Measure" @@ -443,7 +445,7 @@ "activateRemoveLayer": false } - }, "MapFooter", { + }, "AddGroup", "MapFooter", { "name": "Settings", "cfg": { "wrap": true diff --git a/web/client/plugins/AddGroup.jsx b/web/client/plugins/AddGroup.jsx new file mode 100644 index 0000000000..c42828fe62 --- /dev/null +++ b/web/client/plugins/AddGroup.jsx @@ -0,0 +1,101 @@ +/** +* Copyright 2019, 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, {Component} from 'react'; +import PropTypes from 'prop-types'; +import {connect} from 'react-redux'; +import get from 'lodash/get'; +import Portal from '../components/misc/Portal'; +import ResizableModal from '../components/misc/ResizableModal'; +import Message from '../components/I18N/Message'; +import {FormControl, FormGroup} from 'react-bootstrap'; +import {setControlProperties} from '../actions/controls'; +import {addGroup} from '../actions/layers'; +import { createPlugin } from '../utils/PluginsUtils'; + +class AddGroup extends Component { + static propTypes = { + enabled: PropTypes.bool, + parent: PropTypes.string, + onClose: PropTypes.func, + onAdd: PropTypes.func + }; + + static defaultProps = { + enabled: false, + parent: null, + onClose: () => {}, + onAdd: () => {} + }; + + state = { + groupName: "" + }; + + componentWillReceiveProps(newProps) { + if (newProps.enabled && !this.props.enabled) { + this.setState({ + groupName: "" + }); + } + } + + render() { + return ( + } + show={this.props.enabled} + buttons={[{ + text: , + onClick: () => { + this.props.onClose(); + } + }, { + bsStyle: "primary", + disabled: !this.isValid(this.state.groupName), + text: , + onClick: () => { + this.props.onAdd(this.state.groupName, this.props.parent); + this.props.onClose(); + } + }]}> +
+ + + + +
+
+
); + } + + changeName = (el) => { + this.setState({ + groupName: el.target.value + }); + }; + + isValid = (name) => { + return name !== ''; + }; +} + +const AddGroupPlugin = connect((state) => ({ + enabled: get(state, "controls.addgroup.enabled", false), + parent: get(state, "controls.addgroup.parent", null) +}), { + onClose: setControlProperties.bind(null, "addgroup", "enabled", false, "parent", null), + onAdd: addGroup +})(AddGroup); + +export default createPlugin('AddGroup', { + component: AddGroupPlugin +}); diff --git a/web/client/plugins/MetadataExplorer.jsx b/web/client/plugins/MetadataExplorer.jsx index 7b1ade5a07..8080f43004 100644 --- a/web/client/plugins/MetadataExplorer.jsx +++ b/web/client/plugins/MetadataExplorer.jsx @@ -19,12 +19,12 @@ const {addService, deleteService, textSearch, changeCatalogFormat, changeCatalog addLayer, addLayerError, resetCatalog, focusServicesList, changeText} = require("../actions/catalog"); const {zoomToExtent} = require("../actions/map"); const {currentLocaleSelector} = require("../selectors/locale"); -const {setControlProperty} = require("../actions/controls"); +const {setControlProperty, setControlProperties} = require("../actions/controls"); const {resultSelector, serviceListOpenSelector, newServiceSelector, newServiceTypeSelector, selectedServiceTypeSelector, searchOptionsSelector, servicesSelector, formatsSelector, loadingErrorSelector, selectedServiceSelector, modeSelector, layerErrorSelector, activeSelector, savingSelector, authkeyParamNameSelector, - searchTextSelector + searchTextSelector, groupSelector } = require("../selectors/catalog"); const {mapLayoutValuesSelector} = require('../selectors/maplayout'); @@ -56,7 +56,7 @@ const catalogSelector = createSelector([ const catalogClose = () => { return (dispatch) => { - dispatch(setControlProperty('metadataexplorer', "enabled", false)); + dispatch(setControlProperties('metadataexplorer', "enabled", false, "group", null)); dispatch(changeCatalogMode("view")); dispatch(resetCatalog()); }; @@ -92,7 +92,8 @@ class MetadataExplorerComponent extends React.Component { // side panel properties width: PropTypes.number, - dockStyle: PropTypes.object + dockStyle: PropTypes.object, + group: PropTypes.string }; static defaultProps = { @@ -119,11 +120,15 @@ class MetadataExplorerComponent extends React.Component { position: "right", zIndex: 1030 }, - dockStyle: {} + dockStyle: {}, + group: null }; render() { - const panel = ; + const layerBaseConfig = { + group: this.props.group || undefined + }; + const panel = ; return (
@@ -157,8 +162,9 @@ const metadataExplorerSelector = createSelector([ layerErrorSelector, activeSelector, state => mapLayoutValuesSelector(state, {height: true}), - searchTextSelector -], (searchOptions, formats, result, loadingError, selectedService, mode, services, layerError, active, dockStyle, searchText) => ({ + searchTextSelector, + groupSelector +], (searchOptions, formats, result, loadingError, selectedService, mode, services, layerError, active, dockStyle, searchText, group) => ({ searchOptions, formats, result, @@ -168,7 +174,8 @@ const metadataExplorerSelector = createSelector([ layerError, active, dockStyle, - searchText + searchText, + group })); const MetadataExplorerPlugin = connect(metadataExplorerSelector, { diff --git a/web/client/plugins/TOC.jsx b/web/client/plugins/TOC.jsx index 0caa42b973..c4a6cf77b6 100644 --- a/web/client/plugins/TOC.jsx +++ b/web/client/plugins/TOC.jsx @@ -34,7 +34,7 @@ const layersIcon = require('./toolbar/assets/img/layers.png'); const {isObject, head} = require('lodash'); -const {setControlProperty} = require('../actions/controls'); +const { setControlProperties} = require('../actions/controls'); const {createWidget} = require('../actions/widgets'); const {getMetadataRecordById} = require("../actions/catalog"); @@ -175,6 +175,7 @@ class LayerTree extends React.Component { activateSettingsTool: PropTypes.bool, activateMetedataTool: PropTypes.bool, activateWidgetTool: PropTypes.bool, + maxDepth: PropTypes.number, visibilityCheckType: PropTypes.string, settingsOptions: PropTypes.object, chartStyle: PropTypes.object, @@ -194,9 +195,11 @@ class LayerTree extends React.Component { filteredGroups: PropTypes.array, noFilterResults: PropTypes.bool, onAddLayer: PropTypes.func, + onAddGroup: PropTypes.func, onGetMetadataRecord: PropTypes.func, hideLayerMetadata: PropTypes.func, activateAddLayerButton: PropTypes.bool, + activateAddGroupButton: PropTypes.bool, catalogActive: PropTypes.bool, refreshLayerVersion: PropTypes.func, hideOpacityTooltip: PropTypes.bool @@ -237,6 +240,7 @@ class LayerTree extends React.Component { activateQueryTool: false, activateDownloadTool: false, activateWidgetTool: false, + maxDepth: 3, visibilityCheckType: "glyph", settingsOptions: { includeCloseButton: false, @@ -266,9 +270,11 @@ class LayerTree extends React.Component { filteredGroups: [], noFilterResults: false, onAddLayer: () => {}, + onAddGroup: () => {}, onGetMetadataRecord: () => {}, hideLayerMetadata: () => {}, activateAddLayerButton: false, + activateAddGroupButton: false, catalogActive: false, refreshLayerVersion: () => {}, metadataTemplate: null @@ -344,6 +350,7 @@ class LayerTree extends React.Component { layerMetadata={this.props.layerMetadata} wfsdownload={this.props.wfsdownload} metadataTemplate={this.props.metadataTemplate} + maxDepth={this.props.maxDepth} activateTool={{ activateToolsContainer: this.props.activateToolsContainer, activateRemoveLayer: this.props.activateRemoveLayer, @@ -352,6 +359,7 @@ class LayerTree extends React.Component { activateDownloadTool: this.props.activateDownloadTool, activateSettingsTool: this.props.activateSettingsTool, activateAddLayer: this.props.activateAddLayerButton && !this.props.catalogActive, + activateAddGroup: this.props.activateAddGroupButton, includeDeleteButtonInSettings: false, activateMetedataTool: this.props.activateMetedataTool, activateWidgetTool: this.props.activateWidgetTool @@ -373,6 +381,10 @@ class LayerTree extends React.Component { confirmDeleteMessage: , confirmDeleteCancelText: , addLayer: , + addLayerTooltip: , + addLayerToGroupTooltip: , + addGroupTooltip: , + addSubGroupTooltip: , createWidgetTooltip: , zoomToTooltip: { LAYER: , @@ -409,6 +421,7 @@ class LayerTree extends React.Component { onHideSettings: this.props.hideSettings, onReload: this.props.refreshLayerVersion, onAddLayer: this.props.onAddLayer, + onAddGroup: this.props.onAddGroup, onGetMetadataRecord: this.props.onGetMetadataRecord, onHideLayerMetadata: this.props.hideLayerMetadata, onShow: this.props.layerPropertiesChangeHandler}}/> @@ -454,6 +467,7 @@ class LayerTree extends React.Component { * @prop {boolean} cfg.activateDownloadTool: activate a button to download layer data through wfs, default `false` * @prop {boolean} cfg.activateSortLayer: activate drag and drop to sort layers, default `true` * @prop {boolean} cfg.activateAddLayerButton: activate a button to open the catalog, default `false` + * @prop {boolean} cfg.activateAddGroupButton: activate a button to add a new group, default `false` * @prop {boolean} cfg.showFullTitleOnExpand shows full length title in the legend. default `false`. * @prop {boolean} cfg.hideOpacityTooltip hide toolip on opacity sliders * @prop {string[]|string|object|function} cfg.metadataTemplate custom template for displaying metadata @@ -566,7 +580,8 @@ const TOCPlugin = connect(tocSelector, { removeNode, onSelectNode: selectNode, onFilter: filterLayers, - onAddLayer: setControlProperty.bind(null, "metadataexplorer", "enabled", true, true), + onAddLayer: setControlProperties.bind(null, "metadataexplorer", "enabled", true, "group"), + onAddGroup: setControlProperties.bind(null, "addgroup", "enabled", true, "parent"), onGetMetadataRecord: getMetadataRecordById, hideLayerMetadata, onNewWidget: () => createWidget(), diff --git a/web/client/plugins/__tests__/AddGroup-test.jsx b/web/client/plugins/__tests__/AddGroup-test.jsx new file mode 100644 index 0000000000..7f9ece3127 --- /dev/null +++ b/web/client/plugins/__tests__/AddGroup-test.jsx @@ -0,0 +1,113 @@ +/** + * Copyright 2019, 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 expect from 'expect'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +import AddGroupPlugin from '../AddGroup'; +import { getPluginForTest } from './pluginsTestUtils'; +import ReactTestUtils from 'react-dom/test-utils'; + +describe('AddGroup Plugin', () => { + beforeEach((done) => { + document.body.innerHTML = '
'; + setTimeout(done); + }); + + afterEach((done) => { + ReactDOM.unmountComponentAtNode(document.getElementById("container")); + document.body.innerHTML = ''; + setTimeout(done); + }); + + it('Shows AddGroup plugin', () => { + const { Plugin } = getPluginForTest(AddGroupPlugin, { + controls: { + addgroup: { + enabled: true + } + } + }); + ReactDOM.render(, document.getElementById("container")); + expect(document.getElementById('mapstore-add-toc-group')).toExist(); + }); + + it('Closes AddGroup on cancel', () => { + const { Plugin, store } = getPluginForTest(AddGroupPlugin, { + controls: { + addgroup: { + enabled: true + } + } + }); + ReactDOM.render(, document.getElementById("container")); + const btn = document.getElementsByTagName('button')[0]; + ReactTestUtils.Simulate.click(btn); + expect(store.getState().controls.addgroup.enabled).toBe(false); + }); + + it('Add Group on confirm', () => { + const { Plugin, store } = getPluginForTest(AddGroupPlugin, { + map: {}, + controls: { + addgroup: { + enabled: true + } + }, + layers: { + groups: [{id: 'group1', nodes: []}] + } + }); + ReactDOM.render(, document.getElementById("container")); + const input = document.getElementsByTagName('input')[0]; + ReactTestUtils.Simulate.change(input, { + target: { + value: 'newgroup' + } + }); + const btn = document.getElementsByTagName('button')[1]; + ReactTestUtils.Simulate.click(btn); + expect(store.getState().layers.groups.length).toBe(2); + expect(store.getState().layers.groups[1].name).toBe('newgroup'); + expect(store.getState().layers.groups[1].id).toBe('newgroup'); + expect(store.getState().layers.groups[1].title).toBe('newgroup'); + expect(store.getState().layers.groups[1].nodes.length).toBe(0); + }); + + it('Add Nested Group on confirm', () => { + const { Plugin, store } = getPluginForTest(AddGroupPlugin, { + map: {}, + controls: { + addgroup: { + enabled: true, + parent: 'group1.group2' + } + }, + layers: { + groups: [{ id: 'group1', nodes: [{id: 'group1.group2', nodes: []}] }] + } + }); + ReactDOM.render(, document.getElementById("container")); + const input = document.getElementsByTagName('input')[0]; + ReactTestUtils.Simulate.change(input, { + target: { + value: 'newgroup' + } + }); + const btn = document.getElementsByTagName('button')[1]; + ReactTestUtils.Simulate.click(btn); + expect(store.getState().layers.groups.length).toBe(1); + expect(store.getState().layers.groups[0].nodes.length).toBe(1); + expect(store.getState().layers.groups[0].nodes[0].nodes.length).toBe(1); + const newgroup = store.getState().layers.groups[0].nodes[0].nodes[0]; + expect(newgroup.name).toBe('newgroup'); + expect(newgroup.id).toBe('group1.group2.newgroup'); + expect(newgroup.title).toBe('newgroup'); + expect(newgroup.nodes.length).toBe(0); + }); +}); diff --git a/web/client/plugins/__tests__/pluginsTestUtils.js b/web/client/plugins/__tests__/pluginsTestUtils.js index 216a40b2bf..cb3053d2a5 100644 --- a/web/client/plugins/__tests__/pluginsTestUtils.js +++ b/web/client/plugins/__tests__/pluginsTestUtils.js @@ -12,7 +12,7 @@ import {Provider} from 'react-redux'; import { createStore, combineReducers, applyMiddleware } from 'redux'; import { combineEpics, createEpicMiddleware } from 'redux-observable'; -import map from '../../reducers/layers'; +import map from '../../reducers/map'; import layers from '../../reducers/layers'; import controls from '../../reducers/controls'; diff --git a/web/client/product/plugins.js b/web/client/product/plugins.js index ef723b10b5..b4723ff269 100644 --- a/web/client/product/plugins.js +++ b/web/client/product/plugins.js @@ -13,6 +13,7 @@ module.exports = { PrintPlugin: require('../plugins/Print'), IdentifyPlugin: require('../plugins/Identify'), TOCPlugin: require('../plugins/TOC'), + AddGroupPlugin: require('../plugins/AddGroup').default, BackgroundSwitcherPlugin: require('../plugins/BackgroundSwitcher'), MeasurePlugin: require('../plugins/Measure'), MapPlugin: require('../plugins/Map'), diff --git a/web/client/reducers/__tests__/controls-test.js b/web/client/reducers/__tests__/controls-test.js index ac1167ab29..94dcbb1403 100644 --- a/web/client/reducers/__tests__/controls-test.js +++ b/web/client/reducers/__tests__/controls-test.js @@ -8,7 +8,7 @@ const expect = require('expect'); const controls = require('../controls'); -const {TOGGLE_CONTROL, SET_CONTROL_PROPERTY, RESET_CONTROLS} = require('../../actions/controls'); +const {TOGGLE_CONTROL, SET_CONTROL_PROPERTY, SET_CONTROL_PROPERTIES, RESET_CONTROLS} = require('../../actions/controls'); describe('Test the controls reducer', () => { it('default case', () => { @@ -85,6 +85,20 @@ describe('Test the controls reducer', () => { expect(state.mycontrol.prop).toBe(undefined); }); + it('set a list of control properties', () => { + const state = controls({}, { + type: SET_CONTROL_PROPERTIES, + control: 'mycontrol', + properties: { + 'prop1': 'val1', + 'prop2': 'val2' + } + }); + expect(state.mycontrol).toExist(); + expect(state.mycontrol.prop1).toBe('val1'); + expect(state.mycontrol.prop2).toBe('val2'); + }); + it('reset the controls without skip ', () => { const state = controls( { diff --git a/web/client/reducers/__tests__/layers-test.js b/web/client/reducers/__tests__/layers-test.js index bfcada641e..8c3026883e 100644 --- a/web/client/reducers/__tests__/layers-test.js +++ b/web/client/reducers/__tests__/layers-test.js @@ -7,7 +7,7 @@ */ var expect = require('expect'); var layers = require('../layers'); -const { changeLayerParams, addLayer } = require('../../actions/layers'); +const { changeLayerParams, addLayer, ADD_GROUP } = require('../../actions/layers'); describe('Test the layers reducer', () => { @@ -111,6 +111,27 @@ describe('Test the layers reducer', () => { ] }; let state = layers(initialState, testAction); + expect(state.groups.length).toBe(2); + expect(state.flat.length).toBe(1); + }); + it('removeNode layer with remove empty groups flag', () => { + let testAction = { + type: 'REMOVE_NODE', + node: 'layer1', + nodeType: 'layers', + removeEmpty: true + }; + let initialState = { + groups: [ + { name: 'sample1', nodes: ['layer1'], id: 'sample1' }, + { name: 'sample2', nodes: ['layer2'], id: 'sample2' } + ], + flat: [ + { id: 'layer1', group: 'sample1' }, + { id: 'layer2', group: 'sample2' } + ] + }; + let state = layers(initialState, testAction); expect(state.groups.length).toBe(1); expect(state.flat.length).toBe(1); }); @@ -799,4 +820,35 @@ describe('Test the layers reducer', () => { expect(state.layerMetadata.expanded).toEqual(false); }); + it('add root group', () => { + const action = { + type: ADD_GROUP, + group: 'newgroup' + }; + + const state = layers({groups: [{id: 'group1'}]}, action); + expect(state).toExist(); + expect(state.groups.length).toBe(2); + expect(state.groups[1].id).toBe('newgroup'); + }); + + it('add nested group', () => { + const action = { + type: ADD_GROUP, + group: 'newgroup', + parent: 'group1.group2' + }; + + const state = layers({ groups: [{ id: 'group1', nodes: [{ id: 'group1.group2', nodes: [{ id: 'group1.group2.group3', nodes: []}]}] }] }, action); + expect(state).toExist(); + expect(state.groups.length).toBe(1); + expect(state.groups[0].nodes.length).toBe(1); + expect(state.groups[0].nodes[0].nodes.length).toBe(2); + const newgroup = state.groups[0].nodes[0].nodes[1]; + expect(newgroup.id).toBe('group1.group2.newgroup'); + expect(newgroup.name).toBe('newgroup'); + expect(newgroup.title).toBe('newgroup'); + expect(newgroup.nodes.length).toBe(0); + }); + }); diff --git a/web/client/reducers/controls.js b/web/client/reducers/controls.js index 242877090e..4f748d6878 100644 --- a/web/client/reducers/controls.js +++ b/web/client/reducers/controls.js @@ -6,7 +6,7 @@ * LICENSE file in the root directory of this source tree. */ -const {TOGGLE_CONTROL, SET_CONTROL_PROPERTY, RESET_CONTROLS} = require('../actions/controls'); +const { TOGGLE_CONTROL, SET_CONTROL_PROPERTY, SET_CONTROL_PROPERTIES, RESET_CONTROLS} = require('../actions/controls'); const assign = require('object-assign'); /** * Manages the state of the controls in MapStore2 @@ -66,6 +66,11 @@ function controls(state = {}, action) { [action.property]: action.value }) }); + case SET_CONTROL_PROPERTIES: { + return assign({}, state, { + [action.control]: assign({}, state[action.control], action.properties) + }); + } case RESET_CONTROLS: { const newControls = Object.keys(state).filter(c => (action.skip || []).indexOf(c) === -1); const resetted = newControls.reduce((previous, controlName) => { diff --git a/web/client/reducers/layers.js b/web/client/reducers/layers.js index 92ca163302..6f3955c95c 100644 --- a/web/client/reducers/layers.js +++ b/web/client/reducers/layers.js @@ -7,7 +7,7 @@ */ var { LAYER_LOADING, LAYER_LOAD, LAYER_ERROR, CHANGE_LAYER_PARAMS, CHANGE_LAYER_PROPERTIES, CHANGE_GROUP_PROPERTIES, - TOGGLE_NODE, SORT_NODE, REMOVE_NODE, UPDATE_NODE, ADD_LAYER, REMOVE_LAYER, + TOGGLE_NODE, SORT_NODE, REMOVE_NODE, UPDATE_NODE, ADD_LAYER, REMOVE_LAYER, ADD_GROUP, SHOW_SETTINGS, HIDE_SETTINGS, UPDATE_SETTINGS, REFRESH_LAYERS, LAYERS_REFRESH_ERROR, LAYERS_REFRESHED, CLEAR_LAYERS, SELECT_NODE, FILTER_LAYERS, SHOW_LAYER_METADATA, HIDE_LAYER_METADATA } = require('../actions/layers'); @@ -54,7 +54,20 @@ const moveNode = (groups, node, groupId, newLayers, foreground = true) => { }else { newGroups = LayersUtils.deepChange(newGroups, group.id, 'nodes', foreground ? [node].concat(group.nodes.slice(0)) : group.nodes.concat(node)); } - return LayersUtils.removeEmptyGroups(newGroups); + return newGroups; +}; + +const insertNode = (nodes, node, parent) => { + if (!parent) { + return [...nodes, node]; + } + return nodes.map(n => isString(n) ? n : (n.id === parent ? { + ...n, + nodes: [...n.nodes, node] + } : { + ...n, + nodes: insertNode(n.nodes, node, parent) + })); }; function layers(state = { flat: [] }, action) { @@ -208,11 +221,13 @@ function layers(state = { flat: [] }, action) { }; } if (action.nodeType === 'layers') { - const newGroups = deepRemove(state.groups, action.node); + const newGroups = action.removeEmpty ? + LayersUtils.removeEmptyGroups(deepRemove(state.groups, action.node)) : + deepRemove(state.groups, action.node); const newLayers = state.flat.filter((layer) => layer.id !== action.node); return assign({}, state, { flat: newLayers, - groups: LayersUtils.removeEmptyGroups(newGroups) + groups: newGroups }); } return state; @@ -240,6 +255,19 @@ function layers(state = { flat: [] }, action) { groups: newGroups }); } + case ADD_GROUP: { + const id = action.group.replace(/\./g, '\${dot}'); + const newGroups = insertNode(state.groups, { + id: action.parent ? (action.parent + '.' + id) : id, + title: action.group, + name: action.group, + nodes: [], + expanded: true + }, action.parent); + return assign({}, state, { + groups: newGroups + }); + } case SHOW_SETTINGS: { let settings = assign({}, state.settings, { expanded: true, diff --git a/web/client/selectors/__tests__/catalog-test.js b/web/client/selectors/__tests__/catalog-test.js index 2473d9d491..1c0dabf2c2 100644 --- a/web/client/selectors/__tests__/catalog-test.js +++ b/web/client/selectors/__tests__/catalog-test.js @@ -22,7 +22,8 @@ const { layerErrorSelector, activeSelector, authkeyParamNameSelector, - searchTextSelector + searchTextSelector, + groupSelector } = require("../catalog"); const {set} = require('../../utils/ImmutableUtils'); @@ -30,7 +31,8 @@ const url = "https://demo.geo-solutions.it/geoserver/wms"; const state = { controls: { metadataexplorer: { - enabled: true + enabled: true, + group: 'mygroup' } }, catalog: { @@ -83,6 +85,10 @@ const state = { }; describe('Test catalog selectors', () => { + it('test groupSelector', () => { + const retVal = groupSelector(state); + expect(retVal).toBe('mygroup'); + }); it('test resultSelector', () => { const retVal = resultSelector(state); expect(retVal).toExist(); diff --git a/web/client/selectors/catalog.js b/web/client/selectors/catalog.js index 908afdc37e..588b1333f9 100644 --- a/web/client/selectors/catalog.js +++ b/web/client/selectors/catalog.js @@ -1,6 +1,7 @@ const {get} = require('lodash'); module.exports = { + groupSelector: (state) => get(state, "controls.metadataexplorer.group"), savingSelector: (state) => get(state, "catalog.saving"), resultSelector: (state) => get(state, "catalog.result"), serviceListOpenSelector: (state) => get(state, "catalog.openCatalogServiceList"), diff --git a/web/client/themes/default/icons.less b/web/client/themes/default/icons.less index 08aa37f92f..23e33e3ddd 100644 --- a/web/client/themes/default/icons.less +++ b/web/client/themes/default/icons.less @@ -892,6 +892,10 @@ content: "\002c"; } +.glyphicon-add-folder:before { + content: "\00e3" +} + .glyphicon-counter:before { content: "\003d"; } diff --git a/web/client/themes/default/icons/icons.eot b/web/client/themes/default/icons/icons.eot index 2a3a558d73ec59b0eec72da4700e61ff6e4292da..be1c652b0269cb870bb5f1572e619c3318ffcb96 100644 GIT binary patch delta 3127 zcmZ{mdsGxh7RKv#S5GtJgO|X7#2G*ZHBm%ER5T(11VjTGke52Z$V-qxMnptG1Vpnz zO{s%Q5Ef8yjZ18gkVLbr8k6JEXtJ81ArbHqvl@H^S%NIRcN};BTl)O^`|ho07uD0% za)%b*qe8I{kj_2ATl8!nH@L^&=vq+U{DQ#rc0!2j!oZ+l_>NGFYcbaDx#mzLO$jB$ z%1DUfTymaKE1sh_2(i6}#i|rTYL@k>X-5gMo<#_^IyEuZAj^cu=2cj3m72LRB}e)9 z9|>{rA~5wvxZhzdR!GAJ+O>&Us|ODG|43lG4d!+jvU81Gjr;|H3Dty*7&5F| zZD@HmWem2j#rjhT;2jy{`p&Mhp8K4Ppe>joHf(+z}mRKfFINI^I;@w;HN43v9Ia0MIKi3#v&76m3gCjAd?Yu zKFw11W!tG3+nMt$QW=-Kh{9xZ5Bu@#-)2n%)>Ctp*zSmsST-Bs&QZM9H5FzRs&q!#t81yVo@ z#mEly{iwSU)5~{{bmN4&aS~vKYJ)hVw?)+=I0?Wf@AgJ!qo084j|8K~)$9&Ia6;gV z8iB;3$KRfA9gg3fjzIvb0l`T?IBGGn1AR2=Ze$;N9V$+y`vCeBLV5_IK#%QvlokN{ z=&?Z@F`t8~Mx4>-qq_10tHu+(P#kS{v*&i}mvRe>3S zC4r~$dJ^Onqz|eM`XZ=5I3(B*Tp9dz@IM!3EZn{DVh9Ow4~Yr67U~;n4E-!DAgns< zR9OF_S&O0<)hy}>_X>{)F9|=l*ky6b;`SwWOAJdcz3cey&Il5rizta`DT)|~R7FNa z7DrY`_CyXX4PIKg^!sHl%k;~RzZd=97g1hO;Zb=}2cs@U^+fwbmq&LjpSwI`dCT(q z%ll$fG3uBlF?(aq#XO6(igk^Ri!F`45Zf1Lh&vrm;+MwnjsGsbFF~C!Ct+nmMM8VR zzzUxg*H_M2d17V%s)$v!t9o>=>xv3=)w*lCySl-|xrrr-rxFK~CMU%u`!S+d6rt4HZIMWc0JuOJtRFZeK;c{qdMc( z8ugm+HN|T>GJP`jnKhXmS$0`*SqHQ3u6=#2er@&I@3Kc`hh_gMyEglQA;565D90|x zkaIBS(YlrEnsQaSA-PSt_l;AH>x`$2Pu9Dy*RMaa{z0BsURqwu2JME54W~B@=AX$Q z*f?|J-i=QRmK4-(irdt*X{a!;u&VIq&90j>H-EPI*_K&bs*BV`4aGBy3yK?xzuC%d z_1?O2Ys1#Ql7Nz(CB56iwi&loZR;p?DV-Eoda(3XnM>K6vgopPWtC;e%AS<_mdBLm zmsgdyZMWGzce`%8(R`WCc)%p-slz_NFPK!}bcYHC`3apb8C*YA!CTT~&ma!UB*Ub! zB0rVCBvpDpRl(;{vENk?{p4dbhkqtT&wFizFjB6k4N`tcy%Od!*QN8te)$S*qi;${ zOWi>HmwcIiiowoh_e9ZMK0+(0y_6TfK)}&HqyFrS?xF&}s#f%bRFU{Mo^PSEq_EYE zg7`ibPoxT|KO=j(HBX3KL9vXCC2x};R+%%d2>igu$#IO+IB;^DF%D+9`8c9?a8$eo zZte<^x1H&0?>2)M-R${BcXhLkT5Z#;c6UB%t5(|{9ja0cx~Vt-jvwK~3jo8T>_v`p z+`oOtO`#_Hhg^H*SKQF4i*%OS=9r_0y4lvr$+lVT;dsnuIL=iuN}*Ax1UnAIkyI&; z7^4&>j2$*{Z(2JH|1$gr57!CPSN|1qq%j{Y2k{YEK_$L~t*gm}bm@N0J`e-sbF`R7 zOC`0VKr|8+_2bV=`|HwqaV#$1F8(f4G|m&#!V| zfM!;BJ|6b5j`KT|hv;;E92rTRS=V`2R(_#bEG89nJwJl^eyQh(E35u;CkG1VbunJ> zAtiK+RB`bh4}Q|xOKte09U|YR8I)sFFK>XS?8xO{j&EbVmlr@T^S-hWrnCGjK|&5~ zpia`cE1&SfV!4ARN%`MS;ecZe|M&>5N&(lM0DhC=ZX5t1mG}xF(!lpJh1+c4$7DQY zBy^_34R*0J84{$)KmEpwPO^zsQ!i;;_cxT|ho#?3rJEE`)x2#+10~=TdU~igh z2hWAK=~@19tFJx$q!53_rTd!qYjtsfctLo?Z=|zK1sa%+Yx;t2F|}x52HN{{OX~v- zlmXw%pEeoXV7~Z=e4dWsOHHTUU>W>vZ&Bgd&_#wmoH{1H;5WoYval7tvIyaU?pGO`QP z`Da}Z5pwfF*wG_1O`Gb%lRGe;1GEQZLP8Zpu0R|Nu~%k}v0#%rXcEL07_TNfH$_`= z{Hw%j81ObiOhk^hz@Qkydgzb|2MBs?PTKPWK|dhu83ehVhTMGPzn#e65%z)tM~xWr z(hN;QZ@a?r2cf?&!mtN=7GK<(MtNk4>kNP*~m z?87z62jNEQq9|8LPidWk$69(`@i~5jrZNk#k~T6k><8goGf9&)M0*);_lXca0WJe- zzz5Jn>kDd8jKgKrpVZNAGUr{$p?3it9!3b-`@qZko7~stk>6_{PCsOMcX!B6wPjxQ z@P*g~aHa-!26mxG*&>B>mwG5?j1Gcsz0hr+tq z>@YrJfJoY+d>aQ+i}Jn6Z4hgKt$@R8MuWsg zq)s?FfKq`%08u}?aqMYuv*hV;?s(lM4@`jV)Mz&cKcG!^Gp0_5SVqpv?X!RbuZaSc zX`sa36BFuVKO0+Vvi<#}T8rMY;O?(?@BjEo-}diMecy2B^E-#`)Cs4AlfqGb#r!^fqrLr3#0Yp&2t`>BL4Ri=J$p$(Mdd3Di0(#K~I*QN~7aQmp zLY{BhK*tf9`Y#)(0im~G4a%TK&=DKx1VSa=_6W(Klb}vE5d0}E(AmO3{xm2H$bCKs z9Rs+7hY7U^z%=k*gZcrp!CwXq0+xX90#yTRz{7vgqOpPCqAkfl7AisLJ{SW~2%UZc zH32)pKLf1+%-|)2?masgGVob@KLdQ^kht1RPWGZPFix-@JVoIVG|G%v< zm;`$St6{4OZVP@H5*QK}QWIhgRfYP5CWn@Xk+A7uny~t?3t>ayy72BLj!RZ8>5T}8 zh>EC*xE?VW`C(*nWLxCGQjevHOIwzqW%0|-M5&@uqneg`Ew5ibqV`ZnsB25qjp~6F z6IKMQC|gK%E47}tJ+pQj2RQ-ACnqW9Mid4Se>`}W-N(~h&9Dl z$2P_`$3BYljZ2K%6?Z)DT-@-QNo&@wsg760tK;kAA1C-GWG7T7G$-6hc%C>VF+Q<2 zvGXJSM>p1nudP`-kQA6yoYbyy)szHibegT2J(`5IC)HReDaRumgN2v z*Oc&-qLi~K*3_}75vf~Ko6}CF-AwmOk51o};gfMb(=k(@*_3I`8k1G0Bf0>cQP-?{ zxNgF_ymg)HUS@xootJ$kdpO5GXKPM-&P#oOK3jiM-=F(dZeVU{Zm(gf;Y`VT)q4N+ zmFu79Ey`=mv*s_#H|2L29gI=ND&qy?%MC#rN;kA^RBVjc`1PhKo79{36s#_&E$Axr zEvzbhR1{b=ym`^)eVczQo>g2>d~S!PL=3NAhuwc<#tv%=t-YiHW3%(Z@z(E*z;y26IhJ zKc2;K?$T9aW**aJJ|=_ElsvQ;*!x zY^oQ>)9cNYts>4$y{HqlO1wnu{3?L6lkQ6SDh5PBgz7)Jn z9O?U+;anv%+{@MClY3o6L6CUq;R(zfB|0(v(S8Qct$myUiy`yzn}qF_E-)5x$KWpt zc$pUc`V{k`ZukIUx04eji>iKa!0W}czrU~G9Hno`F_I__yay(a>2h7Lj00!Uw zZ`3-L;4d(Xq%P9b+QH%m!k(7Sv39Kn6<*A-+hJ`?Yd!CbS7PjDc6b9nV|`℘o0U z?o)CPVB$KNg{=b~!>kRGLi!eh=(JQrUW5z!jJ|KwQm1Q}6=r zfb>`5%G@$nPQmk-Wabld`xHEzi9#-Bg(sfJHb^3IFb8`=X;)f@JaMi9KJMUoixhN{ z diff --git a/web/client/themes/default/icons/icons.svg b/web/client/themes/default/icons/icons.svg index 9259bc0cc8..e5ea52ffa2 100644 --- a/web/client/themes/default/icons/icons.svg +++ b/web/client/themes/default/icons/icons.svg @@ -1,9 +1,9 @@ - + -Created by FontForge 20170731 at Mon Feb 18 10:15:57 2019 - By stefano +Created by FontForge 20120702 at Tue May 21 14:35:33 2019 + @@ -571,6 +571,12 @@ d="M672 -120h128v1200h-128h128v-1200h-128zM672 1080h-272v0l272 -272v-656l-272 -2 d="M536 1080v-204h128v204h-128zM536 1080h128v-204h-128v204zM536 748v-204h128v204h-128zM536 748h128v-204h-128v204zM536 416v-204h128v204h-128zM536 416h128v-204h-128v204zM536 84v-204h128v204h-128zM536 84h128v-204h-128v204zM536 748v-204h128v204h-128zM536 748 h128v-204h-128v204zM536 416v-204h128v204h-128zM536 416h128v-204h-128v204zM536 84v-204h128v204h-128zM536 84h128v-204h-128v204zM536 416v-204h128v204h-128zM536 416h128v-204h-128v204zM536 84v-204h128v204h-128zM536 84h128v-204h-128v204zM536 84v-204h128v204 h-128zM536 84h128v-204h-128v204zM536 1080h128v-204h-128v204zM536 748h128v-204h-128v204zM536 416h128v-204h-128v204zM536 84h128v-204h-128v204z" /> + /> - + diff --git a/web/client/themes/default/icons/icons.ttf b/web/client/themes/default/icons/icons.ttf index 52badd18b0cd60c011a875638cdbb3867401242f..8bd9b26910087de568858d4740fc54b7a033c5e7 100644 GIT binary patch delta 3066 zcmZ{mc~}%j8piAEuAYVw0RcJ0Faur~q6iv-LLw4CM9={Rxzyp1OO63X1Ux_lJmMm2 zspCNqBN~#838sC-T!yGIt|7`AGm!4yF((`RXtb7UKR;4Eu>SUSl zc)fjCZ3dq#<~-*yq~cuDb-%Jr4~D|zy>}Um{11Lix>xCJTW6jU%c-3 zpdpOAu*2Qic_~RPUkz%p!`p=L;Wg6*8Ce;x#YFJk=XO*tG&%+Kc(10gQADIoDj3KW7vz1oAK*LpT<|IlvpNmfuG)B+Q-qP0L3&4atIj{O_9OUyL=VcuD!0$&IqJ4kd|^}9@7h+qsuWpo;HI5)tfa7(=ACTTH_f; z3fV(J1rf|b;Q{H)S1}X*!Lk)9a9}$WbAe)QN2>d(9@TBtbyd6SiYil;u1ZpARdK3Vl|~h&3R1mh z)*2h+VDeHtM>1W};J^Lxxq z0A8cV8nMTGKB^<)guWQn)dZBHPC%w$K6)LR8OUr5u+yFZWC8l^s2U^={ccpP3BWZm zD4T#o1fGr=fj|R+fp-y=vF zloeDFbPA6r!S2DS!41J@f(JrELv$fEAs0g)%+H!%JO4r`33UsN4Q*fGvp~P#!zfkv);aQ6W(^QP-D@Tavouy`?cr&qTXNhesDhABesb-4o*-QytT}%zs(dvgT#? zmi5OfV;y4`#qN$h8`~FW7B@aFKCUwEd|ZFLF8)*kNr+0=op3dwKhZI9PU4Eht%W+{R`zIL(w3EK>$L6KUhPnle^N!#$)us=7n9?Yi;`QDAEk^- z2}>zWc|WBq)h;zOb$x1cYVRt?G>bI&hlm!t=tzbfGq>Gqr}Ao|Jg(tN&8`q2M{QG$hhgf>bY^N*N=KP!%$D-Out(9`r~ z=}e?6h`-5g^dk)JMg1s>Zt^i&Lv5w2@$&@i?PD6i9JLn|gd=A3eW_RbInOs!U+Gxt zQ9*nIt0z;16qS|dWyKRBZ>3mAoXKk>m_5+Bya;~a?O<=`-~tZzGhJY&tG7M+vG$4= zz|~D5@?&QC*t*W-MORzqm2W$Bc%Nd(RmlNx{3r)r0C+yyR^%wh{oBXIgBomq=2~mM z;)YLNU=0O!6XVA#Mk^Fb!G;6Tf|`q??97Ep&d&|p%T{Bb|MU4Y9y$nXJ@^6SOS-yc zAU-6^sl->X%WoD!rW9De2gE@6EG?%o(hrA5gQzD;>c^jx`WiBM(HSRbC*RAG8($SO zNnOfOlBu*#y|bW}Vx{AEaKa_1xEDIoV3r z@T1tS^Qjye&j!zL=RmJo9|9UO_%DA== zjz7)9+U7wa+tD^3yjVwDu#it1se|P5%?VzJkUMFz)Y0z20k`YhH{ps@|E&YSFVd-w z{UD?hA0bp)dR?Y)hb_I8g5L?JZ)L(Y=5{*;5~b?fzwn}iY@l`2T`KLmOga9!6!zm$ z;Hzn{)OT+`4*_h)gLDXx`X4w`;imj4-znKW{uTdJrs#VNFGvG@2XPAMQR>I`{&obi zq&b5xbE1`eiPqCNsc0w&C(2PiOwaS{4QBy5{~NWu#ldk9rpTA+ww9$7j!@yad`jS3 zhRxu0QP_!#(X}PW8kPXq8upEWr^0LWGyZYQE*tn>A^wCjcaisNDRP1YL3qfQP+!A! z7x2Om@OWGU?QjB`7V()iG#ShumKLFk5=s5rY delta 2954 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 diff --git a/web/client/themes/default/icons/icons.woff b/web/client/themes/default/icons/icons.woff index 7b03c14feb0ad2a3a7f19b10dc593d775109056a..c0f096252234e0be069254d920d3467005ddaca5 100644 GIT binary patch delta 44652 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⩔8r4}==s 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 C8`^dN delta 44524 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 z
ek1&9o1^~zvK{3}9LX~qo$0zb+n>qmtl+Ocb$fmTFVB`}<8VGbIVdTh>=S(7> zCTuB_&ONZd=e5$)XxwT8dJ3#e`&4L(8S7;HaMU!8Yv4zv7O1JIUPidOu7%JM+&u* zLp0S6Op;5LbluTbx7=`n=UOMCp$y`=Nd2%iDVNSPij(68z>Uc`fFF-Z0xLBvSpQC}t!_xnP6A{BBbR3FROZ2~KLG|}ry zCxSTcNh(2sam#XBIA;4vZv3RY%kc&imUJ

D?ahxO5iVd|@myUX@2U?yZ#lfQ^oT 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 OO { + recordToLayer: (record, type = "wms", {removeParams = [], catalogURL, url} = {}, baseConfig = {}) => { if (!record || !record.references) { // we don't have a valid record so no buttons to add return null; @@ -406,13 +406,14 @@ const CatalogUtils = { links: getRecordLinks(record), params: params, allowedSRS: allowedSRS, - catalogURL + catalogURL, + ...baseConfig }; }, getCatalogRecords: (format, records, options) => { return converters[format] && converters[format](records, options) || null; }, - esriToLayer: (record) => { + esriToLayer: (record, baseConfig = {}) => { if (!record || !record.references) { // we don't have a valid record so no buttons to add return null; @@ -433,7 +434,8 @@ const CatalogUtils = { maxx: record.boundingBox.extent[2], maxy: record.boundingBox.extent[3] } - } + }, + ...baseConfig }; }