mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-30 03:59:41 +00:00
fix: reconcile sticky update indicators with Anatomy preview (#1698)
* fix: reconcile sticky update indicators with Anatomy preview Sidebar, Updates filter, and Fleet treated retained partial/failed scanner has_update as confirmed. Keep raw state for retention/notifications, project confirmed-only to APIs, show distinct incomplete indicators, and clear sticky rows only after an authoritative-negative preview. Closes #1685 * test: align sidebar truncate E2E with failed-over-retained precedence Purple update indicators are confirmed-only; hasUpdate with a failed check correctly shows the failed trailing icon. * fix: clear confirmed update rows on authoritative-negative preview Address audit SF-1/SF-2/SF-3: observation-watermark clears for older ok+has_update rows (DB + memory gens), Fleet checkability parity with backend not_checkable, and Updates chip confirmed-only regressions. * fix: tombstone equal-generation writers on preview clear Advance the per-stack write generation when clearing at the observation watermark so a scanner reserved before preview cannot recreate the row after an authoritative-negative reconcile. * fix: clear sticky updates with digest and tag preview parity Share detection across scanner and preview, keep GET read-only with POST reconcile, gate Apply to digest and rebuild updates, and invalidate the hub fleet cache on clear. * test: set digestUpdate on auto-update checkImage mocks Scheduler and execute routes now gate Compose on digest drift; fixtures that expect an apply need digestUpdate so they exercise the update path. * fix: clear unused lint errors on sticky update branch Drop unused partial helper and fleet invalidate import; keep the CacheService inflight self-ref as let with an eslint exception so tsc stays green. * fix: use inflight holder for CacheService prefer-const Keep generation-aware ownership without a let self-reference that fights ESLint and tsc.
This commit is contained in:
@@ -6,6 +6,7 @@ import { cn } from '@/lib/utils';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import type { StackStatusEntry, MetricPoint, StackCpuSeries, StackStatusesLoadStatus } from './types';
|
||||
import type { StackUpdateInfo } from '@/types/imageUpdates';
|
||||
import { isConfirmedImageUpdate, isConfirmedServiceUpdate } from '@/types/imageUpdates';
|
||||
import { aggregateCurrentUsage } from './aggregateCurrentUsage';
|
||||
import { classifyRow, type RowState } from './classifyRow';
|
||||
import { updateAvailableBadge, updateAvailableLabel } from '@/lib/updateAvailableLabel';
|
||||
@@ -119,6 +120,7 @@ export function StackHealthTable({
|
||||
const series = stackCpuSeries[name];
|
||||
const peakCpu = series?.peakValue ?? agg?.cpu ?? 0;
|
||||
const state = classifyRow(entry.status, peakCpu);
|
||||
const updateInfo = stackUpdates[file];
|
||||
return {
|
||||
file,
|
||||
name,
|
||||
@@ -132,9 +134,9 @@ export function StackHealthTable({
|
||||
runningSince: entry.runningSince ?? null,
|
||||
source: entry.source ?? 'local',
|
||||
mainPort: entry.mainPort ?? null,
|
||||
hasUpdate: stackUpdates[file]?.hasUpdate ?? false,
|
||||
outdatedServices: (stackUpdates[file]?.services ?? [])
|
||||
.filter((s) => s.hasUpdate)
|
||||
hasUpdate: updateInfo != null && isConfirmedImageUpdate(updateInfo),
|
||||
outdatedServices: (updateInfo?.services ?? [])
|
||||
.filter((s) => isConfirmedServiceUpdate(s))
|
||||
.map((s) => s.service),
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user