Skip to content

NMS-20488: Let pages and plugins hide the Vue app shell's chrome - #9019

Open
marshallmassengill wants to merge 1 commit into
foundation-2026from
mm/NMS-20488-smoke
Open

marshallmassengill wants to merge 1 commit into
foundation-2026from
mm/NMS-20488-smoke

Conversation

@marshallmassengill

Copy link
Copy Markdown
Contributor

Wall displays, full-screen dashboards and plugin pages such as an operator board need a page without the menu bar, side menu and footer. A page cannot remove that chrome itself without styling the host's class names and the inline padding SideMenu sets, and covering it with a fixed overlay puts PrimeVue dialogs and dropdowns underneath.

This adds a shared, seam-level way for core pages and plugins to show full screen without the menu bar, side menu and footer, for wall displays and similar views.

Assisted by Anthropic Claude Opus 5.5

External References

Wall displays, full-screen dashboards and plugin pages such as an
operator board need a page without the menu bar, side menu and footer.
A page cannot remove that chrome itself without styling the host's
class names and the inline padding SideMenu sets, and covering it with
a fixed overlay puts PrimeVue dialogs and dropdowns underneath.

The seam package gains useOnmsChromeless(): enterChromeless() hides the
chrome until exitChromeless() or Escape, and isChromeless is a readonly
ref for a toggle's state. Its state is module-level, like useOnmsToast,
so the host and plugins share it through window.OnmsUI and plugins get
typed imports and the exports-test contract.

App.vue calls useOnmsChromelessHost() once: it turns the chrome off for
routes with meta.chromeless (a new route undoes an exit, not an enter)
and installs the Escape handler. Escape is ignored while a dialog or
drawer is open, since PrimeVue closes those on Escape without marking
the event handled; that PrimeVue class check stays inside the package.
App.vue then drops the header and footer slots and the padding that
clears them. SideMenu already clears its inline padding and side-menu
offset on unmount.
@joseanes

Copy link
Copy Markdown
  1. Escape exits chromeless mode too eagerly. The Escape handler listens on the whole document and never checks whether something else already handled the key. Cancelling an inline edit or clearing a search box with Escape, as TopologyCanvas.vue and Search.vue do, also brings back the menu bar, side menu and footer.
  2. Only full-screen dialogs and drawers protect Escape. Popovers, confirm popups and non-modal dialogs don't. Escape closes the popup and also exits chromeless mode.
  3. Pages can't handle Escape first. The handler runs before handlers registered on window, such as Topology's, so a page has no way to claim Escape. Adding a check for already-handled keys alone wouldn't fix this.
  4. Chromeless mode outlives the page that turned it on. It isn't reset on navigation. If a plugin page turns it on and the user presses Back, every later page has no menu bar, side menu or footer, and only Escape (never shown on screen) restores them.
  5. No version bump for the shared UI package. Two new exports were added, but @opennms/onms-ui stays at 0.4.0. Plugins use that version to check what the app provides, and earlier PRs that added exports (NMS-20054: Plugin shared UI, Phase 1 #8717, NMS-20243: Move icons to onms-ui #8793) bumped it.
  6. The menu bar and side menu are rebuilt on every toggle. The v-if in App.vue removes and re-creates both each time chromeless mode changes, so they lose their state. Hiding them with a CSS class would keep them in place.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants