• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 12831531306

17 Jan 2025 03:01PM UTC coverage: 77.182% (+0.07%) from 77.115%
12831531306

Pull #10746

github

web-flow
Merge 501dbaeea into 4e4dabc03
Pull Request #10746: Fix #10739 Changing correctly resolutions limits when switching map CRS

30373 of 47156 branches covered (64.41%)

34 of 43 new or added lines in 2 files covered. (79.07%)

126 existing lines in 15 files now uncovered.

37769 of 48935 relevant lines covered (77.18%)

35.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/web/client/plugins/TOC/components/TOC.jsx
1
/*
2
 * Copyright 2015, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8

9
import React from 'react';
10
import LayersTree from './LayersTree';
11
import {
12
    NodeTypes,
13
    denormalizeGroups,
14
    splitMapAndLayers,
15
    sortGroups,
16
    changeNodeConfiguration
17
} from '../../../utils/LayersUtils';
18
import { selectedNodesIdsToObject } from '../utils/TOCUtils';
19
import {
20
    saveMapConfiguration
21
} from '../../../utils/MapUtils';
22

23
/**
24
 * Controlled TOC component that supports map configuration
25
 * @prop {object} tree nodes tree
26
 * @prop {object} contextMenu context menu payload
27
 * @prop {function} onSort return the sorted node information
28
 * @prop {function} onChange return the changes of a specific node
29
 * @prop {function} onContextMenu return the context menu event of a specific node
30
 * @prop {component} groupNodeComponent custom group node component
31
 * @prop {component} layerNodeComponent custom layer node component
32
 * @prop {array} selectedNodes list of selected node objects
33
 * @prop {function} onSelectNode return the current selected node on click event
34
 * @prop {string} filterText filter to apply to layers title
35
 * @prop {string} theme layers tree theme, one of undefined or `legend`
36
 * @prop {string} className additional class name for the layer tree
37
 * @prop {array} nodeContentItems list of node content component to customize specific content available after expanding the node, expected structure [ { name, Component } ]
38
 * @prop {array} nodeItems list of node component to customize specific nodes, expected structure [ { name, Component, selector } ]
39
 * @prop {array} nodeToolItems list of node tool component to customize specific tool available on a node, expected structure [ { name, Component } ]
40
 * @prop {object} singleDefaultGroup if true it hides the default group nodes
41
 * @prop {object} config optional configuration available for the nodes
42
 * @prop {number} config.resolution map resolution
43
 * @prop {array} config.resolutions list of available map resolutions
44
 * @prop {array} config.scales list of available map scales
45
 * @prop {number} config.zoom zoom level of the map
46
 * @prop {string} config.visualizationMode visualization mode of the map, `2D` or `3D`
47
 * @prop {boolean} config.sortable activate the possibility to sort nodes
48
 * @prop {boolean} config.hideOpacitySlider hide the opacity slider
49
 * @prop {string} config.language current language code
50
 * @prop {string} config.currentLocale current language code
51
 * @prop {boolean} config.showTitleTooltip show the title tooltip
52
 * @prop {boolean} config.showOpacityTooltip show the opacity tooltip
53
 * @prop {object} config.groupOptions specific options for group nodes
54
 * @prop {object} config.groupOptions.tooltipOptions options for group title tooltip
55
 * @prop {object} config.layerOptions specific options for layer nodes
56
 * @prop {object} config.layerOptions.tooltipOptions options for layer title tooltip
57
 * @prop {boolean} config.layerOptions.hideLegend hide the legend of the layer
58
 * @prop {object} config.layerOptions.legendOptions additional options for WMS legend
59
 * @prop {boolean} config.layerOptions.hideFilter hide the filter button in the layer nodes
60
 */
61
export function ControlledTOC({
62
    tree,
63
    contextMenu,
64
    onSort = () => {},
×
65
    onChange = () => {},
×
66
    onSelectNode = () => {},
×
67
    onContextMenu = () => {},
36✔
68
    groupNodeComponent,
69
    layerNodeComponent,
70
    filterText,
71
    selectedNodes,
72
    rootGroupId,
73
    nodeTypes = NodeTypes,
36✔
74
    config = {},
×
75
    className,
76
    nodeItems,
77
    nodeToolItems,
78
    nodeContentItems,
79
    singleDefaultGroup,
80
    theme
81
}) {
82
    return (
57✔
83
        <LayersTree
84
            className={className}
85
            theme={theme}
86
            tree={tree}
87
            filterText={filterText}
88
            onSort={onSort}
89
            onChange={({ options, node: currentNode, nodeType }) =>
90
                onChange(currentNode.id, nodeType, options)
9✔
91
            }
92
            groupNodeComponent={groupNodeComponent}
93
            layerNodeComponent={layerNodeComponent}
94
            contextMenu={contextMenu}
95
            onContextMenu={onContextMenu}
96
            selectedNodes={selectedNodes}
97
            onSelect={({ event, node: currentNode, nodeType }) =>
98
                onSelectNode(currentNode.id, nodeType === nodeTypes.GROUP ? 'group' : 'layer', event?.ctrlKey)
2✔
99
            }
100
            nodeTypes={nodeTypes}
101
            rootGroupId={rootGroupId}
102
            config={config}
103
            nodeItems={nodeItems}
104
            nodeToolItems={nodeToolItems}
105
            nodeContentItems={nodeContentItems}
106
            singleDefaultGroup={singleDefaultGroup}
107
        />
108
    );
109
}
110

