From d7fe3a056ef74d85f3d4e310a6e053b244b659f8 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 8 Mar 2023 02:01:52 +0100 Subject: [PATCH] feat(themes): add questionHint to give extra information about a question --- Models/ThemeConfig/Conversion/Validation.ts | 27 ++++++++++++++++--- .../QuestionableTagRenderingConfigJson.ts | 8 +++++- Models/ThemeConfig/TagRenderingConfig.ts | 2 ++ UI/Popup/TagRenderingQuestion.ts | 5 ++++ scripts/generateLayerOverview.ts | 4 +++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Models/ThemeConfig/Conversion/Validation.ts b/Models/ThemeConfig/Conversion/Validation.ts index 6e366b64b..d836fe9a1 100644 --- a/Models/ThemeConfig/Conversion/Validation.ts +++ b/Models/ThemeConfig/Conversion/Validation.ts @@ -3,7 +3,7 @@ import { LayerConfigJson } from "../Json/LayerConfigJson" import LayerConfig from "../LayerConfig" import { Utils } from "../../../Utils" import Constants from "../../Constants" -import { Translation } from "../../../UI/i18n/Translation" +import { Translation, TypedTranslation } from "../../../UI/i18n/Translation" import { LayoutConfigJson } from "../Json/LayoutConfigJson" import LayoutConfig from "../LayoutConfig" import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson" @@ -14,6 +14,7 @@ import Translations from "../../../UI/i18n/Translations" import Svg from "../../../Svg" import FilterConfigJson from "../Json/FilterConfigJson" import DeleteConfig from "../DeleteConfig" +import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson" class ValidateLanguageCompleteness extends DesugaringStep { private readonly _languages: string[] @@ -586,11 +587,11 @@ export class DetectMappingsWithImages extends DesugaringStep { constructor() { - super("Miscellanious checks on the tagrendering", ["special"], "MiscTagREnderingChecksRew") + super("Miscellanious checks on the tagrendering", ["special"], "MiscTagRenderingChecks") } convert( - json: TagRenderingConfigJson, + json: TagRenderingConfigJson | QuestionableTagRenderingConfigJson, context: string ): { result: TagRenderingConfigJson @@ -598,6 +599,7 @@ class MiscTagRenderingChecks extends DesugaringStep { warnings?: string[] information?: string[] } { + const warnings = [] const errors = [] if (json["special"] !== undefined) { errors.push( @@ -606,9 +608,28 @@ class MiscTagRenderingChecks extends DesugaringStep { ': detected `special` on the top level. Did you mean `{"render":{ "special": ... }}`' ) } + if (json["question"]) { + const question = Translations.T( + new TypedTranslation(json["question"]), + context + ".question" + ) + const html = question.ConstructElement() + 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 contains a div, a span, a br or an element with class 'subtle'. Please, use a `questionHint` instead" + ) + } + } return { result: json, errors, + warnings, } } } diff --git a/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts b/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts index 89f97acf2..a317d0361 100644 --- a/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts +++ b/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts @@ -139,7 +139,13 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs * If it turns out that this tagRendering doesn't match _any_ value, then we show this question. * If undefined, the question is never asked and this tagrendering is read-only */ - question?: string | any + question?: string | Record + + /** + * A hint which is shown in subtle text under the question. + * This can give some extra information on what the answer should ook like + */ + questionHint?: string | Record /** * Allow freeform text input from the user diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index dbbe10675..79f81620a 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -47,6 +47,7 @@ export default class TagRenderingConfig { public readonly group: string public readonly render?: TypedTranslation public readonly question?: TypedTranslation + public readonly questionhint?: TypedTranslation public readonly condition?: TagsFilter public readonly description?: Translation @@ -119,6 +120,7 @@ export default class TagRenderingConfig { this.labels = json.labels ?? [] this.render = Translations.T(json.render, translationKey + ".render") this.question = Translations.T(json.question, translationKey + ".question") + this.question = Translations.T(json.questionHint, translationKey + ".questionHint") this.description = Translations.T(json.description, translationKey + ".description") this.condition = TagUtils.Tag(json.condition ?? { and: [] }, `${context}.condition`) if (json.freeform) { diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index e02a49739..de217104b 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -85,6 +85,10 @@ export default class TagRenderingQuestion extends Combine { ), 3 ) + let questionHint = undefined + if (configuration.questionhint !== undefined) { + questionHint = new SubstitutedTranslation(configuration.questionhint, tags, state) + } const feedback = new UIEventSource(undefined) const inputElement: ReadonlyInputElement = new VariableInputElement( @@ -139,6 +143,7 @@ export default class TagRenderingQuestion extends Combine { } super([ question, + questionHint, inputElement, new VariableUiElement( feedback.map( diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 7670167e0..678280932 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -4,6 +4,7 @@ import licenses from "../assets/generated/license_info.json" import { LayoutConfigJson } from "../Models/ThemeConfig/Json/LayoutConfigJson" import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson" import Constants from "../Models/Constants" +import * as fakedom from "fake-dom" import { DetectDuplicateFilters, DoesImageExist, @@ -241,6 +242,9 @@ class LayerOverviewUtils { } main(args: string[]) { + if (fakedom === undefined) { + throw "Fakedom not initialized" + } const forceReload = args.some((a) => a == "--force") const licensePaths = new Set()