Files
ss-tools/frontend/src/components/DynamicForm.svelte
busya cf7b3556f7 refactor(frontend): enforce semantic tokens + extract 3 Screen Models
Color tokens: 3658→0 violations across 186 .svelte/.svelte.ts files.
All raw Tailwind colors (bg-blue-*, text-gray-*, border-red-*, etc.)
replaced with semantic tokens from tailwind.config.js in 5 perl passes.

Model extraction (11→8 oversized pages):
- LLMReportModel.svelte.ts: LLM report page 413→221 lines
- DatasetDetailModel.svelte.ts: dataset detail page 416→218 lines
- DatasetsHubModel.svelte.ts: datasets hub page 468→246 lines

Tests: 14 assertions updated (color classes + model refs).
Build: 1 duplicate class:text-primary fix in ValidationTaskForm.
All 699/699 tests pass.
2026-06-02 17:58:36 +03:00

93 lines
3.1 KiB
Svelte
Executable File

<!-- #region DynamicForm [C:3] [TYPE Component] [SEMANTICS form, schema, dynamic, json-schema, generate] -->
<!-- @BRIEF Component component: components/DynamicForm.svelte -->
<!-- @LAYER UI -->
<!--
@SEMANTICS: form, schema, dynamic, json-schema
@PURPOSE: Generates a form dynamically based on a JSON schema.
@LAYER UI
@RELATION BINDS_TO -> [onsubmit callback]
@PROPS:
- schema: Object - JSON schema for the form.
@EVENTS:
- submit: Object - Dispatched when the form is submitted, containing the form data.
-->
<script lang="ts">
let {
schema,
onsubmit = () => {},
} = $props();
let formData = {};
// #region handleSubmit:Function [TYPE Function]
/**
* @purpose Emits submitted form data via callback prop.
* @pre formData contains user input.
* @post Parent callback receives formData snapshot.
*/
function handleSubmit() {
console.log("[DynamicForm][Action] Submitting form data.", { formData });
onsubmit(formData);
}
// #endregion handleSubmit:Function
// #region initializeForm:Function [TYPE Function]
/**
* @purpose Initialize form data with default values from the schema.
* @pre schema is provided and contains properties.
* @post formData is initialized with default values or empty strings.
*/
function initializeForm() {
if (schema && schema.properties) {
for (const key in schema.properties) {
formData[key] = schema.properties[key].default || '';
}
}
}
// #endregion initializeForm:Function
initializeForm();
</script>
<!-- [SECTION: TEMPLATE] -->
<form onsubmit={(event) => { event.preventDefault(); handleSubmit(); }} class="space-y-4">
{#if schema && schema.properties}
{#each Object.entries(schema.properties) as [key, prop]}
<div class="flex flex-col">
<label for={key} class="mb-1 font-semibold text-text">{prop.title || key}</label>
{#if prop.type === 'string'}
<input
type="text"
id={key}
bind:value={formData[key]}
placeholder={prop.description || ''}
class="p-2 border rounded-md"
/>
{:else if prop.type === 'number' || prop.type === 'integer'}
<input
type="number"
id={key}
bind:value={formData[key]}
placeholder={prop.description || ''}
class="p-2 border rounded-md"
/>
{:else if prop.type === 'boolean'}
<input
type="checkbox"
id={key}
bind:checked={formData[key]}
class="h-5 w-5"
/>
{/if}
</div>
{/each}
<button type="submit" class="w-full bg-success text-white p-2 rounded-md hover:bg-success">
Run Task
</button>
{/if}
</form>
<!-- [/SECTION] -->
<!-- #endregion DynamicForm -->