pocketbase/ui/src/components/records/fields/JsonField.svelte

81 lines
2.1 KiB
Svelte

<script>
import { onMount } from "svelte";
import tooltip from "@/actions/tooltip";
import CommonHelper from "@/utils/CommonHelper";
import Field from "@/components/base/Field.svelte";
export let field;
export let value = undefined;
let editorComponent;
let serialized = serialize(value);
$: if (value !== serialized?.trim()) {
serialized = serialize(value);
value = serialized;
}
$: isValid = isValidJson(serialized);
function serialize(val) {
return JSON.stringify(typeof val === "undefined" ? null : val, null, 2);
}
function isValidJson(val) {
try {
JSON.parse(val === "" ? null : val);
return true;
} catch (_) {}
return false;
}
onMount(async () => {
try {
editorComponent = (await import("@/components/base/CodeEditor.svelte")).default;
} catch (err) {
console.warn(err);
}
});
</script>
<Field class="form-field {field.required ? 'required' : ''}" name={field.name} let:uniqueId>
<label for={uniqueId}>
<i class={CommonHelper.getFieldTypeIcon(field.type)} />
<span class="txt">{field.name}</span>
<span
class="json-state"
use:tooltip={{ position: "left", text: isValid ? "Valid JSON" : "Invalid JSON" }}
>
{#if isValid}
<i class="ri-checkbox-circle-fill txt-success" />
{:else}
<i class="ri-error-warning-fill txt-danger" />
{/if}
</span>
</label>
{#if editorComponent}
<svelte:component
this={editorComponent}
id={uniqueId}
maxHeight="500"
language="json"
value={serialized}
on:change={(e) => {
serialized = e.detail;
value = serialized.trim();
}}
/>
{:else}
<input type="text" class="txt-mono" value="Loading..." disabled />
{/if}
</Field>
<style>
.json-state {
position: absolute;
right: 10px;
}
</style>