Commit graph

153 commits

Author SHA1 Message Date
rcourtman
c004c4517f Bulletproof the update auto-refresh with fallback mechanisms (related to #671)
After the initial fix, added multiple layers of reliability to ensure updates
ALWAYS auto-refresh, even in edge cases:

1. Fallback polling: GlobalUpdateProgressWatcher now polls /api/updates/status
   every 5 seconds as a safety net in case WebSocket events are dropped, missed,
   or the tab connects mid-update. This ensures tabs that join late or have
   WebSocket issues still detect in-progress updates.

2. Manual reload button: Added "Reload Now" button in UpdateProgressModal that
   appears after 5+ health check attempts during restart. Gives users an escape
   hatch if auto-reload is delayed (slow DNS, reverse proxy issues, etc.).

3. Already protected: Modal close button only shows when update is complete,
   preventing users from accidentally closing it mid-update.

These changes address all failure modes identified:
- Tabs without WebSocket: covered by polling fallback
- Tabs joining mid-update: covered by polling fallback
- Health check delays: covered by manual reload button
- User accidentally closing modal: already prevented

The combination of WebSocket events (primary), polling (fallback), health checks
(restart detection), and manual reload (escape hatch) should make this bulletproof.
2025-11-08 23:19:51 +00:00
rcourtman
8dad0872ae Fix CSRF token parsing in config export/import (related to #646)
The config backup export and import functions were incorrectly parsing
the CSRF token from cookies, causing "Export requires authentication"
errors even when users were properly logged in.

Two issues were fixed:

1. Cookie parsing used `.split('=')[1]` which truncated tokens containing
   `=` padding characters (common in base64 tokens). Fixed by using
   `.split('=').slice(1).join('=')` to preserve the full value.

2. Missing URL decoding of the cookie value. Browsers percent-encode
   cookie values, so `=` becomes `%3D`. The backend then failed to match
   the encoded token hash. Fixed by adding `decodeURIComponent()`.

Both fixes mirror the pattern already used in apiClient.ts.
2025-11-08 11:17:18 +00:00
rcourtman
cb9d8d1ab1 Fix config backup/restore by enforcing 12-char minimum password (related to #646)
Users with 8-11 character passwords could not export/restore config backups
because the export encryption requires 12+ character passphrases for security,
but the password creation UI only enforced an 8-character minimum.

This created a confusing UX where users with short passwords saw validation
errors when trying to export backups, with the only solution being to use a
custom passphrase or change their password.

Root cause:
- FirstRunSetup and ChangePasswordModal allowed 8+ char passwords
- Config export/import requires 12+ char passphrases (backend validation)
- The v4.26.4 fix added frontend validation that showed the mismatch
- Users hit client-side validation before request was sent (no backend logs)

This fix raises the minimum password length to 12 characters everywhere:
- internal/auth/password.go: MinPasswordLength 8 → 12
- FirstRunSetup.tsx: validation and placeholder updated
- ChangePasswordModal.tsx: validation, minLength, and help text updated
- QuickSecuritySetup.tsx: validation and label updated

Impact:
- New users must create 12+ character passwords
- Existing users with <12 char passwords are unaffected (can't detect from hash)
- Those users will see the existing helpful error directing them to use custom
  passphrase for backups
- "Use your login password" option now works for all future passwords

This aligns password requirements across the system and eliminates the
confusing mismatch between login credentials and backup encryption requirements.

Related to #646 where user confirmed backups still failed in v4.26.5
2025-11-07 22:51:55 +00:00
rcourtman
d70fa88d26 Fix config restore for CLI exports (related to #646)
The v4.26.4 fix inadvertently broke CLI export compatibility. The frontend
attempted JSON.parse on all backup files and returned early with "Invalid
JSON file format" when parsing failed. This prevented the format detection
code from ever executing, breaking CLI-generated exports which are raw
base64 strings without a JSON wrapper.

Root cause:
- CLI exports (`pulse config export`) output raw base64 via
  internal/config/export.go:128
- The fix at Settings.tsx:2030-2034 called showError() and returned
  immediately on parse failure
- Format detection logic at lines 2040-2049 never executed for CLI exports

This changes the parsing flow to:
1. Try JSON.parse first (handles UI exports with {status, data} format)
2. On parse success, extract data field as before
3. On parse failure, treat entire file contents as raw base64 (CLI format)

This preserves the v4.26.4 improvements (12-char validation, better error
messages) while restoring CLI export compatibility.

Related to #646 where user confirmed v4.26.4 still failed to restore backups.
2025-11-07 17:57:22 +00:00
rcourtman
48fabdd827 Improve Docker temperature monitoring documentation for clarity (related to #600)
Updated the Quick Start for Docker section in TEMPERATURE_MONITORING.md to be
more user-friendly and address common setup issues:

- Added clear explanation of why the proxy is needed (containers can't access hardware)
- Provided concrete IP example instead of placeholder
- Showed full docker-compose.yml context with proper YAML structure
- Added sudo to commands where needed
- Updated docker-compose commands to v2 syntax with note about v1
- Expanded verification steps with clearer success indicators
- Added reminder to check container name in verification commands

These improvements should help users who encounter blank temperature displays
due to missing proxy installation or bind mount configuration.
2025-11-07 15:09:42 +00:00
rcourtman
5898cb81be Fix update modal hanging indefinitely after completion (related to #628)
When updates complete quickly, the status API may return 'completed' before
the frontend detects the 'restarting' phase. This left users staring at a
frozen modal with no feedback, requiring manual page refresh.

Changes:
- When status is 'completed', immediately check /api/health
- If backend is healthy, reload the page to get new version
- If health check fails, assume restart in progress and start health polling
- Ensures users always get reloaded to the new version automatically

This fixes the UX issue reported in discussion #628 where the update modal
appeared frozen indefinitely despite successful update completion.
2025-11-07 08:11:52 +00:00
rcourtman
4f9ba7a285 Allow layout to expand on wide displays (related to #643)
Changed .pulse-shell from fixed 95rem cap to fluid clamp(95rem, 92vw, 120rem)
to match standard monitoring dashboard behavior (Proxmox, Grafana, Portainer).

On laptops/small screens: unchanged (capped at 1520px)
On 1080p displays: expands to ~1766px usable width
On 4K/ultrawide: expands up to 1920px max for readability

Added back 2xl column widths (totaling ~1720px) that properly fit within
the expanded shell, giving wide-display users more breathing room while
maintaining proportional scaling across all breakpoints.

Changed files:
- index.css: Update .pulse-shell max-width to use clamp()
- Dashboard.tsx: Add 2xl column widths calculated for expanded shell
- GuestRow.tsx: Add matching 2xl column widths
2025-11-06 21:51:17 +00:00
rcourtman
68caf5592b Fix Proxmox dashboard table overflow on wide displays (related to #643)
Removed 2xl: width overrides that caused the table to exceed container width.
At ≥1536px viewport, the 2xl breakpoint expanded table columns to ~1528px
total width while .pulse-shell container provides only ~1416px usable space,
forcing Net In/Net Out columns off-screen and requiring horizontal scroll.

Table now caps at xl: breakpoint widths (~1266px) which fit comfortably within
the container at all viewport sizes. Net In/Net Out columns are now visible
without scrolling on 1080p, 4K, and all wide displays.

Changed files:
- Dashboard.tsx: Remove 2xl: width classes from all table header columns
- GuestRow.tsx: Remove 2xl: width classes from all table cell columns
2025-11-06 21:36:30 +00:00
rcourtman
2c3768341a Fix Docker host row dimming for degraded status
Docker hosts with 'degraded' status were incorrectly appearing dimmed
(opacity-60) in the summary table, making them visually identical to
offline hosts. This was confusing because degraded hosts are still
actively reporting - they just have unhealthy containers or >35% of
containers not running.

The isHostOnline function now treats 'degraded' as an online status,
so these rows maintain full opacity. The status badge already provides
visual indication of the degraded state.
2025-11-06 19:11:17 +00:00
rcourtman
7ed9203e4b Fix config backup/restore failures (related to #646)
Addresses two issues preventing configuration backup/restore:

1. Export passphrase validation mismatch: UI only validated 12+ char
   requirement when using custom passphrase, but backend always enforced
   it. Users with shorter login passwords saw unexplained failures.
   - Frontend now validates all passphrases meet 12-char minimum
   - Clear error message suggests custom passphrase if login password too short

2. Import data parsing failed silently: Frontend sent `exportData.data`
   which was undefined for legacy/CLI backups (raw base64 strings).
   Backend rejected these with no logs.
   - Frontend now handles both formats: {status, data} and raw strings
   - Backend logs validation failures for easier troubleshooting

Related to #646 where user reported "error after entering password" with
no container logs. These changes ensure proper validation feedback and
make the backup system resilient to different export formats.
2025-11-06 17:53:54 +00:00
rcourtman
47748230f4 Fix first-run setup 401 error by adding bootstrap token unlock screen (related to #639)
After the security hardening that introduced bootstrap token protection,
the first-run setup flow was broken because FirstRunSetup.tsx didn't
prompt users for the token. This caused a 401 "Bootstrap setup token
required" error during initial admin account creation.

Changes:
- Add dedicated unlock screen before the setup wizard
- Display instructions for retrieving token from host
- Include bootstrap token in quick-setup API request headers and body
- Only require unlock for first-run setup (skip in force mode)

The unlock screen follows the documented flow in README.md and ensures
only users with host access can configure an unconfigured instance.

Related to #639
2025-11-06 16:45:51 +00:00
rcourtman
40abcd1237 Fix empty space below backup chart by matching container and SVG heights
The chart container was set to min-h-[12rem] (192px) on desktop while the SVG
was hardcoded to 128px, creating 64px of unwanted empty space. Changed container
to fixed h-32 (128px) to match the SVG height.
2025-11-06 15:34:20 +00:00
rcourtman
a8fa834d24 Fix critical truncation bug preventing data readability on touch devices (related to #643)
Removed CSS truncate from key identifier columns (container names, service names,
guest names, host names, image names) that were making data inaccessible on mobile/
touch devices where title tooltips don't work.

Users can now read full identifiers via horizontal scroll (already implemented via
ScrollableTable component). Data should always be readable without requiring additional
UI affordances.

Changed files:
- DockerUnifiedTable: Remove truncate from container/service names and images
- GuestRow: Remove truncate from guest names
- HostsOverview: Remove truncate from host display names and hostnames

Column resizing remains on backlog as optional enhancement; users should not need
a drag handle just to read the contents.
2025-11-06 15:00:36 +00:00
rcourtman
20854256c3 Fix VM migration issue where custom alert thresholds are lost
Resolves #641

## Problem
When a VM migrates between Proxmox nodes, Pulse was treating it as a new
resource and discarding custom alert threshold overrides. This occurred
because guest IDs included the node name (e.g., `instance-node-VMID`),
causing the ID to change when the VM moved to a different node.

Users reported that after migrating a VM, previously disabled alerts
(e.g., memory threshold set to 0) would resume firing.

## Root Cause
Guest IDs were constructed as:
- Standalone: `node-VMID`
- Cluster: `instance-node-VMID`

When a VM migrated from node1 to node2, the ID changed from
`instance-node1-100` to `instance-node2-100`, causing:
- Alert threshold overrides to be orphaned (keyed by old ID)
- Guest metadata (custom URLs, descriptions) to be orphaned
- Active alerts to reference the wrong resource ID

## Solution
Changed guest ID format to be stable across node migrations:
- New format: `instance-VMID` (for both standalone and cluster)
- Retains uniqueness across instances while being node-independent
- Allows VMs to migrate freely without losing configuration

## Implementation

### Backend Changes
1. **Guest ID Construction** (`monitor_polling.go`):
   - Simplified to always use `instance-VMID` format
   - Removed node from the ID construction logic

2. **Alert Override Migration** (`alerts.go`):
   - Added lazy migration in `getGuestThresholds()`
   - Detects legacy ID formats and migrates to new format
   - Preserves user configurations automatically

3. **Guest Metadata Migration** (`guest_metadata.go`):
   - Added `GetWithLegacyMigration()` helper method
   - Called during VM/container polling to migrate metadata
   - Preserves custom URLs and descriptions

4. **Active Alerts Migration** (`alerts.go`):
   - Added migration logic in `LoadActiveAlerts()`
   - Translates legacy alert resource IDs to new format
   - Preserves alert acknowledgments across restarts

### Frontend Changes
5. **ID Construction Updates**:
   - `ThresholdsTable.tsx`: Updated fallback from `instance-node-vmid` to `instance-vmid`
   - `Dashboard.tsx`: Simplified guest ID construction
   - `GuestRow.tsx`: Updated `buildGuestId()` helper

## Migration Strategy
- **Lazy Migration**: Configs are migrated as guests are discovered
- **Backwards Compatible**: Old IDs are detected and automatically converted
- **Zero Downtime**: No manual intervention required
- **Persisted**: Migrated configs are saved on next config write cycle

## Testing Recommendations
After deployment:
1. Verify existing alert overrides still apply
2. Test VM migration - confirm thresholds persist
3. Check guest metadata (custom URLs) survive migration
4. Verify active alerts maintain acknowledgment state

## Related
- Addresses similar issues with guest metadata and active alert tracking
- Lays groundwork for any future guest-specific configuration features
- Aligns with project philosophy: correctness and UX over implementation complexity
2025-11-06 10:27:15 +00:00
rcourtman
d62259ffa7 Add AMD GPU temperature monitoring support
Related to #600

- Add GPU field to Temperature model with edge, junction, and mem sensors
- Add amdgpu chip recognition to temperature parser
- Implement parseGPUTemps() to extract AMD GPU temperature data
- Update frontend TypeScript types to include GPU temperatures
- Display GPU temps in node table tooltip alongside CPU temps
- Set hasGPU flag when GPU data is available

This enables temperature monitoring for AMD GPUs (amdgpu sensors)
that was previously being collected via SSH but silently discarded
during parsing.
2025-11-06 00:19:04 +00:00
rcourtman
7936808193 Add custom display name support for Docker hosts
This implements the ability for users to assign custom display names to Docker hosts,
similar to the existing functionality for Proxmox nodes. This addresses the issue where
multiple Docker hosts with identical hostnames but different IPs/domains cannot be
easily distinguished in the UI.

Backend changes:
- Add CustomDisplayName field to DockerHost model (internal/models/models.go:201)
- Update UpsertDockerHost to preserve custom display names across updates (internal/models/models.go:1110-1113)
- Add SetDockerHostCustomDisplayName method to State for updating names (internal/models/models.go:1221-1235)
- Add SetDockerHostCustomDisplayName method to Monitor (internal/monitoring/monitor.go:1070-1088)
- Add HandleSetCustomDisplayName API handler (internal/api/docker_agents.go:385-426)
- Route /api/agents/docker/hosts/{id}/display-name PUT requests (internal/api/docker_agents.go:117-120)

Frontend changes:
- Add customDisplayName field to DockerHost TypeScript interface (frontend-modern/src/types/api.ts:136)
- Add MonitoringAPI.setDockerHostDisplayName method (frontend-modern/src/api/monitoring.ts:151-187)
- Update getDisplayName function to prioritize custom names (frontend-modern/src/components/Settings/DockerAgents.tsx:84-89)
- Add inline editing UI with save/cancel buttons in Docker Agents settings (frontend-modern/src/components/Settings/DockerAgents.tsx:1349-1413)
- Update sorting to use custom display names (frontend-modern/src/components/Docker/DockerHosts.tsx:58-59)
- Update DockerHostSummaryTable to display custom names (frontend-modern/src/components/Docker/DockerHostSummaryTable.tsx:40-42, 87, 120, 254)

Users can now click the edit icon next to any Docker host name in Settings > Docker Agents
to set a custom display name. The custom name will be preserved across agent reconnections
and takes priority over the hostname reported by the agent.

Related to #623
2025-11-05 23:18:03 +00:00
rcourtman
fd4182563e Fix custom backup polling interval selection not persisting
Addresses issue #567 where selecting "Custom interval..." from the
backup polling dropdown would revert to a preset option if the current
custom minutes value happened to match a predefined interval.

The bug occurred because:
1. User selects "Custom interval..." from dropdown
2. Code sets interval based on current customMinutes value
3. If that value matches a preset (e.g., 60 min = 1 hour), the
   computed select value returns the preset instead of 'custom'
4. Dropdown reverts, hiding the custom input field

Fix introduces a dedicated state variable (backupPollingUseCustom)
to explicitly track whether custom mode is active, independent of
whether the current interval value matches a preset option.

Changes:
- Add backupPollingUseCustom signal to track custom mode state
- Update backupIntervalSelectValue() to check custom flag first
- Set/clear custom flag in dropdown onChange handler
- Initialize custom flag when loading settings from API

Related to #567
2025-11-05 20:15:48 +00:00
rcourtman
b1488620b1 Fix Docker container prefix textarea not accepting newlines
Added explicit onKeyDown handler to stop event propagation when Enter
is pressed in the ignored container prefixes textarea. This ensures
newlines can be properly entered to separate multiple prefixes.

Related to #625
2025-11-05 19:37:16 +00:00
rcourtman
404d461d35 Add helpful guidance for empty physical disk list
Improves user experience when physical disks don't appear by providing
clear, context-aware instructions. The empty state now shows:

- When no PVE nodes are configured: prompt to add nodes
- When nodes exist but no disks appear: step-by-step requirements
  including enabling SMART monitoring in both Pulse and Proxmox

This addresses confusion from issue #594 where users didn't realize
they needed to enable SMART monitoring in Proxmox itself (not just
in Pulse settings) and wait 5 minutes for data collection.

Related to #594
2025-11-05 19:25:59 +00:00
rcourtman
b1831d7b3e Add guest URL support for PVE hosts
Related to discussion #615

Add optional GuestURL field to PVE instances and cluster endpoints,
allowing users to specify a separate guest-accessible URL for web UI
navigation that differs from the internal management URL.

Backend changes:
- Add GuestURL field to PVEInstance and ClusterEndpoint structs
- Add GuestURL field to Node model
- Update cluster auto-discovery to preserve existing GuestURL values
- Update node creation logic to populate GuestURL from config
- Update API handlers to accept and persist GuestURL field

Frontend changes:
- Add GuestURL input field to NodeModal for configuration
- Update NodeGroupHeader and NodeSummaryTable to use GuestURL for navigation
- Add GuestURL to Node and PVENodeConfig TypeScript interfaces

When GuestURL is configured, it will be used for navigation links
instead of the Host URL, allowing users to access PVE hosts through
a reverse proxy or different domain while maintaining internal API
connections.
2025-11-05 19:06:08 +00:00
rcourtman
449d77504f Improve PMG connection testing to validate metrics endpoints
Related to #551

Enhanced the PMG connection test to actually validate the metrics
endpoints that Pulse uses for monitoring, rather than only checking
the version endpoint. This provides users with immediate feedback if
their PMG credentials lack the necessary permissions to collect metrics.

Backend changes:
- Test mail statistics, cluster status, and quarantine endpoints during
  connection test (internal/api/config_handlers.go:1695-1714)
- Return warnings array in test response when endpoints are unavailable
- Increased timeout from 10s to 15s to accommodate multiple endpoint checks
- Added warning logs for failed endpoint checks

Frontend changes:
- Added showWarning() toast function for warning messages
- Enhanced NodeModal to display warning status with amber styling
- Added warnings list display in test results UI
- Updated Settings.tsx to show warnings from connection tests

This change helps users identify permission issues immediately rather
than discovering later that metrics aren't being collected despite a
"successful" connection.
2025-11-05 18:40:39 +00:00
rcourtman
fdf0977be2 Add host agent multi-platform binary distribution and improve host details UI
- Build host agent binaries for all platforms (linux/darwin/windows, amd64/arm64/armv7) in Docker
- Add Makefile target for building agent binaries locally
- Add startup validation to check for missing agent binaries
- Improve download endpoint error messages with troubleshooting guidance
- Enhance host details drawer layout with better organization and visual hierarchy
- Update base images to rolling versions (node:20-alpine, golang:1.24-alpine, alpine:3.20)
2025-11-05 17:38:17 +00:00
rcourtman
5a328637af Improve drawer layout and UX for Docker and Proxmox pages
- Add flex-1 to all drawer cards for consistent space filling
- Implement single-drawer-open behavior (accordion-style)
- Add text truncation to labels and IP badges to prevent overflow
- Replace Map-based state with reactive signals for better performance
2025-11-05 14:46:13 +00:00
rcourtman
27f2038dab Add per-node temperature monitoring and fix critical config update bug
This commit implements per-node temperature monitoring control and fixes a critical
bug where partial node updates were destroying existing configuration.

Backend changes:
- Add TemperatureMonitoringEnabled field (*bool) to PVEInstance, PBSInstance, and PMGInstance
- Update monitor.go to check per-node temperature setting with global fallback
- Convert all NodeConfigRequest boolean fields to *bool pointers
- Add nil checks in HandleUpdateNode to prevent overwriting unmodified fields
- Fix critical bug where partial updates zeroed out MonitorVMs, MonitorContainers, etc.
- Update NodeResponse, NodeFrontend, and StateSnapshot to include temperature setting
- Fix HandleAddNode and test connection handlers to use pointer-based boolean fields

Frontend changes:
- Add temperatureMonitoringEnabled to Node interface and config types
- Create per-node temperature monitoring toggle handler with optimistic updates
- Update NodeModal to wire up per-node temperature toggle
- Add isTemperatureMonitoringEnabled helper to check effective monitoring state
- Update ConfiguredNodeTables to show/hide temperature badge based on monitoring state
- Update NodeSummaryTable to conditionally show temperature column
- Pass globalTemperatureMonitoringEnabled prop through component tree

The critical bug fix ensures that when updating a single field (like temperature
monitoring), the backend only modifies that specific field instead of zeroing out
all other boolean configuration fields.
2025-11-05 14:11:53 +00:00
rcourtman
d52ac6d8b5 Fix CSRF token validation and improve token management
- Add Access-Control-Expose-Headers to allow frontend to read X-CSRF-Token response header
- Implement proactive CSRF token issuance on GET requests when session exists but CSRF cookie is missing
- Ensures frontend always has valid CSRF token before making POST requests
- Fixes 403 Forbidden errors when toggling system settings

This resolves CSRF validation failures that occurred when CSRF tokens expired or were missing while valid sessions existed.
2025-11-05 09:23:44 +00:00
rcourtman
6eb1a10d9b Refactor: Code cleanup and localStorage consolidation
This commit includes comprehensive codebase cleanup and refactoring:

## Code Cleanup
- Remove dead TypeScript code (types/monitoring.ts - 194 lines duplicate)
- Remove unused Go functions (GetClusterNodes, MigratePassword, GetClusterHealthInfo)
- Clean up commented-out code blocks across multiple files
- Remove unused TypeScript exports (helpTextClass, private tag color helpers)
- Delete obsolete test files and components

## localStorage Consolidation
- Centralize all storage keys into STORAGE_KEYS constant
- Update 5 files to use centralized keys:
  * utils/apiClient.ts (AUTH, LEGACY_TOKEN)
  * components/Dashboard/Dashboard.tsx (GUEST_METADATA)
  * components/Docker/DockerHosts.tsx (DOCKER_METADATA)
  * App.tsx (PLATFORMS_SEEN)
  * stores/updates.ts (UPDATES)
- Benefits: Single source of truth, prevents typos, better maintainability

## Previous Work Committed
- Docker monitoring improvements and disk metrics
- Security enhancements and setup fixes
- API refactoring and cleanup
- Documentation updates
- Build system improvements

## Testing
- All frontend tests pass (29 tests)
- All Go tests pass (15 packages)
- Production build successful
- Zero breaking changes

Total: 186 files changed, 5825 insertions(+), 11602 deletions(-)
2025-11-04 21:50:46 +00:00
rcourtman
5c4be1921c chore: snapshot current changes 2025-11-02 22:47:55 +00:00
rcourtman
fb22469eb0 Add disk usage threshold support for Docker containers
Extends the Docker monitoring and alerting system to track writable layer
usage as a percentage of the container's root filesystem. This helps
identify containers with bloated copy-on-write layers before they
consume excessive disk space.

- Add disk threshold to DockerThresholdConfig (default: 85% trigger, 80% clear)
- Evaluate disk alerts for running containers when RootFilesystemBytes > 0
- Include disk metadata (writable layer, total filesystem, block I/O stats)
- Update frontend to display and configure disk thresholds
- Add test coverage for disk usage alert hysteresis
- Document disk monitoring in DOCKER_MONITORING.md

Per-container and per-host overrides apply to disk thresholds the same
way they do for CPU and memory.
2025-10-29 14:52:25 +00:00
rcourtman
730c6bf864 Fix Docker agent removal and improve security
This commit addresses multiple issues in the Docker/host agent removal flow:

Agent Stop Fix:
- Add systemctl stop command after agent acknowledgement to prevent systemd restart
- Previous behavior: agent disabled but systemd immediately restarted it (Restart=always)
- New behavior: agent disables itself, sends ack, then stops systemd service completely

UX Improvements:
- Add real-time elapsed time counter during removal wait
- Show progress indicators prominently (no longer hidden in dropdown)
- Display expected time range (30-60 seconds) and last heartbeat
- Auto-show timeout warning after 2 minutes with actionable "Force remove" button
- Add contextual help explaining what's happening at each stage

Security Enhancement:
- Automatically revoke API tokens when removing Docker/host agents
- Previous behavior: tokens remained valid after agent removal
- New behavior: tokens are revoked and persisted immediately on removal
- Prevents removed agents from re-authenticating with old credentials
2025-10-29 12:27:36 +00:00
rcourtman
32392d1212 Add disk metrics, block I/O, and mount details to Docker monitoring
Extends Docker container monitoring with comprehensive disk and storage information:
- Writable layer size and root filesystem usage displayed in new Disk column
- Block I/O statistics (read/write bytes totals) shown in container drawer
- Mount metadata including type, source, destination, mode, and driver details
- Configurable via --collect-disk flag (enabled by default, can be disabled for large fleets)

Also fixes config watcher to consistently use production auth config path instead of following PULSE_DATA_DIR when in mock mode.
2025-10-29 12:05:36 +00:00
rcourtman
35ab52b75b Align Docker drawer cards with Proxmox layout 2025-10-29 11:00:04 +00:00
rcourtman
b606a0db99 Adjust Docker host badges and task type column 2025-10-29 10:53:17 +00:00
rcourtman
93faaacbd1 Simplify metric bar labels 2025-10-29 10:37:18 +00:00
rcourtman
7ee417a629 Refine grouped guest indentation 2025-10-29 08:43:02 +00:00
rcourtman
b3285c05c8 Consolidate pending changes
- Add Docker metadata test comment
- Update alerts configuration and thresholds
- Enhance config file watcher
- Update documentation
- Refine settings UI
2025-10-28 23:20:44 +00:00
rcourtman
bd4f12c98f Fix Docker URL link icon to appear immediately after save
Optimistically update local and parent state before the API call completes, so the external link icon appears instantly when the user saves a URL. If the API fails, the state reverts automatically.

Before: Link icon appeared after API response (~100-500ms delay)
After: Link icon appears immediately with smooth fade-in animation
2025-10-28 23:14:38 +00:00
rcourtman
0d2bd7a304 Add custom URL editing to Docker containers and services
Implements clickable name field with inline URL editor for Docker resources, matching the Proxmox guest URL feature:

- Create DockerMetadataAPI for storing custom URLs
- Add metadata loading and caching in DockerHosts component
- Add URL editing UI to DockerContainerRow and DockerServiceRow
- Global editing state prevents multiple simultaneous edits
- Shows external link icon when URL is set
- Supports Enter to save, Escape to cancel
- Toast notifications for save/delete operations
- Stores metadata with format: {hostId}:container:{containerId}

Allows users to add quick links to container/service dashboards (e.g., Portainer, Traefik, internal UIs).
2025-10-28 22:50:31 +00:00
rcourtman
28277757ab Align Docker table row heights with Proxmox table
Change vertical padding from py-1 to py-0.5 on all data cells to match Proxmox guest table row heights for visual consistency across both monitoring interfaces.
2025-10-28 22:41:30 +00:00
rcourtman
33331d34f6 Remove status dots from Docker table to match Proxmox UI
Remove redundant colored status dots from Docker container and service rows to align with Proxmox guest table design. Status is already clearly indicated by the Status column badge.
2025-10-28 22:39:31 +00:00
rcourtman
6462ec6ba1 Apply offline dimming to Docker containers and services
Match Proxmox behavior by dimming stopped containers and degraded services with opacity-60, and showing dashes for metrics (CPU, memory, uptime, restarts) when containers are not running.
2025-10-28 22:37:49 +00:00
rcourtman
0f43c33bb7 Fix Docker table Type column width
The Type column was too narrow at 8%, causing Service and Container badges to be truncated. Increased to 11% and redistributed space from other columns to maintain 100% total width.
2025-10-28 22:31:31 +00:00
rcourtman
59efa69ee8 Prevent wrapping on Docker tables 2025-10-28 22:29:31 +00:00
rcourtman
995c04652c ui: align docker filters with proxmox 2025-10-28 19:06:01 +00:00
rcourtman
52b0c65977 ui: align tables and docker styling 2025-10-28 18:51:52 +00:00
rcourtman
f2acdd59af Normalize docker agent version handling 2025-10-28 08:42:58 +00:00
rcourtman
7733d4b870 Adjust header layout and widen guest name column 2025-10-27 20:55:28 +00:00
rcourtman
a3cd7ba7b8 Reduce backups chart mobile padding 2025-10-27 20:04:32 +00:00
rcourtman
a8e90e1e0e Simplify metric bar labels on narrow viewports 2025-10-27 19:53:40 +00:00
rcourtman
74a8372d48 Add CTA to Docker empty state 2025-10-27 19:49:05 +00:00
rcourtman
e07336dd9f refactor: remove legacy DISABLE_AUTH flag and enhance authentication UX
Major authentication system improvements:

- Remove deprecated DISABLE_AUTH environment variable support
- Update all documentation to remove DISABLE_AUTH references
- Add auth recovery instructions to docs (create .auth_recovery file)
- Improve first-run setup and Quick Security wizard flows
- Enhance login page with better error messaging and validation
- Refactor Docker hosts view with new unified table and tree components
- Add useDebouncedValue hook for better search performance
- Improve Settings page with better security configuration UX
- Update mock mode and development scripts for consistency
- Add ScrollableTable persistence and improved responsive design

Backend changes:
- Remove DISABLE_AUTH flag detection and handling
- Improve auth configuration validation and error messages
- Enhance security status endpoint responses
- Update router integration tests

Frontend changes:
- New Docker components: DockerUnifiedTable, DockerTree, DockerSummaryStats
- Better connection status indicator positioning
- Improved authentication state management
- Enhanced CSRF and session handling
- Better loading states and error recovery

This completes the migration away from the insecure DISABLE_AUTH pattern
toward proper authentication with recovery mechanisms.
2025-10-27 19:46:51 +00:00