mapcomplete/src/UI/Studio/EditLayer.svelte

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

122 lines
4.7 KiB
Svelte
Raw Normal View History

2023-06-16 02:36:11 +02:00
<script lang="ts">
2023-10-16 15:06:50 +02:00
import EditLayerState, { LayerStateSender } from "./EditLayerState";
2023-09-15 01:16:33 +02:00
import layerSchemaRaw from "../../assets/schemas/layerconfigmeta.json";
import Region from "./Region.svelte";
import TabbedGroup from "../Base/TabbedGroup.svelte";
import { Store } from "../../Logic/UIEventSource";
2023-09-15 01:16:33 +02:00
import type { ConfigMeta } from "./configMeta";
import { Utils } from "../../Utils";
2023-10-07 03:07:32 +02:00
import type { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson";
2023-10-16 15:06:50 +02:00
import type { ConversionMessage } from "../../Models/ThemeConfig/Conversion/Conversion";
import ErrorIndicatorForRegion from "./ErrorIndicatorForRegion.svelte";
2023-06-16 02:36:11 +02:00
2023-09-15 01:16:33 +02:00
const layerSchema: ConfigMeta[] = <any>layerSchemaRaw;
2023-10-16 15:06:50 +02:00
export let state: EditLayerState;
const messages = state.messages;
2023-10-16 15:06:50 +02:00
const hasErrors = messages.map((m: ConversionMessage[]) => m.filter(m => m.level === "error").length);
export let initialLayerConfig: Partial<LayerConfigJson> = {};
2023-10-07 03:07:32 +02:00
state.configuration.setData(initialLayerConfig);
2023-09-15 01:16:33 +02:00
const configuration = state.configuration;
new LayerStateSender(state);
2023-09-15 01:16:33 +02:00
/**
* 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"];
2023-09-15 01:16:33 +02:00
const allNames = Utils.Dedup(layerSchema.map(meta => meta.hints.group));
2023-06-16 02:36:11 +02:00
2023-09-15 01:16:33 +02:00
const perRegion: Record<string, ConfigMeta[]> = {};
for (const region of allNames) {
perRegion[region] = layerSchema.filter(meta => meta.hints.group === region);
}
2023-06-16 02:36:11 +02:00
const baselayerRegions: string[] = ["Basic", "presets", "filters"];
2023-09-15 01:16:33 +02:00
for (const baselayerRegion of baselayerRegions) {
if (perRegion[baselayerRegion] === undefined) {
console.error("BaseLayerRegions in editLayer: no items have group '" + baselayerRegion + "\"");
2023-06-16 02:36:11 +02:00
}
2023-09-15 01:16:33 +02:00
}
const title: Store<string> = state.getStoreFor(["id"]);
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;
}
2023-06-16 02:36:11 +02:00
</script>
2023-10-16 15:06:50 +02:00
<div class="w-full flex justify-between">
<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</a>
2023-10-16 15:06:50 +02:00
{/if}
</div>
<div class="m4">
<TabbedGroup>
<div slot="title0" class="flex">General properties
<ErrorIndicatorForRegion firstPaths={firstPathsFor(...baselayerRegions)} {state} />
</div>
2023-06-16 02:36:11 +02:00
<div class="flex flex-col" slot="content0">
2023-09-15 01:16:33 +02:00
{#each baselayerRegions as region}
<Region {state} configs={perRegion[region]} title={region} />
{/each}
2023-06-16 02:36:11 +02:00
</div>
<div slot="title1" class="flex">Information panel (questions and answers)
<ErrorIndicatorForRegion firstPaths={firstPathsFor("title","tagrenderings","editing")} {state} /></div>
2023-06-16 02:36:11 +02:00
<div slot="content1">
2023-09-15 01:16:33 +02:00
<Region configs={perRegion["title"]} {state} title="Popup title" />
<Region configs={perRegion["tagrenderings"]} {state} title="Popup contents" />
2023-09-15 01:16:33 +02:00
<Region configs={perRegion["editing"]} {state} title="Other editing elements" />
2023-06-16 02:36:11 +02:00
</div>
<div slot="title2" class="flex">Rendering on the map
<ErrorIndicatorForRegion firstPaths={firstPathsFor("linerendering","pointrendering")} {state} /></div>
2023-06-16 02:36:11 +02:00
<div slot="content2">
<Region configs={perRegion["linerendering"]} {state} />
<Region configs={perRegion["pointrendering"]} {state} />
2023-09-15 01:16:33 +02:00
</div>
<div slot="title3" class="flex">Advanced functionality
<ErrorIndicatorForRegion firstPaths={firstPathsFor("advanced","expert")} {state} /></div>
2023-09-15 01:16:33 +02:00
<div slot="content3">
<Region configs={perRegion["advanced"]} {state} />
<Region configs={perRegion["expert"]} {state} />
</div>
<div slot="title4">Configuration file</div>
<div slot="content4">
2023-09-15 01:16:33 +02:00
<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>
{#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}
2023-06-16 02:36:11 +02:00
</div>
2023-09-15 01:16:33 +02:00
</TabbedGroup>
</div>