Refactoring: add more types to special visualisations arguments

This commit is contained in:
Pieter Vander Vennet 2025-08-14 15:54:33 +02:00
parent 0601a9df6f
commit 6bb33771b4
18 changed files with 81 additions and 29 deletions

View file

@ -2,6 +2,7 @@ import { Store, Stores, UIEventSource } from "../../Logic/UIEventSource"
import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig" import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig"
import { Changes } from "../../Logic/Osm/Changes" import { Changes } from "../../Logic/Osm/Changes"
import { import {
SpecialVisualisationArg,
SpecialVisualization, SpecialVisualization,
SpecialVisualizationState, SpecialVisualizationState,
SpecialVisualizationSvelte, SpecialVisualizationSvelte,
@ -31,12 +32,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
public readonly funcName: string = "auto_apply" public readonly funcName: string = "auto_apply"
public readonly needsUrls = [] public readonly needsUrls = []
public readonly group = "data_import" public readonly group = "data_import"
public readonly args: { public readonly args: SpecialVisualisationArg[] = [
name: string
defaultValue?: string
doc: string
required?: boolean
}[] = [
{ {
name: "target_layer", name: "target_layer",
doc: "The layer that the target features will reside in", doc: "The layer that the target features will reside in",
@ -54,6 +50,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
}, },
{ {
name: "text", name: "text",
type:"translation",
doc: "The text to show on the button", doc: "The text to show on the button",
required: true, required: true,
}, },

View file

@ -302,6 +302,7 @@ class PointsInTimeVis extends SpecialVisualization {
args = [ args = [
{ {
name: "key", name: "key",
type:"key",
required: true, required: true,
doc: "The key out of which the points_in_time will be parsed", doc: "The key out of which the points_in_time will be parsed",
}, },

View file

@ -14,6 +14,7 @@ export class HistogramViz extends SpecialVisualization {
args = [ args = [
{ {
name: "key", name: "key",
type:"key",
doc: "The key to be read and to generate a histogram from", doc: "The key to be read and to generate a histogram from",
required: true, required: true,
}, },

View file

@ -1,4 +1,4 @@
import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization" import { SpecialVisualisationArg, SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
import { UIEventSource } from "../../../Logic/UIEventSource" import { UIEventSource } from "../../../Logic/UIEventSource"
import { Feature, Geometry, LineString, Polygon } from "geojson" import { Feature, Geometry, LineString, Polygon } from "geojson"
import BaseUIElement from "../../BaseUIElement" import BaseUIElement from "../../BaseUIElement"
@ -28,15 +28,11 @@ export default class ConflateImportButtonViz extends SpecialVisualization implem
group = "data_import" group = "data_import"
public readonly funcName: string = "conflate_button" public readonly funcName: string = "conflate_button"
public readonly args: { public readonly args: SpecialVisualisationArg[] = [
name: string
defaultValue?: string
doc: string
required?: boolean
}[] = [
...ImportFlowUtils.generalArguments, ...ImportFlowUtils.generalArguments,
{ {
name: "way_to_conflate", name: "way_to_conflate",
type:"key",
doc: "The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag", doc: "The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag",
}, },
] ]

View file

@ -10,37 +10,44 @@ export class LanguageElement extends SpecialVisualization {
funcName: string = "language_chooser" funcName: string = "language_chooser"
needsUrls = [] needsUrls = []
docs: string | BaseUIElement = docs: string =
"The language element allows to show and pick all known (modern) languages. The key can be set" "The language element allows to show and pick all known (modern) languages. The key can be set"
args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [ args: { name: string; defaultValue?: string; doc: string; required?: boolean; type?: string }[] = [
{ {
name: "key", name: "key",
required: true, required: true,
type:"key",
doc: "What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `<key>:nl=yes` if _nl_ is picked ", doc: "What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `<key>:nl=yes` if _nl_ is picked ",
}, },
{ {
name: "question", name: "question",
required: true, required: true,
type: "translation",
doc: "What to ask if no questions are known", doc: "What to ask if no questions are known",
}, },
{ {
name: "render_list_item", name: "render_list_item",
type: "translation",
doc: "How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain).", doc: "How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain).",
defaultValue: "{language()}", defaultValue: "{language()}",
}, },
{ {
name: "render_single_language", name: "render_single_language",
type: "translation",
doc: "What will be shown if the feature only supports a single language", doc: "What will be shown if the feature only supports a single language",
required: true, required: true,
}, },
{ {
type: "translation",
name: "render_all", name: "render_all",
doc: "The full rendering. Use `{list}` to show where the list of languages must come. Optional if mode=single", doc: "The full rendering. U0se `{list}` to show where the list of languages must come. Optional if mode=single",
defaultValue: "{list()}", defaultValue: "{list()}",
}, },
{ {
name: "no_known_languages", name: "no_known_languages",
type: "translation",
doc: "The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead", doc: "The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead",
}, },
] ]

View file

@ -19,7 +19,9 @@ export class MultiApplyViz extends SpecialVisualizationSvelte {
doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features.", doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features.",
required: true, required: true,
}, },
{ name: "text", doc: "The text to show on the button" }, { name: "text",
type: "translation",
doc: "The text to show on the button" },
{ {
name: "autoapply", name: "autoapply",
doc: "A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown", doc: "A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown",

View file

@ -31,6 +31,7 @@ export class PlantNetDetectionViz extends SpecialVisualizationSvelte {
args = [ args = [
{ {
name: "image_key", name: "image_key",
type:"key",
defaultValue: AllImageProviders.defaultKeys.join(","), defaultValue: AllImageProviders.defaultKeys.join(","),
doc: "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated ", doc: "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated ",
}, },

View file

@ -17,6 +17,7 @@ export class ShareLinkViz extends SpecialVisualizationSvelte {
}, },
{ {
name: "text", name: "text",
type:"translation",
doc: "The text to show on the button. If none is given, will act as a titleIcon", doc: "The text to show on the button. If none is given, will act as a titleIcon",
}, },
] ]

View file

@ -47,6 +47,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
args = [ args = [
{ {
name: "message", name: "message",
type: "translation",
doc: "A message to show to the user", doc: "A message to show to the user",
}, },
{ {
@ -56,6 +57,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
}, },
{ {
name: "message_confirm", name: "message_confirm",
type: "translation",
doc: "What to show when the task is closed, either by the user or was already closed.", doc: "What to show when the task is closed, either by the user or was already closed.",
}, },
{ {
@ -65,11 +67,13 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
}, },
{ {
name: "maproulette_id", name: "maproulette_id",
type:"key",
doc: "The property name containing the maproulette id", doc: "The property name containing the maproulette id",
defaultValue: "mr_taskId", defaultValue: "mr_taskId",
}, },
{ {
name: "ask_feedback", name: "ask_feedback",
type: "translation",
doc: "If not an empty string, this will be used as question to ask some additional feedback. A text field will be added", doc: "If not an empty string, this will be used as question to ask some additional feedback. A text field will be added",
defaultValue: "", defaultValue: "",
}, },
@ -106,6 +110,7 @@ class LinkedDataFromWebsite extends SpecialVisualization {
{ {
name: "key", name: "key",
defaultValue: "website", defaultValue: "website",
type:"key",
doc: "Attempt to load ld+json from the specified URL. This can be in an embedded <script type='ld+json'>", doc: "Attempt to load ld+json from the specified URL. This can be in an embedded <script type='ld+json'>",
}, },
{ {
@ -248,6 +253,7 @@ class CompareData extends SpecialVisualization {
{ {
name: "url", name: "url",
required: true, required: true,
type:"key",
doc: "The attribute containing the url where to fetch more data", doc: "The attribute containing the url where to fetch more data",
}, },
{ {

View file

@ -95,8 +95,8 @@ class ImageUpload extends SpecialVisualizationSvelte {
needsUrls = [Constants.panoramax, Constants.osmAuthConfig] needsUrls = [Constants.panoramax, Constants.osmAuthConfig]
args = [ args = [
{ {
type: "key",
name: "image_key", name: "image_key",
type: "key",
doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)", doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)",
defaultValue: "panoramax", defaultValue: "panoramax",
required: false, required: false,
@ -105,6 +105,7 @@ class ImageUpload extends SpecialVisualizationSvelte {
name: "label", name: "label",
doc: "The text to show on the button", doc: "The text to show on the button",
required: false, required: false,
type: "translation"
}, },
{ {
name: "disable_blur", name: "disable_blur",

View file

@ -28,6 +28,7 @@ class CloseNoteViz extends SpecialVisualizationSvelte {
{ {
name: "text", name: "text",
doc: "Text to show on this button", doc: "Text to show on this button",
type: "translation",
required: true, required: true,
}, },
{ {
@ -39,6 +40,7 @@ class CloseNoteViz extends SpecialVisualizationSvelte {
name: "idkey", name: "idkey",
doc: "The property name where the ID of the note to close can be found", doc: "The property name where the ID of the note to close can be found",
defaultValue: "id", defaultValue: "id",
type:"key"
}, },
{ {
name: "comment", name: "comment",
@ -87,6 +89,7 @@ class AddNoteCommentViz extends SpecialVisualizationSvelte {
name: "Id-key", name: "Id-key",
doc: "The property name where the ID of the note to close can be found", doc: "The property name where the ID of the note to close can be found",
defaultValue: "id", defaultValue: "id",
type:"key"
}, },
] ]
public readonly group = "notes" public readonly group = "notes"
@ -129,6 +132,7 @@ class AddImageToNote extends SpecialVisualizationSvelte {
name: "Id-key", name: "Id-key",
doc: "The property name where the ID of the note to close can be found", doc: "The property name where the ID of the note to close can be found",
defaultValue: "id", defaultValue: "id",
type:"key"
}, },
] ]
group = "notes" group = "notes"
@ -150,6 +154,7 @@ class VisualiseNoteComment extends SpecialVisualization {
name: "commentsKey", name: "commentsKey",
doc: "The property name of the comments, which should be stringified json", doc: "The property name of the comments, which should be stringified json",
defaultValue: "comments", defaultValue: "comments",
type:"key"
}, },
{ {
name: "start", name: "start",

View file

@ -43,6 +43,7 @@ class CreateReview extends SpecialVisualizationSvelte {
{ {
name: "subjectKey", name: "subjectKey",
defaultValue: "name", defaultValue: "name",
type:"key",
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>", doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>",
}, },
{ {
@ -51,6 +52,8 @@ class CreateReview extends SpecialVisualizationSvelte {
}, },
{ {
name: "question", name: "question",
type: "translation",
doc: "The question to ask during the review", doc: "The question to ask during the review",
}, },
] ]
@ -91,6 +94,7 @@ class ListReview extends SpecialVisualizationSvelte {
{ {
name: "subjectKey", name: "subjectKey",
defaultValue: "name", defaultValue: "name",
type: "key",
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>", doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>",
}, },
{ {
@ -125,6 +129,7 @@ class Rating extends SpecialVisualizationSvelte {
{ {
name: "subjectKey", name: "subjectKey",
defaultValue: "name", defaultValue: "name",
type:"key",
doc: "The key to use to determine the subject. If the value is specified, the subject will be <b>tags[subjectKey]</b> and will use this to filter the reviews.", doc: "The key to use to determine the subject. If the value is specified, the subject will be <b>tags[subjectKey]</b> and will use this to filter the reviews.",
}, },
{ {
@ -161,6 +166,7 @@ class ImportMangroveKey extends SpecialVisualizationSvelte {
args = [ args = [
{ {
name: "text", name: "text",
type: "translation",
doc: "The text that is shown on the button", doc: "The text that is shown on the button",
}, },
] ]
@ -186,6 +192,7 @@ class Reviews extends SpecialVisualization {
{ {
name: "subjectKey", name: "subjectKey",
defaultValue: "name", defaultValue: "name",
type:"key",
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>", doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>",
}, },
{ {
@ -194,6 +201,7 @@ class Reviews extends SpecialVisualization {
}, },
{ {
name: "question", name: "question",
type: "translation",
doc: "The question to ask in the review form. Optional", doc: "The question to ask in the review form. Optional",
}, },
] ]

View file

@ -111,6 +111,7 @@ export class ClearCachesVis extends SpecialVisualizationSvelte {
{ {
name: "text", name: "text",
required: true, required: true,
type: "translation",
doc: "The text to show on the button", doc: "The text to show on the button",
}, },
] ]
@ -136,6 +137,7 @@ class LoginButtonVis extends SpecialVisualizationSvelte {
}, },
{ {
name: "message", name: "message",
type: "translation",
doc: "Message to display on the button", doc: "Message to display on the button",
}, },
] ]
@ -160,6 +162,7 @@ class QrLogin extends SpecialVisualizationSvelte {
funcName = "qr_login" funcName = "qr_login"
args = [ args = [
{ {
type: "translation",
name: "text", name: "text",
doc: "Extra text on the side of the QR-code", doc: "Extra text on the side of the QR-code",
}, },

View file

@ -26,6 +26,7 @@ export default class TagApplyViz extends SpecialVisualization implements AutoAct
}, },
{ {
name: "message", name: "message",
type:"translation",
doc: "The text to show to the contributor", doc: "The text to show to the contributor",
}, },
{ {

View file

@ -27,6 +27,7 @@ class StealViz extends SpecialVisualization {
args = [ args = [
{ {
name: "featureId", name: "featureId",
type:"key",
doc: "The key of the attribute which contains the id of the feature from which to use the tags", doc: "The key of the attribute which contains the id of the feature from which to use the tags",
required: true, required: true,
}, },
@ -117,6 +118,7 @@ class Multi extends SpecialVisualization {
args = [ args = [
{ {
name: "key", name: "key",
type:"key",
doc: "The property to read and to interpret as a list of properties", doc: "The property to read and to interpret as a list of properties",
required: true, required: true,
}, },

View file

@ -99,6 +99,7 @@ class Minimap extends SpecialVisualizationSvelte {
doc: "The key of one or more properties of the feature, semi-colon separated. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. ", doc: "The key of one or more properties of the feature, semi-colon separated. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. ",
name: "idKey", name: "idKey",
defaultValue: "id", defaultValue: "id",
type:"key"
}, },
{ {
name: "class", name: "class",
@ -203,7 +204,7 @@ class QrCodeVis extends SpecialVisualizationSvelte {
funcName = "qr_code" funcName = "qr_code"
args = [ args = [
{ {
name: "text", name: "text",type:"translation",
doc: "Extra text on the side of the QR-code", doc: "Extra text on the side of the QR-code",
}, },
{ {
@ -238,6 +239,7 @@ class IfNothingKnown extends SpecialVisualizationSvelte {
{ {
name: "text", name: "text",
doc: "Text to show", doc: "Text to show",
type:"translation",
required: true, required: true,
}, },
{ name: "cssClasses", doc: "Classes to apply onto the text" }, { name: "cssClasses", doc: "Classes to apply onto the text" },
@ -346,6 +348,7 @@ class BracedVis extends SpecialVisualization {
name: "text", name: "text",
required: true, required: true,
doc: "The value to show", doc: "The value to show",
type:"translation"
}, },
] ]
@ -373,7 +376,6 @@ class CreateCopyVis extends SpecialVisualizationSvelte {
layer: LayerConfig layer: LayerConfig
): SvelteUIElement { ): SvelteUIElement {
try { try {
console.log(">>> create_copy invoked")
return new SvelteUIElement(CreateCopy, { state, tags, argument, feature, layer }) return new SvelteUIElement(CreateCopy, { state, tags, argument, feature, layer })
} catch (e) { } catch (e) {
console.error(">>> failed", e) console.error(">>> failed", e)

View file

@ -25,6 +25,7 @@ class FediverseLinkVis extends SpecialVisualization {
args = [ args = [
{ {
name: "key", name: "key",
type:"key",
doc: "The attribute-name containing the link", doc: "The attribute-name containing the link",
required: true, required: true,
}, },
@ -47,6 +48,7 @@ class WikipediaVis extends SpecialVisualization {
args = [ args = [
{ {
name: "keyToShowWikipediaFor", name: "keyToShowWikipediaFor",
type:"key",
doc: "Use the wikidata entry from this key to show the wikipedia article for. Multiple keys can be given (separated by ';'), in which case the first matching value is used", doc: "Use the wikidata entry from this key to show the wikipedia article for. Multiple keys can be given (separated by ';'), in which case the first matching value is used",
defaultValue: "wikidata;wikipedia", defaultValue: "wikidata;wikipedia",
}, },
@ -76,6 +78,7 @@ class WikidatalabelVis extends SpecialVisualization {
args = [ args = [
{ {
name: "keyToShowWikidataFor", name: "keyToShowWikidataFor",
type:"key",
doc: "Use the wikidata entry from this key to show the label", doc: "Use the wikidata entry from this key to show the label",
defaultValue: "wikidata", defaultValue: "wikidata",
}, },
@ -117,21 +120,25 @@ class SendEmailVis extends SpecialVisualizationSvelte {
{ {
name: "to", name: "to",
doc: "Who to send the email to?", doc: "Who to send the email to?",
type:"key",
required: true, required: true,
}, },
{ {
name: "subject", name: "subject",
type: "translation",
doc: "The subject of the email", doc: "The subject of the email",
required: true, required: true,
}, },
{ {
name: "body", name: "body",
type: "translation",
doc: "The text in the email", doc: "The text in the email",
required: true, required: true,
}, },
{ {
name: "button_text", name: "button_text",
type: "translation",
doc: "The text shown on the button in the UI", doc: "The text shown on the button in the UI",
required: true, required: true,
}, },
@ -151,11 +158,12 @@ class LinkVis extends SpecialVisualizationSvelte {
{ {
name: "text", name: "text",
doc: "Text to be shown", doc: "Text to be shown",
type: "translation",
required: true, required: true,
}, },
{ {
name: "href", name: "href",
doc: "The URL to link to. Note that this will be URI-encoded before ", doc: "The URL to link to. Note that this will be URI-encoded before and (as everything) supports substitutions of attributes",
required: true, required: true,
}, },
{ {

View file

@ -28,6 +28,7 @@ import FeaturePropertiesStore from "../Logic/FeatureSource/Actors/FeaturePropert
import SvelteUIElement from "./Base/SvelteUIElement" import SvelteUIElement from "./Base/SvelteUIElement"
import { Utils } from "../Utils" import { Utils } from "../Utils"
import { ServerSourceInfo } from "../Models/SourceOverview" import { ServerSourceInfo } from "../Models/SourceOverview"
import { Translation } from "./i18n/Translation"
/** /**
* The state needed to render a special Visualisation. * The state needed to render a special Visualisation.
@ -87,9 +88,24 @@ export interface SpecialVisualizationState {
reportError(message: string | Error | XMLHttpRequest, extramessage?: string): Promise<void> reportError(message: string | Error | XMLHttpRequest, extramessage?: string): Promise<void>
} }
export interface SpecialVisualisationArg {
name: string
defaultValue?: string
doc: string
required?: false | boolean
type?: "key" | "translation" | string
}
export class SpecialVisualizationUtils {
}
export abstract class SpecialVisualization { export abstract class SpecialVisualization {
readonly funcName: string readonly funcName: string
readonly docs: string | BaseUIElement readonly docs: string
/** /**
* The 'group' is merely what association it has in the docs * The 'group' is merely what association it has in the docs
*/ */
@ -107,13 +123,7 @@ export abstract class SpecialVisualization {
/** /**
* Indicates that this special visualisation will make requests to the 'alLNodesDatabase' and that it thus should be included * Indicates that this special visualisation will make requests to the 'alLNodesDatabase' and that it thus should be included
*/ */
readonly args: { readonly args: SpecialVisualisationArg[]
name: string
defaultValue?: string
doc: string
required?: false | boolean
type?: "key" | string
}[]
readonly getLayerDependencies?: (argument: string[]) => string[] readonly getLayerDependencies?: (argument: string[]) => string[]
structuredExamples?(): { feature: Feature<Geometry, Record<string, string>>; args: string[] }[] structuredExamples?(): { feature: Feature<Geometry, Record<string, string>>; args: string[] }[]