Skip to content

feat(ui): global plugin overlay slot via Teleport (companion to OIA PR #181) - #8602

Closed
joseanesONMS wants to merge 1 commit into
OpenNMS:developfrom
joseanesONMS:feature/global-plugin-mount
Closed

feat(ui): global plugin overlay slot via Teleport (companion to OIA PR #181)#8602
joseanesONMS wants to merge 1 commit into
OpenNMS:developfrom
joseanesONMS:feature/global-plugin-mount

Conversation

@joseanesONMS

@joseanesONMS joseanesONMS commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

ALEC-302

Summary

Plugins that declare UIExtension.getGlobalModuleFileName() (new OIA default method, OIA PR #181) now get their module loaded and rendered in a <Teleport to="body"> at the root App level — visible on every page, not just under Plugins > menu.

Changes

File What changed
ui/src/main/App.vue Import GlobalPlugin; compute globalPlugins; add <Teleport to="body">
ui/src/components/Plugin/GlobalPlugin.vue New — loads a plugin's global module via the existing Container component
ui/src/types/index.ts Add optional globalModuleFileName?: string to the Plugin type

Backward compatibility

  • Plugins without getGlobalModuleFileName() (all existing plugins) return null; the REST layer omits or nulls the field; the v-for filter skips them — zero behaviour change.
  • Old OpenNMS that does not serve this field: globalPlugins is always empty, <Teleport> renders nothing — no visual or functional regression.
  • No new REST endpoints, no schema migration, no OSGi changes.

Dependencies

Requires OIA PR #181 to be merged and a new OIA snapshot published before globalModuleFileName appears in /rest/plugins responses for plugins that implement the method.

First consumer

ALEC-302 — ALEC context-aware chatbot overlay.

…gets

Plugins that declare UIExtension.getGlobalModuleFileName() (new OIA default
method) now get their module loaded and rendered in a <Teleport to="body">
at the root App level, so the component is visible on every page — not just
under the Plugins > menu route.

Changes:
- App.vue: import GlobalPlugin; compute globalPlugins (plugins with a non-null
  globalModuleFileName); render them inside <Teleport to="body">
- GlobalPlugin.vue: new component that loads the global module via the existing
  Container + externalComponent machinery (same URL pattern as Plugin.vue)
- types/index.ts: add optional globalModuleFileName field to the Plugin type

Backward compatibility:
- Plugins that do not override getGlobalModuleFileName() return null; the REST
  layer omits or nulls the field; the v-for filter skips them — zero behaviour
  change for all existing plugins.
- Old OpenNMS that does not serve this field: globalPlugins is always empty,
  Teleport renders nothing — no visual or functional regression.

Relates-To: ALEC-302
@joseanesONMS

Copy link
Copy Markdown
Contributor Author

@marshallmassengill @cgorantla — updated the PR description. Please take a look when you get a chance.

@synqotik

Copy link
Copy Markdown
Contributor

@joseanesONMS

This seems reasonable for a single use case, but we may need to think more about it.

For example, if there are multiple global plugins, this could get messy very quickly.

If the purpose is to have a chat window, it may make sense to build that into the product (with placement, styling and chat functionality, but not connected to any other functionality in particular), then have a way to connect it with plugins that actually provide the feature / data / etc.

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.

3 participants