Skip to content

Commit f6a6510

Browse files
committed
front: resizable section and GET
Signed-off-by: Egor Berezovskiy <[email protected]>
1 parent e1bb669 commit f6a6510

File tree

7 files changed

+181
-54
lines changed

7 files changed

+181
-54
lines changed

front/src/applications/operationalStudies/views/SimulationResults.tsx

+54-36
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { useTranslation } from 'react-i18next';
77
import type { SimulationResultsData } from 'applications/operationalStudies/types';
88
import type { Conflict } from 'common/api/osrdEditoastApi';
99
import SimulationWarpedMap from 'common/Map/WarpedMap/SimulationWarpedMap';
10-
import ManchetteWithSpaceTimeChartWrapper from 'modules/simulationResult/components/ManchetteWithSpaceTimeChart/ManchetteWithSpaceTimeChart';
10+
import ResizableSection from 'common/ResizableSection';
11+
import ManchetteWithSpaceTimeChartWrapper, {
12+
MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT,
13+
} from 'modules/simulationResult/components/ManchetteWithSpaceTimeChart/ManchetteWithSpaceTimeChart';
1114
import SimulationResultsMap from 'modules/simulationResult/components/SimulationResultsMap/SimulationResultsMap';
1215
import useGetProjectedTrainOperationalPoints from 'modules/simulationResult/components/SpaceTimeChart/useGetProjectedTrainOperationalPoints';
1316
import useProjectedConflicts from 'modules/simulationResult/components/SpaceTimeChart/useProjectedConflicts';
@@ -24,6 +27,7 @@ import { getPointCoordinates } from 'utils/geometry';
2427

2528
const SPEED_SPACE_CHART_HEIGHT = 521.5;
2629
const HANDLE_TAB_RESIZE_HEIGHT = 20;
30+
const MANCHETTE_HEIGHT_DIFF = 76;
2731

