Таймлайн ТГУ: по умолчанию только актуальная цепочка планов
Раньше таймлайн рисовал планы всех статусов, включая историю версий (SUPERSEDED/EXPIRED/REJECTED), из-за чего активная цепочка тонула в наложении старых планов. Теперь по умолчанию показываются только актуальные планы (PLANNED/ISSUING/WAITING_DECISION/ACCEPTED), а историю версий можно включить чекбоксом над таймлайном.
This commit is contained in:
@@ -10,6 +10,7 @@ import { TguPlanningLayout } from "./TguPlanningLayout";
|
||||
import { TguSidebar } from "./TguSidebar";
|
||||
import { TguTimeline } from "./TguTimeline";
|
||||
import { TguToolbar } from "./TguToolbar";
|
||||
import { isActivePlanStatus } from "./tguStatus";
|
||||
import { buildPlatformsForInterval, buildTimelineRows, mapPlans } from "./tguTimelineMapper";
|
||||
|
||||
const DAY_MS = 24 * 60 * 60 * 1000;
|
||||
@@ -28,6 +29,9 @@ export function TguPlanningPage() {
|
||||
const [selectedSpacecraftId, setSelectedSpacecraftId] = useState<string>();
|
||||
const [selectedPlanId, setSelectedPlanId] = useState<string>();
|
||||
const [activeTab, setActiveTab] = useState<TguActiveTab>("timeline");
|
||||
// По умолчанию на таймлайне видна только актуальная цепочка; история версий
|
||||
// (SUPERSEDED/EXPIRED/REJECTED и т.п.) скрыта, чтобы не было визуальной каши.
|
||||
const [showHistory, setShowHistory] = useState(false);
|
||||
// Вкладки рендерятся в режиме keep-alive: каждую монтируем при первом открытии
|
||||
// и дальше держим смонтированной (скрытой через display:none), чтобы её
|
||||
// внутреннее состояние — загруженные заявки, выбор, слои, скролл — не сбрасывалось
|
||||
@@ -98,9 +102,14 @@ export function TguPlanningPage() {
|
||||
() => buildPlatformsForInterval(rawPlatforms, plans, appliedRange),
|
||||
[rawPlatforms, plans, appliedRange]
|
||||
);
|
||||
// Планы, показываемые на таймлайне: по умолчанию только актуальная цепочка.
|
||||
const timelinePlans = useMemo(
|
||||
() => (showHistory ? plans : plans.filter((plan) => isActivePlanStatus(plan.status))),
|
||||
[plans, showHistory]
|
||||
);
|
||||
const rows = useMemo(
|
||||
() => buildTimelineRows(plans, platforms, appliedRange, selectedSpacecraftId),
|
||||
[plans, platforms, appliedRange, selectedSpacecraftId]
|
||||
() => buildTimelineRows(timelinePlans, platforms, appliedRange, selectedSpacecraftId),
|
||||
[timelinePlans, platforms, appliedRange, selectedSpacecraftId]
|
||||
);
|
||||
const selectedPlan = useMemo(() => {
|
||||
const plan = plans.find((item) => item.planId === selectedPlanId);
|
||||
@@ -181,6 +190,16 @@ export function TguPlanningPage() {
|
||||
}}
|
||||
/>
|
||||
<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
|
||||
rows={rows}
|
||||
range={appliedRange}
|
||||
|
||||
@@ -14,6 +14,19 @@ export const STATUS_STYLES: TimelineStatusStyle[] = [
|
||||
|
||||
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 {
|
||||
return (
|
||||
STATUS_BY_NAME.get(status) ?? {
|
||||
|
||||
@@ -346,6 +346,27 @@
|
||||
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 {
|
||||
min-width: 48rem;
|
||||
min-height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user