forked from MapComplete/MapComplete
Studio+UX: various UX tweaks after usertesting
This commit is contained in:
parent
4219b23af1
commit
3a915bdf25
31 changed files with 2476 additions and 108 deletions
|
|
@ -1,10 +1,11 @@
|
|||
<script lang="ts">
|
||||
import type { ConfigMeta } from "./configMeta";
|
||||
import EditLayerState from "./EditLayerState";
|
||||
import type { QuestionableTagRenderingConfigJson } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson";
|
||||
import type {
|
||||
QuestionableTagRenderingConfigJson
|
||||
} from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson";
|
||||
import { UIEventSource } from "../../Logic/UIEventSource";
|
||||
import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte";
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig";
|
||||
|
||||
export let schema: ConfigMeta;
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@
|
|||
</div>
|
||||
|
||||
<div slot="title2">
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("presets")} {state} />
|
||||
Creating a new point
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("presets")} {state} />
|
||||
</div>
|
||||
|
||||
<div slot="content2">
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
import configs from "../../assets/schemas/questionabletagrenderingconfigmeta.json";
|
||||
import { Utils } from "../../Utils";
|
||||
|
||||
export let mapping: MappingConfigJson;
|
||||
export let state: EditLayerState;
|
||||
export let path: (string | number)[];
|
||||
let tag: UIEventSource<TagConfigJson> = state.getStoreFor([...path, "if"]);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
import type { TagRenderingConfigJson } from "../../Models/ThemeConfig/Json/TagRenderingConfigJson";
|
||||
import FromHtml from "../Base/FromHtml.svelte";
|
||||
import { Utils } from "../../Utils";
|
||||
import ShowConversionMessage from "./ShowConversionMessage.svelte";
|
||||
import NextButton from "../Base/NextButton.svelte";
|
||||
|
||||
export let state: EditLayerState;
|
||||
export let path: ReadonlyArray<string | number>;
|
||||
|
|
@ -73,18 +75,16 @@
|
|||
{#if $id}
|
||||
TagRendering {$id}
|
||||
{/if}
|
||||
<button on:click={() => state.highlightedItem.setData({path, schema})}>
|
||||
<NextButton clss="primary" on:click={() => state.highlightedItem.setData({path, schema})}>
|
||||
{#if schema.hints.question}
|
||||
{schema.hints.question}
|
||||
{/if}
|
||||
</button>
|
||||
</NextButton>
|
||||
{#if description}
|
||||
<FromHtml src={description} />
|
||||
{/if}
|
||||
{#each $messages as message}
|
||||
<div class="alert">
|
||||
{message.message}
|
||||
</div>
|
||||
<ShowConversionMessage {message}/>
|
||||
{/each}
|
||||
|
||||
<slot class="self-end my-4"></slot>
|
||||
|
|
@ -93,6 +93,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col w-full m-4">
|
||||
<h3>Preview of this question</h3>
|
||||
{#each $configs as config}
|
||||
<TagRenderingEditable
|
||||
selectedElement={state.exampleFeature}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import QuestionPreview from "./QuestionPreview.svelte";
|
||||
import { Utils } from "../../Utils";
|
||||
import SchemaBasedMultiType from "./SchemaBasedMultiType.svelte";
|
||||
import ShowConversionMessage from "./ShowConversionMessage.svelte";
|
||||
|
||||
export let state: EditLayerState;
|
||||
export let schema: ConfigMeta;
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
}
|
||||
}
|
||||
let createdItems = values.data.length;
|
||||
let messages = state.messagesFor(path)
|
||||
|
||||
|
||||
function createItem(valueToSet?: any) {
|
||||
|
|
@ -125,6 +127,11 @@
|
|||
|
||||
{#if $values.length === 0}
|
||||
No values are defined
|
||||
{#if $messages.length > 0}
|
||||
{#each $messages as message}
|
||||
<ShowConversionMessage {message}/>
|
||||
{/each}
|
||||
{/if}
|
||||
{:else if subparts.length === 0}
|
||||
<!-- We need an array of values, so we use the typehint of the _parent_ element as field -->
|
||||
{#each $values as value (value)}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@
|
|||
import { onDestroy } from "svelte";
|
||||
import type { JsonSchemaType } from "./jsonSchema";
|
||||
import { ConfigMetaUtils } from "./configMeta.ts";
|
||||
import ShowConversionMessage from "./ShowConversionMessage.svelte";
|
||||
|
||||
export let state: EditLayerState;
|
||||
export let path: (string | number)[] = [];
|
||||
export let schema: ConfigMeta;
|
||||
export let startInEditModeIfUnset: boolean = false
|
||||
export let startInEditModeIfUnset: boolean = !schema.hints.ifunset
|
||||
let value = new UIEventSource<string | any>(undefined);
|
||||
|
||||
const isTranslation = schema.hints.typehint === "translation" || schema.hints.typehint === "rendered" || ConfigMetaUtils.isTranslation(schema);
|
||||
|
|
@ -118,8 +119,8 @@
|
|||
err = path.join(".") + " " + e;
|
||||
}
|
||||
let startValue = state.getCurrentValueFor(path);
|
||||
const tags = new UIEventSource<Record<string, string>>({ value: startValue });
|
||||
let startInEditMode = !startValue && startInEditModeIfUnset
|
||||
const tags = new UIEventSource<Record<string, string>>({ value: startValue });
|
||||
try {
|
||||
onDestroy(state.register(path, tags.map(tgs => {
|
||||
const v = tgs["value"];
|
||||
|
|
@ -161,12 +162,12 @@
|
|||
<div class="w-full flex flex-col">
|
||||
<TagRenderingEditable editMode={startInEditMode} {config} selectedElement={undefined} showQuestionIfUnknown={true} {state} {tags} />
|
||||
{#if $messages.length > 0}
|
||||
{#each $messages as msg}
|
||||
<div class="alert">{msg.message}</div>
|
||||
{#each $messages as message}
|
||||
<ShowConversionMessage {message}/>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if window.location.hostname === "127.0.0.1"}
|
||||
<span class="subtle">{path.join(".")} {schema.hints.typehint}</span>
|
||||
<span class="subtle">SchemaBasedField <b>{path.join(".")}</b> <span class="cursor-pointer" on:click={() => console.log(schema)}>{schema.hints.typehint}</span></span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
import type { JsonSchemaType } from "./jsonSchema";
|
||||
// @ts-ignore
|
||||
import nmd from "nano-markdown";
|
||||
import ShowConversionMessage from "./ShowConversionMessage.svelte";
|
||||
|
||||
/**
|
||||
* If 'types' is defined: allow the user to pick one of the types to input.
|
||||
|
|
@ -216,9 +217,12 @@
|
|||
path={[...subpath, (subschema?.path?.at(-1) ?? "???")]}></SchemaBasedInput>
|
||||
{/each}
|
||||
{:else if $messages.length > 0}
|
||||
{#each $messages as msg}
|
||||
<div class="alert">{msg.message}</div>
|
||||
{#each $messages as message}
|
||||
<ShowConversionMessage {message}/>
|
||||
{/each}
|
||||
{/if}
|
||||
{/if}
|
||||
{#if window.location.hostname === "127.0.0.1"}
|
||||
<span class="subtle">SchemaBasedMultiType <b>{path.join(".")}</b> <span class="cursor-pointer" on:click={() => console.log(schema)}>{schema.hints.typehint}</span></span>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
<script lang="ts">
|
||||
import type { ConversionMessage } from "../../Models/ThemeConfig/Conversion/Conversion";
|
||||
import { ExclamationTriangleIcon } from "@babeard/svelte-heroicons/solid";
|
||||
import { ExclamationCircleIcon, ExclamationIcon, InformationCircleIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
|
||||
/**
|
||||
* Single conversion message, styled depending on the type
|
||||
*/
|
||||
export let message: ConversionMessage;
|
||||
</script>
|
||||
|
||||
{#if message.level === "error"}
|
||||
<div class="alert flex justify-between items-center">
|
||||
<ExclamationIcon class="w-6 h-6 mx-1 shrink-0" />
|
||||
{message.message}
|
||||
<div/>
|
||||
</div>
|
||||
{:else if message.level === "warning"}
|
||||
<div class="warning flex justify-between items-center">
|
||||
<ExclamationIcon class="w-6 h-6 mx-1 shrink-0" />
|
||||
{message.message}
|
||||
<div/>
|
||||
</div>
|
||||
{:else if message.level === "information"}
|
||||
<div class="information flex justify-between items-center">
|
||||
<InformationCircleIcon class="w-6 h-6 mx-1 shrink-0" />
|
||||
{message.message}
|
||||
<div/>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -28,7 +28,7 @@ let value = state.getCurrentValueFor(path);
|
|||
* Allows the theme builder to create 'writable' themes.
|
||||
* Should only be enabled for 'tagrenderings' in the theme, if the source is OSM
|
||||
*/
|
||||
let allowQuestions: Store<boolean> = (state.configuration.mapD(config => config.source?.geoJson === undefined))
|
||||
let allowQuestions: Store<boolean> = (state.configuration.mapD(config => path.at(0) === "tagRenderings" && config.source?.geoJson === undefined))
|
||||
|
||||
|
||||
let mappingsBuiltin: MappingConfigJson[] = [];
|
||||
|
|
@ -118,7 +118,7 @@ const missing: string[] = questionableTagRenderingSchemaRaw.filter(schema => sch
|
|||
{/if}
|
||||
{#each ($mappings ?? []) as mapping, i (mapping)}
|
||||
<div class="flex interactive w-full">
|
||||
<MappingInput {mapping} {state} path={path.concat(["mappings", i])}>
|
||||
<MappingInput {state} path={path.concat(["mappings", i])}>
|
||||
<button slot="delete" class="rounded-full no-image-background" on:click={() => {
|
||||
initMappings();
|
||||
mappings.data.splice(i, 1)
|
||||
|
|
@ -132,7 +132,7 @@ const missing: string[] = questionableTagRenderingSchemaRaw.filter(schema => sch
|
|||
|
||||
<button class="primary"
|
||||
on:click={() =>{ initMappings(); mappings.data.push({if: undefined, then: {}}); mappings.ping()} }>
|
||||
Add a mapping
|
||||
Add a predefined option
|
||||
</button>
|
||||
|
||||
<SchemaBasedField {state} path={[...path,"multiAnswer"]} schema={topLevelItems["multiAnswer"]} />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue