Skip to content

[Alerting v2] Export composable page components from public start contract - #288805

Merged
dominiqueclarke merged 10 commits into
elastic:mainfrom
dominiqueclarke:alerting-v2/export-composable-pages
Sep 6, 2026
Merged

[Alerting v2] Export composable page components from public start contract#288805
dominiqueclarke merged 10 commits into
elastic:mainfrom
dominiqueclarke:alerting-v2/export-composable-pages

Conversation

@dominiqueclarke

@dominiqueclarke dominiqueclarke commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes elastic/rna-program#1019

Exports five DI-wrapped page components from AlertingV2PublicStart so solution plugins (e.g. Observability Alerting) can mount alerting v2 surfaces at their own routes without duplicating provider setup.

New exports on AlertingV2PublicStart

Component Surface
RulesPage Rules list, rule detail, sequence builder
RuleLibraryPage Rule library / templates
EpisodesPage Alerts inbox, alert detail
ActionPoliciesPage Action policies CRUD
ExecutionHistoryPage Execution history

Props

interface AlertingV2PageProps {
  coreStart: CoreStart;
  setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void;
}

Each component internally resolves the Inversify DI container from coreStart.injection.getContainer(), creates a fresh QueryClient, and wraps the corresponding *App in the full provider stack (Context.Provider, QueryClientProvider, BreadcrumbProvider, I18nProvider). EpisodesPage additionally assembles the KibanaContextProvider service bag and RedirectAppLinks.

Consumer usage

const { RulesPage } = alertingVTwoStart;

<Route path="/rules/v2">
  <RulesPage coreStart={coreStart} setBreadcrumbs={setBreadcrumbs} />
</Route>

Files changed

  • public/application/composable_pages.tsx — new, the five wrapped components
  • public/application/composable_pages.test.tsx — new, 11 tests
  • public/types.ts — add page types + AlertingV2PageProps to start contract
  • public/index.ts — lazy-load composable pages, wire into start binding

Test plan

  • All 11 composable page tests pass
  • Verify alerting v2 management apps still work (unaffected — mount.tsx unchanged)
  • Consumer integration test: mount a composable page from another plugin's app shell

Made with Cursor

…ublic start contract

Adds five lazy-loaded page components (RulesPage, RuleLibraryPage, EpisodesPage,
ActionPoliciesPage, ExecutionHistoryPage) to AlertingV2PublicStart so solution
plugins can mount alerting v2 surfaces at their own routes without duplicating
the DI container, QueryClient, breadcrumb, and i18n provider setup.

Each component accepts { coreStart, setBreadcrumbs } and internally resolves
the Inversify container, creates a fresh QueryClient, and wraps the
corresponding *App component in the full provider stack. EpisodesPage
additionally assembles the KibanaContextProvider service bag from the DI
container, matching the management mount behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added the author:actionable-obs PRs authored by the actionable obs team label Sep 2, 2026
@dominiqueclarke dominiqueclarke added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting v9.6.0 labels Sep 2, 2026
@dominiqueclarke
dominiqueclarke marked this pull request as ready for review September 2, 2026 19:42
@dominiqueclarke
dominiqueclarke requested a review from a team as a code owner September 2, 2026 19:42

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the composable page exports. The five wrapped components faithfully mirror the existing mount.tsx provider stack (all episode dependencies are requiredPlugins, so the DI container.get calls are safe, and the module is correctly code-split via React.lazy). One inline note on stabilizing the EpisodesPage services bag to avoid unnecessary context re-renders.

Generated by Claude Reviewer for #288805 · opus · 153.1 AIC · ⌖ 14.2 AIC · ⊞ 5.1K

kibanamachine and others added 4 commits September 2, 2026 19:54
…outer,

tab href overrides, and execution history tab rename

Fixes discovered during the IA demo:
- Inject the alerting v2 DI container via module-level closure instead of
  coreStart.injection.getContainer() (wrong container scope for cross-plugin
  consumers)
- Wrap each composable page in MemoryRouter so inner *App routes see / as root
- Add EuiPageSection paddingSize="m" for management-parity layout
- Add TabHrefOverrides context so v1/v2 Rules tab hrefs can be overridden by
  solution plugins (observability alerting URLs instead of management)
- Wire tabs into RulesListHeader via useTabHrefOverrides
- Rename execution history "Policies" tab to "Action Policies"
- Update tests for new container prop and internal MemoryRouter

Co-authored-by: Cursor <cursoragent@cursor.com>
…elated changes

Memoize kibanaReactServices in AlertingV2EpisodesPage with useMemo keyed
on coreStart/container and hoist Storage to module scope to prevent
unnecessary KibanaContextProvider re-renders. Revert rules_list_header
tab-wiring and execution_history label rename that depend on packages not
yet on main.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the new tabHrefOverrides prop and the reworked container/lazy wiring. One inline note on the shared page props advertising tabHrefOverrides on all five exported pages while only RulesPage honors it. The earlier EpisodesPage services-bag memoization concern is now addressed (useMemo + hoisted Storage); requesting resolution of that thread.

