38 KiB
SPRINT_1229_003_FE: SBOM Sources Manager UI
Executive Summary
This sprint implements the frontend Sources Manager - a comprehensive UI for configuring, monitoring, and managing SBOM ingestion sources across all four types: Zastava (registry webhooks), Docker (direct image), CLI (external submission), and Git (repository).
Working Directory: src/Web/StellaOps.Web/src/app/features/sources/
Module: FE (Frontend)
Dependencies: SPRINT_1229_001_BE, SPRINT_1229_002_BE
UI Architecture
┌─────────────────────────────────────────────────────────────────────────────┐
│ Sources Feature Module │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Sources List Page │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ Status Overview Cards (Active, Paused, Error, Pending) │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ Filters: Type | Status | Search | Tags │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ Sources DataTable │ │ │
│ │ │ Name | Type | Status | Last Run | Next Run | Actions │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Source Detail Page │ │
│ │ ┌─────────────┐ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Header │ │ Configuration Panel (read-only or edit) │ │ │
│ │ │ + Actions │ └─────────────────────────────────────────────┘ │ │
│ │ └─────────────┘ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Run History Table │ │ │
│ │ │ (paginated, with status, duration, items) │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Add/Edit Source Wizard │ │
│ │ Step 1: Type Selection │ │
│ │ Step 2: Basic Info (name, description, tags) │ │
│ │ Step 3: Type-Specific Configuration │ │
│ │ Step 4: Credentials │ │
│ │ Step 5: Schedule (optional) │ │
│ │ Step 6: Review & Test Connection │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Page Designs
1. Sources List Page
Route: /sources
┌──────────────────────────────────────────────────────────────────────────────┐
│ SBOM Sources [+ Add Source] │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 12 Active │ │ 3 Paused │ │ 2 Error │ │ 1 Pending │ │
│ │ ● │ │ ⏸ │ │ ⚠ │ │ ○ │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Type: [All ▼] Status: [All ▼] Search: [________________] Tags: [▼]│ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ □ │ Name │ Type │ Status │ Last Run │ Actions │ │
│ ├───┼───────────────────┼──────────┼─────────┼─────────────┼───────────┤ │
│ │ □ │ Docker Hub Prod │ Zastava │ ● Active│ 5 min ago │ ⋮ │ │
│ │ □ │ Harbor Staging │ Zastava │ ● Active│ 12 min ago │ ⋮ │ │
│ │ □ │ Daily Images │ Docker │ ● Active│ 2h ago │ ⋮ │ │
│ │ □ │ CI Pipeline │ CLI │ ⏸ Paused│ 1 day ago │ ⋮ │ │
│ │ □ │ GitHub Monorepo │ Git │ ⚠ Error │ Failed │ ⋮ │ │
│ │ □ │ GitLab Backend │ Git │ ● Active│ 30 min ago │ ⋮ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ Showing 1-6 of 18 [< Prev] [1] [2] [3] [Next >] │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Actions Menu (per row):
- View Details
- Edit
- Trigger Scan
- Test Connection
- Pause / Resume
- Delete
2. Source Detail Page
Route: /sources/:sourceId
┌──────────────────────────────────────────────────────────────────────────────┐
│ ← Back to Sources │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Docker Hub Production │ │
│ │ ──────────────────────────────────────────────────────────────────── │ │
│ │ Type: Zastava (Registry Webhook) Status: ● Active │ │
│ │ Created: Dec 15, 2025 by admin Last Updated: Dec 28, 2025 │ │
│ │ │ │
│ │ [Trigger Scan] [Test Connection] [Edit] [Pause] [Delete] │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Configuration ──────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Registry URL: https://registry-1.docker.io │ │
│ │ Registry Type: Docker Hub │ │
│ │ Webhook Path: /api/v1/webhooks/zastava/abc-123-def │ │
│ │ │ │
│ │ Repository Filters: myorg/*, prod-* │ │
│ │ Tag Filters: v*, latest │ │
│ │ Excluded Tags: *-dev, *-test │ │
│ │ │ │
│ │ Analyzers: OS, Node.js, Python, Go │ │
│ │ Reachability: Enabled │ │
│ │ VEX Lookup: Enabled │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Run History ─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ │ Run ID │ Trigger │ Status │ Started │ Duration │ Items │ │
│ │ ├──────────┼───────────┼───────────┼─────────────┼──────────┼───────┤ │
│ │ │ run-456 │ Webhook │ ✓ Success │ 5 min ago │ 45s │ 3/3 │ │
│ │ │ run-455 │ Webhook │ ✓ Success │ 12 min ago │ 38s │ 1/1 │ │
│ │ │ run-454 │ Manual │ ✓ Success │ 1h ago │ 2m 15s │ 12/12 │ │
│ │ │ run-453 │ Webhook │ ⚠ Partial │ 2h ago │ 1m 30s │ 4/5 │ │
│ │ │ run-452 │ Scheduled │ ✗ Failed │ 3h ago │ 12s │ 0/0 │ │
│ │ │ │
│ │ [Load More] │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
3. Add Source Wizard
Route: /sources/new or modal
┌──────────────────────────────────────────────────────────────────────────────┐
│ Add SBOM Source [×] │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ○ Step 1: Type ── ○ Step 2: Info ── ○ Step 3: Config ── ... │
│ ───────────────────────────────────────────────────────────────────────────│
│ │
│ Select Source Type │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ ☐ Zastava │ │ ☐ Docker │ │
│ │ │ │ │ │
│ │ Registry webhooks │ │ Direct image │ │
│ │ Automatic scans on │ │ scans on schedule │ │
│ │ image push │ │ or on-demand │ │
│ │ │ │ │ │
│ │ Supports: │ │ Supports: │ │
│ │ • Docker Hub │ │ • Any registry │ │
│ │ • Harbor │ │ • Scheduled scans │ │
│ │ • Quay, ECR, GCR │ │ • Tag patterns │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ ☐ CLI │ │ ☐ Git │ │
│ │ │ │ │ │
│ │ External SBOM │ │ Repository source │ │
│ │ submissions from │ │ code scanning │ │
│ │ CI/CD pipelines │ │ │ │
│ │ │ │ Supports: │ │
│ │ Supports: │ │ • GitHub │ │
│ │ • stella-cli │ │ • GitLab │ │
│ │ • Trivy, Syft │ │ • Bitbucket │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ [Cancel] [Next →] │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Step 3 (Type-Specific) - Zastava Example:
┌──────────────────────────────────────────────────────────────────────────────┐
│ Add SBOM Source [×] │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ✓ Step 1 ── ✓ Step 2 ── ● Step 3: Config ── ○ Step 4 ── ... │
│ ───────────────────────────────────────────────────────────────────────────│
│ │
│ Registry Configuration │
│ │
│ Registry Type * │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Docker Hub ▼ │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ Registry URL * │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ https://registry-1.docker.io │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ ───────────────────────────────────────────────────────────────────────── │
│ │
│ Filters │
│ │
│ Repository Patterns (one per line, supports globs) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ myorg/* │ │
│ │ prod-* │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ Tag Patterns (one per line) Excluded Tags │
│ ┌──────────────────────────┐ ┌──────────────────────────┐ │
│ │ v* │ │ *-dev │ │
│ │ latest │ │ *-test │ │
│ │ release-* │ │ │ │
│ └──────────────────────────┘ └──────────────────────────┘ │
│ │
│ ───────────────────────────────────────────────────────────────────────── │
│ │
│ Scan Options │
│ │
│ Analyzers │
│ ☑ OS Packages ☑ Node.js ☑ Python ☐ Java ☑ Go ☐ Ruby │
│ │
│ ☑ Enable Reachability Analysis │
│ ☑ Enable VEX Lookup │
│ │
│ [← Back] [Cancel] [Next →] │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Step 6 (Review & Test):
┌──────────────────────────────────────────────────────────────────────────────┐
│ Add SBOM Source [×] │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ✓ 1 ── ✓ 2 ── ✓ 3 ── ✓ 4 ── ✓ 5 ── ● Step 6: Review │
│ ───────────────────────────────────────────────────────────────────────────│
│ │
│ Review Configuration │
│ │
│ ┌─ Basic Info ─────────────────────────────────────────────────────────┐ │
│ │ Name: Docker Hub Production │ │
│ │ Type: Zastava (Registry Webhook) │ │
│ │ Description: Production images from Docker Hub │ │
│ │ Tags: production, docker-hub │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Configuration ──────────────────────────────────────────────────────┐ │
│ │ Registry: Docker Hub (https://registry-1.docker.io) │ │
│ │ Repositories: myorg/*, prod-* │ │
│ │ Tags: v*, latest, release-* │ │
│ │ Excluded: *-dev, *-test │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Connection Test ────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [Test Connection] │ │
│ │ │ │
│ │ ✓ Registry connection successful │ │
│ │ ✓ Credentials valid │ │
│ │ ✓ Webhook endpoint ready: /api/v1/webhooks/zastava/abc-123 │ │
│ │ │ │
│ │ ℹ Copy this webhook URL to your Docker Hub repository settings │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ [← Back] [Cancel] [Create Source] │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Component Structure
src/app/features/sources/
├── sources.routes.ts
├── sources-list/
│ ├── sources-list.component.ts
│ ├── sources-list.component.html
│ └── sources-list.component.scss
├── source-detail/
│ ├── source-detail.component.ts
│ ├── source-detail.component.html
│ └── source-detail.component.scss
├── source-wizard/
│ ├── source-wizard.component.ts
│ ├── source-wizard.component.html
│ ├── source-wizard.component.scss
│ ├── steps/
│ │ ├── type-selection-step.component.ts
│ │ ├── basic-info-step.component.ts
│ │ ├── zastava-config-step.component.ts
│ │ ├── docker-config-step.component.ts
│ │ ├── cli-config-step.component.ts
│ │ ├── git-config-step.component.ts
│ │ ├── credentials-step.component.ts
│ │ ├── schedule-step.component.ts
│ │ └── review-step.component.ts
│ └── source-wizard.models.ts
├── components/
│ ├── source-status-badge.component.ts
│ ├── source-type-icon.component.ts
│ ├── run-status-badge.component.ts
│ ├── webhook-url-display.component.ts
│ └── connection-test-result.component.ts
├── services/
│ ├── sources-api.service.ts
│ └── sources.models.ts
└── index.ts
API Service
// src/app/features/sources/services/sources-api.service.ts
@Injectable({ providedIn: 'root' })
export class SourcesApiService {
private readonly http = inject(HttpClient);
private readonly baseUrl = '/api/v1/sources';
// List sources with filters
listSources(params: SourceListParams): Observable<PagedResult<SbomSource>> {
return this.http.get<PagedResult<SbomSource>>(this.baseUrl, { params });
}
// Get single source
getSource(sourceId: string): Observable<SbomSource> {
return this.http.get<SbomSource>(`${this.baseUrl}/${sourceId}`);
}
// Create source
createSource(request: CreateSourceRequest): Observable<SbomSource> {
return this.http.post<SbomSource>(this.baseUrl, request);
}
// Update source
updateSource(sourceId: string, request: UpdateSourceRequest): Observable<SbomSource> {
return this.http.put<SbomSource>(`${this.baseUrl}/${sourceId}`, request);
}
// Delete source
deleteSource(sourceId: string): Observable<void> {
return this.http.delete<void>(`${this.baseUrl}/${sourceId}`);
}
// Test connection
testConnection(sourceId: string): Observable<ConnectionTestResult> {
return this.http.post<ConnectionTestResult>(`${this.baseUrl}/${sourceId}/test`, {});
}
// Test connection for new source (before creation)
testNewSourceConnection(request: TestConnectionRequest): Observable<ConnectionTestResult> {
return this.http.post<ConnectionTestResult>(`${this.baseUrl}/test`, request);
}
// Trigger manual scan
triggerScan(sourceId: string): Observable<SbomSourceRun> {
return this.http.post<SbomSourceRun>(`${this.baseUrl}/${sourceId}/trigger`, {});
}
// Pause source
pauseSource(sourceId: string, reason: string, ticket?: string): Observable<SbomSource> {
return this.http.post<SbomSource>(`${this.baseUrl}/${sourceId}/pause`, { reason, ticket });
}
// Resume source
resumeSource(sourceId: string): Observable<SbomSource> {
return this.http.post<SbomSource>(`${this.baseUrl}/${sourceId}/resume`, {});
}
// Get run history
getSourceRuns(sourceId: string, params: RunListParams): Observable<PagedResult<SbomSourceRun>> {
return this.http.get<PagedResult<SbomSourceRun>>(`${this.baseUrl}/${sourceId}/runs`, { params });
}
// Get run details
getRunDetails(sourceId: string, runId: string): Observable<SbomSourceRun> {
return this.http.get<SbomSourceRun>(`${this.baseUrl}/${sourceId}/runs/${runId}`);
}
}
Task Breakdown
T1: Sources Module Setup (TODO)
Files to Create:
src/app/features/sources/sources.routes.tssrc/app/features/sources/index.tssrc/app/features/sources/services/sources.models.tssrc/app/features/sources/services/sources-api.service.ts
T2: Sources List Page (TODO)
Files to Create:
src/app/features/sources/sources-list/sources-list.component.tssrc/app/features/sources/sources-list/sources-list.component.htmlsrc/app/features/sources/sources-list/sources-list.component.scss
Features:
- Status overview cards
- Filterable/searchable data table
- Actions menu per row
- Bulk actions (pause, delete)
T3: Source Detail Page (TODO)
Files to Create:
src/app/features/sources/source-detail/source-detail.component.tssrc/app/features/sources/source-detail/source-detail.component.htmlsrc/app/features/sources/source-detail/source-detail.component.scss
Features:
- Header with actions
- Configuration display (read-only)
- Run history table with pagination
- Webhook URL copy button
T4: Source Wizard - Base & Steps 1-2 (TODO)
Files to Create:
src/app/features/sources/source-wizard/source-wizard.component.tssrc/app/features/sources/source-wizard/source-wizard.models.tssrc/app/features/sources/source-wizard/steps/type-selection-step.component.tssrc/app/features/sources/source-wizard/steps/basic-info-step.component.ts
T5: Source Wizard - Type Config Steps (TODO)
Files to Create:
src/app/features/sources/source-wizard/steps/zastava-config-step.component.tssrc/app/features/sources/source-wizard/steps/docker-config-step.component.tssrc/app/features/sources/source-wizard/steps/cli-config-step.component.tssrc/app/features/sources/source-wizard/steps/git-config-step.component.ts
T6: Source Wizard - Credentials & Schedule (TODO)
Files to Create:
src/app/features/sources/source-wizard/steps/credentials-step.component.tssrc/app/features/sources/source-wizard/steps/schedule-step.component.ts
T7: Source Wizard - Review & Test (TODO)
Files to Create:
src/app/features/sources/source-wizard/steps/review-step.component.tssrc/app/features/sources/components/connection-test-result.component.ts
T8: Shared Components (TODO)
Files to Create:
src/app/features/sources/components/source-status-badge.component.tssrc/app/features/sources/components/source-type-icon.component.tssrc/app/features/sources/components/run-status-badge.component.tssrc/app/features/sources/components/webhook-url-display.component.ts
T9: Navigation Integration (TODO)
Files to Modify:
src/app/core/navigation/navigation.config.ts- Add Sources menu itemsrc/app/app.routes.ts- Add sources routes
T10: Unit Tests (TODO)
Files to Create:
src/app/features/sources/sources-list/sources-list.component.spec.tssrc/app/features/sources/source-detail/source-detail.component.spec.tssrc/app/features/sources/source-wizard/source-wizard.component.spec.tssrc/app/features/sources/services/sources-api.service.spec.ts
Delivery Tracker
| Task | Status | Notes |
|---|---|---|
| T1: Module Setup | TODO | |
| T2: Sources List | TODO | |
| T3: Source Detail | TODO | |
| T4: Wizard Base | TODO | |
| T5: Type Configs | TODO | |
| T6: Creds & Schedule | TODO | |
| T7: Review & Test | TODO | |
| T8: Shared Components | TODO | |
| T9: Navigation | TODO | |
| T10: Unit Tests | TODO |
Next Sprint
SPRINT_1229_004_FE_sbom-sources-dashboard - Sources dashboard and monitoring:
- Sources health dashboard widget
- Real-time status updates
- Error alerting integration
- Run metrics and charts