From c32819578b254d4caf1e839e0179f47a2d2e8814 Mon Sep 17 00:00:00 2001 From: theocrsb Date: Thu, 6 Mar 2025 11:50:38 +0100 Subject: [PATCH] front: insert div in manchette with space time chart Signed-off-by: theocrsb --- .../ManchetteSplit/ManchetteSplit.stories.tsx | 8 +--- .../ManchetteWithSpaceTimeChart.tsx | 18 ++++++--- .../src/helpers.ts | 5 +++ .../hooks/useManchetteWithSpaceTimeChart.ts | 37 ++++++++++++++++--- .../src/stories/simple.stories.tsx | 2 +- .../src/stories/split.stories.tsx | 34 +++++++++++++++++ .../src/components/PathLayer.tsx | 35 ++++++++++++++---- .../src/components/SpaceGraduations.tsx | 6 ++- .../src/components/SpaceTimeChart.tsx | 8 ++-- ui-spacetimechart/src/lib/types.ts | 19 ++++++++-- .../src/stories/additional-data.stories.tsx | 2 +- .../src/stories/base-rendering.stories.tsx | 2 +- .../src/stories/custom-styles.stories.tsx | 2 +- .../src/stories/horizontal-zoom.stories.tsx | 4 +- .../src/stories/layers.stories.tsx | 2 +- .../src/stories/measuring.stories.tsx | 2 +- .../src/stories/options.stories.tsx | 2 +- .../stories/paths-interactions.stories.tsx | 2 +- .../src/stories/performances.stories.tsx | 2 +- .../src/stories/scroll-navigation.stories.tsx | 2 +- .../src/stories/split.stories.tsx | 2 +- .../stories/stage-interactions.stories.tsx | 2 +- .../src/stories/work-schedules.stories.tsx | 34 ++++++++++++----- 23 files changed, 175 insertions(+), 57 deletions(-) create mode 100644 ui-manchette-with-spacetimechart/src/stories/split.stories.tsx diff --git a/storybook/stories/ManchetteSplit/ManchetteSplit.stories.tsx b/storybook/stories/ManchetteSplit/ManchetteSplit.stories.tsx index 194aa914a..9571061fa 100644 --- a/storybook/stories/ManchetteSplit/ManchetteSplit.stories.tsx +++ b/storybook/stories/ManchetteSplit/ManchetteSplit.stories.tsx @@ -2,9 +2,9 @@ import React from 'react'; import '@osrd-project/ui-core/dist/theme.css'; import '@osrd-project/ui-manchette/dist/theme.css'; +import Manchette from '@osrd-project/ui-manchette'; import type { Meta, StoryObj } from '@storybook/react'; -import Manchette from '@osrd-project/ui-manchette'; import { SAMPLE_WAYPOINTS } from '../../../ui-manchette/src/stories/assets/sampleData'; const meta: Meta = { @@ -17,11 +17,7 @@ const meta: Meta = { export default meta; type Story = StoryObj; -const customDiv = ( -
- Hello World -
-); +const customDiv =
; export const Default: Story = { args: { diff --git a/ui-manchette-with-spacetimechart/src/components/ManchetteWithSpaceTimeChart.tsx b/ui-manchette-with-spacetimechart/src/components/ManchetteWithSpaceTimeChart.tsx index 7a66c4b16..66888b1c6 100644 --- a/ui-manchette-with-spacetimechart/src/components/ManchetteWithSpaceTimeChart.tsx +++ b/ui-manchette-with-spacetimechart/src/components/ManchetteWithSpaceTimeChart.tsx @@ -4,17 +4,19 @@ import Manchette, { type ProjectPathTrainResult, type Waypoint, type ManchetteProps, + InteractiveWaypoint, } from '@osrd-project/ui-manchette'; import { PathLayer, SpaceTimeChart, + isInteractiveWaypoint, type SpaceTimeChartProps, } from '@osrd-project/ui-spacetimechart'; import useManchetteWithSpaceTimeChart from '../hooks/useManchetteWithSpaceTimeChart'; export type ManchetteWithSpaceTimeChartProps = { - waypoints: Waypoint[]; + contents: (InteractiveWaypoint | React.ReactNode)[]; projectPathTrainResult: ProjectPathTrainResult[]; selectedTrain?: number; height?: number; @@ -31,7 +33,7 @@ export type ManchetteWithSpaceTimeChartProps = { * and space time chart, the useManchetteWithSpaceTimeChart() hook can be used. */ const ManchetteWithSpaceTimeChart = ({ - waypoints, + contents, projectPathTrainResult, selectedTrain, height = 561, @@ -44,7 +46,7 @@ const ManchetteWithSpaceTimeChart = ({ const spaceTimeChartRef = useRef(null); const { manchetteProps, spaceTimeChartProps, handleScroll } = useManchetteWithSpaceTimeChart( - waypoints, + contents, projectPathTrainResult, manchetteWithSpaceTimeChartRef, selectedTrain, @@ -79,9 +81,13 @@ const ManchetteWithSpaceTimeChart = ({ {...spaceTimeChartProps} {...additionalSpaceTimeChartProps} > - {spaceTimeChartProps.paths.map((path) => ( - - ))} + {spaceTimeChartProps.paths.map((path, index) => + path.id ? ( + + ) : ( +
{'coucou'}
+ ) + )} {children}
diff --git a/ui-manchette-with-spacetimechart/src/helpers.ts b/ui-manchette-with-spacetimechart/src/helpers.ts index d2763fdd3..3fce2c200 100644 --- a/ui-manchette-with-spacetimechart/src/helpers.ts +++ b/ui-manchette-with-spacetimechart/src/helpers.ts @@ -41,6 +41,11 @@ export const filterVisibleElements = ( return displayedElements.sort((a, b) => a.position - b.position); }; +export const isInteractiveWaypoint = ( + item: InteractiveWaypoint | React.ReactNode +): item is InteractiveWaypoint => + item != null && typeof item === 'object' && 'id' in item && 'position' in item; + export const computeWaypointsToDisplay = ( waypoints: Waypoint[], { height, isProportional, yZoom }: WaypointsOptions diff --git a/ui-manchette-with-spacetimechart/src/hooks/useManchetteWithSpaceTimeChart.ts b/ui-manchette-with-spacetimechart/src/hooks/useManchetteWithSpaceTimeChart.ts index 0b3d17d84..35618ad39 100644 --- a/ui-manchette-with-spacetimechart/src/hooks/useManchetteWithSpaceTimeChart.ts +++ b/ui-manchette-with-spacetimechart/src/hooks/useManchetteWithSpaceTimeChart.ts @@ -1,6 +1,10 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import type { ProjectPathTrainResult, Waypoint } from '@osrd-project/ui-manchette'; +import type { + InteractiveWaypoint, + ProjectPathTrainResult, + Waypoint, +} from '@osrd-project/ui-manchette'; import type { SpaceScale, SpaceTimeChartProps } from '@osrd-project/ui-spacetimechart'; import usePaths from './usePaths'; @@ -11,6 +15,7 @@ import { zoomX, zoomValueToTimeScale, timeScaleToZoomValue, + isInteractiveWaypoint, } from '../helpers'; import { getDiff } from '../utils/point'; @@ -28,8 +33,17 @@ type State = { scales: SpaceScale[]; }; +type SimplifiedWaypoint = { + id: string; + label: string; + position: number; + importanceLevel: number; +}; + +type SimplifiedWaypoints = (SimplifiedWaypoint | React.ReactNode)[]; + const useManchettesWithSpaceTimeChart = ( - waypoints: Waypoint[], + contents: (InteractiveWaypoint | React.ReactNode)[], projectPathTrainResult: ProjectPathTrainResult[], manchetteWithSpaceTimeChartContainer: React.RefObject, selectedTrain?: number, @@ -48,6 +62,7 @@ const useManchettesWithSpaceTimeChart = ( waypointsChart: [], scales: [], }); + const waypoints = useMemo(() => contents.filter(isInteractiveWaypoint), [contents]); const { xZoom, yZoom, xOffset, yOffset, scrollTo, panning, isProportional } = state; @@ -149,9 +164,19 @@ const useManchettesWithSpaceTimeChart = ( [simplifiedWaypoints, height, isProportional, yZoom] ); + const contentsToDisplay = useMemo( + () => + contents.map((content) => + isInteractiveWaypoint(content) + ? waypointsToDisplay.find((wp) => wp.id === content.id) || content + : content + ), + [contents, waypointsToDisplay] + ); + const manchetteProps = useMemo( () => ({ - contents: waypointsToDisplay, + contents: contentsToDisplay, zoomYIn, zoomYOut, resetZoom, @@ -160,7 +185,7 @@ const useManchettesWithSpaceTimeChart = ( isProportional, yOffset, }), - [waypointsToDisplay, zoomYIn, zoomYOut, resetZoom, toggleMode, yZoom, isProportional, yOffset] + [contentsToDisplay, zoomYIn, zoomYOut, resetZoom, toggleMode, yZoom, isProportional, yOffset] ); const handleXZoom = useCallback( @@ -175,7 +200,7 @@ const useManchettesWithSpaceTimeChart = ( const spaceTimeChartProps = useMemo( () => ({ - operationalPoints: simplifiedWaypoints, + contents: simplifiedWaypoints, spaceScales: computedScales, timeScale: zoomValueToTimeScale(xZoom), paths, diff --git a/ui-manchette-with-spacetimechart/src/stories/simple.stories.tsx b/ui-manchette-with-spacetimechart/src/stories/simple.stories.tsx index e2a3a6c11..550e0249c 100644 --- a/ui-manchette-with-spacetimechart/src/stories/simple.stories.tsx +++ b/ui-manchette-with-spacetimechart/src/stories/simple.stories.tsx @@ -16,7 +16,7 @@ export default meta; export const Default = { args: { - waypoints: SAMPLE_WAYPOINTS, + contents: SAMPLE_WAYPOINTS, projectPathTrainResult: SAMPLE_PATHS_DATA, selectedTrain: 1, }, diff --git a/ui-manchette-with-spacetimechart/src/stories/split.stories.tsx b/ui-manchette-with-spacetimechart/src/stories/split.stories.tsx new file mode 100644 index 000000000..ce4bf0d18 --- /dev/null +++ b/ui-manchette-with-spacetimechart/src/stories/split.stories.tsx @@ -0,0 +1,34 @@ +import React from 'react'; + +import type { Meta } from '@storybook/react'; + +import '@osrd-project/ui-core/dist/theme.css'; +import '@osrd-project/ui-manchette/dist/theme.css'; +import '@osrd-project/ui-manchette-with-spacetimechart/dist/theme.css'; + +import { SAMPLE_WAYPOINTS, SAMPLE_PATHS_DATA } from '../assets/sampleData'; +import ManchetteWithSpaceTimeChart from '../components/ManchetteWithSpaceTimeChart'; + +const meta: Meta = { + title: 'Manchette with SpaceTimeChart/split', + component: ManchetteWithSpaceTimeChart, +}; + +const customDiv =
; + +const allWaypoints = SAMPLE_WAYPOINTS.map((waypoint, index) => { + if (index === 0 || index === 1 || index === 3) { + return [waypoint, customDiv]; + } + return waypoint; +}).flat(); + +export default meta; + +export const Default = { + args: { + contents: allWaypoints, + projectPathTrainResult: SAMPLE_PATHS_DATA, + selectedTrain: 1, + }, +}; diff --git a/ui-spacetimechart/src/components/PathLayer.tsx b/ui-spacetimechart/src/components/PathLayer.tsx index f562d0af3..6f831d22b 100644 --- a/ui-spacetimechart/src/components/PathLayer.tsx +++ b/ui-spacetimechart/src/components/PathLayer.tsx @@ -8,11 +8,12 @@ import { type DataPoint, DEFAULT_PATH_END, type DrawingFunction, - type OperationalPoint, type PathData, type PickingDrawingFunction, type Point, type SpaceTimeChartContextType, + InteractiveWaypoint, + OperationalPoint, } from '../lib/types'; import { drawAliasedDisc, @@ -68,6 +69,20 @@ export type PathLayerProps = { level?: PathLevel; }; +export const isInteractiveWaypoint = ( + item: InteractiveWaypoint | React.ReactNode +): item is InteractiveWaypoint | OperationalPoint => + item != null && typeof item === 'object' && 'id' in item && 'position' in item; + +export const isOp = ( + item: InteractiveWaypoint | React.ReactNode | OperationalPoint +): item is OperationalPoint => + item != null && + typeof item === 'object' && + 'id' in item && + 'position' in item && + 'importanceLevel' in item; + /** * This component handles drawing a Path inside a SpaceTimeChart. It renders: * - The path itself @@ -134,6 +149,7 @@ export const PathLayer = ({ }, [path] ); + /** * This function returns the list of important points, where the mouse can snap. */ @@ -143,10 +159,11 @@ export const PathLayer = ({ getSpacePixel, timeAxis, spaceAxis, - operationalPoints, + contents, }: SpaceTimeChartContextType): Point[] => { const res: Point[] = []; - const stopPositions = new Set(operationalPoints.map((p) => p.position)); + const waypoints = contents.filter(isInteractiveWaypoint); + const stopPositions = new Set(waypoints.map((p) => p.position)); path.points.forEach(({ position, time }) => { if (stopPositions.has(position)) res.push({ @@ -163,8 +180,9 @@ export const PathLayer = ({ * This function draws the stops of the path on the operational points. */ const drawPauses = useCallback( - (ctx, { getTimePixel, getSpacePixel, operationalPoints, swapAxis }) => { - const stopPositions = new Set(operationalPoints.map((p) => p.position)); + (ctx, { getTimePixel, getSpacePixel, contents, swapAxis }) => { + const waypoints = contents.filter(isInteractiveWaypoint); + const stopPositions = new Set(waypoints.map((p) => p.position)); path.points.forEach(({ position, time }, i, a) => { if (i) { const { position: prevPosition, time: prevTime } = a[i - 1]; @@ -309,11 +327,12 @@ export const PathLayer = ({ ); const computePathLength = useCallback( - (operationalPoints: OperationalPoint[], segments: Point[]) => { + (contents: (InteractiveWaypoint | React.ReactNode)[], segments: Point[]) => { let totalLength = 0; + const waypoints = contents.filter(isInteractiveWaypoint); // Compute length of pauses - const stopPositions = new Set(operationalPoints.map((p) => p.position)); + const stopPositions = new Set(waypoints.map((p) => p.position)); path.points.forEach(({ position, time }, i, pointsArray) => { if (i > 0) { const { position: prevPosition, time: prevTime } = pointsArray[i - 1]; @@ -371,7 +390,7 @@ export const PathLayer = ({ // Draw label: if (!stcContext.hidePathsLabels) { - const pathLength = computePathLength(stcContext.operationalPoints, segments); + const pathLength = computePathLength(stcContext.contents, segments); drawLabel(ctx, stcContext, path.label, color, segments, pathLength); } }, diff --git a/ui-spacetimechart/src/components/SpaceGraduations.tsx b/ui-spacetimechart/src/components/SpaceGraduations.tsx index 691af4f1b..87c6f336c 100644 --- a/ui-spacetimechart/src/components/SpaceGraduations.tsx +++ b/ui-spacetimechart/src/components/SpaceGraduations.tsx @@ -4,6 +4,7 @@ import { useDraw } from '../hooks/useCanvas'; import { type DrawingFunction } from '../lib/types'; import { getCrispLineCoordinate } from '../utils/canvas'; import { getSpacePixels } from '../utils/paths'; +import { isInteractiveWaypoint, isOp } from './PathLayer'; const SpaceGraduations = () => { const drawingFunction = useCallback( @@ -12,7 +13,7 @@ const SpaceGraduations = () => { { timePixelOffset, getSpacePixel, - operationalPoints, + contents, swapAxis, width, height, @@ -21,6 +22,9 @@ const SpaceGraduations = () => { ) => { const axisSize = !swapAxis ? width : height; + const waypoints = contents.filter(isInteractiveWaypoint); + const operationalPoints = waypoints.filter(isOp); + // Draw operational point lines: operationalPoints.forEach((point) => { const styles = spaceGraduationsStyles[point.importanceLevel || 0]; diff --git a/ui-spacetimechart/src/components/SpaceTimeChart.tsx b/ui-spacetimechart/src/components/SpaceTimeChart.tsx index 175222a54..bd92fe54e 100644 --- a/ui-spacetimechart/src/components/SpaceTimeChart.tsx +++ b/ui-spacetimechart/src/components/SpaceTimeChart.tsx @@ -31,7 +31,7 @@ import { snapPosition } from '../utils/snapping'; export const SpaceTimeChart = (props: SpaceTimeChartProps) => { const { - operationalPoints, + contents, spaceOrigin, spaceScales, timeOrigin, @@ -63,7 +63,7 @@ export const SpaceTimeChart = (props: SpaceTimeChartProps) => { const fingerprint = useMemo( () => JSON.stringify({ - operationalPoints, + contents, width, height, spaceOrigin, @@ -78,7 +78,7 @@ export const SpaceTimeChart = (props: SpaceTimeChartProps) => { showTicks, }), [ - operationalPoints, + contents, width, height, spaceOrigin, @@ -140,7 +140,7 @@ export const SpaceTimeChart = (props: SpaceTimeChartProps) => { pickingElements, resetPickingElements, registerPickingElement, - operationalPoints, + contents, spaceOrigin, spaceScaleTree, timeOrigin, diff --git a/ui-spacetimechart/src/lib/types.ts b/ui-spacetimechart/src/lib/types.ts index ed89d662c..45a43e0c1 100644 --- a/ui-spacetimechart/src/lib/types.ts +++ b/ui-spacetimechart/src/lib/types.ts @@ -1,4 +1,4 @@ -import { type HTMLProps, type ReactNode } from 'react'; +import { CSSProperties, type HTMLProps, type ReactNode } from 'react'; import type { Track, @@ -171,11 +171,24 @@ export type SpaceTimeChartTheme = { timeGraduationsStyles: Record; }; +export type Waypoint = { + id: string; + position: number; // in mm + name?: string; + secondaryCode?: string; + weight?: number; +}; + +export type InteractiveWaypoint = Waypoint & { + styles?: CSSProperties; + onClick?: (waypointId: string) => void; +}; + // CORE COMPONENT MAIN TYPES: export type SpaceTimeChartProps = { children?: ReactNode[]; - operationalPoints: OperationalPoint[]; + contents: (InteractiveWaypoint | React.ReactNode)[]; // The space origin (i.e. the space value for the most top point) spaceOrigin: number; @@ -273,7 +286,7 @@ export type SpaceTimeChartContextType = { getData: PointToData; // Useful data: - operationalPoints: OperationalPoint[]; + contents: (InteractiveWaypoint | React.ReactNode)[]; tracks?: Track[]; occupancyZones?: OccupancyZone[]; diff --git a/ui-spacetimechart/src/stories/additional-data.stories.tsx b/ui-spacetimechart/src/stories/additional-data.stories.tsx index f4a8053b5..44a0b1dad 100644 --- a/ui-spacetimechart/src/stories/additional-data.stories.tsx +++ b/ui-spacetimechart/src/stories/additional-data.stories.tsx @@ -191,7 +191,7 @@ const Wrapper = ({ swapAxis, spaceScaleType }: WrapperProps) => {
({ diff --git a/ui-spacetimechart/src/stories/base-rendering.stories.tsx b/ui-spacetimechart/src/stories/base-rendering.stories.tsx index fa722264b..a1ecd957a 100644 --- a/ui-spacetimechart/src/stories/base-rendering.stories.tsx +++ b/ui-spacetimechart/src/stories/base-rendering.stories.tsx @@ -53,7 +53,7 @@ const Wrapper = ({
{
({ from: point.position, diff --git a/ui-spacetimechart/src/stories/horizontal-zoom.stories.tsx b/ui-spacetimechart/src/stories/horizontal-zoom.stories.tsx index 4dd76e021..a79238356 100644 --- a/ui-spacetimechart/src/stories/horizontal-zoom.stories.tsx +++ b/ui-spacetimechart/src/stories/horizontal-zoom.stories.tsx @@ -23,7 +23,7 @@ const MAX_ZOOM_MS_PER_PX = 625; const DEFAULT_ZOOM_MS_PER_PX = 7500; type SpaceTimeHorizontalZoomWrapperProps = { offset: number; - operationalPoints: OperationalPoint[]; + contents: (InteractiveWaypoint | React.ReactNode)[]; paths: (PathData & { color: string })[]; }; @@ -86,7 +86,7 @@ const SpaceTimeHorizontalZoomWrapper = ({ xOffset={state.xOffset} yOffset={state.yOffset} timeOrigin={+new Date('2024/04/02')} - operationalPoints={simpleOperationalPoints} + contents={simpleOperationalPoints} timeScale={zoomValueToTimeScale(state.zoomValue)} spaceScales={spaceScale} onZoom={({ delta, position: { x } }) => { diff --git a/ui-spacetimechart/src/stories/layers.stories.tsx b/ui-spacetimechart/src/stories/layers.stories.tsx index 5888d9ebe..24a75ef53 100644 --- a/ui-spacetimechart/src/stories/layers.stories.tsx +++ b/ui-spacetimechart/src/stories/layers.stories.tsx @@ -110,7 +110,7 @@ const Wrapper = () => {
({ from: point.position, diff --git a/ui-spacetimechart/src/stories/measuring.stories.tsx b/ui-spacetimechart/src/stories/measuring.stories.tsx index c81141fef..2db546932 100644 --- a/ui-spacetimechart/src/stories/measuring.stories.tsx +++ b/ui-spacetimechart/src/stories/measuring.stories.tsx @@ -42,7 +42,7 @@ const Wrapper = ({ spaceScaleType, enableSnapping }: WrapperProps) => { ({ from: point.position, diff --git a/ui-spacetimechart/src/stories/options.stories.tsx b/ui-spacetimechart/src/stories/options.stories.tsx index a9d5eaebb..936cc3f33 100644 --- a/ui-spacetimechart/src/stories/options.stories.tsx +++ b/ui-spacetimechart/src/stories/options.stories.tsx @@ -83,7 +83,7 @@ const Wrapper = ({ hideGrid={hideGrid} hidePathsLabels={hidePathsLabels} swapAxis={swapAxis} - operationalPoints={OPERATIONAL_POINTS} + contents={OPERATIONAL_POINTS} spaceOrigin={0} spaceScales={OPERATIONAL_POINTS.slice(0, -1).map((point, i) => ({ from: point.position, diff --git a/ui-spacetimechart/src/stories/paths-interactions.stories.tsx b/ui-spacetimechart/src/stories/paths-interactions.stories.tsx index 2eb8ba09c..ceb9d5282 100644 --- a/ui-spacetimechart/src/stories/paths-interactions.stories.tsx +++ b/ui-spacetimechart/src/stories/paths-interactions.stories.tsx @@ -66,7 +66,7 @@ const Wrapper = ({ state.panTarget && 'cursor-grabbing', state.hoveredPathId && 'cursor-pointer' )} - operationalPoints={OPERATIONAL_POINTS} + contents={OPERATIONAL_POINTS} spaceOrigin={0} spaceScales={OPERATIONAL_POINTS.slice(0, -1).map((point, i) => ({ from: point.position, diff --git a/ui-spacetimechart/src/stories/performances.stories.tsx b/ui-spacetimechart/src/stories/performances.stories.tsx index 2d0a21611..29e3681f7 100644 --- a/ui-spacetimechart/src/stories/performances.stories.tsx +++ b/ui-spacetimechart/src/stories/performances.stories.tsx @@ -97,7 +97,7 @@ const Wrapper = ({
({ from: point.position, diff --git a/ui-spacetimechart/src/stories/scroll-navigation.stories.tsx b/ui-spacetimechart/src/stories/scroll-navigation.stories.tsx index 25a17d5b1..75cb05edb 100644 --- a/ui-spacetimechart/src/stories/scroll-navigation.stories.tsx +++ b/ui-spacetimechart/src/stories/scroll-navigation.stories.tsx @@ -54,7 +54,7 @@ const Wrapper = ({ spaceScaleType }: WrapperProps) => { state.panTarget && 'cursor-grabbing', state.hoveredPathId && 'cursor-pointer' )} - operationalPoints={OPERATIONAL_POINTS} + contents={OPERATIONAL_POINTS} spaceOrigin={0} spaceScales={OPERATIONAL_POINTS.slice(0, -1).map((point, i) => ({ from: point.position, diff --git a/ui-spacetimechart/src/stories/split.stories.tsx b/ui-spacetimechart/src/stories/split.stories.tsx index 4d01085bf..b4dfad891 100644 --- a/ui-spacetimechart/src/stories/split.stories.tsx +++ b/ui-spacetimechart/src/stories/split.stories.tsx @@ -114,7 +114,7 @@ const SplitSpaceTimeChartWrapper = ({ xOffset={state.xOffset} yOffset={state.yOffset} timeOrigin={+new Date('2024/04/02')} - operationalPoints={OPERATIONAL_POINTS} + contents={OPERATIONAL_POINTS} timeScale={100000 / state.xZoomLevel} spaceScales={spaceScales} onPan={({ initialPosition, position, isPanning }) => { diff --git a/ui-spacetimechart/src/stories/stage-interactions.stories.tsx b/ui-spacetimechart/src/stories/stage-interactions.stories.tsx index 0923103ee..ea2cb3c1e 100644 --- a/ui-spacetimechart/src/stories/stage-interactions.stories.tsx +++ b/ui-spacetimechart/src/stories/stage-interactions.stories.tsx @@ -46,7 +46,7 @@ const Wrapper = ({ xPan, yPan, xZoom, yZoom, spaceScaleType }: WrapperProps) =>
({ from: point.position, diff --git a/ui-spacetimechart/src/stories/work-schedules.stories.tsx b/ui-spacetimechart/src/stories/work-schedules.stories.tsx index 9b3e97517..fbd5a3c00 100644 --- a/ui-spacetimechart/src/stories/work-schedules.stories.tsx +++ b/ui-spacetimechart/src/stories/work-schedules.stories.tsx @@ -9,7 +9,12 @@ import upward from '../assets/images/ScheduledMaintenanceUp.svg'; import { PathLayer } from '../components/PathLayer'; import { SpaceTimeChart } from '../components/SpaceTimeChart'; import { WorkScheduleLayer } from '../components/WorkScheduleLayer'; -import { type Point, type PathData, type OperationalPoint } from '../lib/types'; +import { + type Point, + type PathData, + type OperationalPoint, + InteractiveWaypoint, +} from '../lib/types'; import { type WorkSchedule } from '../types'; import { getDiff } from '../utils/vectors'; @@ -43,13 +48,13 @@ const SAMPLE_WORK_SCHEDULES: WorkSchedule[] = [ const DEFAULT_HEIGHT = 550; type WorkSchedulesWrapperProps = { - operationalPoints: OperationalPoint[]; + contents: (InteractiveWaypoint | React.ReactNode)[]; paths: (PathData & { color: string })[]; workSchedules: WorkSchedule[]; }; const WorkSchedulesWrapper = ({ - operationalPoints = [], + contents = [], paths = [], workSchedules, }: WorkSchedulesWrapperProps) => { @@ -62,11 +67,22 @@ const WorkSchedulesWrapper = ({ yOffset: 0, panning: null, }); - const simpleOperationalPoints = operationalPoints.map(({ id, position }) => ({ - id, - label: id, - position, - })); + + const isInteractiveWaypoint = ( + item: InteractiveWaypoint | React.ReactNode + ): item is InteractiveWaypoint => + item != null && typeof item === 'object' && 'id' in item && 'position' in item; + + const simpleContents = contents.map((point) => + isInteractiveWaypoint(point) + ? { + id: point.id, + label: point.id, + position: point.position, + } + : point + ); + const spaceScale = [ { from: 0, @@ -82,7 +98,7 @@ const WorkSchedulesWrapper = ({ xOffset={state.xOffset} yOffset={state.yOffset} timeOrigin={+new Date('2024/04/02')} - operationalPoints={simpleOperationalPoints} + contents={simpleContents} timeScale={10000} spaceScales={spaceScale} onPan={({ initialPosition, position, isPanning }) => {