Chore: formatting

This commit is contained in:
Pieter Vander Vennet 2024-06-16 16:06:26 +02:00
parent 35eff07c80
commit c08fe03ed0
422 changed files with 31594 additions and 43019 deletions

View file

@ -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
)
}
}

View file

@ -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

View file

@ -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
}

View file

@ -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'"
)
}
}
}

View file

@ -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"]

View file

@ -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),

View file

@ -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 }

View file

@ -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
}
>
)[]
/**

View file

@ -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
}

View file

@ -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?

View file

@ -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}]`)
)
)

View file

@ -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

View file

@ -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)

View file

@ -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(":")

View file

@ -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
})
}
}

View file

@ -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])
}

View file

@ -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 ? " " : ""