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

geosolutions-it / MapStore2 / 14534587011

18 Apr 2025 11:41AM UTC coverage: 76.977% (-0.02%) from 76.993%
14534587011

Pull #11037

github

web-flow
Merge f22d700f6 into 48d6a1a15
Pull Request #11037: Remove object assign pollyfills

30792 of 47937 branches covered (64.23%)

446 of 556 new or added lines in 94 files covered. (80.22%)

8 existing lines in 4 files now uncovered.

38277 of 49725 relevant lines covered (76.98%)

36.07 hits per line

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

81.58
/web/client/plugins/BurgerMenu.jsx
1
/*
2
 * Copyright 2016, 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
import React from 'react';
9
import PropTypes from 'prop-types';
10
import { connect } from 'react-redux';
11
import { DropdownButton, Glyphicon, MenuItem } from 'react-bootstrap';
12

13
import tooltip from "../components/misc/enhancers/tooltip";
14
import ToolsContainer from './containers/ToolsContainer';
15
import Message from './locale/Message';
16
import { createPlugin } from '../utils/PluginsUtils';
17
import {setControlProperty} from "../actions/controls";
18
import {burgerMenuSelector} from "../selectors/controls";
19

20
import './burgermenu/burgermenu.css';
21

22
const TDropdownButton = tooltip(DropdownButton);
1✔
23
const Container = ({children, ...props}) => (
1✔
24
    <TDropdownButton
4✔
25
        noCaret
26
        pullRight
27
        bsStyle="primary"
28
        title={<Glyphicon glyph="menu-hamburger"/>}
29
        tooltipId="options"
30
        tooltipPosition="bottom"
31
        {...props}
32
    >
33
        {children}
34
    </TDropdownButton>
35
);
36

37
const InnerContainer = ({children, ...props}) => (
1✔
38
    <div {...props}>
2✔
39
        {children}
40
    </div>
41
);
42

43
const AnchorElement = ({children, href, target, onClick}) => (
1✔
44
    <a href={href} target={target} onClick={onClick}>{children}</a>
6✔
45
);
46

47
const BurgerMenuMenuItem = ({
1✔
48
    active,
49
    onClick,
50
    glyph,
51
    labelId,
52
    className
53
}) => {
54
    return (
×
55
        <MenuItem
56
            active={active}
57
            className={className}
58
            onClick={() => onClick(!active)}
×
59
        >
60
            <Glyphicon glyph={glyph}/><Message msgId={labelId}/>
61
        </MenuItem>
62
    );
63
};
64

65
class BurgerMenu extends React.Component {
66
    static propTypes = {
1✔
67
        id: PropTypes.string,
68
        dispatch: PropTypes.func,
69
        items: PropTypes.array,
70
        title: PropTypes.node,
71
        onItemClick: PropTypes.func,
72
        onInit: PropTypes.func,
73
        onDetach: PropTypes.func,
74
        controls: PropTypes.object,
75
        panelStyle: PropTypes.object,
76
        panelClassName: PropTypes.string,
77
        className: PropTypes.string
78
    };
79

80
    static contextTypes = {
1✔
81
        messages: PropTypes.object,
82
        router: PropTypes.object
83
    };
84

85
    static defaultProps = {
1✔
86
        id: "mapstore-burger-menu",
87
        className: 'square-button',
88
        items: [],
89
        onItemClick: () => {},
90
        title: <MenuItem header><Message msgId="options"/></MenuItem>,
91
        controls: [],
92
        panelStyle: {
93
            minWidth: "300px",
94
            right: "52px",
95
            zIndex: 100,
96
            position: "absolute",
97
            overflow: "auto"
98
        },
99
        panelClassName: "toolbar-panel",
100
        onInit: () => {},
101
        onDetach: () => {}
102
    };
103

104
    componentDidMount() {
105
        const { onInit } = this.props;
2✔
106
        onInit();
2✔
107
    }
108

109
    componentDidUpdate(prevProps) {
110
        const { onInit } = this.props;
2✔
111
        prevProps.isActive === false && onInit();
2!
112
    }
113

114
    componentWillUnmount() {
115
        const { onDetach } = this.props;
2✔
116
        onDetach();
2✔
117
    }
118

119

120
    getPanels = items => {
2✔
121
        return items.filter((item) => item.panel)
8✔
NEW
122
            .map((item) => Object.assign({}, item, {panel: item.panel === true ? item.plugin : item.panel})).concat(
×
123
                items.filter((item) => item.tools).reduce((previous, current) => {
8✔
124
                    return previous.concat(
×
125
                        current.tools.map((tool, index) => ({
×
126
                            name: current.name + index,
127
                            panel: tool,
128
                            cfg: current.cfg.toolsCfg ? current.cfg.toolsCfg[index] : {}
×
129
                        }))
130
                    );
131
                }, [])
132
            );
133
    };
134

135
    getTools = () => {
2✔
136
        const processChildren = (children = []) => {
4✔
137
            const childTools = children.map(child => ({
8✔
138
                ...child,
139
                ...processChildren(child.children)
140
            })).sort((a, b) => a.position - b.position);
×
141
            const innerProps = {
8✔
142
                container: InnerContainer,
143
                containerWrapperStyle: {position: 'static'},
144
                className: 'burger-menu-submenu',
145
                toolStyle: 'primary',
146
                activeStyle: 'default',
147
                stateSelector: 'burgermenu',
148
                eventSelector: 'onSelect',
149
                tool: MenuItem,
150
                // tool: ({ children: c, ...props }) => <MenuItem componentClass={AnchorElement} {...props} >{c}</MenuItem>,
151
                panelStyle: this.props.panelStyle,
152
                panelClassName: this.props.panelClassName
153
            };
154
            return children.length > 0 ? {
8✔
155
                containerWrapperStyle: {position: 'static'},
156
                style: {position: 'relative'},
157
                childTools,
158
                childPanels: this.getPanels(children),
159
                innerProps
160
            } : {};
161
        };
162

163
        return [
4✔
164
            {
165
                element:
166
                    <span key="burger-menu-title">
167
                        {this.props.title}
168
                    </span>
169
            },
170
            ...this.props.items.map(item => ({
6✔
171
                ...item,
172
                ...processChildren(item.children)
173
            })).sort((a, b) => a.position - b.position)
2✔
174
        ];
175
    };
176

177
    render() {
178
        return (
4✔
179
            <ToolsContainer id={this.props.id} className={this.props.className}
180
                container={Container}
181
                toolStyle="primary"
182
                activeStyle="default"
183
                stateSelector="burgermenu"
184
                eventSelector="onSelect"
185
                tool={({ children: c, ...props }) => <MenuItem componentClass={AnchorElement} {...props} >{c}</MenuItem>}
6✔
186
                tools={this.getTools()}
187
                panels={this.getPanels(this.props.items)}
188
                panelStyle={this.props.panelStyle}
189
                panelClassName={this.props.panelClassName}
190
                toolComponent={BurgerMenuMenuItem}
191
            />);
192
    }
193
}
194

195
const BurgerMenuPlugin = connect((state) =>({
4✔
196
    controls: state.controls,
197
    active: burgerMenuSelector(state)
198
}), {
199
    onInit: setControlProperty.bind(null, 'burgermenu', 'enabled', true),
200
    onDetach: setControlProperty.bind(null, 'burgermenu', 'enabled', false)
201
})(BurgerMenu);
202

203
/**
204
 * Menu button that can contain other plugins entries.
205
 * Usually rendered inside {@link #plugins.OmniBar|plugins.OmniBar}
206
 * You can render an item inside burger menu by adding the following to the `containers` entry of your plugin.
207
 * It is a wrapper for `ToolsContainer` so all the properties of the tools of {@link #plugins.containers.ToolContainer|ToolContainer} can be used here (action, selector ...).
208
 * ```
209
 * BurgerMenu: {
210
 *      name: 'my_entry', // name of your entry
211
 *      position: 1000, // the position you want
212
 *      text: <Message msgId="details.title"/>, // the text to show in the menu entry
213
 *      icon: <Glyphicon glyph="sheet"/>, // the icon to use
214
 *      // the following are some examples from ToolContainer property
215
 *      action: openDetailsPanel, // the function to call when the menu entry is clicked
216
 *      selector: a function that can return some additional properties for the menu entry. Is used typically to hide the menu returning, under certain contdition `{ style: {display: "none"} }`
217
 *  },
218
 * ```
219
 * @name BurgerMenu
220
 * @class
221
 * @memberof plugins
222
 */
223
export default createPlugin(
224
    'BurgerMenu',
225
    {
226
        component: BurgerMenuPlugin,
227
        containers: {
228
            OmniBar: {
229
                name: "burgermenu",
230
                position: 2,
231
                tool: true,
232
                priority: 1
233
            },
234
            BrandNavbar: {
235
                position: 8,
236
                priority: 2,
237
                target: 'right-menu',
238
                Component: connect(() => ({ id: 'ms-burger-menu', className: 'square-button-md' }))(BurgerMenuPlugin)
×
239
            }
240
        }
241
    }
242
);
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