Studio: move some validation from throwing errors in LayerConfig.ts into errors in Validation

This commit is contained in:
Pieter Vander Vennet 2023-10-17 16:06:58 +02:00
parent 632dd6dfb1
commit ec79672fa6
10 changed files with 160 additions and 79 deletions

View file

@ -19,7 +19,7 @@
export let condition3: Store<boolean> = tr
export let condition4: Store<boolean> = tr
export let tab: UIEventSource<number>;
export let tab: UIEventSource<number> = new UIEventSource<number>(0);
let tabElements: HTMLElement[] = [];
$: tabElements[$tab]?.click();
$: {

View file

@ -4,11 +4,12 @@
import layerSchemaRaw from "../../assets/schemas/layerconfigmeta.json";
import Region from "./Region.svelte";
import TabbedGroup from "../Base/TabbedGroup.svelte";
import { Store, UIEventSource } from "../../Logic/UIEventSource";
import { Store } from "../../Logic/UIEventSource";
import type { ConfigMeta } from "./configMeta";
import { Utils } from "../../Utils";
import type { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson";
import type { ConversionMessage } from "../../Models/ThemeConfig/Conversion/Conversion";
import ErrorIndicatorForRegion from "./ErrorIndicatorForRegion.svelte";
const layerSchema: ConfigMeta[] = <any>layerSchemaRaw;
@ -37,10 +38,22 @@
console.error("BaseLayerRegions in editLayer: no items have group '" + baselayerRegion + "\"");
}
}
const leftoverRegions: string[] = allNames.filter(r => regionBlacklist.indexOf(r) < 0 && baselayerRegions.indexOf(r) < 0);
const title: Store<string> = state.getStoreFor(["id"]);
const wl = window.location
const baseUrl = wl.protocol+"//"+wl.host+"/theme.html?userlayout="
const wl = window.location;
const baseUrl = wl.protocol + "//" + wl.host + "/theme.html?userlayout=";
function firstPathsFor(...regionNames: string[]): Set<string> {
const pathNames = new Set<string>();
for (const regionName of regionNames) {
const region: ConfigMeta[] = perRegion[regionName]
for (const configMeta of region) {
pathNames.add(configMeta.path[0])
}
}
return pathNames;
}
</script>
<div class="w-full flex justify-between">
@ -48,31 +61,37 @@
{#if $hasErrors > 0}
<div class="alert">{$hasErrors} errors detected</div>
{:else}
<a class="primary button" href={baseUrl+state.server.layerUrl(title.data)} target="_blank" rel="noopener">Try it out</a>
<a class="primary button" href={baseUrl+state.server.layerUrl(title.data)} target="_blank" rel="noopener">Try it
out</a>
{/if}
</div>
<div class="m4">
<TabbedGroup tab={new UIEventSource(2)}>
<div slot="title0">General properties</div>
<TabbedGroup>
<div slot="title0" class="flex">General properties
<ErrorIndicatorForRegion firstPaths={firstPathsFor(...baselayerRegions)} {state} />
</div>
<div class="flex flex-col" slot="content0">
{#each baselayerRegions as region}
<Region {state} configs={perRegion[region]} title={region} />
{/each}
</div>
<div slot="title1">Information panel (questions and answers)</div>
<div slot="title1" class="flex">Information panel (questions and answers)
<ErrorIndicatorForRegion firstPaths={firstPathsFor("title","tagrenderings","editing")} {state} /></div>
<div slot="content1">
<Region configs={perRegion["title"]} {state} title="Popup title" />
<Region configs={perRegion["tagrenderings"]} {state} title="Popup contents" />
<Region configs={perRegion["editing"]} {state} title="Other editing elements" />
</div>
<div slot="title2">Rendering on the map</div>
<div slot="title2" class="flex">Rendering on the map
<ErrorIndicatorForRegion firstPaths={firstPathsFor("linerendering","pointrendering")} {state} /></div>
<div slot="content2">
<Region configs={perRegion["linerendering"]} {state} />
<Region configs={perRegion["pointrendering"]} {state} />
</div>
<div slot="title3">Advanced functionality</div>
<div slot="title3" class="flex">Advanced functionality
<ErrorIndicatorForRegion firstPaths={firstPathsFor("advanced","expert")} {state} /></div>
<div slot="content3">
<Region configs={perRegion["advanced"]} {state} />
<Region configs={perRegion["expert"]} {state} />
@ -91,6 +110,9 @@
{message.level}
<span class="literal-code">{message.context.path.join(".")}</span>
{message.message}
<span class="literal-code">
{message.context.operation.join(".")}
</span>
</li>
{/each}
</div>

View file

@ -72,7 +72,6 @@ export default class EditLayerState {
}
}
this.messages = this.configuration.mapD((config) => {
const context = ConversionContext.construct([], ["prepare"])
const trs = Utils.NoNull(config.tagRenderings ?? [])
for (let i = 0; i < trs.length; i++) {
const tr = trs[i]
@ -98,6 +97,8 @@ export default class EditLayerState {
new PrepareLayer(state),
new ValidateLayer("dynamic", false, undefined)
)
const context = ConversionContext.construct([], ["prepare"])
prepare.convert(<LayerConfigJson>config, context)
return context.messages
})

View file

@ -0,0 +1,19 @@
<script lang="ts">
import EditLayerState from "./EditLayerState";
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid";
export let firstPaths: Set<string>;
export let state: EditLayerState;
let messagesCount = state.messages.map(msgs => msgs.filter(msg => {
const pth = msg.context.path
return firstPaths.has(pth[0]) || (pth.length > 1 && firstPaths.has(pth[1]));
}).length);
</script>
{#if $messagesCount > 0}
<span class="alert flex w-min">
<ExclamationIcon class="w-6 h-6" />
{$messagesCount}
</span>
{/if}

View file

@ -89,6 +89,15 @@
}
let config: TagRenderingConfig
let err: string = undefined
let messages = state.messages.mapD(msgs => msgs.filter(msg => {
const pth = msg.context.path
for (let i = 0; i < Math.min(pth.length, path.length); i++) {
if(pth[i] !== path[i]){
return false
}
}
return true
}))
try {
config = new TagRenderingConfig(configJson, "config based on " + schema.path.join("."))
} catch (e) {
@ -133,11 +142,15 @@
console.error("Could not register", path,"due to",e)
}
</script>
{#if err !== undefined}
<span class="alert">{err}</span>
{:else}
<div class="w-full flex flex-col">
<TagRenderingEditable {config} selectedElement={undefined} showQuestionIfUnknown={true} {state} {tags}/>
{#if $messages.length > 0}
{#each $messages as msg}
<div class="alert">{msg.message}</div>
{/each}
{/if}
</div>
{/if}