diff --git a/src/Platform/StellaOps.Platform.WebService/Services/TopologyLayoutService.cs b/src/Platform/StellaOps.Platform.WebService/Services/TopologyLayoutService.cs index 952417f53..74e0cfb8d 100644 --- a/src/Platform/StellaOps.Platform.WebService/Services/TopologyLayoutService.cs +++ b/src/Platform/StellaOps.Platform.WebService/Services/TopologyLayoutService.cs @@ -217,7 +217,7 @@ public sealed class TopologyLayoutService var deployingCount = envPaths.Count(p => p.Status is "running" or "deploying"); var pendingCount = envPaths.Count(p => p.Status is "pending" or "awaiting_approval" or "gates_running"); var failedCount = envPaths.Count(p => p.Status is "failed"); - var totalDeployments = envPaths.Count; + var totalDeployments = env?.TargetCount ?? 0; var agentStatus = ResolveAgentStatus(envId, targetsByEnv); diff --git a/src/Web/StellaOps.Web/src/app/features/policy-studio/services/policy-pack.store.ts b/src/Web/StellaOps.Web/src/app/features/policy-studio/services/policy-pack.store.ts index 894709d1d..bfc838923 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-studio/services/policy-pack.store.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-studio/services/policy-pack.store.ts @@ -88,20 +88,7 @@ export class PolicyPackStore { } private fallbackPacks(): PolicyPackSummary[] { - return [ - { - id: 'pack-1', - name: 'Core Policy Pack', - description: '', - version: 'latest', - status: 'active', - createdAt: '', - modifiedAt: '', - createdBy: '', - modifiedBy: '', - tags: [], - }, - ]; + return []; } private readCache(): PolicyPackSummary[] | null { diff --git a/src/Web/StellaOps.Web/src/app/features/policy-studio/workspace/policy-workspace.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-studio/workspace/policy-workspace.component.ts index 690caa0f3..f4d5347f2 100644 --- a/src/Web/StellaOps.Web/src/app/features/policy-studio/workspace/policy-workspace.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/policy-studio/workspace/policy-workspace.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from '@angular/common'; -import { Component, ChangeDetectionStrategy, inject, signal, ChangeDetectorRef } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AuthService, AUTH_SERVICE } from '../../../core/auth'; import { Router, RouterLink } from '@angular/router'; @@ -13,9 +13,9 @@ import { PolicyPackStore } from '../services/policy-pack.store'; imports: [CommonModule, RouterLink, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: ` -
+
- +
@if (scopeHint) { @@ -25,7 +25,7 @@ import { PolicyPackStore } from '../services/policy-pack.store'; }
- @for (pack of packs; track pack) { + @for (pack of packs(); track pack) {
@@ -93,7 +93,7 @@ import { PolicyPackStore } from '../services/policy-pack.store';
} @empty { - @if (!loading) { + @if (!loading()) {

No policy packs configured

@@ -165,8 +165,9 @@ import { PolicyPackStore } from '../services/policy-pack.store'; ] }) export class PolicyWorkspaceComponent { - protected loading = false; - protected packs: PolicyPackSummary[] = []; + protected readonly loading = signal(true); + protected readonly packs = signal([]); + protected readonly refreshing = signal(false); protected canAuthor = false; protected canSimulate = false; protected canReview = false; @@ -176,7 +177,6 @@ export class PolicyWorkspaceComponent { protected canReviewOrApprove = false; protected canView = false; protected scopeHint = ''; - protected refreshing = false; protected readonly newPackName = signal(''); protected readonly newPackDesc = signal(''); @@ -187,32 +187,39 @@ export class PolicyWorkspaceComponent { private readonly policyApi = inject(PolicyApiService); private readonly auth = inject(AUTH_SERVICE) as AuthService; private readonly router = inject(Router); - private readonly cdr = inject(ChangeDetectorRef); constructor() { - this.loading = true; + this.loading.set(true); this.applyScopes(); - this.packStore.getPacks().subscribe((packs) => { - this.packs = this.sortPacks(packs); - this.loading = false; - this.cdr.markForCheck(); + this.packStore.getPacks().subscribe({ + next: (packs) => { + this.packs.set(this.sortPacks(packs)); + this.loading.set(false); + }, + error: () => { + this.packs.set([]); + this.loading.set(false); + }, }); } refresh(): void { - this.refreshing = true; - this.cdr.markForCheck(); + this.refreshing.set(true); this.packStore.refresh(); - this.packStore.getPacks().subscribe((packs) => { - this.packs = this.sortPacks(packs); - this.refreshing = false; - this.cdr.markForCheck(); + this.packStore.getPacks().subscribe({ + next: (packs) => { + this.packs.set(this.sortPacks(packs)); + this.refreshing.set(false); + }, + error: () => { + this.refreshing.set(false); + }, }); } private sortPacks(packs: PolicyPackSummary[]): PolicyPackSummary[] { return [...packs].sort((a, b) => - b.modifiedAt.localeCompare(a.modifiedAt) || a.id.localeCompare(b.id) + (b.modifiedAt ?? '').localeCompare(a.modifiedAt ?? '') || (a.id ?? '').localeCompare(b.id ?? '') ); }