Fix: correctly replace fields in filterview

This commit is contained in:
Pieter Vander Vennet 2023-05-24 00:50:27 +02:00
parent af7bc0f7ce
commit ae491f4916
2 changed files with 77 additions and 49 deletions

View file

@ -1,57 +1,60 @@
<script lang="ts"> <script lang="ts">
import FilteredLayer from "../../Models/FilteredLayer"; import FilteredLayer from "../../Models/FilteredLayer";
import type { FilterConfigOption } from "../../Models/ThemeConfig/FilterConfig"; import type {FilterConfigOption} from "../../Models/ThemeConfig/FilterConfig";
import Locale from "../i18n/Locale"; import Locale from "../i18n/Locale";
import ValidatedInput from "../InputElement/ValidatedInput.svelte"; import ValidatedInput from "../InputElement/ValidatedInput.svelte";
import { UIEventSource } from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import { onDestroy } from "svelte"; import {onDestroy} from "svelte";
import {Utils} from "../../Utils";
export let filteredLayer: FilteredLayer; export let filteredLayer: FilteredLayer;
export let option: FilterConfigOption; export let option: FilterConfigOption;
export let id: string; export let id: string;
let parts: string[]; let parts: ({ message: string } | { subs: string })[];
let language = Locale.language; let language = Locale.language;
$: { $: {
parts = option.question.textFor($language).split("{"); const template = option.question.textFor($language)
} parts = Utils.splitIntoSubstitutionParts(template)
let fieldValues: Record<string, UIEventSource<string>> = {};
let fieldTypes: Record<string, string> = {};
let appliedFilter = <UIEventSource<string>>filteredLayer.appliedFilters.get(id);
let initialState: Record<string, string> = JSON.parse(appliedFilter?.data ?? "{}");
function setFields() {
const properties: Record<string, string> = {};
for (const key in fieldValues) {
const v = fieldValues[key].data;
const k = key.substring(0, key.length - 1);
if (v === undefined) {
properties[k] = undefined;
} else {
properties[k] = v;
}
} }
appliedFilter?.setData(FilteredLayer.fieldsToString(properties)); let fieldValues: Record<string, UIEventSource<string>> = {};
} let fieldTypes: Record<string, string> = {};
let appliedFilter = <UIEventSource<string>>filteredLayer.appliedFilters.get(id);
let initialState: Record<string, string> = JSON.parse(appliedFilter?.data ?? "{}");
for (const field of option.fields) { function setFields() {
// A bit of cheating: the 'parts' will have '}' suffixed for fields const properties: Record<string, string> = {};
fieldTypes[field.name + "}"] = field.type; for (const key in fieldValues) {
const src = new UIEventSource<string>(initialState[field.name] ?? ""); const v = fieldValues[key].data;
fieldValues[field.name + "}"] = src; if (v === undefined) {
onDestroy(src.stabilized(200).addCallback(() => { properties[key] = undefined;
setFields(); } else {
})); properties[key] = v;
} }
}
appliedFilter?.setData(FilteredLayer.fieldsToString(properties));
}
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] ?? "");
fieldTypes[field.name] = field.type;
fieldValues[field.name] = src;
onDestroy(src.stabilized(200).addCallback(() => {
setFields();
}));
}
</script> </script>
<div> <div>
{#each parts as part, i} {#each parts as part, i}
{#if part.endsWith("}")} {#if part.subs}
<!-- This is a field! --> <!-- This is a field! -->
<ValidatedInput value={fieldValues[part]} type={fieldTypes[part]} /> <span class="mx-1">
{:else} <ValidatedInput value={fieldValues[part.subs]} type={fieldTypes[part.subs]}/>
{part} </span>
{/if} {:else}
{/each} {part.message}
{/if}
{/each}
</div> </div>

View file

@ -1430,7 +1430,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
return true return true
} }
static SameObject(a: any, b: any) { public static SameObject(a: any, b: any) {
if (a === b) { if (a === b) {
return true return true
} }
@ -1465,4 +1465,29 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
) { ) {
return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b) return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b)
} }
/**
*
* Utils.splitIntoSubstitutionParts("abc") // => [{message: "abc"}]
* Utils.splitIntoSubstitutionParts("abc {search} def") // => [{message: "abc "}, {subs: "search"}, {message: " def"}]
*
*/
public static splitIntoSubstitutionParts(template: string): ({ message: string } | {subs: string})[]{
const preparts = template.split("{")
const spec : ({ message: string } | {subs: string})[] = []
for (const prepart of preparts) {
const postParts = prepart.split("}")
if(postParts.length === 1){
// This was a normal part
spec.push({message: postParts[0]})
}else{
const [subs, message] = postParts
spec.push({subs})
if(message !== ""){
spec.push({message})
}
}
}
return spec
}
} }