pcp-tgu-ops-ui: гасить кнопки решения по истечении grace-окна WAITING_DECISION

This commit is contained in:
Дмитрий Соловьев
2026-06-03 10:00:44 +03:00
parent 9a2ba655e1
commit c32e13e09c
@@ -4,6 +4,13 @@ import { platformLabel } from "./tguTimelineMapper";
import { statusStyle } from "./tguStatus"; import { statusStyle } from "./tguStatus";
import { formatUtcDateTime, parseUtc } from "../../utils/utcTime"; import { formatUtcDateTime, parseUtc } from "../../utils/utcTime";
// Бэкенд (pcp-tgu-service) ждёт решения по плану только waiting-decision-grace-minutes
// минут после его startTime; затем IssueDuePlanWorker.tryAdvancePastUnconfirmedPlan
// «молчаливо» продолжает цепочку, оставляя план в WAITING_DECISION, но решение по нему
// больше не принимается (endpoint вернёт 409). Держим значение синхронным с
// config-repo/pcp-tgu-service.yaml → tgu.planning.waiting-decision-grace-minutes.
const DECISION_GRACE_MINUTES = 30;
type TguPlanDetailsProps = { type TguPlanDetailsProps = {
plan?: TguPlanUi; plan?: TguPlanUi;
decisionInFlight: boolean; decisionInFlight: boolean;
@@ -27,6 +34,8 @@ export function TguPlanDetails({ plan, decisionInFlight, notice, error, onDecisi
const style = statusStyle(plan.status); const style = statusStyle(plan.status);
const duration = formatDuration(plan.endMs - plan.startMs); const duration = formatDuration(plan.endMs - plan.startMs);
// Окно решения закрылось, если с момента старта плана прошло больше grace-периода.
const decisionWindowClosed = Date.now() > plan.startMs + DECISION_GRACE_MINUTES * 60_000;
const reject = () => { const reject = () => {
const reason = window.prompt("Reason для REJECTED", "UI_TEST_REJECTED"); const reason = window.prompt("Reason для REJECTED", "UI_TEST_REJECTED");
@@ -62,7 +71,13 @@ export function TguPlanDetails({ plan, decisionInFlight, notice, error, onDecisi
<Detail label="status" value={plan.status} mono /> <Detail label="status" value={plan.status} mono />
</dl> </dl>
{plan.status === "WAITING_DECISION" && ( {plan.status === "WAITING_DECISION" &&
(decisionWindowClosed ? (
<div className="tgu-alert tgu-alert--warning">
Окно решения истекло: прошло больше {DECISION_GRACE_MINUTES} мин после начала плана. Система продолжила
цепочку без подтверждения решение по этому плану больше не принимается.
</div>
) : (
<div className="tgu-details__actions"> <div className="tgu-details__actions">
<button <button
className="tgu-button tgu-button--accept" className="tgu-button tgu-button--accept"
@@ -76,7 +91,7 @@ export function TguPlanDetails({ plan, decisionInFlight, notice, error, onDecisi
Отклонить Отклонить
</button> </button>
</div> </div>
)} ))}
</aside> </aside>
); );
} }