mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-05 23:36:37 +00:00
refactor(recovery): group inventory by posture
This commit is contained in:
parent
e691b5328a
commit
a3fa842866
9 changed files with 161 additions and 31 deletions
|
|
@ -50,6 +50,7 @@ import { titleCaseDelimitedLabel } from '@/utils/textPresentation';
|
|||
type VerificationFilter = 'all' | 'verified' | 'unverified' | 'unknown';
|
||||
type ProtectedSortCol = 'item' | 'type' | 'platform' | 'lastBackup' | 'outcome';
|
||||
type SortDir = 'asc' | 'desc';
|
||||
type ProtectedInventoryGroupKey = 'attention' | 'healthy';
|
||||
|
||||
interface RecoveryRollupSummary {
|
||||
total: number;
|
||||
|
|
@ -58,6 +59,12 @@ interface RecoveryRollupSummary {
|
|||
neverSucceeded: number;
|
||||
}
|
||||
|
||||
interface ProtectedInventoryGroup {
|
||||
key: ProtectedInventoryGroupKey;
|
||||
label: string;
|
||||
items: ProtectionRollup[];
|
||||
}
|
||||
|
||||
interface RecoveryProtectedInventorySectionProps {
|
||||
filteredRollups: Accessor<ProtectionRollup[]>;
|
||||
historyOutcomeFilter: Accessor<'all' | RecoveryOutcome>;
|
||||
|
|
@ -170,6 +177,38 @@ export const RecoveryProtectedInventorySection: Component<
|
|||
return sortedRollups().slice(start, start + PROTECTED_ITEMS_PAGE_SIZE);
|
||||
});
|
||||
|
||||
const isAttentionRollup = (rollup: ProtectionRollup): boolean => {
|
||||
const nowMs = Date.now();
|
||||
const outcome = normalizeRecoveryOutcome(rollup.lastOutcome);
|
||||
if (outcome === 'failed' || outcome === 'warning' || outcome === 'unknown') return true;
|
||||
if (isRecoveryRollupStale(rollup, nowMs)) return true;
|
||||
const successMs = rollup.lastSuccessAt ? Date.parse(rollup.lastSuccessAt) : 0;
|
||||
const attemptMs = rollup.lastAttemptAt ? Date.parse(rollup.lastAttemptAt) : 0;
|
||||
return successMs <= 0 && attemptMs > 0;
|
||||
};
|
||||
|
||||
const visibleGroupedRollups = createMemo<ProtectedInventoryGroup[]>(() => {
|
||||
const attention: ProtectionRollup[] = [];
|
||||
const healthy: ProtectionRollup[] = [];
|
||||
|
||||
for (const rollup of visibleRollups()) {
|
||||
if (isAttentionRollup(rollup)) {
|
||||
attention.push(rollup);
|
||||
} else {
|
||||
healthy.push(rollup);
|
||||
}
|
||||
}
|
||||
|
||||
const groups: ProtectedInventoryGroup[] = [];
|
||||
if (attention.length > 0) {
|
||||
groups.push({ key: 'attention', label: 'Needs Attention', items: attention });
|
||||
}
|
||||
if (healthy.length > 0) {
|
||||
groups.push({ key: 'healthy', label: 'Healthy Coverage', items: healthy });
|
||||
}
|
||||
return groups;
|
||||
});
|
||||
|
||||
const pageStart = createMemo(() =>
|
||||
sortedRollups().length === 0 ? 0 : (protectedPage() - 1) * PROTECTED_ITEMS_PAGE_SIZE + 1,
|
||||
);
|
||||
|
|
@ -399,8 +438,24 @@ export const RecoveryProtectedInventorySection: Component<
|
|||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody class="divide-y divide-border">
|
||||
<For each={visibleRollups()}>
|
||||
{(rollup) => {
|
||||
<For each={visibleGroupedRollups()}>
|
||||
{(group) => (
|
||||
<>
|
||||
<TableRow class="bg-surface-alt">
|
||||
<TableCell
|
||||
colspan={5}
|
||||
class="py-1 pr-3 pl-3 text-[12px] sm:text-sm font-semibold text-base-content"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<span>{group.label}</span>
|
||||
<span class="text-[10px] font-normal uppercase tracking-wide text-muted">
|
||||
{group.items.length} item{group.items.length === 1 ? '' : 's'}
|
||||
</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<For each={group.items}>
|
||||
{(rollup) => {
|
||||
const resourceIndex = props.resourcesById();
|
||||
const label = getRecoveryRollupItemLabel(rollup, resourceIndex);
|
||||
const attemptMs = rollup.lastAttemptAt ? Date.parse(rollup.lastAttemptAt) : 0;
|
||||
|
|
@ -544,7 +599,10 @@ export const RecoveryProtectedInventorySection: Component<
|
|||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}}
|
||||
}}
|
||||
</For>
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue