mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-03 12:42:43 +00:00
Move Install agent attention from global callout to row-level chips
The 'Install agents' recommendation rendered above the table as a secondary button + paragraph: 'Install Pulse Agent on pbs-docker when you want node-local telemetry...'. The user had to read the paragraph and then map the named system back to the table row. Surface the same attention directly on the affected row instead. For systems with API coverage but no Pulse Agent, render a small '+ Install agent' chip in the actions column above the Manage button. The chip routes to the same agent-install picker the global button used. Hide the global recommendation card when its kind is 'agent' so the two affordances don't duplicate each other. Other recommendation states (discovery scan, coverage coherent, add infrastructure on empty) still render as before.
This commit is contained in:
@@ -610,7 +610,17 @@ export const InfrastructureSourceManager: Component<InfrastructureSourceManagerP
|
||||
)}
|
||||
</For>
|
||||
</dl>
|
||||
<Show when={!props.readOnly && Boolean(setupConfidenceAction().onClick)}>
|
||||
{/* Recommendation button hides for the apiOnly install-agents case
|
||||
because row-level install-agent chips now surface the same
|
||||
attention per-system. Other recommendations (discovery scan,
|
||||
coverage coherent, add infrastructure) still render here. */}
|
||||
<Show
|
||||
when={
|
||||
!props.readOnly &&
|
||||
Boolean(setupConfidenceAction().onClick) &&
|
||||
setupConfidenceAction().kind !== 'agent'
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setupConfidenceAction().onClick?.()}
|
||||
@@ -623,7 +633,9 @@ export const InfrastructureSourceManager: Component<InfrastructureSourceManagerP
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<p class="mt-3 text-xs leading-5 text-muted">{setupConfidenceAction().detail}</p>
|
||||
<Show when={setupConfidenceAction().kind !== 'agent'}>
|
||||
<p class="mt-3 text-xs leading-5 text-muted">{setupConfidenceAction().detail}</p>
|
||||
</Show>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -849,13 +861,37 @@ export const InfrastructureSourceManager: Component<InfrastructureSourceManagerP
|
||||
<span class="text-xs text-muted">Read only</span>
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => props.onOpenConnection?.(row)}
|
||||
class={inlineButtonClass}
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
<div class="flex flex-col items-end gap-1">
|
||||
{/* Row-level install-agent shortcut: the
|
||||
apiOnly attention state lands directly on
|
||||
the affected system instead of the user
|
||||
reading a global callout and figuring out
|
||||
which row it referred to. */}
|
||||
<Show
|
||||
when={
|
||||
rowHasApiCoverage(row) &&
|
||||
!rowHasAgentCoverage(row) &&
|
||||
Boolean(props.onAddSource)
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => props.onAddSource?.('agent')}
|
||||
class="inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium text-blue-700 transition-colors hover:bg-blue-50 dark:text-blue-300 dark:hover:bg-blue-950/30"
|
||||
title="Install Pulse Agent on this system to add node-local telemetry (temperatures, SMART, host identity)."
|
||||
>
|
||||
<Plus class="h-3 w-3" />
|
||||
Install agent
|
||||
</button>
|
||||
</Show>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => props.onOpenConnection?.(row)}
|
||||
class={inlineButtonClass}
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</div>
|
||||
</Show>
|
||||
</TableCell>
|
||||
</Show>
|
||||
|
||||
@@ -289,7 +289,12 @@ describe('InfrastructureWorkspace', () => {
|
||||
expect(screen.getByRole('button', { name: /Discovery settings/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /^Add infrastructure$/i })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: /^Detect address$/i })).toBeNull();
|
||||
expect(screen.queryByRole('button', { name: /^Install agent$/i })).toBeNull();
|
||||
// Row-level 'Install agent' surfaces per system that has API coverage
|
||||
// but no Pulse Agent yet. The fixture has one such system, so at least
|
||||
// one of these buttons should exist.
|
||||
expect(
|
||||
screen.getAllByRole('button', { name: /^Install agent$/i }).length,
|
||||
).toBeGreaterThan(0);
|
||||
const readiness = screen.getByRole('region', {
|
||||
name: /Infrastructure setup summary/i,
|
||||
});
|
||||
@@ -304,7 +309,12 @@ describe('InfrastructureWorkspace', () => {
|
||||
expect(within(readiness).getAllByText('1 system').length).toBeGreaterThan(0);
|
||||
expect(within(readiness).getAllByText('0 systems').length).toBeGreaterThan(0);
|
||||
expect(within(readiness).getByText('Discovery off')).toBeInTheDocument();
|
||||
expect(within(readiness).getByRole('button', { name: /Install agents/i })).toBeInTheDocument();
|
||||
// Global 'Install agents' recommendation button is hidden when
|
||||
// row-level 'Install agent' chips already surface the apiOnly state
|
||||
// per-system.
|
||||
expect(
|
||||
within(readiness).queryByRole('button', { name: /Install agents/i }),
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Proxmox VE')).toBeInTheDocument();
|
||||
expect(screen.getByText('Proxmox VE').closest('tr')?.className).toContain('grouped-table-row');
|
||||
expect(screen.queryByText('VMware vCenter')).toBeNull();
|
||||
@@ -322,13 +332,9 @@ describe('InfrastructureWorkspace', () => {
|
||||
|
||||
await waitFor(() => expect(screen.getByText('Infrastructure systems')).toBeInTheDocument());
|
||||
|
||||
fireEvent.click(
|
||||
within(
|
||||
screen.getByRole('region', {
|
||||
name: /Infrastructure setup summary/i,
|
||||
}),
|
||||
).getByRole('button', { name: /Install agents/i }),
|
||||
);
|
||||
// Row-level 'Install agent' replaced the global 'Install agents'
|
||||
// recommendation button; same routing target.
|
||||
fireEvent.click(screen.getAllByRole('button', { name: /^Install agent$/i })[0]);
|
||||
expect(navigateSpy).toHaveBeenLastCalledWith('/settings/infrastructure?add=agent', {
|
||||
scroll: false,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user