forked from MapComplete/MapComplete
Themes(toilets): add an allowed range to some freeform inputs, allow to specify 'units' in the freeform, add the possibility to convert units
This commit is contained in:
parent
32cb8f489f
commit
fb8ead2a2c
16 changed files with 270 additions and 103 deletions
|
@ -4,12 +4,17 @@
|
|||
import Validators from "./Validators"
|
||||
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
|
||||
import { createEventDispatcher, onDestroy } from "svelte"
|
||||
import { Validator } from "./Validator"
|
||||
import { Unit } from "../../Models/Unit"
|
||||
import UnitInput from "../Popup/UnitInput.svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import type { ValueRange } from "../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import Translations from "../i18n/Translations"
|
||||
import FloatValidator from "./Validators/FloatValidator"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
|
||||
export let type: ValidatorType
|
||||
export let feedback: UIEventSource<Translation> | undefined = undefined
|
||||
|
@ -18,6 +23,7 @@
|
|||
export let placeholder: string | Translation | undefined = undefined
|
||||
export let autofocus: boolean = false
|
||||
export let unit: Unit = undefined
|
||||
export let range: ValueRange = undefined
|
||||
/**
|
||||
* Valid state, exported to the calling component
|
||||
*/
|
||||
|
@ -42,7 +48,7 @@
|
|||
|
||||
function initValueAndDenom() {
|
||||
if (unit && value.data) {
|
||||
const [v, denom] = unit?.findDenomination(value.data, getCountry)
|
||||
const [v, denom] = unit.findDenomination(value.data, getCountry)
|
||||
if (denom) {
|
||||
unvalidatedText.setData(v)
|
||||
selectedUnit.setData(denom.canonical)
|
||||
|
@ -62,7 +68,6 @@
|
|||
}
|
||||
}
|
||||
initValueAndDenom()
|
||||
|
||||
$: {
|
||||
// The type changed -> reset some values
|
||||
validator = Validators.get(type ?? "string")
|
||||
|
@ -77,6 +82,41 @@
|
|||
initValueAndDenom()
|
||||
}
|
||||
|
||||
const t = Translations.t.validation.generic
|
||||
|
||||
/**
|
||||
* Side effect: sets the feedback, returns true/false if valid
|
||||
* @param canonicalValue
|
||||
*/
|
||||
function validateRange(canonicalValue: number): boolean {
|
||||
if (!range) {
|
||||
return true
|
||||
}
|
||||
if (canonicalValue < range.warnBelow) {
|
||||
feedback.set(t.suspiciouslyLow)
|
||||
}
|
||||
if (canonicalValue > range.warnAbove) {
|
||||
feedback.set(t.suspiciouslyHigh)
|
||||
}
|
||||
if (canonicalValue > range.max) {
|
||||
let max: number | string | BaseUIElement = range.max
|
||||
if (unit) {
|
||||
max = unit.asHumanLongValue(max)
|
||||
}
|
||||
feedback.set(t.tooHigh.Subs({ max }))
|
||||
return false
|
||||
}
|
||||
if (canonicalValue < range.min) {
|
||||
let min: number | string | BaseUIElement = range.min
|
||||
if (unit) {
|
||||
min = unit.asHumanLongValue(min)
|
||||
}
|
||||
feedback.set(t.tooLow.Subs({ min }))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function setValues() {
|
||||
// Update the value stores
|
||||
const v = unvalidatedText.data
|
||||
|
@ -92,13 +132,22 @@
|
|||
}
|
||||
|
||||
if (selectedUnit.data) {
|
||||
value.setData(unit.toOsm(v, selectedUnit.data))
|
||||
const canonicalValue = unit.valueInCanonical(v + selectedUnit.data)
|
||||
if (validateRange(canonicalValue)) {
|
||||
value.setData(unit.toOsm(v, selectedUnit.data))
|
||||
} else {
|
||||
value.set(undefined)
|
||||
}
|
||||
} else {
|
||||
value.setData(v)
|
||||
if (validateRange(v)) {
|
||||
value.setData(v)
|
||||
} else {
|
||||
value.set(undefined)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(unvalidatedText.addCallbackAndRun((_) => setValues()))
|
||||
onDestroy(unvalidatedText.addCallbackAndRun(() => setValues()))
|
||||
if (unit === undefined) {
|
||||
onDestroy(
|
||||
value.addCallbackAndRunD((fromUpstream) => {
|
||||
|
@ -110,7 +159,7 @@
|
|||
} else {
|
||||
// Handled by the UnitInput
|
||||
}
|
||||
onDestroy(selectedUnit.addCallback((_) => setValues()))
|
||||
onDestroy(selectedUnit.addCallback(() => setValues()))
|
||||
if (validator === undefined) {
|
||||
throw (
|
||||
"Not a valid type (no validator found) for type '" +
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue