forked from MapComplete/MapComplete
Refactoring: split 'Utils' into multiple files; fix some stray uppercase-method names
This commit is contained in:
parent
81be4db044
commit
3ec89826e4
97 changed files with 884 additions and 921 deletions
|
|
@ -9,6 +9,7 @@ import { Utils } from "../Utils"
|
|||
import { TagUtils } from "../Logic/Tags/TagUtils"
|
||||
import { And } from "../Logic/Tags/And"
|
||||
import { GlobalFilter } from "./GlobalFilter"
|
||||
import { Lists } from "../Utils/Lists"
|
||||
|
||||
export default class FilteredLayer {
|
||||
/**
|
||||
|
|
@ -287,7 +288,7 @@ export default class FilteredLayer {
|
|||
}
|
||||
needed.push(filter.options[state.data].osmTags)
|
||||
}
|
||||
needed = Utils.NoNull(needed)
|
||||
needed = Lists.noNull(needed)
|
||||
if (needed.length == 0) {
|
||||
return undefined
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ import { ThemeConfigJson } from "../../src/Models/ThemeConfig/Json/ThemeConfigJs
|
|||
import SpecialVisualizations from "../../src/UI/SpecialVisualizations"
|
||||
import ValidationUtils from "../../src/Models/ThemeConfig/Conversion/ValidationUtils"
|
||||
import {
|
||||
QuestionableTagRenderingConfigJson
|
||||
QuestionableTagRenderingConfigJson,
|
||||
} from "../../src/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
|
||||
import { LayerConfigJson } from "../../src/Models/ThemeConfig/Json/LayerConfigJson"
|
||||
import { Lists } from "../Utils/Lists"
|
||||
|
||||
export interface ServerSourceInfo {
|
||||
url: string
|
||||
|
|
@ -81,7 +82,7 @@ export class SourceOverview {
|
|||
|
||||
const geojsonSources: string[] = layout?.layers?.map((l) => l.source?.geojsonSource) ?? []
|
||||
|
||||
return Utils.NoNull(apiUrls.concat(...geojsonSources)).filter((item) => {
|
||||
return Lists.noNull(apiUrls.concat(...geojsonSources)).filter((item) => {
|
||||
if (typeof item === "string") {
|
||||
return true
|
||||
}
|
||||
|
|
@ -117,7 +118,7 @@ export class SourceOverview {
|
|||
"Background layer source or supporting sources for " + f.properties.id,
|
||||
trigger: ["specific_feature"],
|
||||
category: "maplayer",
|
||||
moreInfo: Utils.NoEmpty([
|
||||
moreInfo: Lists.noEmpty([
|
||||
"https://github.com/osmlab/editor-layer-index",
|
||||
f.properties?.attribution?.url,
|
||||
]),
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
QuestionableTagRenderingConfigJson,
|
||||
} from "../Json/QuestionableTagRenderingConfigJson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import { ConversionContext } from "./ConversionContext"
|
||||
|
||||
export default class AddPrefixToTagRenderingConfig extends DesugaringStep<QuestionableTagRenderingConfigJson> {
|
||||
private readonly _prefix: string
|
||||
|
|
@ -142,7 +143,8 @@ export default class AddPrefixToTagRenderingConfig extends DesugaringStep<Questi
|
|||
}
|
||||
|
||||
public convert(
|
||||
json: Readonly<QuestionableTagRenderingConfigJson>
|
||||
json: Readonly<QuestionableTagRenderingConfigJson>,
|
||||
context: ConversionContext
|
||||
): QuestionableTagRenderingConfigJson {
|
||||
let freeform = json.freeform
|
||||
if (freeform) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
|
||||
import { ConversionContext } from "./ConversionContext"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export interface DesugaringContext {
|
||||
tagRenderings: Map<string, QuestionableTagRenderingConfigJson>
|
||||
|
|
@ -219,7 +219,7 @@ export class Concat<X, T> extends Conversion<X[], T[]> {
|
|||
return <undefined | null>values
|
||||
}
|
||||
const vals: T[][] = new Each(this._step).convert(values, context.inOperation("concat"))
|
||||
return [].concat(...vals)
|
||||
return vals.flatMap(l => l)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +264,6 @@ export class Cached<TIn, TOut> extends Conversion<TIn, TOut> {
|
|||
}
|
||||
|
||||
export class Fuse<T> extends DesugaringStep<T> {
|
||||
protected debug = false
|
||||
private readonly steps: DesugaringStep<T>[]
|
||||
|
||||
constructor(doc: string, ...steps: DesugaringStep<T>[]) {
|
||||
|
|
@ -274,18 +273,12 @@ export class Fuse<T> extends DesugaringStep<T> {
|
|||
"This fused pipeline of the following steps: " +
|
||||
steps.map((s) => s.name).join(", ")
|
||||
)
|
||||
this.steps = Utils.NoNull(steps)
|
||||
this.steps = Lists.noNull(steps)
|
||||
}
|
||||
|
||||
public enableDebugging(): Fuse<T> {
|
||||
this.debug = true
|
||||
return this
|
||||
}
|
||||
|
||||
convert(json: T, context: ConversionContext): T {
|
||||
const timings = []
|
||||
for (let i = 0; i < this.steps.length; i++) {
|
||||
const start = new Date()
|
||||
const step = this.steps[i]
|
||||
try {
|
||||
const r = step.convert(json, context.inOperation(step.name))
|
||||
|
|
@ -297,14 +290,6 @@ export class Fuse<T> extends DesugaringStep<T> {
|
|||
console.error("Step " + step.name + " failed due to ", e, e.stack)
|
||||
throw e
|
||||
}
|
||||
if (this.debug) {
|
||||
const stop = new Date()
|
||||
const timeNeededMs = stop.getTime() - start.getTime()
|
||||
timings.push(timeNeededMs)
|
||||
}
|
||||
}
|
||||
if (this.debug) {
|
||||
console.log("Time needed,", timings.join(", "))
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { DesugaringStep } from "./Conversion"
|
||||
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||
import { ConversionContext } from "./ConversionContext"
|
||||
import { Utils } from "../../../Utils"
|
||||
import Translations from "../../../UI/i18n/Translations"
|
||||
import { DoesImageExist } from "./Validation"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJson> {
|
||||
private readonly _doesImageExist: DoesImageExist
|
||||
|
|
@ -45,7 +45,7 @@ export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJ
|
|||
for (let i = 0; i < json.mappings.length; i++) {
|
||||
const mapping = json.mappings[i]
|
||||
const ignore = mapping["#"]?.indexOf(ignoreToken) >= 0
|
||||
const images = Utils.Dedup(Translations.T(mapping.then)?.ExtractImages() ?? [])
|
||||
const images = Lists.dedup(Translations.T(mapping.then)?.ExtractImages() ?? [])
|
||||
const ctx = context.enters("mappings", i)
|
||||
if (images.length > 0) {
|
||||
if (!ignore) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import Translations from "../../../UI/i18n/Translations"
|
|||
import { FlatTag, OptimizedTag, TagsFilterClosed } from "../../../Logic/Tags/TagTypes"
|
||||
import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
|
||||
import { Translation } from "../../../UI/i18n/Translation"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export class PruneFilters extends DesugaringStep<LayerConfigJson> {
|
||||
constructor() {
|
||||
|
|
@ -107,9 +108,7 @@ export class PruneFilters extends DesugaringStep<LayerConfigJson> {
|
|||
const sourceTags = TagUtils.Tag(json.source["osmTags"])
|
||||
return {
|
||||
...json,
|
||||
filter: Utils.NoNull(
|
||||
json.filter?.map((obj) => this.prune(sourceTags, <FilterConfigJson>obj, context))
|
||||
),
|
||||
filter: Lists.noNull(json.filter?.map((obj) => this.prune(sourceTags, <FilterConfigJson>obj, context))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { Utils } from "../../../Utils"
|
|||
import { AddContextToTranslations } from "./AddContextToTranslations"
|
||||
import AddPrefixToTagRenderingConfig from "./AddPrefixToTagRenderingConfig"
|
||||
import { Translatable } from "../Json/Translatable"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export class ExpandTagRendering extends Conversion<
|
||||
| string
|
||||
|
|
@ -41,8 +42,7 @@ export class ExpandTagRendering extends Conversion<
|
|||
) {
|
||||
super(
|
||||
"ExpandTagRendering",
|
||||
"Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins",
|
||||
[]
|
||||
"Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins"
|
||||
)
|
||||
this._state = state
|
||||
this._self = self
|
||||
|
|
@ -387,7 +387,7 @@ export class ExpandTagRendering extends Conversion<
|
|||
if (layer === undefined) {
|
||||
const candidates = Utils.sortedByLevenshteinDistance(
|
||||
layerName,
|
||||
Utils.NoNull(Array.from(state.sharedLayers.keys()))
|
||||
Lists.noNull(Array.from(state.sharedLayers.keys()))
|
||||
)
|
||||
if (candidates.length === 0) {
|
||||
ctx.err(
|
||||
|
|
@ -413,7 +413,7 @@ export class ExpandTagRendering extends Conversion<
|
|||
// We are dealing with a looping import, no error is necessary
|
||||
continue
|
||||
}
|
||||
candidates = Utils.NoNull(layer.tagRenderings.map((tr) => tr["id"])).map(
|
||||
candidates = Lists.noNull(layer.tagRenderings.map((tr) => tr["id"])).map(
|
||||
(id) => layerName + "." + id
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import Translations from "../../../UI/i18n/Translations"
|
|||
|
||||
import { parse as parse_html } from "node-html-parser"
|
||||
import { ConversionContext } from "./ConversionContext"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export class ExtractImages extends Conversion<
|
||||
ThemeConfigJson,
|
||||
|
|
@ -243,16 +244,12 @@ export class ExtractImages extends Conversion<
|
|||
}
|
||||
|
||||
// Split "circle:white;./assets/layers/.../something.svg" into ["circle", "./assets/layers/.../something.svg"]
|
||||
const allPaths = Utils.NoNull(
|
||||
Utils.NoEmpty(
|
||||
foundImage.path?.split(";")?.map((part) => {
|
||||
if (part.startsWith("http")) {
|
||||
return part
|
||||
}
|
||||
return part.split(":")[0]
|
||||
})
|
||||
)
|
||||
)
|
||||
const allPaths = Lists.noNull(Lists.noEmpty(foundImage.path?.split(";")?.map((part) => {
|
||||
if (part.startsWith("http")) {
|
||||
return part
|
||||
}
|
||||
return part.split(":")[0]
|
||||
})))
|
||||
for (const path of allPaths) {
|
||||
cleanedImages.push({
|
||||
path,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { ThemeConfigJson } from "../Json/ThemeConfigJson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import LineRenderingConfigJson from "../Json/LineRenderingConfigJson"
|
||||
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||
import { DesugaringStep, Each, Fuse, On } from "./Conversion"
|
||||
import PointRenderingConfigJson from "../Json/PointRenderingConfigJson"
|
||||
import { ConversionContext } from "./ConversionContext"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export class UpdateLegacyLayer extends DesugaringStep<
|
||||
LayerConfigJson | string | { builtin; override }
|
||||
|
|
@ -190,7 +190,7 @@ export class UpdateLegacyLayer extends DesugaringStep<
|
|||
) {
|
||||
iconConfig = iconConfig.render
|
||||
}
|
||||
const icon = Utils.NoEmpty(iconConfig.split(";"))
|
||||
const icon = Lists.noEmpty(iconConfig.split(";"))
|
||||
pr.marker = icon.map((i) => {
|
||||
if (i.startsWith("http")) {
|
||||
return { icon: i }
|
||||
|
|
@ -281,7 +281,7 @@ class UpdateLegacyTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
}
|
||||
}
|
||||
|
||||
oldThemeConfig.layers = Utils.NoNull(oldThemeConfig.layers)
|
||||
oldThemeConfig.layers = Lists.noNull(oldThemeConfig.layers)
|
||||
delete oldThemeConfig["language"]
|
||||
delete oldThemeConfig["version"]
|
||||
delete oldThemeConfig["clustering"]
|
||||
|
|
|
|||
|
|
@ -1,18 +1,6 @@
|
|||
import {
|
||||
Concat,
|
||||
DesugaringContext,
|
||||
DesugaringStep,
|
||||
Each,
|
||||
FirstOf,
|
||||
Fuse,
|
||||
On,
|
||||
SetDefault,
|
||||
} from "./Conversion"
|
||||
import { Concat, DesugaringContext, DesugaringStep, Each, FirstOf, Fuse, On, SetDefault } from "./Conversion"
|
||||
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||
import {
|
||||
MinimalTagRenderingConfigJson,
|
||||
TagRenderingConfigJson,
|
||||
} from "../Json/TagRenderingConfigJson"
|
||||
import { MinimalTagRenderingConfigJson, TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import RewritableConfigJson from "../Json/RewritableConfigJson"
|
||||
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
||||
|
|
@ -33,6 +21,7 @@ import { TagUtils } from "../../../Logic/Tags/TagUtils"
|
|||
import { ExpandFilter, PruneFilters } from "./ExpandFilter"
|
||||
import { ExpandTagRendering } from "./ExpandTagRendering"
|
||||
import layerconfig from "../../../assets/schemas/layerconfigmeta.json"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
class AddFiltersFromTagRenderings extends DesugaringStep<LayerConfigJson> {
|
||||
constructor() {
|
||||
|
|
@ -360,7 +349,7 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
|
|||
const addByDefault = this.builtinQuestions.filter((tr) => tr.labels?.indexOf(key) >= 0)
|
||||
const ids = new Set(addByDefault.map((tr) => tr.id))
|
||||
const idsInOrder = this._desugaring.tagRenderingOrder?.filter((id) => ids.has(id)) ?? []
|
||||
return Utils.NoNull(idsInOrder.map((id) => this._desugaring.tagRenderings.get(id)))
|
||||
return Lists.noNull(idsInOrder.map((id) => this._desugaring.tagRenderings.get(id)))
|
||||
}
|
||||
|
||||
convert(json: LayerConfigJson, _: ConversionContext): LayerConfigJson {
|
||||
|
|
@ -771,11 +760,11 @@ class ExpandIconBadges extends DesugaringStep<PointRenderingConfigJson> {
|
|||
const condition = tr.condition
|
||||
for (const trElement of tr.mappings) {
|
||||
const showIf = TagUtils.optimzeJson({
|
||||
and: Utils.NoNull([
|
||||
condition,
|
||||
{
|
||||
or: Utils.NoNull([trElement.alsoShowIf, trElement.if]),
|
||||
},
|
||||
and: Lists.noNull([
|
||||
condition,
|
||||
{
|
||||
or: Lists.noNull([trElement.alsoShowIf, trElement.if]),
|
||||
},
|
||||
]),
|
||||
})
|
||||
if (showIf === true) {
|
||||
|
|
@ -984,14 +973,12 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
|
|||
|
||||
const allAutoIndex = json.titleIcons.indexOf(<any>"auto:*")
|
||||
if (allAutoIndex >= 0) {
|
||||
const generated = Utils.NoNull(
|
||||
json.tagRenderings.map((tr) => {
|
||||
if (typeof tr === "string") {
|
||||
return undefined
|
||||
}
|
||||
return this.createTitleIconsBasedOn(<any>tr)
|
||||
})
|
||||
)
|
||||
const generated = Lists.noNull(json.tagRenderings.map((tr) => {
|
||||
if (typeof tr === "string") {
|
||||
return undefined
|
||||
}
|
||||
return this.createTitleIconsBasedOn(<any>tr)
|
||||
}))
|
||||
json.titleIcons.splice(allAutoIndex, 1, ...generated)
|
||||
return json
|
||||
}
|
||||
|
|
@ -1113,9 +1100,7 @@ export class OrderTagRendering extends DesugaringStep<TagRenderingConfigJson | s
|
|||
}
|
||||
|
||||
export class OrderLayer extends DesugaringStep<string | LayerConfigJson> {
|
||||
private static readonly layerAttributesOrder: ReadonlyArray<string> = Utils.Dedup(
|
||||
(<ConfigMeta[]>layerconfig).filter((c) => c.path.length === 1).map((c) => c.path[0])
|
||||
)
|
||||
private static readonly layerAttributesOrder: ReadonlyArray<string> = Lists.dedup((<ConfigMeta[]>layerconfig).filter((c) => c.path.length === 1).map((c) => c.path[0]))
|
||||
|
||||
constructor() {
|
||||
super("OrderLayer", "Reorders a tagRendering to the default order")
|
||||
|
|
@ -1151,7 +1136,8 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
|
|||
"Fully prepares and expands a layer for the LayerConfig.",
|
||||
new DeriveSource(),
|
||||
new On("tagRenderings", new Each(new RewriteSpecial())),
|
||||
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
||||
new On("tagRenderings", new Concat(new ExpandRewrite())
|
||||
.andThenF(Utils.Flatten)),
|
||||
new On(
|
||||
"tagRenderings",
|
||||
(layer) =>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,4 @@
|
|||
import {
|
||||
Concat,
|
||||
Conversion,
|
||||
DesugaringContext,
|
||||
DesugaringStep,
|
||||
Each,
|
||||
Fuse,
|
||||
On,
|
||||
Pass,
|
||||
SetDefault,
|
||||
} from "./Conversion"
|
||||
import { Concat, Conversion, DesugaringContext, DesugaringStep, Each, Fuse, On, Pass, SetDefault } from "./Conversion"
|
||||
import { ThemeConfigJson } from "../Json/ThemeConfigJson"
|
||||
import { OrderLayer, PrepareLayer, RewriteSpecial } from "./PrepareLayer"
|
||||
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||
|
|
@ -22,6 +12,7 @@ import ValidationUtils from "./ValidationUtils"
|
|||
import { ConversionContext } from "./ConversionContext"
|
||||
import { ConfigMeta } from "../../../UI/Studio/configMeta"
|
||||
import themeconfig from "../../../assets/schemas/layoutconfigmeta.json"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJson[]> {
|
||||
private readonly _state: DesugaringContext
|
||||
|
|
@ -198,7 +189,7 @@ export class AddDefaultLayers extends DesugaringStep<ThemeConfigJson> {
|
|||
|
||||
convert(json: ThemeConfigJson, context: ConversionContext): ThemeConfigJson {
|
||||
const state = this._state
|
||||
json.layers = Utils.NoNull([...(json.layers ?? [])])
|
||||
json.layers = Lists.noNull([...(json.layers ?? [])])
|
||||
const alreadyLoaded = new Set(json.layers.map((l) => l["id"]))
|
||||
|
||||
for (const layerName of Constants.added_by_default) {
|
||||
|
|
@ -612,9 +603,7 @@ class PostvalidateTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
}
|
||||
}
|
||||
export class OrderTheme extends Fuse<ThemeConfigJson> {
|
||||
private static readonly themeAttributesOrder: ReadonlyArray<string> = Utils.Dedup(
|
||||
(<ConfigMeta[]>themeconfig).filter((c) => c.path.length === 1).map((c) => c.path[0])
|
||||
)
|
||||
private static readonly themeAttributesOrder: ReadonlyArray<string> = Lists.dedup((<ConfigMeta[]>themeconfig).filter((c) => c.path.length === 1).map((c) => c.path[0]))
|
||||
|
||||
constructor() {
|
||||
super("Reorders the layer to the default order",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { And } from "../../../Logic/Tags/And"
|
|||
import { DoesImageExist, ValidateFilter, ValidatePointRendering } from "./Validation"
|
||||
import { ValidateTagRenderings } from "./ValidateTagRenderings"
|
||||
import { TagsFilterClosed } from "../../../Logic/Tags/TagTypes"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
|
||||
private readonly _isBuiltin: boolean
|
||||
|
|
@ -207,10 +208,8 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
|
|||
}
|
||||
{
|
||||
// duplicate ids in tagrenderings check
|
||||
const duplicates = Utils.NoNull(
|
||||
Utils.Duplicates(Utils.NoNull((json.tagRenderings ?? []).map((tr) => tr["id"])))
|
||||
)
|
||||
if (duplicates.length > 0) {
|
||||
const duplicates = Lists.noNull(Utils.Duplicates(json.tagRenderings?.map((tr) => tr?.["id"])))
|
||||
if (duplicates?.length > 0) {
|
||||
// It is tempting to add an index to this warning; however, due to labels the indices here might be different from the index in the tagRendering list
|
||||
context
|
||||
.enter("tagRenderings")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
||||
import { RenderingSpecification, SpecialVisualization } from "../../../UI/SpecialVisualization"
|
||||
import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export default class ValidationUtils {
|
||||
public static getAllSpecialVisualisations(
|
||||
|
|
@ -51,9 +51,9 @@ export default class ValidationUtils {
|
|||
JSON.stringify(renderingConfig.mappings)
|
||||
)
|
||||
}
|
||||
const translations: any[] = Utils.NoNull([
|
||||
renderingConfig.render,
|
||||
...(renderingConfig.mappings ?? []).map((m) => m.then),
|
||||
const translations: any[] = Lists.noNull([
|
||||
renderingConfig.render,
|
||||
...(renderingConfig.mappings ?? []).map((m) => m.then),
|
||||
])
|
||||
const all: RenderingSpecification[] = []
|
||||
for (let translation of translations) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { Utils } from "../../Utils"
|
|||
import { RegexTag } from "../../Logic/Tags/RegexTag"
|
||||
import MarkdownUtils from "../../Utils/MarkdownUtils"
|
||||
import Validators, { ValidatorType } from "../../UI/InputElement/Validators"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
|
||||
export type FilterConfigOption = {
|
||||
question: Translation
|
||||
|
|
@ -225,17 +226,17 @@ export default class FilterConfig {
|
|||
public GenerateDocs(): string {
|
||||
const hasField = this.options.some((opt) => opt.fields?.length > 0)
|
||||
return MarkdownUtils.table(
|
||||
Utils.NoNull(["id", "question", "osmTags", hasField ? "fields" : undefined]),
|
||||
Lists.noNull(["id", "question", "osmTags", hasField ? "fields" : undefined]),
|
||||
this.options.map((opt, i) => {
|
||||
const isDefault = this.options.length > 1 && (this.defaultSelection ?? 0) == i
|
||||
return <string[]>(
|
||||
Utils.NoNull([
|
||||
this.id + "." + i,
|
||||
isDefault ? `*${opt.question.txt}* (default)` : opt.question,
|
||||
opt.osmTags?.asHumanString() ?? "",
|
||||
opt.fields?.length > 0
|
||||
? opt.fields.map((f) => f.name + " (" + f.type + ")").join(" ")
|
||||
: undefined,
|
||||
Lists.noNull([
|
||||
this.id + "." + i,
|
||||
isDefault ? `*${opt.question.txt}* (default)` : opt.question,
|
||||
opt.osmTags?.asHumanString() ?? "",
|
||||
opt.fields?.length > 0
|
||||
? opt.fields.map((f) => f.name + " (" + f.type + ")").join(" ")
|
||||
: undefined,
|
||||
])
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import MarkdownUtils from "../../Utils/MarkdownUtils"
|
|||
import { And } from "../../Logic/Tags/And"
|
||||
import OsmWiki from "../../Logic/Osm/OsmWiki"
|
||||
import { UnitUtils } from "../UnitUtils"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
|
||||
export default class LayerConfig extends WithContextLoader {
|
||||
public static readonly syncSelectionAllowed = ["no", "local", "theme-only", "global"] as const
|
||||
|
|
@ -226,7 +227,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
if (json.lineRendering) {
|
||||
this.lineRendering = Utils.NoNull(json.lineRendering).map(
|
||||
this.lineRendering = Lists.noNull(json.lineRendering).map(
|
||||
(r, i) => new LineRenderingConfig(r, `${context}[${i}]`)
|
||||
)
|
||||
} else {
|
||||
|
|
@ -234,7 +235,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
if (json.pointRendering) {
|
||||
this.mapRendering = Utils.NoNull(json.pointRendering).map(
|
||||
this.mapRendering = Lists.noNull(json.pointRendering).map(
|
||||
(r, i) => new PointRenderingConfig(r, `${context}[${i}](${this.id})`)
|
||||
)
|
||||
} else {
|
||||
|
|
@ -283,7 +284,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
const missingIds =
|
||||
Utils.NoNull(json.tagRenderings)?.filter(
|
||||
Lists.noNull(json.tagRenderings)?.filter(
|
||||
(tr) =>
|
||||
typeof tr !== "string" &&
|
||||
tr["builtin"] === undefined &&
|
||||
|
|
@ -298,7 +299,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
throw msg
|
||||
}
|
||||
|
||||
this.tagRenderings = (Utils.NoNull(json.tagRenderings) ?? []).map(
|
||||
this.tagRenderings = (Lists.noNull(json.tagRenderings) ?? []).map(
|
||||
(tr, i) =>
|
||||
new TagRenderingConfig(
|
||||
<QuestionableTagRenderingConfigJson>tr,
|
||||
|
|
@ -431,7 +432,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
|
||||
return [
|
||||
`[${tr.id}](#${tr.id}) ${origDef}`,
|
||||
Utils.NoNull([q, r, options]).join("<br/>"),
|
||||
Lists.noNull([q, r, options]).join("<br/>"),
|
||||
tr.labels.join(", "),
|
||||
key,
|
||||
]
|
||||
|
|
@ -560,7 +561,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
]
|
||||
}
|
||||
|
||||
for (const revDep of Utils.Dedup(layerIsNeededBy?.get(this.id) ?? [])) {
|
||||
for (const revDep of Lists.dedup(layerIsNeededBy?.get(this.id) ?? [])) {
|
||||
extraProps.push(
|
||||
["This layer is needed as dependency for layer", `[${revDep}](#${revDep})`].join(
|
||||
" "
|
||||
|
|
@ -568,32 +569,30 @@ export default class LayerConfig extends WithContextLoader {
|
|||
)
|
||||
}
|
||||
|
||||
const tableRows: string[][] = Utils.NoNull(
|
||||
this.tagRenderings
|
||||
.map((tr) => tr.FreeformValues())
|
||||
.filter((values) => values !== undefined)
|
||||
.filter((values) => values.key !== "id")
|
||||
.map((values) => {
|
||||
const embedded: string[] = values.values?.map((v) =>
|
||||
OsmWiki.constructLinkMd(values.key, v)
|
||||
) ?? ["_no preset options defined, or no values in them_"]
|
||||
const statistics = `https://taghistory.raifer.tech/?#***/${encodeURIComponent(
|
||||
values.key
|
||||
)}/`
|
||||
const tagInfo = `https://taginfo.openstreetmap.org/keys/${values.key}#values`
|
||||
return [
|
||||
[
|
||||
`<a target="_blank" href='${tagInfo}'><img src='https://mapcomplete.org/assets/svg/search.svg' height='18px'></a>`,
|
||||
`<a target="_blank" href='${statistics}'><img src='https://mapcomplete.org/assets/svg/statistics.svg' height='18px'></a>`,
|
||||
OsmWiki.constructLinkMd(values.key),
|
||||
].join(" "),
|
||||
values.type === undefined
|
||||
? "Multiple choice"
|
||||
: `[${values.type}](../SpecialInputElements.md#${values.type})`,
|
||||
embedded.join(" "),
|
||||
]
|
||||
})
|
||||
)
|
||||
const tableRows: string[][] = Lists.noNull(this.tagRenderings
|
||||
.map((tr) => tr.FreeformValues())
|
||||
.filter((values) => values !== undefined)
|
||||
.filter((values) => values.key !== "id")
|
||||
.map((values) => {
|
||||
const embedded: string[] = values.values?.map((v) =>
|
||||
OsmWiki.constructLinkMd(values.key, v)
|
||||
) ?? ["_no preset options defined, or no values in them_"]
|
||||
const statistics = `https://taghistory.raifer.tech/?#***/${encodeURIComponent(
|
||||
values.key
|
||||
)}/`
|
||||
const tagInfo = `https://taginfo.openstreetmap.org/keys/${values.key}#values`
|
||||
return [
|
||||
[
|
||||
`<a target="_blank" href='${tagInfo}'><img src='https://mapcomplete.org/assets/svg/search.svg' height='18px'></a>`,
|
||||
`<a target="_blank" href='${statistics}'><img src='https://mapcomplete.org/assets/svg/statistics.svg' height='18px'></a>`,
|
||||
OsmWiki.constructLinkMd(values.key),
|
||||
].join(" "),
|
||||
values.type === undefined
|
||||
? "Multiple choice"
|
||||
: `[${values.type}](../SpecialInputElements.md#${values.type})`,
|
||||
embedded.join(" "),
|
||||
]
|
||||
}))
|
||||
|
||||
let quickOverview: string[] = []
|
||||
if (tableRows.length > 0) {
|
||||
|
|
@ -693,7 +692,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
AllTagRenderings(): TagRenderingConfig[] {
|
||||
return Utils.NoNull([...this.tagRenderings, ...this.titleIcons, this.title])
|
||||
return Lists.noNull([...this.tagRenderings, ...this.titleIcons, this.title])
|
||||
}
|
||||
|
||||
public isLeftRightSensitive(): boolean {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import { TagUtils } from "../../Logic/Tags/TagUtils"
|
|||
import { And } from "../../Logic/Tags/And"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
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"
|
||||
|
|
@ -21,6 +18,7 @@ import { UploadableTag } from "../../Logic/Tags/TagTypes"
|
|||
import LayerConfig from "./LayerConfig"
|
||||
import ComparingTag from "../../Logic/Tags/ComparingTag"
|
||||
import { Unit } from "../Unit"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
|
||||
export interface Mapping {
|
||||
readonly if: UploadableTag
|
||||
|
|
@ -317,7 +315,7 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
keys.push(...mapping.if.usedKeys())
|
||||
}
|
||||
keys = Utils.Dedup(keys)
|
||||
keys = Lists.dedup(keys)
|
||||
for (let i = 0; i < this.mappings.length; i++) {
|
||||
const mapping = this.mappings[i]
|
||||
if (mapping.hideInAnswer) {
|
||||
|
|
@ -352,7 +350,7 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
allKeys = allKeys.concat(mapping.if.usedKeys())
|
||||
}
|
||||
allKeys = Utils.Dedup(allKeys)
|
||||
allKeys = Lists.dedup(allKeys)
|
||||
if (allKeys.length > 1 && !allHaveIfNot) {
|
||||
throw `${context}: A multi-answer is defined, which generates values over multiple keys. Please define ifnot-tags too on every mapping`
|
||||
}
|
||||
|
|
@ -541,20 +539,18 @@ export default class TagRenderingConfig {
|
|||
if?: TagsFilter
|
||||
then: TypedTranslation<Record<string, string>>
|
||||
img?: string
|
||||
}[] = Utils.NoNull(
|
||||
(this.mappings ?? [])?.filter((mapping) => {
|
||||
if (mapping.if === undefined) {
|
||||
return true
|
||||
}
|
||||
if (TagUtils.MatchesMultiAnswer(mapping.if, tags)) {
|
||||
return true
|
||||
}
|
||||
if (mapping.alsoShowIf?.matchesProperties(tags)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
)
|
||||
}[] = Lists.noNull((this.mappings ?? [])?.filter((mapping) => {
|
||||
if (mapping.if === undefined) {
|
||||
return true
|
||||
}
|
||||
if (TagUtils.MatchesMultiAnswer(mapping.if, tags)) {
|
||||
return true
|
||||
}
|
||||
if (mapping.alsoShowIf?.matchesProperties(tags)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}))
|
||||
|
||||
if (freeformKeyDefined && tags[this.freeform.key] !== undefined) {
|
||||
const usedFreeformValues = new Set<string>(
|
||||
|
|
@ -659,9 +655,7 @@ export default class TagRenderingConfig {
|
|||
const key = this.freeform?.key
|
||||
const answerMappings = this.mappings?.filter((m) => m.hideInAnswer !== true)
|
||||
if (key === undefined) {
|
||||
const values: { k: string; v: string }[][] = Utils.NoNull(
|
||||
answerMappings?.map((m) => m.if.asChange({})) ?? []
|
||||
)
|
||||
const values: { k: string; v: string }[][] = Lists.noNull(answerMappings?.map((m) => m.if.asChange({})) ?? [])
|
||||
if (values.length === 0) {
|
||||
return
|
||||
}
|
||||
|
|
@ -677,17 +671,13 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
return {
|
||||
key: commonKey,
|
||||
values: Utils.NoNull(
|
||||
values.map((arr) => arr.filter((item) => item.k === commonKey)[0]?.v)
|
||||
),
|
||||
values: Lists.noNull(values.map((arr) => arr.filter((item) => item.k === commonKey)[0]?.v)),
|
||||
}
|
||||
}
|
||||
|
||||
let values = Utils.NoNull(
|
||||
answerMappings?.map(
|
||||
(m) => m.if.asChange({}).filter((item) => item.k === key)[0]?.v
|
||||
) ?? []
|
||||
)
|
||||
let values = Lists.noNull(answerMappings?.map(
|
||||
(m) => m.if.asChange({}).filter((item) => item.k === key)[0]?.v
|
||||
) ?? [])
|
||||
if (values.length === undefined) {
|
||||
values = undefined
|
||||
}
|
||||
|
|
@ -1027,18 +1017,18 @@ export default class TagRenderingConfig {
|
|||
].join(" ")
|
||||
}
|
||||
|
||||
return Utils.NoNull([
|
||||
"### " + this.id,
|
||||
this.description,
|
||||
this.question !== undefined
|
||||
? "The question is `" + this.question.txt + "`"
|
||||
: "_This tagrendering has no question and is thus read-only_",
|
||||
freeform,
|
||||
mappings,
|
||||
condition,
|
||||
labels,
|
||||
"",
|
||||
reuse,
|
||||
return Lists.noNull([
|
||||
"### " + this.id,
|
||||
this.description,
|
||||
this.question !== undefined
|
||||
? "The question is `" + this.question.txt + "`"
|
||||
: "_This tagrendering has no question and is thus read-only_",
|
||||
freeform,
|
||||
mappings,
|
||||
condition,
|
||||
labels,
|
||||
"",
|
||||
reuse,
|
||||
]).join("\n")
|
||||
}
|
||||
|
||||
|
|
@ -1061,7 +1051,7 @@ export default class TagRenderingConfig {
|
|||
tags.push(m.ifnot)
|
||||
}
|
||||
|
||||
return Utils.NoNull(tags)
|
||||
return Lists.noNull(tags)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { TagsFilter } from "../../Logic/Tags/TagsFilter"
|
|||
import TagRenderingConfig from "./TagRenderingConfig"
|
||||
import { TagUtils } from "../../Logic/Tags/TagUtils"
|
||||
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
|
||||
/**
|
||||
* Minimal information about a theme
|
||||
|
|
@ -381,7 +382,7 @@ export default class ThemeConfig implements ThemeInformation {
|
|||
const usedImages = jsonNoFavourites._usedImages
|
||||
usedImages.sort()
|
||||
|
||||
this.usedImages = Utils.Dedup(usedImages)
|
||||
this.usedImages = Lists.dedup(usedImages)
|
||||
return this.usedImages
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue