Skip to content

Global Health bar is tightly coupled to MetalK8s UI, not exposed via shell-ui #4872

@eve-scality

Description

@eve-scality

Identified by automated analysis of MK8S-219

Analysis Report

Current Implementation

The Global Health bar (DashboardGlobalHealth) is currently defined at ui/src/components/DashboardGlobalHealth.tsx and is only consumed by ui/src/containers/DashboardPage.tsx. It is not exported from shell-ui via Module Federation, making it inaccessible to Artesca or any other micro-frontend.

The component has the following dependency structure that prevents sharing:

  1. MetalK8s-specific data fetching: Uses getClusterAlertSegmentQuery() from ui/src/services/platformlibrary/metrics.ts which queries Prometheus for ClusterAtRisk|ClusterDegraded|Watchdog ALERTS, then processes them through getSegments() and convertSegmentToAlert(). This is tightly coupled to MetalK8s-specific Prometheus queries and Loki alert formatting.

  2. Local provider hooks: Imports useAlertLibrary, useHighestSeverityAlerts, highestAlertToStatus from ui/src/containers/AlertProvider.tsx — which are thin wrappers around useShellAlerts() from @scality/module-federation. These are already partially abstracted.

  3. Local time provider: Uses useStartingTimeStamp() from ui/src/containers/StartTimeProvider.tsx — a context-based provider that rounds timestamps to frequency factors.

  4. Child components: Embeds DashboardAlerts, CircleStatus, and StatusIcon — all defined locally in ui/src/components/.

  5. core-ui primitive: The underlying chart visualization (GlobalHealthBarRecharts) is already in @scality/core-ui/dist/next and is shared. The issue is the orchestration layer around it.

Current shell-ui Module Federation exposes (in rspack.config.ts): ./App, ./lang, ./auth/AuthProvider, ./alerts/AlertProvider, ./alerts/alertHooks, ./navbar/navbarHooks, ./moduleFederation/ConfigurationProvider, ./moduleFederation/ShellConfigurationProvider, ./moduleFederation/UIListProvider, ./useNotificationCenter. No health bar or dashboard component is exposed.

Affected Component

  • Repo: scality/metalk8s
  • Path: ui/src/components/DashboardGlobalHealth.tsx

Relevant Code

ui/src/components/DashboardGlobalHealth.tsx
└── L39: const DashboardGlobalHealth = () => { ...  — The DashboardGlobalHealth component is defined in the MetalK8s ui/ package with 6 hooks that mix shared infrastructure (useAlertLibrary, useHighestSeverityAlerts from shell-ui alerts) with MetalK8s-specific data fetching (getClusterAlertSegmentQuery, useStartingTimeStamp). To share this with Artesca, the component must be refactored to accept product-agnostic props or be moved to shell-ui with configurable alert selectors.
shell-ui/rspack.config.ts
└── L130: new ModuleFederationPlugin({ ...  — The shell-ui Module Federation exposes config lists 10 modules — none of which include the Global Health bar or its dependent data-fetching logic. A new entry like './dashboard/GlobalHealth' would need to be added to expose the shared component.
shell-ui/src/platform/library.ts
└── L1: import packageJson from '../../package.json'; ...  — The shell-ui platform library only exposes k8s node/volume count utilities via window.shellUIPlatform. There is no export of health bar components or health data hooks, confirming the Global Health bar is completely unavailable outside the MetalK8s UI.
ui/src/services/platformlibrary/metrics.ts
└── L860: export const getClusterAlertSegmentQuery = (duration: number) => { ...  — The getClusterAlertSegmentQuery function fetches alert history segments from Prometheus with a hardcoded MetalK8s-specific PromQL query (ClusterAtRisk|ClusterDegraded|Watchdog). For Artesca reuse, this query pattern needs to be parameterizable — Artesca may have different alert names but the same segment visualization logic.
ui/src/containers/DashboardPage.tsx
└── L77: <AppContainer.OverallSummary> ...  — DashboardGlobalHealth is currently only consumed by DashboardPage. After extraction to shell-ui, this import would change to consume the shared component via Module Federation, and Artesca could similarly import and render it.

Change Scope

Medium impact — this improvement enables Artesca to display platform health status using the same Global Health bar component, reducing UI duplication and ensuring consistent health visualization across products. Without this change, Artesca would need to reimplement the Global Health bar from scratch, leading to divergent implementations and maintenance overhead. The core-ui GlobalHealthBarRecharts primitive is already shared, but the orchestration layer (data fetching, alert processing, status display) is not.

Confidence

high

Improvement Plan

Recommended approach: Extract and expose a configurable Global Health bar through shell-ui Module Federation.

Step 1: Create a shared Global Health component in shell-ui

Create shell-ui/src/dashboard/GlobalHealthBar.tsx with a props-based API that decouples from MetalK8s-specific data:

type GlobalHealthBarProps = {
  alerts: Alert[];           // Alert segments to render
  status: 'healthy' | 'warning' | 'critical';
  startTime: Date;
  endTime: Date;
  isLoading?: boolean;
  isError?: boolean;
  errorMessage?: string;
  entityName?: string;       // "Platform" for MetalK8s, configurable for Artesca
  entityIcon?: string;       // Icon name
};

This wrapper composes the existing GlobalHealthBarRecharts from @scality/core-ui/dist/next with status display (CircleStatus, StatusIcon) and a loading/error state handler.

Step 2: Extract the alert segment query logic

Move getClusterAlertSegmentQuery from ui/src/services/platformlibrary/metrics.ts into a shared utility in shell-ui (e.g., shell-ui/src/dashboard/alertSegmentQuery.ts), parameterizing the alert names:

export const getAlertSegmentQuery = (
  duration: number,
  alertNames: string[] = ['ClusterAtRisk', 'ClusterDegraded', 'Watchdog']
) => { ... }

Step 3: Expose via Module Federation

Add to shell-ui/rspack.config.ts exposes:

'./dashboard/GlobalHealthBar': './src/dashboard/GlobalHealthBar.tsx',
'./dashboard/alertSegmentQuery': './src/dashboard/alertSegmentQuery.ts',

Step 4: Migrate helper components

Move CircleStatus and StatusIcon to shell-ui or to @scality/core-ui since they are generic status display components with no MetalK8s-specific logic.

Step 5: Refactor MetalK8s DashboardGlobalHealth

Update ui/src/components/DashboardGlobalHealth.tsx to consume the shared component from shell-ui instead of defining it locally. Keep MetalK8s-specific data fetching (like the DashboardAlerts sub-component) at the MetalK8s UI level.

Step 6: Add tests

DashboardGlobalHealth currently has no tests. Add unit tests for the shared component covering: loading state, error state, healthy/warning/critical rendering, and alert segment display.

Files to create/modify:

  • New: shell-ui/src/dashboard/GlobalHealthBar.tsx — shared component
  • New: shell-ui/src/dashboard/alertSegmentQuery.ts — parameterized query
  • Modify: shell-ui/rspack.config.ts — add Module Federation expose entries
  • Modify: ui/src/components/DashboardGlobalHealth.tsx — consume shared component
  • Move: ui/src/components/CircleStatus.tsx, StatusIcon.tsx — to shell-ui or core-ui
  • New: Tests for the shared Global Health bar component

Metadata

Metadata

Assignees

No one assigned

    Labels

    cerebro-analyzedIssue created by Cerebro automated analysis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions