refactoring: more fixes, first attempt at tagRenderingAnswer

This commit is contained in:
Pieter Vander Vennet 2023-03-30 04:51:56 +02:00
parent aaaaf1948d
commit 29372c465e
24 changed files with 278 additions and 113 deletions

View file

@ -0,0 +1,43 @@
<script lang="ts">
import { Store, UIEventSource } from "../../Logic/UIEventSource";
import type { ValidatorType } from "./Validators";
import Validators from "./Validators";
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid";
import { Translation } from "../i18n/Translation";
export let value: UIEventSource<string>;
// Internal state, only copied to 'value' so that no invalid values leak outside
let _value = new UIEventSource(value.data ?? "")
export let type: ValidatorType;
let validator = Validators.get(type);
export let feedback: UIEventSource<Translation> | undefined = undefined
_value.addCallbackAndRun(v => {
if(validator.isValid(v)){
feedback?.setData(undefined)
value.setData(v)
return
}
value.setData(undefined)
feedback?.setData(validator.getFeedback(v));
})
if (validator === undefined) {
throw "Not a valid type for a validator:" + type;
}
const isValid = _value.map(v => validator.isValid(v));
</script>
{#if validator.textArea}
<textarea bind:value={$_value} inputmode={validator.inputmode ?? "text"}></textarea>
{:else }
<div class="flex">
<input bind:value={$_value} inputmode={validator.inputmode ?? "text"}>
{#if !$isValid}
<ExclamationIcon class="h-6 w-6 -ml-6"></ExclamationIcon>
{/if}
</div>
{/if}

View file

@ -17,10 +17,17 @@ export abstract class Validator {
* What HTML-inputmode to use
*/
public readonly inputmode?: string
public readonly textArea: boolean
constructor(name: string, explanation: string | BaseUIElement, inputmode?: string) {
constructor(
name: string,
explanation: string | BaseUIElement,
inputmode?: string,
textArea?: false | boolean
) {
this.name = name
this.inputmode = inputmode
this.textArea = textArea ?? false
if (this.name.endsWith("textfield")) {
this.name = this.name.substr(0, this.name.length - "TextField".length)
}
@ -46,7 +53,7 @@ export abstract class Validator {
}
}
public isValid(string: string, requestCountry: () => string): boolean {
public isValid(string: string, requestCountry?: () => string): boolean {
return true
}

View file

@ -19,8 +19,29 @@ import BaseUIElement from "../BaseUIElement"
import Combine from "../Base/Combine"
import Title from "../Base/Title"
export type ValidatorType = typeof Validators.availableTypes[number]
export default class Validators {
private static readonly AllValidators: ReadonlyArray<Validator> = [
public static readonly availableTypes = [
"string",
"text",
"date",
"nat",
"int",
"distance",
"direction",
"wikidata",
"pnat",
"float",
"pfloat",
"email",
"url",
"phone",
"opening_hours",
"color",
] as const
public static readonly AllValidators: ReadonlyArray<Validator> = [
new StringValidator(),
new TextValidator(),
new DateValidator(),
@ -38,8 +59,16 @@ export default class Validators {
new OpeningHoursValidator(),
new ColorValidator(),
]
public static allTypes: Map<string, Validator> = Validators.allTypesDict()
private static _byType = Validators._byTypeConstructor()
private static _byTypeConstructor(): Map<ValidatorType, Validator> {
const map = new Map<ValidatorType, Validator>()
for (const validator of Validators.AllValidators) {
map.set(<ValidatorType>validator.name, validator)
}
return map
}
public static HelpText(): BaseUIElement {
const explanations: BaseUIElement[] = Validators.AllValidators.map((type) =>
new Combine([new Title(type.name, 3), type.explanation]).SetClass("flex flex-col")
@ -51,15 +80,7 @@ export default class Validators {
]).SetClass("flex flex-col")
}
public static AvailableTypes(): string[] {
return Validators.AllValidators.map((tp) => tp.name)
}
private static allTypesDict(): Map<string, Validator> {
const types = new Map<string, Validator>()
for (const tp of Validators.AllValidators) {
types.set(tp.name, tp)
}
return types
static get(type: ValidatorType): Validator {
return Validators._byType.get(type)
}
}

View file

@ -9,7 +9,17 @@ export default class DirectionValidator extends IntValidator {
)
}
isValid(str): boolean {
if (str.endsWith("°")) {
str = str.substring(0, str.length - 1)
}
return super.isValid(str)
}
reformat(str): string {
if (str.endsWith("°")) {
str = str.substring(0, str.length - 1)
}
const n = Number(str) % 360
return "" + n
}

View file

@ -2,6 +2,6 @@ import { Validator } from "../Validator"
export default class TextValidator extends Validator {
constructor() {
super("text", "A longer piece of text. Uses an textArea instead of a textField", "text")
super("text", "A longer piece of text. Uses an textArea instead of a textField", "text", true)
}
}