Add test data box to template editor for live preview

Enter a JS snippet returning a fields object (e.g. return { resistance: '10k' })
to preview the formatter against synthetic data instead of the first real component.
Both the formatter and test data textareas update the preview on input.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 00:18:26 +00:00
parent 896b6fcb39
commit b66b2f95d3
2 changed files with 29 additions and 6 deletions

View File

@@ -584,13 +584,15 @@ function open_template_dialog(tmpl = null) {
} catch (err) { alert(`Error: ${err.message}`); } } catch (err) { alert(`Error: ${err.message}`); }
}); });
// Live preview against first component // Live preview
qs(template_dialog, '#tmpl-formatter').addEventListener('input', update_tmpl_preview); qs(template_dialog, '#tmpl-formatter').addEventListener('input', update_tmpl_preview);
qs(template_dialog, '#tmpl-test-data').addEventListener('input', update_tmpl_preview);
} }
qs(template_dialog, '.dialog-title').textContent = tmpl ? 'Edit template' : 'Add template'; qs(template_dialog, '.dialog-title').textContent = tmpl ? 'Edit template' : 'Add template';
qs(template_dialog, '#tmpl-name').value = tmpl?.name ?? ''; qs(template_dialog, '#tmpl-name').value = tmpl?.name ?? '';
qs(template_dialog, '#tmpl-formatter').value = tmpl?.formatter ?? ''; qs(template_dialog, '#tmpl-formatter').value = tmpl?.formatter ?? '';
qs(template_dialog, '#tmpl-test-data').value = '';
update_tmpl_preview(); update_tmpl_preview();
template_dialog_callback = async () => { template_dialog_callback = async () => {
@@ -617,15 +619,32 @@ function update_tmpl_preview() {
const preview_el = qs(template_dialog, '#tmpl-preview'); const preview_el = qs(template_dialog, '#tmpl-preview');
const formatter_str = qs(template_dialog, '#tmpl-formatter').value.trim(); const formatter_str = qs(template_dialog, '#tmpl-formatter').value.trim();
if (!formatter_str) { preview_el.textContent = '—'; return; } if (!formatter_str) { preview_el.textContent = '—'; return; }
const sample = all_components[0];
if (!sample) { preview_el.textContent = '(no components to preview)'; return; } // Build the component to preview against
let preview_comp;
const test_data_str = qs(template_dialog, '#tmpl-test-data').value.trim();
if (test_data_str) {
try {
// eslint-disable-next-line no-new-func
const test_fields = new Function(test_data_str)();
preview_comp = { name: '(test)', fields: test_fields ?? {} };
} catch (err) {
preview_el.textContent = `Test data error: ${err.message}`;
return;
}
} else {
const sample = all_components[0];
if (!sample) { preview_el.textContent = '(no components to preview)'; return; }
preview_comp = named_fields_comp(sample);
}
try { try {
// eslint-disable-next-line no-new-func // eslint-disable-next-line no-new-func
const fn = new Function('c', `"use strict"; return (${formatter_str})(c);`); const fn = new Function('c', `"use strict"; return (${formatter_str})(c);`);
const result = fn(named_fields_comp(sample)); const result = fn(preview_comp);
preview_el.textContent = result != null ? String(result) : `null — falls back to "${sample.name}"`; preview_el.textContent = result != null ? String(result) : `null — falls back to "${preview_comp.name}"`;
} catch (err) { } catch (err) {
preview_el.textContent = `Error: ${err.message}`; preview_el.textContent = `Formatter error: ${err.message}`;
} }
} }

View File

@@ -184,6 +184,10 @@
<label for="tmpl-formatter">Formatter <span class="label-hint">(JS arrow function, return null to skip)</span></label> <label for="tmpl-formatter">Formatter <span class="label-hint">(JS arrow function, return null to skip)</span></label>
<textarea id="tmpl-formatter" rows="8" class="code-input" placeholder="(c) => {&#10; const r = c.fields?.resistance;&#10; if (!r) return null;&#10; return `Resistor ${r}`;&#10;}"></textarea> <textarea id="tmpl-formatter" rows="8" class="code-input" placeholder="(c) => {&#10; const r = c.fields?.resistance;&#10; if (!r) return null;&#10; return `Resistor ${r}`;&#10;}"></textarea>
</div> </div>
<div class="form-row">
<label for="tmpl-test-data">Test data <span class="label-hint">(optional — return a fields object to preview against)</span></label>
<textarea id="tmpl-test-data" rows="3" class="code-input" placeholder="return { resistance: '10k', mounting_tech: 'PTH' }"></textarea>
</div>
<div class="tmpl-preview-row"> <div class="tmpl-preview-row">
<span class="label-hint">Preview:</span> <span class="label-hint">Preview:</span>
<span id="tmpl-preview" class="tmpl-preview-value"></span> <span id="tmpl-preview" class="tmpl-preview-value"></span>