* docs: add design spec for configurable icons from Docker share Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add implementation plan for configurable icons from Docker share Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove icons * feat: serve icons from config/icons/ Docker share via static file middleware Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * update readme --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2.3 KiB
2.3 KiB
Configurable Icons from Docker Share
Date: 2026-04-14
Status: Approved
Problem
Icons for shifts are currently PNG files bundled in the repository under Client/wwwroot/icons/. This means adding or changing an icon requires a code change and a redeployment. The user wants icons to be configurable at runtime, placed on the same Docker-mounted volume as monthly schedule files and other configuration.
Solution
Serve icon files from config/icons/ (a subfolder of the existing Docker share) using ASP.NET Core's static file middleware with a PhysicalFileProvider. No frontend changes are required — the URL path /icons/filename.png stays identical.
Architecture
Server change (Server/Program.cs)
Add a second UseStaticFiles call after the existing one:
var iconsPath = Path.Combine(Directory.GetCurrentDirectory(), "config", "icons");
Directory.CreateDirectory(iconsPath);
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(iconsPath),
RequestPath = "/icons"
});
config/icons/is created automatically on first run if absent.- Files placed there are served at
/icons/{filename}immediately, no restart needed. - Built-in ASP.NET Core static file serving provides ETags, cache headers, and range request support.
Cleanup
- Delete
Client/wwwroot/icons/and all PNG files within it. - Remove all
<Content Update="wwwroot\icons\*.png">entries fromClient/ShiftScheduler.Client.csproj.
No changes needed
Shift.IsPngIconcomputed propertyShift.Iconfield<img src="icons\@shift.Icon">inIndex.razorConfigurationDialog.razor- Any other frontend or shared model code
Data Flow
- User places
myicon.pnginconfig/icons/on the Docker share. - In
appsettings.json(orconfig/shifts.json), the shift'sIconfield is set tomyicon.png. - The Blazor client fetches shift config from
GET /api/shift/shifts. Shift.IsPngIconreturnstrue, and the UI renders<img src="icons/myicon.png">.- The browser GETs
/icons/myicon.png— served by thePhysicalFileProviderfromconfig/icons/myicon.png.
Out of Scope
- Emoji icons are unaffected.
- No upload UI for icons — files are placed on the share directly (consistent with how schedule files work).
- No fallback to repo-bundled icons (repo icons are removed entirely).