swarm-ui: show agent panel read failures as text and keep loaded data
Inference, resource caps and linked accounts showed a failed read as a badge with the reason in a hover title, which keyboard and touch users cannot read. They now use ApiErrorPanel, and a list that already loaded stays on screen under a failed refetch.
This commit is contained in:
parent
ac0bed47e9
commit
e727774dc8
4 changed files with 38 additions and 29 deletions
|
|
@ -435,7 +435,10 @@ name that already holds an account; delete that account first to replace it.
|
||||||
The agent's detail panel lists its linked accounts under **accounts**, one row
|
The agent's detail panel lists its linked accounts under **accounts**, one row
|
||||||
per account: kind, name and host. Opening an agent makes one request,
|
per account: kind, name and host. Opening an agent makes one request,
|
||||||
`GET /api/hives/{hive}/agents/{agent}/linked-accounts`, which returns every
|
`GET /api/hives/{hive}/agents/{agent}/linked-accounts`, which returns every
|
||||||
account of that agent as names and hosts and never a credential.
|
account of that agent as names and hosts and never a credential. When the panel
|
||||||
|
fails to read the accounts, the inference settings or the resource caps, it
|
||||||
|
shows the reason as text. A list the panel already loaded stays on screen
|
||||||
|
beneath the error.
|
||||||
|
|
||||||
| kind | one row per | name | host |
|
| kind | one row per | name | host |
|
||||||
| ------- | ------------------------------------------- | ----------- | ------------------------ |
|
| ------- | ------------------------------------------- | ----------- | ------------------------ |
|
||||||
|
|
|
||||||
|
|
@ -205,21 +205,23 @@ export function AgentInference({ agent }: { agent: string }) {
|
||||||
};
|
};
|
||||||
}, [agent, reload]);
|
}, [agent, reload]);
|
||||||
|
|
||||||
if (error) {
|
// Shown as text, not a hover title. Settings already loaded stay under a
|
||||||
return (
|
// failed refetch, so a save that worked is not hidden by a read that did not.
|
||||||
<Badge
|
const errorPanel = error ? (
|
||||||
tone="negative"
|
<ApiErrorPanel
|
||||||
value="inference unavailable"
|
context="reading the inference settings failed"
|
||||||
title={error.detail ?? "reading the inference settings failed"}
|
problem={error}
|
||||||
/>
|
/>
|
||||||
);
|
) : null;
|
||||||
|
if (view === null) {
|
||||||
|
return errorPanel ?? <span class="ui-agent-inference-muted">…</span>;
|
||||||
}
|
}
|
||||||
if (view === null) return <span class="ui-agent-inference-muted">…</span>;
|
|
||||||
|
|
||||||
const { configured, effective } = view;
|
const { configured, effective } = view;
|
||||||
const swarmModels = configured?.subagent_models ?? [];
|
const swarmModels = configured?.subagent_models ?? [];
|
||||||
return (
|
return (
|
||||||
<div class="ui-agent-inference">
|
<div class="ui-agent-inference">
|
||||||
|
{errorPanel}
|
||||||
<ul class="ui-agent-inference-list">
|
<ul class="ui-agent-inference-list">
|
||||||
<li>
|
<li>
|
||||||
{effective ? (
|
{effective ? (
|
||||||
|
|
|
||||||
|
|
@ -114,19 +114,18 @@ export function AgentLimits({ agent }: { agent: string }) {
|
||||||
};
|
};
|
||||||
}, [agent, reload]);
|
}, [agent, reload]);
|
||||||
|
|
||||||
if (error) {
|
// Shown as text, not a hover title. Caps already loaded stay under a
|
||||||
return (
|
// failed refetch, so a save that worked is not hidden by a read that did not.
|
||||||
<Badge
|
const errorPanel = error ? (
|
||||||
tone="negative"
|
<ApiErrorPanel context="reading the resource caps failed" problem={error} />
|
||||||
value="resource caps unavailable"
|
) : null;
|
||||||
title={error.detail ?? "reading the resource caps failed"}
|
if (caps === null) {
|
||||||
/>
|
return errorPanel ?? <span class="ui-agent-limits-muted">…</span>;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (caps === null) return <span class="ui-agent-limits-muted">…</span>;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="ui-agent-limits">
|
<div class="ui-agent-limits">
|
||||||
|
{errorPanel}
|
||||||
<ul class="ui-agent-limits-list">
|
<ul class="ui-agent-limits-list">
|
||||||
<li>
|
<li>
|
||||||
<Badge label="cpu quota" value={caps.cpu_quota ?? HIVE_DECIDES} />
|
<Badge label="cpu quota" value={caps.cpu_quota ?? HIVE_DECIDES} />
|
||||||
|
|
|
||||||
|
|
@ -156,21 +156,26 @@ export function LinkedAccounts({
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (error) {
|
// Shown as text, not a hover title. A list already loaded stays under a
|
||||||
return (
|
// failed refetch, so a link or delete that worked is not hidden by a read
|
||||||
<Badge
|
// that did not.
|
||||||
tone="negative"
|
const errorPanel = error ? (
|
||||||
value="accounts unavailable"
|
<ApiErrorPanel context="listing linked accounts failed" problem={error} />
|
||||||
title={error.detail ?? "listing linked accounts failed"}
|
) : null;
|
||||||
/>
|
if (accounts === null) {
|
||||||
);
|
return errorPanel ?? <span class="ui-linked-accounts-muted">…</span>;
|
||||||
}
|
}
|
||||||
if (accounts === null) return <span class="ui-linked-accounts-muted">…</span>;
|
|
||||||
if (accounts.length === 0) {
|
if (accounts.length === 0) {
|
||||||
return <span class="ui-linked-accounts-muted">none linked</span>;
|
return (
|
||||||
|
<>
|
||||||
|
{errorPanel}
|
||||||
|
<span class="ui-linked-accounts-muted">none linked</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{errorPanel}
|
||||||
<ul class="ui-linked-accounts">
|
<ul class="ui-linked-accounts">
|
||||||
{accounts.map((a) => (
|
{accounts.map((a) => (
|
||||||
<li key={`${a.kind}/${a.name}`}>
|
<li key={`${a.kind}/${a.name}`}>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue