Studio: add slideshow, add useability tweaks
This commit is contained in:
parent
2df9aa8564
commit
8bc555fbe0
26 changed files with 440 additions and 316 deletions
|
@ -11,6 +11,7 @@
|
|||
import type { ConversionMessage } from "../../Models/ThemeConfig/Conversion/Conversion";
|
||||
import ErrorIndicatorForRegion from "./ErrorIndicatorForRegion.svelte";
|
||||
import { ChevronRightIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import SchemaBasedInput from "./SchemaBasedInput.svelte";
|
||||
|
||||
const layerSchema: ConfigMeta[] = <any>layerSchemaRaw;
|
||||
|
||||
|
@ -25,7 +26,6 @@
|
|||
* Blacklist of regions for the general area tab
|
||||
* These are regions which are handled by a different tab
|
||||
*/
|
||||
const regionBlacklist = ["hidden", undefined, "infobox", "tagrenderings", "maprendering", "editing", "title", "linerendering", "pointrendering"];
|
||||
const allNames = Utils.Dedup(layerSchema.map(meta => meta.hints.group));
|
||||
|
||||
const perRegion: Record<string, ConfigMeta[]> = {};
|
||||
|
@ -33,12 +33,7 @@
|
|||
perRegion[region] = layerSchema.filter(meta => meta.hints.group === region);
|
||||
}
|
||||
|
||||
const baselayerRegions: string[] = ["Basic", "presets", "filters"];
|
||||
for (const baselayerRegion of baselayerRegions) {
|
||||
if (perRegion[baselayerRegion] === undefined) {
|
||||
console.error("BaseLayerRegions in editLayer: no items have group '" + baselayerRegion + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
const title: Store<string> = state.getStoreFor(["id"]);
|
||||
const wl = window.location;
|
||||
const baseUrl = wl.protocol + "//" + wl.host + "/theme.html?userlayout=";
|
||||
|
@ -46,80 +41,122 @@
|
|||
function firstPathsFor(...regionNames: string[]): Set<string> {
|
||||
const pathNames = new Set<string>();
|
||||
for (const regionName of regionNames) {
|
||||
const region: ConfigMeta[] = perRegion[regionName]
|
||||
const region: ConfigMeta[] = perRegion[regionName];
|
||||
for (const configMeta of region) {
|
||||
pathNames.add(configMeta.path[0])
|
||||
pathNames.add(configMeta.path[0]);
|
||||
}
|
||||
}
|
||||
return pathNames;
|
||||
|
||||
}
|
||||
|
||||
function configForRequiredField(id: string): ConfigMeta{
|
||||
let config = layerSchema.find(config => config.path.length === 1 && config.path[0] === id)
|
||||
config = Utils.Clone(config)
|
||||
config.required = true
|
||||
console.log(">>>", config)
|
||||
config.hints.ifunset = undefined
|
||||
return config
|
||||
}
|
||||
|
||||
let requiredFields = ["id", "name", "description"];
|
||||
let currentlyMissing = state.configuration.map(config => {
|
||||
const missing = [];
|
||||
for (const requiredField of requiredFields) {
|
||||
if (!config[requiredField]) {
|
||||
missing.push(requiredField);
|
||||
}
|
||||
}
|
||||
return missing;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<div class="w-full flex justify-between">
|
||||
<slot />
|
||||
<h3>Editing layer {$title}</h3>
|
||||
{#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
|
||||
<ChevronRightIcon class= "h-6 w-6 shrink-0"/>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="m4">
|
||||
<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" 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>
|
||||
{#if $currentlyMissing.length > 0}
|
||||
|
||||
<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>
|
||||
{#each requiredFields as required}
|
||||
<SchemaBasedInput {state}
|
||||
schema={configForRequiredField(required)}
|
||||
path={[required]} />
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="w-full flex justify-between my-2">
|
||||
<slot />
|
||||
<h3>Editing layer {$title}</h3>
|
||||
{#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
|
||||
<ChevronRightIcon class="h-6 w-6 shrink-0" />
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="m4">
|
||||
<TabbedGroup>
|
||||
<div slot="title0" class="flex">General properties
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("Basic")} {state} />
|
||||
</div>
|
||||
<div class="flex flex-col" slot="content0">
|
||||
<Region {state} configs={perRegion["Basic"]} />
|
||||
|
||||
<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} />
|
||||
</div>
|
||||
<div slot="title4">Configuration file</div>
|
||||
<div slot="content4">
|
||||
<div>
|
||||
Below, you'll find the raw configuration file in `.json`-format.
|
||||
This is mostly for debugging purposes
|
||||
</div>
|
||||
<div class="literal-code">
|
||||
{JSON.stringify($configuration, null, " ")}
|
||||
|
||||
|
||||
<div slot="title1" class="flex">Information panel (questions and answers)
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("title","tagrenderings","editing")} {state} />
|
||||
</div>
|
||||
{#each $messages as message}
|
||||
<li>
|
||||
{message.level}
|
||||
<span class="literal-code">{message.context.path.join(".")}</span>
|
||||
{message.message}
|
||||
<span class="literal-code">
|
||||
<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">
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("presets")} {state} />
|
||||
Creating a new point
|
||||
</div>
|
||||
|
||||
<div slot="content2">
|
||||
<Region {state} configs={perRegion["presets"]} />
|
||||
</div>
|
||||
|
||||
<div slot="title3" class="flex">Rendering on the map
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("linerendering","pointrendering")} {state} />
|
||||
</div>
|
||||
<div slot="content3">
|
||||
<Region configs={perRegion["linerendering"]} {state} />
|
||||
<Region configs={perRegion["pointrendering"]} {state} />
|
||||
</div>
|
||||
|
||||
<div slot="title4" class="flex">Advanced functionality
|
||||
<ErrorIndicatorForRegion firstPaths={firstPathsFor("advanced","expert")} {state} />
|
||||
</div>
|
||||
<div slot="content4">
|
||||
<Region configs={perRegion["advanced"]} {state} />
|
||||
<Region configs={perRegion["expert"]} {state} />
|
||||
</div>
|
||||
<div slot="title5">Configuration file</div>
|
||||
<div slot="content5">
|
||||
<div>
|
||||
Below, you'll find the raw configuration file in `.json`-format.
|
||||
This is mosSendertly for debugging purposes
|
||||
</div>
|
||||
<div class="literal-code">
|
||||
{JSON.stringify($configuration, null, " ")}
|
||||
</div>
|
||||
{#each $messages as message}
|
||||
<li>
|
||||
{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>
|
||||
</TabbedGroup>
|
||||
</li>
|
||||
{/each}
|
||||
</div>
|
||||
</TabbedGroup>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue