forked from MapComplete/MapComplete
		
	TagRenderingConfig: fix 'leftovers' of multi-answer freeform, generateDocs now generates Markdown instead of a BaseUIElement, add 'postfixDistinguished'-option for 'charge'-key
This commit is contained in:
		
							parent
							
								
									53ef1b947d
								
							
						
					
					
						commit
						3a69157d10
					
				
					 4 changed files with 138 additions and 92 deletions
				
			
		|  | @ -867,6 +867,7 @@ | ||||||
|     }, |     }, | ||||||
|     "website", |     "website", | ||||||
|     { |     { | ||||||
|  |       "id": "charge_cost_rewritten", | ||||||
|       "rewrite": { |       "rewrite": { | ||||||
|         "sourceString": [ |         "sourceString": [ | ||||||
|           "{product_key}", |           "{product_key}", | ||||||
|  | @ -902,7 +903,9 @@ | ||||||
|           ] |           ] | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "renderings": { |       "renderings": [ | ||||||
|  |         { | ||||||
|  |           "id": "charge_{product_key}", | ||||||
|           "question": { |           "question": { | ||||||
|             "en": "How much does a {product_name} cost?", |             "en": "How much does a {product_name} cost?", | ||||||
|             "ca": "Quant costa {product_name}?", |             "ca": "Quant costa {product_name}?", | ||||||
|  | @ -914,22 +917,24 @@ | ||||||
|             "pt": "Quanto custa {product_name}?" |             "pt": "Quanto custa {product_name}?" | ||||||
|           }, |           }, | ||||||
|           "render": { |           "render": { | ||||||
|           "en": "{product_name} costs {charge:{product_key}}", |             "en": "{product_name} costs {charge}", | ||||||
|           "ca": "{product_name} costa {charge:{product_key}}", |             "ca": "{product_name} costa {charge}", | ||||||
|           "de": "{product_name} kostet {charge:{product_key}}", |             "de": "{product_name} kostet {charge}", | ||||||
|           "cs": "{product_name} {charge:{product_key}}", |             "cs": "{product_name} {charge}", | ||||||
|           "nl": "{product_name} kost {charge:{product_key}}", |             "nl": "{product_name} kost {charge}", | ||||||
|           "pt_BR": "{product_name} custa {charge:{product_key}}", |             "pt_BR": "{product_name} custa {charge}", | ||||||
|           "es": "{product_name} cuesta {charge:{product_key}}", |             "es": "{product_name} cuesta {charge}", | ||||||
|           "pt": "{product_name} custa {charge:{product_key}}" |             "pt": "{product_name} custa {charge}" | ||||||
|           }, |           }, | ||||||
|           "freeform": { |           "freeform": { | ||||||
|           "key": "charge:{product_key}", |             "key": "charge", | ||||||
|           "type": "currency" |             "type": "currency", | ||||||
|  |             "inline": true, | ||||||
|  |             "postfixDistinguished":  "{product_key}" | ||||||
|           }, |           }, | ||||||
|         "condition": "vending~.*{product_key}.*", |           "condition": "vending~.*{product_key}.*" | ||||||
|         "id": "charge_{product_key}" |  | ||||||
|         } |         } | ||||||
|  |       ] | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "id": "operational_status", |       "id": "operational_status", | ||||||
|  |  | ||||||
|  | @ -264,7 +264,22 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs | ||||||
|          * ifunset: The question will be considered answered if any value is set for the key |          * ifunset: The question will be considered answered if any value is set for the key | ||||||
|          * group: expert |          * group: expert | ||||||
|          */ |          */ | ||||||
|         invalidValues?: TagConfigJson |         invalidValues?: TagConfigJson, | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * question: If this key shared and distinguished by a postfix, what is the postfix? | ||||||
|  |          * This option is used specifically for `charge`, where the cost is indicated with `/item`. | ||||||
|  |          * | ||||||
|  |          * For example, a vending machine might sell `bicycle_tube`. | ||||||
|  |          * Setting this value to `bicycle_tube`, then answering this question will set `charge= €XX/bicycle_tube`. | ||||||
|  |          * If charge did already contain another value, e.g. `charge= €YY/some_item; €ZZ/other_item`, then `€XX/bicycle_tube`will be added. | ||||||
|  |          * Note: those values are sorted alphabetically | ||||||
|  |          * Note: no need to add the `/` | ||||||
|  |          * | ||||||
|  |          * ifunset: Don't distinguish by postfix | ||||||
|  |          * group: expert | ||||||
|  |          */ | ||||||
|  |         postfixDistinguished?: string | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  |  | ||||||
|  | @ -5,13 +5,8 @@ import { TagUtils, UploadableTag } from "../../Logic/Tags/TagUtils" | ||||||
| import { And } from "../../Logic/Tags/And" | import { And } from "../../Logic/Tags/And" | ||||||
| import { Utils } from "../../Utils" | import { Utils } from "../../Utils" | ||||||
| import { Tag } from "../../Logic/Tags/Tag" | import { Tag } from "../../Logic/Tags/Tag" | ||||||
| import BaseUIElement from "../../UI/BaseUIElement" |  | ||||||
| import Combine from "../../UI/Base/Combine" |  | ||||||
| import Title from "../../UI/Base/Title" |  | ||||||
| import Link from "../../UI/Base/Link" | import Link from "../../UI/Base/Link" | ||||||
| import List from "../../UI/Base/List" |  | ||||||
| import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "./Json/QuestionableTagRenderingConfigJson" | import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "./Json/QuestionableTagRenderingConfigJson" | ||||||
| import { FixedUiElement } from "../../UI/Base/FixedUiElement" |  | ||||||
| import Validators, { ValidatorType } from "../../UI/InputElement/Validators" | import Validators, { ValidatorType } from "../../UI/InputElement/Validators" | ||||||
| import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson" | import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson" | ||||||
| import { RegexTag } from "../../Logic/Tags/RegexTag" | import { RegexTag } from "../../Logic/Tags/RegexTag" | ||||||
|  | @ -19,9 +14,7 @@ import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" | ||||||
| import NameSuggestionIndex from "../../Logic/Web/NameSuggestionIndex" | import NameSuggestionIndex from "../../Logic/Web/NameSuggestionIndex" | ||||||
| import { GeoOperations } from "../../Logic/GeoOperations" | import { GeoOperations } from "../../Logic/GeoOperations" | ||||||
| import { Feature } from "geojson" | import { Feature } from "geojson" | ||||||
| 
 | import MarkdownUtils from "../../Utils/MarkdownUtils" | ||||||
| export interface Icon { |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| export interface Mapping { | export interface Mapping { | ||||||
|     readonly if: UploadableTag |     readonly if: UploadableTag | ||||||
|  | @ -72,6 +65,7 @@ export default class TagRenderingConfig { | ||||||
|         readonly addExtraTags: UploadableTag[] |         readonly addExtraTags: UploadableTag[] | ||||||
|         readonly inline: boolean |         readonly inline: boolean | ||||||
|         readonly default?: string |         readonly default?: string | ||||||
|  |         readonly postfixDistinguished?: string | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public readonly multiAnswer: boolean |     public readonly multiAnswer: boolean | ||||||
|  | @ -201,7 +195,8 @@ export default class TagRenderingConfig { | ||||||
|                         TagUtils.ParseUploadableTag(tg, `${context}.extratag[${i}]`) |                         TagUtils.ParseUploadableTag(tg, `${context}.extratag[${i}]`) | ||||||
|                     ) ?? [], |                     ) ?? [], | ||||||
|                 inline: json.freeform.inline ?? false, |                 inline: json.freeform.inline ?? false, | ||||||
|                 default: json.freeform.default |                 default: json.freeform.default, | ||||||
|  |                 postfixDistinguished: json.freeform.postfixDistinguished?.trim() | ||||||
|             } |             } | ||||||
|             if (json.freeform["extraTags"] !== undefined) { |             if (json.freeform["extraTags"] !== undefined) { | ||||||
|                 throw `Freeform.extraTags is defined. This should probably be 'freeform.addExtraTag' (at ${context})` |                 throw `Freeform.extraTags is defined. This should probably be 'freeform.addExtraTag' (at ${context})` | ||||||
|  | @ -218,6 +213,14 @@ export default class TagRenderingConfig { | ||||||
|                     throw `If you use a freeform key 'questions', the ID must be 'questions' too to trigger the special behaviour. The current id is '${this.id}' (at ${context})` |                     throw `If you use a freeform key 'questions', the ID must be 'questions' too to trigger the special behaviour. The current id is '${this.id}' (at ${context})` | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             if (this.freeform.postfixDistinguished) { | ||||||
|  |                 if (this.multiAnswer) { | ||||||
|  |                     throw "At " + context + ": a postfixDistinguished-value cannot be used with a multiAnswer" | ||||||
|  |                 } | ||||||
|  |                 if (this.freeform.postfixDistinguished.startsWith("/")) { | ||||||
|  |                     throw "At " + context + ": a postfixDistinguished-value should not start with `/`. This will be inserted automatically" | ||||||
|  |                 } | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             // freeform.type is validated in Validation.ts so that we don't need ValidatedTextFields here
 |             // freeform.type is validated in Validation.ts so that we don't need ValidatedTextFields here
 | ||||||
|             if (this.freeform.addExtraTags) { |             if (this.freeform.addExtraTags) { | ||||||
|  | @ -466,9 +469,9 @@ export default class TagRenderingConfig { | ||||||
|         // A flag to check that the freeform key isn't matched multiple times
 |         // A flag to check that the freeform key isn't matched multiple times
 | ||||||
|         // If it is undefined, it is "used" already, or at least we don't have to check for it anymore
 |         // If it is undefined, it is "used" already, or at least we don't have to check for it anymore
 | ||||||
|         const freeformKeyDefined = this.freeform?.key !== undefined |         const freeformKeyDefined = this.freeform?.key !== undefined | ||||||
|         const usedFreeformValues = new Set<string>() |  | ||||||
|         // We run over all the mappings first, to check if the mapping matches
 |         // We run over all the mappings first, to check if the mapping matches
 | ||||||
|         const applicableMappings: { |         const applicableMappings: { | ||||||
|  |             if?: TagsFilter | ||||||
|             then: TypedTranslation<Record<string, string>> |             then: TypedTranslation<Record<string, string>> | ||||||
|             img?: string |             img?: string | ||||||
|         }[] = Utils.NoNull( |         }[] = Utils.NoNull( | ||||||
|  | @ -477,23 +480,23 @@ export default class TagRenderingConfig { | ||||||
|                     return mapping |                     return mapping | ||||||
|                 } |                 } | ||||||
|                 if (TagUtils.MatchesMultiAnswer(mapping.if, tags)) { |                 if (TagUtils.MatchesMultiAnswer(mapping.if, tags)) { | ||||||
|                     if (freeformKeyDefined && mapping.if.isUsableAsAnswer()) { |  | ||||||
|                         // THe freeform key is defined: what value does it use though?
 |  | ||||||
|                         // We mark the value to see if we have any leftovers
 |  | ||||||
|                         const value = mapping.if |  | ||||||
|                             .asChange({}) |  | ||||||
|                             .find((kv) => kv.k === this.freeform.key).v |  | ||||||
|                         usedFreeformValues.add(value) |  | ||||||
|                     } |  | ||||||
|                     return mapping |                     return mapping | ||||||
|                 } |                 } | ||||||
|                 return undefined |                 return undefined | ||||||
|             }) |             }) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         if (freeformKeyDefined && tags[this.freeform.key] !== undefined) { |         if (freeformKeyDefined && tags[this.freeform.key] !== undefined) { | ||||||
|  |             const usedFreeformValues = new Set<string>( | ||||||
|  |                 applicableMappings | ||||||
|  |                     ?.flatMap(m => m.if?.usedTags() ?? []) | ||||||
|  |                     ?.filter(kv => kv.key === this.freeform.key) | ||||||
|  |                     ?.map(kv => kv.value) | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|             const freeformValues = tags[this.freeform.key].split(";") |             const freeformValues = tags[this.freeform.key].split(";") | ||||||
|             const leftovers = freeformValues.filter((v) => !usedFreeformValues.has(v)) |             const leftovers = freeformValues.filter((v) => !usedFreeformValues.has(v.trim())) | ||||||
|             for (const leftover of leftovers) { |             for (const leftover of leftovers) { | ||||||
|                 applicableMappings.push({ |                 applicableMappings.push({ | ||||||
|                     then: new TypedTranslation<object>( |                     then: new TypedTranslation<object>( | ||||||
|  | @ -539,6 +542,23 @@ export default class TagRenderingConfig { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (this.freeform?.key === undefined || tags[this.freeform.key] !== undefined) { |         if (this.freeform?.key === undefined || tags[this.freeform.key] !== undefined) { | ||||||
|  |             const postfix = this.freeform?.postfixDistinguished | ||||||
|  |             if (postfix !== undefined) { | ||||||
|  |                 const allFreeforms = tags[this.freeform.key].split(";").map(s => s.trim()) | ||||||
|  |                 for (const allFreeform of allFreeforms) { | ||||||
|  |                     if (allFreeform.endsWith(postfix)) { | ||||||
|  |                         const [v] = allFreeform.split("/") | ||||||
|  |                         // We found the needed postfix
 | ||||||
|  |                         return { | ||||||
|  |                             then: this.render.PartialSubs({ [this.freeform.key]: v.trim() }), | ||||||
|  |                             icon: this.renderIcon, | ||||||
|  |                             iconClass: this.renderIconClass | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 // needed postfix not found
 | ||||||
|  |                 return undefined | ||||||
|  |             } | ||||||
|             return { then: this.render, icon: this.renderIcon, iconClass: this.renderIconClass } |             return { then: this.render, icon: this.renderIcon, iconClass: this.renderIconClass } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -643,6 +663,11 @@ export default class TagRenderingConfig { | ||||||
|      * const tags = config.constructChangeSpecification("Tu-Fr 05:30-09:30", undefined, undefined, { }} |      * const tags = config.constructChangeSpecification("Tu-Fr 05:30-09:30", undefined, undefined, { }} | ||||||
|      * tags // =>new And([ new Tag("opening_hours", "Tu-Fr 05:30-09:30")])
 |      * tags // =>new And([ new Tag("opening_hours", "Tu-Fr 05:30-09:30")])
 | ||||||
|      * |      * | ||||||
|  |      * const config = new TagRenderingConfig({"id": "charge", render: "One tube costs {charge}", freeform: {key: "charge", postfixDistinguished: "bicycle_tube"]}, }) | ||||||
|  |      * const tags = config.constructChangeSpecification("€5", undefined, undefined, {vending: "books;bicycle_tubes" charge: "€42/book"}) | ||||||
|  |      * tags // =>new And([ new Tag("charge", "€5/bicycle_tube; €42/book")])
 | ||||||
|  |      * | ||||||
|  |      * | ||||||
|      * @param freeformValue The freeform value which will be applied as 'freeform.key'. Ignored if 'freeform.key' is not set |      * @param freeformValue The freeform value which will be applied as 'freeform.key'. Ignored if 'freeform.key' is not set | ||||||
|      * |      * | ||||||
|      * @param singleSelectedMapping (Only used if multiAnswer == false): the single mapping to apply. Use (mappings.length) for the freeform |      * @param singleSelectedMapping (Only used if multiAnswer == false): the single mapping to apply. Use (mappings.length) for the freeform | ||||||
|  | @ -658,6 +683,7 @@ export default class TagRenderingConfig { | ||||||
|         if (typeof freeformValue === "string") { |         if (typeof freeformValue === "string") { | ||||||
|             freeformValue = freeformValue?.trim() |             freeformValue = freeformValue?.trim() | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         const validator = Validators.get(<ValidatorType>this.freeform?.type) |         const validator = Validators.get(<ValidatorType>this.freeform?.type) | ||||||
|         if (validator && freeformValue) { |         if (validator && freeformValue) { | ||||||
|             freeformValue = validator.reformat(freeformValue, () => currentProperties["_country"]) |             freeformValue = validator.reformat(freeformValue, () => currentProperties["_country"]) | ||||||
|  | @ -665,6 +691,18 @@ export default class TagRenderingConfig { | ||||||
|         if (freeformValue === "") { |         if (freeformValue === "") { | ||||||
|             freeformValue = undefined |             freeformValue = undefined | ||||||
|         } |         } | ||||||
|  |         if (this.freeform?.postfixDistinguished && freeformValue !== undefined) { | ||||||
|  |             const allValues = currentProperties[this.freeform.key].split(";").map(s => s.trim()) | ||||||
|  |             const perPostfix: Record<string, string> = {} | ||||||
|  |             for (const value of allValues) { | ||||||
|  |                 const [v, postfix] = value.split("/") | ||||||
|  |                 perPostfix[postfix.trim()] = v.trim() | ||||||
|  |             } | ||||||
|  |             perPostfix[this.freeform.postfixDistinguished] = freeformValue | ||||||
|  |             const keys = Object.keys(perPostfix) | ||||||
|  |             keys.sort() | ||||||
|  |             freeformValue = keys.map(k => perPostfix[k] + "/" + k).join("; ") | ||||||
|  |         } | ||||||
|         if ( |         if ( | ||||||
|             freeformValue === undefined && |             freeformValue === undefined && | ||||||
|             singleSelectedMapping === undefined && |             singleSelectedMapping === undefined && | ||||||
|  | @ -740,6 +778,7 @@ export default class TagRenderingConfig { | ||||||
|                 !someMappingIsShown || |                 !someMappingIsShown || | ||||||
|                 singleSelectedMapping === undefined) |                 singleSelectedMapping === undefined) | ||||||
|         if (useFreeform) { |         if (useFreeform) { | ||||||
|  | 
 | ||||||
|             return new And([ |             return new And([ | ||||||
|                 new Tag(this.freeform.key, freeformValue), |                 new Tag(this.freeform.key, freeformValue), | ||||||
|                 ...(this.freeform.addExtraTags ?? []) |                 ...(this.freeform.addExtraTags ?? []) | ||||||
|  | @ -762,30 +801,23 @@ export default class TagRenderingConfig { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     GenerateDocumentation(): BaseUIElement { |     GenerateDocumentation(): string { | ||||||
|         let withRender: (BaseUIElement | string)[] = [] |         let withRender: string[] = [] | ||||||
|         if (this.freeform?.key !== undefined) { |         if (this.freeform?.key !== undefined) { | ||||||
|             withRender = [ |             withRender = [ | ||||||
|                 `This rendering asks information about the property `, |                 `This rendering asks information about the property `, | ||||||
|                 Link.OsmWiki(this.freeform.key), |                 Link.OsmWiki(this.freeform.key).AsMarkdown(), | ||||||
|                 new Combine([ |                 "This is rendered with `" + this.render.txt + "`" | ||||||
|                     "This is rendered with ", |  | ||||||
|                     new FixedUiElement(this.render.txt).SetClass("code font-bold") |  | ||||||
|                 ]) |  | ||||||
|             ] |             ] | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let mappings: BaseUIElement = undefined |         let mappings: string = undefined | ||||||
|         if (this.mappings !== undefined) { |         if (this.mappings !== undefined) { | ||||||
|             mappings = new List( |             mappings = MarkdownUtils.list( | ||||||
|                 [].concat( |                 this.mappings.flatMap((m) => { | ||||||
|                     ...this.mappings.map((m) => { |                         const msgs: (string)[] = [ | ||||||
|                         const msgs: (string | BaseUIElement)[] = [ |                             "*" + m.then.txt + "* corresponds with " + | ||||||
|                             new Combine([ |  | ||||||
|                                 new FixedUiElement(m.then.txt).SetClass("font-bold"), |  | ||||||
|                                 " corresponds with ", |  | ||||||
|                             m.if.asHumanString(true, false, {}) |                             m.if.asHumanString(true, false, {}) | ||||||
|                             ]) |  | ||||||
|                         ] |                         ] | ||||||
|                         if (m.hideInAnswer === true) { |                         if (m.hideInAnswer === true) { | ||||||
|                             msgs.push("_This option cannot be chosen as answer_") |                             msgs.push("_This option cannot be chosen as answer_") | ||||||
|  | @ -799,43 +831,31 @@ export default class TagRenderingConfig { | ||||||
|                         return msgs |                         return msgs | ||||||
|                     }) |                     }) | ||||||
|             ) |             ) | ||||||
|             ) |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let condition: BaseUIElement = undefined |         let condition: string = undefined | ||||||
|         if (this.condition !== undefined && !this.condition?.matchesProperties({})) { |         if (this.condition !== undefined && !this.condition?.matchesProperties({})) { | ||||||
|             condition = new Combine([ |             const conditionAsLink = (<TagsFilter>this.condition.optimize()).asHumanString(true, false, {}) | ||||||
|                 "This tagrendering is only visible in the popup if the following condition is met:", |             condition = "This tagrendering is only visible in the popup if the following condition is met: " + conditionAsLink | ||||||
|                 new FixedUiElement( |  | ||||||
|                     (<TagsFilter>this.condition.optimize()).asHumanString(true, false, {}) |  | ||||||
|                 ).SetClass("code") |  | ||||||
|             ]) |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let labels: BaseUIElement = undefined |         let labels: string = undefined | ||||||
|         if (this.labels?.length > 0) { |         if (this.labels?.length > 0) { | ||||||
|             labels = new Combine([ |             labels = [ | ||||||
|                 "This tagrendering has labels ", |                 "This tagrendering has labels ", | ||||||
|                 ...this.labels.map((label) => new FixedUiElement(label).SetClass("code")) |                 ...this.labels.map((label) => "`" + label + "`") | ||||||
|             ]).SetClass("flex") |             ].join("\n") | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return new Combine([ |         return [ | ||||||
|             new Title(this.id, 3), |             "### this.id", | ||||||
|             this.description, |             this.description, | ||||||
|             this.question !== undefined |             this.question !== undefined ? ("The question is `" + this.question.txt + "`") : "_This tagrendering has no question and is thus read-only_", | ||||||
|                 ? new Combine([ |             withRender.join("\n"), | ||||||
|                     "The question is ", |  | ||||||
|                     new FixedUiElement(this.question.txt).SetClass("font-bold bold") |  | ||||||
|                 ]) |  | ||||||
|                 : new FixedUiElement( |  | ||||||
|                     "This tagrendering has no question and is thus read-only" |  | ||||||
|                 ).SetClass("italic"), |  | ||||||
|             new Combine(withRender), |  | ||||||
|             mappings, |             mappings, | ||||||
|             condition, |             condition, | ||||||
|             labels |             labels | ||||||
|         ]).SetClass("flex flex-col") |         ].join("\n") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public usedTags(): TagsFilter[] { |     public usedTags(): TagsFilter[] { | ||||||
|  | @ -872,7 +892,7 @@ export class TagRenderingConfigUtils { | ||||||
|         const extraMappings = tags |         const extraMappings = tags | ||||||
|             .bindD(tags => { |             .bindD(tags => { | ||||||
|                 const country = tags._country |                 const country = tags._country | ||||||
|                 if(country === undefined){ |                 if (country === undefined) { | ||||||
|                     return undefined |                     return undefined | ||||||
|                 } |                 } | ||||||
|                 const center = GeoOperations.centerpointCoordinates(feature) |                 const center = GeoOperations.centerpointCoordinates(feature) | ||||||
|  | @ -883,7 +903,10 @@ export class TagRenderingConfigUtils { | ||||||
|                 return config |                 return config | ||||||
|             } |             } | ||||||
|             const clone: TagRenderingConfig = Object.create(config) |             const clone: TagRenderingConfig = Object.create(config) | ||||||
|             const oldMappingsCloned = clone.mappings?.map(m => ({ ...m, priorityIf: m.priorityIf ?? TagUtils.Tag("id~*") })) ?? [] |             const oldMappingsCloned = clone.mappings?.map(m => ({ | ||||||
|  |                 ...m, | ||||||
|  |                 priorityIf: m.priorityIf ?? TagUtils.Tag("id~*") | ||||||
|  |             })) ?? [] | ||||||
|             clone.mappings = [...oldMappingsCloned, ...extraMappings] |             clone.mappings = [...oldMappingsCloned, ...extraMappings] | ||||||
|             return clone |             return clone | ||||||
|         }) |         }) | ||||||
|  |  | ||||||
|  | @ -16,4 +16,7 @@ export default class MarkdownUtils { | ||||||
|         return result |         return result | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     static list(strings: string[]): string { | ||||||
|  |         return strings.map(item => " - "+item).join("\n") | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue