forked from MapComplete/MapComplete
feat(themes): add questionHint to give extra information about a question
This commit is contained in:
parent
60f3499eb0
commit
d7fe3a056e
5 changed files with 42 additions and 4 deletions
|
@ -3,7 +3,7 @@ import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||||
import LayerConfig from "../LayerConfig"
|
import LayerConfig from "../LayerConfig"
|
||||||
import { Utils } from "../../../Utils"
|
import { Utils } from "../../../Utils"
|
||||||
import Constants from "../../Constants"
|
import Constants from "../../Constants"
|
||||||
import { Translation } from "../../../UI/i18n/Translation"
|
import { Translation, TypedTranslation } from "../../../UI/i18n/Translation"
|
||||||
import { LayoutConfigJson } from "../Json/LayoutConfigJson"
|
import { LayoutConfigJson } from "../Json/LayoutConfigJson"
|
||||||
import LayoutConfig from "../LayoutConfig"
|
import LayoutConfig from "../LayoutConfig"
|
||||||
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||||
|
@ -14,6 +14,7 @@ import Translations from "../../../UI/i18n/Translations"
|
||||||
import Svg from "../../../Svg"
|
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"
|
||||||
|
|
||||||
class ValidateLanguageCompleteness extends DesugaringStep<any> {
|
class ValidateLanguageCompleteness extends DesugaringStep<any> {
|
||||||
private readonly _languages: string[]
|
private readonly _languages: string[]
|
||||||
|
@ -586,11 +587,11 @@ export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJ
|
||||||
|
|
||||||
class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJson> {
|
class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJson> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Miscellanious checks on the tagrendering", ["special"], "MiscTagREnderingChecksRew")
|
super("Miscellanious checks on the tagrendering", ["special"], "MiscTagRenderingChecks")
|
||||||
}
|
}
|
||||||
|
|
||||||
convert(
|
convert(
|
||||||
json: TagRenderingConfigJson,
|
json: TagRenderingConfigJson | QuestionableTagRenderingConfigJson,
|
||||||
context: string
|
context: string
|
||||||
): {
|
): {
|
||||||
result: TagRenderingConfigJson
|
result: TagRenderingConfigJson
|
||||||
|
@ -598,6 +599,7 @@ class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJson> {
|
||||||
warnings?: string[]
|
warnings?: string[]
|
||||||
information?: string[]
|
information?: string[]
|
||||||
} {
|
} {
|
||||||
|
const warnings = []
|
||||||
const errors = []
|
const errors = []
|
||||||
if (json["special"] !== undefined) {
|
if (json["special"] !== undefined) {
|
||||||
errors.push(
|
errors.push(
|
||||||
|
@ -606,9 +608,28 @@ 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"]) {
|
||||||
|
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 {
|
return {
|
||||||
result: json,
|
result: json,
|
||||||
errors,
|
errors,
|
||||||
|
warnings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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
|
* If undefined, the question is never asked and this tagrendering is read-only
|
||||||
*/
|
*/
|
||||||
question?: string | any
|
question?: string | Record<string, string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<string, string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow freeform text input from the user
|
* Allow freeform text input from the user
|
||||||
|
|
|
@ -47,6 +47,7 @@ export default class TagRenderingConfig {
|
||||||
public readonly group: string
|
public readonly group: string
|
||||||
public readonly render?: TypedTranslation<object>
|
public readonly render?: TypedTranslation<object>
|
||||||
public readonly question?: TypedTranslation<object>
|
public readonly question?: TypedTranslation<object>
|
||||||
|
public readonly questionhint?: TypedTranslation<object>
|
||||||
public readonly condition?: TagsFilter
|
public readonly condition?: TagsFilter
|
||||||
public readonly description?: Translation
|
public readonly description?: Translation
|
||||||
|
|
||||||
|
@ -119,6 +120,7 @@ export default class TagRenderingConfig {
|
||||||
this.labels = json.labels ?? []
|
this.labels = json.labels ?? []
|
||||||
this.render = Translations.T(json.render, translationKey + ".render")
|
this.render = Translations.T(json.render, translationKey + ".render")
|
||||||
this.question = Translations.T(json.question, translationKey + ".question")
|
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.description = Translations.T(json.description, translationKey + ".description")
|
||||||
this.condition = TagUtils.Tag(json.condition ?? { and: [] }, `${context}.condition`)
|
this.condition = TagUtils.Tag(json.condition ?? { and: [] }, `${context}.condition`)
|
||||||
if (json.freeform) {
|
if (json.freeform) {
|
||||||
|
|
|
@ -85,6 +85,10 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
),
|
),
|
||||||
3
|
3
|
||||||
)
|
)
|
||||||
|
let questionHint = undefined
|
||||||
|
if (configuration.questionhint !== undefined) {
|
||||||
|
questionHint = new SubstitutedTranslation(configuration.questionhint, tags, state)
|
||||||
|
}
|
||||||
|
|
||||||
const feedback = new UIEventSource<Translation>(undefined)
|
const feedback = new UIEventSource<Translation>(undefined)
|
||||||
const inputElement: ReadonlyInputElement<UploadableTag> = new VariableInputElement(
|
const inputElement: ReadonlyInputElement<UploadableTag> = new VariableInputElement(
|
||||||
|
@ -139,6 +143,7 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
}
|
}
|
||||||
super([
|
super([
|
||||||
question,
|
question,
|
||||||
|
questionHint,
|
||||||
inputElement,
|
inputElement,
|
||||||
new VariableUiElement(
|
new VariableUiElement(
|
||||||
feedback.map(
|
feedback.map(
|
||||||
|
|
|
@ -4,6 +4,7 @@ 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,
|
||||||
|
@ -241,6 +242,9 @@ 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>()
|
||||||
|
|
Loading…
Add table
Reference in a new issue