Files
Agent-System/web/src/lib/projectSettingsMode.ts
T
weichenandCursor 3a0f7a1033 fix(web): route prefixed task keys and keep live settings editable
Message routing follows the project's real task key, account switches clear local workbench state, and the duty matrix writes the reassignment API instead of a local drill.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-21 05:20:01 +00:00

85 lines
2.8 KiB
TypeScript

import type { ProjectSettings, WorkflowPlan } from '../types/projectSettings';
export type ProjectSettingsMode = 'loading' | 'planning' | 'live_edit' | 'frozen' | 'error';
export function resolveProjectSettingsMode(input: {
loading?: boolean;
settings?: Pick<ProjectSettings, 'can_edit_plan' | 'lifecycle_status' | 'live_instance' | 'plan_edit_mode'> | null;
loadError?: boolean;
}): ProjectSettingsMode {
if (input.loadError && !input.settings) return 'error';
if (input.loading && !input.settings) return 'loading';
const settings = input.settings;
if (!settings) return 'loading';
if (settings.plan_edit_mode === 'frozen') return 'frozen';
if (settings.plan_edit_mode === 'live') return 'live_edit';
if (settings.plan_edit_mode === 'planning') return 'planning';
const live = settings.live_instance;
const closed = Boolean(live && (live.status === 'completed' || live.status === 'terminated'));
if (closed) return 'frozen';
if (live) return 'live_edit';
if (!settings.can_edit_plan) return 'frozen';
if (settings.lifecycle_status === 'active') return 'frozen';
return 'planning';
}
export function shouldShowPlanEditor(mode: ProjectSettingsMode): boolean {
return mode === 'planning' || mode === 'live_edit';
}
export function shouldShowSavePreview(mode: ProjectSettingsMode): boolean {
return mode === 'planning' || mode === 'live_edit';
}
export function projectSettingsChrome(mode: ProjectSettingsMode): {
showWorkflowSelector: boolean;
showDutySelects: boolean;
showSavePreview: boolean;
showStepPills: boolean;
showFrozenSnapshot: boolean;
showDutyReassign: boolean;
} {
const planning = mode === 'planning';
const live = mode === 'live_edit';
const frozen = mode === 'frozen';
return {
showWorkflowSelector: planning,
showDutySelects: planning || live,
showSavePreview: planning || live,
showStepPills: planning,
showFrozenSnapshot: frozen,
showDutyReassign: frozen,
};
}
export function afterFrozenConflictReload(
settings: Pick<ProjectSettings, 'can_edit_plan' | 'lifecycle_status' | 'live_instance'>,
draftPlan: WorkflowPlan,
): { plan: WorkflowPlan; mode: ProjectSettingsMode } {
return {
plan: draftPlan,
mode: resolveProjectSettingsMode({ settings }),
};
}
export function frozenDutySnapshot(plan?: WorkflowPlan | null): Array<{
taskKey: string;
title: string;
author?: number;
reviewer?: number;
approver?: number;
}> {
if (!plan) return [];
return plan.stages.flatMap((stage) =>
stage.doc_tasks
.filter((task) => task.enabled)
.map((task) => ({
taskKey: task.task_key,
title: task.task_title || task.task_key,
author: task.duties.author_user_id,
reviewer: task.duties.reviewer_user_id,
approver: task.duties.approver_user_id,
})),
);
}