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

geosolutions-it / MapStore2 / 13560354468

27 Feb 2025 06:32AM UTC coverage: 76.792% (-0.01%) from 76.806%
13560354468

push

github

web-flow
Fix #10859 Share button on new dashbaord (#10879)

31292 of 48873 branches covered (64.03%)

4 of 5 new or added lines in 3 files covered. (80.0%)

13 existing lines in 3 files now uncovered.

38842 of 50581 relevant lines covered (76.79%)

35.74 hits per line

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

68.0
/web/client/plugins/Share.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

9
import React from 'react';
10
import {connect, createPlugin} from '../utils/PluginsUtils';
11
import { Glyphicon } from 'react-bootstrap';
12
import Message from '../components/I18N/Message';
13
import { toggleControl, setControlProperty } from '../actions/controls';
14
import ConfigUtils from '../utils/ConfigUtils';
15
import {getApiUrl, getConfigUrl} from '../utils/ShareUtils';
16
import {getExtentFromViewport} from '../utils/CoordinatesUtils';
17
import { versionSelector } from '../selectors/version';
18
import shareEpics from '../epics/queryparams';
19
import SharePanel from '../components/share/SharePanel';
20
import { createSelector } from 'reselect';
21
import { mapIdSelector, mapSelector } from '../selectors/map';
22
import { currentContextSelector } from '../selectors/context';
23
import { get } from 'lodash';
24
import controls from '../reducers/controls';
25
import { changeFormat } from '../actions/mapInfo';
26
import { addMarker, hideMarker } from '../actions/search';
27
import { updateMapView } from '../actions/map';
28
import { resourceSelector as geostoryResourceSelector, updateUrlOnScrollSelector } from '../selectors/geostory';
29
import { shareSelector } from "../selectors/controls";
30
import { mapTypeSelector } from "../selectors/maptype";
31
import { dashboardResource } from '../selectors/dashboard';
32
/**
33
 * Share Plugin allows to share the current URL (location.href) in some different ways.
34
 * You can share it on socials networks(facebook,twitter,google+,linkedIn)
35
 * copying the direct link
36
 * copying the embedded code
37
 * using the QR code with mobile apps
38
 * @class
39
 * @memberof plugins
40
 * @prop {node} [title] the title of the page
41
 * @prop {string} [shareUrlRegex] reqular expression to parse the shareUrl to generate the final url, using shareUrlReplaceString
42
 * @prop {string} [shareUrlReplaceString] expression to be replaced by groups of the shareUrlRegex to get the final shareUrl to use for the iframe
43
 * @prop {object} [embedOptions] options for the iframe version of embedded share options
44
 * @prop {boolean} [embedOptions.showTOCToggle] true by default, set to false to hide the "show TOC" toggle.
45
 * @prop {boolean} [showAPI] default true, if false, hides the API entry of embed.
46
 * @prop {function} [onClose] function to call on close window event.
47
 * @prop {function} [getCount] function used to get the count for social links.
48
 * @prop {object} [cfg.advancedSettings] show advanced settings (bbox param, centerAndZoom param or home button) f.e {bbox: true, homeButton: true, centerAndZoom: true}
49
 * @prop {boolean} [cfg.advancedSettings.bbox] if true, the share url is generated with the bbox param
50
 * @prop {boolean} [cfg.advancedSettings.centerAndZoom] if true, the share url is generated with the center and zoom params
51
 * @prop {string} [cfg.advancedSettings.defaultEnabled] the value can either be "bbox", "centerAndZoom", "markerAndZoom". Based on the value, the checkboxes corresponding to the param will be enabled by default
52
 * @prop {string} [cfg.advancedSettings.hideInTab] based on the value (i.e value can be "link" or "social" or "embed"), the advancedSettings is hidden in the tab value specified
53
 * For example this will display marker, coordinates and zoom fields with the marker enabled by default generating share url with respective params
54
 * ```
55
 * "cfg": {
56
 *    "advancedSettings" : {
57
 *       "bbox": true,
58
 *       "centerAndZoom": true,
59
 *       "defaultEnabled": "markerAndZoom"
60
 *    }
61
 *  }
62
 * ```
63
 */
64

65
const Share = connect(createSelector([
1✔
66
    shareSelector,
67
    versionSelector,
68
    mapSelector,
69
    mapTypeSelector,
70
    currentContextSelector,
71
    state => get(state, 'controls.share.settings', {}),
14✔
72
    (state) => state.mapInfo && state.mapInfo.formatCoord || ConfigUtils.getConfigProp("defaultCoordinateFormat"),
14✔
73
    state => state.search && state.search.markerPosition || {},
14✔
74
    updateUrlOnScrollSelector,
75
    state => get(state, 'map.present.viewerOptions'),
14✔
76
    state => {
77
        const map = mapSelector(state);
14✔
78
        // get the camera position available in the 3D mode
79
        const cameraPosition = map?.viewerOptions?.cameraPosition;
14✔
80
        const center = cameraPosition
14!
81
            ? [cameraPosition.longitude, cameraPosition.latitude]
82
            : map?.center;
83
        return center && ConfigUtils.getCenter(center);
14✔
84
    },
85
    state => get(state, 'controls.share.resource.shareUrl') || location.href,
14✔
86
    state => get(state, 'controls.share.resource.categoryName')
14✔
87
], (isVisible, version, map, mapType, context, settings, formatCoords, point, isScrollPosition, viewerOptions, center, shareUrl, categoryName) => ({
14✔
88
    isVisible,
89
    shareUrl,
90
    shareApiUrl: getApiUrl(shareUrl),
91
    shareConfigUrl: getConfigUrl(shareUrl, ConfigUtils.getConfigProp('geoStoreUrl')),
92
    version,
93
    viewerOptions,
94
    mapType,
95
    bbox: isVisible && map && map.bbox && getExtentFromViewport(map.bbox),
44✔
96
    center,
97
    zoom: map && map.zoom,
28✔
98
    showAPI: !context,
99
    embedOptions: {
100
        showTOCToggle: !context
101
    },
102
    settings,
103
    advancedSettings: {
104
        bbox: true,
105
        centerAndZoom: true
106
    },
107
    formatCoords: formatCoords,
108
    point,
109
    isScrollPosition,
110
    categoryName})), {
111
    onClose: toggleControl.bind(null, 'share', null),
112
    hideMarker,
113
    updateMapView,
114
    onUpdateSettings: setControlProperty.bind(null, 'share', 'settings'),
115
    onChangeFormat: changeFormat,
116
    addMarker: addMarker,
117
    onClearShareResource: setControlProperty.bind(null, 'share', 'resource', undefined)
118
})(({ categoryName, ...props }) => {
119
    const categoryCfg = props[categoryName];
14✔
120
    return <SharePanel {...props} {...categoryCfg} />;
14✔
121
});
122

123
const ActionCardShareButton = connect(
1✔
124
    () => ({}),
×
125
    {
126
        onToggle: toggleControl.bind(null, 'share', null),
127
        setShareResource: setControlProperty.bind(null, 'share', 'resource')
128
    }
129
)(({
130
    resource,
131
    viewerUrl,
132
    onToggle,
133
    setShareResource,
134
    component
135
}) => {
136
    const Component = component;
×
137
    function handleToggle() {
138
        const baseURL = location && (location.origin + location.pathname);
×
139
        const shareUrl = baseURL + viewerUrl;
×
140
        setShareResource({
×
141
            shareUrl,
142
            categoryName: (resource?.category?.name || '').toLowerCase()
×
143
        });
144
        onToggle();
×
145
    }
146
    return (<Component
×
147
        iconType="glyphicon"
148
        glyph="share-alt"
149
        labelId="share.title"
150
        onClick={handleToggle}
151
    />);
152
});
153

154
const shareButtonSelector = createSelector([
1✔
155
    mapIdSelector,
156
    dashboardResource,
157
    geostoryResourceSelector
158
], (mapId, dashboard, geostory) => {
NEW
159
    return {
×
160
        style: mapId || dashboard?.id || geostory?.id ? { } : { display: 'none' }
×
161
    };
162
});
163

164
const SharePlugin = createPlugin('Share', {
1✔
165
    component: Share,
166
    containers: {
167
        BurgerMenu: {
168
            name: 'share',
169
            position: 1000,
170
            priority: 2,
171
            doNotHide: true,
172
            text: <Message msgId="share.title"/>,
173
            tooltip: "share.tooltip",
174
            icon: <Glyphicon glyph="share-alt"/>,
175
            action: toggleControl.bind(null, 'share', null),
176
            selector: shareButtonSelector
177
        },
178
        SidebarMenu: {
179
            name: 'share',
180
            position: 1000,
181
            priority: 1,
182
            doNotHide: true,
183
            tooltip: "share.tooltip",
184
            text: <Message msgId="share.title"/>,
185
            icon: <Glyphicon glyph="share-alt"/>,
186
            action: toggleControl.bind(null, 'share', null),
187
            toggle: true,
188
            selector: shareButtonSelector
189
        },
190
        Toolbar: {
191
            name: 'share',
192
            alwaysVisible: true,
193
            position: 2,
194
            priority: 0,
195
            doNotHide: true,
196
            tooltip: "share.title",
197
            icon: <Glyphicon glyph="share-alt"/>,
198
            action: toggleControl.bind(null, 'share', null),
199
            selector: shareButtonSelector
200
        },
201
        ResourcesGrid: {
202
            priority: 1,
203
            target: 'card-options',
204
            doNotHide: true,
205
            Component: ActionCardShareButton,
206
            position: 1
207
        }
208
    },
209
    epics: shareEpics,
210
    reducers: { controls }
211
});
212

213
export default SharePlugin;
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