UNPKG

qwc2

Version:
308 lines (306 loc) 15.7 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /** * Copyright 2016-2024 Sourcepole AG * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ import React from 'react'; import { connect } from 'react-redux'; import classnames from 'classnames'; import { remove as removeDiacritics } from 'diacritics'; import PropTypes from 'prop-types'; import { toggleFullscreen } from '../actions/display'; import { openExternalUrl, setTopbarHeight } from '../actions/windows'; import { Swipeable } from '../components/Swipeable'; import ConfigUtils from '../utils/ConfigUtils'; import LocaleUtils from '../utils/LocaleUtils'; import { registerSearchProvider, SearchResultType, unregisterSearchProvider } from '../utils/SearchProviders'; import ThemeUtils from '../utils/ThemeUtils'; import './style/TopBar.css'; /** * Top bar, containing the logo, searchbar, task buttons and app menu. */ var TopBar = /*#__PURE__*/function (_React$Component) { function TopBar() { var _this; _classCallCheck(this, TopBar); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, TopBar, [].concat(args)); _defineProperty(_this, "state", { allowedMenuItems: [], allowedToolbarItems: [] }); _defineProperty(_this, "openUrl", function (url, target, title, icon) { if (target === "iframe") { target = ":iframedialog:externallinkiframe"; } _this.props.openExternalUrl(url, target, { title: title, icon: icon }); }); _defineProperty(_this, "storeHeight", function (el) { if (el) { _this.props.setTopbarHeight(el.clientHeight); } }); _defineProperty(_this, "searchTasks", function (text, searchParams, callback) { var filter = new RegExp(removeDiacritics(text).replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"), "i"); var results = []; _this.searchTaskGroup(results, filter, _this.state.allowedMenuItems); if (results.length > 0) { callback({ results: [{ id: "tasks", title: LocaleUtils.tr("search.tasks"), type: SearchResultType.TASK, items: results }] }); } else { callback({ results: [] }); } }); _defineProperty(_this, "searchTaskGroup", function (results, filter, group) { group.forEach(function (item) { if (item.subitems) { _this.searchTaskGroup(results, filter, item.subitems); } else { var label = item.title ? LocaleUtils.tr(item.title) : LocaleUtils.tr("appmenu.items." + item.key + (item.mode || "")); if (removeDiacritics(label).match(filter)) { results.push({ id: "tasks:" + results.length, text: label, task: item }); } } }); }); return _this; } _inherits(TopBar, _React$Component); return _createClass(TopBar, [{ key: "componentDidMount", value: function componentDidMount() { this.setState({ allowedToolbarItems: ThemeUtils.allowedItems(this.props.toolbarItems, this.props.currentTheme), allowedMenuItems: ThemeUtils.allowedItems(this.props.menuItems, this.props.currentTheme) }); if (this.props.registerTaskSearchProvider) { registerSearchProvider("tasksearch", { label: LocaleUtils.tr("search.tasks"), onSearch: this.searchTasks }); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this.props.registerTaskSearchProvider) { unregisterSearchProvider("tasksearch"); } } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { if (this.props.currentTheme !== prevProps.currentTheme) { this.setState({ allowedToolbarItems: ThemeUtils.allowedItems(this.props.toolbarItems, this.props.currentTheme), allowedMenuItems: ThemeUtils.allowedItems(this.props.menuItems, this.props.currentTheme) }); } } }, { key: "render", value: function render() { var _this2 = this; var logo; var assetsPath = ConfigUtils.getAssetsPath(); var isMobile = ConfigUtils.isMobile(); if (isMobile) { logo = assetsPath + "/img/logo-mobile." + this.props.logoFormat; } else { logo = assetsPath + "/img/logo." + this.props.logoFormat; } var classes = classnames({ TopBar: true, mobile: isMobile, fullscreen: this.props.fullscreen }); var logoEl = /*#__PURE__*/React.createElement("img", { className: "topbar-logo", src: this.props.logoSrc || logo }); if (this.props.logoUrl) { logoEl = /*#__PURE__*/React.createElement("a", { href: this.props.logoUrl, rel: "noreferrer", target: "_blank" }, logoEl); } // Convert legacy minScale option to minScaleDenom var searchOptions = _objectSpread(_objectSpread({}, TopBar.defaultProps.searchOptions), this.props.searchOptions); searchOptions.minScaleDenom = searchOptions.minScaleDenom || searchOptions.minScale; delete searchOptions.minScale; // Menu compact only available for desktop client var menuCompact = !isMobile ? this.props.appMenuCompact : false; // Keep menu open when appMenu is in compact mode (Visible on Hover) var keepMenuOpen = menuCompact; // Menu should be visible on startup when appMenu is in compact mode (Visible on Hover) var showOnStartup = this.props.appMenuVisibleOnStartup || menuCompact; var style = { marginLeft: this.props.mapMargins.outerLeft + 'px', marginRight: this.props.mapMargins.outerRight + 'px' }; return /*#__PURE__*/React.createElement(Swipeable, { onSwipedDown: function onSwipedDown() { return _this2.props.toggleFullscreen(false); }, onSwipedUp: function onSwipedUp() { return _this2.props.toggleFullscreen(true); } }, /*#__PURE__*/React.createElement("div", { className: classes, ref: this.storeHeight, style: style }, logoEl, /*#__PURE__*/React.createElement("div", { className: "topbar-center-span" }, this.props.components.Search ? /*#__PURE__*/React.createElement("div", { className: "topbar-search-container" }, /*#__PURE__*/React.createElement(this.props.components.Search, { searchOptions: searchOptions })) : null, this.props.components.Toolbar ? /*#__PURE__*/React.createElement(this.props.components.Toolbar, { openExternalUrl: this.openUrl, toolbarItems: this.state.allowedToolbarItems, toolbarItemsShortcutPrefix: this.props.toolbarItemsShortcutPrefix }) : null), this.props.components.AppMenu && !this.props.appMenuHidden ? /*#__PURE__*/React.createElement(this.props.components.AppMenu, { appMenuClearsTask: this.props.appMenuClearsTask, appMenuShortcut: this.props.appMenuShortcut, buttonLabel: LocaleUtils.tr("appmenu.menulabel"), keepMenuOpen: keepMenuOpen, menuCompact: menuCompact, menuItems: this.state.allowedMenuItems, openExternalUrl: this.openUrl, showFilterField: this.props.appMenuFilterField, showOnStartup: showOnStartup }) : null, this.props.components.FullscreenSwitcher ? /*#__PURE__*/React.createElement(this.props.components.FullscreenSwitcher, null) : null)); } }]); }(React.Component); _defineProperty(TopBar, "propTypes", { /** Whether opening the app menu clears the active task. */ appMenuClearsTask: PropTypes.bool, /** Whether show an appMenu compact (menu visible on icons hover) - Only available for desktop client. */ appMenuCompact: PropTypes.bool, /** Whether to display the filter field in the app menu. */ appMenuFilterField: PropTypes.bool, /** Whether to hide the app menu (useful primarely as a theme specific setting). */ appMenuHidden: PropTypes.bool, /** The shortcut for tiggering the app menu, i.e. alt+shift+m. */ appMenuShortcut: PropTypes.string, /** Whether to open the app menu on application startup. */ appMenuVisibleOnStartup: PropTypes.bool, components: PropTypes.object, currentTheme: PropTypes.object, fullscreen: PropTypes.bool, /** The logo file format. */ logoFormat: PropTypes.string, /** The logo image URL if a different source than the default `assets/img/logo.<ext>` and `assets/img/logo-mobile.<ext>` is desired. */ logoSrc: PropTypes.string, /** The hyperlink to open when the logo is clicked. */ logoUrl: PropTypes.string, mapMargins: PropTypes.object, /** The menu items. Refer to the corresponding chapter of the viewer documentation and the sample config.json. */ menuItems: PropTypes.array, openExternalUrl: PropTypes.func, /** Whether to register a search provider which allows searching menu tasks through the global search field. */ registerTaskSearchProvider: PropTypes.bool, /** Options passed down to the search component. */ searchOptions: PropTypes.shape({ /** Whether to show the search filter widget. */ allowSearchFilters: PropTypes.bool, /** Whether to focus the search field on startup. */ focusOnStartup: PropTypes.bool, /** Whether to hide the result labels on the map. */ hideResultLabels: PropTypes.bool, /** The style used for highlighting search result geometries. */ highlightStyle: PropTypes.shape({ /* Stroke color rgba array, i.e. [255, 0, 0, 0.5] */ strokeColor: PropTypes.array, /* Stroke width */ strokeWidth: PropTypes.number, /* Stroke dash/gap pattern array. Empty for solid line. */ strokeDash: PropTypes.array, /* Fill color rgba array, i.e. [255, 0, 0, 0.33] */ fillColor: PropTypes.array }), /** Minimum scale denominator when zooming to search result. */ minScaleDenom: PropTypes.number, /** Result count limit which is passed to the search provider. */ resultLimit: PropTypes.number, /** Whether to collapse search sections by default. */ sectionsDefaultCollapsed: PropTypes.bool, /** Whether to show a highlight marker in the center of the search result geometry. */ showHighlightMarker: PropTypes.bool, /** Whether to show the layer tree after selecting a theme result. */ showLayerAfterChangeTheme: PropTypes.bool, /** Whether to show layer results before pkaces in the result menu. */ showLayerResultsBeforePlaces: PropTypes.bool, /** Whether to replace the search text with the selected search result text. */ showResultInSearchText: PropTypes.bool, /** Whether to zoom to layer search results. */ zoomToLayers: PropTypes.bool }), setTopbarHeight: PropTypes.func, toggleFullscreen: PropTypes.func, /** The toolbar. Refer to the corresponding chapter of the viewer documentation and the sample config.json. */ toolbarItems: PropTypes.array, /** The keyboard shortcut prefix for triggering toolbar tasks. I.e. alt+shift. The task are then triggered by <prefix>+{1,2,3,...} for the 1st, 2nd, 3rd... toolbar icon. */ toolbarItemsShortcutPrefix: PropTypes.string }); _defineProperty(TopBar, "defaultProps", { searchOptions: { showHighlightMarker: true, showResultInSearchText: true, minScaleDenom: 1000 }, menuItems: [], toolbarItems: [], logoFormat: "svg" }); export default (function (components) { return connect(function (state) { return { fullscreen: state.display.fullscreen, components: components, currentTheme: state.theme.current, mapMargins: state.windows.mapMargins }; }, { toggleFullscreen: toggleFullscreen, openExternalUrl: openExternalUrl, setTopbarHeight: setTopbarHeight })(TopBar); });