Skip to main content
The dashboard provides analytics over indexed SAP metadata. It has two views: Connection Dashboard (one per indexed connection) and Diff Dashboard (cross-connection comparison).

Connection Dashboard

Rendered by SystemDashboard.tsx. Accepts a connectionId prop. Fetches stats via the useDashboardStats hook, which calls the get_dashboard_stats RPC with p_connection_id.

Layout

The dashboard is organized top-to-bottom into four zones:
  1. Summary cards — Custom objects count, relationships count, modules count
  2. Analysis section — Clean Core score (S/4) or Conversion Readiness score (ECC), findings table, action items, executive summary. Collapsible. Only appears when analysis data exists.
  3. Charts — Module breakdown, type distribution, delivery class, risk tiers
  4. Tables — Hub tables (top 10 by connections), object inventory

Chart components

ComponentFileData sourceClick behavior
SummaryCardsSummaryCards.tsxstats top-level countsClicks scroll to inventory with reset filters
ModuleBreakdownChartModuleBreakdownChart.tsxstats.module_breakdownModule name opens side detail panel; count filters inventory by module; “+X more” switches to module view
TypeDistributionChartTypeDistributionChart.tsxstats.type_distributionClicks filter inventory by type
DeliveryClassChartDeliveryClassChart.tsxstats.delivery_class_distributionClicks filter inventory by delivery class
RiskTiersChartRiskTiersChart.tsxstats.risk_tiersClicks filter inventory by risk level
HubTablesTableHubTablesTable.tsxstats.hub_tablesClicks open object detail panel
ObjectInventoryTableObjectInventoryTable.tsxuseDashboardEntries hookPaginated table with filters for search, type, module, delivery class, and risk

Clickable numbers pattern

All charts route clicks to the inventory section at the bottom. The SystemDashboard component lifts inventory filter state and exposes a scrollToInventory callback:
scrollToInventory({ view?, type?, module?, risk?, deliveryClass? })
This sets the appropriate filter on ObjectInventoryTable and smooth-scrolls to it. Each chart passes its own filter dimension:
  • Type distribution → sets type filter (e.g., 'table')
  • Delivery class → sets deliveryClass filter (e.g., 'A')
  • Risk tiers → sets risk filter (e.g., 'High')
  • Module breakdown count → sets module filter (e.g., 'FI')
  • Summary cards → resets all filters, switches to objects view

Module breakdown split click

The ModuleBreakdownChart has two distinct click targets per row:
  • Module name (left) — calls openObjectDetail('module:FI', connectionId) to open the side detail panel for that module
  • Object count (right) — calls onModuleClick('FI') which filters inventory to that module
The “+X more” text (when more than 10 modules exist) calls onTotalClick, which switches inventory to the modules view.

Inventory filters

ObjectInventoryTable supports these filter dimensions:
FilterQuery paramUI element
Search textqText input
Object typetypeDropdown (table, program, class, bapi, tcode, etc.)
ModulemoduleDropdown (populated from stats.module_breakdown)
Delivery classdelivery_classDropdown (A-Application, C-Customizing, L-Temporary, G-Protected, E-System, S-SAP Internal, W-Transfer)
Risk levelDropdown (populated from stats.risk_tiers)
Filters are lifted as external*Filter props so charts can set them. Each external prop syncs to local state via useEffect. The inventory also has a view switcher: Objects (paginated table), Modules (module list), and Business Processes (inferred processes).

Diff Dashboard

Rendered by DiffDashboard.tsx. Compares two indexed connections side-by-side. Fetches diff data via useDiffData, which calls the compute_system_diff RPC with source_connection_id and target_connection_id.

Layout

  1. Summary cards — Source system stats, target system stats
  2. Coverage bar — Matched, partial, source-only, target-only counts
  3. Module comparison chart — Dumbbell chart comparing module counts across systems
  4. Gap analysis — Source-only and target-only objects
  5. Matched objects table — Objects present in both systems with diff status

Module comparison chart

ModuleComparisonChart.tsx uses a dumbbell chart to visualize module-level differences between source and target systems. Each row shows:
  • Module name on the left
  • A horizontal track with two color-coded dots (source and target) positioned proportionally to their object count
  • A connecting line between the dots — shorter line = more similar coverage
  • Color-coded counts on the right matching the dot colors
An info button (ⓘ) next to the heading toggles an explanation of how to read the chart. All modules are shown in a scrollable container with no truncation.

API Endpoints

All dashboard routes are under /api/workspaces/:id/dashboard and require org membership.
MethodPathPurpose
GET/connectionsIndexed connections (returns connection_id, name, system_type, status, last_indexed_at)
GET/:connectionId/statsAggregated stats via get_dashboard_stats RPC
GET/:connectionId/entriesPaginated object inventory with filters (q, type, module, delivery_class, risk, page, page_size)
GET/:connectionId/entry/:entryKeySingle entry with resolved related entries
POST/:connectionId/resolve-keysBatch resolve bare names to entry_key values
GET/diffsList saved diffs
POST/diffsCreate a new diff (name, source_connection_id, target_connection_id)
GET/diff/:diffIdComputed diff data via compute_system_diff RPC

Pagination

The entries endpoint clamps page_size to a maximum of 200. Default is 50.

Filtering

The entries endpoint accepts these query parameters:
  • q — text search across name and description (sanitized for PostgREST)
  • type — exact match on entry_type
  • module — exact match on module
  • delivery_class — exact match on delivery_class

Data hooks

HookFileReturns
useIndexedConnections(workspaceId)useDashboardData.ts{ connections: IndexedConnection[] }
useDashboardStats(workspaceId, connectionId)useDashboardData.ts{ stats: DashboardStats }
useDashboardEntries(workspaceId, connectionId, filters)useDashboardData.ts{ entries, total, page, page_size }
useSavedDiffs(workspaceId)useDashboardData.ts{ diffs: SavedDiff[] }
useDiffData(workspaceId, diffId)useDashboardData.ts{ diff: SavedDiff & { data: DiffData } }
useCreateDiff(workspaceId)useDashboardData.tsSWR mutation for POST /diffs
All hooks use useAuthSWR which attaches the Supabase JWT and handles revalidation.

Frontend components

components/dashboard/
  SystemDashboard.tsx          # Orchestrator for single-connection view
  DiffDashboard.tsx            # Orchestrator for cross-connection comparison
  SummaryCards.tsx              # Top-level stat cards
  ModuleBreakdownChart.tsx     # Module list with click-to-panel and click-to-filter
  TypeDistributionChart.tsx    # Object type breakdown (horizontal bars)
  DeliveryClassChart.tsx       # Delivery class breakdown (stacked bar + legend)
  RiskTiersChart.tsx           # High/medium/low risk breakdown
  HubTablesTable.tsx           # Top connected tables
  ObjectInventoryTable.tsx     # Paginated, filterable object table
  ModuleComparisonChart.tsx    # Dumbbell chart for diff view
  CoverageBar.tsx              # Coverage visualization for diff view
  DiffSummaryCards.tsx         # Source/target stat cards for diff view
  GapAnalysis.tsx              # Source-only / target-only entries
  MatchedObjectsTable.tsx      # Objects in both systems
  CleanCoreScoreCard.tsx       # Clean Core score display
  ConversionReadinessCard.tsx  # Conversion readiness display
  FindingsTable.tsx            # Analysis findings table
  FindingCard.tsx              # Individual finding card
  ActionItemsList.tsx          # Remediation action items
  ChartErrorBoundary.tsx       # Error boundary wrapper for charts