Files
deploy-felhom-compose/TASK.md
T

12 KiB

TASK.md — v0.13.1 UI Polish Fixes (Round 2)

Version: v0.13.1 Type: UI polish — 4 fixes Files likely affected: deploy.html, backups.html, dashboard.html, monitoring.html, layout.html, style.css, handlers.go, alerts.go, funcmap.go

Read CLAUDE.md, controller/README.md, and CONTEXT.md before starting.


Fix 1: Backup section on deploy page needs card/box styling

Problem: The "Biztonsági mentés" section on app deploy/settings pages (e.g., /stacks/immich/deploy) has no visible border or card styling, unlike the "Adattárolás" section above it and other card sections on the page. It looks flat and out of place.

Where: deploy.html line ~96: <div class="deploy-cross-drive"> and the .deploy-cross-drive CSS class in style.css.

Solution: Add card-like styling to .deploy-cross-drive in style.css. Look at how .deploy-storage-info (the "Adattárolás" card above it on the same page) is styled and match it:

  • border: 1px solid var(--border)
  • background: var(--card-bg)
  • border-radius: 12px
  • padding: 1.5rem

If .deploy-cross-drive already exists in CSS, add the missing border/background properties. If it doesn't exist, create it with the above properties.


Fix 2: Clean up auto-generated env values section on deploy page

Problem: The "Automatikusan generált értékek" section on the deploy page is cluttered. Each field currently shows: input + "Megjelenítés" button (for passwords) + "Másolás" button + badge. Too many elements stacked together.

Current code location: deploy.html lines ~254-281, inside the {{if .AutoFields}} block.

Current structure per field:

<div class="form-group form-group-auto">
    <label>{{.Label}}</label>
    {{if and $isDeployed $val}}
    {{if eq .Type "secret"}}
    <div class="input-with-button">
        <input type="password" ...>
        <button ... onclick="toggleAutoField(...)">Megjelenítés</button>
        <button ... onclick="copyAutoField(...)">Másolás</button>
    </div>
    {{else}}
    <div class="input-with-button">
        <input type="text" ...>
        <button ... onclick="copyAutoField(...)">Másolás</button>
    </div>
    {{end}}
    {{end}}
    <span class="auto-generated-badge">✓ Automatikusan generálva</span>
</div>

Changes:

  1. Remove ALL "Másolás" buttons — users can select+copy natively, dedicated button adds clutter
  2. Keep the "Megjelenítés"/"Elrejtés" toggle button for secret/password fields (essential)
  3. Move the badge inline with the label — instead of on a separate line below the input, put it next to the label text

New structure per field:

<div class="form-group form-group-auto">
    <label>{{.Label}} <span class="auto-generated-badge">✓ Automatikusan generálva</span></label>
    {{if and $isDeployed $val}}
    {{if eq .Type "secret"}}
    <div class="input-with-button">
        <input type="password" id="auto-field-{{.EnvVar}}" class="form-control" value="{{$val}}" readonly>
        <button type="button" class="btn btn-sm btn-outline" onclick="toggleAutoField('auto-field-{{.EnvVar}}', this)">Megjelenítés</button>
    </div>
    {{else}}
    <input type="text" id="auto-field-{{.EnvVar}}" class="form-control" value="{{$val}}" readonly>
    {{end}}
    {{end}}
</div>
  1. Remove the copyAutoField JS function — search for function copyAutoField in deploy.html's <script> block and remove it entirely.

  2. CSS adjustments in style.css:

    • .form-group-auto label should use display: flex; align-items: center; gap: 0.5rem; so the badge sits inline with the label text
    • .auto-generated-badge should be font-size: 0.75rem and font-weight: normal to not overpower the label
    • Read-only inputs (.form-group-auto .form-control[readonly]) could have a slightly muted background (e.g., background: var(--bg-secondary)) to visually indicate they're not editable

Fix 3: Pillanatképek — show 0 instead of n/a

Problem: In the Pillanatképek table on the backup page, columns "Hozzáadott (új adat)", "Új fájl", "Változott" show n/a with a long tooltip when HasStats is false. The user wants 0 instead — n/a implies "data unavailable", but 0 correctly means "no changes".

Current code (backups.html, in the snapshot table tbody):

<td class="mono">{{if .HasStats}}+{{.DataAdded}}{{else}}<span class="col-na" title="A restic pillanatképek nem tartalmaznak méretadatot — csak az utolsó mentés adatai állnak rendelkezésre.">n/a</span>{{end}}</td>
<td class="mono">{{if .HasStats}}{{.FilesNew}}{{else}}<span class="col-na" title="A restic pillanatképek nem tartalmaznak fájlszámot — csak az utolsó mentés adatai állnak rendelkezésre.">n/a</span>{{end}}</td>
<td class="mono">{{if .HasStats}}{{.FilesChanged}}{{else}}<span class="col-na" title="A restic pillanatképek nem tartalmaznak fájlszámot — csak az utolsó mentés adatai állnak rendelkezésre.">n/a</span>{{end}}</td>

Replace with:

<td class="mono">{{if .HasStats}}+{{.DataAdded}}{{else}}0{{end}}</td>
<td class="mono">{{if .HasStats}}{{.FilesNew}}{{else}}0{{end}}</td>
<td class="mono">{{if .HasStats}}{{.FilesChanged}}{{else}}0{{end}}</td>

Remove the <span class="col-na" title="..."> wrappers entirely. Simple 0 values.

Also remove the .col-na CSS class from style.css if it's no longer used elsewhere.


Fix 4: Move disk warnings from top banner to inline under storage bars

Problem: The yellow HDD warning banner ("Az adattároló nem külön meghajtón van...") appears at the very top of the page via layout.html, rendered as a full-width alert banner. Even though v0.13.0 added PageOnly filtering (only dashboard + monitoring), the warnings are still too prominent and positioned at the top rather than near the relevant storage info.

Goal:

  1. Disk warnings should NOT appear in the layout.html top banner at all
  2. They should render inline, under the relevant storage usage bar on dashboard and monitoring pages
  3. They should be smaller and more subtle than the current full-width alert banner

Step 1: Add Inline field to Alert struct

In alerts.go, add an Inline bool field to the Alert struct:

type Alert struct {
    ID       string
    Level    string
    Message  string
    Link     string
    LinkText string
    PageOnly []string
    Inline   bool     // If true, rendered by page template, not layout
}

Step 2: Mark disk warnings as inline in Refresh()

In alerts.go Refresh(), where disk warnings get PageOnly set (the block checking for "meghajtón" / "adattároló" / "meghajtó"), also set Inline: true:

if strings.Contains(w, "meghajtón") || strings.Contains(w, "adattároló") || strings.Contains(w, "meghajtó") {
    alert.ID = "disk-not-separate"
    alert.PageOnly = []string{"dashboard", "monitoring"}
    alert.Inline = true
}

Step 3: Skip inline alerts in layout.html

In layout.html, update the alert rendering loop to skip inline alerts:

Current:

{{range .Alerts}}
{{if or (not .PageOnly) (pageMatch .PageOnly $.Page)}}
<div class="alert-banner alert-banner-{{.Level}}">

Change to:

{{range .Alerts}}
{{if and (not .Inline) (or (not .PageOnly) (pageMatch .PageOnly $.Page))}}
<div class="alert-banner alert-banner-{{.Level}}">

Step 4: Add GetInlineAlerts method to AlertManager

In alerts.go, add a new method:

// GetInlineAlerts returns alerts marked as Inline for a specific page.
func (am *AlertManager) GetInlineAlerts(page string) []Alert {
    am.mu.RLock()
    defer am.mu.RUnlock()

    var result []Alert
    for _, a := range am.alerts {
        if !a.Inline {
            continue
        }
        if len(a.PageOnly) == 0 {
            result = append(result, a)
            continue
        }
        for _, p := range a.PageOnly {
            if p == page {
                result = append(result, a)
                break
            }
        }
    }
    return result
}

Step 5: Pass inline alerts in dashboard and monitoring handlers

In handlers.go:

In dashboardHandler, after baseData() call, add:

if s.alertManager != nil {
    data["DiskWarnings"] = s.alertManager.GetInlineAlerts("dashboard")
}

In monitoringHandler, after baseData() call, add:

if s.alertManager != nil {
    data["DiskWarnings"] = s.alertManager.GetInlineAlerts("monitoring")
}

Step 6: Render inline warnings in dashboard.html

In dashboard.html, inside the .system-info-card, right after the second .system-info-items block (the one with SSD and HDD bars) — just before the closing </div> of .system-info-card — add:

{{if .DiskWarnings}}
<div class="inline-warnings">
    {{range .DiskWarnings}}
    <div class="inline-warning inline-warning-{{.Level}}">
        <span class="inline-warning-dot"></span>
        <span class="inline-warning-text">{{.Message}}</span>
        {{if .Link}}<a href="{{.Link}}" class="inline-warning-link">{{.LinkText}} →</a>{{end}}
    </div>
    {{end}}
</div>
{{end}}

Place this INSIDE the {{if .SystemInfo.TotalMemMB}}...{{end}} block, after the storage bars but before the closing </div> of .system-info-card.

Step 7: Render inline warnings in monitoring.html

In monitoring.html, inside the Tárhely .monitor-card (currently Section 1.5), right after the .storage-bars closing </div> but still inside the .monitor-card, add the same block:

{{if .DiskWarnings}}
<div class="inline-warnings">
    {{range .DiskWarnings}}
    <div class="inline-warning inline-warning-{{.Level}}">
        <span class="inline-warning-dot"></span>
        <span class="inline-warning-text">{{.Message}}</span>
        {{if .Link}}<a href="{{.Link}}" class="inline-warning-link">{{.LinkText}} →</a>{{end}}
    </div>
    {{end}}
</div>
{{end}}

Step 8: Add CSS for inline warnings

In style.css, add:

.inline-warnings {
    margin-top: 0.75rem;
}
.inline-warning {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.75rem;
    margin-top: 0.25rem;
    font-size: 0.8rem;
    border-radius: 6px;
}
.inline-warning-warning {
    color: var(--yellow);
    background: rgba(250, 204, 21, 0.06);
    border: 1px solid rgba(250, 204, 21, 0.15);
}
.inline-warning-error {
    color: var(--red);
    background: rgba(218, 54, 51, 0.06);
    border: 1px solid rgba(218, 54, 51, 0.15);
}
.inline-warning-dot {
    font-size: 0.6rem;
    flex-shrink: 0;
}
.inline-warning-text {
    flex: 1;
}
.inline-warning-link {
    color: inherit;
    opacity: 0.8;
    white-space: nowrap;
    text-decoration: none;
}
.inline-warning-link:hover {
    opacity: 1;
    text-decoration: underline;
}

This makes the warnings compact (small font, subtle background, thin border) and positioned right under the storage bar they relate to.


Implementation order

  1. Fix 3 — Pillanatképek 0 vs n/a (template-only, 1 min)
  2. Fix 1 — Deploy page card border (CSS only, 1 min)
  3. Fix 2 — Auto-generated values cleanup (template + CSS)
  4. Fix 4 — Disk warnings inline (alerts.go + layout.html + dashboard.html + monitoring.html + handlers.go + style.css)

Build & deploy

After all fixes, bump version to v0.13.1, then follow the standard build workflow in CLAUDE.md:

Read TASK.md for the full plan. Apply all code changes described, then build and deploy.
After all fixes are done:
1. Run `go build ./...` and `go vet ./...` from the controller/ directory — fix any errors
2. Update CHANGELOG.md with a new entry at the top (read top 30 lines only for format, then Edit to insert)
3. Commit, build, and deploy following the workflow in CLAUDE.md