forked from MapComplete/MapComplete
Chore: formatting
This commit is contained in:
parent
35eff07c80
commit
c08fe03ed0
422 changed files with 31594 additions and 43019 deletions
|
|
@ -149,9 +149,8 @@ export class Denomination {
|
|||
if (stripped === null) {
|
||||
return null
|
||||
}
|
||||
if(inverted){
|
||||
if (inverted) {
|
||||
return (stripped + "/" + this.canonical).trim()
|
||||
|
||||
}
|
||||
if (stripped === "1" && this._canonicalSingular !== undefined) {
|
||||
return ("1 " + this._canonicalSingular).trim()
|
||||
|
|
@ -187,10 +186,10 @@ export class Denomination {
|
|||
return value.substring(key.length).trim()
|
||||
}
|
||||
let trimmed = value.substring(0, value.length - key.length).trim()
|
||||
if(!inverted){
|
||||
if (!inverted) {
|
||||
return trimmed
|
||||
}
|
||||
if(trimmed.endsWith("/")){
|
||||
if (trimmed.endsWith("/")) {
|
||||
trimmed = trimmed.substring(0, trimmed.length - 1).trim()
|
||||
}
|
||||
return trimmed
|
||||
|
|
@ -218,13 +217,23 @@ export class Denomination {
|
|||
return null
|
||||
}
|
||||
|
||||
if(!this._validator.isValid(value.trim())){
|
||||
if (!this._validator.isValid(value.trim())) {
|
||||
return null
|
||||
}
|
||||
return this._validator.reformat(value.trim())
|
||||
}
|
||||
|
||||
withValidator(validator: Validator) {
|
||||
return new Denomination(this.canonical, this._canonicalSingular, this.useIfNoUnitGiven, this.prefix, this.addSpace, this.alternativeDenominations, this.human, this.humanSingular, validator)
|
||||
return new Denomination(
|
||||
this.canonical,
|
||||
this._canonicalSingular,
|
||||
this.useIfNoUnitGiven,
|
||||
this.prefix,
|
||||
this.addSpace,
|
||||
this.alternativeDenominations,
|
||||
this.human,
|
||||
this.humanSingular,
|
||||
validator
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,12 @@ export class AvailableRasterLayers {
|
|||
matching.push(AvailableRasterLayers.bing)
|
||||
}
|
||||
matching.push(...AvailableRasterLayers.globalLayers)
|
||||
if(!matching.some(l => l.id === AvailableRasterLayers.defaultBackgroundLayer.properties.id)){
|
||||
if (
|
||||
!matching.some(
|
||||
(l) =>
|
||||
l.id === AvailableRasterLayers.defaultBackgroundLayer.properties.id
|
||||
)
|
||||
) {
|
||||
matching.push(AvailableRasterLayers.defaultBackgroundLayer)
|
||||
}
|
||||
return matching
|
||||
|
|
|
|||
|
|
@ -39,7 +39,12 @@ export abstract class Conversion<TIn, TOut> {
|
|||
ConversionContext.print(msg)
|
||||
}
|
||||
if (context.hasErrors()) {
|
||||
throw new Error(["Detected one or more errors, stopping now:", context.getAll("error").map(e => e.context.path.join(".")+": "+e.message)].join("\n\t"))
|
||||
throw new Error(
|
||||
[
|
||||
"Detected one or more errors, stopping now:",
|
||||
context.getAll("error").map((e) => e.context.path.join(".") + ": " + e.message),
|
||||
].join("\n\t")
|
||||
)
|
||||
}
|
||||
return fixed
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,10 +157,14 @@ export class ConversionContext {
|
|||
* @constructor
|
||||
*/
|
||||
MergeObjectsForOverride<T, S>(source: Readonly<S>, target: T): T & S {
|
||||
try{
|
||||
return Utils.Merge(source,target)
|
||||
}catch (e) {
|
||||
this.err("Could not apply an override: due to "+e+"\n\tHINT: did you just pull changes from the repository or switch branches? Try 'npm run reset:layeroverview'")
|
||||
try {
|
||||
return Utils.Merge(source, target)
|
||||
} catch (e) {
|
||||
this.err(
|
||||
"Could not apply an override: due to " +
|
||||
e +
|
||||
"\n\tHINT: did you just pull changes from the repository or switch branches? Try 'npm run reset:layeroverview'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export class UpdateLegacyLayer extends DesugaringStep<
|
|||
delete config["overpassTags"]
|
||||
}
|
||||
|
||||
if(config.allowMove?.["enableImproveAccuraccy"]){
|
||||
if (config.allowMove?.["enableImproveAccuraccy"]) {
|
||||
// Fix common misspelling: 'accuracy' is often typo'ed as 'accuraCCy'
|
||||
config.allowMove["enableImproveAccuracy"] = config.allowMove["enableImproveAccuraccy"]
|
||||
delete config.allowMove["enableImproveAccuraccy"]
|
||||
|
|
|
|||
|
|
@ -161,9 +161,8 @@ class ExpandTagRendering extends Conversion<
|
|||
private readonly _options: {
|
||||
/* If true, will copy the 'osmSource'-tags into the condition */
|
||||
applyCondition?: true | boolean
|
||||
noHardcodedStrings?: false | boolean,
|
||||
noHardcodedStrings?: false | boolean
|
||||
addToContext?: false | boolean
|
||||
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
|
@ -171,7 +170,7 @@ class ExpandTagRendering extends Conversion<
|
|||
self: LayerConfigJson,
|
||||
options?: {
|
||||
applyCondition?: true | boolean
|
||||
noHardcodedStrings?: false | boolean,
|
||||
noHardcodedStrings?: false | boolean
|
||||
// If set, a question will be added to the 'sharedTagRenderings'. Should only be used for 'questions.json'
|
||||
addToContext?: false | boolean
|
||||
}
|
||||
|
|
@ -208,17 +207,16 @@ class ExpandTagRendering extends Conversion<
|
|||
if (typeof tr === "string" || tr["builtin"] !== undefined) {
|
||||
const stable = this.convert(tr, ctx.inOperation("recursive_resolve"))
|
||||
result.push(...stable)
|
||||
if(this._options?.addToContext){
|
||||
if (this._options?.addToContext) {
|
||||
for (const tr of stable) {
|
||||
this._state.tagRenderings?.set(tr.id, tr)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.push(tr)
|
||||
if(this._options?.addToContext){
|
||||
this._state.tagRenderings?.set(tr["id"], <QuestionableTagRenderingConfigJson> tr)
|
||||
if (this._options?.addToContext) {
|
||||
this._state.tagRenderings?.set(tr["id"], <QuestionableTagRenderingConfigJson>tr)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1274,14 +1272,23 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
|
|||
}
|
||||
|
||||
export class PrepareLayer extends Fuse<LayerConfigJson> {
|
||||
constructor(state: DesugaringContext, options?: {addTagRenderingsToContext?: false | boolean}) {
|
||||
constructor(
|
||||
state: DesugaringContext,
|
||||
options?: { addTagRenderingsToContext?: false | boolean }
|
||||
) {
|
||||
super(
|
||||
"Fully prepares and expands a layer for the LayerConfig.",
|
||||
new On("tagRenderings", new Each(new RewriteSpecial())),
|
||||
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
||||
new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer, {
|
||||
addToContext: options?.addTagRenderingsToContext ?? false
|
||||
}))),
|
||||
new On(
|
||||
"tagRenderings",
|
||||
(layer) =>
|
||||
new Concat(
|
||||
new ExpandTagRendering(state, layer, {
|
||||
addToContext: options?.addTagRenderingsToContext ?? false,
|
||||
})
|
||||
)
|
||||
),
|
||||
new On("tagRenderings", new Each(new DetectInline())),
|
||||
new AddQuestionBox(),
|
||||
new AddEditingElements(state),
|
||||
|
|
|
|||
|
|
@ -566,7 +566,11 @@ export class DetectMappingsShadowedByCondition extends DesugaringStep<TagRenderi
|
|||
private readonly _forceError: boolean
|
||||
|
||||
constructor(forceError: boolean = false) {
|
||||
super("Checks that, if the tagrendering has a condition, that a mapping is not contradictory to it, i.e. that there are no dead mappings", [], "DetectMappingsShadowedByCondition")
|
||||
super(
|
||||
"Checks that, if the tagrendering has a condition, that a mapping is not contradictory to it, i.e. that there are no dead mappings",
|
||||
[],
|
||||
"DetectMappingsShadowedByCondition"
|
||||
)
|
||||
this._forceError = forceError
|
||||
}
|
||||
|
||||
|
|
@ -588,24 +592,28 @@ export class DetectMappingsShadowedByCondition extends DesugaringStep<TagRenderi
|
|||
* ctx.hasErrors() // => true
|
||||
*/
|
||||
convert(json: TagRenderingConfigJson, context: ConversionContext): TagRenderingConfigJson {
|
||||
if(!json.condition && !json.metacondition){
|
||||
if (!json.condition && !json.metacondition) {
|
||||
return json
|
||||
}
|
||||
if(!json.mappings || json.mappings?.length ==0){
|
||||
if (!json.mappings || json.mappings?.length == 0) {
|
||||
return json
|
||||
}
|
||||
let conditionJson = json.condition ?? json.metacondition
|
||||
if(json.condition !== undefined && json.metacondition !== undefined){
|
||||
conditionJson = {and: [json.condition, json.metacondition]}
|
||||
if (json.condition !== undefined && json.metacondition !== undefined) {
|
||||
conditionJson = { and: [json.condition, json.metacondition] }
|
||||
}
|
||||
const condition = TagUtils.Tag(conditionJson, context.path.join("."))
|
||||
|
||||
for (let i = 0; i < json.mappings.length; i++){
|
||||
for (let i = 0; i < json.mappings.length; i++) {
|
||||
const mapping = json.mappings[i]
|
||||
const tagIf = TagUtils.Tag(mapping.if, context.path.join("."))
|
||||
const optimized = new And([tagIf, condition]).optimize()
|
||||
if(optimized === false){
|
||||
const msg = ("Detected a conflicting mapping and condition. The mapping requires tags " + tagIf.asHumanString() + ", yet this can never happen because the set condition requires " + condition.asHumanString())
|
||||
if (optimized === false) {
|
||||
const msg =
|
||||
"Detected a conflicting mapping and condition. The mapping requires tags " +
|
||||
tagIf.asHumanString() +
|
||||
", yet this can never happen because the set condition requires " +
|
||||
condition.asHumanString()
|
||||
const ctx = context.enters("mappings", i)
|
||||
if (this._forceError) {
|
||||
ctx.err(msg)
|
||||
|
|
@ -615,10 +623,8 @@ export class DetectMappingsShadowedByCondition extends DesugaringStep<TagRenderi
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> {
|
||||
|
|
@ -1094,14 +1100,26 @@ class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJson> {
|
|||
)
|
||||
}
|
||||
}
|
||||
if(this._layerConfig?.source?.osmTags && NameSuggestionIndex.supportedTypes().indexOf(json.freeform.key) >= 0){
|
||||
const tags= TagUtils.TagD(this._layerConfig?.source?.osmTags)?.usedTags()
|
||||
if (
|
||||
this._layerConfig?.source?.osmTags &&
|
||||
NameSuggestionIndex.supportedTypes().indexOf(json.freeform.key) >= 0
|
||||
) {
|
||||
const tags = TagUtils.TagD(this._layerConfig?.source?.osmTags)?.usedTags()
|
||||
const suggestions = NameSuggestionIndex.getSuggestionsFor(json.freeform.key, tags)
|
||||
if(suggestions === undefined){
|
||||
context.enters("freeform","type").err("No entry found in the 'Name Suggestion Index'. None of the 'osmSource'-tags match an entry in the NSI.\n\tOsmSource-tags are "+tags.map(t => t.asHumanString()).join(" ; "))
|
||||
if (suggestions === undefined) {
|
||||
context
|
||||
.enters("freeform", "type")
|
||||
.err(
|
||||
"No entry found in the 'Name Suggestion Index'. None of the 'osmSource'-tags match an entry in the NSI.\n\tOsmSource-tags are " +
|
||||
tags.map((t) => t.asHumanString()).join(" ; ")
|
||||
)
|
||||
}
|
||||
}else if(json.freeform.type === "nsi"){
|
||||
context.enters("freeform","type").warn("No need to explicitly set type to 'NSI', autodetected based on freeform type")
|
||||
} else if (json.freeform.type === "nsi") {
|
||||
context
|
||||
.enters("freeform", "type")
|
||||
.warn(
|
||||
"No need to explicitly set type to 'NSI', autodetected based on freeform type"
|
||||
)
|
||||
}
|
||||
}
|
||||
if (json.render && json["question"] && json.freeform === undefined) {
|
||||
|
|
@ -1720,8 +1738,12 @@ export class ValidateLayer extends Conversion<
|
|||
}
|
||||
}
|
||||
|
||||
if(json.allowMove?.["enableAccuraccy"] !== undefined){
|
||||
context.enters("allowMove", "enableAccuracy").err("`enableAccuracy` is written with two C in the first occurrence and only one in the last")
|
||||
if (json.allowMove?.["enableAccuraccy"] !== undefined) {
|
||||
context
|
||||
.enters("allowMove", "enableAccuracy")
|
||||
.err(
|
||||
"`enableAccuracy` is written with two C in the first occurrence and only one in the last"
|
||||
)
|
||||
}
|
||||
|
||||
return { raw: json, parsed: layerConfig }
|
||||
|
|
|
|||
|
|
@ -527,7 +527,16 @@ export interface LayerConfigJson {
|
|||
*/
|
||||
units?: (
|
||||
| UnitConfigJson
|
||||
| Record<string, string | { quantity: string; denominations: string[]; canonical?: string, inverted?: boolean }>
|
||||
| Record<
|
||||
string,
|
||||
| string
|
||||
| {
|
||||
quantity: string
|
||||
denominations: string[]
|
||||
canonical?: string
|
||||
inverted?: boolean
|
||||
}
|
||||
>
|
||||
)[]
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -450,5 +450,4 @@ export interface LayoutConfigJson {
|
|||
* iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey
|
||||
*/
|
||||
enableMorePrivacy: boolean
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs
|
|||
* ifunset: The question will be considered answered if any value is set for the key
|
||||
* group: expert
|
||||
*/
|
||||
invalidValues?: TagConfigJson,
|
||||
invalidValues?: TagConfigJson
|
||||
|
||||
/**
|
||||
* question: If this key shared and distinguished by a postfix, what is the postfix?
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
this.units = [].concat(
|
||||
...(json.units ?? []).map((unitJson, i) =>
|
||||
Unit.fromJson(unitJson, this.tagRenderings,`${context}.unit[${i}]`)
|
||||
Unit.fromJson(unitJson, this.tagRenderings, `${context}.unit[${i}]`)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ export class LayoutInformation {
|
|||
id: string
|
||||
icon: string
|
||||
title: Translatable | Translation
|
||||
shortDescription: Translatable| Translation
|
||||
definition?: Translatable| Translation
|
||||
shortDescription: Translatable | Translation
|
||||
definition?: Translatable | Translation
|
||||
mustHaveLanguage?: boolean
|
||||
hideFromOverview?: boolean
|
||||
keywords?: (Translatable| Translation)[]
|
||||
keywords?: (Translatable | Translation)[]
|
||||
}
|
||||
|
||||
export default class LayoutConfig implements LayoutInformation {
|
||||
|
|
@ -65,7 +65,6 @@ export default class LayoutConfig implements LayoutInformation {
|
|||
public readonly enableTerrain: boolean
|
||||
public readonly enableMorePrivacy: boolean
|
||||
|
||||
|
||||
public readonly customCss?: string
|
||||
|
||||
public readonly overpassUrl: string[]
|
||||
|
|
@ -206,7 +205,9 @@ export default class LayoutConfig implements LayoutInformation {
|
|||
this.overpassTimeout = json.overpassTimeout ?? 30
|
||||
this.overpassMaxZoom = json.overpassMaxZoom ?? 16
|
||||
this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1
|
||||
this.enableMorePrivacy = json.enableMorePrivacy || json.layers.some(l => (<LayerConfigJson> l).enableMorePrivacy)
|
||||
this.enableMorePrivacy =
|
||||
json.enableMorePrivacy ||
|
||||
json.layers.some((l) => (<LayerConfigJson>l).enableMorePrivacy)
|
||||
|
||||
this.layersDict = new Map<string, LayerConfig>()
|
||||
for (const layer of this.layers) {
|
||||
|
|
@ -315,7 +316,8 @@ export default class LayoutConfig implements LayoutInformation {
|
|||
continue
|
||||
}
|
||||
if (layer.source.osmTags.matchesProperties(tags)) {
|
||||
if(!layer.isShown || layer.isShown.matchesProperties(tags)){// https://github.com/pietervdvn/MapComplete/issues/1959
|
||||
if (!layer.isShown || layer.isShown.matchesProperties(tags)) {
|
||||
// https://github.com/pietervdvn/MapComplete/issues/1959
|
||||
return layer
|
||||
}
|
||||
}
|
||||
|
|
@ -324,16 +326,22 @@ export default class LayoutConfig implements LayoutInformation {
|
|||
return undefined
|
||||
}
|
||||
|
||||
public getUsedImages(){
|
||||
if(this.usedImages){
|
||||
public getUsedImages() {
|
||||
if (this.usedImages) {
|
||||
return this.usedImages
|
||||
}
|
||||
const json = this.source
|
||||
// The 'favourite'-layer contains pretty much all images as it bundles all layers, so we exclude it
|
||||
const jsonNoFavourites = {...json, layers: json.layers.filter(l => l["id"] !== "favourite")}
|
||||
const jsonNoFavourites = {
|
||||
...json,
|
||||
layers: json.layers.filter((l) => l["id"] !== "favourite"),
|
||||
}
|
||||
this.usedImages = Array.from(
|
||||
new ExtractImages(this.official, undefined)
|
||||
.convertStrict(jsonNoFavourites, ConversionContext.construct([json.id], ["ExtractImages"]))
|
||||
.convertStrict(
|
||||
jsonNoFavourites,
|
||||
ConversionContext.construct([json.id], ["ExtractImages"])
|
||||
)
|
||||
.map((i) => i.path)
|
||||
).sort()
|
||||
return this.usedImages
|
||||
|
|
|
|||
|
|
@ -20,8 +20,13 @@ export default class LineRenderingConfig extends WithContextLoader {
|
|||
this.color = this.tr("color", "#0000ff")
|
||||
this.width = this.tr("width", "7")
|
||||
this.dashArray = json.dashArray
|
||||
if(this.dashArray !== undefined && typeof this.dashArray !== "string"){
|
||||
throw "Invalid dasharray at "+context+"; this should be a string but is a "+typeof this.dashArray
|
||||
if (this.dashArray !== undefined && typeof this.dashArray !== "string") {
|
||||
throw (
|
||||
"Invalid dasharray at " +
|
||||
context +
|
||||
"; this should be a string but is a " +
|
||||
typeof this.dashArray
|
||||
)
|
||||
}
|
||||
this.lineCap = this.tr("lineCap", "round")
|
||||
this.fill = this.tr("fill", undefined)
|
||||
|
|
|
|||
|
|
@ -123,12 +123,15 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
context + ".rotationAlignment"
|
||||
)
|
||||
}
|
||||
private static FromHtmlMulti(multiSpec: string, tags: Store<Record<string, string>>): BaseUIElement {
|
||||
private static FromHtmlMulti(
|
||||
multiSpec: string,
|
||||
tags: Store<Record<string, string>>
|
||||
): BaseUIElement {
|
||||
const icons: IconConfig[] = []
|
||||
|
||||
for (const subspec of multiSpec.split(";")) {
|
||||
if(subspec.startsWith("http://") || subspec.startsWith("https://")){
|
||||
icons.push(new IconConfig({icon: subspec}))
|
||||
if (subspec.startsWith("http://") || subspec.startsWith("https://")) {
|
||||
icons.push(new IconConfig({ icon: subspec }))
|
||||
continue
|
||||
}
|
||||
const [icon, color] = subspec.split(":")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ import { And } from "../../Logic/Tags/And"
|
|||
import { Utils } from "../../Utils"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import Link from "../../UI/Base/Link"
|
||||
import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import {
|
||||
MappingConfigJson,
|
||||
QuestionableTagRenderingConfigJson,
|
||||
} from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import Validators, { ValidatorType } from "../../UI/InputElement/Validators"
|
||||
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
|
||||
import { RegexTag } from "../../Logic/Tags/RegexTag"
|
||||
|
|
@ -76,7 +79,10 @@ export default class TagRenderingConfig {
|
|||
public readonly classes: string[] | undefined
|
||||
|
||||
constructor(
|
||||
config: string | TagRenderingConfigJson | (QuestionableTagRenderingConfigJson & { questionHintIsMd?: boolean }),
|
||||
config:
|
||||
| string
|
||||
| TagRenderingConfigJson
|
||||
| (QuestionableTagRenderingConfigJson & { questionHintIsMd?: boolean }),
|
||||
context?: string
|
||||
) {
|
||||
let json = <string | QuestionableTagRenderingConfigJson>config
|
||||
|
|
@ -196,7 +202,7 @@ export default class TagRenderingConfig {
|
|||
) ?? [],
|
||||
inline: json.freeform.inline ?? false,
|
||||
default: json.freeform.default,
|
||||
postfixDistinguished: json.freeform.postfixDistinguished?.trim()
|
||||
postfixDistinguished: json.freeform.postfixDistinguished?.trim(),
|
||||
}
|
||||
if (json.freeform["extraTags"] !== undefined) {
|
||||
throw `Freeform.extraTags is defined. This should probably be 'freeform.addExtraTag' (at ${context})`
|
||||
|
|
@ -215,10 +221,18 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
if (this.freeform.postfixDistinguished) {
|
||||
if (this.multiAnswer) {
|
||||
throw "At " + context + ": a postfixDistinguished-value cannot be used with a 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"
|
||||
throw (
|
||||
"At " +
|
||||
context +
|
||||
": a postfixDistinguished-value should not start with `/`. This will be inserted automatically"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,7 +414,7 @@ export default class TagRenderingConfig {
|
|||
iconClass,
|
||||
addExtraTags,
|
||||
searchTerms: mapping.searchTerms,
|
||||
priorityIf: prioritySearch
|
||||
priorityIf: prioritySearch,
|
||||
}
|
||||
if (isQuestionable) {
|
||||
if (hideInAnswer !== true && mp.if !== undefined && !mp.if.isUsableAsAnswer()) {
|
||||
|
|
@ -486,13 +500,12 @@ export default class TagRenderingConfig {
|
|||
})
|
||||
)
|
||||
|
||||
|
||||
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)
|
||||
?.flatMap((m) => m.if?.usedTags() ?? [])
|
||||
?.filter((kv) => kv.key === this.freeform.key)
|
||||
?.map((kv) => kv.value)
|
||||
)
|
||||
|
||||
const freeformValues = tags[this.freeform.key].split(";")
|
||||
|
|
@ -502,7 +515,7 @@ export default class TagRenderingConfig {
|
|||
then: new TypedTranslation<object>(
|
||||
this.render.replace("{" + this.freeform.key + "}", leftover).translations,
|
||||
this.render.context
|
||||
)
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -544,7 +557,7 @@ export default class TagRenderingConfig {
|
|||
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())
|
||||
const allFreeforms = tags[this.freeform.key].split(";").map((s) => s.trim())
|
||||
for (const allFreeform of allFreeforms) {
|
||||
if (allFreeform.endsWith(postfix)) {
|
||||
const [v] = allFreeform.split("/")
|
||||
|
|
@ -552,7 +565,7 @@ export default class TagRenderingConfig {
|
|||
return {
|
||||
then: this.render.PartialSubs({ [this.freeform.key]: v.trim() }),
|
||||
icon: this.renderIcon,
|
||||
iconClass: this.renderIconClass
|
||||
iconClass: this.renderIconClass,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -607,7 +620,7 @@ export default class TagRenderingConfig {
|
|||
key: commonKey,
|
||||
values: Utils.NoNull(
|
||||
values.map((arr) => arr.filter((item) => item.k === commonKey)[0]?.v)
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -622,7 +635,7 @@ export default class TagRenderingConfig {
|
|||
return {
|
||||
key,
|
||||
type: this.freeform.type,
|
||||
values
|
||||
values,
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not create FreeformValues for tagrendering", this.id)
|
||||
|
|
@ -692,7 +705,7 @@ export default class TagRenderingConfig {
|
|||
freeformValue = undefined
|
||||
}
|
||||
if (this.freeform?.postfixDistinguished && freeformValue !== undefined) {
|
||||
const allValues = currentProperties[this.freeform.key].split(";").map(s => s.trim())
|
||||
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("/")
|
||||
|
|
@ -701,7 +714,7 @@ export default class TagRenderingConfig {
|
|||
perPostfix[this.freeform.postfixDistinguished] = freeformValue
|
||||
const keys = Object.keys(perPostfix)
|
||||
keys.sort()
|
||||
freeformValue = keys.map(k => perPostfix[k] + "/" + k).join("; ")
|
||||
freeformValue = keys.map((k) => perPostfix[k] + "/" + k).join("; ")
|
||||
}
|
||||
if (
|
||||
freeformValue === undefined &&
|
||||
|
|
@ -728,7 +741,7 @@ export default class TagRenderingConfig {
|
|||
// Either no mappings, or this is a radio-button selected freeform value
|
||||
const tag = new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
const newProperties = tag.applyOn(currentProperties)
|
||||
if (this.invalidValues?.matchesProperties(newProperties)) {
|
||||
|
|
@ -752,7 +765,7 @@ export default class TagRenderingConfig {
|
|||
selectedMappings.push(
|
||||
new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
|
@ -778,15 +791,14 @@ export default class TagRenderingConfig {
|
|||
!someMappingIsShown ||
|
||||
singleSelectedMapping === undefined)
|
||||
if (useFreeform) {
|
||||
|
||||
return new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
} else if (singleSelectedMapping !== undefined) {
|
||||
return new And([
|
||||
this.mappings[singleSelectedMapping].if,
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? [])
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? []),
|
||||
])
|
||||
} else {
|
||||
console.error("TagRenderingConfig.ConstructSpecification has a weird fallback for", {
|
||||
|
|
@ -794,7 +806,7 @@ export default class TagRenderingConfig {
|
|||
singleSelectedMapping,
|
||||
multiSelectedMapping,
|
||||
currentProperties,
|
||||
useFreeform
|
||||
useFreeform,
|
||||
})
|
||||
|
||||
return undefined
|
||||
|
|
@ -807,7 +819,7 @@ export default class TagRenderingConfig {
|
|||
withRender = [
|
||||
`This rendering asks information about the property `,
|
||||
Link.OsmWiki(this.freeform.key).AsMarkdown(),
|
||||
"This is rendered with `" + this.render.txt + "`"
|
||||
"This is rendered with `" + this.render.txt + "`",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -815,46 +827,56 @@ export default class TagRenderingConfig {
|
|||
if (this.mappings !== undefined) {
|
||||
mappings = MarkdownUtils.list(
|
||||
this.mappings.flatMap((m) => {
|
||||
const msgs: (string)[] = [
|
||||
"*" + m.then.txt + "* corresponds with " +
|
||||
m.if.asHumanString(true, false, {})
|
||||
]
|
||||
if (m.hideInAnswer === true) {
|
||||
msgs.push("_This option cannot be chosen as answer_")
|
||||
}
|
||||
if (m.ifnot !== undefined) {
|
||||
msgs.push(
|
||||
"Unselecting this answer will add " +
|
||||
const msgs: string[] = [
|
||||
"*" +
|
||||
m.then.txt +
|
||||
"* corresponds with " +
|
||||
m.if.asHumanString(true, false, {}),
|
||||
]
|
||||
if (m.hideInAnswer === true) {
|
||||
msgs.push("_This option cannot be chosen as answer_")
|
||||
}
|
||||
if (m.ifnot !== undefined) {
|
||||
msgs.push(
|
||||
"Unselecting this answer will add " +
|
||||
m.ifnot.asHumanString(true, false, {})
|
||||
)
|
||||
}
|
||||
return msgs
|
||||
})
|
||||
)
|
||||
}
|
||||
return msgs
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
let condition: string = undefined
|
||||
if (this.condition !== undefined && !this.condition?.matchesProperties({})) {
|
||||
const conditionAsLink = (<TagsFilter>this.condition.optimize()).asHumanString(true, false, {})
|
||||
condition = "This tagrendering is only visible in the popup if the following condition is met: " + conditionAsLink
|
||||
const conditionAsLink = (<TagsFilter>this.condition.optimize()).asHumanString(
|
||||
true,
|
||||
false,
|
||||
{}
|
||||
)
|
||||
condition =
|
||||
"This tagrendering is only visible in the popup if the following condition is met: " +
|
||||
conditionAsLink
|
||||
}
|
||||
|
||||
let labels: string = undefined
|
||||
if (this.labels?.length > 0) {
|
||||
labels = [
|
||||
"This tagrendering has labels ",
|
||||
...this.labels.map((label) => "`" + label + "`")
|
||||
...this.labels.map((label) => "`" + label + "`"),
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
return [
|
||||
"### this.id",
|
||||
this.description,
|
||||
this.question !== undefined ? ("The question is `" + this.question.txt + "`") : "_This tagrendering has no question and is thus read-only_",
|
||||
this.question !== undefined
|
||||
? "The question is `" + this.question.txt + "`"
|
||||
: "_This tagrendering has no question and is thus read-only_",
|
||||
withRender.join("\n"),
|
||||
mappings,
|
||||
condition,
|
||||
labels
|
||||
labels,
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
|
|
@ -879,37 +901,45 @@ export default class TagRenderingConfig {
|
|||
|
||||
return Utils.NoNull(tags)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class TagRenderingConfigUtils {
|
||||
|
||||
public static withNameSuggestionIndex(config: TagRenderingConfig, tags: UIEventSource<Record<string, string>>, feature?: Feature): Store<TagRenderingConfig> {
|
||||
public static withNameSuggestionIndex(
|
||||
config: TagRenderingConfig,
|
||||
tags: UIEventSource<Record<string, string>>,
|
||||
feature?: Feature
|
||||
): Store<TagRenderingConfig> {
|
||||
const isNSI = NameSuggestionIndex.supportedTypes().indexOf(config.freeform?.key) >= 0
|
||||
if (!isNSI) {
|
||||
return new ImmutableStore(config)
|
||||
}
|
||||
const extraMappings = tags
|
||||
.bindD(tags => {
|
||||
const country = tags._country
|
||||
if (country === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const center = GeoOperations.centerpointCoordinates(feature)
|
||||
return UIEventSource.FromPromise(NameSuggestionIndex.generateMappings(config.freeform.key, tags, country.split(";"), center))
|
||||
})
|
||||
return extraMappings.map(extraMappings => {
|
||||
const extraMappings = tags.bindD((tags) => {
|
||||
const country = tags._country
|
||||
if (country === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const center = GeoOperations.centerpointCoordinates(feature)
|
||||
return UIEventSource.FromPromise(
|
||||
NameSuggestionIndex.generateMappings(
|
||||
config.freeform.key,
|
||||
tags,
|
||||
country.split(";"),
|
||||
center
|
||||
)
|
||||
)
|
||||
})
|
||||
return extraMappings.map((extraMappings) => {
|
||||
if (!extraMappings || extraMappings.length == 0) {
|
||||
return 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]
|
||||
return clone
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
featurePropertiesStore: this.featureProperties,
|
||||
osmConnection: this.osmConnection,
|
||||
historicalUserLocations: this.geolocation.historicalUserLocations,
|
||||
featureSwitches: this.featureSwitches
|
||||
featureSwitches: this.featureSwitches,
|
||||
},
|
||||
layout?.isLeftRightSensitive() ?? false
|
||||
)
|
||||
|
|
@ -497,8 +497,8 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
Utils.LoadCustomCss(this.layout.customCss)
|
||||
}
|
||||
|
||||
Hash.hash.addCallbackAndRunD(hash => {
|
||||
if(hash === "current_view" || hash.match(/current_view_[0-9]+/)){
|
||||
Hash.hash.addCallbackAndRunD((hash) => {
|
||||
if (hash === "current_view" || hash.match(/current_view_[0-9]+/)) {
|
||||
this.selectCurrentView()
|
||||
}
|
||||
})
|
||||
|
|
@ -827,7 +827,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
)
|
||||
}
|
||||
|
||||
public selectCurrentView(){
|
||||
public selectCurrentView() {
|
||||
this.guistate.closeAll()
|
||||
this.selectedElement.setData(this.currentView.features?.data?.[0])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,11 +76,13 @@ export class Unit {
|
|||
static fromJson(
|
||||
json:
|
||||
| UnitConfigJson
|
||||
| Record<string, string | { quantity: string; denominations: string[], inverted?: boolean }>,
|
||||
| Record<
|
||||
string,
|
||||
string | { quantity: string; denominations: string[]; inverted?: boolean }
|
||||
>,
|
||||
tagRenderings: TagRenderingConfig[],
|
||||
ctx: string
|
||||
): Unit[] {
|
||||
|
||||
let types: Record<string, ValidatorType> = {}
|
||||
for (const tagRendering of tagRenderings) {
|
||||
if (tagRendering.freeform?.type) {
|
||||
|
|
@ -94,7 +96,12 @@ export class Unit {
|
|||
return this.parse(<UnitConfigJson>json, types, ctx)
|
||||
}
|
||||
|
||||
private static parseDenomination(json: UnitConfigJson, validator: Validator, appliesToKey: string, ctx: string): Unit {
|
||||
private static parseDenomination(
|
||||
json: UnitConfigJson,
|
||||
validator: Validator,
|
||||
appliesToKey: string,
|
||||
ctx: string
|
||||
): Unit {
|
||||
const applicable = json.applicableUnits.map((u, i) =>
|
||||
Denomination.fromJson(u, validator, `${ctx}.units[${i}]`)
|
||||
)
|
||||
|
|
@ -157,7 +164,11 @@ export class Unit {
|
|||
* ]
|
||||
* }, "test")
|
||||
*/
|
||||
private static parse(json: UnitConfigJson, types: Record<string, ValidatorType>, ctx: string): Unit[] {
|
||||
private static parse(
|
||||
json: UnitConfigJson,
|
||||
types: Record<string, ValidatorType>,
|
||||
ctx: string
|
||||
): Unit[] {
|
||||
const appliesTo = json.appliesToKey
|
||||
for (let i = 0; i < (appliesTo ?? []).length; i++) {
|
||||
let key = appliesTo[i]
|
||||
|
|
@ -171,7 +182,6 @@ export class Unit {
|
|||
}
|
||||
// Some keys do have unit handling
|
||||
|
||||
|
||||
const units: Unit[] = []
|
||||
if (appliesTo === undefined) {
|
||||
units.push(this.parseDenomination(json, Validators.get("float"), undefined, ctx))
|
||||
|
|
@ -213,7 +223,8 @@ export class Unit {
|
|||
private static loadFromLibrary(
|
||||
spec: Record<
|
||||
string,
|
||||
string | { quantity: string; denominations: string[]; canonical?: string, inverted?: boolean }
|
||||
| string
|
||||
| { quantity: string; denominations: string[]; canonical?: string; inverted?: boolean }
|
||||
>,
|
||||
types: Record<string, ValidatorType>,
|
||||
ctx: string
|
||||
|
|
@ -225,7 +236,14 @@ export class Unit {
|
|||
if (typeof toLoad === "string") {
|
||||
const loaded = this.getFromLibrary(toLoad, ctx)
|
||||
units.push(
|
||||
new Unit(loaded.quantity, [key], loaded.denominations, loaded.eraseInvalid, validator, toLoad["inverted"])
|
||||
new Unit(
|
||||
loaded.quantity,
|
||||
[key],
|
||||
loaded.denominations,
|
||||
loaded.eraseInvalid,
|
||||
validator,
|
||||
toLoad["inverted"]
|
||||
)
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
|
@ -246,19 +264,32 @@ export class Unit {
|
|||
return found
|
||||
}
|
||||
|
||||
if(!Array.isArray(toLoad.denominations)){
|
||||
throw "toLoad is not an array. Did you forget the [ and ] around the denominations at "+ctx+"?"
|
||||
if (!Array.isArray(toLoad.denominations)) {
|
||||
throw (
|
||||
"toLoad is not an array. Did you forget the [ and ] around the denominations at " +
|
||||
ctx +
|
||||
"?"
|
||||
)
|
||||
}
|
||||
const denoms = toLoad.denominations
|
||||
.map((d) => d.toLowerCase())
|
||||
.map((d) => fetchDenom(d))
|
||||
.map(d => d.withValidator(validator))
|
||||
.map((d) => d.withValidator(validator))
|
||||
|
||||
if (toLoad.canonical) {
|
||||
const canonical = fetchDenom(toLoad.canonical).withValidator(validator)
|
||||
denoms.unshift(canonical.withBlankCanonical())
|
||||
}
|
||||
units.push(new Unit(loaded.quantity, [key], denoms, loaded.eraseInvalid, validator, toLoad["inverted"]))
|
||||
units.push(
|
||||
new Unit(
|
||||
loaded.quantity,
|
||||
[key],
|
||||
denoms,
|
||||
loaded.eraseInvalid,
|
||||
validator,
|
||||
toLoad["inverted"]
|
||||
)
|
||||
)
|
||||
}
|
||||
return units
|
||||
}
|
||||
|
|
@ -280,7 +311,11 @@ export class Unit {
|
|||
}
|
||||
const defaultDenom = this.getDefaultDenomination(country)
|
||||
for (const denomination of this.denominationsSorted) {
|
||||
const bare = denomination.StrippedValue(valueWithDenom, defaultDenom === denomination, this.inverted)
|
||||
const bare = denomination.StrippedValue(
|
||||
valueWithDenom,
|
||||
defaultDenom === denomination,
|
||||
this.inverted
|
||||
)
|
||||
if (bare !== null) {
|
||||
return [bare, denomination]
|
||||
}
|
||||
|
|
@ -294,8 +329,8 @@ export class Unit {
|
|||
}
|
||||
const [stripped, denom] = this.findDenomination(value, country)
|
||||
const human = denom?.human
|
||||
if(this.inverted ){
|
||||
return human.Subs({quantity: stripped+"/"})
|
||||
if (this.inverted) {
|
||||
return human.Subs({ quantity: stripped + "/" })
|
||||
}
|
||||
if (stripped === "1") {
|
||||
return denom?.humanSingular ?? stripped
|
||||
|
|
@ -309,8 +344,8 @@ export class Unit {
|
|||
|
||||
public toOsm(value: string, denomination: string) {
|
||||
const denom = this.denominations.find((d) => d.canonical === denomination)
|
||||
if(this.inverted){
|
||||
return value+"/"+denom._canonicalSingular
|
||||
if (this.inverted) {
|
||||
return value + "/" + denom._canonicalSingular
|
||||
}
|
||||
|
||||
const space = denom.addSpace ? " " : ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue