Image assets (3/3): widget config UI + settings image-cache card - #1082
Closed
dillan wants to merge 14 commits into
Closed
Image assets (3/3): widget config UI + settings image-cache card#1082dillan wants to merge 14 commits into
dillan wants to merge 14 commits into
Conversation
resolveKipPluginBaseUrl() extracts the <server>/plugins/kip/ resolution (mirroring kip-series-api-client) and snapImageWidth() snaps a container width (x DPR) to the server's variant allow-list so the client requests stable, cache-friendly URLs. ImageAssetService wraps the plugin endpoints: upload (multipart FormData with progress), list, delete, cacheStats, purgeCache, and urlFor(id, cssWidth, dpr) for the widget. Requests are auto-authenticated by the JWT interceptor. 9 vitest cases green.
This was referenced Jun 24, 2026
New widget-image renders a selected image (by id) via ImageAssetService, scaled to fit the widget with object-fit (contain/cover) over a configurable background that defaults to transparent so the dashboard shows through. It tracks its container width with the existing kipResizeObserver directive and requests a server variant matched to that width (x DPR) so a small widget never downloads a full-resolution image. Shows an empty state when nothing is selected. Registered in WidgetService (component map + Component-category definition); adds the `image` config block to IWidgetSvcConfig. 3 vitest cases (empty state, render+object-fit, background default/override).
Lets users upload an image (client-side 10 MB + type guard, progress), pick or delete from the shared library, and set the scaling, alt text, and a background color or transparent background for the Image widget. Wired into the widget config Display tab for widgets that expose an image config group.
Shows the on-disk size of generated image variants and a Purge button (with confirmation). Purging keeps originals; variants regenerate on demand. Refresh re-reads the size after viewing images.
Splits the thumbnail into a select button and a sibling delete button so both are keyboard-focusable and avoid an invalid nested-button structure.
Make the gallery selection a signal so the highlight updates under zoneless change detection even when set from async upload/delete callbacks, instead of relying on an incidental signal write. Add a sequence guard so a slow image list() response can't overwrite a newer one.
Matches the sibling image-source-setup component and the project's takeUntilDestroyed convention. HttpClient one-shots self-complete, so this is convention-consistency, not a leak fix.
Add a small horizontal gap between the Refresh and Purge buttons on the settings image-cache card (the footer is text-align:end, not flex).
dillan
force-pushed
the
feat/image-assets-config-ui
branch
from
June 24, 2026 10:06
0e3e544 to
c269267
Compare
dillan
marked this pull request as ready for review
June 24, 2026 11:29
The image cache card was placed on the Configurations tab, which is for KIP configuration management (backup, restore, import, export). Move it to a new Media tab, placed before Configurations, so the image cache lives with media concerns rather than config management. Extracts the image-cache logic into a SettingsMediaComponent (with its own spec) and removes it from SettingsConfigComponent. Updates the Image widget help doc to point at Settings → Media → Image Cache.
The Image widget had no icon in the widget picker (icon was empty). Add an "imageWidget" landscape/image glyph to the shared SVG icon set and reference it from the widget definition so the widget shows a recognizable icon.
Acts on a UX audit of the Image widget. Safety / state - Deleting an image now asks for confirmation, naming the shared, boat-wide scope — a single tap previously removed it from every display with no undo. The delete control moved to a 44px button in a footer row, out of the select tap zone. - The gallery distinguishes a failed library load from a truly empty one (loading spinner, error + Retry), so an unreachable server no longer reads as "no images". The live widget shows "Image unavailable" instead of a broken glyph when its image disappears. - Upload and delete share one status-aware error mapper. Accessibility - Thumbnails expose selection (aria-pressed) and group semantics, visible keyboard focus, a named delete label, and a live region announces upload/delete status. "Alt text" is now "Description" with a hint; thumbnails are captioned with the image name and sorted newest-first. Clarity / theming - Plainer copy throughout (errors, the Fill option, the cache card's "Clear cache"). Touch-safe color control. The opaque background seeds from the active theme instead of hardcoded black, transparent diagrams sit on a neutral checkerboard, and a live preview shows the chosen fit/background. Updates the component specs (delete confirmation, 401 mapping, gallery error state, newest-first sort, theme-seeded background).
Relabels the help text to match the new UI ("Alt text" -> "Description",
"Purge" -> "Clear cache") and refreshes the screenshots: the redesigned
config dialog (shared "Boat image library" with thumbnails, captions and
footer delete) and the Media -> Image Cache card showing a real cache size.
Also points the help menu at the renamed image-widget.md and gitignores the
Playwright MCP working dir.
Spins up an open (no-login) Signal K server with the integrated KIP image plugin + webapp, seeded with realistic marine diagrams, so the Image widget help screenshots (gallery, thumbnails, real cache size) can be reliably re-captured as the UI evolves. The image feature spans three branches (server/client/config-ui); the README documents merging the server branch and `npm pack` to produce the kip.tgz the Dockerfile installs (which resolves native deps like sharp for the container).
Contributor
Author
|
Superseded by #1120 (consolidated). The config UI + Settings → Media cache card land there, re-pointed at the standalone |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Image assets (3/3) — widget config UI + settings image-cache card
Part 3 of 3 adding user-uploaded image assets to KIP dashboards. This PR adds the config UI for the Image widget (upload, shared-library picker, display options) and a settings card to manage the on-disk image cache.
Stacked on PR 2 (client). It builds on the
ImageAssetServiceand Image widget from PR 2, so this branch contains PR 2's two commits as well — review/merge PR 2 first and this PR's diff collapses to just the config-UI changes below. (GitHub shows the cumulative diff because both targetmaster.)What it does
image-source-setupwidget-config sub-component (wired into the widget config Display tab via@else if (widgetConfig?.image)):list()to reuse an image across widgets/dashboards; select sets the widget'simageId; per-item delete. The selection highlight is signal-driven so it updates correctly under zoneless change detection even from async upload/delete callbacks, and gallery refreshes are sequence-guarded against out-of-order responses.imagewidget.md+ menu entry) and a CHANGELOG entry.Tests
image-source-setup.component.spec.ts(ensure/preserve controls, ≤10 MB + type validation incl. HEIC-by-extension, gallery load, select/delete, upload success + 401 error mapping, transparent toggle, signal highlight).config.component.spec.tsextended (cache size formatting, Unavailable when not ready, purge-after-confirm, no-purge-when-declined). Vitest/zoneless. Lint clean; app builds.Status / gates
ng lintclean; image-source-setup (13 tests) + config-card additions pass. An independent adversarial review of this UI found two zoneless-reactivity issues that are fixed here (signal-driven gallery highlight; sequence-guarded list refresh).Stacking
📚 3-PR stack (review/merge in order)
PR 2 needs PR 1 at runtime; PR 3 is stacked on PR 2. Together they add the full image-assets feature.
You are viewing PR 3 of 3.