UX: indicate that a search field is actually a regex, add feedback to the filterview

This commit is contained in:
Pieter Vander Vennet 2024-09-17 02:51:02 +02:00
parent 5da63bf83a
commit ebe7ff85f8
5 changed files with 39 additions and 7 deletions

View file

@ -850,6 +850,9 @@
"description": "a positive, whole number",
"noZero": "Zero is not allowed"
},
"regex": {
"description": "a regular expression"
},
"slope": {
"inputExplanation": "Place your phone on the ground with the top side of your phone pointing towards the top of the slope.",
"inputIncorrect": "For correct measurements, make sure the arrow is within the green area."

View file

@ -60,7 +60,7 @@ export default class FilterConfig {
}
const fields: { name: string; type: ValidatorType }[] = (option.fields ?? []).map((f, i) => {
const type = <ValidatorType> f.type ?? "string"
const type = <ValidatorType> f.type ?? "regex"
if(Validators.availableTypes.indexOf(type) < 0){
throw `Invalid filter: type is not a valid validator. Did you mean one of ${Utils.sortedByLevenshteinDistance(type, <any>Validators.availableTypes, x => x).slice(0, 3)}`
}

View file

@ -8,6 +8,8 @@
import { Utils } from "../../Utils"
import type { ValidatorType } from "../InputElement/Validators"
import InputHelper from "../InputElement/InputHelper.svelte"
import { Translation } from "../i18n/Translation"
import Tr from "../Base/Tr.svelte"
export let filteredLayer: FilteredLayer
export let option: FilterConfigOption
@ -36,7 +38,7 @@
appliedFilter?.setData(FilteredLayer.fieldsToString(properties))
}
let firstValue : UIEventSource<string>
let firstValue: UIEventSource<string>
for (const field of option.fields) {
// A bit of cheating: the 'parts' will have '}' suffixed for fields
const src = new UIEventSource<string>(initialState[field.name] ?? "")
@ -47,9 +49,10 @@
onDestroy(
src.stabilized(200).addCallback(() => {
setFields()
}),
})
)
}
let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined)
</script>
<div class="low-interaction p-1 rounded-2xl px-3" class:interactive={$firstValue?.length > 0}>
@ -58,11 +61,15 @@
<!-- This is a field! -->
<span class="mx-1">
<InputHelper value={fieldValues[part["subs"]]} type={fieldTypes[part["subs"]]}>
<ValidatedInput slot="fallback" value={fieldValues[part["subs"]]} type={fieldTypes[part["subs"]]} />
<ValidatedInput slot="fallback" value={fieldValues[part["subs"]]} type={fieldTypes[part["subs"]]}
{feedback} />
</InputHelper>
</span>
{:else}
{@html part["message"]}
{/if}
{/each}
{#if $feedback}
<Tr cls="alert" t={$feedback}/>
{/if}
</div>

View file

@ -15,9 +15,6 @@ import UrlValidator from "./Validators/UrlValidator"
import PhoneValidator from "./Validators/PhoneValidator"
import OpeningHoursValidator from "./Validators/OpeningHoursValidator"
import ColorValidator from "./Validators/ColorValidator"
import BaseUIElement from "../BaseUIElement"
import Combine from "../Base/Combine"
import Title from "../Base/Title"
import SimpleTagValidator from "./Validators/SimpleTagValidator"
import ImageUrlValidator from "./Validators/ImageUrlValidator"
import TagKeyValidator from "./Validators/TagKeyValidator"
@ -30,6 +27,7 @@ import SlopeValidator from "./Validators/SlopeValidator"
import VeloparkValidator from "./Validators/VeloparkValidator"
import NameSuggestionIndexValidator from "./Validators/NameSuggestionIndexValidator"
import CurrencyValidator from "./Validators/CurrencyValidator"
import RegexValidator from "./Validators/RegexValidator"
export type ValidatorType = (typeof Validators.availableTypes)[number]
@ -64,6 +62,7 @@ export default class Validators {
"velopark",
"nsi",
"currency",
"regex"
] as const
public static readonly AllValidators: ReadonlyArray<Validator> = [
@ -95,6 +94,7 @@ export default class Validators {
new VeloparkValidator(),
new NameSuggestionIndexValidator(),
new CurrencyValidator(),
new RegexValidator()
]
private static _byType = Validators._byTypeConstructor()

View file

@ -0,0 +1,22 @@
import StringValidator from "./StringValidator"
import { s } from "vitest/dist/env-afee91f0"
import { Translation } from "../../i18n/Translation"
import Translations from "../../i18n/Translations"
export default class RegexValidator extends StringValidator{
constructor() {
super("regex", "Validates a regex")
}
getFeedback(s: string): Translation | undefined {
try{
new RegExp(s)
}catch (e) {
return Translations.T("Not a valid Regex: "+e)
}
}
isValid(s: string): boolean {
return this.getFeedback(s) === undefined
}
}