forked from MapComplete/MapComplete
Studio: more finetuning, first version working
This commit is contained in:
parent
c4d4a57a08
commit
ac1e7c7f06
39 changed files with 2971 additions and 7187 deletions
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
|
||||
import EditLayerState, { LayerStateSender } from "./EditLayerState";
|
||||
import { LayerStateSender } from "./EditLayerState";
|
||||
import layerSchemaRaw from "../../assets/schemas/layerconfigmeta.json";
|
||||
import Region from "./Region.svelte";
|
||||
import TabbedGroup from "../Base/TabbedGroup.svelte";
|
||||
|
|
@ -10,12 +10,13 @@
|
|||
import type { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson";
|
||||
|
||||
const layerSchema: ConfigMeta[] = <any>layerSchemaRaw;
|
||||
let state = new EditLayerState(layerSchema);
|
||||
|
||||
export let state;
|
||||
const messages = state.messages;
|
||||
export let initialLayerConfig: Partial<LayerConfigJson> = {};
|
||||
state.configuration.setData(initialLayerConfig);
|
||||
const configuration = state.configuration;
|
||||
new LayerStateSender("http://localhost:1235", state);
|
||||
new LayerStateSender(state);
|
||||
/**
|
||||
* Blacklist of regions for the general area tab
|
||||
* These are regions which are handled by a different tab
|
||||
|
|
@ -76,6 +77,7 @@
|
|||
</div>
|
||||
{#each $messages as message}
|
||||
<li>
|
||||
{message.level}
|
||||
<span class="literal-code">{message.context.path.join(".")}</span>
|
||||
{message.message}
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -13,26 +13,21 @@ import { PrepareLayer } from "../../Models/ThemeConfig/Conversion/PrepareLayer"
|
|||
import { ValidateLayer } from "../../Models/ThemeConfig/Conversion/Validation"
|
||||
import { AllSharedLayers } from "../../Customizations/AllSharedLayers"
|
||||
import { QuestionableTagRenderingConfigJson } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
|
||||
import { TagUtils } from "../../Logic/Tags/TagUtils"
|
||||
import StudioServer from "./StudioServer"
|
||||
|
||||
/**
|
||||
* Sends changes back to the server
|
||||
*/
|
||||
export class LayerStateSender {
|
||||
constructor(serverLocation: string, layerState: EditLayerState) {
|
||||
constructor(layerState: EditLayerState) {
|
||||
layerState.configuration.addCallback(async (config) => {
|
||||
// console.log("Current config is", Utils.Clone(config))
|
||||
const id = config.id
|
||||
if (id === undefined) {
|
||||
console.log("No id found in layer, not updating")
|
||||
console.warn("No id found in layer, not updating")
|
||||
return
|
||||
}
|
||||
const fresponse = await fetch(`${serverLocation}/layers/${id}/${id}.json`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8",
|
||||
},
|
||||
body: JSON.stringify(config, null, " "),
|
||||
})
|
||||
await layerState.server.updateLayer(<LayerConfigJson>config)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -47,9 +42,11 @@ export default class EditLayerState {
|
|||
Partial<LayerConfigJson>
|
||||
>({})
|
||||
public readonly messages: Store<ConversionMessage[]>
|
||||
public readonly server: StudioServer
|
||||
|
||||
constructor(schema: ConfigMeta[]) {
|
||||
constructor(schema: ConfigMeta[], server: StudioServer) {
|
||||
this.schema = schema
|
||||
this.server = server
|
||||
this.osmConnection = new OsmConnection({
|
||||
oauth_token: QueryParameters.GetQueryParameter(
|
||||
"oauth_token",
|
||||
|
|
@ -73,18 +70,36 @@ export default class EditLayerState {
|
|||
sharedLayers: layers,
|
||||
}
|
||||
}
|
||||
this.messages = this.configuration.map((config) => {
|
||||
this.messages = this.configuration.mapD((config) => {
|
||||
const context = ConversionContext.construct([], ["prepare"])
|
||||
|
||||
for (let i = 0; i < (config.tagRenderings ?? []).length; i++) {
|
||||
const tr = config.tagRenderings[i]
|
||||
if (typeof tr === "string") {
|
||||
continue
|
||||
}
|
||||
if (!tr["id"] && !tr["override"]) {
|
||||
const qtr = <QuestionableTagRenderingConfigJson>tr
|
||||
let id = "" + i
|
||||
if (qtr?.freeform?.key) {
|
||||
id = qtr?.freeform?.key
|
||||
} else if (qtr.mappings?.[0]?.if) {
|
||||
id =
|
||||
qtr.freeform?.key ??
|
||||
TagUtils.Tag(qtr.mappings[0].if).usedKeys()?.[0] ??
|
||||
"" + i
|
||||
}
|
||||
qtr["id"] = id
|
||||
}
|
||||
}
|
||||
|
||||
const prepare = new Pipe(
|
||||
new PrepareLayer(state),
|
||||
new ValidateLayer("dynamic", false, undefined)
|
||||
)
|
||||
prepare.convert(<LayerConfigJson>config, context)
|
||||
console.log(context.messages)
|
||||
return context.messages
|
||||
})
|
||||
console.log("Configuration store:", this.configuration)
|
||||
}
|
||||
|
||||
public getCurrentValueFor(path: ReadonlyArray<string | number>): any | undefined {
|
||||
|
|
@ -104,7 +119,6 @@ export default class EditLayerState {
|
|||
public getStoreFor(path: ReadonlyArray<string | number>): UIEventSource<any | undefined> {
|
||||
const store = new UIEventSource<any>(this.getCurrentValueFor(path))
|
||||
store.addCallback((v) => {
|
||||
console.log("UPdating store", path, v)
|
||||
this.setValueAt(path, v)
|
||||
})
|
||||
return store
|
||||
|
|
@ -156,7 +170,6 @@ export default class EditLayerState {
|
|||
|
||||
public setValueAt(path: ReadonlyArray<string | number>, v: any) {
|
||||
let entry = this.configuration.data
|
||||
console.log("Setting value", v, "to", path, "in entry", entry)
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
const breadcrumb = path[i]
|
||||
if (entry[breadcrumb] === undefined) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
const subparts: ConfigMeta = state.getSchemaStartingWith(schema.path)
|
||||
.filter(part => part.path.length - 1 === schema.path.length);
|
||||
console.log("For ", schema.path, "got subparts", subparts)
|
||||
/**
|
||||
* Store the _indices_
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@
|
|||
try {
|
||||
onDestroy(state.register(path, tags.map(tgs => {
|
||||
const v = tgs["value"];
|
||||
console.log("Registering",path,"setting value to", v)
|
||||
if(typeof v !== "string"){
|
||||
return v
|
||||
}
|
||||
|
|
@ -116,6 +117,9 @@
|
|||
}
|
||||
}
|
||||
if (schema.type === "number") {
|
||||
if(v === ""){
|
||||
return undefined
|
||||
}
|
||||
return Number(v)
|
||||
}
|
||||
if (isTranslation) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
types.splice(hasBooleanOption);
|
||||
}
|
||||
|
||||
|
||||
let lastIsString = false;
|
||||
{
|
||||
const types: string | string[] = Array.isArray(schema.type) ? schema.type[schema.type.length - 1].type : [];
|
||||
|
|
@ -217,5 +218,4 @@
|
|||
path={[...subpath, (subschema?.path?.at(-1) ?? "???")]}></SchemaBasedInput>
|
||||
{/each}
|
||||
{/if}
|
||||
{chosenOption}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ import Constants from "../../Models/Constants"
|
|||
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
|
||||
|
||||
export default class StudioServer {
|
||||
private _url: string
|
||||
private readonly url: string
|
||||
|
||||
constructor(url: string) {
|
||||
this._url = url
|
||||
this.url = url
|
||||
}
|
||||
|
||||
public async fetchLayerOverview(): Promise<Set<string>> {
|
||||
const { allFiles } = <{ allFiles: string[] }>(
|
||||
await Utils.downloadJson(this._url + "/overview")
|
||||
await Utils.downloadJson(this.url + "/overview")
|
||||
)
|
||||
const layers = allFiles
|
||||
.filter((f) => f.startsWith("layers/"))
|
||||
|
|
@ -20,19 +20,27 @@ export default class StudioServer {
|
|||
return new Set<string>(layers)
|
||||
}
|
||||
|
||||
async fetchLayer(layerId: string, checkNew: boolean = false): Promise<LayerConfigJson> {
|
||||
async fetchLayer(layerId: string): Promise<LayerConfigJson> {
|
||||
try {
|
||||
return await Utils.downloadJson(
|
||||
this._url +
|
||||
"/layers/" +
|
||||
layerId +
|
||||
"/" +
|
||||
layerId +
|
||||
".json" +
|
||||
(checkNew ? ".new.json" : "")
|
||||
this.url + "/layers/" + layerId + "/" + layerId + ".json"
|
||||
)
|
||||
} catch (e) {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
async updateLayer(config: LayerConfigJson) {
|
||||
const id = config.id
|
||||
if (id === undefined || id === "") {
|
||||
return
|
||||
}
|
||||
await fetch(`${this.url}/layers/${id}/${id}.json`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8",
|
||||
},
|
||||
body: JSON.stringify(config, null, " "),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ const freeformSchema = <ConfigMeta[]> questionableTagRenderingSchemaRaw.filter(
|
|||
|
||||
<SchemaBasedField {state} path={[...path,"question"]} schema={topLevelItems["question"]}></SchemaBasedField>
|
||||
<SchemaBasedField {state} path={[...path,"questionHint"]} schema={topLevelItems["questionHint"]}></SchemaBasedField>
|
||||
<SchemaBasedField {state} path={[...path,"render"]} schema={topLevelItems["render"]}></SchemaBasedField>
|
||||
|
||||
{#each ($mappings ?? []) as mapping, i (mapping)}
|
||||
<div class="flex interactive w-full">
|
||||
|
|
@ -102,7 +103,12 @@ const freeformSchema = <ConfigMeta[]> questionableTagRenderingSchemaRaw.filter(
|
|||
Add a mapping
|
||||
</button>
|
||||
|
||||
<SchemaBasedField {state} path={[...path,"multiAnswer"]} schema={topLevelItems["multiAnswer"]}></SchemaBasedField>
|
||||
|
||||
<div class="border border-gray-200 border-dashed">
|
||||
<h3>Text field and input element configuration</h3>
|
||||
<Region {state} {path} configs={freeformSchema}/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue