forked from MapComplete/MapComplete
Better validated text fields with translations and human-friendly texts: first draft
This commit is contained in:
parent
695a0867c7
commit
9ab4fbd6f5
7 changed files with 581 additions and 528 deletions
|
@ -1,6 +0,0 @@
|
||||||
import CompiledTranslations from "./assets/generated/CompiledTranslations";
|
|
||||||
|
|
||||||
export default class AllTranslationAssets {
|
|
||||||
|
|
||||||
public static t = CompiledTranslations.t;
|
|
||||||
}
|
|
|
@ -93,10 +93,22 @@ export default class TagRenderingConfig {
|
||||||
if (json.freeform.addExtraTags !== undefined && json.freeform.addExtraTags.map === undefined) {
|
if (json.freeform.addExtraTags !== undefined && json.freeform.addExtraTags.map === undefined) {
|
||||||
throw `Freeform.addExtraTags should be a list of strings - not a single string (at ${context})`
|
throw `Freeform.addExtraTags should be a list of strings - not a single string (at ${context})`
|
||||||
}
|
}
|
||||||
|
const type = json.freeform.type ?? "string"
|
||||||
|
|
||||||
|
let placeholder = Translations.T(json.freeform.placeholder)
|
||||||
|
if (placeholder === undefined) {
|
||||||
|
const typeDescription = Translations.t.validation[type]?.description
|
||||||
|
placeholder = Translations.T(json.freeform.key+" ("+type+")")
|
||||||
|
if(typeDescription !== undefined){
|
||||||
|
console.log(typeDescription)
|
||||||
|
placeholder = placeholder.Fuse(typeDescription, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.freeform = {
|
this.freeform = {
|
||||||
key: json.freeform.key,
|
key: json.freeform.key,
|
||||||
type: json.freeform.type ?? "string",
|
type,
|
||||||
placeholder: Translations.T(json.freeform.placeholder ?? (json.freeform.key + "(" + (json.freeform.type ?? "string") + ")")),
|
placeholder,
|
||||||
addExtraTags: json.freeform.addExtraTags?.map((tg, i) =>
|
addExtraTags: json.freeform.addExtraTags?.map((tg, i) =>
|
||||||
TagUtils.Tag(tg, `${context}.extratag[${i}]`)) ?? [],
|
TagUtils.Tag(tg, `${context}.extratag[${i}]`)) ?? [],
|
||||||
inline: json.freeform.inline ?? false,
|
inline: json.freeform.inline ?? false,
|
||||||
|
@ -375,6 +387,7 @@ export default class TagRenderingConfig {
|
||||||
public GetRenderValue(tags: any, defltValue: any = undefined): Translation {
|
public GetRenderValue(tags: any, defltValue: any = undefined): Translation {
|
||||||
return this.GetRenderValueWithImage(tags, defltValue).then
|
return this.GetRenderValueWithImage(tags, defltValue).then
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the correct rendering value (or undefined if not known)
|
* Gets the correct rendering value (or undefined if not known)
|
||||||
* Not compatible with multiAnswer - use GetRenderValueS instead in that case
|
* Not compatible with multiAnswer - use GetRenderValueS instead in that case
|
||||||
|
|
|
@ -23,6 +23,7 @@ import Table from "../Base/Table";
|
||||||
import Combine from "../Base/Combine";
|
import Combine from "../Base/Combine";
|
||||||
import Title from "../Base/Title";
|
import Title from "../Base/Title";
|
||||||
import InputElementMap from "./InputElementMap";
|
import InputElementMap from "./InputElementMap";
|
||||||
|
import Translations from "../i18n/Translations";
|
||||||
|
|
||||||
interface TextFieldDef {
|
interface TextFieldDef {
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -84,7 +85,7 @@ class WikidataTextField implements TextFieldDef {
|
||||||
]).AsMarkdown()
|
]).AsMarkdown()
|
||||||
|
|
||||||
|
|
||||||
public isValid(str) {
|
public isValid(str) : boolean{
|
||||||
|
|
||||||
if (str === undefined) {
|
if (str === undefined) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -490,6 +491,7 @@ export default class ValidatedTextField {
|
||||||
* {string (typename) --> TextFieldDef}
|
* {string (typename) --> TextFieldDef}
|
||||||
*/
|
*/
|
||||||
public static AllTypes: Map<string, TextFieldDef> = ValidatedTextField.allTypesDict();
|
public static AllTypes: Map<string, TextFieldDef> = ValidatedTextField.allTypesDict();
|
||||||
|
private static Tranlations: string | BaseUIElement;
|
||||||
|
|
||||||
public static InputForType(type: string, options?: {
|
public static InputForType(type: string, options?: {
|
||||||
placeholder?: string | BaseUIElement,
|
placeholder?: string | BaseUIElement,
|
||||||
|
@ -508,7 +510,9 @@ export default class ValidatedTextField {
|
||||||
inputStyle?: string
|
inputStyle?: string
|
||||||
}): InputElement<string> {
|
}): InputElement<string> {
|
||||||
options = options ?? {};
|
options = options ?? {};
|
||||||
options.placeholder = options.placeholder ?? type;
|
if(options.placeholder === undefined) {
|
||||||
|
options.placeholder = Translations.t.validation[type]?.description ?? type
|
||||||
|
}
|
||||||
const tp: TextFieldDef = ValidatedTextField.AllTypes.get(type)
|
const tp: TextFieldDef = ValidatedTextField.AllTypes.get(type)
|
||||||
const isValidTp = tp.isValid;
|
const isValidTp = tp.isValid;
|
||||||
let isValid;
|
let isValid;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||||
import AllTranslationAssets from "../../AllTranslationAssets";
|
|
||||||
import {Translation} from "./Translation";
|
import {Translation} from "./Translation";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
import * as known_languages from "../../assets/generated/used_languages.json"
|
import * as known_languages from "../../assets/generated/used_languages.json"
|
||||||
|
import CompiledTranslations from "../../assets/generated/CompiledTranslations";
|
||||||
|
|
||||||
export default class Translations {
|
export default class Translations {
|
||||||
|
|
||||||
static t = AllTranslationAssets.t;
|
static t = CompiledTranslations.t;
|
||||||
private static knownLanguages = new Set(known_languages.languages)
|
private static knownLanguages = new Set(known_languages.languages)
|
||||||
constructor() {
|
constructor() {
|
||||||
throw "Translations is static. If you want to intitialize a new translation, use the singular form"
|
throw "Translations is static. If you want to intitialize a new translation, use the singular form"
|
||||||
|
|
|
@ -517,5 +517,16 @@
|
||||||
},
|
},
|
||||||
"importInspector": {
|
"importInspector": {
|
||||||
"title": "Inspect and manage import notes"
|
"title": "Inspect and manage import notes"
|
||||||
|
},
|
||||||
|
"validation": {
|
||||||
|
"string": {
|
||||||
|
"description": "a piece of text"
|
||||||
|
},
|
||||||
|
"pnat": {
|
||||||
|
"description": "a positive number"
|
||||||
|
},
|
||||||
|
"nat": {
|
||||||
|
"description": "a positive number or zero"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ import ReplaceGeometrySpec from "./ReplaceGeometry.spec";
|
||||||
import LegacyThemeLoaderSpec from "./LegacyThemeLoader.spec";
|
import LegacyThemeLoaderSpec from "./LegacyThemeLoader.spec";
|
||||||
import T from "./TestHelper";
|
import T from "./TestHelper";
|
||||||
import CreateNoteImportLayerSpec from "./CreateNoteImportLayer.spec";
|
import CreateNoteImportLayerSpec from "./CreateNoteImportLayer.spec";
|
||||||
|
import ValidatedTextFieldTranslations from "./ValidatedTextFieldTranslations.spec";
|
||||||
|
import ValidatedTextFieldTranslationsSpec from "./ValidatedTextFieldTranslations.spec";
|
||||||
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
@ -38,7 +40,8 @@ async function main() {
|
||||||
new ActorsSpec(),
|
new ActorsSpec(),
|
||||||
new ReplaceGeometrySpec(),
|
new ReplaceGeometrySpec(),
|
||||||
new LegacyThemeLoaderSpec(),
|
new LegacyThemeLoaderSpec(),
|
||||||
new CreateNoteImportLayerSpec()
|
new CreateNoteImportLayerSpec(),
|
||||||
|
new ValidatedTextFieldTranslationsSpec()
|
||||||
]
|
]
|
||||||
|
|
||||||
Utils.externalDownloadFunction = async (url) => {
|
Utils.externalDownloadFunction = async (url) => {
|
||||||
|
|
27
test/ValidatedTextFieldTranslations.spec.ts
Normal file
27
test/ValidatedTextFieldTranslations.spec.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import T from "./TestHelper";
|
||||||
|
import ValidatedTextField from "../UI/Input/ValidatedTextField";
|
||||||
|
import Translations from "../UI/i18n/Translations";
|
||||||
|
|
||||||
|
export default class ValidatedTextFieldTranslationsSpec extends T {
|
||||||
|
constructor() {
|
||||||
|
super([
|
||||||
|
["Test all", () => {
|
||||||
|
const ts = Translations.t.validation;
|
||||||
|
console.log("Hello world!")
|
||||||
|
const allErrors = Array.from(ValidatedTextField.AllTypes.keys()).map(key => {
|
||||||
|
const errors = []
|
||||||
|
const t = ts[key]
|
||||||
|
if (t === undefined) {
|
||||||
|
errors.push("No tranlations at all for " + key)
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
})
|
||||||
|
const errs = [].concat(...allErrors)
|
||||||
|
if (errs.length > 0) {
|
||||||
|
errs.forEach(e => console.log(e))
|
||||||
|
// throw errs.join("\n")
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue