-
Sub-task
-
Resolution: Unresolved
-
Undefined
-
None
-
None
-
None
-
None
-
False
-
-
False
-
-
AwsBreakdown is a Redux/route-aware container that composes presentational pieces; to keep ui-lib free of SaaS/app concerns, we should extract a UI-only view and keep a thin app wrapper.
Migration steps: AwsBreakdown → ui-lib (UI-only) + app wrapper
- Identify what must stay out of ui-lib
- Keep in app: Redux connect, selectors/actions, routes, getQueryState, FeatureToggleSelectors, session storage (getCostType, getCurrency), API query builders, router HOCs.
- Safe for ui-lib: Layout and rendering logic (what BreakdownBase does), typed props, purely presentational children (if any).
- Define a UI props interface in ui-lib
- Create libs/ui-lib/src/components/aws-breakdown/types.ts with an interface that captures only UI data and callbacks used by the view (things currently passed to BreakdownBase: breadcrumbPath, title, description, showCostType, providerType, tagPathsType, report, reportError, reportFetchStatus, providers, providersError, providersFetchStatus, costOverviewComponent, historicalDataComponent, optional instancesComponent, etc.).
- Ensure no Redux, router, or API types leak into the interface. Use primitive or ui-lib-local types.
- Extract the presentational view into ui-lib
- Create libs/ui-lib/src/components/aws-breakdown/AwsBreakdown.tsx as a pure functional component that renders the UI using the new props interface. It should not import from store/, api/, routes/*, or session storage.
- If BreakdownBase is already a pure view, move it first to libs/ui-lib/src/components/breakdown/BreakdownBase.tsx and have AwsBreakdown view use it; otherwise, embed equivalent presentational logic directly.
- Export from ui-lib
- Add barrel exports so consumers can import @koku-ui/ui-lib/components/AwsBreakdown/AwsBreakdown.
- Keep strict TypeScript, functional components, and PatternFly primitives.
- Refactor the app wrapper
- In apps/koku-ui-hccm/src/routes/details/awsBreakdown/awsBreakdown.tsx, keep mapStateToProps and mapDispatchToProps intact.
- Replace the current connect(...)(BreakdownBase) with a thin wrapper that renders <AwsBreakdown {...derivedProps} /> from ui-lib.
- Continue composing costOverviewComponent, historicalDataComponent, and optional instancesComponent locally and pass them down as props (these components can also be migrated later if they’re purely presentational).
- Keep routing unchanged
- Continue lazy-loading the app wrapper in routes.tsx:
- const AwsBreakdown = lazy(() => import('routes/details/awsBreakdown'));
- Unlike NotFound, don’t import the ui-lib view directly in routes (it needs the wrapper’s data wiring and userAccess).
- Verify build and types
- Run type-checks and fix any prop mismatches introduced by the new interface.
- Ensure no ui-lib files import from store/, api/, or app-only utilities.
- Tests
- Add unit tests for the ui-lib view (render with minimal mock props; snapshot for stability).
- Keep/adjust existing container tests in the app as needed.
- Style and a11y
- Ensure PatternFly components and a11y attributes are maintained in the ui-lib view.
- Optional follow-ups
- If CostOverview, HistoricalData, Instances, or BreakdownBase are purely presentational, migrate them similarly into ui-lib to reduce duplication.
- Consider generalizing into a provider-agnostic BreakdownView with a providerType prop to reuse across Azure/GCP/OCP.
- Distribution/config
- Confirm @koku-ui/ui-lib path exports cover the new component. No module federation changes should be needed if ui-lib is already consumed via workspace/alias.