Fix Pack creation: clear cache on refresh, trigger CD, navigate on success

PolicyPackStore.refresh() now clears the sessionStorage cache before
fetching, so API responses aren't hidden behind stale cached data.

PolicyWorkspaceComponent fixes:
- Add ChangeDetectorRef.markForCheck() after every async state mutation
  (OnPush was preventing UI updates from plain field assignments)
- Navigate to the new pack on successful creation
- Show clearer error when policy gateway is unreachable (status 0)
- Clear pack cache before navigation so the new pack appears

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-29 00:04:23 +02:00
parent 55e6ea0672
commit 4e6c14037c
2 changed files with 36 additions and 13 deletions

View File

@@ -32,9 +32,18 @@ export class PolicyPackStore {
}
refresh(): void {
this.clearCache();
this.fetch();
}
clearCache(): void {
try {
sessionStorage.removeItem(this.cacheKey);
} catch {
/* ignore */
}
}
private fetch(): void {
if (!this.canReadPolicyPacks()) {
this.usingFallback = true;

View File

@@ -1,8 +1,8 @@
import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal } from '@angular/core';
import { Component, ChangeDetectionStrategy, inject, signal, ChangeDetectorRef } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AuthService, AUTH_SERVICE } from '../../../core/auth';
import { RouterLink } from '@angular/router';
import { Router, RouterLink } from '@angular/router';
import { PolicyPackSummary } from '../models/policy.models';
import { PolicyApiService } from '../services/policy-api.service';
@@ -186,29 +186,36 @@ export class PolicyWorkspaceComponent {
private readonly packStore = inject(PolicyPackStore);
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.applyScopes();
this.packStore.getPacks().subscribe((packs) => {
this.packs = [...packs].sort((a, b) =>
b.modifiedAt.localeCompare(a.modifiedAt) || a.id.localeCompare(b.id)
);
this.packs = this.sortPacks(packs);
this.loading = false;
this.cdr.markForCheck();
});
}
refresh(): void {
this.refreshing = true;
this.cdr.markForCheck();
this.packStore.refresh();
this.packStore.getPacks().subscribe((packs) => {
this.packs = [...packs].sort((a, b) =>
b.modifiedAt.localeCompare(a.modifiedAt) || a.id.localeCompare(b.id)
);
this.packs = this.sortPacks(packs);
this.refreshing = false;
this.cdr.markForCheck();
});
}
private sortPacks(packs: PolicyPackSummary[]): PolicyPackSummary[] {
return [...packs].sort((a, b) =>
b.modifiedAt.localeCompare(a.modifiedAt) || a.id.localeCompare(b.id)
);
}
createPack(): void {
const name = this.newPackName().trim();
if (!name) return;
@@ -223,16 +230,23 @@ export class PolicyWorkspaceComponent {
content: '',
})
.subscribe({
next: () => {
next: (pack) => {
this.newPackName.set('');
this.newPackDesc.set('');
this.creating.set(false);
this.refresh();
this.packStore.clearCache();
if (pack?.id) {
void this.router.navigate(['/ops/policy/packs', pack.id]);
} else {
this.refresh();
}
},
error: (err) => {
this.createError.set(
err?.error?.message ?? err?.message ?? 'Failed to create policy pack. Please try again.'
);
const message =
err?.status === 0
? 'Cannot reach the policy service. Check that the policy gateway is running.'
: err?.error?.message ?? err?.message ?? 'Failed to create policy pack. Please try again.';
this.createError.set(message);
this.creating.set(false);
},
});