pcp-tgu-ops-ui: вкладка Редактор — план, включения, нижняя панель

- Слева выводим даты начала/конца плана и корректные счётчики
  съёмки/сброса (из plan modes, а не из заглушки-черновика).
- На таймлайне показываем реальные включения плана (read-only): убран
  фейковый «сброс на весь интервал»; вместо линии «сейчас» — маркеры
  начала и конца плана; клик по включению открывает его инфо справа.
- Включения съёмки и сброса разнесены на два ряда (верх/низ) и различаются
  цветом, слева — подписи рядов.
- Нижняя панель: активная дорожка резиновая — примыкает к низу и не
  пустует, при подъёме панели ряды расширяются; высота бара ограничена
  потолком и центрируется в ряду, чтобы узкие включения не вытягивались.
- Время в редакторе парсится/форматируется через utils/utcTime.
This commit is contained in:
Дмитрий Соловьев
2026-06-02 16:54:01 +03:00
parent fb0332a030
commit ac2220d063
7 changed files with 340 additions and 181 deletions
@@ -1,11 +1,12 @@
import type { TguPlanUi, TguPlatformUi } from "../../model/timelineTypes";
import type { Draft, EditorWork } from "./model/editorTypes";
import { formatDateTime } from "./editorPresentation";
type EditorRailProps = {
selectedSpacecraftId?: string;
selectedPlan?: TguPlanUi;
platforms: TguPlatformUi[];
draft: Draft;
surveyCount: number;
downlinkCount: number;
conflictCount: number;
contextSpacecraftIds: Set<string>;
onToggleContext: (spacecraftId: string) => void;
@@ -15,7 +16,8 @@ export function EditorRail({
selectedSpacecraftId,
selectedPlan,
platforms,
draft,
surveyCount,
downlinkCount,
conflictCount,
contextSpacecraftIds,
onToggleContext
@@ -32,10 +34,19 @@ export function EditorRail({
{selectedPlan ? `${selectedPlan.planId} · КПП ${selectedPlan.kppId}` : "План не выбран"}
</div>
{selectedPlan && (
<dl className="tgu-editor-rail__plan-dates">
<dt>Начало</dt>
<dd className="mono">{formatDateTime(selectedPlan.startMs)}</dd>
<dt>Окончание</dt>
<dd className="mono">{formatDateTime(selectedPlan.endMs)}</dd>
</dl>
)}
<div className="tgu-editor-stats">
<RailStat label="Включений" value={draft.works.length} />
<RailStat label="Съёмка" value={countWorks(draft.works, "shoot")} color="var(--t-optical)" />
<RailStat label="Сброс" value={countWorks(draft.works, "downlink")} color="var(--accent)" />
<RailStat label="Включений" value={surveyCount + downlinkCount} />
<RailStat label="Съёмка" value={surveyCount} color="var(--t-optical)" />
<RailStat label="Сброс" value={downlinkCount} color="var(--accent)" />
<RailStat label="Конфл." value={conflictCount} color={conflictCount > 0 ? "var(--now)" : undefined} />
</div>
</section>
@@ -76,7 +87,3 @@ function RailStat({ label, value, color }: { label: string; value: number; color
</div>
);
}
function countWorks(works: EditorWork[], kind: EditorWork["kind"]): number {
return works.filter((work) => work.kind === kind).length;
}