Refactoring: fix most of the custom input elements, support right click/long tap/double click to add a new element

This commit is contained in:
Pieter Vander Vennet 2023-04-16 03:42:26 +02:00
parent b0052d3a36
commit 1123a72c5e
25 changed files with 390 additions and 531 deletions

View file

@ -5,28 +5,36 @@
import Tr from "../../Base/Tr.svelte";
import TagRenderingConfig from "../../../Models/ThemeConfig/TagRenderingConfig";
import Inline from "./Inline.svelte";
import { createEventDispatcher } from "svelte";
import { createEventDispatcher, onDestroy } from "svelte";
import InputHelper from "../../InputElement/InputHelper.svelte";
import type { Feature } from "geojson";
export let value: UIEventSource<string>;
export let config: TagRenderingConfig;
export let tags: UIEventSource<Record<string, string>>;
export let feature: Feature = undefined;
let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined);
let dispatch = createEventDispatcher<{ "selected" }>();
onDestroy(value.addCallbackD(() => {dispatch("selected")}))
</script>
{#if config.freeform.inline}
<Inline key={config.freeform.key} {tags} template={config.render}>
<div class="inline-flex flex-col">
{#if config.freeform.inline}
<Inline key={config.freeform.key} {tags} template={config.render}>
<ValidatedInput {feedback} on:selected={() => dispatch("selected")}
type={config.freeform.type} {value}></ValidatedInput>
</Inline>
{:else}
<ValidatedInput {feedback} on:selected={() => dispatch("selected")}
type={config.freeform.type} {value}></ValidatedInput>
</Inline>
{:else}
<ValidatedInput {feedback} on:selected={() => dispatch("selected")}
type={config.freeform.type} {value}></ValidatedInput>
{/if}
{/if}
<InputHelper args={config.freeform.helperArgs} {config} {feature} type={config.freeform.type} {value}></InputHelper>
</div>
{#if $feedback !== undefined}
<div class="alert">

View file

@ -41,13 +41,11 @@
return true;
}
let baseQuestions = []
$: {
baseQuestions = (layer.tagRenderings ?? [])?.filter(tr => allowed(tr.labels) && tr.question !== undefined);
}
let skippedQuestions = new UIEventSource<Set<string>>(new Set<string>());
let questionsToAsk = tags.map(tags => {
const baseQuestions = (layer.tagRenderings ?? [])?.filter(tr => allowed(tr.labels) && tr.question !== undefined);
console.log("Determining questions for", baseQuestions)
const questionsToAsk: TagRenderingConfig[] = [];
for (const baseQuestion of baseQuestions) {
if (skippedQuestions.data.has(baseQuestion.id) > 0) {
@ -64,6 +62,7 @@
return questionsToAsk;
}, [skippedQuestions]);
let _questionsToAsk: TagRenderingConfig[];
let _firstQuestion: TagRenderingConfig;
onDestroy(questionsToAsk.subscribe(qta => {

View file

@ -17,25 +17,27 @@
export let state: SpecialVisualizationState;
export let selectedElement: Feature;
export let config: TagRenderingConfig;
if(config === undefined){
throw "Config is undefined in tagRenderingAnswer"
if (config === undefined) {
throw "Config is undefined in tagRenderingAnswer";
}
export let layer: LayerConfig
export let layer: LayerConfig;
let trs: { then: Translation; icon?: string; iconClass?: string }[];
$: trs = Utils.NoNull(config?.GetRenderValues(_tags));
</script>
{#if config !== undefined && (config?.condition === undefined || config.condition.matchesProperties(_tags))}
{#if trs.length === 1}
<TagRenderingMapping mapping={trs[0]} {tags} {state} {selectedElement} {layer}></TagRenderingMapping>
{/if}
{#if trs.length > 1}
<ul>
{#each trs as mapping}
<li>
<TagRenderingMapping {mapping} {tags} {state} {selectedElement} {layer}></TagRenderingMapping>
</li>
{/each}
</ul>
{/if}
<div class="flex flex-col w-full">
{#if trs.length === 1}
<TagRenderingMapping mapping={trs[0]} {tags} {state} {selectedElement} {layer}></TagRenderingMapping>
{/if}
{#if trs.length > 1}
<ul>
{#each trs as mapping}
<li>
<TagRenderingMapping {mapping} {tags} {state} {selectedElement} {layer}></TagRenderingMapping>
</li>
{/each}
</ul>
{/if}
</div>
{/if}

View file

@ -11,7 +11,7 @@
import FreeformInput from "./FreeformInput.svelte";
import Translations from "../../i18n/Translations.js";
import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction";
import { createEventDispatcher } from "svelte";
import { createEventDispatcher, onDestroy } from "svelte";
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid";
import SpecialTranslation from "./SpecialTranslation.svelte";
@ -25,6 +25,12 @@
// Will be bound if a freeform is available
let freeformInput = new UIEventSource<string>(undefined);
onDestroy(tags.addCallbackAndRunD(tags => {
// initialize with the previous value
if (config.freeform?.key) {
freeformInput.setData(tags[config.freeform.key]);
}
}));
let selectedMapping: number = undefined;
let checkedMappings: boolean[];
$: {
@ -126,7 +132,7 @@
{#if config.freeform?.key && !(mappings?.length > 0)}
<!-- There are no options to choose from, simply show the input element: fill out the text field -->
<FreeformInput {config} {tags} value={freeformInput} />
<FreeformInput {config} {tags} feature={selectedElement} value={freeformInput} />
{:else if mappings !== undefined && !config.multiAnswer}
<!-- Simple radiobuttons as mapping -->
<div class="flex flex-col">
@ -143,7 +149,7 @@
<label>
<input type="radio" bind:group={selectedMapping} name={"mappings-radio-"+config.id}
value={config.mappings.length}>
<FreeformInput {config} {tags} value={freeformInput}
<FreeformInput {config} {tags} feature={selectedElement} value={freeformInput}
on:selected={() => selectedMapping = config.mappings.length } />
</label>
{/if}
@ -162,7 +168,7 @@
<label>
<input type="checkbox" name={"mappings-checkbox-"+config.id+"-"+config.mappings.length}
bind:checked={checkedMappings[config.mappings.length]}>
<FreeformInput {config} {tags} value={freeformInput}
<FreeformInput {config} {tags} feature={selectedElement} value={freeformInput}
on:selected={() => checkedMappings[config.mappings.length] = true} />
</label>
{/if}
@ -180,7 +186,7 @@
{:else }
<div class="w-6 h-6">
<!-- Invalid value; show an inactive button or something like that-->
<ExclamationIcon></ExclamationIcon>
<ExclamationIcon/>
</div>
{/if}
</div>