Frontend addresses flows and dashboards by id: routes /flows/$flowId, /dashboards/$id and /view/$id, query keys, saves, lists, device pickers, search, brain and endpoint links and generated results dashboards go by id, while live values, issues, pauses and message names keep the key; tabs take the title from the document; creating uses POST and opens the issued id; the flow and dashboard panels show key and id with a copy button and a served HTTP or WebSocket node shows its hook URL under the flow id; specs create by POST and ids.spec.ts exercises issued ids

This commit is contained in:
2026-11-02 19:57:43 +01:00
parent fd637e0f1e
commit fa15522cb0
65 changed files with 1380 additions and 784 deletions
+15 -6
View File
@@ -133,9 +133,19 @@ async function captureRuns(page, dir) {
}).catch(() => null)
if (!answer?.ok) return null
const body = await answer.json()
return (body.data || [])
.map((one) => one.name)
.find((n) => n.endsWith("_results"))
const board = (body.data || []).find((one) => one.name.endsWith("_results"))
if (!board) return null
// Named after its flow's key; the runs screen filters by the flow's id.
const flows = await fetch(
`/api/v1/flows/?name=${board.name.replace(/_results$/, "")}`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
},
).then((reply) => (reply.ok ? reply.json() : { data: [] }))
const flow = flows.data?.[0]?.id
return flow ? { id: board.id, flow } : null
})
// A dashboard read against two runs: the same page a live run is watched
@@ -144,8 +154,7 @@ async function captureRuns(page, dir) {
// the table is filtered to its flow rather than read from the top. Another
// flow's run finishing later would otherwise photograph an empty grid.
if (results) {
const flow = results.replace(/_results$/, "")
await page.goto(`${APP_URL}/runs?flow=${flow}`, {
await page.goto(`${APP_URL}/runs?flow=${results.flow}`, {
waitUntil: "networkidle",
})
const ids = await page.getByTestId("run-link").evaluateAll((links) =>
@@ -155,7 +164,7 @@ async function captureRuns(page, dir) {
.filter(Boolean),
)
if (ids.length) {
await page.goto(`${APP_URL}/view/${results}?runs=${ids.join(",")}`, {
await page.goto(`${APP_URL}/view/${results.id}?runs=${ids.join(",")}`, {
waitUntil: "networkidle",
})
await page.waitForTimeout(2000)