Simplify Backup Page "Alkalmazás adatok" Section

This commit is contained in:
2026-02-17 16:31:36 +01:00
parent a4713c054b
commit 6b27753b40
2 changed files with 157 additions and 344 deletions
+3 -2
View File
@@ -101,8 +101,9 @@ git add -A && git commit -m "<descriptive message>" && git push
### Step 2: Build + push the container image on the build server ### Step 2: Build + push the container image on the build server
The build server (192.168.0.180) has the build toolchain. The version tag should be incremented The build server (192.168.0.180) has the build toolchain. The version tag should be incremented from the current running version.
from the current running version.
!! Important: use "kisfenyo" user for SSH, as written below
First, check the current running version: First, check the current running version:
```bash ```bash
+153 -341
View File
@@ -1,392 +1,204 @@
# TASK — v0.11.9 UI Polish Fixes # TASK — Simplify Backup Page "Alkalmazás adatok" Section
## Context ## Goal
These are UI-only fixes for the deploy/settings page backup section introduced in v0.11.8. No backend changes needed. All changes are in `deploy.html` and `style.css`. Replace the current complex app data section on the backup page (checkboxes, paths, docker volumes, save button) with a simple, read-only status list of all deployed apps.
**Important design principle:** Use minimal emojis in the UI. The project prefers a clean, professional look. Replace emoji indicators with text or CSS-styled elements instead. ## Current state (v0.11.9)
## Files to modify The backup page shows an "Alkalmazás adatok" section with:
- Checkboxes per app to toggle backup on/off
- Full HDD path listings with sizes
- Docker volume names with "(nem mentett)" labels
- DB dump status per app
- A "Mentés" (save) button
- `internal/web/templates/deploy.html` **Problems:**
- `internal/web/templates/style.css` - Too much detail for the customer — confusing
- `internal/web/templates/backups.html` (emoji cleanup in cross-drive summary section) - Docker volume names shown as "nem mentett" can mislead users into thinking DB data isn't backed up (it is, via DB dump)
- Backup enable/disable should be configured on the app's own settings page, not here
- The section should be informational only on this page
--- ## Desired state
## Fix 1: Spacing between cards and "Automatikusan generált értékek" A clean, read-only list of ALL deployed apps (including those without user data) showing a simple status per app:
**Problem:** No clear visual separation between the last card above the deploy form (`deploy-cross-drive` or `deploy-stale-data`) and the "Automatikusan generált értékek" section inside `.deploy-form`. ```
┌────────────────────────────────────────────────────────┐
**Root cause:** `.deploy-cross-drive` has `margin-bottom: 1rem` which doesn't provide enough separation before the next card. When stale data card exists without cross-drive, it's also tight. │ Alkalmazás adatok │
│ Az alkalmazások felhasználói adatainak mentési │
**Fix in `style.css`:** │ állapota. Beállítás az alkalmazás oldalán. │
│ │
```css │ Immich Külső tárhely (hdd_1) ● Aktív │
/* Change margin-bottom from 1rem to 1.5rem */ │ Paperless-ngx Külső tárhely (hdd_p.) ○ Inaktív │
.deploy-cross-drive { │ Gokapi — N/A │
/* ... existing ... */ │ Mealie — N/A │
margin-bottom: 1.5rem; /* was 1rem */ │ RoMM Külső tárhely (hdd_p.) ○ Inaktív │
} └────────────────────────────────────────────────────────┘
``` ```
No change needed for `.deploy-stale-data` — it already has `margin-bottom: 1.5rem`. But verify the margin is actually applied (check if another element is overriding it or if the stale data card is inside a container that collapses margins). Each app name links to its deploy/settings page where backup can be configured.
--- **Status indicators (no emoji, just styled text/dots):**
- `● Aktív` — green dot + text — backup enabled for this app (has HDD data and toggle is on)
- `○ Inaktív` — gray dot + text — has HDD data but backup not enabled
- `— N/A` — muted dash + text — no user data folder, backup not applicable (this is fine, not a warning)
## Fix 2: Rename restic method + add info tooltip on "Módszer" **Optional:** For apps with "Aktív" status, show the data size in muted text next to the storage label (e.g., `47.9 MB`).
**Problem:** "Verziózott mentés (restic)" doesn't highlight the most important differentiator (encryption). Users should also understand the tradeoffs before picking. ## Changes
**Fix in `deploy.html` — method dropdown (around line 16934-16942):** ### 1. `backups.html` — Replace Section 4
Replace everything from `<!-- Section 4: App data backup toggles -->` through the closing `{{end}}` (lines 16199-16247) with:
Replace:
```html ```html
<div class="settings-row"> <!-- Section 4: App data backup status (read-only) -->
<span class="settings-label">Módszer</span> {{if .Backup.AppDataInfo}}
<select name="cross_drive_method" class="form-control" style="max-width:20rem"> <div class="backup-section-card">
<option value="rsync" {{if and .CrossDriveConfig (eq .CrossDriveConfig.Method "rsync")}}selected{{end}}> <h3>Alkalmazás adatok</h3>
Egyszerű másolat (rsync) <p class="backup-section-desc">Az alkalmazások felhasználói adatainak mentési állapota. Beállítás az alkalmazás oldalán.</p>
</option> <div class="app-backup-list">
<option value="restic" {{if and .CrossDriveConfig (eq .CrossDriveConfig.Method "restic")}}selected{{end}}> {{range .Backup.AppDataInfo}}
Verziózott mentés (restic) <div class="app-backup-item">
</option> <div class="app-backup-header">
</select> <a href="/stacks/{{.StackName}}/deploy" class="app-backup-name-link">{{.DisplayName}}</a>
</div> <div class="app-backup-status-row">
``` {{if .HasHDDData}}
{{if .StorageLabel}}<span class="meta-badge meta-badge-storage">{{.StorageLabel}}</span>{{end}}
With: {{if .BackupEnabled}}
```html <span class="app-backup-size mono">{{.HDDSizeHuman}}</span>
<div class="settings-row"> <span class="app-backup-status app-backup-active">Aktív</span>
<span class="settings-label">
Módszer
<span class="info-tooltip" tabindex="0">
<span class="info-icon">i</span>
<span class="info-tooltip-text">
<strong>Egyszerű másolat (rsync):</strong> Tükörszerű másolat, a fájlok közvetlenül böngészhetők.
Nem titkosított, nem verziózott — mindig a legfrissebb állapotot tartalmazza.
<br><br>
<strong>Titkosított mentés (restic):</strong> Titkosított, tömörített, verziózott mentés.
Korábbi állapotok visszaállíthatók. Nem böngészhető közvetlenül —
visszaállításhoz a vezérlőpult szükséges.
</span>
</span>
</span>
<select name="cross_drive_method" class="form-control" style="max-width:20rem">
<option value="rsync" {{if and .CrossDriveConfig (eq .CrossDriveConfig.Method "rsync")}}selected{{end}}>
Egyszerű másolat (rsync)
</option>
<option value="restic" {{if and .CrossDriveConfig (eq .CrossDriveConfig.Method "restic")}}selected{{end}}>
Titkosított mentés (restic)
</option>
</select>
</div>
```
**Add to `style.css`:**
```css
/* Info tooltip (i icon with hover popup) */
.info-tooltip {
position: relative;
display: inline-flex;
align-items: center;
margin-left: .35rem;
cursor: help;
}
.info-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid var(--text-muted);
color: var(--text-muted);
font-size: .65rem;
font-weight: 700;
font-style: italic;
font-family: Georgia, serif;
line-height: 1;
}
.info-tooltip-text {
display: none;
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
width: 320px;
padding: .75rem 1rem;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: var(--radius);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
font-size: .8rem;
font-weight: 400;
line-height: 1.5;
color: var(--text-secondary);
z-index: 100;
white-space: normal;
}
/* Show on hover or focus (for keyboard) */
.info-tooltip:hover .info-tooltip-text,
.info-tooltip:focus .info-tooltip-text,
.info-tooltip:focus-within .info-tooltip-text {
display: block;
}
/* Arrow pointing down from tooltip */
.info-tooltip-text::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: var(--border-color);
}
```
---
## Fix 3: Cursor on "Napi mentésbe foglalás" label
**Problem:** The `<label class="toggle">` wrapping the disabled checkbox uses `cursor: pointer` from the `.toggle` class, making it look clickable when it's not.
**Fix in `deploy.html` (around line 16886-16890):**
Replace:
```html
<div class="cross-drive-nightly">
<label class="toggle">
<input type="checkbox" id="app-backup-enabled" {{if .AppBackupEnabled}}checked{{end}} disabled>
<span class="toggle-label">Napi mentésbe foglalás (restic, helyi)</span>
</label>
```
With:
```html
<div class="cross-drive-nightly">
<div class="cross-drive-nightly-status">
{{if .AppBackupEnabled}}
<span class="nightly-status-indicator nightly-enabled"></span>
{{else}} {{else}}
<span class="nightly-status-indicator nightly-disabled"></span> <span class="app-backup-status app-backup-inactive">Inaktív</span>
{{end}}
{{else}}
<span class="app-backup-status app-backup-na">N/A</span>
{{end}} {{end}}
<span class="toggle-label">Napi mentésbe foglalás (restic, helyi)</span>
</div> </div>
</div>
</div>
{{end}}
</div>
</div>
{{end}}
``` ```
This replaces the disabled checkbox with a simple colored dot indicator — green if enabled, gray if not. Not clickable, not a checkbox, no confusing cursor. **Key differences from current:**
- No `<form>`, no checkboxes, no submit button
- No HDD paths, no Docker volume names, no DB dump notes
- No "app-backup-notice" about Docker volumes
- App name is a link to its deploy page
- Simple status indicator per app
**Add to `style.css`:** ### 2. `style.css` — Update styles
Keep existing `.app-backup-list` and `.app-backup-item` styles. Add/modify:
```css ```css
/* Nightly backup status indicator (non-interactive) */ /* App backup status list (read-only on backup page) */
.cross-drive-nightly-status { .app-backup-name-link {
font-weight: 500;
font-size: .9rem;
color: var(--text-primary);
text-decoration: none;
}
.app-backup-name-link:hover {
color: var(--accent-blue);
text-decoration: underline;
}
.app-backup-status-row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: .5rem; gap: .5rem;
} }
.nightly-status-indicator { .app-backup-status {
font-size: .8rem;
font-weight: 500;
display: inline-flex;
align-items: center;
gap: .35rem;
}
.app-backup-status::before {
content: '';
display: inline-block; display: inline-block;
width: 10px; width: 8px;
height: 10px; height: 8px;
border-radius: 50%; border-radius: 50%;
flex-shrink: 0; flex-shrink: 0;
} }
.nightly-enabled { .app-backup-active {
color: var(--green);
}
.app-backup-active::before {
background: var(--green); background: var(--green);
box-shadow: 0 0 4px rgba(35, 134, 54, 0.4); box-shadow: 0 0 4px rgba(35, 134, 54, 0.4);
} }
.nightly-disabled { .app-backup-inactive {
background: var(--text-muted); color: var(--text-muted);
opacity: 0.5; }
.app-backup-inactive::before {
border: 1px solid var(--text-muted);
background: transparent;
width: 6px;
height: 6px;
}
.app-backup-na {
color: var(--text-muted);
}
.app-backup-na::before {
content: '—';
width: auto;
height: auto;
border-radius: 0;
background: none;
border: none;
box-shadow: none;
font-size: .8rem;
} }
``` ```
--- **Remove unused CSS classes** (no longer needed — these were for the old section):
- `.app-backup-toggle`
- `.app-backup-disabled-icon`
- `.app-backup-details`
- `.app-backup-path`
- `.app-backup-volume`
- `.app-backup-dbinfo`
- `.app-backup-actions`
- `.app-backup-notice`
## Fix 4: Progressive disclosure — disable config fields until enabled Only remove them if they're not used elsewhere. Search the templates first.
**Problem:** Users see the destination/method/schedule dropdowns and might think the backup is already configured/active, even though the "Engedélyezve" checkbox is unchecked. ### 3. Handlers — keep backend as-is
**Fix in `deploy.html` — add JS to toggle field states:** The `POST /settings/app-backup` endpoint and the `DiscoverAppData()` function should remain — the per-app backup toggle still works from the app's deploy/settings page. We're only removing the UI from the centralized backup page.
Add `onchange` handler to the enabled checkbox and `disabled` attribute to the select fields: The `AppDataInfo` data is still populated and still needed — we use `.HasHDDData`, `.BackupEnabled`, `.StorageLabel`, `.HDDSizeHuman`, `.StackName`, and `.DisplayName` in the new simplified template.
```html ### 4. Ensure ALL deployed apps appear
<div class="settings-row">
<span class="settings-label">Engedélyezve</span>
<label class="toggle" style="margin:0">
<input type="checkbox" name="cross_drive_enabled" id="cross-drive-enabled"
{{if and .CrossDriveConfig .CrossDriveConfig.Enabled}}checked{{end}}
onchange="toggleCrossDriveFields()">
<span class="toggle-label">Igen</span>
</label>
</div>
<div class="settings-row">
<span class="settings-label">Cél tárhely</span>
<select name="cross_drive_dest" id="cd-dest" class="form-control cross-drive-field" style="max-width:20rem"
{{if not (and .CrossDriveConfig .CrossDriveConfig.Enabled)}}disabled{{end}}>
...options...
</select>
</div>
<div class="settings-row">
<span class="settings-label">
Módszer
<span class="info-tooltip" tabindex="0">...</span>
</span>
<select name="cross_drive_method" id="cd-method" class="form-control cross-drive-field" style="max-width:20rem"
{{if not (and .CrossDriveConfig .CrossDriveConfig.Enabled)}}disabled{{end}}>
...options...
</select>
</div>
<div class="settings-row">
<span class="settings-label">Ütemezés</span>
<select name="cross_drive_schedule" id="cd-schedule" class="form-control cross-drive-field" style="max-width:20rem"
{{if not (and .CrossDriveConfig .CrossDriveConfig.Enabled)}}disabled{{end}}>
...options...
</select>
</div>
```
Add JS function (inside the existing `<script>` block at the bottom of deploy.html): Currently, `DiscoverAppData()` iterates `provider.ListDeployedStacks()` which should include all deployed apps. Verify that apps without HDD data (like Gokapi, Mealie) also appear in the list — they should since `.NeedsHDD` can be false and they'd still be in the output with `HasHDDData: false`.
```javascript If some apps are missing, the issue is in `ListDeployedStacks()` filtering — make sure it returns all deployed stacks, not just HDD-capable ones.
function toggleCrossDriveFields() {
var enabled = document.getElementById('cross-drive-enabled').checked;
var fields = document.querySelectorAll('.cross-drive-field');
for (var i = 0; i < fields.length; i++) {
fields[i].disabled = !enabled;
}
}
```
**Important:** The `disabled` attribute prevents form submission of those fields. The backend handler for `POST /settings/cross-backup/{name}` must handle missing form values gracefully — if `cross_drive_enabled` is unchecked (not in form data), set `Enabled: false` and preserve existing dest/method/schedule values from settings (don't reset them to empty strings just because they weren't submitted).
Check `internal/web/handlers.go` (or `internal/api/router.go`) — the `saveCrossBackupConfig` handler. If it reads form values like:
```go
cfg.DestinationPath = req.FormValue("cross_drive_dest")
cfg.Method = req.FormValue("cross_drive_method")
```
Then when disabled fields aren't submitted, these would be empty strings. Fix: only update those fields if enabled is true, otherwise preserve existing config:
```go
enabled := req.FormValue("cross_drive_enabled") == "on"
// Load existing config to preserve values when disabled
existing := s.settings.GetCrossDriveConfig(name)
cfg := settings.CrossDriveBackup{
Enabled: enabled,
}
if enabled {
// Read from form
cfg.DestinationPath = req.FormValue("cross_drive_dest")
cfg.Method = req.FormValue("cross_drive_method")
cfg.Schedule = req.FormValue("cross_drive_schedule")
} else if existing != nil {
// Preserve existing settings when disabling
cfg.DestinationPath = existing.DestinationPath
cfg.Method = existing.Method
cfg.Schedule = existing.Schedule
}
// Always preserve runtime state
if existing != nil {
cfg.LastRun = existing.LastRun
cfg.LastStatus = existing.LastStatus
cfg.LastError = existing.LastError
cfg.LastDuration = existing.LastDuration
cfg.LastSizeHuman = existing.LastSizeHuman
}
```
---
## Fix 5: Remove/reduce emojis
**Problem:** Too many emoji throughout the UI. Replace with text or CSS-styled elements.
### deploy.html changes:
| Location | Current | Replace with |
|----------|---------|-------------|
| Line ~16884 h4 | `🔒 Biztonsági mentés` | `Biztonsági mentés` |
| Line ~16902 warning | `⚠️ {{.BackupDestWarning}}` | `{{.BackupDestWarning}}` (the `.alert-warning` class already visually marks it as warning) |
| Line ~16964 status ok | `✅ Sikeres` | `Sikeres` |
| Line ~16964 status error | `❌ Hiba:` | `Hiba:` |
| Line ~16964 status running | `⏳ Fut...` | `Fut...` |
| Line ~16982 bottom hint | `⚠️ A cél meghajtó legyen...` | `A cél meghajtó legyen...` (already inside form-hint, visually distinct) |
| Stale data delete button | `🗑️ Korábbi adatok törlése` | `Korábbi adatok törlése` |
| Stale data h4 | `🗑️ Korábbi adatok` (if emoji present) | `Korábbi adatok` |
### backups.html cross-drive summary section changes:
| Location | Current | Replace with |
|----------|---------|-------------|
| Status ok badge | `✅ {{.LastRunShort}}` | `{{.LastRunShort}}` (use `.meta-badge-ok` class for green) |
| Status error badge | `❌ Hiba` | `Hiba` (use `.meta-badge-fail` class for red) |
| Running badge | `⏳ Fut...` | `Fut...` |
| Schedule badge | `⏰ {{.ScheduleLabel}}` | `{{.ScheduleLabel}}` |
| Unconfigured apps warning | `⚠️ {{len ...}}` | `{{len ...}}` (already in yellow-colored div) |
**Note:** The `.alert-warning` class already provides visual differentiation (yellow/orange background/border), and `.meta-badge-ok`/`.meta-badge-fail` provide green/red colors. Emojis are redundant with these CSS classes.
### Also check for any remaining emoji in:
- `stacks.html` — if any status emojis were left
- `backups.html` — the existing sections (db dumps, etc.)
---
## Fix 6 (bonus): "Automatikusan generálva" badge also uses emoji
In the auto-generated values section (line ~17031):
```html
<span class="auto-generated-badge">✓ Automatikusan generálva</span>
```
This is fine — the checkmark (`✓`) is a Unicode character, not an emoji. Leave as-is.
---
## Summary of visual outcome
**Before (v0.11.8):**
- Disabled checkbox that looks clickable
- Pointer cursor on non-interactive label
- All form fields visible/enabled even when backup disabled
- Emoji scattered throughout
- No explanation of rsync vs restic
- Tight spacing between sections
**After (v0.11.9):**
- Clean green/gray dot indicator for nightly backup status
- Default cursor on non-interactive elements
- Dropdowns grayed out until "Engedélyezve" is checked → clear progressive disclosure
- No emoji — clean professional look using CSS classes for visual feedback
- Info tooltip on "Módszer" explaining both options clearly
- Proper spacing between all sections
- "Titkosított mentés" label better communicates restic's key advantage
## Testing ## Testing
1. Visit deployed app page (e.g., `/stacks/immich/deploy`) 1. Visit `/backups` page
2. Verify spacing between all cards is consistent 2. All deployed apps should appear in the list (Immich, Paperless-ngx, Gokapi, Mealie, RoMM, etc.)
3. Verify no emoji visible in the backup section 3. Apps with backup enabled show green dot + "Aktív" + size
4. Verify nightly backup shows green dot (if enabled) or gray dot (if not) 4. Apps with HDD data but backup disabled show hollow dot + "Inaktív"
5. Verify cursor doesn't change to pointer on the nightly status line 5. Apps without HDD data show dash + "N/A"
6. Uncheck "Engedélyezve" → dropdowns should become disabled/grayed 6. Clicking app name navigates to `/stacks/{name}/deploy`
7. Check "Engedélyezve" → dropdowns should become active 7. No checkboxes, no paths, no volumes, no save button visible
8. Save with "Engedélyezve" unchecked → verify existing config preserved (check settings.json) 8. The per-app backup toggle on the deploy page still works (toggle on backup page → save → return to backup page → status updated)
9. Hover/focus on the (i) icon next to "Módszer" → tooltip appears with explanation
10. Check backup page → no emoji in cross-drive summary section