feat: choose probe/agent links from the admin, fix the overview popover [CI]

The panel decides which probes link to which agents (probes dial out): an
auto-link setting plus per-pair manual overrides with a link matrix in the
admin, and the hovered overview card is lifted above its neighbours.
This commit is contained in:
justme committed 2026-10-06 23:22:45 +08:00
1 parent d449e50791
commit 6e945657c1
32 files changed
+788 -39

No files matched your search

+1
View File
@@ -83,5 +83,6 @@ export const api = {
get: <T>(path: string, query?: Query, init?: RequestInit) => request<T>('GET', withQuery(path, query), undefined, init),
post: <T>(path: string, body?: unknown) => request<T>('POST', path, body ?? {}),
patch: <T>(path: string, body: unknown) => request<T>('PATCH', path, body),
put: <T>(path: string, body: unknown) => request<T>('PUT', path, body),
del: <T>(path: string) => request<T>('DELETE', path),
}
+151
View File
@@ -851,6 +851,40 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/admin/links": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Every probe/agent pair: whether it is linked, the manual override and whether it is connected */
get: operations["links_list"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/admin/links/{probe_id}/{agent_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
/** Force a link on or off, or give it back to the automatic setting (enabled: null) */
put: operations["links_set"];
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/healthz": {
parameters: {
query?: never;
@@ -1250,6 +1284,19 @@ export interface components {
kinds: string[];
last_test: null | components["schemas"]["TestSummaryDto"];
};
LinkDto: {
probe_id: string;
probe_name: string;
agent_id: string;
agent_name: string;
linked: boolean;
override: null | boolean;
connected: boolean;
};
LinkMatrixDto: {
auto_link: boolean;
items: components["schemas"]["LinkDto"][];
};
LocalLimitsDto: {
/** Format: double */
max_total_mbps: number | string;
@@ -1594,6 +1641,9 @@ export interface components {
[key: string]: string;
};
};
SetLinkRequest: {
enabled: null | boolean;
};
SettingDto: {
key: string;
type: string;
@@ -4760,6 +4810,107 @@ export interface operations {
};
};
};
links_list: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LinkMatrixDto"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
links_set: {
parameters: {
query?: never;
header?: never;
path: {
probe_id: string;
agent_id: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["SetLinkRequest"];
};
};
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LinkDto"];
};
};
/** @description Bad Request */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
health_get: {
parameters: {
query?: never;
+2
View File
@@ -19,6 +19,8 @@ export type BuildInfoDto = Narrow<S['BuildInfoDto']>
export type NodeBuildDto = Narrow<S['NodeBuildDto']>
export type NodeUpdateDto = Narrow<S['NodeUpdateDto']>
export type ReleaseDto = Narrow<S['ReleaseDto']>
export type LinkDto = Narrow<S['LinkDto']>
export type LinkMatrixDto = Narrow<S['LinkMatrixDto']>
export type OverviewDto = Narrow<S['OverviewDto']>
export type OverviewLineDto = Narrow<S['OverviewLineDto']>
export type SeriesDto = Narrow<S['SeriesDto']>