diff --git a/e2e/canvas.spec.ts b/e2e/canvas.spec.ts index 92a4b34..6032014 100644 --- a/e2e/canvas.spec.ts +++ b/e2e/canvas.spec.ts @@ -18,6 +18,13 @@ test('palette click creates a dashed draft and Apply posts the intent', async ({ await expect(page.locator('.resource-node.draft')).toHaveCount(0) }) +test('clicking a node shows its origin in the inspector source row', async ({ page }) => { + await page.goto('/') + await page.getByText('web', { exact: true }).click() + await expect(page.locator('.source-row')).toBeVisible() + await expect(page.locator('.source-row')).toContainText('terraform') +}) + test('context menu marks a node for removal', async ({ page }) => { await page.goto('/') await page.getByText('web', { exact: true }).click({ button: 'right' }) diff --git a/packages/ui/src/Inspector.tsx b/packages/ui/src/Inspector.tsx index d1cc692..b3c9e1b 100644 --- a/packages/ui/src/Inspector.tsx +++ b/packages/ui/src/Inspector.tsx @@ -1,4 +1,5 @@ import { useStore } from './store.js' +import { SourceIcon } from './icons.js' function Value({ v }: { v: unknown }) { if (v === undefined) return @@ -56,6 +57,12 @@ export function Inspector() { {node.status} {node.type} + {node.origin && ( +
+ + {node.origin} +
+ )}
{!(node.id in modifies) && ( diff --git a/packages/ui/src/icons.tsx b/packages/ui/src/icons.tsx index e43974a..53efc25 100644 --- a/packages/ui/src/icons.tsx +++ b/packages/ui/src/icons.tsx @@ -27,3 +27,24 @@ export function ResourceIcon({ type }: { type: string }) { ) } + +// Provider/origin glyph — distinct from ResourceIcon (which keys off the +// resource *type*). 'terraform' gets a layered-squares glyph evoking stacked +// state layers; any other provider id (e.g. a future live-scan origin) falls +// back to a generic database/cloud glyph. SVG only, never emoji. +export function SourceIcon({ origin }: { origin: string }) { + const isTerraform = origin === 'terraform' + return ( + + {isTerraform + ? <> + + + + : <> + + + } + + ) +} diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css index 5d2e9f9..551d20d 100644 --- a/packages/ui/src/styles.css +++ b/packages/ui/src/styles.css @@ -39,6 +39,8 @@ body { margin: 0; font-family: ui-sans-serif, system-ui, sans-serif; } .status-pill.status-update { background: #fef9c3; } .status-pill.status-delete { background: #fee2e2; } .status-pill.status-replace { background: #f3e8ff; } +.source-row { display: flex; align-items: center; gap: 6px; margin: 6px 0; + font-size: 11px; color: #64748b; } .inspector-actions { display: flex; gap: 6px; margin: 8px 0; } .inspector-actions button { font-size: 12px; padding: 4px 8px; border: 1px solid #e2e8f0; border-radius: 6px; background: #fff; cursor: pointer; }