feat(proxies): per-row Triggers deep-link to /apps/[id]#bindings
The proxies page now exposes the trigger bindings for each routed
workload via a per-row action chip. Resolves the explicit "what's
next" call-out in WORKLOAD_REFACTOR_TODO under Priority 3 polish.
- Added id="bindings" to the existing trigger bindings <section> on
/apps/[id]/+page.svelte so URL fragments resolve to the panel.
- New triggersHref(route) helper in /proxies that builds
/apps/{workload_id}#bindings; code-pointer comment explains the
back-compat naming (ProxyRoute.project_id is actually the workload
ID — see internal/store/models.go:110-113), so a future contributor
doesn't trip on the mismatch and rip the helper out.
- New right-aligned "Actions" column with a button-shaped link;
defensive — falls back to — when project_id is absent.
- Three new i18n keys under proxies.* (actions, viewTriggers,
viewTriggersTitle) mirrored across EN + RU. Key parity now 1512
each.
No backend change needed; ListProxyRoutes already selects w.id into
ProxyRoute.project_id. Workload-aware batch endpoints (showing
trigger counts inline) were deliberately out of scope for this
half-turn — flagged as a future enhancement only if users want
inline counts.
Verification: svelte-check 0 errors + 3 pre-existing warnings in
TagCombobox; go build + go test ./... all green across 20 packages.
This commit is contained in:
@@ -392,7 +392,10 @@
|
||||
"noMatch": "No routes match your search.",
|
||||
"loadFailed": "Failed to load proxy routes",
|
||||
"route": "route",
|
||||
"routes": "routes"
|
||||
"routes": "routes",
|
||||
"actions": "Actions",
|
||||
"viewTriggers": "Triggers",
|
||||
"viewTriggersTitle": "View trigger bindings for this workload"
|
||||
},
|
||||
"common": {
|
||||
"cancel": "Cancel",
|
||||
|
||||
@@ -392,7 +392,10 @@
|
||||
"noMatch": "Нет маршрутов, соответствующих поиску.",
|
||||
"loadFailed": "Не удалось загрузить прокси-маршруты",
|
||||
"route": "маршрут",
|
||||
"routes": "маршрутов"
|
||||
"routes": "маршрутов",
|
||||
"actions": "Действия",
|
||||
"viewTriggers": "Триггеры",
|
||||
"viewTriggersTitle": "Посмотреть привязки триггеров для этой нагрузки"
|
||||
},
|
||||
"common": {
|
||||
"cancel": "Отмена",
|
||||
|
||||
@@ -2168,7 +2168,7 @@
|
||||
"Add trigger" opens a modal with two tabs: inline-create
|
||||
a new trigger record, or pick an existing one. -->
|
||||
{#if !editing}
|
||||
<section class="panel" aria-labelledby="trig-bindings-heading">
|
||||
<section id="bindings" class="panel" aria-labelledby="trig-bindings-heading">
|
||||
<header class="panel-head split bindings-head">
|
||||
<div class="bindings-head-left">
|
||||
<h2 class="panel-title" id="trig-bindings-heading">
|
||||
|
||||
@@ -57,6 +57,14 @@
|
||||
return q ? `/containers?q=${q}` : '/containers';
|
||||
}
|
||||
|
||||
// `project_id` on a ProxyRoute is actually the workload ID
|
||||
// (back-compat naming — see internal/store/models.go:110-113). Anchor
|
||||
// at the bindings section on /apps/[id] so the operator lands directly
|
||||
// on the trigger list for this workload.
|
||||
function triggersHref(route: ProxyRoute): string {
|
||||
return route.project_id ? `/apps/${route.project_id}#bindings` : '/triggers';
|
||||
}
|
||||
|
||||
async function loadRoutes() {
|
||||
loading = true;
|
||||
try {
|
||||
@@ -136,6 +144,7 @@
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('proxies.tag')}</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('proxies.port')}</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('proxies.status')}</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('proxies.actions')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--border-secondary)]">
|
||||
@@ -172,6 +181,19 @@
|
||||
<td class="px-4 py-3">
|
||||
<StatusBadge status={route.status} />
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
{#if route.project_id}
|
||||
<a
|
||||
href={triggersHref(route)}
|
||||
title={$t('proxies.viewTriggersTitle')}
|
||||
class="inline-flex items-center rounded-md border border-[var(--border-primary)] bg-[var(--surface-card)] px-2.5 py-1 text-xs font-medium text-[var(--text-secondary)] transition-colors hover:border-[var(--color-brand-500)] hover:text-[var(--text-primary)]"
|
||||
>
|
||||
{$t('proxies.viewTriggers')}
|
||||
</a>
|
||||
{:else}
|
||||
<span class="text-xs text-[var(--text-tertiary)]">—</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user