MapComplete/src/UI/Studio/SchemaBasedField.svelte

133 lines
4.5 KiB
Svelte
Raw Normal View History

2023-06-16 02:36:11 +02:00
<script lang="ts">
import {UIEventSource} from "../../Logic/UIEventSource";
import type {ConfigMeta} from "./configMeta";
import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte";
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig";
import nmd from "nano-markdown"
2023-06-16 02:36:11 +02:00
import type {
QuestionableTagRenderingConfigJson
} from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson";
import EditLayerState from "./EditLayerState";
import { onDestroy } from "svelte";
2023-08-23 11:11:53 +02:00
import type { JsonSchemaType } from "./jsonSchema";
2023-09-15 01:16:33 +02:00
import { ConfigMetaUtils } from "./configMeta.ts"
2023-06-16 02:36:11 +02:00
export let state: EditLayerState
export let path: (string | number)[] = []
2023-06-16 02:36:11 +02:00
export let schema: ConfigMeta
let value = new UIEventSource<string>(undefined)
2023-09-15 01:16:33 +02:00
const isTranslation = schema.hints.typehint === "translation" || schema.hints.typehint === "rendered" || ConfigMetaUtils.isTranslation(schema)
let type = schema.hints.typehint ?? "string"
2023-09-15 01:16:33 +02:00
if(isTranslation){
type = "translation"
}
2023-08-23 11:11:53 +02:00
if(type.endsWith("[]")){
type = type.substring(0, type.length - 2)
}
2023-06-16 02:36:11 +02:00
const configJson: QuestionableTagRenderingConfigJson = {
2023-06-20 01:32:24 +02:00
id: path.join("_"),
2023-08-08 13:52:58 +02:00
render: schema.type === "boolean" ? undefined : ((schema.hints.inline ?? schema.path.at(-1) )+ ": <b>{translated(value)}</b>"),
2023-06-16 02:36:11 +02:00
question: schema.hints.question,
questionHint: nmd(schema.description),
freeform: schema.type === "boolean" ? undefined : {
2023-06-16 02:36:11 +02:00
key: "value",
type,
inline: schema.hints.inline !== undefined
},
2023-06-16 02:36:11 +02:00
}
if (schema.hints.default) {
configJson.mappings = [{
if: "value=", // We leave this blank
then: schema.path.at(-1) + " is not set. The default value <b>" + schema.hints.default + "</b> will be used. " + (schema.hints.ifunset ?? ""),
}]
} else if (!schema.required) {
2023-06-16 02:36:11 +02:00
configJson.mappings = [{
if: "value=",
then: schema.path.at(-1) + " is not set. " + (schema.hints.ifunset ?? ""),
}]
}
2023-08-23 11:11:53 +02:00
function mightBeBoolean(type: undefined | JsonSchemaType): boolean {
if(type === undefined){
return false
}
if(type["type"]){
type = type["type"]
}
if(type === "boolean"){
return true
}
if(!Array.isArray(type)){
return false
}
return type.some(t => mightBeBoolean(t) )
}
if (mightBeBoolean(schema.type)) {
configJson.mappings = configJson.mappings ?? []
configJson.mappings.push(
{
if: "value=true",
then: "Yes "+(schema.hints?.iftrue??"")
},
{
if: "value=false",
then: "No "+(schema.hints?.iffalse??"")
}
)
}
if (schema.hints.suggestions) {
if (!configJson.mappings) {
configJson.mappings = []
}
configJson.mappings.push(...schema.hints.suggestions)
}
2023-06-16 02:36:11 +02:00
let config: TagRenderingConfig
let err: string = undefined
try {
config = new TagRenderingConfig(configJson, "config based on " + schema.path.join("."))
} catch (e) {
console.error(e, config)
err = path.join(".") + " " + e
}
let startValue = state.getCurrentValueFor(path)
if (typeof startValue !== "string") {
startValue = JSON.stringify(startValue)
2023-06-16 02:36:11 +02:00
}
const tags = new UIEventSource<Record<string, string>>({value: startValue ?? ""})
try {
onDestroy(state.register(path, tags.map(tgs => {
const v = tgs["value"];
if (schema.type === "boolan") {
return v === "true" || v === "yes" || v === "1"
}
if (schema.type === "number") {
return Number(v)
}
if (isTranslation) {
if (v === "") {
return {}
}
return JSON.parse(v)
}
return v
}), isTranslation))
}catch (e) {
console.error("Could not register", path,"due to",e)
}
2023-06-16 02:36:11 +02:00
</script>
{#if err !== undefined}
<span class="alert">{err}</span>
{:else}
2023-08-23 11:11:53 +02:00
<div class="w-full flex flex-col">
<span class="subtle">{path.join(".")}</span>
<TagRenderingEditable {config} selectedElement={undefined} showQuestionIfUnknown={true} {state} {tags}/>
2023-06-16 02:36:11 +02:00
</div>
{/if}