feat(webui): match Migrate tab to app-detail tab design
Give the fleet Overview › Migrate tab the same in-content header + sub-tab styling the per-app detail tabs use: - Add a .config-title header (icon + title + description) inside the Migrate pane, above the Restore/Peers sub-tabs, and hide the generic floating fleet header for Migrate (mirrors how Backups already supplies its own heading). - Make the .tab-button icon↔label gap explicit (flex + 6px gap) so sub-tabs render identically whether or not the markup has whitespace between the emoji and name spans; align the Backups sub-tab strip gap to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
bb6db43392
commit
f6f29bf68b
@ -317,6 +317,13 @@
|
|||||||
<div class="tab-pane" data-tab="improvements" id="ov-pane-improvements"></div>
|
<div class="tab-pane" data-tab="improvements" id="ov-pane-improvements"></div>
|
||||||
<div class="tab-pane" data-tab="backups" id="ov-pane-backups"></div>
|
<div class="tab-pane" data-tab="backups" id="ov-pane-backups"></div>
|
||||||
<div class="tab-pane" data-tab="migrate" id="ov-pane-migrate">
|
<div class="tab-pane" data-tab="migrate" id="ov-pane-migrate">
|
||||||
|
<!-- In-content header (mirrors the per-app Config tab's .config-title:
|
||||||
|
icon + title + description sit inside the pane, above the sub-tabs).
|
||||||
|
The generic fleet header is hidden for this tab (.ov-migrate-active). -->
|
||||||
|
<div class="config-title">
|
||||||
|
<h3>🔀 Migrate</h3>
|
||||||
|
<p>Move apps in from another LibrePortal, and manage the peers you share backup locations with.</p>
|
||||||
|
</div>
|
||||||
<!-- Cross-host area: nested segmented sub-tabs (Config-tab design). -->
|
<!-- Cross-host area: nested segmented sub-tabs (Config-tab design). -->
|
||||||
<div class="tabs-wrapper ov-subtabs">
|
<div class="tabs-wrapper ov-subtabs">
|
||||||
<div class="tabs-list">
|
<div class="tabs-list">
|
||||||
|
|||||||
@ -135,7 +135,8 @@
|
|||||||
/* The Backups tab mounts the real BackupPage. Its own page-header replaces the
|
/* The Backups tab mounts the real BackupPage. Its own page-header replaces the
|
||||||
generic fleet header, and its left sidebar is restyled into a horizontal
|
generic fleet header, and its left sidebar is restyled into a horizontal
|
||||||
nested tab strip so the whole thing reads as tabs-within-tabs. */
|
nested tab strip so the whole thing reads as tabs-within-tabs. */
|
||||||
#overview-view.ov-backups-active .overview-header { display: none; }
|
#overview-view.ov-backups-active .overview-header,
|
||||||
|
#overview-view.ov-migrate-active .overview-header { display: none; }
|
||||||
|
|
||||||
#overview-view #ov-pane-backups .backup-layout { display: block; }
|
#overview-view #ov-pane-backups .backup-layout { display: block; }
|
||||||
#overview-view #ov-pane-backups .backup-layout > .sidebar {
|
#overview-view #ov-pane-backups .backup-layout > .sidebar {
|
||||||
@ -164,7 +165,7 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 8px;
|
gap: 6px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 12px 14px;
|
padding: 12px 14px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@ -117,10 +117,15 @@ class OverviewManager {
|
|||||||
|
|
||||||
_applyTab(id) {
|
_applyTab(id) {
|
||||||
if (this.tabs) this.tabs.switch(id);
|
if (this.tabs) this.tabs.switch(id);
|
||||||
// The Backups tab embeds the full backup center, which brings its own header
|
// Backups embeds the full backup center (its own header + nested sub-tab
|
||||||
// and a nested sub-tab strip — hide the generic fleet header for it.
|
// strip) and Migrate carries its own in-content .config-title header above
|
||||||
|
// its sub-tabs — both supply their own heading, so hide the generic fleet
|
||||||
|
// header for them.
|
||||||
const root = document.getElementById('overview-view');
|
const root = document.getElementById('overview-view');
|
||||||
if (root) root.classList.toggle('ov-backups-active', id === 'backups');
|
if (root) {
|
||||||
|
root.classList.toggle('ov-backups-active', id === 'backups');
|
||||||
|
root.classList.toggle('ov-migrate-active', id === 'migrate');
|
||||||
|
}
|
||||||
this.updateHeader(id);
|
this.updateHeader(id);
|
||||||
this.renderTab(id);
|
this.renderTab(id);
|
||||||
this.current = id;
|
this.current = id;
|
||||||
|
|||||||
@ -526,7 +526,14 @@ html[data-theme="nebula"]::after {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
/* Lay the icon + label out as flex children with a fixed gap so spacing is
|
||||||
|
identical whether or not the markup has whitespace between the two spans
|
||||||
|
(the per-app Config sub-tabs rely on source whitespace; the Migrate
|
||||||
|
sub-tabs don't — this makes both render the same). */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Task Status Indicator */
|
/* Task Status Indicator */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user