Flow canvas draws panel I/O ports as panel:<id>:<port> endpoints that open their panel in the Panels dialog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WgBfkm4rCmtd1T4vHWjEPx
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useMutation, useQuery } from "@tanstack/react-query"
|
||||
import { Plus, Trash2, X } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import {
|
||||
type ApiError,
|
||||
@@ -72,7 +72,7 @@ const objectOnly = (value: unknown) =>
|
||||
* publish, so it lives in a dialog over the dashboards list instead of a page
|
||||
* of its own. Every change saves as it is made — there is no form to submit.
|
||||
*/
|
||||
export function PanelsDialog() {
|
||||
export function PanelsDialog({ focus }: { focus?: string } = {}) {
|
||||
const { data: config } = useQuery(panelsQueryOptions())
|
||||
const { data: dashboards } = useQuery(dashboardsQueryOptions())
|
||||
const { user } = useAuth()
|
||||
@@ -125,6 +125,15 @@ export function PanelsDialog() {
|
||||
const newId = slugify(name)
|
||||
const taken = panels.some((panel) => panel.id === newId)
|
||||
|
||||
// Arriving about one panel, from its port on a flow canvas, lands on it.
|
||||
const focusLoaded = Boolean(config) && Boolean(focus)
|
||||
useEffect(() => {
|
||||
if (!focusLoaded) return
|
||||
document
|
||||
.querySelector(`[data-testid="panel-${focus}"]`)
|
||||
?.scrollIntoView({ block: "start" })
|
||||
}, [focusLoaded, focus])
|
||||
|
||||
return (
|
||||
<DialogContent className="max-h-[80vh] overflow-y-auto sm:max-w-lg">
|
||||
<DialogHeader>
|
||||
@@ -146,6 +155,7 @@ export function PanelsDialog() {
|
||||
<PanelRow
|
||||
key={panel.id}
|
||||
panel={panel}
|
||||
focused={panel.id === focus}
|
||||
host={host}
|
||||
remoteHost={remoteHost}
|
||||
canEdit={canEdit}
|
||||
@@ -211,6 +221,7 @@ export function PanelsDialog() {
|
||||
|
||||
function PanelRow({
|
||||
panel,
|
||||
focused,
|
||||
host,
|
||||
remoteHost,
|
||||
canEdit,
|
||||
@@ -219,6 +230,8 @@ function PanelRow({
|
||||
onRemove,
|
||||
}: {
|
||||
panel: PanelDef
|
||||
/** The one a link arrived about, marked so it is found at a glance. */
|
||||
focused: boolean
|
||||
/** Where this instance answers, as it knows itself. */
|
||||
host: string
|
||||
/** Where the portal serves this instance, when it is enrolled. */
|
||||
@@ -288,7 +301,14 @@ function PanelRow({
|
||||
: `Remove ${panel.id}`
|
||||
|
||||
return (
|
||||
<div className="grid gap-3" data-testid={`panel-${panel.id}`}>
|
||||
<div
|
||||
className={cn(
|
||||
"grid scroll-mt-2 gap-3",
|
||||
// An outline rather than a border, so the row does not shift.
|
||||
focused && "rounded-md outline-2 outline-offset-4 outline-primary/40",
|
||||
)}
|
||||
data-testid={`panel-${panel.id}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input
|
||||
value={panel.title}
|
||||
|
||||
Reference in New Issue
Block a user