forked from MapComplete/MapComplete
refactoring: Fix generate:layeroverview
This commit is contained in:
parent
41e6a2c760
commit
9b2f92dedc
25 changed files with 194 additions and 216 deletions
|
@ -228,10 +228,13 @@ class ExpandTagRendering extends Conversion<
|
||||||
let found: TagRenderingConfigJson = Utils.Clone(matchingTrs[i])
|
let found: TagRenderingConfigJson = Utils.Clone(matchingTrs[i])
|
||||||
if (this._options?.applyCondition) {
|
if (this._options?.applyCondition) {
|
||||||
// The matched tagRenderings are 'stolen' from another layer. This means that they must match the layer condition before being shown
|
// The matched tagRenderings are 'stolen' from another layer. This means that they must match the layer condition before being shown
|
||||||
if (found.condition === undefined) {
|
|
||||||
found.condition = layer.source.osmTags
|
if (typeof layer.source !== "string") {
|
||||||
} else {
|
if (found.condition === undefined) {
|
||||||
found.condition = { and: [found.condition, layer.source.osmTags] }
|
found.condition = layer.source.osmTags
|
||||||
|
} else {
|
||||||
|
found.condition = { and: [found.condition, layer.source.osmTags] }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ import Constants from "../../Constants"
|
||||||
import CreateNoteImportLayer from "./CreateNoteImportLayer"
|
import CreateNoteImportLayer from "./CreateNoteImportLayer"
|
||||||
import LayerConfig from "../LayerConfig"
|
import LayerConfig from "../LayerConfig"
|
||||||
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||||
import { SubstitutedTranslation } from "../../../UI/SubstitutedTranslation"
|
|
||||||
import DependencyCalculator from "../DependencyCalculator"
|
import DependencyCalculator from "../DependencyCalculator"
|
||||||
import { AddContextToTranslations } from "./AddContextToTranslations"
|
import { AddContextToTranslations } from "./AddContextToTranslations"
|
||||||
|
import ValidationUtils from "./ValidationUtils"
|
||||||
|
|
||||||
class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJson[]> {
|
class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJson[]> {
|
||||||
private readonly _state: DesugaringContext
|
private readonly _state: DesugaringContext
|
||||||
|
@ -322,31 +322,7 @@ export class AddMiniMap extends DesugaringStep<LayerConfigJson> {
|
||||||
* AddMiniMap.hasMinimap({render: "Some random value {minimap}"}) // => false
|
* AddMiniMap.hasMinimap({render: "Some random value {minimap}"}) // => false
|
||||||
*/
|
*/
|
||||||
static hasMinimap(renderingConfig: TagRenderingConfigJson): boolean {
|
static hasMinimap(renderingConfig: TagRenderingConfigJson): boolean {
|
||||||
const translations: any[] = Utils.NoNull([
|
return ValidationUtils.getSpecialVisualisations(renderingConfig).indexOf("minimap") >= 0
|
||||||
renderingConfig.render,
|
|
||||||
...(renderingConfig.mappings ?? []).map((m) => m.then),
|
|
||||||
])
|
|
||||||
for (let translation of translations) {
|
|
||||||
if (typeof translation == "string") {
|
|
||||||
translation = { "*": translation }
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const key in translation) {
|
|
||||||
if (!translation.hasOwnProperty(key)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const template = translation[key]
|
|
||||||
const parts = SubstitutedTranslation.ExtractSpecialComponents(template)
|
|
||||||
const hasMiniMap = parts
|
|
||||||
.filter((part) => part.special !== undefined)
|
|
||||||
.some((special) => special.special.func.funcName === "minimap")
|
|
||||||
if (hasMiniMap) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
convert(layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson } {
|
convert(layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson } {
|
||||||
|
|
|
@ -15,7 +15,8 @@ import Svg from "../../../Svg"
|
||||||
import FilterConfigJson from "../Json/FilterConfigJson"
|
import FilterConfigJson from "../Json/FilterConfigJson"
|
||||||
import DeleteConfig from "../DeleteConfig"
|
import DeleteConfig from "../DeleteConfig"
|
||||||
import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
|
import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
|
||||||
import ValidatedTextField from "../../../UI/Input/ValidatedTextField"
|
import Validators from "../../../UI/InputElement/Validators"
|
||||||
|
import xml2js from "xml2js"
|
||||||
|
|
||||||
class ValidateLanguageCompleteness extends DesugaringStep<any> {
|
class ValidateLanguageCompleteness extends DesugaringStep<any> {
|
||||||
private readonly _languages: string[]
|
private readonly _languages: string[]
|
||||||
|
@ -619,36 +620,16 @@ class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJson> {
|
||||||
': detected `special` on the top level. Did you mean `{"render":{ "special": ... }}`'
|
': detected `special` on the top level. Did you mean `{"render":{ "special": ... }}`'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (json["question"] && !this._options?.noQuestionHintCheck) {
|
|
||||||
const question = Translations.T(
|
|
||||||
new TypedTranslation(json["question"]),
|
|
||||||
context + ".question"
|
|
||||||
)
|
|
||||||
for (const lng of question.SupportedLanguages()) {
|
|
||||||
const html = document.createElement("p")
|
|
||||||
html.innerHTML = question.textFor(lng)
|
|
||||||
const divs = Array.from(html.getElementsByTagName("div"))
|
|
||||||
const spans = Array.from(html.getElementsByTagName("span"))
|
|
||||||
const brs = Array.from(html.getElementsByTagName("br"))
|
|
||||||
const subtles = Array.from(html.getElementsByClassName("subtle"))
|
|
||||||
if (divs.length + spans.length + brs.length + subtles.length > 0) {
|
|
||||||
warnings.push(
|
|
||||||
`At ${context}: the question for ${lng} contains a div, a span, a br or an element with class 'subtle'. Please, use a \`questionHint\` instead.
|
|
||||||
The question is: ${question.textFor(lng)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const freeformType = json["freeform"]?.["type"]
|
const freeformType = json["freeform"]?.["type"]
|
||||||
if (freeformType) {
|
if (freeformType) {
|
||||||
if (ValidatedTextField.AvailableTypes().indexOf(freeformType) < 0) {
|
if (Validators.AvailableTypes().indexOf(freeformType) < 0) {
|
||||||
throw (
|
throw (
|
||||||
"At " +
|
"At " +
|
||||||
context +
|
context +
|
||||||
".freeform.type is an unknown type: " +
|
".freeform.type is an unknown type: " +
|
||||||
freeformType +
|
freeformType +
|
||||||
"; try one of " +
|
"; try one of " +
|
||||||
ValidatedTextField.AvailableTypes().join(", ")
|
Validators.AvailableTypes().join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -942,13 +923,12 @@ export class ValidateFilter extends DesugaringStep<FilterConfigJson> {
|
||||||
for (let i = 0; i < option.fields.length; i++) {
|
for (let i = 0; i < option.fields.length; i++) {
|
||||||
const field = option.fields[i]
|
const field = option.fields[i]
|
||||||
const type = field.type ?? "string"
|
const type = field.type ?? "string"
|
||||||
if (!ValidatedTextField.ForType(type) !== undefined) {
|
if (Validators.AvailableTypes().find((t) => t === type) === undefined) {
|
||||||
continue
|
const err = `Invalid filter: ${type} is not a valid textfield type (at ${context}.fields[${i}])\n\tTry one of ${Array.from(
|
||||||
|
Validators.AvailableTypes()
|
||||||
|
).join(",")}`
|
||||||
|
errors.push(err)
|
||||||
}
|
}
|
||||||
const err = `Invalid filter: ${type} is not a valid validated textfield type (at ${context}.fields[${i}])\n\tTry one of ${Array.from(
|
|
||||||
ValidatedTextField.AvailableTypes()
|
|
||||||
).join(",")}`
|
|
||||||
errors.push(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { result: filter, errors }
|
return { result: filter, errors }
|
||||||
|
|
36
Models/ThemeConfig/Conversion/ValidationUtils.ts
Normal file
36
Models/ThemeConfig/Conversion/ValidationUtils.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||||
|
import { Utils } from "../../../Utils"
|
||||||
|
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
||||||
|
|
||||||
|
export default class ValidationUtils {
|
||||||
|
/**
|
||||||
|
* Gives all the (function names of) used special visualisations
|
||||||
|
* @param renderingConfig
|
||||||
|
*/
|
||||||
|
public static getSpecialVisualisations(renderingConfig: TagRenderingConfigJson): string[] {
|
||||||
|
const translations: any[] = Utils.NoNull([
|
||||||
|
renderingConfig.render,
|
||||||
|
...(renderingConfig.mappings ?? []).map((m) => m.then),
|
||||||
|
])
|
||||||
|
const all: string[] = []
|
||||||
|
for (let translation of translations) {
|
||||||
|
if (typeof translation == "string") {
|
||||||
|
translation = { "*": translation }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key in translation) {
|
||||||
|
if (!translation.hasOwnProperty(key)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = translation[key]
|
||||||
|
const parts = SpecialVisualizations.constructSpecification(template)
|
||||||
|
const specials = parts
|
||||||
|
.filter((p) => typeof p !== "string")
|
||||||
|
.map((special) => special["func"].funcName)
|
||||||
|
all.push(...specials)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
import { SubstitutedTranslation } from "../../UI/SubstitutedTranslation"
|
|
||||||
import TagRenderingConfig from "./TagRenderingConfig"
|
import TagRenderingConfig from "./TagRenderingConfig"
|
||||||
import { ExtraFuncParams, ExtraFunctions } from "../../Logic/ExtraFunctions"
|
import { ExtraFuncParams, ExtraFunctions } from "../../Logic/ExtraFunctions"
|
||||||
import LayerConfig from "./LayerConfig"
|
import LayerConfig from "./LayerConfig"
|
||||||
import { SpecialVisualization } from "../../UI/SpecialVisualization"
|
import { SpecialVisualization } from "../../UI/SpecialVisualization"
|
||||||
|
import SpecialVisualizations from "../../UI/SpecialVisualizations"
|
||||||
|
|
||||||
export default class DependencyCalculator {
|
export default class DependencyCalculator {
|
||||||
public static GetTagRenderingDependencies(tr: TagRenderingConfig): string[] {
|
public static GetTagRenderingDependencies(tr: TagRenderingConfig): string[] {
|
||||||
|
@ -16,8 +16,9 @@ export default class DependencyCalculator {
|
||||||
|
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
const specialVizs: { func: SpecialVisualization; args: string[] }[] =
|
const specialVizs: { func: SpecialVisualization; args: string[] }[] =
|
||||||
SubstitutedTranslation.ExtractSpecialComponents(part)
|
SpecialVisualizations.constructSpecification(part)
|
||||||
.map((o) => o.special)
|
.filter((p) => typeof p !== "string")
|
||||||
|
.map((p) => <{ func: SpecialVisualization; args: string[] }>p)
|
||||||
.filter((o) => o?.func?.getLayerDependencies !== undefined)
|
.filter((o) => o?.func?.getLayerDependencies !== undefined)
|
||||||
for (const specialViz of specialVizs) {
|
for (const specialViz of specialVizs) {
|
||||||
deps.push(...specialViz.func.getLayerDependencies(specialViz.args))
|
deps.push(...specialViz.func.getLayerDependencies(specialViz.args))
|
||||||
|
|
|
@ -89,9 +89,6 @@ export default class PointRenderingConfig extends WithContextLoader {
|
||||||
this.iconSize = this.tr("iconSize", "40,40,center")
|
this.iconSize = this.tr("iconSize", "40,40,center")
|
||||||
this.label = this.tr("label", undefined)
|
this.label = this.tr("label", undefined)
|
||||||
this.rotation = this.tr("rotation", "0")
|
this.rotation = this.tr("rotation", "0")
|
||||||
if (json.pitchAlignment) {
|
|
||||||
console.log("Got a pitch alignment!", json.pitchAlignment)
|
|
||||||
}
|
|
||||||
this.pitchAlignment = this.tr("pitchAlignment", "canvas")
|
this.pitchAlignment = this.tr("pitchAlignment", "canvas")
|
||||||
this.rotationAlignment = this.tr(
|
this.rotationAlignment = this.tr(
|
||||||
"rotationAlignment",
|
"rotationAlignment",
|
||||||
|
|
56
UI/InputElement/Validator.ts
Normal file
56
UI/InputElement/Validator.ts
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import BaseUIElement from "../BaseUIElement"
|
||||||
|
import { Translation } from "../i18n/Translation"
|
||||||
|
import Translations from "../i18n/Translations"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 'TextFieldValidator' contains various methods to check and cleanup an entered value or to give feedback.
|
||||||
|
* They also double as an index of supported types for textfields in MapComplete
|
||||||
|
*/
|
||||||
|
export abstract class Validator {
|
||||||
|
public readonly name: string
|
||||||
|
/*
|
||||||
|
* An explanation for the theme builder.
|
||||||
|
* This can indicate which special input element is used, ...
|
||||||
|
* */
|
||||||
|
public readonly explanation: string
|
||||||
|
/**
|
||||||
|
* What HTML-inputmode to use
|
||||||
|
*/
|
||||||
|
public readonly inputmode?: string
|
||||||
|
|
||||||
|
constructor(name: string, explanation: string | BaseUIElement, inputmode?: string) {
|
||||||
|
this.name = name
|
||||||
|
this.inputmode = inputmode
|
||||||
|
if (this.name.endsWith("textfield")) {
|
||||||
|
this.name = this.name.substr(0, this.name.length - "TextField".length)
|
||||||
|
}
|
||||||
|
if (this.name.endsWith("textfielddef")) {
|
||||||
|
this.name = this.name.substr(0, this.name.length - "TextFieldDef".length)
|
||||||
|
}
|
||||||
|
if (typeof explanation === "string") {
|
||||||
|
this.explanation = explanation
|
||||||
|
} else {
|
||||||
|
this.explanation = explanation.AsMarkdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a piece of feedback. By default, validation.<type> will be used, resulting in a generic 'not a valid <type>'.
|
||||||
|
* However, inheritors might overwrite this to give more specific feedback
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public getFeedback(s: string): Translation {
|
||||||
|
const tr = Translations.t.validation[this.name]
|
||||||
|
if (tr !== undefined) {
|
||||||
|
return tr["feedback"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isValid(string: string, requestCountry: () => string): boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
public reformat(s: string, country?: () => string): string {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,77 +1,23 @@
|
||||||
import BaseUIElement from "../BaseUIElement"
|
import { Validator } from "./Validator"
|
||||||
import Combine from "../Base/Combine"
|
|
||||||
import Title from "../Base/Title"
|
|
||||||
import Translations from "../i18n/Translations"
|
|
||||||
import { Translation } from "../i18n/Translation"
|
|
||||||
import WikidataValidator from "./Validators/WikidataValidator"
|
|
||||||
import StringValidator from "./Validators/StringValidator"
|
import StringValidator from "./Validators/StringValidator"
|
||||||
import TextValidator from "./Validators/TextValidator"
|
import TextValidator from "./Validators/TextValidator"
|
||||||
import DateValidator from "./Validators/DateValidator"
|
import DateValidator from "./Validators/DateValidator"
|
||||||
import LengthValidator from "./Validators/LengthValidator"
|
|
||||||
import IntValidator from "./Validators/IntValidator"
|
|
||||||
import EmailValidator from "./Validators/EmailValidator"
|
|
||||||
import DirectionValidator from "./Validators/DirectionValidator"
|
|
||||||
import NatValidator from "./Validators/NatValidator"
|
import NatValidator from "./Validators/NatValidator"
|
||||||
import OpeningHoursValidator from "./Validators/OpeningHoursValidator"
|
import IntValidator from "./Validators/IntValidator"
|
||||||
import PFloatValidator from "./Validators/PFloatValidator"
|
import LengthValidator from "./Validators/LengthValidator"
|
||||||
import ColorValidator from "./Validators/ColorValidator"
|
import DirectionValidator from "./Validators/DirectionValidator"
|
||||||
import PhoneValidator from "./Validators/PhoneValidator"
|
import WikidataValidator from "./Validators/WikidataValidator"
|
||||||
import UrlValidator from "./Validators/UrlValidator"
|
|
||||||
import FloatValidator from "./Validators/FloatValidator"
|
|
||||||
import PNatValidator from "./Validators/PNatValidator"
|
import PNatValidator from "./Validators/PNatValidator"
|
||||||
|
import FloatValidator from "./Validators/FloatValidator"
|
||||||
/**
|
import PFloatValidator from "./Validators/PFloatValidator"
|
||||||
* A 'TextFieldValidator' contains various methods to check and cleanup an entered value or to give feedback.
|
import EmailValidator from "./Validators/EmailValidator"
|
||||||
* They also double as an index of supported types for textfields in MapComplete
|
import UrlValidator from "./Validators/UrlValidator"
|
||||||
*/
|
import PhoneValidator from "./Validators/PhoneValidator"
|
||||||
export abstract class Validator {
|
import OpeningHoursValidator from "./Validators/OpeningHoursValidator"
|
||||||
public readonly name: string
|
import ColorValidator from "./Validators/ColorValidator"
|
||||||
/*
|
import BaseUIElement from "../BaseUIElement"
|
||||||
* An explanation for the theme builder.
|
import Combine from "../Base/Combine"
|
||||||
* This can indicate which special input element is used, ...
|
import Title from "../Base/Title"
|
||||||
* */
|
|
||||||
public readonly explanation: string
|
|
||||||
/**
|
|
||||||
* What HTML-inputmode to use
|
|
||||||
*/
|
|
||||||
public readonly inputmode?: string
|
|
||||||
|
|
||||||
constructor(name: string, explanation: string | BaseUIElement, inputmode?: string) {
|
|
||||||
this.name = name
|
|
||||||
this.inputmode = inputmode
|
|
||||||
if (this.name.endsWith("textfield")) {
|
|
||||||
this.name = this.name.substr(0, this.name.length - "TextField".length)
|
|
||||||
}
|
|
||||||
if (this.name.endsWith("textfielddef")) {
|
|
||||||
this.name = this.name.substr(0, this.name.length - "TextFieldDef".length)
|
|
||||||
}
|
|
||||||
if (typeof explanation === "string") {
|
|
||||||
this.explanation = explanation
|
|
||||||
} else {
|
|
||||||
this.explanation = explanation.AsMarkdown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a piece of feedback. By default, validation.<type> will be used, resulting in a generic 'not a valid <type>'.
|
|
||||||
* However, inheritors might overwrite this to give more specific feedback
|
|
||||||
* @param s
|
|
||||||
*/
|
|
||||||
public getFeedback(s: string): Translation {
|
|
||||||
const tr = Translations.t.validation[this.name]
|
|
||||||
if (tr !== undefined) {
|
|
||||||
return tr["feedback"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public isValid(string: string, requestCountry: () => string): boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
public reformat(s: string, country?: () => string): string {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Validators {
|
export default class Validators {
|
||||||
private static readonly AllValidators: ReadonlyArray<Validator> = [
|
private static readonly AllValidators: ReadonlyArray<Validator> = [
|
|
@ -1,4 +1,4 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class ColorValidator extends Validator {
|
export default class ColorValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class DateValidator extends Validator {
|
export default class DateValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import IntValidator from "./IntValidator"
|
||||||
import IntValidator from "./IntValidator";
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class DirectionValidator extends IntValidator {
|
export default class DirectionValidator extends IntValidator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -13,5 +13,4 @@ export default class DirectionValidator extends IntValidator {
|
||||||
const n = Number(str) % 360
|
const n = Number(str) % 360
|
||||||
return "" + n
|
return "" + n
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Validator } from "../ValidatedTextField.js"
|
|
||||||
import { Translation } from "../../i18n/Translation.js"
|
import { Translation } from "../../i18n/Translation.js"
|
||||||
import Translations from "../../i18n/Translations.js"
|
import Translations from "../../i18n/Translations.js"
|
||||||
import * as emailValidatorLibrary from "email-validator"
|
import * as emailValidatorLibrary from "email-validator"
|
||||||
|
import { Validator } from "../Validator"
|
||||||
export default class EmailValidator extends Validator {
|
export default class EmailValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("email", "An email adress", "email")
|
super("email", "An email adress", "email")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Translation } from "../../i18n/Translation"
|
import { Translation } from "../../i18n/Translation"
|
||||||
import Translations from "../../i18n/Translations"
|
import Translations from "../../i18n/Translations"
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class FloatValidator extends Validator {
|
export default class FloatValidator extends Validator {
|
||||||
inputmode = "decimal"
|
inputmode = "decimal"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Translation } from "../../i18n/Translation"
|
import { Translation } from "../../i18n/Translation"
|
||||||
import Translations from "../../i18n/Translations"
|
import Translations from "../../i18n/Translations"
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class IntValidator extends Validator {
|
export default class IntValidator extends Validator {
|
||||||
constructor(name?: string, explanation?: string) {
|
constructor(name?: string, explanation?: string) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class LengthValidator extends Validator {
|
export default class LengthValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
|
||||||
import Combine from "../../Base/Combine"
|
import Combine from "../../Base/Combine"
|
||||||
import Title from "../../Base/Title"
|
import Title from "../../Base/Title"
|
||||||
import Table from "../../Base/Table"
|
import Table from "../../Base/Table"
|
||||||
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class OpeningHoursValidator extends Validator {
|
export default class OpeningHoursValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Translation } from "../../i18n/Translation"
|
import { Translation } from "../../i18n/Translation"
|
||||||
import Translations from "../../i18n/Translations"
|
import Translations from "../../i18n/Translations"
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class PFloatValidator extends Validator {
|
export default class PFloatValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
|
||||||
import { parsePhoneNumberFromString } from "libphonenumber-js"
|
import { parsePhoneNumberFromString } from "libphonenumber-js"
|
||||||
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class PhoneValidator extends Validator {
|
export default class PhoneValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class StringValidator extends Validator {
|
export default class StringValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("string", "A simple piece of text")
|
super("string", "A simple piece of text")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class TextValidator extends Validator {
|
export default class TextValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class UrlValidator extends Validator {
|
export default class UrlValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { UIEventSource } from "../../../Logic/UIEventSource"
|
||||||
import Locale from "../../i18n/Locale"
|
import Locale from "../../i18n/Locale"
|
||||||
import { Utils } from "../../../Utils"
|
import { Utils } from "../../../Utils"
|
||||||
import WikidataSearchBox from "../../Wikipedia/WikidataSearchBox"
|
import WikidataSearchBox from "../../Wikipedia/WikidataSearchBox"
|
||||||
import { Validator } from "../ValidatedTextField"
|
import { Validator } from "../Validator"
|
||||||
|
|
||||||
export default class WikidataValidator extends Validator {
|
export default class WikidataValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,47 +1,49 @@
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement"
|
||||||
import { SubtleButton } from "../Base/SubtleButton";
|
import { SubtleButton } from "../Base/SubtleButton"
|
||||||
import { UIEventSource } from "../../Logic/UIEventSource";
|
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import Combine from "../Base/Combine";
|
import Combine from "../Base/Combine"
|
||||||
import { VariableUiElement } from "../Base/VariableUIElement";
|
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||||
import Translations from "../i18n/Translations";
|
import Translations from "../i18n/Translations"
|
||||||
import Toggle from "../Input/Toggle";
|
import Toggle from "../Input/Toggle"
|
||||||
import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction";
|
import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction"
|
||||||
import Loading from "../Base/Loading";
|
import Loading from "../Base/Loading"
|
||||||
import { OsmConnection } from "../../Logic/Osm/OsmConnection";
|
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
|
||||||
import Lazy from "../Base/Lazy";
|
import Lazy from "../Base/Lazy"
|
||||||
import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint";
|
import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint"
|
||||||
import Img from "../Base/Img";
|
import Img from "../Base/Img"
|
||||||
import FilteredLayer from "../../Models/FilteredLayer";
|
import FilteredLayer from "../../Models/FilteredLayer"
|
||||||
import { FixedUiElement } from "../Base/FixedUiElement";
|
import { FixedUiElement } from "../Base/FixedUiElement"
|
||||||
import Svg from "../../Svg";
|
import Svg from "../../Svg"
|
||||||
import { Utils } from "../../Utils";
|
import { Utils } from "../../Utils"
|
||||||
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource";
|
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"
|
||||||
import CreateWayWithPointReuseAction, { MergePointConfig } from "../../Logic/Osm/Actions/CreateWayWithPointReuseAction";
|
import CreateWayWithPointReuseAction, {
|
||||||
import OsmChangeAction, { OsmCreateAction } from "../../Logic/Osm/Actions/OsmChangeAction";
|
MergePointConfig,
|
||||||
import FeatureSource from "../../Logic/FeatureSource/FeatureSource";
|
} from "../../Logic/Osm/Actions/CreateWayWithPointReuseAction"
|
||||||
import { OsmObject, OsmWay } from "../../Logic/Osm/OsmObject";
|
import OsmChangeAction, { OsmCreateAction } from "../../Logic/Osm/Actions/OsmChangeAction"
|
||||||
import { PresetInfo } from "../BigComponents/SimpleAddUI";
|
import FeatureSource from "../../Logic/FeatureSource/FeatureSource"
|
||||||
import { TagUtils } from "../../Logic/Tags/TagUtils";
|
import { OsmObject, OsmWay } from "../../Logic/Osm/OsmObject"
|
||||||
import { And } from "../../Logic/Tags/And";
|
import { PresetInfo } from "../BigComponents/SimpleAddUI"
|
||||||
import ReplaceGeometryAction from "../../Logic/Osm/Actions/ReplaceGeometryAction";
|
import { TagUtils } from "../../Logic/Tags/TagUtils"
|
||||||
import CreateMultiPolygonWithPointReuseAction from "../../Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction";
|
import { And } from "../../Logic/Tags/And"
|
||||||
import { Tag } from "../../Logic/Tags/Tag";
|
import ReplaceGeometryAction from "../../Logic/Osm/Actions/ReplaceGeometryAction"
|
||||||
import TagApplyButton from "./TagApplyButton";
|
import CreateMultiPolygonWithPointReuseAction from "../../Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction"
|
||||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
import { Tag } from "../../Logic/Tags/Tag"
|
||||||
import conflation_json from "../../assets/layers/conflation/conflation.json";
|
import TagApplyButton from "./TagApplyButton"
|
||||||
import { GeoOperations } from "../../Logic/GeoOperations";
|
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||||
import { LoginToggle } from "./LoginButton";
|
import conflation_json from "../../assets/layers/conflation/conflation.json"
|
||||||
import { AutoAction } from "./AutoApplyButton";
|
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||||
import Hash from "../../Logic/Web/Hash";
|
import { LoginToggle } from "./LoginButton"
|
||||||
import { PreciseInput } from "../../Models/ThemeConfig/PresetConfig";
|
import { AutoAction } from "./AutoApplyButton"
|
||||||
import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization";
|
import Hash from "../../Logic/Web/Hash"
|
||||||
import Maproulette from "../../Logic/Maproulette";
|
import { PreciseInput } from "../../Models/ThemeConfig/PresetConfig"
|
||||||
import { Feature, Point } from "geojson";
|
import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
|
||||||
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson";
|
import Maproulette from "../../Logic/Maproulette"
|
||||||
import ShowDataLayer from "../Map/ShowDataLayer";
|
import { Feature, Point } from "geojson"
|
||||||
import { MapLibreAdaptor } from "../Map/MapLibreAdaptor";
|
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
|
||||||
import SvelteUIElement from "../Base/SvelteUIElement";
|
import ShowDataLayer from "../Map/ShowDataLayer"
|
||||||
import MaplibreMap from "../Map/MaplibreMap.svelte";
|
import { MapLibreAdaptor } from "../Map/MapLibreAdaptor"
|
||||||
|
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||||
|
import MaplibreMap from "../Map/MaplibreMap.svelte"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper class for the various import-flows.
|
* A helper class for the various import-flows.
|
||||||
|
@ -377,13 +379,6 @@ export class ConflateButton extends AbstractImportButton {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayerDependencies(argsRaw: string[]): string[] {
|
|
||||||
const deps = super.getLayerDependencies(argsRaw)
|
|
||||||
// Force 'type_node' as dependency
|
|
||||||
deps.push("type_node")
|
|
||||||
return deps
|
|
||||||
}
|
|
||||||
|
|
||||||
constructElement(
|
constructElement(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
args: {
|
args: {
|
||||||
|
@ -543,12 +538,6 @@ export class ImportWayButton extends AbstractImportButton implements AutoAction
|
||||||
return type === "LineString" || type === "Polygon"
|
return type === "LineString" || type === "Polygon"
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayerDependencies(argsRaw: string[]): string[] {
|
|
||||||
const deps = super.getLayerDependencies(argsRaw)
|
|
||||||
deps.push("type_node")
|
|
||||||
return deps
|
|
||||||
}
|
|
||||||
|
|
||||||
constructElement(
|
constructElement(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
args,
|
args,
|
||||||
|
@ -565,7 +554,7 @@ export class ImportWayButton extends AbstractImportButton implements AutoAction
|
||||||
|
|
||||||
// Upload the way to OSM
|
// Upload the way to OSM
|
||||||
const mergeConfigs = this.GetMergeConfig(args)
|
const mergeConfigs = this.GetMergeConfig(args)
|
||||||
let action: OsmCreateAction & {getPreview?: any} = ImportWayButton.CreateAction(
|
let action: OsmCreateAction & { getPreview?: any } = ImportWayButton.CreateAction(
|
||||||
feature,
|
feature,
|
||||||
args,
|
args,
|
||||||
state,
|
state,
|
||||||
|
@ -751,7 +740,7 @@ export class ImportPointButton extends AbstractImportButton {
|
||||||
boundsFactor: 3,
|
boundsFactor: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
const [lon, lat] = <[number,number]> feature.geometry.coordinates
|
const [lon, lat] = <[number, number]>feature.geometry.coordinates
|
||||||
return new ConfirmLocationOfPoint(
|
return new ConfirmLocationOfPoint(
|
||||||
state,
|
state,
|
||||||
state.guistate.filterViewIsOpened,
|
state.guistate.filterViewIsOpened,
|
||||||
|
|
|
@ -1694,4 +1694,4 @@
|
||||||
"fr": "Toutes les infrastructures sur lesquelles quelqu'un peut rouler, accompagnées de questions sur cette infrastructure",
|
"fr": "Toutes les infrastructures sur lesquelles quelqu'un peut rouler, accompagnées de questions sur cette infrastructure",
|
||||||
"ca": "Totes les infraestructures per les quals algú pot ciclar, acompanyades de preguntes sobre aquesta infraestructura"
|
"ca": "Totes les infraestructures per les quals algú pot ciclar, acompanyades de preguntes sobre aquesta infraestructura"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import licenses from "../assets/generated/license_info.json"
|
||||||
import { LayoutConfigJson } from "../Models/ThemeConfig/Json/LayoutConfigJson"
|
import { LayoutConfigJson } from "../Models/ThemeConfig/Json/LayoutConfigJson"
|
||||||
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
|
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
|
||||||
import Constants from "../Models/Constants"
|
import Constants from "../Models/Constants"
|
||||||
import * as fakedom from "fake-dom"
|
|
||||||
import {
|
import {
|
||||||
DetectDuplicateFilters,
|
DetectDuplicateFilters,
|
||||||
DoesImageExist,
|
DoesImageExist,
|
||||||
|
@ -226,9 +225,6 @@ class LayerOverviewUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
main(args: string[]) {
|
main(args: string[]) {
|
||||||
if (fakedom === undefined) {
|
|
||||||
throw "Fakedom not initialized"
|
|
||||||
}
|
|
||||||
const forceReload = args.some((a) => a == "--force")
|
const forceReload = args.some((a) => a == "--force")
|
||||||
|
|
||||||
const licensePaths = new Set<string>()
|
const licensePaths = new Set<string>()
|
||||||
|
@ -339,7 +335,7 @@ class LayerOverviewUtils {
|
||||||
const context = "While building builtin layer " + sharedLayerPath
|
const context = "While building builtin layer " + sharedLayerPath
|
||||||
const fixed = prepLayer.convertStrict(parsed, context)
|
const fixed = prepLayer.convertStrict(parsed, context)
|
||||||
|
|
||||||
if (fixed.source.osmTags["and"] === undefined) {
|
if (typeof fixed.source !== "string" && fixed.source.osmTags["and"] === undefined) {
|
||||||
fixed.source.osmTags = { and: [fixed.source.osmTags] }
|
fixed.source.osmTags = { and: [fixed.source.osmTags] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue