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:
@@ -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}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) => { const r = c.fields?.resistance; if (!r) return null; return `Resistor ${r}`; }"></textarea>
|
<textarea id="tmpl-formatter" rows="8" class="code-input" placeholder="(c) => { const r = c.fields?.resistance; if (!r) return null; return `Resistor ${r}`; }"></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>
|
||||||
|
|||||||
Reference in New Issue
Block a user