Skip to content

Improve performance and UX with progressive loading, multi-file support, and column customization#120

Open
mstrhakr wants to merge 72 commits into
mainfrom
dev
Open

Improve performance and UX with progressive loading, multi-file support, and column customization#120
mstrhakr wants to merge 72 commits into
mainfrom
dev

Conversation

@mstrhakr

@mstrhakr mstrhakr commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Summary

This PR delivers a major Compose Manager upgrade focused on faster perceived load time, richer update metadata, and safer/more flexible compose operations.

Core goals:

  • Render useful stack data earlier with progressive loading.
  • Improve update visibility with cached icons, digest details, and optional changelog links.
  • Add support for multiple compose files and safer compose command handling.
  • Improve table layout/customization and day-to-day stack management UX.

Major Enhancements

1) Progressive Loading and Runtime Data Flow

  • Added progressive stack loading so the page can show stack rows sooner, then progressively enrich each row with heavier metadata.
  • Added Compose-list API modes to support progressive rendering:
    • mode=list returns project names
    • mode=row returns a single project row payload
  • Switched Compose pages to a compose-specific nchan channel and publisher:
    • Nchan channel changed from docker_load to compose_info/composeinfo
    • Added compose-local publisher script with status/snapshot files for better startup/runtime observability
  • Improved metric visibility during progressive load by using snapshot fallback so CPU/memory/network/block metrics appear consistently even while streams initialize.

2) Update Metadata, Icons, and docker.versions Integration

  • Added persistent container icon cache at /boot/config/plugins/compose.manager/containers.cache.json.
  • Implemented cache-first icon resolution with docker inspect fallback and cache refresh when icon values change.
  • Extended update payloads/serialization to include service and icon fields.
  • Added docker.versions integration for changelog links in update UX when available.
  • Updated docs to explain update checks and changelog behavior.

3) Multi-Compose File Support

  • Added support for extra compose files via stack settings and command building.
  • Supports absolute and relative paths (resolved safely against compose source context).
  • Preserves existing extra compose files when stale/older UI clients post settings without that field.
  • Supports explicit clearing when extra compose files are submitted empty.

4) Safer Compose Command Execution and Options

  • Refactored compose command execution to option-based handling (recreate, background, removeOrphans).
  • Added remove-orphans support end-to-end:
    • request handling
    • compose command builder/script argument parsing
    • compose down invocation path
  • Improved command debug logging with complete option context.

5) UI/UX and Table Improvements

  • Added column visibility customization for stack and service tables with persisted preferences.
  • Added responsive transfer-list style column manager and promoted this flow as primary customization UX.
  • Recent UI refinements include compact transfer controls designed to avoid aggressive global button CSS overrides.
  • Added expand/collapse-all stack controls.
  • Improved stack toggle behavior with batching and user-intent tracking.
  • Reworked stack/service column width distribution and fixed-layout math:
    • CSS variable-based width fractions
    • box-sizing fixes to prevent overflow/gap artifacts
    • better handling of dynamic column visibility + colspan syncing

6) Reliability and Behavior Fixes

  • Fixed sortable drag behavior so details rows are safely detached/reattached and do not become orphaned.
  • Added profile-aware row metadata (default and running profiles) to improve action targeting and runtime accuracy.
  • Improved override pruning safety:
    • preserves content in risky “all removed” rename scenarios
    • allows full prune only when orphan blocks are clearly plugin-managed label-only content
  • Updated plugin URL sync workflow to self-heal branch links on push, merged PRs, and manual dispatch.

Packaging and Distribution

  • Updated plugin version/build metadata and release notes entries.
  • Ensured nchan scripts are marked executable during packaging.
  • Removed obsolete test-build-stack fixtures.

Tests and Documentation

  • Expanded unit coverage across:
    • progressive/metric markup expectations
    • update payload fields (service/icon)
    • extra compose files behavior
    • override pruning edge cases
    • source-level integrity checks
  • Updated user documentation for update-check flow and docker.versions changelog support.

Notable User Impact

  • Faster initial page feedback on large installs.
  • Better update decision context (icons, digests, changelogs).
  • More control over compose file layering and orphan cleanup.
  • Improved table readability/customization and more stable UI interactions.

Compatibility Notes

  • docker.versions integration is optional and auto-detected.
  • Existing stacks/settings remain compatible; new options are additive with safe defaults (e.g., REMOVE_ORPHANS_DEFAULT=false).

Closes #6
Closes #119

mstrhakr and others added 24 commits May 31, 2026 11:38
When docker.versions is installed, a Changelog link appears next to the
SHA comparison for each container with a pending update. Clicking it opens
the docker.versions changelog in a sized iframe modal via Nchan, matching
the existing Docker tab experience.

