Dashboard: public routes link to their public URL; drop editable behavior field
- Gateway route table: a public route's address now links to its public URL (green, with the tunnel icon) instead of the internal one. - Program detail: remove the editable `behavior` selector — behavior is a derived label now and drives no logic, so editing it was meaningless (the stored value is preserved on save via the manifest spread).
This commit is contained in:
@@ -89,30 +89,29 @@ export function GatewayPanel({ gateway, statuses }: GatewayPanelProps) {
|
|||||||
className="border-b border-[var(--border)] last:border-b-0 hover:bg-black/20 transition-colors"
|
className="border-b border-[var(--border)] last:border-b-0 hover:bg-black/20 transition-colors"
|
||||||
>
|
>
|
||||||
<td className="px-4 py-2 font-mono text-[var(--primary)]">
|
<td className="px-4 py-2 font-mono text-[var(--primary)]">
|
||||||
{url ? (
|
{(() => {
|
||||||
<a
|
// A public route links to its public URL; otherwise the
|
||||||
href={url}
|
// internal subdomain URL.
|
||||||
target="_blank"
|
const primaryUrl = route.public_url || url
|
||||||
rel="noopener noreferrer"
|
const isPublic = !!route.public_url
|
||||||
className="inline-flex items-center gap-1 hover:underline"
|
return primaryUrl ? (
|
||||||
>
|
<a
|
||||||
{route.address}
|
href={primaryUrl}
|
||||||
<ExternalLink size={11} className="opacity-60 shrink-0" />
|
target="_blank"
|
||||||
</a>
|
rel="noopener noreferrer"
|
||||||
) : (
|
title={primaryUrl}
|
||||||
route.address
|
className={`inline-flex items-center gap-1 hover:underline ${
|
||||||
)}
|
isPublic ? "text-green-500" : ""
|
||||||
{route.public_url && (
|
}`}
|
||||||
<a
|
>
|
||||||
href={route.public_url}
|
{isPublic && <Cable size={11} className="shrink-0" />}
|
||||||
target="_blank"
|
{route.address}
|
||||||
rel="noopener noreferrer"
|
<ExternalLink size={11} className="opacity-60 shrink-0" />
|
||||||
title={route.public_url}
|
</a>
|
||||||
className="ml-2 inline-flex items-center gap-1 text-[0.65rem] px-1.5 py-0.5 rounded bg-green-500/15 text-green-500 hover:bg-green-500/25"
|
) : (
|
||||||
>
|
route.address
|
||||||
<Cable size={10} /> public
|
)
|
||||||
</a>
|
})()}
|
||||||
)}
|
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">
|
||||||
<KindBadge kind={route.kind} />
|
<KindBadge kind={route.kind} />
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ export function ProgramFields({ program, onSave, onDelete }: Props) {
|
|||||||
|
|
||||||
const [description, setDescription] = useState((m.description as string) ?? "")
|
const [description, setDescription] = useState((m.description as string) ?? "")
|
||||||
const [source, setSource] = useState((m.source as string) ?? "")
|
const [source, setSource] = useState((m.source as string) ?? "")
|
||||||
const [behavior, setBehavior] = useState((m.behavior as string) ?? "")
|
|
||||||
const [stack, setStack] = useState((m.stack as string) ?? "")
|
const [stack, setStack] = useState((m.stack as string) ?? "")
|
||||||
const [version, setVersion] = useState((m.version as string) ?? "")
|
const [version, setVersion] = useState((m.version as string) ?? "")
|
||||||
const [repo, setRepo] = useState((m.repo as string) ?? "")
|
const [repo, setRepo] = useState((m.repo as string) ?? "")
|
||||||
@@ -56,7 +55,6 @@ export function ProgramFields({ program, onSave, onDelete }: Props) {
|
|||||||
delete config.id
|
delete config.id
|
||||||
config.description = description || undefined
|
config.description = description || undefined
|
||||||
config.source = source || undefined
|
config.source = source || undefined
|
||||||
config.behavior = behavior || undefined
|
|
||||||
config.stack = stack || undefined
|
config.stack = stack || undefined
|
||||||
config.version = version || undefined
|
config.version = version || undefined
|
||||||
config.repo = repo || undefined
|
config.repo = repo || undefined
|
||||||
@@ -99,17 +97,6 @@ export function ProgramFields({ program, onSave, onDelete }: Props) {
|
|||||||
placeholder="/data/repos/my-prog"
|
placeholder="/data/repos/my-prog"
|
||||||
hint="The working copy on disk. Castle runs dev verbs and builds here. Absolute path, or repo:<name> for castle's own programs."
|
hint="The working copy on disk. Castle runs dev verbs and builds here. Absolute path, or repo:<name> for castle's own programs."
|
||||||
/>
|
/>
|
||||||
<Field
|
|
||||||
label="Behavior"
|
|
||||||
hint="What this program is. tool = a CLI you invoke; daemon = a long-running server; frontend = a web UI. Drives how it activates and deploys."
|
|
||||||
>
|
|
||||||
<select value={behavior} onChange={(e) => setBehavior(e.target.value)} className={`w-48 ${SELECT}`}>
|
|
||||||
<option value="">(none)</option>
|
|
||||||
<option value="tool">tool</option>
|
|
||||||
<option value="daemon">daemon</option>
|
|
||||||
<option value="frontend">frontend</option>
|
|
||||||
</select>
|
|
||||||
</Field>
|
|
||||||
<Field
|
<Field
|
||||||
label="Stack"
|
label="Stack"
|
||||||
hint="Optional toolchain template — seeds default dev-verb commands and a scaffold for new code. Leave empty and declare commands below to wire in any repo."
|
hint="Optional toolchain template — seeds default dev-verb commands and a scaffold for new code. Leave empty and declare commands below to wire in any repo."
|
||||||
|
|||||||
Reference in New Issue
Block a user