qwc2 2025.9.16 → 2025.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/PluginsContainer.js +2 -2
- package/components/style/PluginsContainer.css +30 -0
- package/package.json +1 -1
- package/plugins/Authentication.js +2 -2
- package/plugins/MapLegend.js +1 -1
- package/plugins/ThemeSwitcher.js +2 -2
- package/plugins/style/Authentication.css +1 -14
- package/plugins/style/ThemeSwitcher.css +4 -0
- package/utils/ThemeUtils.js +1 -1
|
@@ -5,10 +5,10 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
5
5
|
*
|
|
6
6
|
* This source code is licensed under the BSD-style license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
|
-
*/import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import ConfigUtils from"../utils/ConfigUtils";import PluginStore from"../utils/PluginStore";import ProcessNotifications from"./ProcessNotifications";import WindowManager from"./WindowManager";import"./style/PluginsContainer.css";export var MapButtonPortalContext=/*#__PURE__*/React.createContext(null);export var MapContainerPortalContext=/*#__PURE__*/React.createContext(null);var PluginsContainer=/*#__PURE__*/function(_React$Component){function PluginsContainer(){var _this;_classCallCheck(this,PluginsContainer);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,PluginsContainer,[].concat(args));_defineProperty(_this,"state",{mapButtonsContainerRef:null,mapContainerRef:null});_defineProperty(_this,"renderPlugins",function(){var device=ConfigUtils.isMobile()?"mobile":"desktop";var plugins=PluginStore.getPlugins();return _this.props.pluginsConfig.map(function(pluginConf){var _this$props$theme,_this$props$theme2,_pluginConf$key;var Plugin=plugins[pluginConf.name+"Plugin"];if(!Plugin){return null}var themeDevicePluginConfig=((_this$props$theme=_this.props.theme)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.config)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme[device])===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.plugins)===null||_this$props$theme===void 0?void 0:_this$props$theme[pluginConf.name])||{};var themePluginConfig=((_this$props$theme2=_this.props.theme)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.config)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.plugins)===null||_this$props$theme2===void 0?void 0:_this$props$theme2[pluginConf.name])||{};var cfg=_objectSpread(_objectSpread(_objectSpread({},pluginConf.cfg||{}),themePluginConfig),themeDevicePluginConfig);return/*#__PURE__*/React.createElement(Plugin,_extends({key:(_pluginConf$key=pluginConf.key)!==null&&_pluginConf$key!==void 0?_pluginConf$key:pluginConf.name},cfg))})});_defineProperty(_this,"setupTouchEvents",function(el){if(el){el.addEventListener("touchstart",function(ev){_this.touchY=ev.targetTouches[0].clientY},{passive:false});el.addEventListener("touchmove",_this.preventOverscroll,{passive:false});var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var height=contentRectEntry.contentRect.height;el.style.setProperty("--plugins-container-height","".concat(height,"px"))}});resizeObserver.observe(el)}});_defineProperty(_this,"preventOverscroll",function(ev){if(ev.touches[0].touchType!=="direct"){// Don't do anything for stylus inputs
|
|
8
|
+
*/import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import ConfigUtils from"../utils/ConfigUtils";import PluginStore from"../utils/PluginStore";import ProcessNotifications from"./ProcessNotifications";import WindowManager from"./WindowManager";import"./style/PluginsContainer.css";export var MapButtonPortalContext=/*#__PURE__*/React.createContext(null);export var MapContainerPortalContext=/*#__PURE__*/React.createContext(null);export var AppInfosPortalContext=/*#__PURE__*/React.createContext(null);var PluginsContainer=/*#__PURE__*/function(_React$Component){function PluginsContainer(){var _this;_classCallCheck(this,PluginsContainer);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,PluginsContainer,[].concat(args));_defineProperty(_this,"state",{mapButtonsContainerRef:null,mapContainerRef:null,appInfosContainerRef:null});_defineProperty(_this,"renderPlugins",function(){var device=ConfigUtils.isMobile()?"mobile":"desktop";var plugins=PluginStore.getPlugins();return _this.props.pluginsConfig.map(function(pluginConf){var _this$props$theme,_this$props$theme2,_pluginConf$key;var Plugin=plugins[pluginConf.name+"Plugin"];if(!Plugin){return null}var themeDevicePluginConfig=((_this$props$theme=_this.props.theme)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.config)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme[device])===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.plugins)===null||_this$props$theme===void 0?void 0:_this$props$theme[pluginConf.name])||{};var themePluginConfig=((_this$props$theme2=_this.props.theme)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.config)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.plugins)===null||_this$props$theme2===void 0?void 0:_this$props$theme2[pluginConf.name])||{};var cfg=_objectSpread(_objectSpread(_objectSpread({},pluginConf.cfg||{}),themePluginConfig),themeDevicePluginConfig);return/*#__PURE__*/React.createElement(Plugin,_extends({key:(_pluginConf$key=pluginConf.key)!==null&&_pluginConf$key!==void 0?_pluginConf$key:pluginConf.name},cfg))})});_defineProperty(_this,"setupTouchEvents",function(el){if(el){el.addEventListener("touchstart",function(ev){_this.touchY=ev.targetTouches[0].clientY},{passive:false});el.addEventListener("touchmove",_this.preventOverscroll,{passive:false});var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var height=contentRectEntry.contentRect.height;el.style.setProperty("--plugins-container-height","".concat(height,"px"))}});resizeObserver.observe(el)}});_defineProperty(_this,"preventOverscroll",function(ev){if(ev.touches[0].touchType!=="direct"){// Don't do anything for stylus inputs
|
|
9
9
|
return}var scrollEvent=false;var element=ev.target;var direction=ev.targetTouches[0].clientY-_this.touchY;_this.touchY=ev.targetTouches[0].clientY;while(!scrollEvent&&element){var scrollable=element.scrollHeight>element.clientHeight;// Workaround for resizeable-window having scrollHeight > clientHeight even though it has no scrollbar
|
|
10
10
|
if(element.classList.contains("resizeable-window")){scrollable=false}if(element.type==="range"){// If it is a range element, treat it as a scroll event
|
|
11
11
|
scrollEvent=true}else if(scrollable&&element.scrollTop+element.clientHeight<element.scrollHeight&&direction<0){// User scrolls down and element is not at end of scroll
|
|
12
12
|
scrollEvent=true}else if(scrollable&&element.scrollTop>0&&direction>0){// User scrolls up and element is not at start of scroll
|
|
13
|
-
scrollEvent=true}else{element=element.parentElement}}if(!scrollEvent){ev.preventDefault()}});_defineProperty(_this,"setMapContainerRef",function(el){_this.setState({mapContainerRef:el})});_defineProperty(_this,"setButtonContainerRef",function(el){_this.setState({mapButtonsContainerRef:el});if(el){var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var width=contentRectEntry.contentRect.width;var height=contentRectEntry.contentRect.height;el.style.setProperty("--buttons-container-width","".concat(width,"px"));el.style.setProperty("--buttons-container-height","".concat(height,"px"))}});resizeObserver.observe(el);el.recomputeSpacers=function(){var slots=new Set;Array.from(el.childNodes).forEach(function(child){if(child.dataset.spacer){el.removeChild(child)}else{slots.add(child.dataset.slot)}});var maxSlot=Math.max.apply(Math,_toConsumableArray(slots));for(var i=0;i<maxSlot;++i){if(!slots.has(String(i))){var child=document.createElement("div");child.className="map-buttons-spacer";child.dataset.spacer=1;child.style.order=i;el.appendChild(child)}}}}});return _this}_inherits(PluginsContainer,_React$Component);return _createClass(PluginsContainer,[{key:"render",value:function render(){var _this$props$className;var left=this.props.mapMargins.left+this.props.mapMargins.outerLeft;var top=this.props.mapMargins.top;var right=this.props.mapMargins.right+this.props.mapMargins.outerRight;var bottom=this.props.mapMargins.bottom;var mapContainerStyle={left:"calc("+left+"px)",top:"calc(var(--topbar-height) + "+top+"px)",right:"calc("+right+"px)",bottom:"calc(var(--bottombar-height) + "+bottom+"px)"};var haveRefs=this.state.mapButtonsContainerRef&&this.state.mapContainerRef;return/*#__PURE__*/React.createElement("div",{className:"plugins-container "+((_this$props$className=this.props.className)!==null&&_this$props$className!==void 0?_this$props$className:""),ref:this.setupTouchEvents},/*#__PURE__*/React.createElement(MapButtonPortalContext.Provider,{value:this.state.mapButtonsContainerRef},/*#__PURE__*/React.createElement(MapContainerPortalContext.Provider,{value:this.state.mapContainerRef},haveRefs?this.renderPlugins():null,haveRefs?this.props.children:null)),/*#__PURE__*/React.createElement(WindowManager,null),/*#__PURE__*/React.createElement("div",{className:"map-container",ref:this.setMapContainerRef,style:mapContainerStyle},/*#__PURE__*/React.createElement(ProcessNotifications,null)),/*#__PURE__*/React.createElement("div",{className:"map-buttons-container",ref:this.setButtonContainerRef,style:mapContainerStyle}))}}])}(React.Component);_defineProperty(PluginsContainer,"propTypes",{children:PropTypes.oneOfType([PropTypes.node,PropTypes.func]),className:PropTypes.string,mapMargins:PropTypes.object,pluginsConfig:PropTypes.array,theme:PropTypes.object});export default connect(function(state){return{// Just to trigger re-render when custom plugins change
|
|
13
|
+
scrollEvent=true}else{element=element.parentElement}}if(!scrollEvent){ev.preventDefault()}});_defineProperty(_this,"setMapContainerRef",function(el){_this.setState({mapContainerRef:el})});_defineProperty(_this,"setAppInfosContainerRef",function(el){_this.setState({appInfosContainerRef:el})});_defineProperty(_this,"setButtonContainerRef",function(el){_this.setState({mapButtonsContainerRef:el});if(el){var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var width=contentRectEntry.contentRect.width;var height=contentRectEntry.contentRect.height;el.style.setProperty("--buttons-container-width","".concat(width,"px"));el.style.setProperty("--buttons-container-height","".concat(height,"px"))}});resizeObserver.observe(el);el.recomputeSpacers=function(){var slots=new Set;Array.from(el.childNodes).forEach(function(child){if(child.dataset.spacer){el.removeChild(child)}else{slots.add(child.dataset.slot)}});var maxSlot=Math.max.apply(Math,_toConsumableArray(slots));for(var i=0;i<maxSlot;++i){if(!slots.has(String(i))){var child=document.createElement("div");child.className="map-buttons-spacer";child.dataset.spacer=1;child.style.order=i;el.appendChild(child)}}}}});return _this}_inherits(PluginsContainer,_React$Component);return _createClass(PluginsContainer,[{key:"render",value:function render(){var _this$props$className;var left=this.props.mapMargins.left+this.props.mapMargins.outerLeft;var top=this.props.mapMargins.top;var right=this.props.mapMargins.right+this.props.mapMargins.outerRight;var bottom=this.props.mapMargins.bottom;var mapContainerStyle={left:"calc("+left+"px)",top:"calc(var(--topbar-height) + "+top+"px)",right:"calc("+right+"px)",bottom:"calc(var(--bottombar-height) + "+bottom+"px)"};var haveRefs=this.state.mapButtonsContainerRef&&this.state.mapContainerRef&&this.state.appInfosContainerRef;return/*#__PURE__*/React.createElement("div",{className:"plugins-container "+((_this$props$className=this.props.className)!==null&&_this$props$className!==void 0?_this$props$className:""),ref:this.setupTouchEvents},/*#__PURE__*/React.createElement(AppInfosPortalContext.Provider,{value:this.state.appInfosContainerRef},/*#__PURE__*/React.createElement(MapButtonPortalContext.Provider,{value:this.state.mapButtonsContainerRef},/*#__PURE__*/React.createElement(MapContainerPortalContext.Provider,{value:this.state.mapContainerRef},haveRefs?this.renderPlugins():null,haveRefs?this.props.children:null))),/*#__PURE__*/React.createElement(WindowManager,null),/*#__PURE__*/React.createElement("div",{className:"map-container",ref:this.setMapContainerRef,style:mapContainerStyle},/*#__PURE__*/React.createElement(ProcessNotifications,null)),/*#__PURE__*/React.createElement("div",{className:"map-buttons-container",ref:this.setButtonContainerRef,style:mapContainerStyle}),/*#__PURE__*/React.createElement("div",{className:"app-infos-container",ref:this.setAppInfosContainerRef,style:mapContainerStyle}))}}])}(React.Component);_defineProperty(PluginsContainer,"propTypes",{children:PropTypes.oneOfType([PropTypes.node,PropTypes.func]),className:PropTypes.string,mapMargins:PropTypes.object,pluginsConfig:PropTypes.array,theme:PropTypes.object});export default connect(function(state){return{// Just to trigger re-render when custom plugins change
|
|
14
14
|
customPlugins:state.localConfig.customPlugins,mapMargins:state.windows.mapMargins,theme:state.theme.current}})(PluginsContainer);
|
|
@@ -10,6 +10,36 @@ div.map-container {
|
|
|
10
10
|
position: absolute;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
div.app-infos-container {
|
|
14
|
+
position: absolute;
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
align-items: flex-start;
|
|
19
|
+
align-content: flex-start;
|
|
20
|
+
justify-content: flex-start;
|
|
21
|
+
flex-wrap: wrap-reverse;
|
|
22
|
+
z-index: 2;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
padding: 1em 1em 2.5em 1em;
|
|
25
|
+
row-gap: 0.25em;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
div.app-info {
|
|
29
|
+
z-index: 1;
|
|
30
|
+
color: var(--panel-text-color);
|
|
31
|
+
background-color: var(--panel-bg-color);
|
|
32
|
+
box-shadow: 0 0 4px rgba(136, 136, 136, 0.5);
|
|
33
|
+
padding: 0.25em 0em 0.125em 0em;
|
|
34
|
+
display: flex;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
div.app-info > span {
|
|
38
|
+
flex: 0 0 auto;
|
|
39
|
+
padding: 0 0.25em;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
13
43
|
div.map-buttons-container {
|
|
14
44
|
position: absolute;
|
|
15
45
|
pointer-events: none;
|
package/package.json
CHANGED
|
@@ -4,10 +4,10 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under the BSD-style license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*/import React from"react";import ReactDOM from"react-dom";import{connect}from"react-redux";import PropTypes from"prop-types";import url from"url";import Icon from"../components/Icon";import{
|
|
7
|
+
*/import React from"react";import ReactDOM from"react-dom";import{connect}from"react-redux";import PropTypes from"prop-types";import url from"url";import Icon from"../components/Icon";import{AppInfosPortalContext}from"../components/PluginsContainer";import ConfigUtils from"../utils/ConfigUtils";import"./style/Authentication.css";/**
|
|
8
8
|
* Handles authentication
|
|
9
9
|
*
|
|
10
10
|
* Invokes the the authentication service specified by `authServiceUrl` in `config.json`.
|
|
11
11
|
*/var Authentication=/*#__PURE__*/function(_React$Component){function Authentication(props){var _this;_classCallCheck(this,Authentication);_this=_callSuper(this,Authentication,[props]);_defineProperty(_this,"showLogin",function(){var urlObj=url.parse(window.location.href,true);if(_this.props.clearLayerParam){delete urlObj.query.l}urlObj.search=undefined;window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"login?url="+encodeURIComponent(url.format(urlObj))});_defineProperty(_this,"resetIdleTimer",function(){if(_this.idleTimer){clearTimeout(_this.idleTimer);_this.idleTimer=setTimeout(_this.idleAutologout,_this.props.idleTimeout*1000)}});_defineProperty(_this,"idleAutologout",function(){var urlObj=url.parse(window.location.href,true);urlObj.search=undefined;var loginUrl=ConfigUtils.getConfigProp("authServiceUrl")+"login?url="+encodeURIComponent(url.format(urlObj));window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"logout?url="+encodeURIComponent(loginUrl)});_this.idleTimer=null;return _this}_inherits(Authentication,_React$Component);return _createClass(Authentication,[{key:"componentDidMount",value:function componentDidMount(){var username=ConfigUtils.getConfigProp("username");if(this.props.requireLogin&&!username){this.showLogin()}if(this.props.idleTimeout&&username){this.idleTimer=setTimeout(this.idleAutologout,this.props.idleTimeout*1000);window.addEventListener("keydown",this.resetIdleTimer,{passive:true});window.addEventListener("mousedown",this.resetIdleTimer,{passive:true});window.addEventListener("wheel",this.resetIdleTimer,{passive:true})}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var task=this.props.task;if(task!==prevProps.task){// "Login" and "Logout" task ids are legacy
|
|
12
12
|
if(task.id==="Login"||task.id==="Authentication"&&task.mode==="Login"){this.showLogin()}else if(task.id==="Logout"||task.id==="Authentication"&&task.mode==="Logout"){// logout and redirect to custom logoutTargetUrl or current location if not set
|
|
13
|
-
window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"logout?url="+encodeURIComponent(this.props.logoutTargetUrl||window.location.href)}}}},{key:"render",value:function render(){if(!this.props.showLoginUser){return null}var username=ConfigUtils.getConfigProp("username");if(!username){return null}return/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"login-user"},/*#__PURE__*/React.createElement(Icon,{icon:"login"}),/*#__PURE__*/React.createElement("span",null,username)),this.context)}}])}(React.Component);_defineProperty(Authentication,"contextType",
|
|
13
|
+
window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"logout?url="+encodeURIComponent(this.props.logoutTargetUrl||window.location.href)}}}},{key:"render",value:function render(){if(!this.props.showLoginUser){return null}var username=ConfigUtils.getConfigProp("username");if(!username){return null}return/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"app-info login-user"},/*#__PURE__*/React.createElement(Icon,{icon:"login"}),/*#__PURE__*/React.createElement("span",null,username)),this.context)}}])}(React.Component);_defineProperty(Authentication,"contextType",AppInfosPortalContext);_defineProperty(Authentication,"availableIn3D",true);_defineProperty(Authentication,"propTypes",{/** Whether to clear the layer parameter from the URL on login. */clearLayerParam:PropTypes.bool,/** An idle timeout in seconds after which the user is automatically logged of. */idleTimeout:PropTypes.number,/** An URL to redirect to on logout, instead of the viewer URL. */logoutTargetUrl:PropTypes.string,/** Whether authentication is required, i.e. the viewer automatically redirects to the login page if no user is authenticated. */requireLogin:PropTypes.bool,/** Whether to display the currently logged in user below the application menu button. */showLoginUser:PropTypes.bool,task:PropTypes.object});export default connect(function(state){return{task:state.task}},{})(Authentication);
|
package/plugins/MapLegend.js
CHANGED
|
@@ -10,5 +10,5 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
10
10
|
* The user can toggle whether to display only layers which are enabled, visible in the current extent and/or visible at the current scale.
|
|
11
11
|
*
|
|
12
12
|
* See https://docs.qgis.org/3.28/en/docs/server_manual/services/wms.html#wms-getlegendgraphic for supported extra legend params.
|
|
13
|
-
*/var MapLegend=/*#__PURE__*/function(_React$Component){function MapLegend(props){var _this;_classCallCheck(this,MapLegend);_this=_callSuper(this,MapLegend,[props]);_defineProperty(_this,"state",{onlyVisibleLegend:false,bboxDependentLegend:false,scaleDependentLegend:false,visible:false});_defineProperty(_this,"onClose",function(){_this.setState({visible:false})});_defineProperty(_this,"printLayerLegend",function(layer,sublayer,mapScale){var isCategorized=(sublayer.sublayers||[]).find(function(entry){return entry.category_sublayer===true});if(_this.props.excludeLayers.includes(sublayer.name)){return null}else if(sublayer.sublayers&&!isCategorized&&(!_this.state.onlyVisibleLegend||sublayer.visibility)){if(_this.props.addGroupTitles){var children=sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)}).filter(function(x){return x});if(isEmpty(children)){return null}else{return/*#__PURE__*/React.createElement("div",{className:"map-legend-group",key:sublayer.name},/*#__PURE__*/React.createElement("div",{className:"map-legend-group-title"},sublayer.title||sublayer.name),/*#__PURE__*/React.createElement("div",{className:"map-legend-group-entries"},sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})))}}else{return sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})}}else{if(_this.state.onlyVisibleLegend&&!sublayer.visibility){return null}if((_this.state.onlyVisibleLegend||_this.state.scaleDependentLegend)&&!LayerUtils.layerScaleInRange(sublayer,mapScale)){return null}var request=LayerUtils.getLegendUrl(layer,
|
|
13
|
+
*/var MapLegend=/*#__PURE__*/function(_React$Component){function MapLegend(props){var _this;_classCallCheck(this,MapLegend);_this=_callSuper(this,MapLegend,[props]);_defineProperty(_this,"state",{onlyVisibleLegend:false,bboxDependentLegend:false,scaleDependentLegend:false,visible:false});_defineProperty(_this,"onClose",function(){_this.setState({visible:false})});_defineProperty(_this,"printLayerLegend",function(layer,sublayer,mapScale){var isCategorized=(sublayer.sublayers||[]).find(function(entry){return entry.category_sublayer===true});if(_this.props.excludeLayers.includes(sublayer.name)){return null}else if(sublayer.sublayers&&!isCategorized&&(!_this.state.onlyVisibleLegend||sublayer.visibility)){if(_this.props.addGroupTitles){var children=sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)}).filter(function(x){return x});if(isEmpty(children)){return null}else{return/*#__PURE__*/React.createElement("div",{className:"map-legend-group",key:sublayer.name},/*#__PURE__*/React.createElement("div",{className:"map-legend-group-title"},sublayer.title||sublayer.name),/*#__PURE__*/React.createElement("div",{className:"map-legend-group-entries"},sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})))}}else{return sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})}}else{if(_this.state.onlyVisibleLegend&&!sublayer.visibility){return null}if((_this.state.onlyVisibleLegend||_this.state.scaleDependentLegend)&&!LayerUtils.layerScaleInRange(sublayer,mapScale)){return null}var request=LayerUtils.getLegendUrl(layer,sublayer,mapScale,_this.props.map,_this.state.bboxDependentLegend,_this.state.scaleDependentLegend,_this.props.extraLegendParameters);return request?/*#__PURE__*/React.createElement("div",{className:"map-legend-legend-entry",key:sublayer.name},/*#__PURE__*/React.createElement("div",null,_this.props.addLayerTitles&&!sublayer.category_sublayer?/*#__PURE__*/React.createElement("div",{className:"map-legend-entry-title"},sublayer.title||sublayer.name):null,/*#__PURE__*/React.createElement("div",{className:"map-legend-entry-image"},/*#__PURE__*/React.createElement(Image,{src:request})))):null}});_this.state.onlyVisibleLegend=props.onlyVisibleLegend;_this.state.bboxDependentLegend=props.bboxDependentLegend;_this.state.scaleDependentLegend=props.scaleDependentLegend;return _this}_inherits(MapLegend,_React$Component);return _createClass(MapLegend,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.active&&!prevProps.active){this.setState({visible:true});// Clear task immediately, visibility is stored as state
|
|
14
14
|
this.props.setCurrentTask(null)}}},{key:"render",value:function render(){var _this2=this;if(!this.state.visible&&!this.props.lockedWindow){return null}var mapScale=MapUtils.computeForZoom(this.props.map.scales,this.props.map.zoom);var extraControls=[{icon:"eye",callback:function callback(){return _this2.setState(function(state){return{onlyVisibleLegend:!state.onlyVisibleLegend}})},active:this.state.onlyVisibleLegend,title:LocaleUtils.tr("maplegend.onlyvisible")},{icon:"box",callback:function callback(){return _this2.setState(function(state){return{bboxDependentLegend:!state.bboxDependentLegend}})},active:this.state.bboxDependentLegend,title:LocaleUtils.tr("maplegend.bboxdependent")},{icon:"scale",callback:function callback(){return _this2.setState(function(state){return{scaleDependentLegend:!state.scaleDependentLegend}})},active:this.state.scaleDependentLegend,title:LocaleUtils.tr("maplegend.scaledependent")}];return/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:this.props.lockedWindow?false:this.props.geometry.side,extraControls:extraControls,icon:"list-alt",initialHeight:this.props.geometry.initialHeight,initialWidth:this.props.geometry.initialWidth,initialX:this.props.geometry.initialX,initialY:this.props.geometry.initialY,initiallyDocked:this.props.geometry.initiallyDocked,maximizeable:false,onClose:this.props.lockedWindow?null:this.onClose,title:LocaleUtils.tr("maplegend.windowtitle")},/*#__PURE__*/React.createElement("div",{className:"map-legend",role:"body"},this.props.layers.map(function(layer){if(_this2.state.onlyVisibleLegend&&!layer.visibility){return null}else if(layer.legendUrl){return _this2.printLayerLegend(layer,layer,mapScale)}else if(layer.color){return/*#__PURE__*/React.createElement("div",{className:"map-legend-legend-entry",key:layer.name},/*#__PURE__*/React.createElement("span",{className:"map-legend-color-box",style:{backgroundColor:layer.color}}),/*#__PURE__*/React.createElement("span",{className:"map-legend-entry-title"},layer.title||layer.name))}else{return null}})))}}])}(React.Component);_defineProperty(MapLegend,"propTypes",{active:PropTypes.bool,/** Whether to add group titles to the legend. */addGroupTitles:PropTypes.bool,/** Whether to add layer titles to the legend. Note that often the legend image itself already contains the layer title. */addLayerTitles:PropTypes.bool,/** Whether to display a BBOX-dependent legend by default. */bboxDependentLegend:PropTypes.bool,/** List of layernames to exclude from the legend. */excludeLayers:PropTypes.array,/** Extra parameters to add to the GetLegendGraphics request. */extraLegendParameters:PropTypes.string,/** Default window geometry with size, position and docking status. A locked window is not closeable and not resizeable. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool,side:PropTypes.string}),layers:PropTypes.array,/** Whether the legend window is locked (always visible, not moveable or closeable). Set position and size via `geometry`. */lockedWindow:PropTypes.bool,map:PropTypes.object,/** Whether to only include enabled layers in the legend by default. */onlyVisibleLegend:PropTypes.bool,/** Whether to display a scale-dependent legend by default. */scaleDependentLegend:PropTypes.bool,setCurrentTask:PropTypes.func});_defineProperty(MapLegend,"defaultProps",{addGroupTitles:false,addLayerTitles:false,bboxDependentLegend:false,excludeLayers:[],onlyVisibleLegend:false,scaleDependentLegend:false,geometry:{initialWidth:320,initialHeight:320,initialX:0,initialY:0,initiallyDocked:false,side:"left"}});export default connect(function(state){return{active:state.task.id==="MapLegend",layers:state.layers.flat,map:state.map}},{setCurrentTask:setCurrentTask})(MapLegend);
|
package/plugins/ThemeSwitcher.js
CHANGED
|
@@ -4,7 +4,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under the BSD-style license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*/import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import Icon from"../components/Icon";import SideBar from"../components/SideBar";import ThemeLayersListWindow from"../components/ThemeLayersListWindow";import ThemeList from"../components/ThemeList";import InputContainer from"../components/widgets/InputContainer";import ConfigUtils from"../utils/ConfigUtils";import LocaleUtils from"../utils/LocaleUtils";import"./style/ThemeSwitcher.css";/**
|
|
7
|
+
*/import React from"react";import ReactDOM from"react-dom";import{connect}from"react-redux";import PropTypes from"prop-types";import Icon from"../components/Icon";import{AppInfosPortalContext}from"../components/PluginsContainer";import SideBar from"../components/SideBar";import ThemeLayersListWindow from"../components/ThemeLayersListWindow";import ThemeList from"../components/ThemeList";import InputContainer from"../components/widgets/InputContainer";import ConfigUtils from"../utils/ConfigUtils";import LocaleUtils from"../utils/LocaleUtils";import"./style/ThemeSwitcher.css";/**
|
|
8
8
|
* Theme switcher panel.
|
|
9
9
|
*/var ThemeSwitcher=/*#__PURE__*/function(_React$Component){function ThemeSwitcher(){var _this;_classCallCheck(this,ThemeSwitcher);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,ThemeSwitcher,[].concat(args));_defineProperty(_this,"state",{filter:""});_defineProperty(_this,"focusFilterField",function(el){if(el){// Need to wait until slide in transition is over
|
|
10
|
-
setTimeout(function(){if(_this.props.currentTask&&_this.props.currentTask.id==="ThemeSwitcher"){el.focus()}},500)}});return _this}_inherits(ThemeSwitcher,_React$Component);return _createClass(ThemeSwitcher,[{key:"render",value:function render(){var _this2=this;var allowAddingOtherThemes=ConfigUtils.getConfigProp("allowAddingOtherThemes",this.props.activeTheme)===true;var showAddThemeButton=allowAddingOtherThemes&&!this.props.hideAddThemeButton;var showAddThemeLayersButton=allowAddingOtherThemes&&!this.props.hideAddThemeLayersButton;var themeFilter=this.props.showThemeFilter?/*#__PURE__*/React.createElement(InputContainer,{className:"theme-switcher-filter"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this2.setState({filter:ev.target.value})},placeholder:LocaleUtils.tr("themeswitcher.filter"),ref:this.focusFilterField,role:"input",type:"text",value:this.state.filter}),/*#__PURE__*/React.createElement(Icon,{icon:"remove",onClick:function onClick(){return _this2.setState({filter:""})},role:"suffix"})):null;var extraTitlebarContent=themeFilter;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(SideBar,{extraTitlebarContent:extraTitlebarContent,icon:"themes",id:"ThemeSwitcher",minWidth:"16em",side:this.props.side,title:LocaleUtils.tr("appmenu.items.ThemeSwitcher"),width:this.props.width},function(){return{body:/*#__PURE__*/React.createElement(ThemeList,{activeTheme:_this2.props.activeTheme,allowAddingOtherThemeLayers:showAddThemeLayersButton,allowAddingOtherThemes:showAddThemeButton,collapsibleGroups:_this2.props.collapsibleGroups,filter:_this2.state.filter,showDefaultThemeSelector:_this2.props.showDefaultThemeSelector,showLayerAfterChangeTheme:_this2.props.showLayerAfterChangeTheme})}}),showAddThemeLayersButton?/*#__PURE__*/React.createElement(ThemeLayersListWindow,{windowSize:this.props.themeLayersListWindowSize}):null)}}])}(React.Component);_defineProperty(ThemeSwitcher,"availableIn3D",true);_defineProperty(ThemeSwitcher,"propTypes",{activeTheme:PropTypes.object,/** Whether to allow collapsing theme groups. */collapsibleGroups:PropTypes.bool,currentTask:PropTypes.object,/** Whether to hide the add theme button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeButton:PropTypes.bool,/** Whether to hide the add theme layers button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeLayersButton:PropTypes.bool,/** Whether to show an icon to select the default theme/bookmark (of a logged in user). */showDefaultThemeSelector:PropTypes.bool,/** Whether to show the LayerTree by default after switching the theme. */showLayerAfterChangeTheme:PropTypes.bool,/** Wether to show the theme filter field in the top bar. */showThemeFilter:PropTypes.bool,/** The side of the application on which to display the sidebar. */side:PropTypes.string,/** The default window size for the theme layers dialog. */themeLayersListWindowSize:PropTypes.shape({width:PropTypes.number,height:PropTypes.number}),/** Default width as a CSS string. */width:PropTypes.string});_defineProperty(ThemeSwitcher,"defaultProps",{width:"50%",showThemeFilter:true,showDefaultThemeSelector:true,showLayerAfterChangeTheme:false,themeLayersListWindowSize:{width:400,height:300},side:"right"});var selector=function selector(state){return{activeTheme:state.theme.current}};export default connect(selector,{})(ThemeSwitcher);
|
|
10
|
+
setTimeout(function(){if(_this.props.currentTask&&_this.props.currentTask.id==="ThemeSwitcher"){el.focus()}},500)}});return _this}_inherits(ThemeSwitcher,_React$Component);return _createClass(ThemeSwitcher,[{key:"render",value:function render(){var _this2=this;var allowAddingOtherThemes=ConfigUtils.getConfigProp("allowAddingOtherThemes",this.props.activeTheme)===true;var showAddThemeButton=allowAddingOtherThemes&&!this.props.hideAddThemeButton;var showAddThemeLayersButton=allowAddingOtherThemes&&!this.props.hideAddThemeLayersButton;var themeFilter=this.props.showThemeFilter?/*#__PURE__*/React.createElement(InputContainer,{className:"theme-switcher-filter"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this2.setState({filter:ev.target.value})},placeholder:LocaleUtils.tr("themeswitcher.filter"),ref:this.focusFilterField,role:"input",type:"text",value:this.state.filter}),/*#__PURE__*/React.createElement(Icon,{icon:"remove",onClick:function onClick(){return _this2.setState({filter:""})},role:"suffix"})):null;var extraTitlebarContent=themeFilter;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(SideBar,{extraTitlebarContent:extraTitlebarContent,icon:"themes",id:"ThemeSwitcher",minWidth:"16em",side:this.props.side,title:LocaleUtils.tr("appmenu.items.ThemeSwitcher"),width:this.props.width},function(){return{body:/*#__PURE__*/React.createElement(ThemeList,{activeTheme:_this2.props.activeTheme,allowAddingOtherThemeLayers:showAddThemeLayersButton,allowAddingOtherThemes:showAddThemeButton,collapsibleGroups:_this2.props.collapsibleGroups,filter:_this2.state.filter,showDefaultThemeSelector:_this2.props.showDefaultThemeSelector,showLayerAfterChangeTheme:_this2.props.showLayerAfterChangeTheme})}}),showAddThemeLayersButton?/*#__PURE__*/React.createElement(ThemeLayersListWindow,{windowSize:this.props.themeLayersListWindowSize}):null,this.props.showActiveTheme&&this.props.activeTheme?(/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"app-info active-theme"},/*#__PURE__*/React.createElement(Icon,{icon:"themes"}),/*#__PURE__*/React.createElement("span",null,this.props.activeTheme.title||this.props.activeTheme.name||this.props.activeTheme.id)),this.context)):null)}}])}(React.Component);_defineProperty(ThemeSwitcher,"contextType",AppInfosPortalContext);_defineProperty(ThemeSwitcher,"availableIn3D",true);_defineProperty(ThemeSwitcher,"propTypes",{activeTheme:PropTypes.object,/** Whether to allow collapsing theme groups. */collapsibleGroups:PropTypes.bool,currentTask:PropTypes.object,/** Whether to hide the add theme button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeButton:PropTypes.bool,/** Whether to hide the add theme layers button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeLayersButton:PropTypes.bool,/** Whether to display the currently active theme below the application menu button. Default: false */showActiveTheme:PropTypes.bool,/** Whether to show an icon to select the default theme/bookmark (of a logged in user). */showDefaultThemeSelector:PropTypes.bool,/** Whether to show the LayerTree by default after switching the theme. */showLayerAfterChangeTheme:PropTypes.bool,/** Wether to show the theme filter field in the top bar. */showThemeFilter:PropTypes.bool,/** The side of the application on which to display the sidebar. */side:PropTypes.string,/** The default window size for the theme layers dialog. */themeLayersListWindowSize:PropTypes.shape({width:PropTypes.number,height:PropTypes.number}),/** Default width as a CSS string. */width:PropTypes.string});_defineProperty(ThemeSwitcher,"defaultProps",{width:"50%",showActiveTheme:false,showThemeFilter:true,showDefaultThemeSelector:true,showLayerAfterChangeTheme:false,themeLayersListWindowSize:{width:400,height:300},side:"right"});var selector=function selector(state){return{activeTheme:state.theme.current}};export default connect(selector,{})(ThemeSwitcher);
|
|
@@ -1,16 +1,3 @@
|
|
|
1
1
|
div.login-user {
|
|
2
|
-
|
|
3
|
-
right: 0.25em;
|
|
4
|
-
top: 0.25em;
|
|
5
|
-
z-index: 1;
|
|
6
|
-
color: var(--panel-text-color);
|
|
7
|
-
background-color: var(--panel-bg-color);
|
|
8
|
-
box-shadow: 0 0 4px rgba(136, 136, 136, 0.5);
|
|
9
|
-
padding: 0.25em 0em 0.125em 0em;
|
|
10
|
-
display: flex;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
div.login-user > span {
|
|
14
|
-
flex: 0 0 auto;
|
|
15
|
-
padding: 0 0.25em;
|
|
2
|
+
order: 1;
|
|
16
3
|
}
|
package/utils/ThemeUtils.js
CHANGED
|
@@ -9,4 +9,4 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
9
9
|
console.warn("Could not find background layer "+entry.name)}};for(_iterator.s();!(_step=_iterator.n()).done;){if(_loop())continue}}catch(err){_iterator.e(err)}finally{_iterator.f()}if(visibleIdx>=0){bgLayers[visibleIdx].visibility=true}else if(defaultVisibleIdx>=0&&visibleLayer!==""){bgLayers[defaultVisibleIdx].visibility=true}return bgLayers},createThemeLayer:function createThemeLayer(theme,themes){var role=arguments.length>2&&arguments[2]!==undefined?arguments[2]:LayerRole.THEME;var subLayers=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var urlParts=url.parse(theme.url,true);// Resolve relative urls
|
|
10
10
|
if(!urlParts.host){var locationParts=url.parse(window.location.href);urlParts.protocol=locationParts.protocol;urlParts.host=locationParts.host}var sublayerNames=LayerUtils.getSublayerNames({sublayers:subLayers!==null&&subLayers!==void 0?subLayers:theme.sublayers});var baseParams=urlParts.query;var layer={type:"wms",id:theme.id,url:url.format(urlParts),version:theme.version||themes.defaultWMSVersion||"1.3.0",visibility:true,expanded:theme.expanded,name:theme.name,title:theme.title,bbox:theme.bbox,sublayers:subLayers!==null&&subLayers!==void 0?subLayers:theme.sublayers,tiled:theme.tiled,tileSize:theme.tileSize,ratio:!theme.tiled?1:undefined,serverType:"qgis",format:theme.format,rev:+new Date,role:role,attribution:theme.attribution,legendUrl:ThemeUtils.inheritBaseUrlParams(theme.legendUrl,theme.url,baseParams),printUrl:ThemeUtils.inheritBaseUrlParams(theme.printUrl,theme.url,baseParams),featureInfoUrl:ThemeUtils.inheritBaseUrlParams(theme.featureInfoUrl,theme.url,baseParams),infoFormats:theme.infoFormats,mapFormats:theme.availableFormats,layerTreeHiddenSublayers:theme.layerTreeHiddenSublayers,predefinedFilters:(theme.predefinedFilters||[]).filter(function(entry){return Object.keys(entry.filter).find(function(name){return sublayerNames.includes(name)})}),externalLayerMap:_objectSpread(_objectSpread({},theme.externalLayerMap),(theme.externalLayers||[]).reduce(function(res,cur){res[cur.internalLayer]=_objectSpread({},themes.externalLayers.find(function(entry){return entry.name===cur.name}));LayerUtils.completeExternalLayer(res[cur.internalLayer],LayerUtils.searchSubLayer(theme,"name",cur.internalLayer));return res},{})),translations:theme.translations};layer=LayerUtils.recomputeLayerBBox(layer);// Drawing order only makes sense if layer reordering is disabled
|
|
11
11
|
if(ConfigUtils.getConfigProp("allowReorderingLayers",theme)!==true){layer.drawingOrder=theme.drawingOrder}return layer},inheritBaseUrlParams:function inheritBaseUrlParams(capabilityUrl,baseUrl,baseParams){if(!capabilityUrl){return baseUrl}if(capabilityUrl.split("?")[0]===baseUrl.split("?")[0]){var parts=url.parse(capabilityUrl,true);parts.query=_objectSpread(_objectSpread({},baseParams),parts.query);return url.format(parts)}return capabilityUrl},searchThemes:function searchThemes(themes,searchtext){var filter=new RegExp(removeDiacritics(searchtext).replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&"),"i");var matches=[];var _searchThemeGroup=function searchThemeGroup(themeGroup){(themeGroup.subdirs||[]).forEach(function(subdir){return _searchThemeGroup(subdir,filter)});matches.push.apply(matches,_toConsumableArray((themeGroup.items||[]).filter(function(item){return removeDiacritics(item.title).match(filter)||removeDiacritics(item.keywords||"").match(filter)||removeDiacritics(item["abstract"]||"").match(filter)})))};_searchThemeGroup(themes,filter);return isEmpty(matches)?[]:[{id:"themes",titlemsgid:"search.themes",type:SearchResultType.THEME,items:matches.map(function(theme){return{id:theme.id,text:theme.title,theme:theme,layer:ThemeUtils.createThemeLayer(theme,themes),thumbnail:ConfigUtils.getAssetsPath()+"/"+theme.thumbnail}})}]},searchThemeLayers:function searchThemeLayers(themes,searchtext){var filter=new RegExp(removeDiacritics(searchtext).replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&"),"i");var matches=[];var _searchLayer=function searchLayer(theme,layer){var path=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];(layer.sublayers||[]).forEach(function(sublayer,idx){var subpath=[].concat(_toConsumableArray(path),[idx]);if(removeDiacritics(sublayer.name).match(filter)||removeDiacritics(sublayer.title).match(filter)){// Clone theme, ensuring path to layer is visible
|
|
12
|
-
var newtheme=_objectSpread({},theme);var cur=newtheme;var _loop2=function _loop2(i){var isMutuallyExclusive=cur.mutuallyExclusive;cur.sublayers=cur.sublayers.map(function(entry,j){return _objectSpread(_objectSpread({},entry),{},{visibility:j===subpath[i]||entry.visibility&&!isMutuallyExclusive})});cur=cur.sublayers[subpath[i]]};for(var i=0;i<subpath.length;++i){_loop2(i)}matches.push({theme:newtheme,layer:ThemeUtils.createThemeLayer(newtheme,themes,LayerRole.USERLAYER,[cur])})}_searchLayer(theme,sublayer,subpath)})};var _searchThemeGroup2=function searchThemeGroup(themeGroup){(themeGroup.subdirs||[]).forEach(function(subdir){return _searchThemeGroup2(subdir,filter)});(themeGroup.items||[]).forEach(function(item){return _searchLayer(item,item)})};_searchThemeGroup2(themes,filter);return isEmpty(matches)?[]:[{id:"themelayers",titlemsgid:"search.themelayers",type:SearchResultType.THEMELAYER,items:matches.map(function(result){return{id:result.layer.id+":"+result.layer.sublayers[0].name,text:result.layer.title+": "+result.layer.sublayers[0].title,layer:result.layer,theme:result.theme}})}]},getThemeNames:function getThemeNames(themes){var names=(themes.items||[]).reduce(function(res,theme){return _objectSpread(_objectSpread({},res),{},_defineProperty({},theme.id,theme.title))},{});(themes.subdirs||[]).forEach(function(group){Object.assign(names,ThemeUtils.getThemeNames(group))});return names},themeFlagsAllowed:function themeFlagsAllowed(theme,flagWhitelist,flagBlacklist){var themeFlags=(theme===null||theme===void 0?void 0:theme.flags)||[];if(flagBlacklist&&flagBlacklist.find(function(flag){return themeFlags.includes(flag)})!==undefined){return false}if(flagWhitelist&&flagWhitelist.find(function(flag){return themeFlags.includes(flag)})===undefined){return false}return true},allowedItems:function allowedItems(items,theme){var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;return(items||[]).map(function(item){if(item.subitems){var subitems=ThemeUtils.allowedItems(item.subitems,
|
|
12
|
+
var newtheme=_objectSpread({},theme);var cur=newtheme;var _loop2=function _loop2(i){var isMutuallyExclusive=cur.mutuallyExclusive;cur.sublayers=cur.sublayers.map(function(entry,j){return _objectSpread(_objectSpread({},entry),{},{visibility:j===subpath[i]||entry.visibility&&!isMutuallyExclusive})});cur=cur.sublayers[subpath[i]]};for(var i=0;i<subpath.length;++i){_loop2(i)}matches.push({theme:newtheme,layer:ThemeUtils.createThemeLayer(newtheme,themes,LayerRole.USERLAYER,[cur])})}_searchLayer(theme,sublayer,subpath)})};var _searchThemeGroup2=function searchThemeGroup(themeGroup){(themeGroup.subdirs||[]).forEach(function(subdir){return _searchThemeGroup2(subdir,filter)});(themeGroup.items||[]).forEach(function(item){return _searchLayer(item,item)})};_searchThemeGroup2(themes,filter);return isEmpty(matches)?[]:[{id:"themelayers",titlemsgid:"search.themelayers",type:SearchResultType.THEMELAYER,items:matches.map(function(result){return{id:result.layer.id+":"+result.layer.sublayers[0].name,text:result.layer.title+": "+result.layer.sublayers[0].title,layer:result.layer,theme:result.theme}})}]},getThemeNames:function getThemeNames(themes){var names=(themes.items||[]).reduce(function(res,theme){return _objectSpread(_objectSpread({},res),{},_defineProperty({},theme.id,theme.title))},{});(themes.subdirs||[]).forEach(function(group){Object.assign(names,ThemeUtils.getThemeNames(group))});return names},themeFlagsAllowed:function themeFlagsAllowed(theme,flagWhitelist,flagBlacklist){var themeFlags=(theme===null||theme===void 0?void 0:theme.flags)||[];if(flagBlacklist&&flagBlacklist.find(function(flag){return themeFlags.includes(flag)})!==undefined){return false}if(flagWhitelist&&flagWhitelist.find(function(flag){return themeFlags.includes(flag)})===undefined){return false}return true},allowedItems:function allowedItems(items,theme){var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;return(items||[]).map(function(item){if(item.subitems){var subitems=ThemeUtils.allowedItems(item.subitems,theme,filter).filter(Boolean);if(!isEmpty(subitems)){return _objectSpread(_objectSpread({},item),{},{subitems:subitems})}else{return null}}else{if(filter&&!filter(item)){return null}if(theme){if(!ThemeUtils.themeFlagsAllowed(theme,item.themeFlagWhitelist,item.themeFlagBlacklist)){return null}if(item.themeBlacklist&&(item.themeBlacklist.includes(theme.title)||item.themeBlacklist.includes(theme.name))){return null}if(item.themeWhitelist&&!(item.themeWhitelist.includes(theme.title)||item.themeWhitelist.includes(theme.name))){return null}if(item.requireAuth&&!ConfigUtils.getConfigProp("username")){return null}}return item}}).filter(Boolean)},applyTranslations:function applyTranslations(group){return _objectSpread(_objectSpread({},group),{},{subdirs:group.subdirs?group.subdirs.map(ThemeUtils.applyTranslations):null,items:group.items?group.items.map(function(item){var _item$translations$th,_item$translations;return _objectSpread(_objectSpread({},LayerUtils.applyTranslations(item,item.translations)),{},{title:(_item$translations$th=(_item$translations=item.translations)===null||_item$translations===void 0||(_item$translations=_item$translations.theme)===null||_item$translations===void 0?void 0:_item$translations.title)!==null&&_item$translations$th!==void 0?_item$translations$th:item.title})}):null})}};export default ThemeUtils;
|