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

geosolutions-it / MapStore2 / 19927888806

04 Dec 2025 10:45AM UTC coverage: 76.676% (-0.002%) from 76.678%
19927888806

Pull #11715

github

web-flow
Update User Guide - Isochrone plugin (#11769)

* add_11665

* Update docs/user-guide/isochrone.md

* Update docs/user-guide/isochrone.md

---------

Co-authored-by: Suren <dsuren1@gmail.com>
Pull Request #11715: Fix the dashboard save, legend dependency and maximize issue

32310 of 50262 branches covered (64.28%)

35 of 41 new or added lines in 5 files covered. (85.37%)

27 existing lines in 6 files now uncovered.

40211 of 52443 relevant lines covered (76.68%)

37.92 hits per line

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

43.9
/web/client/components/dashboard/WidgetViewWrapper.jsx
1
import React from 'react';
2
import WidgetsView from '../widgets/view/WidgetsView';
3
import ViewSwitcher from './ViewSwitcher';
4
import uuidv1 from 'uuid/v1';
5
import { getNextAvailableName } from '../../utils/WidgetsUtils';
6
import ConfigureView from './ConfigureView';
7
import FlexBox from '../layout/FlexBox';
8

9
const WidgetViewWrapper = props => {
1✔
10
    const { layouts = [], onLayoutViewReplace, selectedLayoutId, onLayoutViewSelected, active, setActive, widgets = [], onWidgetsReplace, canEdit } = props;
3!
11

12
    const getSelectedLayout = () => {
3✔
13
        if (Array.isArray(layouts)) {
3!
14
            return layouts.find(l => l?.id === selectedLayoutId) || {};
3✔
15
        }
16
        // fallback for old object format
NEW
17
        return layouts;
×
18
    };
19

20
    const handleSelectLayout = (id) => {
3✔
UNCOV
21
        onLayoutViewSelected(id);
×
22
    };
23

24
    // strip out "properties" before passing
25
    const selectedLayout = getSelectedLayout();
3✔
26
    const { id, name, color, order, ...layoutForWidgets } = selectedLayout;
3✔
27

28
    const filteredProps = {...props};
3✔
29
    if (props.widgets) {
3!
30
        filteredProps.widgets = props.widgets.filter(widget => widget.layoutId === selectedLayoutId);
3✔
31
    }
32

33
    const handleAddLayout = () => {
3✔
UNCOV
34
        const newLayout = {
×
35
            id: uuidv1(),
36
            name: getNextAvailableName(layouts),
37
            color: null,
38
            md: [],
39
            xxs: []
40
        };
UNCOV
41
        const finalLayout = [...layouts, newLayout];
×
UNCOV
42
        onLayoutViewReplace?.(finalLayout);
×
UNCOV
43
        onLayoutViewSelected(newLayout.id);
×
44
    };
45

46
    const handleRemoveLayout = (layoutId) => {
3✔
UNCOV
47
        const updatedLayouts = layouts.filter(layout => layout.id !== layoutId);
×
UNCOV
48
        onLayoutViewReplace(updatedLayouts);
×
UNCOV
49
        onLayoutViewSelected(updatedLayouts?.[updatedLayouts.length - 1]?.id);
×
50

51
        const updatedWidgets = widgets.filter(w => w.layoutId !== layoutId);
×
52
        onWidgetsReplace(updatedWidgets);
×
53
    };
54

55
    const handleMoveLayout = (layoutId, direction) => {
3✔
UNCOV
56
        const index = layouts.findIndex(layout => layout.id === layoutId);
×
UNCOV
57
        if (index === -1) return; // Layout not found
×
58

59
        // Clone the array to avoid mutating state directly
60
        const updatedLayouts = [...layouts];
×
61

62
        if (direction === "left" && index > 0) {
×
63
            // Swap with the previous layout
UNCOV
64
            [updatedLayouts[index - 1], updatedLayouts[index]] = [updatedLayouts[index], updatedLayouts[index - 1]];
×
UNCOV
65
        } else if (direction === "right" && index < updatedLayouts.length - 1) {
×
66
            // Swap with the next layout
67
            [updatedLayouts[index], updatedLayouts[index + 1]] = [updatedLayouts[index + 1], updatedLayouts[index]];
×
68
        }
UNCOV
69
        onLayoutViewReplace(updatedLayouts);
×
70
    };
71

72
    const handleToggle = () => setActive(false);
3✔
73

74
    const handleSave = (data) => {
3✔
75
        const updatedLayouts = layouts.map(layout => layout.id === id
×
76
            ? { ...layout, name: data.name, color: data.color }
77
            : layout
78
        );
UNCOV
79
        onLayoutViewReplace(updatedLayouts);
×
80
        setActive(false);
×
81
    };
82

83
    const layoutViews = Array.isArray(layouts) ? layouts : [layouts];
3!
84

85
    return (
3✔
86
        <FlexBox column classNames={["_relative", "_fill"]}>
87
            <FlexBox.Fill classNames={["_relative", "_overflow-auto"]}>
88
                <WidgetsView
89
                    {...filteredProps}
90
                    layouts={layoutForWidgets} // only selected layout without properties
91
                />
92
            </FlexBox.Fill>
93
            {(canEdit || layoutViews.length > 1) && (
6!
94
                <ViewSwitcher
95
                    layouts={layoutViews}
96
                    selectedLayoutId={selectedLayoutId}
97
                    onSelect={handleSelectLayout}
98
                    onAdd={handleAddLayout}
99
                    onRemove={handleRemoveLayout}
100
                    onMove={handleMoveLayout}
UNCOV
101
                    onConfigure={() => setActive(true)}
×
102
                    canEdit={canEdit}
103
                />
104
            )}
105
            <ConfigureView
106
                active={active}
107
                onToggle={handleToggle}
108
                onSave={handleSave}
109
                name={name}
110
                color={color}
111
            />
112
        </FlexBox>
113
    );
114
};
115

116
export default WidgetViewWrapper;
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