diff --git a/services/pcp-tgu-ops-ui/src/features/tgu-editor/EditorPanels.tsx b/services/pcp-tgu-ops-ui/src/features/tgu-editor/EditorPanels.tsx
index 822f593..19ba16e 100644
--- a/services/pcp-tgu-ops-ui/src/features/tgu-editor/EditorPanels.tsx
+++ b/services/pcp-tgu-ops-ui/src/features/tgu-editor/EditorPanels.tsx
@@ -29,6 +29,10 @@ type WorkInspectorProps = {
work: EditorWork;
modes: EditorMode[];
stations: EditorGroundStation[];
+ /** Название аппарата редактора — для блока параметров включения. */
+ spacecraftLabel?: string;
+ /** Метка съёмки по id режима — для перечня сбрасываемых маршрутов у сброса. */
+ surveyModeLabel?: (surveyModeId: number) => string;
conflicts: string[];
/** Включение существующего плана — показываем только информацию, без правок. */
readOnly?: boolean;
@@ -118,6 +122,8 @@ export function WorkInspector({
work,
modes,
stations,
+ spacecraftLabel,
+ surveyModeLabel,
conflicts,
readOnly,
onUpdate,
@@ -160,6 +166,58 @@ export function WorkInspector({
)}
+
+ Параметры включения
+
+ - Аппарат
+ - {spacecraftLabel ?? "—"}
+ - Виток
+ - {work.revolution ?? "—"}
+ {work.kind === "shoot" && (
+ <>
+ - Крен
+ - {work.rollDeg != null ? `${work.rollDeg.toFixed(1)}°` : "—"}
+ - Угол захвата
+ - {work.captureAngleDeg != null ? `${work.captureAngleDeg.toFixed(1)}°` : "—"}
+ - Центр контура
+ -
+ {work.centerLat != null && work.centerLon != null
+ ? `${work.centerLat.toFixed(2)}, ${work.centerLon.toFixed(2)}`
+ : "—"}
+
+ >
+ )}
+ {work.kind === "downlink" && (
+ <>
+ - Станция
+ - {stations.find((station) => station.id === work.stationId)?.name ?? work.stationId ?? "—"}
+ >
+ )}
+
+
+
+ {work.kind === "shoot" && (
+
+ Задания под маршрутом
+ Привязка заданий к маршруту появится позже.
+
+ )}
+
+ {work.kind === "downlink" && (
+
+ Сбрасываемые съёмки
+ {work.surveyIds && work.surveyIds.length > 0 ? (
+
+ {work.surveyIds.map((surveyId) => (
+ - {surveyModeLabel ? surveyModeLabel(surveyId) : `Маршрут #${surveyId}`}
+ ))}
+
+ ) : (
+ Маршруты съёмки к сбросу не привязаны.
+ )}
+
+ )}
+
{work.kind === "shoot" && (
Режим аппаратуры
@@ -183,20 +241,16 @@ export function WorkInspector({
)}
- {work.kind === "downlink" && (
+ {work.kind === "downlink" && !readOnly && (
Станция приёма
- {readOnly ? (
- {stations.find((station) => station.id === work.stationId)?.name ?? work.stationId ?? "—"}
- ) : (
-
- )}
+
)}
diff --git a/services/pcp-tgu-ops-ui/src/features/tgu-editor/TguEditorTab.tsx b/services/pcp-tgu-ops-ui/src/features/tgu-editor/TguEditorTab.tsx
index a3bfedd..1530538 100644
--- a/services/pcp-tgu-ops-ui/src/features/tgu-editor/TguEditorTab.tsx
+++ b/services/pcp-tgu-ops-ui/src/features/tgu-editor/TguEditorTab.tsx
@@ -453,7 +453,12 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
endMs,
label: mode?.label ?? "Съёмка",
modeId,
- target
+ target,
+ revolution: surveyRoute?.revolution ?? selectedShootPass.revolution,
+ rollDeg: surveyRoute?.roll ?? routeRoll,
+ captureAngleDeg: surveyRoute?.captureAngle ?? DEFAULT_CAPTURE_ANGLE_DEG,
+ centerLat: surveyRoute?.lat,
+ centerLon: surveyRoute?.longitude
})
);
setSelectedWorkId(id);
@@ -468,6 +473,17 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
[stationDtos]
);
+ // Метка съёмки по id режима — для перечня сбрасываемых маршрутов в инспекторе сброса.
+ const surveyModeLabel = useCallback(
+ (surveyModeId: number) => {
+ const mode = planModes.find(
+ (m): m is PlanSurveyMode => m.type === "SURVEY" && m.id === surveyModeId
+ );
+ return mode ? `Съёмка · виток ${mode.revolution}` : `Маршрут #${surveyModeId}`;
+ },
+ [planModes]
+ );
+
const addDropWork = async () => {
if (!selectedPlan || !selectedZone || selectedDropSurveyIds.size === 0) return;
const numericNorad = noradId ? Number(noradId) : NaN;
@@ -735,6 +751,8 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
work={selectedWork}
modes={modes}
stations={stations}
+ spacecraftLabel={activeLabel}
+ surveyModeLabel={surveyModeLabel}
conflicts={conflicts[selectedWork.id] ?? []}
readOnly={selectedWork.origin === "plan"}
onUpdate={onChangeWork}
diff --git a/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.test.ts b/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.test.ts
index eedaae2..4eb494e 100644
--- a/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.test.ts
+++ b/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.test.ts
@@ -88,6 +88,11 @@ describe("editorDraft", () => {
startMs: parseUtc("2026-05-29T01:10:00Z"),
endMs: parseUtc("2026-05-29T01:10:00Z") + 180_000,
origin: "plan",
+ planModeId: 11,
+ revolution: 4321,
+ rollDeg: 0,
+ centerLat: 55.7,
+ centerLon: 37.6,
targetLat: 55.7,
targetLon: 37.6
},
@@ -98,7 +103,10 @@ describe("editorDraft", () => {
startMs: parseUtc("2026-05-29T01:40:00Z"),
endMs: parseUtc("2026-05-29T01:40:00Z") + 120_000,
origin: "plan",
- stationId: "102"
+ planModeId: 22,
+ revolution: 4322,
+ stationId: "102",
+ surveyIds: [11]
}
]);
});
diff --git a/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.ts b/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.ts
index d3b1b4e..54179fe 100644
--- a/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.ts
+++ b/services/pcp-tgu-ops-ui/src/features/tgu-editor/editorDraft.ts
@@ -22,6 +22,12 @@ export type AddShootInput = {
label: string;
modeId?: string;
target: EditorTarget;
+ /** Параметры построенного маршрута (если съёмка строилась с превью). */
+ revolution?: number;
+ rollDeg?: number;
+ captureAngleDeg?: number;
+ centerLat?: number;
+ centerLon?: number;
};
export type AddDownlinkInput = {
@@ -66,6 +72,12 @@ export function planModesToWorks(modes: PlanMode[]): EditorWork[] {
startMs,
endMs,
origin: "plan",
+ planModeId: mode.id,
+ revolution: mode.revolution,
+ rollDeg: mode.roll,
+ centerLat: mode.lat,
+ centerLon: mode.longitude,
+ // Центр контура — он же опорная точка для проверки видимости.
targetLat: mode.lat,
targetLon: mode.longitude
}];
@@ -78,7 +90,10 @@ export function planModesToWorks(modes: PlanMode[]): EditorWork[] {
startMs,
endMs,
origin: "plan",
- stationId: mode.station ?? undefined
+ planModeId: mode.id,
+ revolution: mode.revolution,
+ stationId: mode.station ?? undefined,
+ surveyIds: mode.surveys
}];
});
}
@@ -136,6 +151,11 @@ export function addShoot(draft: Draft, input: AddShootInput): Draft {
targetName: input.target.name,
targetLat: input.target.lat,
targetLon: input.target.lon,
+ revolution: input.revolution,
+ rollDeg: input.rollDeg,
+ captureAngleDeg: input.captureAngleDeg,
+ centerLat: input.centerLat,
+ centerLon: input.centerLon,
origin: "added",
isNew: true
};
diff --git a/services/pcp-tgu-ops-ui/src/features/tgu-editor/model/editorTypes.ts b/services/pcp-tgu-ops-ui/src/features/tgu-editor/model/editorTypes.ts
index c1bfa97..2a69a9d 100644
--- a/services/pcp-tgu-ops-ui/src/features/tgu-editor/model/editorTypes.ts
+++ b/services/pcp-tgu-ops-ui/src/features/tgu-editor/model/editorTypes.ts
@@ -20,11 +20,28 @@ export type EditorShootWork = EditorWorkBase & {
targetName?: string;
targetLat?: number;
targetLon?: number;
+ /** Идентификатор сохранённого режима съёмки в БД (есть у включений плана). */
+ planModeId?: number;
+ /** Номер витка. */
+ revolution?: number;
+ /** Крен (gamma), град. */
+ rollDeg?: number;
+ /** Угол захвата (полуширина полосы), град. Есть только у свежепостроенного маршрута. */
+ captureAngleDeg?: number;
+ /** Центр контура съёмки, град. */
+ centerLat?: number;
+ centerLon?: number;
};
export type EditorDownlinkWork = EditorWorkBase & {
kind: "downlink";
stationId?: string;
+ /** Идентификатор сохранённого режима сброса в БД (есть у включений плана). */
+ planModeId?: number;
+ /** Номер витка зоны радиовидимости. */
+ revolution?: number;
+ /** Идентификаторы режимов съёмки (survey_modes), сбрасываемых в этом сеансе. */
+ surveyIds?: number[];
};
export type EditorWork = EditorShootWork | EditorDownlinkWork;
diff --git a/services/pcp-tgu-ops-ui/src/styles/tgu-editor.css b/services/pcp-tgu-ops-ui/src/styles/tgu-editor.css
index 01f341e..0b8a24a 100644
--- a/services/pcp-tgu-ops-ui/src/styles/tgu-editor.css
+++ b/services/pcp-tgu-ops-ui/src/styles/tgu-editor.css
@@ -47,6 +47,15 @@
font-size: 0.68rem;
}
+.tgu-editor-panel__list {
+ margin: 0;
+ padding-left: 1.1rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+ font-size: 0.72rem;
+}
+
.tgu-editor-toolbar__group {
display: flex;
gap: 0.35rem;