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
		Add a link
		
	
		Reference in a new issue