Studio: Fix some usability errors

This commit is contained in:
Pieter Vander Vennet 2023-10-17 00:32:54 +02:00
parent 80b7a038cf
commit 2f8cb91d31
9 changed files with 43 additions and 30 deletions

View file

@ -28,7 +28,8 @@
</script>
{#if $badge}
{#if !ignoreLoading && $loadingStatus === "loading"}
<slot/>
<!-- {#if !ignoreLoading && $loadingStatus === "loading"}
<slot name="loading">
<Loading />
</slot>
@ -41,5 +42,5 @@
<slot />
{:else if $loadingStatus === "not-attempted"}
<slot name="not-logged-in" />
{/if}
{/if} -->
{/if}

View file

@ -88,7 +88,7 @@ export class LoginToggle extends VariableUiElement {
)
},
[state.featureSwitchUserbadge, state.osmConnection?.apiIsOnline]
) ?? new ImmutableStore(el) //
) ?? new ImmutableStore(el)
)
}
}

View file

@ -16,7 +16,7 @@
export let tags: UIEventSource<Record<string, string>>
export let selectedElement: Feature | undefined
export let state: SpecialVisualizationState
export let layer: LayerConfig
export let layer: LayerConfig = undefined
export let editingEnabled : Store<boolean> | undefined = state?.featureSwitchUserbadge

View file

