mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-20 01:01:20 +00:00
Fix infrastructure dialog scrolling
This commit is contained in:
parent
4d02f0769f
commit
2932822b60
7 changed files with 21 additions and 5 deletions
|
|
@ -341,7 +341,11 @@ an add-only capacity posture.
|
|||
slot; it must not bypass the probe endpoint or fabricate probe
|
||||
candidates, and the agent credential slot must continue to reach
|
||||
`InfrastructureInstallerSection.tsx` so install handoffs remain on the
|
||||
canonical unified-agent install path. For PVE, PBS, and PMG, the
|
||||
canonical unified-agent install path. Those governed add/edit dialogs
|
||||
must also keep their form body scrollable inside the modal:
|
||||
`InfrastructureWorkspace.tsx` and `ConnectionEditor.tsx` keep the
|
||||
content shell on `min-h-0` flex columns so long lifecycle forms do not
|
||||
clip lower fields behind the dialog boundary. For PVE, PBS, and PMG, the
|
||||
credential slot is
|
||||
`frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/NodeCredentialSlot.tsx`,
|
||||
which reuses the existing `NodeModalBasicInfoSection`,
|
||||
|
|
|
|||
|
|
@ -232,6 +232,11 @@ work extends shared components instead of creating new local variants.
|
|||
helper plus runtime `monitored_system_capacity` reads rather than
|
||||
reconstructing raw `current / limit` slash math or `0 remaining` copy in
|
||||
the banner shell, state owner, or shared model.
|
||||
Shared modal scroll containment follows that same owner split. The dialog
|
||||
shell in `frontend-modern/src/components/shared/dialogModel.ts` must keep
|
||||
shared panels `min-h-0`, and page-owned modal bodies may use
|
||||
`overflow-y-auto` only under shrinkable flex columns instead of clipping
|
||||
lower fields behind a fixed-height shell.
|
||||
5. Keep shared infrastructure shell state on the reusable settings boundary: `frontend-modern/src/components/Settings/useSettingsInfrastructurePanelProps.ts` and `frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx` must continue to derive provider counts, availability, and shared subtab copy from one infrastructure-settings source — via the unified aggregator through `frontend-modern/src/components/Settings/useConnectionsLedger.ts` — instead of creating provider-local summary fetches or VMware-only shell vocabulary. Phase 9 retired the old `PlatformConnectionsWorkspace` per-type shell, but setup guidance may still use `Platform connections` as the operator-facing label for the shared API-backed onboarding path.
|
||||
That same shared shell boundary now owns the default posture for
|
||||
`/settings/infrastructure`: the landing route should read as one
|
||||
|
|
@ -245,6 +250,10 @@ work extends shared components instead of creating new local variants.
|
|||
Those secondary views must stay under the same single `Infrastructure`
|
||||
sidebar destination, but they may open in governed modal/dialog chrome when
|
||||
that preserves the persistent source-manager page behind them.
|
||||
That governed dialog chrome must also preserve inner form scrolling:
|
||||
`InfrastructureWorkspace.tsx` and `ConnectionEditor.tsx` keep the add/edit
|
||||
shell on `min-h-0` flex columns so long credential forms scroll inside the
|
||||
modal body instead of trapping the lower fields below the fold.
|
||||
That same shared shell boundary now owns one canonical infrastructure
|
||||
destination in the Settings sidebar. `InfrastructureWorkspace.tsx` owns the
|
||||
source-manager landing inside that destination, while route-backed add flows
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export const ConnectionEditor: Component<ConnectionEditorProps> = (props) => {
|
|||
);
|
||||
|
||||
return (
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex h-full min-h-0 flex-col">
|
||||
<Show
|
||||
when={showCredentialSlot()}
|
||||
fallback={
|
||||
|
|
|
|||
|
|
@ -641,7 +641,7 @@ const InfrastructureWorkspaceContent: Component<InfrastructureWorkspaceProps> =
|
|||
ariaLabel={addDialogTitle()}
|
||||
panelClass={isAgentDialog() ? 'max-w-6xl' : 'max-w-5xl'}
|
||||
>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex h-full min-h-0 flex-col">
|
||||
<div class="flex items-start justify-between gap-4 border-b border-border bg-surface-alt px-4 py-4 sm:px-6">
|
||||
<div class="space-y-1">
|
||||
<h2 class="text-base font-semibold text-base-content">{addDialogTitle()}</h2>
|
||||
|
|
@ -712,7 +712,7 @@ const InfrastructureWorkspaceContent: Component<InfrastructureWorkspaceProps> =
|
|||
ariaLabel={editDialogTitle()}
|
||||
panelClass={connection.type === 'agent' ? 'max-w-5xl' : 'max-w-5xl'}
|
||||
>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex h-full min-h-0 flex-col">
|
||||
<div class="flex items-start justify-between gap-4 border-b border-border bg-surface-alt px-4 py-4 sm:px-6">
|
||||
<div class="space-y-1">
|
||||
<h2 class="text-base font-semibold text-base-content">{editDialogTitle()}</h2>
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ describe('settings architecture guardrails', () => {
|
|||
expect(infrastructureWorkspaceSource).toContain('<InfrastructureSourceManager');
|
||||
expect(infrastructureWorkspaceSource).toContain('<InfrastructureSourcePicker');
|
||||
expect(infrastructureWorkspaceSource).not.toContain('<ConnectionsTable rows={rows} />');
|
||||
expect(infrastructureWorkspaceSource).toContain('flex h-full min-h-0 flex-col');
|
||||
expect(infrastructureWorkspaceSource).toContain("showSlotHeader={false}");
|
||||
expect(infrastructureWorkspaceSource).toContain(
|
||||
"trackInitialCatalogSelection={activeAddType() !== 'agent'}",
|
||||
|
|
@ -146,6 +147,7 @@ describe('settings architecture guardrails', () => {
|
|||
expect(connectionEditorSource).toContain('<AddressProbeStep');
|
||||
expect(connectionEditorSource).toContain('Detect from address');
|
||||
expect(connectionEditorSource).toContain('Address probe');
|
||||
expect(connectionEditorSource).toContain('flex h-full min-h-0 flex-col');
|
||||
expect(connectionEditorSource).toContain('Back to source types');
|
||||
expect(connectionEditorSource).toContain('Back to detect');
|
||||
expect(connectionEditorSource).toContain('What happens next');
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ describe('Dialog', () => {
|
|||
));
|
||||
|
||||
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog')).toHaveClass('min-h-0');
|
||||
const backdrop = document.querySelector('[data-dialog-backdrop]') as HTMLElement | null;
|
||||
expect(backdrop).not.toBeNull();
|
||||
if (!backdrop) return;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export function getDialogAlignmentClass(layout: DialogLayout): string {
|
|||
}
|
||||
|
||||
export function getDialogPanelClass(layout: DialogLayout, panelClass?: string): string {
|
||||
return `relative flex w-full flex-col overflow-hidden bg-surface border border-border outline-none pointer-events-auto ${
|
||||
return `relative flex min-h-0 w-full flex-col overflow-hidden bg-surface border border-border outline-none pointer-events-auto ${
|
||||
layout === 'drawer-right'
|
||||
? 'h-dvh max-w-[720px] rounded-none border-y-0 border-r-0 animate-slide-up sm:h-full sm:max-h-dvh sm:rounded-l-xl sm:border-y sm:border-r-0'
|
||||
: 'max-h-[calc(100dvh-2rem)] rounded-md animate-slide-up'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue