diff --git a/Docs/Schemas/LayerConfigJson.schema.json b/Docs/Schemas/LayerConfigJson.schema.json index c850dd1d4..c5cb22f01 100644 --- a/Docs/Schemas/LayerConfigJson.schema.json +++ b/Docs/Schemas/LayerConfigJson.schema.json @@ -215,14 +215,14 @@ ] }, "tags": { - "description": "The tags to add. It determines the icon too.\nUse key=value\n\nquestion: What tag should be added to the new object?\ntype: simpletag", + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n\nquestion: What tag should be added to the new object?\ntype: simple_tag", "type": "array", "items": { "type": "string" } }, "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)", + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "anyOf": [ { "$ref": "#/definitions/Record" @@ -233,7 +233,7 @@ ] }, "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n\nType: image\nquestion: What is the URL of an image showing such a feature?", "type": "array", "items": { "type": "string" diff --git a/Docs/Schemas/LayerConfigJsonJSC.ts b/Docs/Schemas/LayerConfigJsonJSC.ts index cb6a9c9cf..8861e5ecc 100644 --- a/Docs/Schemas/LayerConfigJsonJSC.ts +++ b/Docs/Schemas/LayerConfigJsonJSC.ts @@ -215,14 +215,14 @@ export default { ] }, "tags": { - "description": "The tags to add. It determines the icon too.\nUse key=value\n\nquestion: What tag should be added to the new object?\ntype: simpletag", + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n\nquestion: What tag should be added to the new object?\ntype: simple_tag", "type": "array", "items": { "type": "string" } }, "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)", + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "anyOf": [ { "$ref": "#/definitions/Record" @@ -233,7 +233,7 @@ export default { ] }, "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n\nType: image\nquestion: What is the URL of an image showing such a feature?", "type": "array", "items": { "type": "string" diff --git a/Docs/Schemas/LayoutConfigJson.schema.json b/Docs/Schemas/LayoutConfigJson.schema.json index a9d8d3805..7c898977c 100644 --- a/Docs/Schemas/LayoutConfigJson.schema.json +++ b/Docs/Schemas/LayoutConfigJson.schema.json @@ -1926,14 +1926,14 @@ ] }, "tags": { - "description": "The tags to add. It determines the icon too.\nUse key=value\n\nquestion: What tag should be added to the new object?\ntype: simpletag", + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n\nquestion: What tag should be added to the new object?\ntype: simple_tag", "type": "array", "items": { "type": "string" } }, "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)", + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "anyOf": [ { "$ref": "#/definitions/Record" @@ -1944,7 +1944,7 @@ ] }, "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n\nType: image\nquestion: What is the URL of an image showing such a feature?", "type": "array", "items": { "type": "string" @@ -2372,14 +2372,14 @@ ] }, "tags": { - "description": "The tags to add. It determines the icon too.\nUse key=value\n\nquestion: What tag should be added to the new object?\ntype: simpletag", + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n\nquestion: What tag should be added to the new object?\ntype: simple_tag", "type": "array", "items": { "type": "string" } }, "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)", + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "anyOf": [ { "$ref": "#/definitions/Record" @@ -2390,7 +2390,7 @@ ] }, "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n\nType: image\nquestion: What is the URL of an image showing such a feature?", "type": "array", "items": { "type": "string" diff --git a/Docs/Schemas/LayoutConfigJsonJSC.ts b/Docs/Schemas/LayoutConfigJsonJSC.ts index 649d46f6a..397efe931 100644 --- a/Docs/Schemas/LayoutConfigJsonJSC.ts +++ b/Docs/Schemas/LayoutConfigJsonJSC.ts @@ -1905,14 +1905,14 @@ export default { ] }, "tags": { - "description": "The tags to add. It determines the icon too.\nUse key=value\n\nquestion: What tag should be added to the new object?\ntype: simpletag", + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n\nquestion: What tag should be added to the new object?\ntype: simple_tag", "type": "array", "items": { "type": "string" } }, "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)", + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "anyOf": [ { "$ref": "#/definitions/Record" @@ -1923,7 +1923,7 @@ export default { ] }, "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n\nType: image\nquestion: What is the URL of an image showing such a feature?", "type": "array", "items": { "type": "string" @@ -2350,14 +2350,14 @@ export default { ] }, "tags": { - "description": "The tags to add. It determines the icon too.\nUse key=value\n\nquestion: What tag should be added to the new object?\ntype: simpletag", + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n\nquestion: What tag should be added to the new object?\ntype: simple_tag", "type": "array", "items": { "type": "string" } }, "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)", + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "anyOf": [ { "$ref": "#/definitions/Record" @@ -2368,7 +2368,7 @@ export default { ] }, "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n\nType: image\nquestion: What is the URL of an image showing such a feature?", "type": "array", "items": { "type": "string" diff --git a/Models/ThemeConfig/Json/LayerConfigJson.ts b/Models/ThemeConfig/Json/LayerConfigJson.ts index 006895d76..d5a47b105 100644 --- a/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -254,25 +254,30 @@ export interface LayerConfigJson { */ title: string | Record /** - * The tags to add. It determines the icon too. - * Use key=value + * A single tag (encoded as key=value) out of all the tags to add onto the newly created point. + * Note that the icon in the UI will be chosen automatically based on the tags provided here. * * question: What tag should be added to the new object? - * type: simpletag + * type: simple_tag */ tags: string[] /** + * An extra explanation of what the feature is, if it is not immediately clear from the title alone. + * * The _first sentence_ of the description is shown on the button of the `add` menu. * The full description is shown in the confirmation dialog. * * (The first sentence is until the first '.'-character in the description) + * + * question: How would you describe this feature? */ description?: string | Record /** - * Example images, which show real-life pictures of what such a feature might look like + * The URL of an example image which shows a real-life example of what such a feature might look like. * * Type: image + * question: What is the URL of an image showing such a feature? */ exampleImages?: string[] diff --git a/UI/InputElement/ValidatedInput.svelte b/UI/InputElement/ValidatedInput.svelte index d86b0d082..3661eed8f 100644 --- a/UI/InputElement/ValidatedInput.svelte +++ b/UI/InputElement/ValidatedInput.svelte @@ -8,6 +8,7 @@ import {Validator} from "./Validator" import {Unit} from "../../Models/Unit" import UnitInput from "../Popup/UnitInput.svelte" + import {Utils} from "../../Utils"; export let type: ValidatorType export let feedback: UIEventSource | undefined = undefined @@ -25,6 +26,9 @@ let _value = new UIEventSource(value.data ?? "") let validator: Validator = Validators.get(type ?? "string") + if(validator === undefined){ + console.warn("Didn't find a validator for type", type) + } let selectedUnit: UIEventSource = new UIEventSource(undefined) let _placeholder = placeholder ?? validator?.getPlaceholder() ?? type @@ -47,6 +51,7 @@ $: { // The type changed -> reset some values validator = Validators.get(type ?? "string") + _placeholder = placeholder ?? validator?.getPlaceholder() ?? type feedback = feedback?.setData(validator?.getFeedback(_value.data, getCountry)) @@ -56,9 +61,9 @@ function setValues() { // Update the value stores const v = _value.data - if (!validator.isValid(v, getCountry) || v === "") { + if (!validator?.isValid(v, getCountry) || v === "") { value.setData(undefined) - feedback?.setData(validator.getFeedback(v, getCountry)) + feedback?.setData(validator?.getFeedback(v, getCountry)) return } @@ -74,10 +79,10 @@ onDestroy(_value.addCallbackAndRun((_) => setValues())) onDestroy(selectedUnit.addCallback((_) => setValues())) if (validator === undefined) { - throw "Not a valid type for a validator:" + type + throw "Not a valid type (no validator found) for type '" + type+"'; did you perhaps mean one of: "+Utils.sortedByLevenshteinDistance(type, Validators.AllValidators.map(v => v.name), v => v).slice(0, 5).join(", ") } - const isValid = _value.map((v) => validator.isValid(v, getCountry)) + const isValid = _value.map((v) => validator?.isValid(v, getCountry) ?? true) let htmlElem: HTMLInputElement @@ -89,13 +94,13 @@ } -{#if validator.textArea} +{#if validator?.textArea}
dispatch("submit")}>
{:else} @@ -104,7 +109,7 @@ bind:this={htmlElem} bind:value={$_value} class="w-full" - inputmode={validator.inputmode ?? "text"} + inputmode={validator?.inputmode ?? "text"} placeholder={_placeholder} /> {#if !$isValid} diff --git a/UI/InputElement/Validator.ts b/UI/InputElement/Validator.ts index 5172b2433..2bde3b832 100644 --- a/UI/InputElement/Validator.ts +++ b/UI/InputElement/Validator.ts @@ -61,7 +61,7 @@ export abstract class Validator { return Translations.t.validation[this.name].description } - public isValid(_: string, __?: () => string): boolean { + public isValid(key: string, getCountry?: () => string): boolean { return true } diff --git a/UI/InputElement/Validators.ts b/UI/InputElement/Validators.ts index c340fc355..16ce856f9 100644 --- a/UI/InputElement/Validators.ts +++ b/UI/InputElement/Validators.ts @@ -18,6 +18,8 @@ import ColorValidator from "./Validators/ColorValidator" import BaseUIElement from "../BaseUIElement" import Combine from "../Base/Combine" import Title from "../Base/Title" +import SimpleTagValidator from "./Validators/SimpleTagValidator" +import ImageUrlValidator from "./Validators/ImageUrlValidator" export type ValidatorType = (typeof Validators.availableTypes)[number] @@ -58,6 +60,8 @@ export default class Validators { new PhoneValidator(), new OpeningHoursValidator(), new ColorValidator(), + new SimpleTagValidator(), + new ImageUrlValidator(), ] private static _byType = Validators._byTypeConstructor() diff --git a/UI/InputElement/Validators/ImageUrlValidator.ts b/UI/InputElement/Validators/ImageUrlValidator.ts new file mode 100644 index 000000000..2c18e1d41 --- /dev/null +++ b/UI/InputElement/Validators/ImageUrlValidator.ts @@ -0,0 +1,39 @@ +import UrlValidator from "./UrlValidator" +import { Translation } from "../../i18n/Translation" + +export default class ImageUrlValidator extends UrlValidator { + private static readonly allowedExtensions = ["jpg", "jpeg", "svg", "png"] + + constructor() { + super( + "image", + "Same as the URL-parameter, except that it checks that the URL ends with `.jpg`, `.png` or some other typical image format" + ) + } + + private static hasValidExternsion(str: string): boolean { + str = str.toLowerCase() + return ImageUrlValidator.allowedExtensions.some((ext) => str.endsWith(ext)) + } + + getFeedback(s: string, _?: () => string): Translation | undefined { + const superF = super.getFeedback(s, _) + if (superF) { + return superF + } + if (!ImageUrlValidator.hasValidExternsion(s)) { + return new Translation( + "This URL does not end with one of the allowed extensions. These are: " + + ImageUrlValidator.allowedExtensions.join(", ") + ) + } + return undefined + } + + isValid(str: string): boolean { + if (!super.isValid(str)) { + return false + } + return ImageUrlValidator.hasValidExternsion(str) + } +} diff --git a/UI/InputElement/Validators/SimpleTagValidator.ts b/UI/InputElement/Validators/SimpleTagValidator.ts new file mode 100644 index 000000000..629fd8756 --- /dev/null +++ b/UI/InputElement/Validators/SimpleTagValidator.ts @@ -0,0 +1,57 @@ +import { Validator } from "../Validator" +import { Translation } from "../../i18n/Translation" +import Translations from "../../i18n/Translations" + +/** + * Checks that the input conforms `key=value`, where `key` and `value` don't have too much weird characters + */ +export default class SimpleTagValidator extends Validator { + constructor() { + super( + "simple_tag", + "A simple tag of the format `key=value` where `key` conforms to a normal key `" + ) + } + + getFeedback(tag: string): Translation | undefined { + const parts = tag.split("=") + if (parts.length < 2) { + return Translations.T("A tag should contain a = to separate the 'key' and 'value'") + } + if (parts.length > 2) { + return Translations.T( + "A tag should contain precisely one `=` to separate the 'key' and 'value', but " + + (parts.length - 1) + + " equal signs were found" + ) + } + + const [key, value] = parts + if (key.length > 255) { + return Translations.T("A `key` should be at most 255 characters") + } + if (value.length > 255) { + return Translations.T("A `value should be at most 255 characters") + } + + if (key.length == 0) { + return Translations.T("A `key` should not be empty") + } + if (value.length == 0) { + return Translations.T("A `value should not be empty") + } + + const keyRegex = /[a-zA-Z0-9:_]+/ + if (!key.match(keyRegex)) { + return Translations.T( + "A `key` should only have the characters `a-zA-Z0-9`, `:` or `_`" + ) + } + + return undefined + } + + isValid(tag: string): boolean { + return this.getFeedback(tag) === undefined + } +} diff --git a/UI/InputElement/Validators/UrlValidator.ts b/UI/InputElement/Validators/UrlValidator.ts index 85c8fefe6..bd28cf02f 100644 --- a/UI/InputElement/Validators/UrlValidator.ts +++ b/UI/InputElement/Validators/UrlValidator.ts @@ -1,10 +1,10 @@ import { Validator } from "../Validator" export default class UrlValidator extends Validator { - constructor() { + constructor(name?: string, explanation?: string) { super( - "url", - "The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed", + name ??"url", + explanation?? "The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed", "url" ) } diff --git a/UI/Studio/EditLayerState.ts b/UI/Studio/EditLayerState.ts index f91c14b78..b0d5c1efb 100644 --- a/UI/Studio/EditLayerState.ts +++ b/UI/Studio/EditLayerState.ts @@ -1,13 +1,44 @@ import { OsmConnection } from "../../Logic/Osm/OsmConnection" import { ConfigMeta } from "./configMeta" +import { Store, UIEventSource } from "../../Logic/UIEventSource" +import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson" export default class EditLayerState { public readonly osmConnection: OsmConnection public readonly schema: ConfigMeta[] + public readonly featureSwitches: { featureSwitchIsDebugging: UIEventSource } + + public readonly configuration: UIEventSource> = new UIEventSource< + Partial + >({}) + constructor(schema: ConfigMeta[]) { this.schema = schema this.osmConnection = new OsmConnection({}) + this.featureSwitches = { + featureSwitchIsDebugging: new UIEventSource(true), + } + this.configuration.addCallback((config) => console.log("Current config is", config)) + } + + public register(path: ReadonlyArray, value: Store) { + value.addCallbackAndRun((v) => { + let entry = this.configuration.data + for (let i = 0; i < path.length - 1; i++) { + const breadcrumb = path[i] + if (entry[breadcrumb] === undefined) { + entry[breadcrumb] = typeof path[i + 1] === "number" ? [] : {} + } + entry = entry[breadcrumb] + } + if (v) { + entry[path.at(-1)] = v + } else if (entry) { + delete entry[path.at(-1)] + } + this.configuration.ping() + }) } public getSchemaStartingWith(path: string[]) { diff --git a/UI/Studio/SchemaBasedArray.svelte b/UI/Studio/SchemaBasedArray.svelte index 8e02e6df8..cb7dd3203 100644 --- a/UI/Studio/SchemaBasedArray.svelte +++ b/UI/Studio/SchemaBasedArray.svelte @@ -3,47 +3,79 @@ import type {ConfigMeta} from "./configMeta"; import {UIEventSource} from "../../Logic/UIEventSource"; import SchemaBasedInput from "./SchemaBasedInput.svelte"; + import SchemaBasedField from "./SchemaBasedField.svelte"; export let state: EditLayerState export let schema: ConfigMeta + + let title = schema.path.at(-1) + let singular = title + if (title.endsWith("s")) { + singular = title.slice(0, title.length - 1) + } + let article = "a" + if (singular.match(/^[aeoui]/)) { + article = "an" + } export let path: (string | number)[] = [] const subparts = state.getSchemaStartingWith(schema.path) - console.log("Got array:", {schema, subparts}) + + console.log("Subparts for", schema.path, " are", subparts) let createdItems = 0 /** * Keeps track of the items. * We keep a single string (stringified 'createdItems') to make sure the order is corrects */ - export let values: UIEventSource = new UIEventSource([]) + export let values: UIEventSource = new UIEventSource([]) function createItem() { - values.data.push("" + createdItems) + values.data.push(createdItems) createdItems++ values.ping() } + function fusePath(i: number, subpartPath: string[]): (string | number)[] { + const newPath = [...path, i] + const toAdd = [...subpartPath] + for (const part of path) { + if (toAdd[0] === part) { + toAdd.splice(0, 1) + } + } + newPath.push(...toAdd) + return newPath + } +

{schema.path.at(-1)}

- - {schema.description} - + {#if subparts.length > 0} + + {schema.description} + + {/if} {#if $values.length === 0} No values are defined + {:else if subparts.length === 0} + + {#each $values as value (value)} + + {/each} {:else} {#each $values as value (value)} +

{singular} {value}

{#each subparts as subpart} - + {/each}
{/each} {/if} - +
diff --git a/UI/Studio/SchemaBasedField.svelte b/UI/Studio/SchemaBasedField.svelte index 96452a2e3..b6dcc1a00 100644 --- a/UI/Studio/SchemaBasedField.svelte +++ b/UI/Studio/SchemaBasedField.svelte @@ -16,9 +16,9 @@ export let schema: ConfigMeta let value = new UIEventSource(undefined) let feedback = new UIEventSource(undefined) - + const configJson: QuestionableTagRenderingConfigJson = { - id: schema.path.join("_"), + id: path.join("_"), render: schema.hints.inline ?? schema.path.at(-1) + ": {value}", question: schema.hints.question, questionHint: schema.description, @@ -44,6 +44,7 @@ err = e } let tags = new UIEventSource>({}) + state.register(path, tags.map(tgs => tgs["value"])) {#if err !== undefined} diff --git a/UI/Studio/SchemaBasedInput.svelte b/UI/Studio/SchemaBasedInput.svelte index 82522afc9..22984b8f7 100644 --- a/UI/Studio/SchemaBasedInput.svelte +++ b/UI/Studio/SchemaBasedInput.svelte @@ -10,7 +10,6 @@ -{path.join(".")} {#if schema.type === "array"} {:else} diff --git a/assets/layerconfigmeta.json b/assets/layerconfigmeta.json index 6cf30b602..fc93574e9 100644 --- a/assets/layerconfigmeta.json +++ b/assets/layerconfigmeta.json @@ -34211,11 +34211,11 @@ ], "required": true, "hints": { - "typehint": "simpletag", + "typehint": "simple_tag", "question": "What tag should be added to the new object?" }, "type": "array", - "description": "The tags to add. It determines the icon too.\nUse key=value\n" + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n" }, { "path": [ @@ -34223,7 +34223,9 @@ "description" ], "required": false, - "hints": {}, + "hints": { + "question": "How would you describe this feature?" + }, "type": [ { "$ref": "#/definitions/Record" @@ -34232,7 +34234,7 @@ "type": "string" } ], - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n" }, { "path": [ @@ -34241,10 +34243,11 @@ ], "required": false, "hints": { - "typehint": "image" + "typehint": "image", + "question": "What is the URL of an image showing such a feature?" }, "type": "array", - "description": "Example images, which show real-life pictures of what such a feature might look like\n" + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n" }, { "path": [ diff --git a/assets/layoutconfigmeta.json b/assets/layoutconfigmeta.json index 9a9d14103..809d9227e 100644 --- a/assets/layoutconfigmeta.json +++ b/assets/layoutconfigmeta.json @@ -36255,11 +36255,11 @@ ], "required": true, "hints": { - "typehint": "simpletag", + "typehint": "simple_tag", "question": "What tag should be added to the new object?" }, "type": "array", - "description": "The tags to add. It determines the icon too.\nUse key=value\n" + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n" }, { "path": [ @@ -36268,7 +36268,9 @@ "description" ], "required": false, - "hints": {}, + "hints": { + "question": "How would you describe this feature?" + }, "type": [ { "$ref": "#/definitions/Record" @@ -36277,7 +36279,7 @@ "type": "string" } ], - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n" }, { "path": [ @@ -36287,10 +36289,11 @@ ], "required": false, "hints": { - "typehint": "image" + "typehint": "image", + "question": "What is the URL of an image showing such a feature?" }, "type": "array", - "description": "Example images, which show real-life pictures of what such a feature might look like\n" + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n" }, { "path": [ @@ -80113,11 +80116,11 @@ ], "required": true, "hints": { - "typehint": "simpletag", + "typehint": "simple_tag", "question": "What tag should be added to the new object?" }, "type": "array", - "description": "The tags to add. It determines the icon too.\nUse key=value\n" + "description": "A single tag (encoded as key=value) out of all the tags to add onto the newly created point.\nNote that the icon in the UI will be chosen automatically based on the tags provided here.\n" }, { "path": [ @@ -80127,7 +80130,9 @@ "description" ], "required": false, - "hints": {}, + "hints": { + "question": "How would you describe this feature?" + }, "type": [ { "$ref": "#/definitions/Record" @@ -80136,7 +80141,7 @@ "type": "string" } ], - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" + "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n" }, { "path": [ @@ -80147,10 +80152,11 @@ ], "required": false, "hints": { - "typehint": "image" + "typehint": "image", + "question": "What is the URL of an image showing such a feature?" }, "type": "array", - "description": "Example images, which show real-life pictures of what such a feature might look like\n" + "description": "The URL of an example image which shows a real-life example of what such a feature might look like.\n" }, { "path": [