forked from MapComplete/MapComplete
		
	Themes: allow to easily import tagrenderings and add a prefix key to all tags
This commit is contained in:
		
							parent
							
								
									4d9bdaf877
								
							
						
					
					
						commit
						01680f236c
					
				
					 9 changed files with 201 additions and 31 deletions
				
			
		| 
						 | 
					@ -0,0 +1,134 @@
 | 
				
			||||||
 | 
					import { DesugaringStep } from "./Conversion"
 | 
				
			||||||
 | 
					import { ConversionContext } from "./ConversionContext"
 | 
				
			||||||
 | 
					import SpecialVisualizations from "../../../UI/SpecialVisualizations"
 | 
				
			||||||
 | 
					import { Translatable } from "../Json/Translatable"
 | 
				
			||||||
 | 
					import { TagConfigJson } from "../Json/TagConfigJson"
 | 
				
			||||||
 | 
					import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class AddPrefixToTagRenderingConfig extends DesugaringStep<QuestionableTagRenderingConfigJson> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _prefix: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(prefix: string) {
 | 
				
			||||||
 | 
					        super("Adds `prefix` to _all_ keys. Used to add information about a subamenity withing a bigger amenity (e.g. toilets in a restaurant, a sauna in a water park, ...)", ["*"], "AddPrefixToTagRenderingConfig")
 | 
				
			||||||
 | 
					        this._prefix = prefix
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * const edit = new AddPrefixToTagRenderingConfig("PREFIX")
 | 
				
			||||||
 | 
					     * edit.updateString("Some string") // => "Some string"
 | 
				
			||||||
 | 
					     * edit.updateString("Some string {key0}") // => "Some string {PREFIX:key0}"
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * // Should prefix a key in a special visualisation
 | 
				
			||||||
 | 
					     * new AddPrefixToTagRenderingConfig("PREFIX").updateString("{opening_hours_table(opening_hours)}") // => "{opening_hours_table(PREFIX:opening_hours,,)}"
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * // Should prefix the default key in a special visualisation
 | 
				
			||||||
 | 
					     * new AddPrefixToTagRenderingConfig("PREFIX").updateString("{opening_hours_table()}") // => "{opening_hours_table(PREFIX:opening_hours,,)}"
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private updateString(str: string): string {
 | 
				
			||||||
 | 
					        const parsed = SpecialVisualizations.constructSpecification(str)
 | 
				
			||||||
 | 
					        const fixedSpec: string[] = []
 | 
				
			||||||
 | 
					        for (const spec of parsed) {
 | 
				
			||||||
 | 
					            if (typeof spec === "string") {
 | 
				
			||||||
 | 
					                const part = spec.replace(/{([a-zA-Z0-9:_-]+)}/g, `{${this._prefix}:$1}`)
 | 
				
			||||||
 | 
					                fixedSpec.push(part)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                const newArgs: string[] = []
 | 
				
			||||||
 | 
					                for (let i = 0; i < spec.func.args.length; i++) {
 | 
				
			||||||
 | 
					                    const argDoc = spec.func.args[i]
 | 
				
			||||||
 | 
					                    const argV = spec.args[i]
 | 
				
			||||||
 | 
					                    if (argDoc.type === "key") {
 | 
				
			||||||
 | 
					                        newArgs.push(this._prefix + ":" + (argV ?? argDoc.defaultValue ?? ""))
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        newArgs.push(argV ?? "")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                fixedSpec.push("{" + spec.func.funcName + "(" + newArgs.join(",") + ")}")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return fixedSpec.join("")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private updateTranslatable(val: Translatable | undefined): Translatable | undefined {
 | 
				
			||||||
 | 
					        if (!val) {
 | 
				
			||||||
 | 
					            return val
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (typeof val === "string") {
 | 
				
			||||||
 | 
					            return this.updateString(val)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const newTranslations: Record<string, string> = {}
 | 
				
			||||||
 | 
					        for (const lng in val) {
 | 
				
			||||||
 | 
					            newTranslations[lng] = this.updateString(val[lng])
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return newTranslations
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private updateTag(tags: string): string;
 | 
				
			||||||
 | 
					    private updateTag(tags: TagConfigJson): TagConfigJson;
 | 
				
			||||||
 | 
					    private updateTag(tags: TagConfigJson): TagConfigJson {
 | 
				
			||||||
 | 
					        if (!tags) {
 | 
				
			||||||
 | 
					            return tags
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (tags["and"]) {
 | 
				
			||||||
 | 
					            return { and: this.updateTags(tags["and"]) }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (tags["or"]) {
 | 
				
			||||||
 | 
					            return { or: this.updateTags(tags["or"]) }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this._prefix + ":" + tags
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private updateTags(tags: ReadonlyArray<string>): string[] {
 | 
				
			||||||
 | 
					        return tags?.map(tag => this.updateTag(tag))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private updateMapping(mapping: Readonly<MappingConfigJson>): MappingConfigJson {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            ...mapping,
 | 
				
			||||||
 | 
					            addExtraTags: this.updateTags(mapping.addExtraTags),
 | 
				
			||||||
 | 
					            if: this.updateTag(mapping.if),
 | 
				
			||||||
 | 
					            then: this.updateTranslatable(mapping.then),
 | 
				
			||||||
 | 
					            alsoShowIf: this.updateTag(mapping.alsoShowIf),
 | 
				
			||||||
 | 
					            ifnot: this.updateTag(mapping.ifnot),
 | 
				
			||||||
 | 
					            priorityIf: this.updateTag(mapping.priorityIf),
 | 
				
			||||||
 | 
					            hideInAnswer: mapping.hideInAnswer === true || mapping.hideInAnswer === false ? mapping.hideInAnswer : this.updateTag(mapping.hideInAnswer)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public convert(json: Readonly<QuestionableTagRenderingConfigJson>, context: ConversionContext): QuestionableTagRenderingConfigJson {
 | 
				
			||||||
 | 
					        let freeform = json.freeform
 | 
				
			||||||
 | 
					        if (freeform) {
 | 
				
			||||||
 | 
					            const ff = json.freeform
 | 
				
			||||||
 | 
					            freeform = {
 | 
				
			||||||
 | 
					                ...ff,
 | 
				
			||||||
 | 
					                key: this._prefix + ":" + ff.key,
 | 
				
			||||||
 | 
					                addExtraTags: this.updateTags(ff.addExtraTags)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return <QuestionableTagRenderingConfigJson>{
 | 
				
			||||||
 | 
					            ...json,
 | 
				
			||||||
 | 
					            id: this._prefix + "_" + json.id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            question: this.updateTranslatable(json.question),
 | 
				
			||||||
 | 
					            questionHint: this.updateTranslatable(json.questionHint),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            render: this.updateTranslatable(<Translatable>json.render),
 | 
				
			||||||
 | 
					            freeform,
 | 
				
			||||||
 | 
					            editButtonAriaLabel: json.editButtonAriaLabel,
 | 
				
			||||||
 | 
					            onSoftDelete: this.updateTags(json.onSoftDelete),
 | 
				
			||||||
 | 
					            invalidValues: this.updateTag(json.invalidValues),
 | 
				
			||||||
 | 
					            mappings: json.mappings?.map(mapping => this.updateMapping(mapping)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            condition: this.updateTag(json.condition),
 | 
				
			||||||
 | 
					            metacondition: json.metacondition, // no update here
 | 
				
			||||||
 | 
					            filter: json.filter === true, // We break references to filters, as those references won't have the updated tags
 | 
				
			||||||
 | 
					            _appliedPrefix: this._prefix
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@ import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRende
 | 
				
			||||||
import { TagUtils } from "../../../Logic/Tags/TagUtils"
 | 
					import { TagUtils } from "../../../Logic/Tags/TagUtils"
 | 
				
			||||||
import { Utils } from "../../../Utils"
 | 
					import { Utils } from "../../../Utils"
 | 
				
			||||||
import { AddContextToTranslations } from "./AddContextToTranslations"
 | 
					import { AddContextToTranslations } from "./AddContextToTranslations"
 | 
				
			||||||
 | 
					import AddPrefixToTagRenderingConfig from "./AddPrefixToTagRenderingConfig"
 | 
				
			||||||
 | 
					import { Translatable } from "../Json/Translatable"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class ExpandTagRendering extends Conversion<
 | 
					export class ExpandTagRendering extends Conversion<
 | 
				
			||||||
    | string
 | 
					    | string
 | 
				
			||||||
| 
						 | 
					@ -208,6 +210,21 @@ export class ExpandTagRendering extends Conversion<
 | 
				
			||||||
        let matchingTrs: (TagRenderingConfigJson & { id: string })[]
 | 
					        let matchingTrs: (TagRenderingConfigJson & { id: string })[]
 | 
				
			||||||
        if (id === "*") {
 | 
					        if (id === "*") {
 | 
				
			||||||
            matchingTrs = layerTrs
 | 
					            matchingTrs = layerTrs
 | 
				
			||||||
 | 
					        } else if (id === "title") {
 | 
				
			||||||
 | 
					            const title = layer.title
 | 
				
			||||||
 | 
					            if (title["render"] || title["mappings"]) {
 | 
				
			||||||
 | 
					                const titleTr = <TagRenderingConfigJson>layer.title
 | 
				
			||||||
 | 
					                return [{
 | 
				
			||||||
 | 
					                    ...titleTr,
 | 
				
			||||||
 | 
					                    id: layer.id + "_title"
 | 
				
			||||||
 | 
					                }]
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                const transl = <Translatable>layer.title
 | 
				
			||||||
 | 
					                return [{
 | 
				
			||||||
 | 
					                    render: transl,
 | 
				
			||||||
 | 
					                    id: layer.id + "_title"
 | 
				
			||||||
 | 
					                }]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else if (id.startsWith("*")) {
 | 
					        } else if (id.startsWith("*")) {
 | 
				
			||||||
            const id_ = id.substring(1)
 | 
					            const id_ = id.substring(1)
 | 
				
			||||||
            matchingTrs = layerTrs.filter((tr) => tr["labels"]?.indexOf(id_) >= 0)
 | 
					            matchingTrs = layerTrs.filter((tr) => tr["labels"]?.indexOf(id_) >= 0)
 | 
				
			||||||
| 
						 | 
					@ -249,6 +266,25 @@ export class ExpandTagRendering extends Conversion<
 | 
				
			||||||
        return undefined
 | 
					        return undefined
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns a variation of 'tr' where every key has been prefixed by the given 'prefix'-key.
 | 
				
			||||||
 | 
					     * If the given key is undefined, returns the original tagRendering.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Note: metacondition will _not_ be prefixed
 | 
				
			||||||
 | 
					     * @param key
 | 
				
			||||||
 | 
					     * @param tr
 | 
				
			||||||
 | 
					     * @private
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static applyKeyPrefix(key: string | undefined, tr: Readonly<QuestionableTagRenderingConfigJson>, ctx: ConversionContext): QuestionableTagRenderingConfigJson {
 | 
				
			||||||
 | 
					        if (key === undefined || key === null) {
 | 
				
			||||||
 | 
					            return tr
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (key.endsWith(":")) {
 | 
				
			||||||
 | 
					            ctx.err("A 'prefix'-key should not end with a colon. The offending prefix value is: " + key)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return new AddPrefixToTagRenderingConfig(key).convert(tr, ctx.enter("prefix"))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private convertOnce(
 | 
					    private convertOnce(
 | 
				
			||||||
        tr: string | { builtin: string | string[] } | TagRenderingConfigJson,
 | 
					        tr: string | { builtin: string | string[] } | TagRenderingConfigJson,
 | 
				
			||||||
        ctx: ConversionContext
 | 
					        ctx: ConversionContext
 | 
				
			||||||
| 
						 | 
					@ -310,6 +346,7 @@ export class ExpandTagRendering extends Conversion<
 | 
				
			||||||
                if (
 | 
					                if (
 | 
				
			||||||
                    key === "builtin" ||
 | 
					                    key === "builtin" ||
 | 
				
			||||||
                    key === "override" ||
 | 
					                    key === "override" ||
 | 
				
			||||||
 | 
					                    key === "prefix" ||
 | 
				
			||||||
                    key === "id" ||
 | 
					                    key === "id" ||
 | 
				
			||||||
                    key.startsWith("#")
 | 
					                    key.startsWith("#")
 | 
				
			||||||
                ) {
 | 
					                ) {
 | 
				
			||||||
| 
						 | 
					@ -379,6 +416,7 @@ export class ExpandTagRendering extends Conversion<
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                for (let foundTr of lookup) {
 | 
					                for (let foundTr of lookup) {
 | 
				
			||||||
                    foundTr = Utils.Clone(foundTr)
 | 
					                    foundTr = Utils.Clone(foundTr)
 | 
				
			||||||
 | 
					                    foundTr = ExpandTagRendering.applyKeyPrefix(tr["prefix"], foundTr, ctx)
 | 
				
			||||||
                    ctx.MergeObjectsForOverride(tr["override"] ?? {}, foundTr)
 | 
					                    ctx.MergeObjectsForOverride(tr["override"] ?? {}, foundTr)
 | 
				
			||||||
                    if (names.length == 1) {
 | 
					                    if (names.length == 1) {
 | 
				
			||||||
                        foundTr["id"] = tr["id"] ?? foundTr["id"]
 | 
					                        foundTr["id"] = tr["id"] ?? foundTr["id"]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,4 @@
 | 
				
			||||||
import {
 | 
					import { Concat, Conversion, DesugaringContext, DesugaringStep, Each, Fuse, On, Pass, SetDefault } from "./Conversion"
 | 
				
			||||||
    Concat,
 | 
					 | 
				
			||||||
    Conversion,
 | 
					 | 
				
			||||||
    DesugaringContext,
 | 
					 | 
				
			||||||
    DesugaringStep,
 | 
					 | 
				
			||||||
    Each,
 | 
					 | 
				
			||||||
    Fuse,
 | 
					 | 
				
			||||||
    On,
 | 
					 | 
				
			||||||
    Pass,
 | 
					 | 
				
			||||||
    SetDefault,
 | 
					 | 
				
			||||||
} from "./Conversion"
 | 
					 | 
				
			||||||
import { ThemeConfigJson } from "../Json/ThemeConfigJson"
 | 
					import { ThemeConfigJson } from "../Json/ThemeConfigJson"
 | 
				
			||||||
import { PrepareLayer, RewriteSpecial } from "./PrepareLayer"
 | 
					import { PrepareLayer, RewriteSpecial } from "./PrepareLayer"
 | 
				
			||||||
import { LayerConfigJson } from "../Json/LayerConfigJson"
 | 
					import { LayerConfigJson } from "../Json/LayerConfigJson"
 | 
				
			||||||
| 
						 | 
					@ -163,9 +153,8 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
 | 
				
			||||||
                const unused = Array.from(hideLabels).filter((l) => !usedLabels.has(l))
 | 
					                const unused = Array.from(hideLabels).filter((l) => !usedLabels.has(l))
 | 
				
			||||||
                if (unused.length > 0) {
 | 
					                if (unused.length > 0) {
 | 
				
			||||||
                    context.err(
 | 
					                    context.err(
 | 
				
			||||||
                        "This theme specifies that certain tagrenderings have to be removed based on forbidden layers. One or more of these layers did not match any tagRenderings and caused no deletions: " +
 | 
					                        `You are attempting to import layer '${found.id}' in this theme. This layer import specifies that certain tagrenderings have to be removed based on forbidden ids and/or labels. One or more of these forbidden ids did not match any tagRenderings and caused no deletions: ${unused.join(", ")}
 | 
				
			||||||
                            unused.join(", ") +
 | 
					   This means that this label can be removed or that the original tagRendering that should be deleted does not have this label anymore`
 | 
				
			||||||
                            "\n   This means that this label can be removed or that the original tagRendering that should be deleted does not have this label anymore"
 | 
					 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                found.tagRenderings = filtered
 | 
					                found.tagRenderings = filtered
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -422,8 +422,15 @@ export interface LayerConfigJson {
 | 
				
			||||||
        | string
 | 
					        | string
 | 
				
			||||||
        | {
 | 
					        | {
 | 
				
			||||||
              id?: string
 | 
					              id?: string
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Special value: "<layerid>.title" will return the layer's title for an element
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
              builtin: string | string[]
 | 
					              builtin: string | string[]
 | 
				
			||||||
              override: Partial<QuestionableTagRenderingConfigJson>
 | 
					        override: Partial<QuestionableTagRenderingConfigJson>,
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Add this prefix to all keys. This is applied _before_ the override, thus keys added in 'override' will not be prefixed
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        prefix?: string
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        | QuestionableTagRenderingConfigJson
 | 
					        | QuestionableTagRenderingConfigJson
 | 
				
			||||||
        | (RewritableConfigJson<
 | 
					        | (RewritableConfigJson<
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -289,7 +289,7 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs
 | 
				
			||||||
         * Extra arguments to configure the input element
 | 
					         * Extra arguments to configure the input element
 | 
				
			||||||
         * group: hidden
 | 
					         * group: hidden
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        helperArgs: any
 | 
					        helperArgs?: any
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ import NearbyImagesCollapsed from "../Image/NearbyImagesCollapsed.svelte"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NearbyImageVis implements SpecialVisualizationSvelte {
 | 
					class NearbyImageVis implements SpecialVisualizationSvelte {
 | 
				
			||||||
    // Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
 | 
					    // Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
 | 
				
			||||||
    args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
 | 
					    args: [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            name: "mode",
 | 
					            name: "mode",
 | 
				
			||||||
            defaultValue: "closed",
 | 
					            defaultValue: "closed",
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,7 @@ export class ImageVisualisations {
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "image_key",
 | 
					                        name: "image_key",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        defaultValue: AllImageProviders.defaultKeys.join(";"),
 | 
					                        defaultValue: AllImageProviders.defaultKeys.join(";"),
 | 
				
			||||||
                        doc: "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated ",
 | 
					                        doc: "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated ",
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					@ -95,6 +96,7 @@ export class ImageVisualisations {
 | 
				
			||||||
                needsUrls: [Imgur.apiUrl, ...Imgur.supportingUrls],
 | 
					                needsUrls: [Imgur.apiUrl, ...Imgur.supportingUrls],
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        name: "image_key",
 | 
					                        name: "image_key",
 | 
				
			||||||
                        doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)",
 | 
					                        doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)",
 | 
				
			||||||
                        defaultValue: "panoramax",
 | 
					                        defaultValue: "panoramax",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,7 @@
 | 
				
			||||||
import { Store, UIEventSource } from "../Logic/UIEventSource"
 | 
					import { Store, UIEventSource } from "../Logic/UIEventSource"
 | 
				
			||||||
import BaseUIElement from "./BaseUIElement"
 | 
					import BaseUIElement from "./BaseUIElement"
 | 
				
			||||||
import ThemeConfig from "../Models/ThemeConfig/ThemeConfig"
 | 
					import ThemeConfig from "../Models/ThemeConfig/ThemeConfig"
 | 
				
			||||||
import {
 | 
					import { FeatureSource, IndexedFeatureSource, WritableFeatureSource } from "../Logic/FeatureSource/FeatureSource"
 | 
				
			||||||
    FeatureSource,
 | 
					 | 
				
			||||||
    IndexedFeatureSource,
 | 
					 | 
				
			||||||
    WritableFeatureSource,
 | 
					 | 
				
			||||||
} from "../Logic/FeatureSource/FeatureSource"
 | 
					 | 
				
			||||||
import { OsmConnection } from "../Logic/Osm/OsmConnection"
 | 
					import { OsmConnection } from "../Logic/Osm/OsmConnection"
 | 
				
			||||||
import { Changes } from "../Logic/Osm/Changes"
 | 
					import { Changes } from "../Logic/Osm/Changes"
 | 
				
			||||||
import { ExportableMap, MapProperties } from "../Models/MapProperties"
 | 
					import { ExportableMap, MapProperties } from "../Models/MapProperties"
 | 
				
			||||||
| 
						 | 
					@ -100,7 +96,8 @@ export interface SpecialVisualization {
 | 
				
			||||||
        name: string
 | 
					        name: string
 | 
				
			||||||
        defaultValue?: string
 | 
					        defaultValue?: string
 | 
				
			||||||
        doc: string
 | 
					        doc: string
 | 
				
			||||||
        required?: false | boolean
 | 
					        required?: false | boolean,
 | 
				
			||||||
 | 
					        type?: "key"
 | 
				
			||||||
    }[]
 | 
					    }[]
 | 
				
			||||||
    readonly getLayerDependencies?: (argument: string[]) => string[]
 | 
					    readonly getLayerDependencies?: (argument: string[]) => string[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,7 +130,8 @@ export interface SpecialVisualizationSvelte {
 | 
				
			||||||
        name: string
 | 
					        name: string
 | 
				
			||||||
        defaultValue?: string
 | 
					        defaultValue?: string
 | 
				
			||||||
        doc: string
 | 
					        doc: string
 | 
				
			||||||
        required?: false | boolean
 | 
					        required?: false | boolean,
 | 
				
			||||||
 | 
					        type?: "key" | string
 | 
				
			||||||
    }[]
 | 
					    }[]
 | 
				
			||||||
    readonly getLayerDependencies?: (argument: string[]) => string[]
 | 
					    readonly getLayerDependencies?: (argument: string[]) => string[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -257,6 +257,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "key",
 | 
					                        name: "key",
 | 
				
			||||||
                        defaultValue: "opening_hours",
 | 
					                        defaultValue: "opening_hours",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        doc: "The tagkey from which the table is constructed.",
 | 
					                        doc: "The tagkey from which the table is constructed.",
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
| 
						 | 
					@ -284,6 +285,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "key",
 | 
					                        name: "key",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        defaultValue: "opening_hours",
 | 
					                        defaultValue: "opening_hours",
 | 
				
			||||||
                        doc: "The tagkey from which the opening hours are read.",
 | 
					                        doc: "The tagkey from which the opening hours are read.",
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					@ -324,6 +326,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "key",
 | 
					                        name: "key",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        doc: "The key of the tag to give the canonical text for",
 | 
					                        doc: "The key of the tag to give the canonical text for",
 | 
				
			||||||
                        required: true,
 | 
					                        required: true,
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					@ -412,6 +415,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "key",
 | 
					                        name: "key",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        doc: "The attribute to interpret as json",
 | 
					                        doc: "The attribute to interpret as json",
 | 
				
			||||||
                        defaultValue: "value",
 | 
					                        defaultValue: "value",
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					@ -463,6 +467,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "key",
 | 
					                        name: "key",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        defaultValue: "value",
 | 
					                        defaultValue: "value",
 | 
				
			||||||
                        doc: "The key to look for the tags",
 | 
					                        doc: "The key to look for the tags",
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					@ -470,9 +475,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                constr(
 | 
					                constr(
 | 
				
			||||||
                    state: SpecialVisualizationState,
 | 
					                    state: SpecialVisualizationState,
 | 
				
			||||||
                    tagSource: UIEventSource<Record<string, string>>,
 | 
					                    tagSource: UIEventSource<Record<string, string>>,
 | 
				
			||||||
                    argument: string[],
 | 
					                    argument: string[]
 | 
				
			||||||
                    feature: Feature,
 | 
					 | 
				
			||||||
                    layer: LayerConfig
 | 
					 | 
				
			||||||
                ): BaseUIElement {
 | 
					                ): BaseUIElement {
 | 
				
			||||||
                    const key = argument[0] ?? "value"
 | 
					                    const key = argument[0] ?? "value"
 | 
				
			||||||
                    return new VariableUiElement(
 | 
					                    return new VariableUiElement(
 | 
				
			||||||
| 
						 | 
					@ -508,8 +511,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                    state: SpecialVisualizationState,
 | 
					                    state: SpecialVisualizationState,
 | 
				
			||||||
                    tagSource: UIEventSource<Record<string, string>>,
 | 
					                    tagSource: UIEventSource<Record<string, string>>,
 | 
				
			||||||
                    argument: string[],
 | 
					                    argument: string[],
 | 
				
			||||||
                    feature: Feature,
 | 
					                    feature: Feature
 | 
				
			||||||
                    layer: LayerConfig
 | 
					 | 
				
			||||||
                ): BaseUIElement {
 | 
					                ): BaseUIElement {
 | 
				
			||||||
                    return new SvelteUIElement(DirectionIndicator, { state, feature })
 | 
					                    return new SvelteUIElement(DirectionIndicator, { state, feature })
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
| 
						 | 
					@ -520,6 +522,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                args: [
 | 
					                args: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name: "key",
 | 
					                        name: "key",
 | 
				
			||||||
 | 
					                        type: "key",
 | 
				
			||||||
                        doc: "The attribute containing the degrees",
 | 
					                        doc: "The attribute containing the degrees",
 | 
				
			||||||
                        defaultValue: "_direction:centerpoint",
 | 
					                        defaultValue: "_direction:centerpoint",
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -466,8 +466,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
 | 
				
			||||||
            if (v !== undefined && v !== null) {
 | 
					            if (v !== undefined && v !== null) {
 | 
				
			||||||
                if (v["toISOString"] != undefined) {
 | 
					                if (v["toISOString"] != undefined) {
 | 
				
			||||||
                    // This is a date, probably the timestamp of the object
 | 
					                    // This is a date, probably the timestamp of the object
 | 
				
			||||||
                    // @ts-ignore
 | 
					                    const date: Date = v
 | 
				
			||||||
                    const date: Date = el
 | 
					 | 
				
			||||||
                    v = date.toISOString()
 | 
					                    v = date.toISOString()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue