diff --git a/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-audit-shell.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-audit-shell.component.ts index 2b640e6f2..0dfb6c88f 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-audit-shell.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-audit-shell.component.ts @@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, + computed, DestroyRef, inject, signal, @@ -33,6 +34,13 @@ const PAGE_TABS: readonly StellaPageTab[] = [ imports: [CommonModule, RouterOutlet, StellaPageTabsComponent], template: `
+
+
+

Policy Audit

+

{{ activeSubtitle() }}

+
+
+ (this.readSubview()); + protected readonly activeSubtitle = computed(() => { + switch (this.activeSubview()) { + case 'policy': return 'Policy promotions, simulations, approvals, and lint events.'; + case 'vex': return 'VEX statement creation, revocation, and consensus events.'; + case 'log': return 'Unified audit log across all policy actions.'; + default: return 'Policy promotions, simulations, approvals, and lint events.'; + } + }); + constructor() { this.router.events .pipe( diff --git a/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-vex-shell.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-vex-shell.component.ts index f1b3424e6..b92299c33 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-vex-shell.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-decisioning-vex-shell.component.ts @@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, + computed, DestroyRef, inject, signal, @@ -46,6 +47,13 @@ const PAGE_TABS: readonly StellaPageTab[] = [ imports: [CommonModule, RouterOutlet, StellaPageTabsComponent], template: `
+
+
+

VEX & Exceptions

+

{{ activeSubtitle() }}

+
+
+ (this.readSubview()); + protected readonly activeSubtitle = computed(() => { + switch (this.activeSubview()) { + case 'dashboard': return 'VEX statement overview and activity feed.'; + case 'search': return 'Search VEX statements across all sources.'; + case 'create': return 'Create new VEX statements for findings.'; + case 'stats': return 'VEX coverage and statement metrics.'; + case 'consensus': return 'Multi-source consensus resolution.'; + case 'explorer': return 'Browse and inspect VEX data.'; + case 'conflicts': return 'VEX statement conflicts and resolution.'; + case 'exceptions': return 'Policy exception queue management.'; + default: return 'VEX statement overview and activity feed.'; + } + }); + constructor() { this.router.events .pipe( diff --git a/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-pack-shell.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-pack-shell.component.ts index b2b435561..7dd56c958 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-pack-shell.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-decisioning/policy-pack-shell.component.ts @@ -47,17 +47,10 @@ const PACK_DETAIL_TABS: readonly StellaPageTab[] = [ imports: [CommonModule, RouterOutlet, StellaPageTabsComponent], template: `
-
+
-

Packs

-

{{ packId() ? 'Pack ' + packId() : 'Policy Pack Workspace' }}

-

- {{ - packId() - ? 'Edit rules, YAML, approvals, and simulations for the selected pack.' - : 'Browse deterministic pack inventory and open a pack into authoring mode.' - }} -

+

{{ packId() ? 'Pack ' + packId() : 'Policy Pack Workspace' }}

+

{{ activeSubtitle() }}

@@ -78,31 +71,9 @@ const PACK_DETAIL_TABS: readonly StellaPageTab[] = [ gap: 0.85rem; } - .section-header { - border: 1px solid var(--color-border-primary); - border-radius: var(--radius-lg); - background: var(--color-surface-primary); - padding: 1rem; - } - - .section-header__eyebrow { - margin: 0 0 0.25rem; - color: var(--color-status-success); - font-size: 0.78rem; - font-weight: 700; - letter-spacing: 0.08em; - text-transform: uppercase; - } - - .section-header h2 { - margin: 0; - color: var(--color-text-heading); - } - - .section-header p { - margin: 0.35rem 0 0; - color: var(--color-text-secondary); - } + .pack-shell__header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 1rem; } + .pack-shell__title { font-size: 1.5rem; font-weight: var(--font-weight-bold, 700); color: var(--color-text-heading); margin: 0 0 0.25rem; } + .pack-shell__subtitle { font-size: 0.8125rem; color: var(--color-text-secondary); margin: 0; } `], changeDetection: ChangeDetectionStrategy.OnPush, }) @@ -118,6 +89,23 @@ export class PolicyPackShellComponent { return this.packId() ? PACK_DETAIL_TABS : WORKSPACE_TABS; }); + protected readonly activeSubtitle = computed(() => { + if (!this.packId()) { + return 'Browse deterministic pack inventory and open a pack into authoring mode.'; + } + switch (this.activeSubview()) { + case 'dashboard': return 'Overview of the selected policy pack.'; + case 'edit': return 'Edit rules and configuration for this pack.'; + case 'rules': return 'Manage individual rules within this pack.'; + case 'yaml': return 'View and edit the raw YAML definition.'; + case 'approvals': return 'Review and manage approval workflows.'; + case 'simulate': return 'Run simulations against this pack.'; + case 'explain': return 'Explain evaluation results for a simulation run.'; + case 'workspace': return 'Browse deterministic pack inventory and open a pack into authoring mode.'; + default: return 'Overview of the selected policy pack.'; + } + }); + constructor() { this.router.events .pipe( diff --git a/src/Web/StellaOps.Web/src/app/features/policy-governance/policy-governance.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-governance/policy-governance.component.ts index 7a4550bb7..de2e2e781 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-governance/policy-governance.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-governance/policy-governance.component.ts @@ -1,5 +1,5 @@ -import { Component, ChangeDetectionStrategy, signal, inject, OnInit, DestroyRef } from '@angular/core'; +import { Component, ChangeDetectionStrategy, signal, computed, inject, OnInit, DestroyRef } from '@angular/core'; import { Router, RouterOutlet, NavigationEnd, ActivatedRoute } from '@angular/router'; import { filter } from 'rxjs/operators'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -33,7 +33,7 @@ const GOVERNANCE_TABS: readonly StellaPageTab[] = [

Policy Governance

-

Configure risk budgets, trust weights, staleness rules, sealed mode, and risk profiles.

+

{{ activeSubtitle() }}

('budget'); protected readonly GOVERNANCE_TABS = GOVERNANCE_TABS; + protected readonly activeSubtitle = computed(() => { + switch (this.activeTab()) { + case 'budget': return 'Monitor budget consumption and manage risk thresholds.'; + case 'trust': return 'Configure trust weights for vulnerability sources and issuers.'; + case 'staleness': return 'Configure data freshness thresholds and enforcement rules.'; + case 'sealed': return 'Manage air-gapped operation mode and trusted source overrides.'; + case 'profiles': return 'Manage risk evaluation profiles and signal weights.'; + case 'validator': return 'Validate policy documents against the schema.'; + case 'audit': return 'Track all governance configuration changes.'; + case 'conflicts': return 'Identify and resolve rule overlaps and precedence issues.'; + case 'schema-playground': return 'Test and validate risk profile schemas interactively.'; + case 'schema-docs': return 'Reference documentation for risk profile configuration schemas.'; + default: return 'Monitor budget consumption and manage risk thresholds.'; + } + }); + ngOnInit(): void { this.syncTabFromRoute(); this.router.events diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts index b8844b5f4..8cacc9d65 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts @@ -23,15 +23,7 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Batch Evaluation

-

- Evaluate multiple artifacts against policy rules simultaneously. -

-
-
+
-
@if (activeTab() === 'new') { @@ -431,35 +422,11 @@ import { padding: 1.5rem; } - .batch-evaluation__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .batch-evaluation__eyebrow { - margin: 0; - color: var(--color-status-success); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .batch-evaluation__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .batch-evaluation__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - - .header-tabs { + .batch-evaluation__actions { display: flex; + justify-content: flex-end; gap: 0.5rem; + margin-bottom: 1rem; } .tab-btn { diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts index bcada3ebb..945b693f6 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts @@ -24,15 +24,7 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Conflict Detection

-

- Detect policy conflicts and get AI-assisted resolution suggestions. -

-
-
+
-
@@ -344,35 +335,11 @@ import { padding: 1.5rem; } - .conflict-detection__header { + .conflict-detection__actions { display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .conflict-detection__eyebrow { - margin: 0; - color: var(--color-status-warning); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .conflict-detection__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .conflict-detection__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - - .header-actions { - display: flex; - gap: 0.75rem; + justify-content: flex-end; + gap: 0.5rem; + margin-bottom: 1rem; } .btn { diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts index 2cfed5403..873c61025 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts @@ -29,23 +29,14 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Test Coverage

-

- View coverage percentage per policy rule and identify missing test cases. -

-
-
- - -
-
+
+ + +
@if (result()) { @@ -261,35 +252,11 @@ import { padding: 1.5rem; } - .coverage__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .coverage__eyebrow { - margin: 0; - color: var(--color-status-success); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .coverage__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .coverage__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - .coverage__actions { display: flex; - gap: 0.75rem; + justify-content: flex-end; + gap: 0.5rem; + margin-bottom: 1rem; } .btn { diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts index c465bf9f3..050f87d04 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts @@ -25,18 +25,11 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Effective Policies

-

- View which policies apply to each resource based on inheritance and overrides. -

-
+
-
+
@@ -167,31 +160,7 @@ import { padding: 1.5rem; } - .effective-policy__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .effective-policy__eyebrow { - margin: 0; - color: var(--color-status-excepted); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .effective-policy__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .effective-policy__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } + .effective-policy__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; } .btn { padding: 0.6rem 1.25rem; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts index 14ee8c3d8..319358886 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts @@ -25,18 +25,11 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Audit Log

-

- View change history for policy packs with actor and timestamp details. -

-
+
-
+
@@ -193,31 +186,7 @@ import { padding: 1.5rem; } - .audit-log__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .audit-log__eyebrow { - margin: 0; - color: var(--color-status-excepted); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .audit-log__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .audit-log__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } + .audit-log__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; } .btn { padding: 0.6rem 1.25rem; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts index 80d1661bc..8b74f8da8 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts @@ -29,15 +29,7 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Policy Diff

-

- Compare policy versions to see what changed. -

-
- @if (result()) { + @if (result()) {
v{{ result()?.fromVersion }} @@ -47,7 +39,6 @@ import { v{{ result()?.toVersion }}
} -
@if (result()) { @@ -175,32 +166,6 @@ import { padding: 1.5rem; } - .diff-viewer__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .diff-viewer__eyebrow { - margin: 0; - color: var(--color-status-info); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .diff-viewer__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .diff-viewer__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - .diff-viewer__versions { display: flex; align-items: center; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts index 8afa805ad..8150dd38d 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts @@ -24,18 +24,11 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Policy Exceptions

-

- Manage policy exceptions for specific resources or vulnerabilities. -

-
+
-
+
@if (showCreateForm()) { @@ -254,31 +247,7 @@ import { padding: 1.5rem; } - .policy-exception__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .policy-exception__eyebrow { - margin: 0; - color: var(--color-severity-high); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .policy-exception__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .policy-exception__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } + .policy-exception__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; } .btn { padding: 0.6rem 1.25rem; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts index 6d3ec0202..a58e88da7 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts @@ -29,20 +29,11 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Policy Lint

-

- Check policy syntax, semantics, and best practices. -

-
-
- -
-
+
+ +
@if (result()) { @@ -232,31 +223,7 @@ import { padding: 1.5rem; } - .policy-lint__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .policy-lint__eyebrow { - margin: 0; - color: var(--color-status-warning); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .policy-lint__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .policy-lint__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } + .policy-lint__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; } .btn { padding: 0.6rem 1.25rem; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts index f69700f5c..b27d67556 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts @@ -24,16 +24,6 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Merge Preview

-

- Preview the result of merging multiple policy packs. -

-
-
-
@@ -212,29 +202,6 @@ import { padding: 1.5rem; } - .merge-preview__header { - margin-bottom: 1.5rem; - } - - .merge-preview__eyebrow { - margin: 0; - color: var(--color-status-success); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .merge-preview__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .merge-preview__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - .merge-preview__sources { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts index c010002e1..811fe71cb 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts @@ -33,18 +33,11 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Promotion Gate

-

- Checklist of requirements before promoting policy to production. -

-
+
-
+
@if (result()) { @@ -239,31 +232,7 @@ import { padding: 1.5rem; } - .promotion-gate__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .promotion-gate__eyebrow { - margin: 0; - color: var(--color-status-success); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .promotion-gate__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .promotion-gate__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } + .promotion-gate__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; } .btn { padding: 0.6rem 1.25rem; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/shadow-mode-dashboard.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/shadow-mode-dashboard.component.ts index fe542eace..33e160f20 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/shadow-mode-dashboard.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/shadow-mode-dashboard.component.ts @@ -17,23 +17,13 @@ import { ShadowModeStateService } from './shadow-mode-state.service'; changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Shadow Mode Dashboard

-

- Compare shadow policy evaluations against active production policy. -

-
- - -
+ @if (results()) { @@ -213,33 +203,6 @@ import { ShadowModeStateService } from './shadow-mode-state.service'; padding: 1.5rem; } - .shadow-dashboard__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 1rem; - margin-bottom: 1.5rem; - } - - .shadow-dashboard__eyebrow { - margin: 0; - color: var(--color-status-excepted-border); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .shadow-dashboard__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .shadow-dashboard__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - .shadow-dashboard__summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-console.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-console.component.ts index 48ca90d89..f5c7f0adb 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-console.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-console.component.ts @@ -27,15 +27,8 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Simulation Console

-

- Run policy simulations against SBOMs to preview evaluation outcomes. -

-
- @if (result()) { + @if (result()) { +
}
- } -
+ + }
@@ -332,31 +325,7 @@ import { padding: 1.5rem; } - .sim-console__header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .sim-console__eyebrow { - margin: 0; - color: var(--color-status-info); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .sim-console__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .sim-console__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } + .sim-console__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; } .sim-console__status { display: flex; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-dashboard.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-dashboard.component.ts index 3e4e4ab55..128f44523 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-dashboard.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-dashboard.component.ts @@ -1,5 +1,5 @@  -import { Component, ChangeDetectionStrategy, signal, inject, OnInit } from '@angular/core'; +import { Component, ChangeDetectionStrategy, signal, computed, inject, OnInit } from '@angular/core'; import { RouterModule, Router } from '@angular/router'; import { ShadowModeIndicatorComponent } from './shadow-mode-indicator.component'; @@ -33,6 +33,13 @@ const SIMULATION_TABS: readonly StellaPageTab[] = [ changeDetection: ChangeDetectionStrategy.OnPush, template: `
+
+
+

Policy Simulation

+

{{ activeSubtitle() }}

+
+
+
('shadow'); + + private static readonly SUBTITLES: Record = { + shadow: 'Compare shadow policy evaluations against active production policy.', + console: 'Run policies against test data and review evaluations.', + lint: 'Syntax and semantic validation for policy documents.', + coverage: 'Test coverage metrics per rule and policy pack.', + effective: 'Which policies apply to which environments and artifacts.', + audit: 'Simulation and policy change history.', + exceptions: 'Manage temporary policy exception waivers.', + promotion: 'Pre-promotion checklist and gate enforcement.', + merge: 'Preview pack merge results before applying.', + }; + + protected readonly activeSubtitle = computed(() => + SimulationDashboardComponent.SUBTITLES[this.activeTab()] ?? '' + ); + protected readonly shadowConfig = this.shadowModeState.config; protected readonly shadowLoading = this.shadowModeState.loading; diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-history.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-history.component.ts index bee15961d..017217b2e 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-history.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/simulation-history.component.ts @@ -28,15 +28,7 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, template: `
-
-
-

Policy Simulation Studio

-

Simulation History

-

- View past simulation runs, verify reproducibility, and compare results. -

-
-
+
-
@@ -384,35 +375,11 @@ import { padding: 1.5rem; } - .sim-history__header { + .sim-history__actions { display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 1.5rem; - } - - .sim-history__eyebrow { - margin: 0; - color: var(--color-status-excepted); - font-size: 0.8rem; - letter-spacing: 0.05em; - text-transform: uppercase; - } - - .sim-history__header h1 { - margin: 0.25rem 0 0; - color: var(--color-text-heading); - font-size: 1.5rem; - } - - .sim-history__lede { - margin: 0.25rem 0 0; - color: var(--color-text-muted); - } - - .header-actions { - display: flex; - gap: 0.75rem; + justify-content: flex-end; + gap: 0.5rem; + margin-bottom: 1rem; } .btn {