Skip to content

Commit fcc250e

Browse files
authored
Merge pull request #490 from fractal-analytics-platform/sandbox-improvements
Improved JSON Schema Sandbox page
2 parents 921b341 + 2174bcf commit fcc250e

File tree

6 files changed

+315
-75
lines changed

6 files changed

+315
-75
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
*Note: Numbers like (\#123) point to closed Pull Requests on the fractal-web repository.*
22

3+
# Unreleased
4+
5+
* Improved JSON Schema Sandbox page (\#490).
6+
37
# 1.0.4
48

59
* Removed users management section from admin area v1 (\#485).

src/hooks.server.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { error } from '@sveltejs/kit';
44
export async function handle({ event, resolve }) {
55
console.log(`[${event.request.method}] - ${event.url.pathname}`);
66

7-
if (event.url.pathname == '/' || event.url.pathname.startsWith('/auth')) {
7+
if (
8+
event.url.pathname == '/' ||
9+
event.url.pathname.startsWith('/auth') ||
10+
event.url.pathname.startsWith('/sandbox/jsonschema')
11+
) {
812
console.log('Public page - No auth required');
913
return await resolve(event);
1014
}

src/lib/components/common/jschema/SchemaInput.svelte

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/routes/+layout.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
(!isSubPage($page.url.pathname, apiVersion) ||
1919
$page.url.pathname === '/v2/admin/jobs' ||
2020
$page.url.pathname === '/v1/admin/jobs') &&
21+
!$page.url.pathname.startsWith('/sandbox/jsonschema') &&
2122
selectedSection !== 'home';
2223
2324
/**
Lines changed: 140 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,148 @@
11
<script>
2-
import SchemaInput from '$lib/components/common/jschema/SchemaInput.svelte';
3-
import JSchema from '$lib/components/v1/workflow/JSchema.svelte';
2+
import { displayStandardErrorAlert } from '$lib/common/errors';
3+
import JSchema from '$lib/components/v2/workflow/JSchema.svelte';
4+
import example from './example.json';
45
56
let schema = undefined;
6-
let schemaData = undefined;
7+
let schemaData = {};
78
8-
let jsonSchema = '{"title": "TaskArguments", "type": "object", "properties": {"a": {"title": "A", "description": "This is the description of argument a", "default": 0, "type": "integer"}, "b": {"title": "B", "type": "string"}, "c": {"title": "C", "description": "A boolean field", "default": true, "type": "boolean"}, "d": {"title": "D", "description": "A list of numbers", "default": [0, 1, 2], "type": "array", "items": {"type": "integer"}}, "e": {"title": "E", "description": "A list of strings", "default": ["hello", "this", "test"], "type": "array", "items": {"type": "string"}}, "f": {"title": "F", "description": "A list of bools", "default": [true, false, false], "type": "array", "items": {"type": "boolean"}}, "g": {"title": "G", "description": "A nested list of integers", "default": [[1, 2], [3, 4], [5], [6]], "type": "array", "items": {"type": "array", "items": {"type": "integer"}}}, "h": {"title": "H", "description": "A nested list of strings", "default": [["this", "is"], ["a", "list"], ["of"], ["strings"]], "type": "array", "items": {"type": "array", "items": {"type": "string"}}}, "i": {"title": "I", "description": "A nested list of bools", "type": "array", "items": {"type": "array", "items": {"type": "boolean"}}}, "l": {"title": "L", "description": "An infinite nesting of lists", "default": [[[0]]], "type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "integer"}}}}, "m": {"title": "M", "description": "An infinite nesting of lists", "default": [[[0]]], "type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"$ref": "#/definitions/Argument"}}}}, "n": {"title": "N", "type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"$ref": "#/definitions/Argument"}}}}, "obj1": {"$ref": "#/definitions/Argument"}, "obj2": {"$ref": "#/definitions/Argument"}, "obj3": {"title": "Obj3", "description": "A custom object schema", "allOf": [{"$ref": "#/definitions/Argument"}]}, "obj4": {"title": "Obj4", "description": "A list of arguments", "default": [], "type": "array", "items": {"$ref": "#/definitions/Argument"}}}, "required": ["i", "n", "obj2", "obj3"], "definitions": {"SubArgument": {"title": "SubArgument", "type": "object", "properties": {"subA": {"title": "Suba", "description": "A sub argument property", "default": 0, "type": "integer"}}}, "Argument": {"title": "Argument", "type": "object", "properties": {"a": {"title": "A", "description": "A integer property of an object", "default": 3, "type": "integer"}, "b": {"title": "B", "description": "A string property of an object", "default": "hello", "type": "string"}, "c": {"title": "C", "type": "boolean"}, "d": {"title": "D", "default": [1, 2, 3], "type": "array", "items": {"type": "integer"}}, "e": {"$ref": "#/definitions/SubArgument"}}, "required": ["c", "e"]}}}';
9-
jsonSchema = '';
9+
let jsonSchemaString = '';
10+
let jsonDataString = '{}';
1011
11-
</script>
12+
let jsonSchemaError = '';
13+
let dataError = '';
14+
15+
let legacy = false;
16+
17+
/** @type {JSchema|undefined} */
18+
let jschemaComponent = undefined;
19+
20+
function handleJsonSchemaStringChanged() {
21+
jsonSchemaError = '';
22+
if (jsonSchemaString === '') {
23+
schema = undefined;
24+
return;
25+
}
26+
try {
27+
schema = JSON.parse(jsonSchemaString);
28+
} catch (err) {
29+
schema = undefined;
30+
jsonSchemaError = 'Invalid JSON';
31+
}
32+
}
33+
34+
function handleDataStringChanged() {
35+
dataError = '';
36+
dataError = '';
37+
try {
38+
schemaData = JSON.parse(jsonDataString);
39+
} catch (err) {
40+
schemaData = {};
41+
dataError = 'Invalid JSON';
42+
}
43+
}
1244
13-
<h1 class="fw-light">Sandbox page for jsonschema</h1>
45+
function forceRedraw() {
46+
handleJsonSchemaStringChanged();
47+
handleDataStringChanged();
48+
}
49+
50+
/** @type {import('$lib/components/common/StandardErrorAlert.svelte').default|undefined} */
51+
let errorAlert;
52+
let valid = false;
53+
54+
function validate() {
55+
try {
56+
errorAlert?.hide();
57+
valid = false;
58+
jschemaComponent?.validateArguments();
59+
valid = true;
60+
} catch (err) {
61+
errorAlert = displayStandardErrorAlert(err, `errorAlert-form`);
62+
}
63+
}
64+
65+
function loadExample() {
66+
jsonSchemaString = JSON.stringify(example, null, 2);
67+
handleJsonSchemaStringChanged();
68+
}
69+
70+
function loadCurrentData() {
71+
if (!jschemaComponent) {
72+
return;
73+
}
74+
jsonDataString = JSON.stringify(jschemaComponent.getArguments(), null, 2);
75+
}
76+
</script>
1477
15-
<SchemaInput {jsonSchema} bind:parsedSchema={schema} bind:parsedData={schemaData}></SchemaInput>
78+
<h1 class="fw-light">Sandbox page for JSON Schema</h1>
79+
<p>This is a test page for the JSON Schema component</p>
1680
17-
<JSchema
18-
{schema}
19-
{schemaData}
20-
></JSchema>
81+
<div class="row">
82+
<div class="col-lg-6 mt-3">
83+
<div class="row">
84+
<div class="col">
85+
<button class="btn btn-outline-primary float-end" on:click={loadExample}>
86+
Load example
87+
</button>
88+
<div class="form-check form-switch">
89+
<input
90+
class="form-check-input"
91+
type="checkbox"
92+
role="switch"
93+
id="legacy"
94+
bind:checked={legacy}
95+
on:change={forceRedraw}
96+
/>
97+
<label class="form-check-label" for="legacy"> Legacy</label>
98+
</div>
99+
<div class="form-text">Changes the set of ignored properties (v1 or v2)</div>
100+
</div>
101+
</div>
102+
<div class="row has-validation mt-3 mb-2">
103+
<div class="col">
104+
<label for="jschema">JSON Schema</label>
105+
<textarea
106+
id="jschema"
107+
class="form-control"
108+
bind:value={jsonSchemaString}
109+
on:input={handleJsonSchemaStringChanged}
110+
class:is-invalid={jsonSchemaError}
111+
rows="10"
112+
/>
113+
<span class="invalid-feedback">{jsonSchemaError}</span>
114+
</div>
115+
</div>
116+
<div class="row has-validation mt-3 mb-2">
117+
<div class="col">
118+
<label for="jdata">Initial JSON data</label>
119+
<textarea
120+
id="jdata"
121+
class="form-control"
122+
bind:value={jsonDataString}
123+
on:input={handleDataStringChanged}
124+
class:is-invalid={dataError}
125+
rows="10"
126+
/>
127+
<span class="invalid-feedback">{dataError}</span>
128+
</div>
129+
</div>
130+
<div class="row mt-3 mb-2">
131+
<div class="col">
132+
<div id="errorAlert-form" />
133+
{#if valid}
134+
<div class="alert alert-success">Data is valid</div>
135+
{/if}
136+
<button class="btn btn-outline-primary float-end" on:click={loadCurrentData}>
137+
Load current data
138+
</button>
139+
<button class="btn btn-primary" on:click={validate}>Validate</button>
140+
</div>
141+
</div>
142+
</div>
143+
<div class="col-lg-6 mt-3">
144+
{#if schema}
145+
<JSchema {schema} {schemaData} {legacy} bind:this={jschemaComponent} />
146+
{/if}
147+
</div>
148+
</div>

0 commit comments

Comments
 (0)