Generated by Claude Reviewer for #288805 · opus · 123 AIC · ⌖ 14.4 AIC · ⊞ 5.1K

dominiqueclarke and others added 2 commits September 3, 2026 11:51
Tab href overrides will be introduced in a separate PR; keep this change
focused on the base composable page exports.

Co-authored-by: Cursor <cursoragent@cursor.com>
…t interface

Co-authored-by: Cursor <cursoragent@cursor.com>
@dominiqueclarke
dominiqueclarke requested a review from a team as a code owner September 3, 2026 16:09
<QueryClientProvider client={queryClient}>
<BreadcrumbProvider setBreadcrumbs={setBreadcrumbs}>
<I18nProvider>
<MemoryRouter>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the consumers be the ones to handle all navigation/routing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

React.createElement(
React.Suspense,
{ fallback: null },
React.createElement(LazyComponent, { ...props, container: _alertingV2Container! })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you just use the container from props?

Suggested change
React.createElement(LazyComponent, { ...props, container: _alertingV2Container! })
React.createElement(LazyComponent, { ...props, container: props.coreStart.injection.getContainer() })

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

…I container from props

Consumers must provide their own Router ancestor, removing the internal
MemoryRouter that fought with the consumer's router context. The module-scoped
_alertingV2Container is replaced by props.coreStart.injection.getContainer()
per review feedback. Also drops the deprecated RedirectAppLinks wrapper.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the composable page exports. The five wrapped pages otherwise faithfully mirror the mount.tsx provider stacks; the earlier memoization and tabHrefOverrides concerns are resolved. One inline note on EpisodesPage dropping the episodes-specific RedirectAppLinks wrapper.

Generated by Claude Reviewer for #288805 · opus · 170.2 AIC · ⌖ 14.4 AIC · ⊞ 5.1K

<KibanaContextProvider services={kibanaReactServices}>
<Context.Provider value={container}>
<QueryClientProvider client={queryClient}>
<BreadcrumbProvider setBreadcrumbs={setBreadcrumbs}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mountEpisodesApp in mount.tsx wraps <EpisodesApp /> in <RedirectAppLinks coreStart={coreStart}>, but this composable version omits it (the import is also gone, though the test still mocks @kbn/shared-ux-link-redirect-app). None of the other four pages had RedirectAppLinks in mount.tsx — it was episodes-specific — so a consumer can't be assumed to supply it globally. Without it, cross-app anchor links rendered inside the episodes/alert-detail UI (e.g. Discover, doc-viewer links) fall back to full page reloads instead of SPA navigation, a user-visible regression versus the management episodes app. The PR description states EpisodesPage "additionally assembles ... and RedirectAppLinks", which suggests this drop was unintentional. Re-add the wrapper (and its import) around <EpisodesApp />.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna leave out of this PR for now, the redirect and the router stuff is tricky and I need to be able to use it in a consumer to know exactly what I need.

@davismcphee davismcphee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code-only review, Data Discovery changes LGTM 👍 Just an updated mock.

Comment on lines +279 to +286
services.alertingVTwo = {
CreateRuleOptionsFlyout: createRuleOptionsFlyoutMock,
RulesPage: jest.fn(() => null),
RuleLibraryPage: jest.fn(() => null),
EpisodesPage: jest.fn(() => null),
ActionPoliciesPage: jest.fn(() => null),
ExecutionHistoryPage: jest.fn(() => null),
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: long term, it would be better to instead update the shared services mock directly:

alertingVTwo: {
CreateRuleOptionsFlyout: jest.fn(() => null),
},

Not a blocker or anything though.

@dominiqueclarke
dominiqueclarke enabled auto-merge (squash) September 4, 2026 23:01
@kibanamachine

Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
shared-packages 1256 1264 +8
shared-plugins 3836 3849 +13
total +21

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
alertingVTwo 577.2KB 826.7KB ⚠️ +249.5KB
workflowsManagement 1.5MB 1.5MB -34.6KB
total +214.9KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
alertingVTwo 18.8KB 19.9KB +1.1KB
shared-packages 4.5MB 4.6MB +50.2KB
shared-plugins 11.9MB 12.0MB +41.8KB
total +93.1KB
Unknown metric groups

async chunk count

id before after diff
alertingVTwo 26 27 +1

shared chunks total size

id before after diff
all 7.0MB 6.9MB -37.5KB

total optimizer output size

id before after diff
all 63.2MB 63.5MB ⚠️ +270.6KB

Test Failures

  • [job] [logs] Jest Tests #1 / GraphGroupedNodePreviewPanel Pagination Behavior Page Size Changes should reset pageIndex to 0 when changing pageSize to 25
  • [job] [logs] FTR Configs #84 / lens app - group 2 lens datatable should allow toggling row numbers from the style settings flyout
  • [job] [logs] FTR Configs #64 / serverless search UI - search features Console Notebooks has notebooks view available

History

@dominiqueclarke
dominiqueclarke merged commit d824967 into elastic:main Sep 6, 2026
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author:actionable-obs PRs authored by the actionable obs team backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes v9.6.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants