diff --git a/app/src/pages/dashboard/components/AuroraCard.vue b/app/src/pages/dashboard/components/AuroraCard.vue index 7c470b0..063eea7 100644 --- a/app/src/pages/dashboard/components/AuroraCard.vue +++ b/app/src/pages/dashboard/components/AuroraCard.vue @@ -31,7 +31,7 @@ defineProps({ flex-direction: column; height: 100%; /* Deeper than the generic --aurora-card-bg — the Dashboard is now - wrapped in its own frame (windowChrome.js's .aurora-dashboard-frame, + wrapped in its own frame (dashboardFrame.js's .aurora-dashboard-frame, using --aurora-frame-bg), and that's close in tone to --aurora-card-bg for most presets, so cards would nearly disappear into it otherwise. */ background: var(--aurora-card-bg-deep, var(--aurora-card-bg)); diff --git a/app/src/shell/SiteShell.vue b/app/src/shell/SiteShell.vue index 0d4f4ae..bbbfc3e 100644 --- a/app/src/shell/SiteShell.vue +++ b/app/src/shell/SiteShell.vue @@ -3,8 +3,7 @@ import { ref, onMounted } from 'vue'; import Sidebar from './components/Sidebar.vue'; import Toolbar from './components/Toolbar.vue'; import { applyThemePalette, applyFontFamily } from '@/pages/settings/applyLiveTheme.js'; -import { initWindowChrome } from './windowChrome.js'; -import { getMinimizedWindows, removeMinimizedWindow } from './taskbar.js'; +import { initDashboardFrame } from './dashboardFrame.js'; const props = defineProps({ serverData: { @@ -25,21 +24,7 @@ const toggleMenu = () => { localStorage.setItem('aurora-menu-collapsed', collapsed.value ? '1' : '0'); }; -// Every minimized window (taskbar.js persists the list in sessionStorage -// across the page loads minimizing triggers). Rendered as taskbar items at -// the bottom of every page since SiteShell mounts on all of them — clicking -// one navigates back to it and removes just that entry. -const minimizedWindows = ref([]); -const restoreWindow = (win) => { - removeMinimizedWindow(win.id); - window.location.href = win.url; -}; - onMounted(() => { - minimizedWindows.value = getMinimizedWindows(); - // Reserve bottom space for the taskbar (shell-frame.css) so page content - // stops above it instead of running underneath. - document.documentElement.classList.toggle('aurora-has-taskbar', minimizedWindows.value.length > 0); const settings = props.serverData?.settings || {}; // Every theme preset is its own self-contained dark-toned palette now — // no separate light/dark mode, so this class is always on. It's kept @@ -49,7 +34,7 @@ onMounted(() => { applyThemePalette(settings.theme_preset || 'indigo'); applyCollapsed(); applyFontFamily(settings.font_family); - initWindowChrome(props.serverData?.adminUrl); + initDashboardFrame(); // Signal the shell is live: reveals the framed content and commits to // keeping native chrome hidden (the PHP failsafe stops watching once // aurora-ready is present). @@ -73,74 +58,13 @@ onMounted(() => { :server-data="serverData" @toggle-menu="toggleMenu" /> -
diff --git a/app/src/shell/dashboardFrame.js b/app/src/shell/dashboardFrame.js new file mode 100644 index 0000000..2b5f42a --- /dev/null +++ b/app/src/shell/dashboardFrame.js @@ -0,0 +1,35 @@ +/** + * Structural setup for the takeover Dashboard. + * + * DashboardTakeover.php renders the dashboard into a separate + * #aurora-admin-dashboard-root sibling (above the hidden #wpbody), so unlike + * every other page it never sits inside #wpbody-content and never got that + * element's card frame. Wrap it in .aurora-dashboard-frame so it gets the + * same card treatment, and pull the custom admin notices + * (Notices::render_for_dashboard(), printed as a sibling just before the + * mount point) into that frame so they render as part of the card. + * + * This is the only DOM restructuring the shell does — there is no window + * chrome (title bars, traffic-light controls, minimize taskbar); that whole + * macOS-window metaphor was removed. + */ +export function initDashboardFrame() { + const dashboardRoot = document.getElementById('aurora-admin-dashboard-root'); + if (!dashboardRoot) { + return; + } + // Dedupe: if SiteShell re-mounts, don't wrap a second time. + if (dashboardRoot.parentNode.querySelector('.aurora-dashboard-frame')) { + return; + } + + const frame = document.createElement('div'); + frame.className = 'aurora-dashboard-frame'; + dashboardRoot.parentNode.insertBefore(frame, dashboardRoot); + + const notices = document.getElementById('aurora-admin-dashboard-notices'); + if (notices) { + frame.appendChild(notices); + } + frame.appendChild(dashboardRoot); +} diff --git a/app/src/shell/shell-frame.css b/app/src/shell/shell-frame.css index d8fef43..dc212f4 100644 --- a/app/src/shell/shell-frame.css +++ b/app/src/shell/shell-frame.css @@ -14,13 +14,6 @@ :root { --aurora-sidebar-w: 264px; --aurora-toolbar-h: 56px; - /* SiteShell.vue's taskbar, shown only while a window is minimized - (html.aurora-has-taskbar toggles the bottom space reserved for it). */ - --aurora-taskbar-h: 56px; - /* Height of the strip reserved at the top of the block editor's frame - for .aurora-winbar--editor's traffic-light dots (a sibling element, - not a child of the skeleton — see windowChrome.js). */ - --aurora-editor-winbar-h: 44px; /* Space between the sidebar card and the browser's left/top/bottom edges (Sidebar.vue) — the toolbar and #wpcontent offsets below add the same amount so nothing overlaps the floating sidebar. */ @@ -170,12 +163,6 @@ html.aurora-ready #site-editor { border-radius: var(--aurora-radius-lg); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06); transition: left 0.2s ease; - /* Reserves a strip at the top for .aurora-winbar--editor's dots (a - sibling, not a child — see windowChrome.js) so they sit in their own - clear space instead of overlapping the editor's own logo/toolbar row. - border-box so the padding comes out of the top/left/right/bottom - inset box already defined above, rather than adding to it. */ - padding-top: var(--aurora-editor-winbar-h); box-sizing: border-box; /* border-radius alone doesn't clip children — Gutenberg's own white canvas background ran straight past the rounded bottom corners as a @@ -250,48 +237,6 @@ html.aurora-ready body.post-php #wpbody-content { padding: 0 !important; } -html.aurora-ready body.block-editor-page #wpbody-content > .aurora-winbar, -html.aurora-ready body.post-new-php #wpbody-content > .aurora-winbar, -html.aurora-ready body.post-php #wpbody-content > .aurora-winbar { - display: none !important; -} - -/* SiteShell.vue's taskbar floats along the bottom edge (inset by - --aurora-sidebar-gap, same as the sidebar) only while a window is - minimized. A plain margin-bottom only guarantees a gap once the page is - scrolled all the way down — content taller than the viewport still - renders underneath the fixed taskbar on first paint, since a fixed - element doesn't reserve space from the rest of the page's flow. Instead, - cap the content box's own height to whatever's actually left between the - toolbar and the taskbar and let *it* scroll internally — the same way - the toolbar's reserved space at the top never lets content start behind - it, not just "eventually scroll clear of it". */ -html.aurora-has-taskbar #wpbody-content, -html.aurora-has-taskbar .aurora-dashboard-frame { - /* #wpbody-content's base rule sets min-height: calc(100vh - toolbar-h - - 40px) for the normal (no-taskbar) case — per spec, when min-height is - larger than max-height, min-height always wins and max-height is - silently ignored. Without this override the box kept sizing to that - taller min-height regardless of the taskbar, which is why the - max-height below appeared to do nothing. */ - min-height: 0; - max-height: calc( - 100vh - var(--aurora-toolbar-h) - 16px - 24px - var(--aurora-taskbar-h) - - var(--aurora-sidebar-gap) * 2 - ); - overflow-y: auto; - overflow-anchor: none; -} - -/* The block editor's skeleton is already positioned with fixed insets - (top/left/right/bottom) rather than margin, so reserving taskbar space - is just moving its bottom inset in — no max-height/overflow trick - needed there, unlike the margin-based elements above. */ -html.aurora-has-taskbar .interface-interface-skeleton, -html.aurora-has-taskbar #site-editor { - bottom: calc(24px + var(--aurora-taskbar-h) + var(--aurora-sidebar-gap) * 2) !important; -} - /* Theme installer preview ("Add Themes" > click a theme > full "Preview & Install" overlay, theme-install.php). WP core's own .wp-full-overlay component (shared with the Customizer, but only .theme-install-overlay @@ -355,86 +300,21 @@ html.aurora-ready .theme-install-overlay.collapsed { html.aurora-ready .theme-install-overlay .wp-full-overlay-sidebar { left: calc(var(--aurora-sidebar-w) + var(--aurora-sidebar-gap) * 2 + 24px) !important; - top: calc(var(--aurora-toolbar-h) + 16px + var(--aurora-editor-winbar-h)) !important; + top: calc(var(--aurora-toolbar-h) + 16px) !important; bottom: 24px !important; height: auto !important; border-top-left-radius: var(--aurora-radius-lg); } html.aurora-ready .theme-install-overlay .wp-full-overlay-main { - top: var(--aurora-editor-winbar-h) !important; + top: 0 !important; border-top-right-radius: var(--aurora-radius-lg); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06); } -/* macOS-style title bar (windowChrome.js). Most pages get it injected as - the first child of #wpbody-content — negative margins cancel the 32px - padding above so it spans edge-to-edge like a real window title bar. */ -.aurora-winbar { - display: flex; - align-items: center; - gap: 8px; -} -.aurora-winbar--editor { - position: fixed; - /* Centered vertically within the skeleton's reserved top strip - (--aurora-editor-winbar-h), inset from its left edge to line up with - the padding every other title bar uses. */ - top: calc( - var(--aurora-toolbar-h) + 16px + (var(--aurora-editor-winbar-h) - 12px) / 2 - ); - left: calc(var(--aurora-sidebar-w) + var(--aurora-sidebar-gap) * 2 + 24px + 20px); - height: 12px; - padding: 0; - background: transparent; - border: 0; - border-radius: 0; - box-shadow: none; - z-index: 100000; - transition: left 0.2s ease; -} -#wpbody-content > .aurora-winbar { - margin: -32px -32px 20px -32px; - padding: 14px 16px; - border-bottom: 1px solid var(--aurora-frame-border); - border-top-left-radius: var(--aurora-radius-lg); - border-top-right-radius: var(--aurora-radius-lg); -} -.aurora-winbar__crumb { - margin-left: 8px; - font-size: 0.75rem; - font-weight: 500; - color: var(--aurora-text-muted); - text-decoration: none; - white-space: nowrap; -} -.aurora-winbar__crumb:hover { - color: var(--aurora-text); -} -.aurora-winbar__dot { - width: 12px; - height: 12px; - border-radius: 50%; - border: none; - padding: 0; - cursor: pointer; -} -.aurora-winbar__dot:hover { - filter: brightness(1.15); -} -.aurora-winbar__dot--close { - background: #ff5f57; -} -.aurora-winbar__dot--minimize { - background: #febc2e; -} -.aurora-winbar__dot--maximize { - background: #28c840; -} - /* The Dashboard bypasses #wpbody-content (DashboardTakeover.php renders - it into a separate sibling — see windowChrome.js), so it never got the - card frame every other page has. windowChrome.js wraps the bar + the - dashboard's mount point in this div to give it the same treatment. */ + it into a separate sibling — see dashboardFrame.js), so it never got the + card frame every other page has. dashboardFrame.js wraps the dashboard's + mount point in this div to give it the same treatment. */ .aurora-dashboard-frame { background: var(--aurora-frame-bg); border: 1px solid var(--aurora-frame-border); @@ -444,25 +324,19 @@ html.aurora-ready .theme-install-overlay .wp-full-overlay-main { box-sizing: border-box; /* Same unconditional height cap as #wpbody-content's base rule — this element never got it, since the Dashboard bypasses #wpbody-content - entirely (a separate sibling — see windowChrome.js) and only had the - taskbar-present variant below. Once html/body were locked to - overflow:hidden (to kill a phantom document-level scrollbar on - another page), the dashboard's content past the first ~1500px became - completely unreachable: no internal scroll here, and no document + entirely (a separate sibling — see dashboardFrame.js). Once html/body + were locked to overflow:hidden (to kill a phantom document-level + scrollbar on another page), the dashboard's content past the first + ~1500px became completely unreachable: no internal scroll here, and + no document scroll left to fall back on either. */ max-height: calc(100vh - var(--aurora-toolbar-h) - 40px); overflow-y: auto; overflow-anchor: none; } -.aurora-dashboard-frame > .aurora-winbar { - padding: 14px 20px; - border-bottom: 1px solid var(--aurora-frame-border); - border-top-left-radius: var(--aurora-radius-lg); - border-top-right-radius: var(--aurora-radius-lg); -} /* Custom admin notices (Notices::render_for_dashboard(), reparented in - here by windowChrome.js) — native-dark.css already themes .notice + here by dashboardFrame.js) — native-dark.css already themes .notice elsewhere via #wpbody-content, but that stylesheet isn't loaded on the Dashboard at all (Shell::is_own_page() treats index.php as one of Aurora's own pages), so it needs its own copy of the same treatment @@ -476,41 +350,6 @@ html.aurora-ready .theme-install-overlay .wp-full-overlay-main { margin: 16px 20px 0; } -/* Yellow dot: on the Dashboard itself there's nowhere further "home" to - send it, so minimize just collapses the frame down to the title bar in - place — everywhere else, minimize navigates to the dashboard instead - (see windowChrome.js) and SiteShell.vue's taskbar offers a way back. */ -html.aurora-minimized #aurora-admin-dashboard-root { - display: none !important; -} - -/* Green dot: hide Aurora's own chrome (sidebar/toolbar) and let the - content reclaim the full browser window, like restoring a real OS - window to fullscreen. */ -html.aurora-maximized .sidebar, -html.aurora-maximized .toolbar { - display: none !important; -} -html.aurora-ready.aurora-maximized #wpcontent { - margin-left: 0 !important; -} -html.aurora-ready.aurora-maximized .interface-interface-skeleton, -html.aurora-ready.aurora-maximized #site-editor { - top: 0 !important; - left: 0 !important; - right: 0 !important; - bottom: 0 !important; - height: auto !important; - border-radius: 0; -} -html.aurora-maximized .aurora-winbar--editor { - top: calc((var(--aurora-editor-winbar-h) - 12px) / 2); - left: 20px; -} -html.aurora-maximized .aurora-taskbar { - left: 0 !important; -} - /* The settings page renders its own two boxed panels, so drop the outer content frame there — leaving just those panels on the dark backdrop. No background here: #wpbody-content is inset from the sidebar/gutter, diff --git a/app/src/shell/taskbar.js b/app/src/shell/taskbar.js deleted file mode 100644 index 672749e..0000000 --- a/app/src/shell/taskbar.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Tracks every "minimized" window across page loads. Aurora is a normal - * multi-page WP admin (each nav is a full page load), so a real taskbar - * needs to survive navigation — sessionStorage (tab-scoped, clears when the - * tab closes) is enough for that. Stored as a list, not a single slot — - * minimizing a second page used to silently overwrite the first one's - * entry, so only the most recent minimize ever showed up in the taskbar. - */ -const STORAGE_KEY = 'aurora-minimized-windows'; - -export function getMinimizedWindows() { - try { - const raw = sessionStorage.getItem(STORAGE_KEY); - const parsed = raw ? JSON.parse(raw) : []; - return Array.isArray(parsed) ? parsed : []; - } catch { - return []; - } -} - -function saveMinimizedWindows(list) { - try { - sessionStorage.setItem(STORAGE_KEY, JSON.stringify(list)); - } catch { - /* sessionStorage unavailable (e.g. private mode) — minimize just won't persist */ - } -} - -/** Adds (or, if the same page is already minimized, replaces) an entry. */ -export function addMinimizedWindow(title, url) { - const list = getMinimizedWindows().filter((w) => w.url !== url); - list.push({ id: `${Date.now()}-${Math.random().toString(36).slice(2)}`, title, url }); - saveMinimizedWindows(list); -} - -export function removeMinimizedWindow(id) { - saveMinimizedWindows(getMinimizedWindows().filter((w) => w.id !== id)); -} - -/** - * Best-effort readable label for the current page, used as the taskbar - * item's title. Prefers the page's own on-screen