Fix sub-app permissions bug, add Comments app, support Site Editor
- Root-cause fix for "Sorry, you are not allowed to access this page" on Menu Creator/Activity Log/Role Editor: remove_submenu_page() was corrupting WP core's user_can_access_admin_page() capability lookup. Sub-apps now stay registered in $submenu; MenuSerializer filters them out of the sidebar instead. - Add a 6th sub-app, Comments, with a redirect from native edit-comments.php. - Extend the window-chrome/taskbar framing to the Site Editor (site-editor.php), including a fix for a CSS position:fixed over-constraint bug that let its frame run past the viewport. - Rewrite the taskbar from a single sessionStorage slot to a list so multiple minimized windows are each independently restorable. - Extend native-dark.css coverage to the block editor's own chrome. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b0b0a9999a
commit
8153d4397c
+158
-74
@@ -1,6 +1,6 @@
|
||||
# Aurora Admin v2 — Project Status
|
||||
|
||||
_Last updated: 2026-07-03 (evening session — theme system rebuild + window chrome)_
|
||||
_Last updated: 2026-07-03 (late session — Site Editor support, permissions bug fix, Comments sub-app, taskbar rewrite)_
|
||||
|
||||
## What this project is
|
||||
|
||||
@@ -179,17 +179,29 @@ not a hue applied on top of a shared light/dark base.
|
||||
`app/src/pages/settings/settingsConfig.js`, rendered by
|
||||
`app/src/pages/settings/components/SettingsField.vue` (types: text, toggle,
|
||||
color, image, repeater, multiselect, segmented, remote-sites).
|
||||
- **5 sub-apps** (`admin/src/Pages/SubApps.php` + one PHP feature-class pair
|
||||
- **6 sub-apps** (`admin/src/Pages/SubApps.php` + one PHP feature-class pair
|
||||
each + one Vue page + one Vite entry each) — reachable only via the
|
||||
sidebar's Aurora nav section, not the native WP menu:
|
||||
- Registered via `add_submenu_page('aurora-admin', ...)` then immediately
|
||||
`remove_submenu_page()`'d on a late `admin_menu` hook — the
|
||||
register-but-hide trick: real page/capability/URL, but never appears in
|
||||
WP's native `$submenu` global (so `MenuSerializer` never sees them,
|
||||
nothing to filter there).
|
||||
- Registered via `add_submenu_page('aurora-admin', ...)` (or `'plugins.php'`
|
||||
for Plugins) and **left registered** in WP's native `$submenu` global —
|
||||
**no longer hidden via `remove_submenu_page()`**. An earlier version did
|
||||
call it (the standard register-but-hide trick) but that corrupts WP
|
||||
core's own `user_can_access_admin_page()` capability lookup, which partly
|
||||
depends on the page still being present in `$submenu` to resolve its
|
||||
required capability — removing it caused "Sorry, you are not allowed to
|
||||
access this page" for every user, including admins, on Menu Creator/
|
||||
Activity Log/Role Editor/Comments. Root-caused and fixed this session by
|
||||
deleting `hide_from_native_submenu()` entirely; duplication in the
|
||||
sidebar's native-menu section is instead prevented in
|
||||
`MenuSerializer::serialize()` (see below), which has no such side effect.
|
||||
- All slugs prefixed `aurora-admin-*` so `Shell::is_own_page()`'s existing
|
||||
`strpos($page, "aurora-admin") === 0` check covers them for free (full
|
||||
custom dark theme, `native-dark.css` skipped).
|
||||
custom dark theme, `native-dark.css` skipped). `MenuSerializer::serialize()`
|
||||
skips any submenu slug starting `aurora-admin-` (in addition to already
|
||||
skipping the `aurora-admin` top-level slug) so none of them are
|
||||
duplicated in the sidebar's native-menu section — needed because most are
|
||||
parented under `aurora-admin` (already skipped wholesale) but
|
||||
`aurora-admin-plugins` is parented under the real `plugins.php` menu.
|
||||
- Each page uses the shared two-pane layout `app/src/pages/_shared/AppListShell.vue`
|
||||
(generalized from Settings.vue's box-pair CSS) + `AppListItem.vue` for
|
||||
list rows.
|
||||
@@ -219,14 +231,18 @@ not a hue applied on top of a shared light/dark base.
|
||||
`GET /activity-log?action_type=&object_type=&search=&page=`.
|
||||
- **Plugins** (`admin/src/Rest/PluginsData.php` + `app/src/pages/plugins/Plugins.vue`):
|
||||
custom plugin management list (activate/deactivate/delete), also using
|
||||
`AppListShell.vue`. **Known bug, unresolved**: unlike the other sub-apps,
|
||||
Menu Creator/Activity Log/Role Editor currently throw WordPress's native
|
||||
"Sorry, you are not allowed to access this page" for the logged-in admin
|
||||
user when navigated to directly, while Settings/Plugins/Dashboard work
|
||||
fine — likely a capability-check mismatch in how those three register
|
||||
their submenu pages vs. the working ones. Not yet root-caused; a
|
||||
background investigation task was spawned for it but not completed this
|
||||
session — check for it before re-investigating from scratch.
|
||||
`AppListShell.vue`.
|
||||
- **Comments** (`admin/src/Rest/CommentsData.php` + `app/src/pages/comments/`):
|
||||
newest sub-app, `edit_posts`-gated (not `manage_options` like the others).
|
||||
`SubApps::redirect_native_pages()` (`admin_init`) redirects the native
|
||||
`edit-comments.php` (when hit with no `?page=` param, i.e. a direct nav
|
||||
or an old bookmark/menu link) to `admin.php?page=aurora-admin-comments`.
|
||||
`MenuSerializer::resolve_url()` also maps the `edit-comments.php` slug
|
||||
straight to the Aurora URL so the native-menu-derived sidebar entry (for
|
||||
users who can `edit_posts` but not `manage_options`, so don't see the
|
||||
Aurora nav section) still lands on the Aurora page. The Dashboard's
|
||||
comments card (`DashboardData.php`'s `listUrl`) was updated to point at
|
||||
the same Aurora URL instead of the native one.
|
||||
- **Database Explorer** (`admin/src/DatabaseExplorer/`): no custom table —
|
||||
reads real `$wpdb` schema. `GET /db-tables` (SHOW TABLE STATUS),
|
||||
`GET /db-tables/:table` (columns + paginated rows — table name validated
|
||||
@@ -273,61 +289,108 @@ not a hue applied on top of a shared light/dark base.
|
||||
Known gap: the plugin "More Details" popup renders inside an `<iframe>`
|
||||
pointing at a separate WP page — CSS can't reach into it; would need JS
|
||||
injection into the iframe's own document if that's ever worth fixing.
|
||||
This session also added dark-theme rules for the block editor's own chrome
|
||||
(`.editor-header`/`.edit-post-header`, `.interface-interface-skeleton__sidebar`
|
||||
and its nested `.components-panel`/`.editor-post-status`/
|
||||
`.interface-complementary-area-header`) — found by inspecting the real
|
||||
screen via `computer-use` and drilling into nested elements' computed
|
||||
styles, since `.interface-complementary-area` (nested inside the sidebar)
|
||||
had its own explicit white background the outer rule didn't reach, leaving
|
||||
a white patch below the Tags panel until it was targeted directly. The
|
||||
actual post content canvas is deliberately left untouched (WYSIWYG, matches
|
||||
the front-end).
|
||||
|
||||
## Window chrome (macOS-style title bar + taskbar)
|
||||
|
||||
Added this session, user-requested after seeing a competing plugin's demo.
|
||||
Added earlier this session, user-requested after seeing a competing plugin's
|
||||
demo; extended later the same session to cover the block editor and the Site
|
||||
Editor, and the taskbar was rewritten to support multiple minimized windows.
|
||||
Every page gets a traffic-light title bar; minimizing persists across a full
|
||||
page navigation via a taskbar.
|
||||
|
||||
- `app/src/shell/windowChrome.js`: `initWindowChrome(adminUrl)`, called from
|
||||
`SiteShell.vue::onMounted` (skipped on the block editor — see below).
|
||||
Injects a `.aurora-winbar` div (3 dot buttons) as the first child of
|
||||
`#wpbody-content` — the one container shared by *every* page Aurora
|
||||
manages, native WP pages and all of Aurora's own Vue pages alike, since
|
||||
each Vue entry mounts its root div there. **Exception**: the Dashboard
|
||||
(`DashboardTakeover.php`) renders into a separate `#aurora-admin-dashboard-root`
|
||||
sibling *above* `#wpbody` (which it hides) to fully replace the native
|
||||
dashboard — `#wpbody-content` is empty/collapsed there. `windowChrome.js`
|
||||
detects this and instead wraps the bar + `#aurora-admin-dashboard-root` in
|
||||
a new `.aurora-dashboard-frame` div, giving the Dashboard the same
|
||||
card-frame treatment (`--aurora-frame-bg`, border, radius) every other
|
||||
page already gets from `#wpbody-content` itself.
|
||||
- `app/src/shell/windowChrome.js`: `initWindowChrome(adminUrl)`, called
|
||||
unconditionally from `SiteShell.vue::onMounted` (no longer skipped on the
|
||||
block editor — that special case was removed once the editor got its own
|
||||
handling). Three cases, checked in priority order:
|
||||
1. **Dashboard** (`#aurora-admin-dashboard-root` present) — wraps the bar +
|
||||
the dashboard root in a new `.aurora-dashboard-frame` div, giving it the
|
||||
same card-frame treatment (`--aurora-frame-bg`, border, radius) every
|
||||
other page gets from `#wpbody-content` itself.
|
||||
2. **Block editor / Site Editor** (`isBlockEditorPage()`: body has
|
||||
`block-editor-page`, or the path ends `/post.php` or `/post-new.php` —
|
||||
`site-editor.php` also gets `block-editor-page` on its body, so this
|
||||
already covers it with no JS change needed) — appends a
|
||||
`.aurora-winbar--editor` bar (dots only, no bar surface) directly to
|
||||
`document.body`, since neither editor's real content container is
|
||||
`#wpbody-content`.
|
||||
3. **Everything else** — native WP pages and all of Aurora's own Vue pages,
|
||||
inserted as the first child of `#wpbody-content`.
|
||||
- Red (close): `window.location.href = adminUrl`.
|
||||
- Green (maximize): toggles `html.aurora-maximized` — hides `.sidebar`/
|
||||
`.toolbar`, zeroes `#wpcontent`'s `margin-left` and the block editor
|
||||
skeleton's `left`, so content fills the whole browser window. Toggle again
|
||||
(or minimize) to restore. Nothing persisted — resets on next page load.
|
||||
`.toolbar`, zeroes `#wpcontent`'s `margin-left` and the editor frame's
|
||||
inset, so content fills the whole browser window. Toggle again (or
|
||||
minimize) to restore. Nothing persisted — resets on next page load.
|
||||
- Yellow (minimize): **on the Dashboard itself**, toggles `html.aurora-minimized`
|
||||
which just collapses `#aurora-admin-dashboard-root` down to the bar in
|
||||
place (nowhere further "home" to send it). **On every other page**, calls
|
||||
`taskbar.js`'s `setMinimizedWindow(title, url)` (persists `{title, url}` in
|
||||
`sessionStorage`, tab-scoped) then navigates to the dashboard. Only one
|
||||
minimized window is tracked at a time — this is "minimize sends you home
|
||||
with a way back," not a real window manager.
|
||||
- `SiteShell.vue` reads `taskbar.js`'s `getMinimizedWindow()` on every mount
|
||||
(so the taskbar shows up on whatever page you're on after minimizing) and
|
||||
renders a **full-width docked bar** at the bottom with one pill-shaped
|
||||
item; clicking it clears the sessionStorage entry and navigates back to
|
||||
the stored URL. `html.aurora-has-taskbar` (toggled alongside) reserves
|
||||
bottom margin on `#wpbody-content`/`.aurora-dashboard-frame` equal to
|
||||
`--aurora-taskbar-h` so page content stops above the bar instead of
|
||||
running underneath it. Went through two design iterations (small centered
|
||||
floating pill → back to a full-length bar per explicit user correction —
|
||||
the pill-shaped *item* stayed, just not as the whole bar).
|
||||
- **Block editor exception**: Gutenberg (`post.php`/`post-new.php`) doesn't
|
||||
render inside `#wpcontent`'s normal box model at all — its
|
||||
`.interface-interface-skeleton` is `position: fixed; inset: 0`, anchored to
|
||||
the viewport independent of any margin/padding on ancestors. `SiteShell.vue`
|
||||
detects `document.body.classList.contains('block-editor-page')` and: (a)
|
||||
skips rendering Aurora's own `<Toolbar>` (the editor has its own,
|
||||
equivalent one — stacking both left a gradient seam between them), (b)
|
||||
skips `initWindowChrome()` entirely (`#wpbody-content` is invisible/
|
||||
collapsed there, injecting into it would be dead clutter), (c) insets the
|
||||
skeleton itself via `left`/`top` in `shell-frame.css` so it doesn't render
|
||||
underneath the sidebar. **If a future feature needs to reach the block
|
||||
editor's own chrome**, its real container is `.interface-interface-skeleton`,
|
||||
not `#wpbody-content` — don't assume the normal page structure there.
|
||||
`taskbar.js`'s `addMinimizedWindow(title, url)` then navigates to the
|
||||
dashboard.
|
||||
- **Taskbar rewritten from a single sessionStorage slot to a list**
|
||||
(`app/src/shell/taskbar.js`): minimizing a second page used to silently
|
||||
overwrite the first one's entry, so only the most recent minimize ever
|
||||
showed up. Now `getMinimizedWindows()`/`addMinimizedWindow()` (dedupes by
|
||||
URL)/`removeMinimizedWindow(id)` operate on an array under
|
||||
`sessionStorage['aurora-minimized-windows']`; `SiteShell.vue` `v-for`s over
|
||||
it, rendering one `.aurora-taskbar__item` pill per entry inside a
|
||||
transparent, floating `.aurora-taskbar` bar (inset by `--aurora-sidebar-gap`
|
||||
on all exposed edges, rounded, its own box-shadow — went through a design
|
||||
iteration from a small centered pill back to full-length per explicit user
|
||||
correction, keeping only the pill shape on the individual items). Each item
|
||||
is independently restorable/closable. `currentPageTitle()` prefers the
|
||||
page's own on-screen `<h1>` (`#wpbody-content h1, #aurora-admin-dashboard-root h1`)
|
||||
over `document.title`, since WP's title-tag generation came up empty for
|
||||
Aurora's sub-app pages back when they were still `remove_submenu_page()`'d
|
||||
(see the sub-apps permissions bug above) — `document.title` is still the
|
||||
fallback for pages where that isn't an issue.
|
||||
- **Content-behind-taskbar fix**: `html.aurora-has-taskbar` no longer just
|
||||
adds `margin-bottom` (that only guarantees clearance once scrolled to the
|
||||
very bottom — content taller than the viewport still rendered underneath
|
||||
the fixed taskbar on first paint). Instead it caps `#wpbody-content`'s/
|
||||
`.aurora-dashboard-frame`'s own height via `max-height` + `overflow-y: auto`,
|
||||
same principle as the toolbar's reserved space at the top. This appeared to
|
||||
do nothing at first — `#wpbody-content`'s base rule sets `min-height:
|
||||
calc(100vh - toolbar-h - 40px)`, and per spec `min-height` always wins over
|
||||
a smaller `max-height`; fixed by adding `min-height: 0` to the
|
||||
taskbar-specific override.
|
||||
- **Block editor / Site Editor framing**: neither editor renders inside
|
||||
`#wpcontent`'s normal box model — each has its own fixed, full-viewport
|
||||
root (`.interface-interface-skeleton` itself on `post.php`/`post-new.php`;
|
||||
`#site-editor` on `site-editor.php`, where `.interface-interface-skeleton`
|
||||
is merely `position: relative`, nested inside it — a reset rule puts the
|
||||
nested skeleton back to a plain unpositioned child so the two frames don't
|
||||
stack). `html.aurora-ready .interface-interface-skeleton, html.aurora-ready
|
||||
#site-editor` in `shell-frame.css` frames whichever is the real fixed root
|
||||
with the same insets/background/radius/shadow treatment `#wpbody-content`
|
||||
gets elsewhere, plus `padding-top: var(--aurora-editor-winbar-h)` to
|
||||
reserve a strip for `.aurora-winbar--editor`'s dots and `overflow: hidden`
|
||||
so the rounded corners actually clip the editor's own white canvas
|
||||
background (border-radius alone doesn't clip children). **Known
|
||||
CSS-over-constraint gotcha**: WP core's `.edit-site { height: 100vh; }`
|
||||
class (present on `#site-editor`) means `top`, `height`, and `bottom` are
|
||||
all specified on that box at once — per spec this is over-constrained and
|
||||
`bottom` silently gets recomputed from `top + height` instead of honoring
|
||||
an explicit value, which is why the frame initially ran past the intended
|
||||
bottom inset despite `bottom: 24px !important` being set. Fixed by adding
|
||||
`height: auto !important` to the same rule so `top`/`bottom` actually
|
||||
determine the box size again. **If a future feature needs to reach either
|
||||
editor's own chrome**, the real containers are
|
||||
`.interface-interface-skeleton` (post editor) or `#site-editor` (Site
|
||||
Editor) — don't assume the normal `#wpbody-content` page structure there.
|
||||
- `Shell.php::is_enabled()` no longer excludes the Site Editor screen
|
||||
(`site-editor` used to be in the skip list alongside `customize`) — it
|
||||
turns out to be built on the same `@wordpress/interface` package as the
|
||||
block editor (`body.block-editor-page` is present on both), so the
|
||||
existing block-editor handling covers it once `#site-editor` is framed.
|
||||
|
||||
## Key bugs fixed (root causes, in case they resurface)
|
||||
|
||||
@@ -374,6 +437,24 @@ page navigation via a taskbar.
|
||||
without first deleting the old one left old-hash asset filenames mixed
|
||||
into the new zip (macOS `zip -r` appends/merges rather than replacing).
|
||||
Always `rm -f` the zip before rebuilding.
|
||||
- **`remove_submenu_page()` corrupting WP's own capability check**: root
|
||||
cause of "Sorry, you are not allowed to access this page" on Menu Creator/
|
||||
Activity Log/Role Editor/Comments — see the sub-apps bullet above. Also
|
||||
broke `document.title` on those pages, which is why `taskbar.js`'s
|
||||
`currentPageTitle()` prefers the on-page `<h1>` instead. **If a future
|
||||
custom admin page needs to be kept out of the native menu while staying
|
||||
reachable and capability-checked, filter it out at the menu-serialization
|
||||
layer (like `MenuSerializer.php` does), never with `remove_submenu_page()`.**
|
||||
- **`min-height`/`max-height` conflict silently no-oping a fix**: per spec,
|
||||
when `min-height` is larger than `max-height`, `min-height` always wins and
|
||||
`max-height` is ignored outright — this is why the taskbar-overlap fix
|
||||
first appeared to do nothing (see Window chrome section above).
|
||||
- **`position: fixed` over-constraint silently ignoring an explicit `bottom`**:
|
||||
when `top`, `height`, and `bottom` are all specified on a fixed-position
|
||||
box, the spec has `bottom` get silently recomputed from `top + height`
|
||||
rather than honored — root cause of the Site Editor frame running past the
|
||||
viewport despite an explicit `bottom: 24px !important` (see Window chrome
|
||||
section above).
|
||||
|
||||
## Not-yet-done (deferred, no active request)
|
||||
|
||||
@@ -389,22 +470,25 @@ page navigation via a taskbar.
|
||||
text field).
|
||||
- Menu Creator: stored item `order` field isn't applied at runtime yet
|
||||
(hide/relabel work; reordering doesn't).
|
||||
- **Unresolved from this session**: Menu Creator/Activity Log/Role Editor
|
||||
throw "Sorry, you are not allowed to access this page" for the admin user
|
||||
— see the Plugins sub-app bullet above. A background investigation task
|
||||
was spawned (`task_f8e56f60` at spawn time) but its outcome isn't recorded
|
||||
here — check whether it landed before re-investigating.
|
||||
- No automated tests anywhere in the project — all verification has been
|
||||
manual, live-in-Chrome, per the established workflow rule above.
|
||||
|
||||
## Current state
|
||||
|
||||
No task in progress. This session rebuilt the entire theming system (fixed
|
||||
color presets replacing the old light/dark toggle, gradient backgrounds,
|
||||
several "independently-painted gradient" seam bugs), added the macOS-style
|
||||
window chrome + taskbar feature end-to-end, and extended native-page dark
|
||||
styling coverage. All of it was live-verified in Chrome against the LocalWP
|
||||
site and is pushed to `origin/main` (commit `4a547d2` at session end — a
|
||||
single large commit covering the whole session's work, since it wasn't
|
||||
broken into incremental commits along the way). The one known open issue is
|
||||
the Menu Creator/Activity Log/Role Editor permissions bug noted above.
|
||||
No task in progress. Earlier this session rebuilt the entire theming system
|
||||
(fixed color presets, gradient backgrounds, "independently-painted gradient"
|
||||
seam bugs) and added the macOS-style window chrome + taskbar feature
|
||||
end-to-end (pushed as commits `4a547d2`/`b0b0a99`). Later the same session:
|
||||
root-caused and fixed the Menu Creator/Activity Log/Role Editor "Sorry, you
|
||||
are not allowed to access this page" bug (was `remove_submenu_page()`
|
||||
corrupting WP's own capability lookup); added a 6th sub-app, Comments; fixed
|
||||
a white-patch bug in the block editor's dark-themed sidebar; rewrote the
|
||||
taskbar from a single sessionStorage slot to a list supporting multiple
|
||||
minimized windows; and extended the window-chrome/taskbar framing to the
|
||||
Site Editor (`site-editor.php`), including tracking down a CSS
|
||||
over-constraint bug (`top`+`height`+`bottom` all set on a fixed-position box
|
||||
silently ignoring `bottom`) that was making its frame run past the viewport.
|
||||
All of it was live-verified in Chrome against the LocalWP site. This batch
|
||||
of changes was uncommitted at the point this doc was last updated — commit
|
||||
and push it as one of the next steps if not already done by the time this is
|
||||
read.
|
||||
|
||||
Reference in New Issue
Block a user