111
/**
112
 * TOC component that supports map configuration
113
 * @prop {object} map map configuration
114
 * @prop {function} onChangeNode return the changed node configuration
115
 * @prop {function} onChangeMap return the changed map configuration
116
 * @prop {array} selectedNodes list of selected node identifiers
117
 * @prop {function} onSelectNode return the current selected node on click event
118
 * @prop {string} theme layers tree theme, one of undefined or `legend`
119
 * @prop {string} className additional class name for the layer tree
120
 * @prop {array} nodeItems list of node component to customize specific nodes, expected structure [ { name, Component, selector } ]
121
 * @prop {array} nodeToolItems list of node tool component to customize specific tool available on a node, expected structure [ { name, Component } ]
122
 * @prop {array} nodeContentItems list of node content component to customize specific content available after expanding the node, expected structure [ { name, Component } ]
123
 * @prop {object} singleDefaultGroup if true it hides the default group nodes
124
 * @prop {object} config optional configuration available for the nodes
125
 * @prop {number} config.resolution map resolution
126
 * @prop {array} config.resolutions list of available map resolutions
127
 * @prop {array} config.scales list of available map scales
128
 * @prop {number} config.zoom zoom level of the map
129
 * @prop {string} config.visualizationMode visualization mode of the map, `2D` or `3D`
130
 * @prop {boolean} config.sortable activate the possibility to sort nodes
131
 * @prop {boolean} config.hideOpacitySlider hide the opacity slider
132
 * @prop {string} config.language current language code
133
 * @prop {string} config.currentLocale current language code
134
 * @prop {boolean} config.showTitleTooltip show the title tooltip
135
 * @prop {boolean} config.showOpacityTooltip show the opacity tooltip
136
 * @prop {object} config.groupOptions specific options for group nodes
137
 * @prop {object} config.groupOptions.tooltipOptions options for group title tooltip
138
 * @prop {object} config.layerOptions specific options for layer nodes
139
 * @prop {object} config.layerOptions.tooltipOptions options for layer title tooltip
140
 * @prop {boolean} config.layerOptions.hideLegend hide the legend of the layer
141
 * @prop {object} config.layerOptions.legendOptions additional options for WMS legend
142
 * @prop {boolean} config.layerOptions.hideFilter hide the filter button in the layer nodes
143
 */
144
function TOC({
145
    map = { layers: [], groups: [] },
1✔
146
    onChangeNode = () => {},
23✔
147
    onChangeMap = () => {},
15✔
148
    selectedNodes = [],
30✔
149
    onSelectNode = () => {},
29✔
150
    config,
151
    className,
152
    nodeToolItems,
153
    nodeContentItems,
154
    singleDefaultGroup,
155
    nodeItems,
156
    theme,
157
    filterText
158
}) {
159
    const { layers } = splitMapAndLayers(map) || {};
36!
160
    const tree = denormalizeGroups(layers.flat || [], layers.groups || []).groups;
36!
161
    function handleOnChange(currentLayers, currentGroups) {
162
        const mapConfig = saveMapConfiguration(map, currentLayers || layers.flat, currentGroups || layers.groups, []);
9✔
163
        const newMap = {
9✔
164
            ...map,
165
            layers: mapConfig?.map?.layers,
166
            groups: mapConfig?.map?.groups
167
        };
168
        onChangeMap(newMap);
9✔
169
    }
170
    function handleOnSort(nodeId, groupId, index) {
171
        const sortedGroups = sortGroups({
×
172
            groups: layers.groups,
173
            layers: layers.flat
174
        }, {
175
            node: nodeId,
176
            index,
177
            groupId
178
        });
UNCOV
179
        if (sortedGroups) {
×
UNCOV
180
            handleOnChange(sortedGroups.layers, sortedGroups.groups);
×
181
        }
182
    }
183
    function handleUpdateNode(nodeId, nodeType, options) {
184
        onChangeNode(nodeId, nodeType, options);
9✔
185
        const updatedNode = changeNodeConfiguration({
9✔
186
            groups: layers.groups,
187
            layers: layers.flat
188
        }, {
189
            node: nodeId,
190
            nodeType,
191
            options
192
        });
193
        handleOnChange(updatedNode.layers, updatedNode.groups);
9✔
194
    }
195
    return (
36✔
196
        <ControlledTOC
197
            className={className}
198
            theme={theme}
199
            tree={tree}
200
            filterText={filterText}
201
            selectedNodes={selectedNodesIdsToObject(selectedNodes, layers.flat, tree)}
202
            onSelectNode={onSelectNode}
203
            onSort={handleOnSort}
204
            onChange={handleUpdateNode}
205
            config={{
206
                ...config,
207
                layerOptions: {
208
                    ...config?.layerOptions,
209
                    legendOptions: {
210
                        ...config?.layerOptions?.legendOptions,
211
                        mapSize: map?.size,
212
                        mapBbox: map?.bbox,
213
                        projection: map?.projection
214
                    }
215
                }
216
            }}
217
            nodeItems={nodeItems}
218
            nodeToolItems={nodeToolItems}
219
            nodeContentItems={nodeContentItems}
220
            singleDefaultGroup={singleDefaultGroup}
221
        />
222
    );
223
}
224

225
export default TOC;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc