pcp-tgu-ops-ui: тест-кнопка закладки, статус SUPERSEDED, подсветка цепочки
- Тест-кнопка «Подтвердить закладку» в деталях плана для AWAITING_LAYIN (под подписью «ТЕСТОВЫЙ ФУНКЦИОНАЛ», с подтверждением). Гасится, если по КА уже заложен план со стартом в пределах ±10 мин (дублирует бэкенд-гард). - Статус SUPERSEDED: стиль/подпись/легенда. - Поиск уже созданного черновика — по слоту (КА + окно исходного плана), т.к. basePlanId черновика теперь = предшественник, а не исходный план. - Таймлайн: при выборе плана непричастные планы гаснут, а текущий/прошлый/ следующий обводятся яркими рамками (current #2563EB, prev #94A3B8, next #F59E0B). Асимметрия: prev (явная база выбранного) показывается всегда, даже REJECTED/SUPERSEDED; next (обратная ссылка) не подсвечивает мёртвые статусы — иначе вытесненная коррекция ложно числилась бы «следующей» у заложенного плана.
This commit is contained in:
@@ -15,6 +15,21 @@ import { formatLocalDate, formatLocalDateTime, formatLocalTime, parseLocal } fro
|
||||
|
||||
export type ZrvWindow = { startMs: number; endMs: number; kppId: string };
|
||||
|
||||
// Терминально-«мёртвые» статусы: план выбыл из живой цепочки (вытеснен закладкой, отклонён,
|
||||
// не принят, сбой закладки, неоднозначный старт). Применяется ТОЛЬКО к «следующему» (обратная
|
||||
// ссылка basePlanId → выбранный, она неоднозначна): мёртвый план — это, как правило, коррекция,
|
||||
// проигравшая гонку закладки и оставшаяся со ссылкой base_plan_id на победителя (особенно старые
|
||||
// строки до наследования предшественника), и без фильтра она ложно показывалась бы «следующей».
|
||||
// На «предыдущий» НЕ распространяется: это явная база самого выбранного плана (forward-ссылка из
|
||||
// его поля basePlanId) — её показываем всегда, даже если база REJECTED/SUPERSEDED.
|
||||
const DEAD_LINK_STATUSES: ReadonlySet<string> = new Set([
|
||||
"SUPERSEDED",
|
||||
"REJECTED",
|
||||
"LAYIN_FAILED",
|
||||
"NOT_ACCEPTED",
|
||||
"START_AMBIGUOUS"
|
||||
]);
|
||||
|
||||
type ZrvBands = {
|
||||
spacecraftId: string;
|
||||
windows: ZrvWindow[];
|
||||
@@ -207,19 +222,26 @@ export function TguTimeline({
|
||||
const selected = selectedPlanId === segment.plan.planId;
|
||||
// Сосед выбранного по цепочке: предыдущий (прошлое) — planId == basePlanId выбранного;
|
||||
// следующий (будущее) — basePlanId == выбранный. Подсветка по реальной связи, не по времени.
|
||||
// prev — явная база выбранного плана (forward-ссылка), показываем всегда, даже мёртвую.
|
||||
// next — обратная ссылка; мёртвый план (вытесненный/отклонённый конкурент того же слота)
|
||||
// живым продолжением не подсвечиваем.
|
||||
const liveLink = !DEAD_LINK_STATUSES.has(segment.plan.status);
|
||||
const neighbor = selected
|
||||
? undefined
|
||||
: selectedBasePlanId && segment.plan.planId === selectedBasePlanId
|
||||
? "prev"
|
||||
: selectedPlanId && segment.plan.basePlanId === selectedPlanId
|
||||
: selectedPlanId && liveLink && segment.plan.basePlanId === selectedPlanId
|
||||
? "next"
|
||||
: undefined;
|
||||
const labelVisible = segment.width > 92;
|
||||
// При активном выборе все «непричастные» планы гасим до еле заметных, а текущий /
|
||||
// прошлый / следующий обводим яркой рамкой — так видно звенья цепочки выбранного плана.
|
||||
const dimmed = selectedPlanId !== undefined && !selected && neighbor === undefined;
|
||||
|
||||
return (
|
||||
<g
|
||||
key={segment.plan.planId}
|
||||
className={`tgu-timeline-plan ${selected ? "is-selected" : ""}`}
|
||||
className={`tgu-timeline-plan ${selected ? "is-selected" : ""} ${dimmed ? "is-dimmed" : ""}`}
|
||||
onClick={() => onSelectPlan(segment.plan.planId)}
|
||||
>
|
||||
<title>
|
||||
|
||||
Reference in New Issue
Block a user