diff --git a/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx b/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx index bf4896a..6b71a74 100644 --- a/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx +++ b/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx @@ -351,7 +351,34 @@ export default function DeliverableDetailPage() {
{stages.map((stage: any) => { - const available = TRANSITIONS[stage.status] ?? []; + // Per-stage approval type drives both the inline transition + // set AND whether the StageReviewPanel below the row owns + // the action buttons. NONE = open/close only (Start Work, + // Mark Complete, Reopen — nothing else). SIMPLE/FORMAL hand + // off to the review panel. + const stageApprovalType = + stage.stageDefinition?.approvalType ?? + stage.template?.approvalType ?? + "NONE"; + const isNoneApproval = stageApprovalType === "NONE"; + + // For NONE stages, override the transition set with a minimal + // open/close shape so producers never see Submit-for-Review, + // Approve, Request-Changes, Mark-Delivered on a non-review row. + const NONE_TRANSITIONS: Record = { + BLOCKED: [], + NOT_STARTED: ["IN_PROGRESS"], + IN_PROGRESS: ["APPROVED"], + IN_REVIEW: ["APPROVED"], + CHANGES_REQUESTED: ["IN_PROGRESS"], + APPROVED: ["IN_PROGRESS"], + DELIVERED: ["IN_PROGRESS"], + SKIPPED: ["NOT_STARTED"], + }; + const available = isNoneApproval + ? NONE_TRANSITIONS[stage.status] ?? [] + : TRANSITIONS[stage.status] ?? []; + const assignments = stage.assignments ?? []; const isGate = stage.stageDefinition?.isCriticalGate ?? stage.template.isCriticalGate; const isOptional = stage.stageDefinition?.isOptional ?? stage.template.isOptional; @@ -474,9 +501,15 @@ export default function DeliverableDetailPage() { stage.status === "DELIVERED")) || (nextStatus === "NOT_STARTED" && stage.status === "SKIPPED"); + // NONE-approval stages don't have the review + // concept — relabel APPROVED to "Mark Complete" + // so the affordance reads as a workflow close, + // not a review approval. const label = isReopen ? "Reopen" - : (TRANSITION_LABELS[nextStatus] ?? nextStatus); + : isNoneApproval && nextStatus === "APPROVED" + ? "Mark Complete" + : (TRANSITION_LABELS[nextStatus] ?? nextStatus); return (