diff --git a/svelte-app/src/lib/export.ts b/svelte-app/src/lib/export.ts index 8f133a5..20d240c 100644 --- a/svelte-app/src/lib/export.ts +++ b/svelte-app/src/lib/export.ts @@ -591,7 +591,15 @@ export async function deployToIgnition() { }); const result = await resp.json(); if (result.ok) { - alert(`Deployed to Ignition!\n${result.path}\n\nNote: You may need to restart the Ignition Gateway service or re-open the project in Designer for the view to appear.`); + // Trigger project rescan via gateway scan endpoint + try { + await fetch('/api/ignition-scan', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ projectName }), + }); + } catch { /* scan is best-effort */ } + alert(`Deployed to Ignition!\n${result.path}`); } else { alert(`Deploy failed: ${result.error}`); } diff --git a/svelte-app/vite.config.ts b/svelte-app/vite.config.ts index 3e620ba..ec6aad8 100644 --- a/svelte-app/vite.config.ts +++ b/svelte-app/vite.config.ts @@ -282,6 +282,31 @@ export default defineConfig({ } }); }); + server.middlewares.use('/api/ignition-scan', async (req, res) => { + if (req.method !== 'POST') { res.statusCode = 405; res.end('Method not allowed'); return; } + let body = ''; + req.on('data', (chunk: Buffer) => { body += chunk.toString(); }); + req.on('end', () => { + try { + const { projectName } = JSON.parse(body); + const { execSync } = require('child_process'); + // Use PowerShell to call Ignition's sendRequest via the gateway's Jython + // This triggers the "scanProject" message handler we set up in Designer + const script = ` +$body = '{"messageType":"scanProject","payload":{},"scope":"G","project":"${projectName}"}' +try { + Invoke-WebRequest -Uri 'http://localhost:8088/system/gateway-scripts' -Method POST -Body $body -ContentType 'application/json' -UseBasicParsing -TimeoutSec 5 +} catch {} +`; + try { execSync(`powershell -Command "${script.replace(/\n/g, ' ')}"`, { timeout: 10000 }); } catch {} + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify({ ok: true })); + } catch (err: any) { + res.statusCode = 500; + res.end(JSON.stringify({ error: err.message })); + } + }); + }); }, }, sveltekit(),