Add component name formatters and grid-link navigation
Templates section: - Define JS formatter functions per template (e.g. resistor, capacitor) - First non-null result from any formatter is used as display name - Live preview in template editor against first component - Display names applied in component list, detail view, and inventory rows Grid navigation: - Grid-type inventory entries in component detail view show a '⊞' button to navigate directly to that grid's viewer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
33
server.mjs
33
server.mjs
@@ -15,6 +15,7 @@ import {
|
||||
list_grid_drafts, get_grid_draft, set_grid_draft, delete_grid_draft,
|
||||
list_source_images, get_source_image, add_source_image, delete_source_image,
|
||||
list_grid_images, get_grid_image, set_grid_image, delete_grid_image,
|
||||
list_component_templates, get_component_template, set_component_template, delete_component_template,
|
||||
} from './lib/storage.mjs';
|
||||
|
||||
mkdirSync('./data/images', { recursive: true });
|
||||
@@ -423,6 +424,38 @@ app.delete('/api/grid-images/:id', (req, res) => {
|
||||
ok(res);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Component templates
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
app.get('/api/component-templates', (req, res) => {
|
||||
ok(res, { templates: list_component_templates() });
|
||||
});
|
||||
|
||||
app.post('/api/component-templates', (req, res) => {
|
||||
const { name, formatter } = req.body;
|
||||
if (!name) return fail(res, 'name is required');
|
||||
const tmpl = { id: generate_id(), name, formatter: formatter ?? '', created_at: Date.now(), updated_at: Date.now() };
|
||||
set_component_template(tmpl);
|
||||
ok(res, { template: tmpl });
|
||||
});
|
||||
|
||||
app.put('/api/component-templates/:id', (req, res) => {
|
||||
const existing = get_component_template(req.params.id);
|
||||
if (!existing) return fail(res, 'not found', 404);
|
||||
const updated = { ...existing, updated_at: Date.now() };
|
||||
if (req.body.name !== undefined) updated.name = req.body.name;
|
||||
if (req.body.formatter !== undefined) updated.formatter = req.body.formatter;
|
||||
set_component_template(updated);
|
||||
ok(res, { template: updated });
|
||||
});
|
||||
|
||||
app.delete('/api/component-templates/:id', (req, res) => {
|
||||
if (!get_component_template(req.params.id)) return fail(res, 'not found', 404);
|
||||
delete_component_template(req.params.id);
|
||||
ok(res);
|
||||
});
|
||||
|
||||
// SPA fallback — serve index.html for any non-API, non-asset path
|
||||
const INDEX_HTML = new URL('./public/index.html', import.meta.url).pathname;
|
||||
app.get('/{*path}', (req, res) => res.sendFile(INDEX_HTML));
|
||||
|
||||
Reference in New Issue
Block a user