docker.versions is an optional dependency: the PHP endpoint detects it via
is_dir(), the JS flag defaults false, and the NchanSubscriber guard prevents
any breakage if the plugin is absent or removed while the page is open. A
10-second timeout shows a fallback message if no data arrives. Dialog sizing
is applied via inline styles rather than borrowing docker.versions' CSS classes.
Tests cover all three response paths (no file, valid file, invalid file)
against both the docker.versions-installed and not-installed states.
Uses UnraidStreamWrapper to map the plugin directory to a controlled
temp path without touching the real filesystem.
When the user closes the changelog modal (OK button or outside click),
re-open the Update Stack dialog for the same stack so they can continue
reviewing other containers or proceed with the update.

Pass path and profile through to showComposeChangelog via data attributes
so the callback has enough context to reopen the dialog.
/sub/changelog is a shared channel: Nchan delivers the last buffered
message to every new subscriber, and docker.versions' own subscriber
may be actively publishing output for other containers concurrently.
Both cases caused wrong containers' changelogs to appear in the dialog.

GetChangelog.php always publishes <h3 class='loading'> as its first
message.  Use that as a start-of-stream marker: discard everything
received before it, clear the iframe on arrival, and suppress
loadingInfo progress messages that are noise in this context.
docker.versions publishes many message types — Container: headers, URL
links, warnings, empty <pre> containers, loadingInfo progress — that are
structural scaffolding for its own full-page view and are noise in our
modal.  Replace the loadingInfo-only blacklist with a whitelist: accept
only class='releasesInfo' release entries and the version-summary <h3>
containing '---->', and discard everything else.
Replace the custom NchanSubscriber, message filtering, and markdown
renderer with a direct call to docker.versions' own showChangeLog()
function, which already handles all of that correctly.

Hide the OK/confirm button (it would call updateContainer, bypassing
compose_plugin's update mechanism) and poll for dialog close to reopen
the Update Stack dialog afterward.
…abled

Two bugs found in code review:

1. The setInterval poll had no escape hatch when showChangeLog() opened
   no SweetAlert dialog (e.g. container unknown to docker.versions), so
   the 'appeared' flag never flipped true and clearInterval was never
   reached. Cap at 300 ticks (30 s) so it always self-cleans.

2. When DISABLE_ACTION_WARNINGS is true, renderStackActionDialog() has a
   fast-path that calls UpdateStackConfirmed() directly without showing a
   dialog. Reopening the update dialog after changelog dismiss would
   trigger an immediate update rather than a confirmation prompt. Skip
   the reopen in that mode by checking the setting via getConfig().
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
feat: show docker.versions changelogs in the update dialog
Copilot AI review requested due to automatic review settings June 11, 2026 18:56

This comment was marked as outdated.

@mstrhakr mstrhakr changed the title Implement progressive loading, add docker.versions support, improve icon loading, and more. Implement progressive loading, add docker.versions support, improve icon loading, and support mutpliple compose files. Jun 14, 2026
mstrhakr added 3 commits June 14, 2026 19:38
- Implemented server-side handling for getting and saving column visibility preferences.
- Introduced a new JavaScript module for managing column customization in the UI.
- Updated the main JavaScript file to integrate the new column visibility features.
- Added a new Nchan publisher for real-time container metrics, replacing the deprecated docker_load script.
- Enhanced the UI to support new metrics display including CPU, Memory, Network I/O, and Disk I/O.
- Adjusted CSS styles for better layout and visibility of new columns and modal components.
- Updated unit tests to reflect changes in column structure and ensure new features are covered.
… publishing to ensure data shows during progressive loading
@mstrhakr mstrhakr changed the title Implement progressive loading, add docker.versions support, improve icon loading, and support mutpliple compose files. Implement progressive loading, add docker.versions support, improve icon loading, and support multiple compose files. Jun 15, 2026
@mstrhakr mstrhakr changed the title Implement progressive loading, add docker.versions support, improve icon loading, and support multiple compose files. Improve performance and UX with progressive loading, multi-file support, and column customization Jun 15, 2026
mstrhakr and others added 11 commits June 16, 2026 12:15
Reduce composeListRefreshed event churn while rows are appended progressively.
This avoids repeated dockerload/listener invalidation work for every single row.

- Add debounced composeListRefreshed trigger helper
- Add flush helper for immediate final refresh
- Use debounce in initializeProgressiveLoadedRows
- Flush pending debounce in finalizeComposeLoadlist

Behavior preserved: final load still emits immediate refresh.
…inserts

Remove applyListView(false) from initializeProgressiveLoadedRows so each
new row only runs row-local setup. This prevents repeated full-table
readmore re-initialization and reduces reflow churn while progressively
loading stacks.

Global applyListView behavior remains intact in the normal load lifecycle.
Introduce a small render scheduler for compose dockerload updates and switch
message handling from immediate full repaint to timed rendering (120ms min interval).

- Add scheduled/forced render helper for compose load cache
- Use scheduled render on websocket message events
- Keep immediate render for snapshot seed and tab-visible resume
- Clear pending render timers during subscriber teardown

This reduces DOM update churn and CPU usage while preserving live metric behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Handle orphaned containers Customizable columns for Stacks/Containers (Hide Uptime, Show Mounts)

4 participants