@ -986,6 +986,9 @@ export default class SpecialVisualizations {
constr: (state, tagsSource) =>
new VariableUiElement(
tagsSource.map((tags) => {
if (state.layout === undefined) {
return "<feature title>"
}
const layer = state.layout.getMatchingLayer(tags)
const title = layer?.title?.GetRenderValue(tags)
if (title === undefined) {
@ -1335,10 +1338,10 @@ export default class SpecialVisualizations {
tagSource.map((tags) => {
const v = tags[argument[0] ?? "value"]
try {
const tr = JSON.parse(v)
const tr = typeof v === "string" ? JSON.parse(v) : v
return new Translation(tr).SetClass("font-bold")
} catch (e) {
return v
return JSON.stringify(v)
}
})
)

View file

@ -15,6 +15,7 @@ import { AllSharedLayers } from "../../Customizations/AllSharedLayers"
import { QuestionableTagRenderingConfigJson } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
import { TagUtils } from "../../Logic/Tags/TagUtils"
import StudioServer from "./StudioServer"
import { Utils } from "../../Utils"
/**
* Sends changes back to the server
@ -72,9 +73,9 @@ export default class EditLayerState {
}
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]
const trs = Utils.NoNull(config.tagRenderings ?? [])
for (let i = 0; i < trs.length; i++) {
const tr = trs[i]
if (typeof tr === "string") {
continue
}
@ -116,11 +117,19 @@ export default class EditLayerState {
return entry
}
public getStoreFor(path: ReadonlyArray<string | number>): UIEventSource<any | undefined> {
private readonly _stores = new Map<string, UIEventSource<any>>()
public getStoreFor<T>(path: ReadonlyArray<string | number>): UIEventSource<T | undefined> {
const key = path.join(".")
// TODO check if this gives problems when changing the order of e.g. mappings and questions
if (this._stores.has(key)) {
return this._stores.get(key)
}
const store = new UIEventSource<any>(this.getCurrentValueFor(path))
store.addCallback((v) => {
this.setValueAt(path, v)
})
this._stores.set(key, store)
return store
}
@ -170,19 +179,24 @@ export default class EditLayerState {
public setValueAt(path: ReadonlyArray<string | number>, v: any) {
let entry = this.configuration.data
const isUndefined =
v !== undefined &&
v !== null &&
v !== "" &&
!(typeof v === "object" && Object.keys({}).length === 0)
for (let i = 0; i < path.length - 1; i++) {
const breadcrumb = path[i]
if (entry[breadcrumb] === undefined) {
entry[breadcrumb] = typeof path[i + 1] === "number" ? [] : {}
}
entry = entry[breadcrumb]
if (entry === undefined && isUndefined) {
// Nothing to do anymore: we cannot traverse the object, but don't have to set something anyway
return
}
}
if (
v !== undefined &&
v !== null &&
v !== "" &&
!(typeof v === "object" && Object.keys({}).length === 0)
) {
if (isUndefined) {
entry[path.at(-1)] = v
} else if (entry) {
delete entry[path.at(-1)]

View file

@ -29,7 +29,7 @@
const configJson: QuestionableTagRenderingConfigJson = {
id: path.join("_"),
render: schema.type === "boolean" ? undefined : ((schema.hints.inline ?? schema.path.at(-1) )+ ": <b>{translated(value)}</b>"),
render: schema.type === "boolean" ? undefined : ((schema.hints.inline ?? schema.path.at(-1) )+ ": translated value: <b>{translated(value)}</b>"),
question: schema.hints.question,
questionHint: nmd(schema.description),
freeform: schema.type === "boolean" ? undefined : {
@ -100,7 +100,9 @@
try {
onDestroy(state.register(path, tags.map(tgs => {
const v = tgs["value"];
console.log("Registering",path,"setting value to", v)
if(v !== ""){
console.log("Registering",path,"setting value to", v)
}
if(typeof v !== "string"){
return v
}

View file

@ -113,7 +113,6 @@
for (const requiredAttribute of type.required) {
if (existingValue[requiredAttribute] === undefined) {
console.log(path.join("."), " does not have required field", requiredAttribute, " so it cannot be type ", type);
// The 'existingValue' does _not_ have this required attribute, so it cannot be of this type
continue outer;
}
@ -128,7 +127,6 @@
}
possibleTypes.sort((a, b) => b.optionalMatches - a.optionalMatches);
possibleTypes.sort((a, b) => b.matchingPropertiesCount - a.matchingPropertiesCount);
console.log("Possible types are", possibleTypes)
if (possibleTypes.length > 0) {
chosenOption = possibleTypes[0].index
tags.setData({ chosen_type_index: "" + chosenOption});
@ -157,27 +155,23 @@
let subSchemas: ConfigMeta[] = [];
let subpath = path;
console.log("Initial chosen option for",path.join("."),"is", chosenOption);
const store = state.getStoreFor(path)
onDestroy(tags.addCallbackAndRun(tags => {
if (tags["value"] !== undefined && tags["value"] !== "") {
chosenOption = undefined;
console.log("Resetting chosenOption as `value` is present in the tags:", tags["value"])
return;
}
const oldOption = chosenOption;
console.log("Updating chosenOption based on", tags, oldOption)
chosenOption = tags["chosen_type_index"] ? Number(tags["chosen_type_index"]) : defaultOption;
const type = schema.type[chosenOption];
if (chosenOption !== oldOption) {
// Reset the values beneath
subSchemas = [];
const o = state.getCurrentValueFor(path) ?? {};
console.log({ o });
for (const key of type?.required ?? []) {
console.log(key);
o[key] ??= {};
}
state.setValueAt(path, o);
store.setData(o)
}
if (!type) {
return;
@ -187,7 +181,6 @@
if (type["$ref"] === "#/definitions/Record<string,string>") {
// The subtype is a translation object
const schema = state.getTranslationAt(cleanPath);
console.log("Got a translation,", schema);
subSchemas.push(schema);
subpath = path.slice(0, path.length - 2);
return;

View file

@ -44,9 +44,9 @@ const configBuiltin = new TagRenderingConfig(<QuestionableTagRenderingConfigJson
const tags = new UIEventSource({ value });
const store = state.getStoreFor(path)
tags.addCallbackAndRunD(tgs => {
state.setValueAt(path, tgs["value"]);
store.setData(tgs["value"])
});
let mappings: UIEventSource<MappingConfigJson[]> = state.getStoreFor([...path, "mappings"]);

View file

@ -17,7 +17,7 @@
import layerSchemaRaw from "../../src/assets/schemas/layerconfigmeta.json";
import If from "./Base/If.svelte";
export let studioUrl = /* "https://studio.mapcomplete.org"; /*/ "http://127.0.0.1:1235"; //*/
export let studioUrl = window.location.hostname === "127.0.0.1" ? "http://127.0.0.1:1235" : "https://studio.mapcomplete.org";
const studio = new StudioServer(studioUrl);
let layersWithErr = UIEventSource.FromPromiseWithErr(studio.fetchLayerOverview());
let layers = layersWithErr.mapD(l => l.success);