pcp-tgu-ops-ui: убрать SUPERSEDED/EXPIRED и чекбокс истории на вкладке «Планы»
Статусы SUPERSEDED/EXPIRED удалены из модели tgu-service, поэтому чистим их и во фронте, чтобы не описывать несуществующие состояния. - tguTypes: убраны EXPIRED/SUPERSEDED из union TguPlanStatus. - tguStatus: удалены их стили; заодно снят осиротевший фильтр isActivePlanStatus/ACTIVE_PLAN_STATUSES (после удаления чекбокса не нужен). - tguTimelineMapper: EXPIRED убран из PROBLEM_STATUSES. - tgu-planning.css: удалены классы .status-superseded/.status-expired и осиротевший блок .tgu-timeline-controls. - TguPlanningPage: убран тумблер «Показать историю версий» вместе со стейтом showHistory и фильтром timelinePlans — таймлайн рендерит все планы из API напрямую (перестали скрываться AWAITING_LAYIN/REJECTED/LAYIN_FAILED/NOT_ACCEPTED). EXPIRED в requestTypes (статус заявок) — отдельный домен, не тронут.
This commit is contained in:
@@ -10,7 +10,6 @@ import { TguPlanningLayout } from "./TguPlanningLayout";
|
|||||||
import { TguSidebar } from "./TguSidebar";
|
import { TguSidebar } from "./TguSidebar";
|
||||||
import { TguTimeline } from "./TguTimeline";
|
import { TguTimeline } from "./TguTimeline";
|
||||||
import { TguToolbar } from "./TguToolbar";
|
import { TguToolbar } from "./TguToolbar";
|
||||||
import { isActivePlanStatus } from "./tguStatus";
|
|
||||||
import { buildPlatformsForInterval, buildTimelineRows, mapPlans } from "./tguTimelineMapper";
|
import { buildPlatformsForInterval, buildTimelineRows, mapPlans } from "./tguTimelineMapper";
|
||||||
|
|
||||||
const DAY_MS = 24 * 60 * 60 * 1000;
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
||||||
@@ -29,9 +28,6 @@ export function TguPlanningPage() {
|
|||||||
const [selectedSpacecraftId, setSelectedSpacecraftId] = useState<string>();
|
const [selectedSpacecraftId, setSelectedSpacecraftId] = useState<string>();
|
||||||
const [selectedPlanId, setSelectedPlanId] = useState<string>();
|
const [selectedPlanId, setSelectedPlanId] = useState<string>();
|
||||||
const [activeTab, setActiveTab] = useState<TguActiveTab>("timeline");
|
const [activeTab, setActiveTab] = useState<TguActiveTab>("timeline");
|
||||||
// По умолчанию на таймлайне видна только актуальная цепочка; история версий
|
|
||||||
// (SUPERSEDED/EXPIRED/REJECTED и т.п.) скрыта, чтобы не было визуальной каши.
|
|
||||||
const [showHistory, setShowHistory] = useState(false);
|
|
||||||
// Вкладки рендерятся в режиме keep-alive: каждую монтируем при первом открытии
|
// Вкладки рендерятся в режиме keep-alive: каждую монтируем при первом открытии
|
||||||
// и дальше держим смонтированной (скрытой через display:none), чтобы её
|
// и дальше держим смонтированной (скрытой через display:none), чтобы её
|
||||||
// внутреннее состояние — загруженные заявки, выбор, слои, скролл — не сбрасывалось
|
// внутреннее состояние — загруженные заявки, выбор, слои, скролл — не сбрасывалось
|
||||||
@@ -102,14 +98,9 @@ export function TguPlanningPage() {
|
|||||||
() => buildPlatformsForInterval(rawPlatforms, plans, appliedRange),
|
() => buildPlatformsForInterval(rawPlatforms, plans, appliedRange),
|
||||||
[rawPlatforms, plans, appliedRange]
|
[rawPlatforms, plans, appliedRange]
|
||||||
);
|
);
|
||||||
// Планы, показываемые на таймлайне: по умолчанию только актуальная цепочка.
|
|
||||||
const timelinePlans = useMemo(
|
|
||||||
() => (showHistory ? plans : plans.filter((plan) => isActivePlanStatus(plan.status))),
|
|
||||||
[plans, showHistory]
|
|
||||||
);
|
|
||||||
const rows = useMemo(
|
const rows = useMemo(
|
||||||
() => buildTimelineRows(timelinePlans, platforms, appliedRange, selectedSpacecraftId),
|
() => buildTimelineRows(plans, platforms, appliedRange, selectedSpacecraftId),
|
||||||
[timelinePlans, platforms, appliedRange, selectedSpacecraftId]
|
[plans, platforms, appliedRange, selectedSpacecraftId]
|
||||||
);
|
);
|
||||||
const selectedPlan = useMemo(() => {
|
const selectedPlan = useMemo(() => {
|
||||||
const plan = plans.find((item) => item.planId === selectedPlanId);
|
const plan = plans.find((item) => item.planId === selectedPlanId);
|
||||||
@@ -190,16 +181,6 @@ export function TguPlanningPage() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<section className="tgu-center">
|
<section className="tgu-center">
|
||||||
<div className="tgu-timeline-controls">
|
|
||||||
<label className="tgu-timeline-controls__toggle">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
checked={showHistory}
|
|
||||||
onChange={(event) => setShowHistory(event.target.checked)}
|
|
||||||
/>
|
|
||||||
Показать историю версий (SUPERSEDED, EXPIRED и др.)
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<TguTimeline
|
<TguTimeline
|
||||||
rows={rows}
|
rows={rows}
|
||||||
range={appliedRange}
|
range={appliedRange}
|
||||||
|
|||||||
@@ -7,26 +7,11 @@ export const STATUS_STYLES: TimelineStatusStyle[] = [
|
|||||||
{ status: "WAITING_DECISION", label: "WAITING_DECISION", color: "#f0ad2e", className: "status-waiting" },
|
{ status: "WAITING_DECISION", label: "WAITING_DECISION", color: "#f0ad2e", className: "status-waiting" },
|
||||||
{ status: "PLANNED", label: "PLANNED", color: "#8d99a6", className: "status-planned" },
|
{ status: "PLANNED", label: "PLANNED", color: "#8d99a6", className: "status-planned" },
|
||||||
{ status: "ISSUING", label: "ISSUING", color: "#2f80ed", className: "status-issuing" },
|
{ status: "ISSUING", label: "ISSUING", color: "#2f80ed", className: "status-issuing" },
|
||||||
{ status: "EXPIRED", label: "EXPIRED", color: "#495057", className: "status-expired" },
|
|
||||||
{ status: "SUPERSEDED", label: "SUPERSEDED", color: "#c7ced6", className: "status-superseded" },
|
|
||||||
{ status: "START_AMBIGUOUS", label: "START_AMBIGUOUS", color: "#b42318", className: "status-ambiguous" }
|
{ status: "START_AMBIGUOUS", label: "START_AMBIGUOUS", color: "#b42318", className: "status-ambiguous" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const STATUS_BY_NAME = new Map(STATUS_STYLES.map((style) => [style.status, style]));
|
const STATUS_BY_NAME = new Map(STATUS_STYLES.map((style) => [style.status, style]));
|
||||||
|
|
||||||
/** Статусы актуальной цепочки: их показываем на таймлайне по умолчанию. */
|
|
||||||
const ACTIVE_PLAN_STATUSES = new Set<TguPlanStatus>([
|
|
||||||
"PLANNED",
|
|
||||||
"ISSUING",
|
|
||||||
"WAITING_DECISION",
|
|
||||||
"ACCEPTED"
|
|
||||||
]);
|
|
||||||
|
|
||||||
/** Проверяет, относится ли план к актуальной цепочке (а не к истории версий). */
|
|
||||||
export function isActivePlanStatus(status: TguPlanStatus): boolean {
|
|
||||||
return ACTIVE_PLAN_STATUSES.has(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function statusStyle(status: TguPlanStatus): TimelineStatusStyle {
|
export function statusStyle(status: TguPlanStatus): TimelineStatusStyle {
|
||||||
return (
|
return (
|
||||||
STATUS_BY_NAME.get(status) ?? {
|
STATUS_BY_NAME.get(status) ?? {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { TguPlan, TguPlatform } from "../../model/tguTypes";
|
import type { TguPlan, TguPlatform } from "../../model/tguTypes";
|
||||||
import type { TguPlanUi, TguPlatformUi, TimelineRange, TimelineRow } from "../../model/timelineTypes";
|
import type { TguPlanUi, TguPlatformUi, TimelineRange, TimelineRow } from "../../model/timelineTypes";
|
||||||
|
|
||||||
const PROBLEM_STATUSES = new Set(["REJECTED", "EXPIRED", "START_AMBIGUOUS"]);
|
const PROBLEM_STATUSES = new Set(["REJECTED", "START_AMBIGUOUS"]);
|
||||||
|
|
||||||
export function mapPlans(plans: TguPlan[], platforms: TguPlatform[]): TguPlanUi[] {
|
export function mapPlans(plans: TguPlan[], platforms: TguPlatform[]): TguPlanUi[] {
|
||||||
const platformByNorad = buildPlatformByNorad(platforms);
|
const platformByNorad = buildPlatformByNorad(platforms);
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ export type TguPlanStatus =
|
|||||||
| "WAITING_DECISION"
|
| "WAITING_DECISION"
|
||||||
| "PLANNED"
|
| "PLANNED"
|
||||||
| "ISSUING"
|
| "ISSUING"
|
||||||
| "EXPIRED"
|
|
||||||
| "SUPERSEDED"
|
|
||||||
| "START_AMBIGUOUS"
|
| "START_AMBIGUOUS"
|
||||||
| string;
|
| string;
|
||||||
|
|
||||||
|
|||||||
@@ -183,14 +183,6 @@
|
|||||||
background-color: #2f80ed;
|
background-color: #2f80ed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-expired {
|
|
||||||
background-color: #495057;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-superseded {
|
|
||||||
background-color: #c7ced6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-ambiguous {
|
.status-ambiguous {
|
||||||
background-color: #b42318;
|
background-color: #b42318;
|
||||||
outline: 1px dashed #ffd1d1;
|
outline: 1px dashed #ffd1d1;
|
||||||
@@ -346,27 +338,6 @@
|
|||||||
background: #121516;
|
background: #121516;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tgu-timeline-controls {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.75rem;
|
|
||||||
padding: 0.6rem 0.85rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tgu-timeline-controls__toggle {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.4rem;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--muted, #9aa4ad);
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tgu-timeline-controls__toggle input {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tgu-timeline {
|
.tgu-timeline {
|
||||||
min-width: 48rem;
|
min-width: 48rem;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user