pcp-tgu-ops-ui: одно перекрестие опорной точки + 24ч формат времени

- Редактор: убрано накопление целей съёмки — на карте только одно
  перекрестие текущей точки (pickTarget заменяется при каждом клике),
  с перекрестия убрана подпись. Правая панель переименована в
  «Опорная точка прицеливания» с координатами.
- 24-часовой формат: lang="ru-RU" на всех datetime-local инпутах
  (Планы, фильтры заявок на карте, создание/фильтр заявок), иначе
  браузер рендерил их по локали ОС в AM/PM.
This commit is contained in:
Дмитрий Соловьев
2026-06-02 23:33:32 +03:00
parent e68c17e792
commit f0e16aa4e8
7 changed files with 13 additions and 23 deletions
@@ -250,7 +250,7 @@ export function ShootPanel({
<section className="tgu-editor-panel__section"> <section className="tgu-editor-panel__section">
<div className="tgu-editor-panel__section-head"> <div className="tgu-editor-panel__section-head">
<div className="tgu-editor-eyebrow">1 · цель съёмки</div> <div className="tgu-editor-eyebrow">1 · опорная точка прицеливания</div>
{target && ( {target && (
<button className="tgu-link-button" type="button" onClick={onClearTarget}> <button className="tgu-link-button" type="button" onClick={onClearTarget}>
сбросить сбросить
@@ -258,7 +258,7 @@ export function ShootPanel({
)} )}
</div> </div>
{!target ? ( {!target ? (
<div className="tgu-editor-panel__placeholder">Кликните точку на карте слева, чтобы выбрать цель съёмки.</div> <div className="tgu-editor-panel__placeholder">Кликните точку на карте слева, чтобы задать опорную точку прицеливания.</div>
) : ( ) : (
<div className="tgu-editor-target"> <div className="tgu-editor-target">
<i /> <i />
@@ -37,7 +37,6 @@ import type {
DraftHistory, DraftHistory,
EditorGroundStation, EditorGroundStation,
EditorMode, EditorMode,
EditorShootWork,
EditorTarget, EditorTarget,
EditorTimelineWindow, EditorTimelineWindow,
EditorVisibilityTrack, EditorVisibilityTrack,
@@ -167,13 +166,6 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
() => buildEditorMapScene(selectedSpacecraftId, flightLineData, orbitPasses, stationDtos, requestItems, planModes, effectiveFrom, effectiveTo, surveyRoute), () => buildEditorMapScene(selectedSpacecraftId, flightLineData, orbitPasses, stationDtos, requestItems, planModes, effectiveFrom, effectiveTo, surveyRoute),
[selectedSpacecraftId, flightLineData, orbitPasses, stationDtos, requestItems, planModes, effectiveFrom, effectiveTo, surveyRoute] [selectedSpacecraftId, flightLineData, orbitPasses, stationDtos, requestItems, planModes, effectiveFrom, effectiveTo, surveyRoute]
); );
const shootTargets = useMemo(
() =>
draft.works
.filter((w): w is EditorShootWork => w.kind === "shoot" && w.targetLat !== undefined && w.targetLon !== undefined)
.map((w) => ({ id: w.id, name: w.label, lat: w.targetLat!, lon: w.targetLon! })),
[draft.works]
);
const contextLanes = useMemo( const contextLanes = useMemo(
() => () =>
Array.from(contextSpacecraftIds).map((spacecraftId) => ({ Array.from(contextSpacecraftIds).map((spacecraftId) => ({
@@ -692,19 +684,14 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
layers={EDITOR_MAP_LAYERS} layers={EDITOR_MAP_LAYERS}
redrawToken={0} redrawToken={0}
pickMode={rightMode === "shoot"} pickMode={rightMode === "shoot"}
targets={shootTargets}
pickTarget={target ?? undefined} pickTarget={target ?? undefined}
selectedTargetId={selectedWork?.kind === "shoot" ? selectedWorkId : undefined}
onTargetSelect={(id) => {
setSelectedWorkId(id);
setRightMode("inspect");
setNotice(undefined);
}}
onPickPoint={(point) => { onPickPoint={(point) => {
// Опорная точка прицеливания — всегда одна: каждый клик заменяет
// предыдущее перекрестие, цели не накапливаются.
targetCounterRef.current += 1; targetCounterRef.current += 1;
setTarget({ setTarget({
id: `target-${targetCounterRef.current}`, id: `target-${targetCounterRef.current}`,
name: `Цель ${targetCounterRef.current}`, name: "Опорная точка прицеливания",
lat: point.lat, lat: point.lat,
lon: point.lon lon: point.lon
}); });
@@ -106,6 +106,7 @@ export function Tgu2DMapSidebar({
<label className="tgu-field"> <label className="tgu-field">
<span>С</span> <span>С</span>
<input <input
lang="ru-RU"
type="datetime-local" type="datetime-local"
value={requestsState.fromValue} value={requestsState.fromValue}
onChange={(e) => onRequestsFromChange(e.target.value)} onChange={(e) => onRequestsFromChange(e.target.value)}
@@ -114,6 +115,7 @@ export function Tgu2DMapSidebar({
<label className="tgu-field"> <label className="tgu-field">
<span>По</span> <span>По</span>
<input <input
lang="ru-RU"
type="datetime-local" type="datetime-local"
value={requestsState.toValue} value={requestsState.toValue}
onChange={(e) => onRequestsToChange(e.target.value)} onChange={(e) => onRequestsToChange(e.target.value)}
@@ -426,7 +426,6 @@ export function Tgu2DMapView({
<circle r="6" /> <circle r="6" />
<line x1="-10" x2="10" y1="0" y2="0" /> <line x1="-10" x2="10" y1="0" y2="0" />
<line x1="0" x2="0" y1="-10" y2="10" /> <line x1="0" x2="0" y1="-10" y2="10" />
<text x="10" y="-8">{pickTarget.name}</text>
</g> </g>
); );
})()} })()}
@@ -77,11 +77,11 @@ export function TguToolbar({
<label className="tgu-field"> <label className="tgu-field">
<span>С</span> <span>С</span>
<input type="datetime-local" value={fromValue} onChange={(event) => onFromChange(event.target.value)} /> <input lang="ru-RU" type="datetime-local" value={fromValue} onChange={(event) => onFromChange(event.target.value)} />
</label> </label>
<label className="tgu-field"> <label className="tgu-field">
<span>По</span> <span>По</span>
<input type="datetime-local" value={toValue} onChange={(event) => onToChange(event.target.value)} /> <input lang="ru-RU" type="datetime-local" value={toValue} onChange={(event) => onToChange(event.target.value)} />
</label> </label>
<button className="tgu-button tgu-button--primary" type="button" onClick={onApply} disabled={loading}> <button className="tgu-button tgu-button--primary" type="button" onClick={onApply} disabled={loading}>
@@ -200,11 +200,11 @@ export function RequestCreatePanel({
</label> </label>
<label className="tgu-requests-field"> <label className="tgu-requests-field">
<span>Начало</span> <span>Начало</span>
<input type="datetime-local" value={begin} onChange={(e) => setBegin(e.target.value)} /> <input lang="ru-RU" type="datetime-local" value={begin} onChange={(e) => setBegin(e.target.value)} />
</label> </label>
<label className="tgu-requests-field"> <label className="tgu-requests-field">
<span>Конец</span> <span>Конец</span>
<input type="datetime-local" value={end} onChange={(e) => setEnd(e.target.value)} /> <input lang="ru-RU" type="datetime-local" value={end} onChange={(e) => setEnd(e.target.value)} />
</label> </label>
<label className="tgu-requests-field"> <label className="tgu-requests-field">
<span>КПП</span> <span>КПП</span>
@@ -289,6 +289,7 @@ export function TguRequestsTab({ range, invalidRange, platforms }: TguRequestsTa
<label className="tgu-field"> <label className="tgu-field">
<span>С</span> <span>С</span>
<input <input
lang="ru-RU"
type="datetime-local" type="datetime-local"
value={requestsState.fromValue} value={requestsState.fromValue}
onChange={(e) => setRequestsState((cur) => ({ ...cur, fromValue: e.target.value }))} onChange={(e) => setRequestsState((cur) => ({ ...cur, fromValue: e.target.value }))}
@@ -297,6 +298,7 @@ export function TguRequestsTab({ range, invalidRange, platforms }: TguRequestsTa
<label className="tgu-field"> <label className="tgu-field">
<span>По</span> <span>По</span>
<input <input
lang="ru-RU"
type="datetime-local" type="datetime-local"
value={requestsState.toValue} value={requestsState.toValue}
onChange={(e) => setRequestsState((cur) => ({ ...cur, toValue: e.target.value }))} onChange={(e) => setRequestsState((cur) => ({ ...cur, toValue: e.target.value }))}