Simplify campaign list and add searchable status filters
This commit is contained in:
@@ -2,6 +2,40 @@ import { statusPresentation, type StatusTone } from './status.js';
|
||||
|
||||
export type CampaignServerGroup = 'attention' | 'processing' | 'queued' | 'complete' | 'inactive';
|
||||
|
||||
export interface CampaignSummary {
|
||||
action: string;
|
||||
beta_id: number | null;
|
||||
rolled_back_by: string | null;
|
||||
script_name: string | null;
|
||||
script_version: number | null;
|
||||
scripts: { script_name: string | null; script_version: number | null }[];
|
||||
servers: { restart_state: string; server_deleted_at?: string | null }[];
|
||||
}
|
||||
|
||||
export function campaignTitle(campaign: CampaignSummary): string {
|
||||
const action = campaign.action === 'drift' ? 'Maintenance repair'
|
||||
: campaign.action.charAt(0).toUpperCase() + campaign.action.slice(1);
|
||||
if (campaign.action === 'drift') return action;
|
||||
if (campaign.action === 'rollback' && campaign.beta_id) return `${action} · Beta #${campaign.beta_id}`;
|
||||
if (campaign.scripts.length > 1) return `${action} · ${campaign.scripts.length} scripts`;
|
||||
const script = campaign.scripts[0] ?? campaign;
|
||||
if (script.script_name) return `${action} · ${script.script_name}${script.script_version !== null ? ` v${script.script_version}` : ''}`;
|
||||
return campaign.beta_id ? `${action} · Beta #${campaign.beta_id}` : action;
|
||||
}
|
||||
|
||||
export function campaignOutcome(campaign: Pick<CampaignSummary, 'servers' | 'rolled_back_by'>): {
|
||||
status: 'attention' | 'progress' | 'rolled-back' | 'complete' | 'inactive'; label: string; tone: StatusTone; completed: number;
|
||||
} {
|
||||
const completed = campaign.servers.filter(server => server.restart_state === 'done').length;
|
||||
const live = campaign.servers.filter(server => !server.server_deleted_at);
|
||||
const attention = live.filter(server => ['failed', 'held', 'manual'].includes(server.restart_state));
|
||||
if (attention.length) return { status: 'attention', label: `${attention.length} need attention`, tone: attention.some(server => server.restart_state === 'failed') ? 'danger' : 'warning', completed };
|
||||
if (live.some(server => server.restart_state === 'pending')) return { status: 'progress', label: `${completed}/${campaign.servers.length} complete`, tone: 'info', completed };
|
||||
if (campaign.rolled_back_by) return { status: 'rolled-back', label: 'Rolled back', tone: 'neutral', completed };
|
||||
if (campaign.servers.length && completed === campaign.servers.length) return { status: 'complete', label: 'Complete', tone: 'online', completed };
|
||||
return { status: 'inactive', label: completed ? `${completed}/${campaign.servers.length} complete` : 'Inactive', tone: 'neutral', completed };
|
||||
}
|
||||
|
||||
/** Progress comes from recorded state, not the error field, which also contains routine stage messages. */
|
||||
export function campaignServerStatus(server: {
|
||||
restart_state: string; server_deleted_at?: string | null; restarted_at: string | null;
|
||||
|
||||
Reference in New Issue
Block a user