2832
type SimulationResultsProps = {
2933
scenarioData: { name: string; infraName: string };
@@ -55,6 +59,10 @@ const SimulationResults = ({
5559
const [extViewport, setExtViewport] = useState<Viewport>();
5660
const [showWarpedMap, setShowWarpedMap] = useState(false);
5761

62+
const [manchetteWithSpaceTimeChartHeight, setManchetteWithSpaceTimeChartHeight] = useState(
63+
MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT
64+
);
65+
5866
const [speedSpaceChartContainerHeight, setSpeedSpaceChartContainerHeight] =
5967
useState(SPEED_SPACE_CHART_HEIGHT);
6068
const [mapCanvas, setMapCanvas] = useState<string>();
@@ -129,43 +137,53 @@ const SimulationResults = ({
129137
</div>
130138
)}
131139

132-
{/* SIMULATION : SPACE TIME CHART */}
133-
<div className="simulation-warped-map d-flex flex-row align-items-stretch mb-2">
134-
{projectionData && projectionData.projectedTrains.length > 0 && pathProperties && (
135-
<>
136-
<button
137-
type="button"
138-
className="show-warped-map-button my-3 ml-3 mr-1"
139-
aria-label={t('toggleWarpedMap')}
140-
title={t('toggleWarpedMap')}
141-
onClick={() => setShowWarpedMap(!showWarpedMap)}
142-
>
143-
{showWarpedMap ? <ChevronLeft /> : <ChevronRight />}
144-
</button>
145-
<SimulationWarpedMap
146-
collapsed={!showWarpedMap}
147-
pathGeometry={projectionData.geometry}
148-
/>
140+
<ResizableSection
141+
height={manchetteWithSpaceTimeChartHeight}
142+
setHeight={setManchetteWithSpaceTimeChartHeight}
143+
minHeight={MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT}
144+
>
145+
{/* SIMULATION : SPACE TIME CHART */}
146+
<div
147+
className="simulation-warped-map d-flex flex-row align-items-stretch mb-2"
148+
style={{ height: manchetteWithSpaceTimeChartHeight }}
149+
>
150+
{projectionData && projectionData.projectedTrains.length > 0 && pathProperties && (
151+
<>
152+
<button
153+
type="button"
154+
className="show-warped-map-button my-3 ml-3 mr-1"
155+
aria-label={t('toggleWarpedMap')}
156+
title={t('toggleWarpedMap')}
157+
onClick={() => setShowWarpedMap(!showWarpedMap)}
158+
>
159+
{showWarpedMap ? <ChevronLeft /> : <ChevronRight />}
160+
</button>
161+
<SimulationWarpedMap
162+
collapsed={!showWarpedMap}
163+
pathGeometry={projectionData.geometry}
164+
/>
149165

150-
<div className="osrd-simulation-container d-flex flex-grow-1 flex-shrink-1">
151-
<div className="chart-container">
152-
<ManchetteWithSpaceTimeChartWrapper
153-
operationalPoints={projectedOperationalPoints}
154-
projectPathTrainResult={projectionData?.projectedTrains}
155-
selectedTrainScheduleId={selectedTrainSchedule?.id}
156-
waypointsPanelData={{
157-
filteredWaypoints: filteredOperationalPoints,
158-
setFilteredWaypoints: setFilteredOperationalPoints,
159-
projectionPath: projectionData.trainSchedule.path,
160-
}}
161-
conflicts={conflictZones}
162-
projectionLoaderData={projectionData.projectionLoaderData}
163-
/>
166+
<div className="osrd-simulation-container d-flex flex-grow-1 flex-shrink-1">
167+
<div className="chart-container">
168+
<ManchetteWithSpaceTimeChartWrapper
169+
operationalPoints={projectedOperationalPoints}
170+
projectPathTrainResult={projectionData?.projectedTrains}
171+
selectedTrainScheduleId={selectedTrainSchedule?.id}
172+
waypointsPanelData={{
173+
filteredWaypoints: filteredOperationalPoints,
174+
setFilteredWaypoints: setFilteredOperationalPoints,
175+
projectionPath: projectionData.trainSchedule.path,
176+
}}
177+
conflicts={conflictZones}
178+
projectionLoaderData={projectionData.projectionLoaderData}
179+
height={manchetteWithSpaceTimeChartHeight - MANCHETTE_HEIGHT_DIFF}
180+
/>
181+
</div>
164182
</div>
165-
</div>
166-
</>
167-
)}
168-
</div>
183+
</>
184+
)}
185+
</div>
186+
</ResizableSection>
169187

170188
{/* TRAIN : SPACE SPEED CHART */}
171189
{selectedTrainRollingStock && trainSimulation && pathProperties && selectedTrainSchedule && (

front/src/applications/stdcm/components/StdcmResults/StdcmDebugResults.tsx

+32-12
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ import useProjectedTrainsForStdcm from 'applications/stdcm/hooks/useProjectedTra
77
import type { StdcmResultsOutput } from 'applications/stdcm/types';
88
import { osrdEditoastApi, type TrackRange } from 'common/api/osrdEditoastApi';
99
import { useOsrdConfSelectors } from 'common/osrdContext';
10+
import ResizableSection from 'common/ResizableSection';
1011
import i18n from 'i18n';
11-
import ManchetteWithSpaceTimeChartWrapper from 'modules/simulationResult/components/ManchetteWithSpaceTimeChart/ManchetteWithSpaceTimeChart';
12+
import ManchetteWithSpaceTimeChartWrapper, {
13+
MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT,
14+
} from 'modules/simulationResult/components/ManchetteWithSpaceTimeChart/ManchetteWithSpaceTimeChart';
1215
import SpeedSpaceChartContainer from 'modules/simulationResult/components/SpeedSpaceChart/SpeedSpaceChartContainer';
1316
import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors';
1417

1518
const SPEED_SPACE_CHART_HEIGHT = 521.5;
1619
const HANDLE_TAB_RESIZE_HEIGHT = 20;
20+
const MANCHETTE_HEIGHT_DIFF = 100;
1721

1822
type StdcmDebugResultsProps = {
1923
pathTrackRanges: TrackRange[];
@@ -31,6 +35,10 @@ const StdcmDebugResults = ({
3135
useState(SPEED_SPACE_CHART_HEIGHT);
3236
const tWithoutPrefix = i18n.getFixedT(null, 'stdcm');
3337

38+
const [manchetteWithSpaceTimeChartHeight, setManchetteWithSpaceTimeChartHeight] = useState(
39+
MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT
40+
);
41+
3442
const projectedData = useProjectedTrainsForStdcm(results);
3543

3644
const { data: workSchedules } = osrdEditoastApi.endpoints.postWorkSchedulesProjectPath.useQuery(
@@ -46,18 +54,30 @@ const StdcmDebugResults = ({
4654
return (
4755
<>
4856
{projectedData && pathProperties.manchetteOperationalPoints && (
49-
<div className="osrd-simulation-container mb-2">
50-
<p className="mt-2 mb-3 ml-4 font-weight-bold">{tWithoutPrefix('spaceTimeGraphic')}</p>
51-
<div className="chart-container mt-2">
52-
<ManchetteWithSpaceTimeChartWrapper
53-
operationalPoints={pathProperties.manchetteOperationalPoints}
54-
projectPathTrainResult={projectedData.spaceTimeData}
55-
selectedTrainScheduleId={STDCM_TRAIN_ID}
56-
workSchedules={workSchedules}
57-
projectionLoaderData={projectedData.projectionLoaderData}
58-
/>
57+
<ResizableSection
58+
height={manchetteWithSpaceTimeChartHeight}
59+
setHeight={setManchetteWithSpaceTimeChartHeight}
60+
minHeight={MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT}
61+
>
62+
<div
63+
className="osrd-simulation-container mb-2"
64+
style={{
65+
height: manchetteWithSpaceTimeChartHeight,
66+
}}
67+
>
68+
<p className="mt-2 mb-3 ml-4 font-weight-bold">{tWithoutPrefix('spaceTimeGraphic')}</p>
69+
<div className="chart-container mt-2">
70+
<ManchetteWithSpaceTimeChartWrapper
71+
operationalPoints={pathProperties.manchetteOperationalPoints}
72+
projectPathTrainResult={projectedData.spaceTimeData}
73+
selectedTrainScheduleId={STDCM_TRAIN_ID}
74+
workSchedules={workSchedules}
75+
projectionLoaderData={projectedData.projectionLoaderData}
76+
height={manchetteWithSpaceTimeChartHeight - MANCHETTE_HEIGHT_DIFF}
77+
/>
78+
</div>
5979
</div>
60-
</div>
80+
</ResizableSection>
6181
)}
6282

6383
<div className="osrd-simulation-container my-2 speedspacechart-container">

front/src/common/ResizableSection.tsx

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { useState, type PropsWithChildren } from 'react';
2+
3+
import { Rnd } from 'react-rnd';
4+
5+
const ResizableSection = ({
6+
minHeight,
7+
height,
8+
setHeight,
9+
children,
10+
}: PropsWithChildren<{
11+
minHeight?: number;
12+
height: number;
13+
setHeight?: React.Dispatch<React.SetStateAction<number>>;
14+
}>) => {
15+
const [baseHeight, setBaseHeight] = useState(height);
16+
const [sectionHeight, setSectionHeight] = useState(baseHeight);
17+
18+
return (
19+
<div className="resizable-section" style={{ height: sectionHeight }}>
20+
<Rnd
21+
default={{
22+
x: 0,
23+
y: 0,
24+
width: '100%',
25+
height: sectionHeight,
26+
}}
27+
size={{
28+
width: '100%',
29+
height: sectionHeight,
30+
}}
31+
minHeight={minHeight}
32+
disableDragging
33+
enableResizing={{
34+
top: false,
35+
topLeft: false,
36+
topRight: false,
37+
bottomLeft: false,
38+
bottomRight: false,
39+
bottom: true,
40+
left: false,
41+
right: false,
42+
}}
43+
resizeHandleClasses={{
44+
bottom: 'resizable-section-handle',
45+
}}
46+
onResizeStart={() => {
47+
setBaseHeight(sectionHeight);
48+
}}
49+
onResize={(_e, _dir, _refToElement, delta) => {
50+
setSectionHeight(baseHeight + delta.height);
51+
setHeight?.(baseHeight + delta.height);
52+
}}
53+
>
54+
{children}
55+
</Rnd>
56+
</div>
57+
);
58+
};
59+
60+
export default ResizableSection;

front/src/modules/simulationResult/components/ManchetteWithSpaceTimeChart/ManchetteWithSpaceTimeChart.tsx

+10-6
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ type ManchetteWithSpaceTimeChartProps = {
4040
totalTrains: number;
4141
allTrainsProjected: boolean;
4242
};
43+
height?: number;
4344
};
44-
const DEFAULT_HEIGHT = 561;
45+
46+
export const MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT = 561;
4547

4648
const ManchetteWithSpaceTimeChartWrapper = ({
4749
operationalPoints,
@@ -51,8 +53,8 @@ const ManchetteWithSpaceTimeChartWrapper = ({
5153
conflicts = [],
5254
workSchedules,
5355
projectionLoaderData: { totalTrains, allTrainsProjected },
56+
height = MANCHETTE_WITH_SPACE_TIME_CHART_DEFAULT_HEIGHT,
5457
}: ManchetteWithSpaceTimeChartProps) => {
55-
const [heightOfManchetteWithSpaceTimeChart] = useState(DEFAULT_HEIGHT);
5658
const manchetteWithSpaceTimeChartRef = useRef<HTMLDivElement>(null);
5759

5860
const [waypointsPanelIsOpen, setWaypointsPanelIsOpen] = useState(false);
@@ -154,7 +156,8 @@ const ManchetteWithSpaceTimeChartWrapper = ({
154156
manchetteWaypoints,
155157
cutProjectedTrains,
156158
manchetteWithSpaceTimeChartRef,
157-
selectedTrainScheduleId
159+
selectedTrainScheduleId,
160+
height
158161
);
159162

160163
const [showSettingsPanel, setShowSettingsPanel] = useState(false);
@@ -202,17 +205,17 @@ const ManchetteWithSpaceTimeChartWrapper = ({
202205
<div
203206
ref={manchetteWithSpaceTimeChartRef}
204207
className="manchette flex"
205-
style={{ height: `${heightOfManchetteWithSpaceTimeChart}px` }}
208+
style={{ height }}
206209
onScroll={handleScroll}
207210
>
208-
<Manchette {...manchetteProps} />
211+
<Manchette {...manchetteProps} height={height} />
209212
<div
210213
className="space-time-chart-container"
211214
style={{
212215
bottom: 0,
213216
left: 0,
214217
top: 2,
215-
height: `${heightOfManchetteWithSpaceTimeChart - 6}px`,
218+
height: height - 6,
216219
}}
217220
>
218221
<div className="toolbar">
@@ -229,6 +232,7 @@ const ManchetteWithSpaceTimeChartWrapper = ({
229232
)}
230233
<SpaceTimeChart
231234
className="inset-0 absolute h-full"
235+
height={height}
232236
spaceOrigin={
233237
(waypointsPanelData?.filteredWaypoints ?? operationalPoints).at(0)?.position || 0
234238
}

front/src/modules/simulationResult/components/SpeedSpaceChart/SpeedSpaceChartContainer.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ const SpeedSpaceChartContainer = ({
9191
disableDragging
9292
enableResizing={{
9393
bottom: true,
94+
top: false,
95+
topLeft: false,
96+
topRight: false,
97+
left: false,
98+
right: false,
9499
}}
95100
onResizeStart={() => {
96101
setBaseHeightOfSpeedSpaceChart(heightOfSpeedSpaceChart);

front/src/styles/scss/common/_components.scss

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
@import 'components/selector';
99
@import 'components/stationCard';
1010
@import 'components/tabs';
11+
@import 'components/resizableSection';
1112
@import 'components/tipped';
1213
@import 'components/typeAndPath';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.resizable-section-handle {
2+
position: relative;
3+
display: flex;
4+
justify-content: center;
5+
align-items: center;
6+
7+
&::after {
8+
content: "";
9+
width: 72px;
10+
height: 4px;
11+
border-radius: 2px;
12+
margin-bottom: 6px;
13+
background-color: var(--coolgray3);
14+
15+
}
16+
&:hover::after {
17+
background-color: var(--coolgray9);
18+
}
19+
}

0 commit comments

Comments
 (0)