| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import { FixedInputElement } from "../Input/FixedInputElement" | 
					
						
							|  |  |  | import { RadioButton } from "../Input/RadioButton" | 
					
						
							|  |  |  | import { VariableUiElement } from "../Base/VariableUIElement" | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  | import Toggle, { ClickableToggle } from "../Input/Toggle" | 
					
						
							| 
									
										
										
										
											2021-07-20 15:14:51 +02:00
										 |  |  | import Combine from "../Base/Combine" | 
					
						
							|  |  |  | import Translations from "../i18n/Translations" | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | import { Translation } from "../i18n/Translation" | 
					
						
							| 
									
										
										
										
											2021-07-20 16:29:48 +02:00
										 |  |  | import Svg from "../../Svg" | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  | import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | import BaseUIElement from "../BaseUIElement" | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  | import FilteredLayer, { FilterState } from "../../Models/FilteredLayer" | 
					
						
							| 
									
										
										
										
											2021-07-28 16:48:59 +02:00
										 |  |  | import BackgroundSelector from "./BackgroundSelector" | 
					
						
							| 
									
										
										
										
											2021-08-07 23:11:34 +02:00
										 |  |  | import FilterConfig from "../../Models/ThemeConfig/FilterConfig" | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  | import TilesourceConfig from "../../Models/ThemeConfig/TilesourceConfig" | 
					
						
							| 
									
										
										
										
											2022-01-07 17:31:39 +01:00
										 |  |  | import { SubstitutedTranslation } from "../SubstitutedTranslation" | 
					
						
							|  |  |  | import ValidatedTextField from "../Input/ValidatedTextField" | 
					
						
							|  |  |  | import { QueryParameters } from "../../Logic/Web/QueryParameters" | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  | import { TagUtils } from "../../Logic/Tags/TagUtils" | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  | import { InputElement } from "../Input/InputElement" | 
					
						
							|  |  |  | import { DropDown } from "../Input/DropDown" | 
					
						
							| 
									
										
										
										
											2022-08-18 19:17:15 +02:00
										 |  |  | import { FixedUiElement } from "../Base/FixedUiElement" | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  | import BaseLayer from "../../Models/BaseLayer" | 
					
						
							|  |  |  | import Loc from "../../Models/Loc" | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 12:26:41 +02:00
										 |  |  | export default class FilterView extends VariableUiElement { | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         filteredLayer: Store<FilteredLayer[]>, | 
					
						
							|  |  |  |         tileLayers: { config: TilesourceConfig; isDisplayed: UIEventSource<boolean> }[], | 
					
						
							|  |  |  |         state: { | 
					
						
							|  |  |  |             availableBackgroundLayers?: Store<BaseLayer[]> | 
					
						
							|  |  |  |             featureSwitchBackgroundSelection?: UIEventSource<boolean> | 
					
						
							|  |  |  |             featureSwitchIsDebugging?: UIEventSource<boolean> | 
					
						
							|  |  |  |             locationControl?: UIEventSource<Loc> | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2021-09-07 01:49:18 +02:00
										 |  |  |         const backgroundSelector = new Toggle( | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             new BackgroundSelector(state), | 
					
						
							| 
									
										
										
										
											2021-07-28 16:48:59 +02:00
										 |  |  |             undefined, | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             state.featureSwitchBackgroundSelection ?? new ImmutableStore(false) | 
					
						
							| 
									
										
										
										
											2021-07-28 16:48:59 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |         super( | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |             filteredLayer.map((filteredLayers) => { | 
					
						
							| 
									
										
										
										
											2022-01-27 01:23:04 +01:00
										 |  |  |                 // Create the views which toggle layers (and filters them) ...
 | 
					
						
							| 
									
										
										
										
											2022-02-02 01:51:19 +01:00
										 |  |  |                 let elements = filteredLayers | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |                     ?.map((l) => | 
					
						
							|  |  |  |                         FilterView.createOneFilteredLayerElement(l, state)?.SetClass("filter-panel") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2022-02-02 01:51:19 +01:00
										 |  |  |                     ?.filter((l) => l !== undefined) | 
					
						
							|  |  |  |                 elements[0].SetClass("first-filter-panel") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 01:23:04 +01:00
										 |  |  |                 // ... create views for non-interactive layers ...
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |                 elements = elements.concat( | 
					
						
							|  |  |  |                     tileLayers.map((tl) => FilterView.createOverlayToggle(state, tl)) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2022-01-27 01:23:04 +01:00
										 |  |  |                 // ... and add the dropdown to select a different background
 | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |                 return elements.concat(backgroundSelector) | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |     private static createOverlayToggle( | 
					
						
							|  |  |  |         state: { locationControl?: UIEventSource<Loc> }, | 
					
						
							|  |  |  |         config: { config: TilesourceConfig; isDisplayed: UIEventSource<boolean> } | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |         const iconStyle = "width:1.5rem;height:1.5rem;margin-left:1.25rem;flex-shrink: 0;" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const icon = new Combine([Svg.checkbox_filled]).SetStyle(iconStyle) | 
					
						
							|  |  |  |         const iconUnselected = new Combine([Svg.checkbox_empty]).SetStyle(iconStyle) | 
					
						
							| 
									
										
										
										
											2021-10-25 21:50:38 +02:00
										 |  |  |         const name: Translation = config.config.name | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  |         const styledNameChecked = name.Clone().SetStyle("font-size:large").SetClass("ml-2") | 
					
						
							|  |  |  |         const styledNameUnChecked = name.Clone().SetStyle("font-size:large").SetClass("ml-2") | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const zoomStatus = new Toggle( | 
					
						
							|  |  |  |             undefined, | 
					
						
							| 
									
										
										
										
											2021-10-25 21:50:38 +02:00
										 |  |  |             Translations.t.general.layerSelection.zoomInToSeeThisLayer | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |                 .SetClass("alert") | 
					
						
							|  |  |  |                 .SetStyle("display: block ruby;width:min-content;"), | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             state.locationControl?.map((location) => location.zoom >= config.config.minzoom) ?? | 
					
						
							|  |  |  |                 new ImmutableStore(false) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const style = "display:flex;align-items:center;padding:0.5rem 0;" | 
					
						
							|  |  |  |         const layerChecked = new Combine([icon, styledNameChecked, zoomStatus]) | 
					
						
							|  |  |  |             .SetStyle(style) | 
					
						
							|  |  |  |             .onClick(() => config.isDisplayed.setData(false)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const layerNotChecked = new Combine([iconUnselected, styledNameUnChecked]) | 
					
						
							|  |  |  |             .SetStyle(style) | 
					
						
							|  |  |  |             .onClick(() => config.isDisplayed.setData(true)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return new Toggle(layerChecked, layerNotChecked, config.isDisplayed) | 
					
						
							| 
									
										
										
										
											2021-07-26 12:26:41 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-20 16:29:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |     private static createOneFilteredLayerElement( | 
					
						
							|  |  |  |         filteredLayer: FilteredLayer, | 
					
						
							|  |  |  |         state: { featureSwitchIsDebugging?: Store<boolean>; locationControl?: Store<Loc> } | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2021-09-07 01:49:18 +02:00
										 |  |  |         if (filteredLayer.layerDef.name === undefined) { | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  |             // Name is not defined: we hide this one
 | 
					
						
							| 
									
										
										
										
											2022-04-23 15:20:54 +02:00
										 |  |  |             return new Toggle( | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |                 new FixedUiElement(filteredLayer?.layerDef?.id).SetClass("block"), | 
					
						
							| 
									
										
										
										
											2022-04-23 15:20:54 +02:00
										 |  |  |                 undefined, | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |                 state?.featureSwitchIsDebugging ?? new ImmutableStore(false) | 
					
						
							| 
									
										
										
										
											2022-04-23 15:20:54 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-04 19:47:23 +02:00
										 |  |  |         const iconStyle = "width:1.5rem;height:1.5rem;margin-left:1.25rem;flex-shrink: 0;" | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const icon = new Combine([Svg.checkbox_filled]).SetStyle(iconStyle) | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  |         const layer = filteredLayer.layerDef | 
					
						
							| 
									
										
										
										
											2021-10-31 02:08:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |         const iconUnselected = new Combine([Svg.checkbox_empty]).SetStyle(iconStyle) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         const name: Translation = filteredLayer.layerDef.name.Clone() | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  |         const styledNameChecked = name.Clone().SetStyle("font-size:large").SetClass("ml-3") | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  |         const styledNameUnChecked = name.Clone().SetStyle("font-size:large").SetClass("ml-3") | 
					
						
							| 
									
										
										
										
											2021-09-07 01:49:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  |         const zoomStatus = new Toggle( | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  |             undefined, | 
					
						
							| 
									
										
										
										
											2021-10-25 21:50:38 +02:00
										 |  |  |             Translations.t.general.layerSelection.zoomInToSeeThisLayer | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  |                 .SetClass("alert") | 
					
						
							|  |  |  |                 .SetStyle("display: block ruby;width:min-content;"), | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             state?.locationControl?.map( | 
					
						
							|  |  |  |                 (location) => location.zoom >= filteredLayer.layerDef.minzoom | 
					
						
							|  |  |  |             ) ?? new ImmutableStore(false) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-02 01:51:19 +01:00
										 |  |  |         const toggleClasses = "layer-toggle flex flex-wrap items-center pt-2 pb-2 px-0" | 
					
						
							| 
									
										
										
										
											2022-02-01 04:14:54 +01:00
										 |  |  |         const layerIcon = layer.defaultIcon()?.SetClass("flex-shrink-0 w-8 h-8 ml-2") | 
					
						
							|  |  |  |         const layerIconUnchecked = layer | 
					
						
							|  |  |  |             .defaultIcon() | 
					
						
							|  |  |  |             ?.SetClass("flex-shrink-0 opacity-50  w-8 h-8 ml-2") | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const layerChecked = new Combine([icon, layerIcon, styledNameChecked, zoomStatus]) | 
					
						
							| 
									
										
										
										
											2022-02-01 04:14:54 +01:00
										 |  |  |             .SetClass(toggleClasses) | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |             .onClick(() => filteredLayer.isDisplayed.setData(false)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 02:34:16 +02:00
										 |  |  |         const layerNotChecked = new Combine([ | 
					
						
							|  |  |  |             iconUnselected, | 
					
						
							|  |  |  |             layerIconUnchecked, | 
					
						
							|  |  |  |             styledNameUnChecked, | 
					
						
							|  |  |  |         ]) | 
					
						
							| 
									
										
										
										
											2022-02-01 04:14:54 +01:00
										 |  |  |             .SetClass(toggleClasses) | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |             .onClick(() => filteredLayer.isDisplayed.setData(true)) | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |         const filterPanel: BaseUIElement = new LayerFilterPanel(state, filteredLayer) | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |         return new Toggle( | 
					
						
							|  |  |  |             new Combine([layerChecked, filterPanel]), | 
					
						
							|  |  |  |             layerNotChecked, | 
					
						
							|  |  |  |             filteredLayer.isDisplayed | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-07-26 12:26:41 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class LayerFilterPanel extends Combine { | 
					
						
							|  |  |  |     public constructor(state: any, flayer: FilteredLayer) { | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |         const layer = flayer.layerDef | 
					
						
							| 
									
										
										
										
											2021-07-27 19:39:57 +02:00
										 |  |  |         if (layer.filters.length === 0) { | 
					
						
							| 
									
										
										
										
											2022-08-30 20:26:06 +02:00
										 |  |  |             super([]) | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const toShow: BaseUIElement[] = [] | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const filter of layer.filters) { | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             const [ui, actualTags] = LayerFilterPanel.createFilter(state, filter) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-01 04:14:54 +01:00
										 |  |  |             ui.SetClass("mt-1") | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |             toShow.push(ui) | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |             actualTags.addCallbackAndRun((tagsToFilterFor) => { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                 flayer.appliedFilters.data.set(filter.id, tagsToFilterFor) | 
					
						
							|  |  |  |                 flayer.appliedFilters.ping() | 
					
						
							| 
									
										
										
										
											2021-09-27 18:35:32 +02:00
										 |  |  |             }) | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |             flayer.appliedFilters | 
					
						
							|  |  |  |                 .map((dict) => dict.get(filter.id)) | 
					
						
							|  |  |  |                 .addCallbackAndRun((filters) => actualTags.setData(filters)) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-07 01:49:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |         super(toShow) | 
					
						
							|  |  |  |         this.SetClass("flex flex-col p-2 ml-12 pl-1 pt-0 layer-filters") | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |     // Filter which uses one or more textfields
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |     private static createFilterWithFields( | 
					
						
							|  |  |  |         state: any, | 
					
						
							|  |  |  |         filterConfig: FilterConfig | 
					
						
							|  |  |  |     ): [BaseUIElement, UIEventSource<FilterState>] { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         const filter = filterConfig.options[0] | 
					
						
							|  |  |  |         const mappings = new Map<string, BaseUIElement>() | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         let allValid: Store<boolean> = new ImmutableStore(true) | 
					
						
							|  |  |  |         var allFields: InputElement<string>[] = [] | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         const properties = new UIEventSource<any>({}) | 
					
						
							|  |  |  |         for (const { name, type } of filter.fields) { | 
					
						
							|  |  |  |             const value = QueryParameters.GetQueryParameter( | 
					
						
							|  |  |  |                 "filter-" + filterConfig.id + "-" + name, | 
					
						
							|  |  |  |                 "", | 
					
						
							|  |  |  |                 "Value for filter " + filterConfig.id | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:53:41 +01:00
										 |  |  |             const field = ValidatedTextField.ForType(type) | 
					
						
							|  |  |  |                 .ConstructInputElement({ | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                     value, | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |                 .SetClass("inline-block") | 
					
						
							|  |  |  |             mappings.set(name, field) | 
					
						
							|  |  |  |             const stable = value.stabilized(250) | 
					
						
							|  |  |  |             stable.addCallbackAndRunD((v) => { | 
					
						
							|  |  |  |                 properties.data[name] = v.toLowerCase() | 
					
						
							|  |  |  |                 properties.ping() | 
					
						
							|  |  |  |             }) | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |             allFields.push(field) | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |             allValid = allValid.map( | 
					
						
							|  |  |  |                 (previous) => previous && field.IsValid(stable.data) && stable.data !== "", | 
					
						
							|  |  |  |                 [stable] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |         const tr = new SubstitutedTranslation( | 
					
						
							|  |  |  |             filter.question, | 
					
						
							|  |  |  |             new UIEventSource<any>({ id: filterConfig.id }), | 
					
						
							|  |  |  |             state, | 
					
						
							|  |  |  |             mappings | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         const trigger: Store<FilterState> = allValid.map( | 
					
						
							|  |  |  |             (isValid) => { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                 if (!isValid) { | 
					
						
							|  |  |  |                     return undefined | 
					
						
							| 
									
										
										
										
											2022-01-07 17:31:39 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                 const props = properties.data | 
					
						
							|  |  |  |                 // Replace all the field occurences in the tags...
 | 
					
						
							| 
									
										
										
										
											2022-01-08 22:11:24 +01:00
										 |  |  |                 const tagsSpec = Utils.WalkJson(filter.originalTagsSpec, (v) => { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                     if (typeof v !== "string") { | 
					
						
							|  |  |  |                         return v | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2022-01-07 17:31:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                     for (const key in props) { | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |                         v = (<string>v).replace("{" + key + "}", props[key]) | 
					
						
							| 
									
										
										
										
											2022-01-07 17:31:39 +01:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                     return v | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                 const tagsFilter = TagUtils.Tag(tagsSpec) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                     currentFilter: tagsFilter, | 
					
						
							|  |  |  |                     state: JSON.stringify(props), | 
					
						
							| 
									
										
										
										
											2022-01-07 17:31:39 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |             }, | 
					
						
							|  |  |  |             [properties] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         const settableFilter = new UIEventSource<FilterState>(undefined) | 
					
						
							|  |  |  |         trigger.addCallbackAndRun((state) => settableFilter.setData(state)) | 
					
						
							|  |  |  |         settableFilter.addCallback((state) => { | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             if (state === undefined) { | 
					
						
							| 
									
										
										
										
											2022-06-13 20:16:39 +02:00
										 |  |  |                 // still initializing
 | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             if (state.currentFilter === undefined) { | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |                 allFields.forEach((f) => f.GetValue().setData(undefined)) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         return [tr, settableFilter] | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private static createCheckboxFilter( | 
					
						
							|  |  |  |         filterConfig: FilterConfig | 
					
						
							|  |  |  |     ): [BaseUIElement, UIEventSource<FilterState>] { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         let option = filterConfig.options[0] | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         const icon = Svg.checkbox_filled_svg().SetClass("block mr-2 w-6") | 
					
						
							|  |  |  |         const iconUnselected = Svg.checkbox_empty_svg().SetClass("block mr-2 w-6") | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         const toggle = new ClickableToggle( | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |             new Combine([icon, option.question.Clone().SetClass("block")]).SetClass("flex"), | 
					
						
							|  |  |  |             new Combine([iconUnselected, option.question.Clone().SetClass("block")]).SetClass( | 
					
						
							|  |  |  |                 "flex" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |             .ToggleOnClick() | 
					
						
							|  |  |  |             .SetClass("block m-1") | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |         return [ | 
					
						
							|  |  |  |             toggle, | 
					
						
							|  |  |  |             toggle.isEnabled.sync( | 
					
						
							|  |  |  |                 (enabled) => | 
					
						
							|  |  |  |                     enabled | 
					
						
							|  |  |  |                         ? { | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |                               currentFilter: option.osmTags, | 
					
						
							|  |  |  |                               state: "true", | 
					
						
							|  |  |  |                           } | 
					
						
							|  |  |  |                         : undefined, | 
					
						
							|  |  |  |                 [], | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                 (f) => f !== undefined | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |     private static createMultiFilter( | 
					
						
							|  |  |  |         filterConfig: FilterConfig | 
					
						
							|  |  |  |     ): [BaseUIElement, UIEventSource<FilterState>] { | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |         let options = filterConfig.options | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |         const values: FilterState[] = options.map((f, i) => ({ | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |             currentFilter: f.osmTags, | 
					
						
							|  |  |  |             state: i, | 
					
						
							| 
									
										
										
										
											2021-09-27 18:35:32 +02:00
										 |  |  |         })) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |         let filterPicker: InputElement<number> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (options.length <= 6) { | 
					
						
							|  |  |  |             filterPicker = new RadioButton( | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                 options.map( | 
					
						
							|  |  |  |                     (option, i) => | 
					
						
							|  |  |  |                         new FixedInputElement(option.question.Clone().SetClass("block"), i) | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     dontStyle: true, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |             filterPicker = new DropDown( | 
					
						
							|  |  |  |                 "", | 
					
						
							|  |  |  |                 options.map((option, i) => ({ | 
					
						
							|  |  |  |                     value: i, | 
					
						
							|  |  |  |                     shown: option.question.Clone(), | 
					
						
							|  |  |  |                 })) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |         return [ | 
					
						
							|  |  |  |             filterPicker, | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |             filterPicker.GetValue().sync( | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |                 (i) => values[i], | 
					
						
							| 
									
										
										
										
											2021-09-27 18:35:32 +02:00
										 |  |  |                 [], | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |                 (selected) => { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                     const v = selected?.state | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |                     if (v === undefined || typeof v === "string") { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |                         return undefined | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     return v | 
					
						
							| 
									
										
										
										
											2021-10-14 21:43:14 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-07-27 17:00:05 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |     private static createFilter( | 
					
						
							|  |  |  |         state: {}, | 
					
						
							|  |  |  |         filterConfig: FilterConfig | 
					
						
							|  |  |  |     ): [BaseUIElement, UIEventSource<FilterState>] { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         if (filterConfig.options[0].fields.length > 0) { | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             return LayerFilterPanel.createFilterWithFields(state, filterConfig) | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (filterConfig.options.length === 1) { | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |             return LayerFilterPanel.createCheckboxFilter(filterConfig) | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  |         const filter = LayerFilterPanel.createMultiFilter(filterConfig) | 
					
						
							| 
									
										
										
										
											2022-01-31 14:34:06 +01:00
										 |  |  |         filter[0].SetClass("pl-2") | 
					
						
							|  |  |  |         return filter | 
					
						
							| 
									
										
										
										
											2022-01-08 04:22:50 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-20 15:14:51 +02:00
										 |  |  | } |