Skip to content

Commit 4108074

Browse files
congchen1101cc1101
andauthored
fix(TOC): ensure groups without direct layers are restored in correct position - Fixed an issue where newly created groups without direct child layers, but containing subgroups with layers, were not displayed in the correct position after saving - Added test cases to cover groups with only subgroups On behalf of DB Systel GmbH Co-authored-by: CongChen <cong.chen.mz@gmail.com>
1 parent 9d999b9 commit 4108074

File tree

2 files changed

+114
-1
lines changed

2 files changed

+114
-1
lines changed

web/client/utils/LayersUtils.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,38 @@ export const normalizeMap = (rawMap = {}) =>
467467
* @return function that filter by group
468468
*/
469469
export const belongsToGroup = (gid) => l => (l.group || DEFAULT_GROUP_ID) === gid || (l.group || "").indexOf(`${gid}.`) === 0;
470+
471+
/**
472+
* Retrieves the store index of a group from a list of map layers.
473+
*
474+
* @param {Object} cur - The current group object whose store index is being searched.
475+
* @param {Array} mapLayers - An array of layer objects, each containing a `group` and `storeIndex` property.
476+
* @returns {number} - The store index of the group if found, otherwise `-1`.
477+
*/
478+
const getGroupStoreIndex = (cur, mapLayers) => {
479+
// Create a map for quick lookup of group to storeIndex
480+
const groupMap = new Map(mapLayers.map(el => [el.group, el.storeIndex]));
481+
// Check direct match
482+
if (groupMap.has(cur.id)) {
483+
return groupMap.get(cur.id);
484+
}
485+
// Checks if a layer belongs to the descendants of the current group.
486+
// If yes, return the storeIndex of the first matching layer as the storeIndex for the current group.
487+
// Ensures that groups without direct child layers are assigned a storeIndex
488+
// preventing them from always being placed at the end of the TOC.
489+
for (const el of mapLayers) {
490+
const groupParts = el.group.split('.');
491+
for (let i = groupParts.length - 1; i > 0; i--) {
492+
const parentGroup = groupParts.slice(0, i).join('.');
493+
if (parentGroup === cur.id) {
494+
return el.storeIndex;
495+
}
496+
}
497+
}
498+
// Return -1 if no match is found
499+
return -1;
500+
};
501+
470502
export const getLayersByGroup = (configLayers, configGroups) => {
471503
let i = 0;
472504
let mapLayers = configLayers.map((layer) => Object.assign({}, layer, {storeIndex: i++}));
@@ -488,7 +520,7 @@ export const getLayersByGroup = (configLayers, configGroups) => {
488520
group.nodes = getLayersId(groupId, mapLayers).concat(group.nodes)
489521
.reduce((arr, cur) => {
490522
isObject(cur)
491-
? arr.push({node: cur, order: mapLayers.find((el) => el.group === cur.id)?.storeIndex})
523+
? arr.push({node: cur, order: getGroupStoreIndex(cur, mapLayers)})
492524
: arr.push({node: cur, order: mapLayers.find((el) => el.id === cur)?.storeIndex});
493525
return arr;
494526
}, []).sort((a, b) => b.order - a.order).map(e => e.node);

web/client/utils/__tests__/LayersUtils-test.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,87 @@ describe('LayersUtils', () => {
248248
]);
249249
});
250250

251+
it('getLayersByGroup should return correctly ordered groups even without direct child layers', () => {
252+
// Group Default.root.test does not have direct child layers, but it has child groups
253+
const groups = [
254+
{id: 'Default'},
255+
{id: 'Default.root.test.childGroup001'},
256+
{id: 'Default.root.test.childGroup002'},
257+
{id: 'Default.root.test'},
258+
{id: 'Default.root.custom'},
259+
{id: 'Default.root'}
260+
];
261+
const layers = [
262+
{id: 'layer007', group: 'Default.root'},
263+
{id: 'layer006', group: 'Default.root'},
264+
{id: 'layer005', group: 'Default.root.custom'},
265+
{id: 'layer004', group: 'Default.root.test.childGroup002'},
266+
{id: 'layer003', group: 'Default.root.test.childGroup001'},
267+
{id: 'layer002', group: 'Default.root'},
268+
{id: 'layer001', group: 'Default.root'}
269+
];
270+
271+
const result = LayersUtils.getLayersByGroup(layers, groups);
272+
const expectedGroups = [
273+
{
274+
"expanded": true,
275+
"id": "Default",
276+
"name": "Default",
277+
"nodes": [
278+
{
279+
"expanded": true,
280+
"id": "Default.root",
281+
"name": "root",
282+
"nodes": [
283+
"layer001",
284+
"layer002",
285+
{
286+
"expanded": true,
287+
"id": "Default.root.test",
288+
"name": "test",
289+
"nodes": [
290+
{
291+
"expanded": true,
292+
"id": "Default.root.test.childGroup001",
293+
"name": "childGroup001",
294+
"nodes": [
295+
"layer003"
296+
],
297+
"title": "childGroup001"
298+
},
299+
{
300+
"expanded": true,
301+
"id": "Default.root.test.childGroup002",
302+
"name": "childGroup002",
303+
"nodes": [
304+
"layer004"
305+
],
306+
"title": "childGroup002"
307+
}
308+
],
309+
"title": "test"
310+
},
311+
{
312+
"expanded": true,
313+
"id": "Default.root.custom",
314+
"name": "custom",
315+
"nodes": [
316+
"layer005"
317+
],
318+
"title": "custom"
319+
},
320+
"layer006",
321+
"layer007"
322+
],
323+
"title": "root"
324+
}
325+
],
326+
"title": "Default"
327+
}
328+
];
329+
expect(result).toEqual(expectedGroups);
330+
});
331+
251332
it('deep change in nested group', () => {
252333

253334
const nestedGroups = [

0 commit comments

Comments
 (0)