Add question box as special rendering

This commit is contained in:
Pieter Vander Vennet 2023-03-31 03:28:11 +02:00
parent 15664df63f
commit d47fd7e746
42 changed files with 956 additions and 311 deletions

View file

@ -5,27 +5,27 @@ import { Utils } from "../../Utils"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { Feature } from "geojson"
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer.svelte"
import TagRenderingAnswer from "../../UI/Popup/TagRendering/TagRenderingAnswer.svelte"
import { SpecialVisualizationState } from "../../UI/SpecialVisualization"
export default class TitleHandler {
constructor(
selectedElement: Store<Feature>,
selectedLayer: Store<LayerConfig>,
allElements: FeaturePropertiesStore,
layout: LayoutConfig
state: SpecialVisualizationState
) {
const currentTitle: Store<string> = selectedElement.map(
(selected) => {
const defaultTitle = layout?.title?.txt ?? "MapComplete"
const defaultTitle = state.layout?.title?.txt ?? "MapComplete"
if (selected === undefined) {
return defaultTitle
}
const tags = selected.properties
for (const layer of layout?.layers ?? []) {
for (const layer of state.layout?.layers ?? []) {
if (layer.title === undefined) {
continue
}
@ -33,7 +33,12 @@ export default class TitleHandler {
const tagsSource =
allElements.getStore(tags.id) ??
new UIEventSource<Record<string, string>>(tags)
const title = new SvelteUIElement(TagRenderingAnswer, { tags: tagsSource })
const title = new SvelteUIElement(TagRenderingAnswer, {
tags: tagsSource,
state,
selectedElement: selectedElement.data,
layer: selectedLayer.data,
})
return (
new Combine([defaultTitle, " | ", title]).ConstructElement()
?.textContent ?? defaultTitle

View file

@ -39,7 +39,7 @@ export class And extends TagsFilter {
return new And(ands)
}
matchesProperties(tags: any): boolean {
matchesProperties(tags: Record<string, string>): boolean {
for (const tagsFilter of this.and) {
if (!tagsFilter.matchesProperties(tags)) {
return false
@ -147,7 +147,7 @@ export class And extends TagsFilter {
return [].concat(...this.and.map((subkeys) => subkeys.usedTags()))
}
asChange(properties: any): { k: string; v: string }[] {
asChange(properties: Record<string, string>): { k: string; v: string }[] {
const result = []
for (const tagsFilter of this.and) {
result.push(...tagsFilter.asChange(properties))
@ -375,7 +375,7 @@ export class And extends TagsFilter {
return !this.and.some((t) => !t.isNegative())
}
visit(f: (TagsFilter: any) => void) {
visit(f: (tagsFilter: TagsFilter) => void) {
f(this)
this.and.forEach((sub) => sub.visit(f))
}

View file

@ -15,11 +15,11 @@ export default class ComparingTag implements TagsFilter {
this._representation = representation
}
asChange(properties: any): { k: string; v: string }[] {
asChange(properties: Record<string, string>): { k: string; v: string }[] {
throw "A comparable tag can not be used to be uploaded to OSM"
}
asHumanString(linkToWiki: boolean, shorten: boolean, properties: any) {
asHumanString(linkToWiki: boolean, shorten: boolean, properties: Record<string, string>) {
return this._key + this._representation
}
@ -44,7 +44,7 @@ export default class ComparingTag implements TagsFilter {
* t.matchesProperties({key: 0}) // => true
* t.matchesProperties({differentKey: 42}) // => false
*/
matchesProperties(properties: any): boolean {
matchesProperties(properties: Record<string, string>): boolean {
return this._predicate(properties[this._key])
}

View file

@ -17,7 +17,7 @@ export class Or extends TagsFilter {
return new Or(or)
}
matchesProperties(properties: any): boolean {
matchesProperties(properties: Record<string, string>): boolean {
for (const tagsFilter of this.or) {
if (tagsFilter.matchesProperties(properties)) {
return true
@ -82,7 +82,7 @@ export class Or extends TagsFilter {
return [].concat(...this.or.map((subkeys) => subkeys.usedTags()))
}
asChange(properties: any): { k: string; v: string }[] {
asChange(properties: Record<string, string>): { k: string; v: string }[] {
const result = []
for (const tagsFilter of this.or) {
result.push(...tagsFilter.asChange(properties))
@ -260,7 +260,7 @@ export class Or extends TagsFilter {
return this.or.some((t) => t.isNegative())
}
visit(f: (TagsFilter: any) => void) {
visit(f: (tagsFilter: TagsFilter) => void) {
f(this)
this.or.forEach((t) => t.visit(f))
}

View file

@ -122,7 +122,7 @@ export class RegexTag extends TagsFilter {
* new RegexTag("key","value").matchesProperties({"otherkey":"value"}) // => false
* new RegexTag("key","value",true).matchesProperties({"otherkey":"something"}) // => true
*/
matchesProperties(tags: any): boolean {
matchesProperties(tags: Record<string, string>): boolean {
if (typeof this.key === "string") {
const value = tags[this.key] ?? ""
return RegexTag.doesMatch(value, this.value) != this.invert
@ -244,7 +244,7 @@ export class RegexTag extends TagsFilter {
return []
}
asChange(properties: any): { k: string; v: string }[] {
asChange(properties: Record<string, string>): { k: string; v: string }[] {
if (this.invert) {
return []
}

View file

@ -22,7 +22,7 @@ export default class SubstitutingTag implements TagsFilter {
this._invert = invert
}
private static substituteString(template: string, dict: any): string {
private static substituteString(template: string, dict: Record<string, string>): string {
for (const k in dict) {
template = template.replace(new RegExp("\\{" + k + "\\}", "g"), dict[k])
}
@ -72,7 +72,7 @@ export default class SubstitutingTag implements TagsFilter {
* assign.matchesProperties({"_date:now": "2021-03-29"}) // => false
* assign.matchesProperties({"some_key": "2021-03-29"}) // => false
*/
matchesProperties(properties: any): boolean {
matchesProperties(properties: Record<string, string>): boolean {
const value = properties[this._key]
if (value === undefined || value === "") {
return false
@ -89,7 +89,7 @@ export default class SubstitutingTag implements TagsFilter {
return []
}
asChange(properties: any): { k: string; v: string }[] {
asChange(properties: Record<string, string>): { k: string; v: string }[] {
if (this._invert) {
throw "An inverted substituting tag can not be used to create a change"
}
@ -108,7 +108,7 @@ export default class SubstitutingTag implements TagsFilter {
return false
}
visit(f: (TagsFilter: any) => void) {
visit(f: (tagsFilter: TagsFilter) => void) {
f(this)
}
}

View file

@ -37,7 +37,7 @@ export class Tag extends TagsFilter {
* isEmpty.matchesProperties({"key": undefined}) // => true
*
*/
matchesProperties(properties: any): boolean {
matchesProperties(properties: Record<string, string>): boolean {
const foundValue = properties[this.key]
if (foundValue === undefined && (this.value === "" || this.value === undefined)) {
// The tag was not found
@ -62,7 +62,11 @@ export class Tag extends TagsFilter {
t.asHumanString() // => "key=value"
t.asHumanString(true) // => "<a href='https://wiki.openstreetmap.org/wiki/Key:key' target='_blank'>key</a>=<a href='https://wiki.openstreetmap.org/wiki/Tag:key%3Dvalue' target='_blank'>value</a>"
*/
asHumanString(linkToWiki?: boolean, shorten?: boolean, currentProperties?: any) {
asHumanString(
linkToWiki?: boolean,
shorten?: boolean,
currentProperties?: Record<string, string>
) {
let v = this.value
if (shorten) {
v = Utils.EllipsesAfter(v, 25)
@ -134,7 +138,7 @@ export class Tag extends TagsFilter {
return false
}
visit(f: (TagsFilter) => void) {
visit(f: (tagsFilter: TagsFilter) => void) {
f(this)
}
}

View file

@ -9,9 +9,13 @@ export abstract class TagsFilter {
*/
abstract shadows(other: TagsFilter): boolean
abstract matchesProperties(properties: any): boolean
abstract matchesProperties(properties: Record<string, string>): boolean
abstract asHumanString(linkToWiki: boolean, shorten: boolean, properties: any): string
abstract asHumanString(
linkToWiki: boolean,
shorten: boolean,
properties: Record<string, string>
): string
abstract usedKeys(): string[]
@ -27,7 +31,7 @@ export abstract class TagsFilter {
*
* Note: properties are the already existing tags-object. It is only used in the substituting tag
*/
abstract asChange(properties: any): { k: string; v: string }[]
abstract asChange(properties: Record<string, string>): { k: string; v: string }[]
/**
* Returns an optimized version (or self) of this tagsFilter
@ -54,5 +58,5 @@ export abstract class TagsFilter {
/**
* Walks the entire tree, every tagsFilter will be passed into the function once
*/
abstract visit(f: (TagsFilter) => void)
abstract visit(f: (tagsFilter: TagsFilter) => void)
}

View file

@ -35,6 +35,14 @@ export class QueryParameters {
return source
}
public static SetDefaultFor(key: string, value: string) {
if (QueryParameters.defaults[key] === value) {
return
}
QueryParameters.defaults[key] = value
QueryParameters.Serialize()
}
public static GetBooleanQueryParameter(
key: string,
deflt: boolean,
@ -80,6 +88,11 @@ export class QueryParameters {
}
}
/**
* Set the query parameters of the page location
* @constructor
* @private
*/
private static Serialize() {
const parts = []
for (const key of QueryParameters.order) {