Skip to content

Commit

Permalink
Merge pull request #116 from melfore/develop
Browse files Browse the repository at this point in the history
[Timeline] Added initialDateTime prop to auto scroll
  • Loading branch information
luciob authored Oct 16, 2023
2 parents 66aea76 + 4500178 commit 20b4c9c
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 77 deletions.
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# [1.11.0](https://github.com/melfore/konva-timeline/compare/v1.10.0...v1.11.0) (2023-10-16)


### Features

* 🎸 [Task] Added flags for task operations ([7815a7c](https://github.com/melfore/konva-timeline/commit/7815a7c8aa37ab9974146f297f55920023db3676)), closes [#113](https://github.com/melfore/konva-timeline/issues/113)
* 🎸 [Task] Change callback onResizeEnd ([1fc102b](https://github.com/melfore/konva-timeline/commit/1fc102bec08fc7a0d9b95ffee70f38d2c81d2fec)), closes [#113](https://github.com/melfore/konva-timeline/issues/113)
- 🎸 [Task] Added flags for task operations ([7815a7c](https://github.com/melfore/konva-timeline/commit/7815a7c8aa37ab9974146f297f55920023db3676)), closes [#113](https://github.com/melfore/konva-timeline/issues/113)
- 🎸 [Task] Change callback onResizeEnd ([1fc102b](https://github.com/melfore/konva-timeline/commit/1fc102bec08fc7a0d9b95ffee70f38d2c81d2fec)), closes [#113](https://github.com/melfore/konva-timeline/issues/113)

# [1.10.0](https://github.com/melfore/konva-timeline/compare/v1.9.0...v1.10.0) (2023-10-16)

Expand Down
7 changes: 7 additions & 0 deletions src/KonvaTimeline/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ export const HiddenResources: Story = {
},
};

export const InitialDateTime: Story = {
args: {
...Primary.args,
initialDateTime: (range.start + range.end) / 2,
},
};

export const MixedDateTimeFormats: Story = {
args: {
...Primary.args,
Expand Down
10 changes: 4 additions & 6 deletions src/tasks/components/Task/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { findResourceByCoordinate, findResourceIndexByCoordinate } from "../../.
import { useTimelineContext } from "../../../timeline/TimelineContext";
import { KonvaDrawable, KonvaPoint } from "../../../utils/konva";
import { getContrastColor } from "../../../utils/theme";
import { getTaskYCoordinate, TaskData } from "../../utils/tasks";
import TaskResizeHandler from "../TaskResizeHandler";
import { getTaskYCoordinate, TASK_BORDER_RADIUS, TaskData } from "../../utils/tasks";
import TaskResizeHandle from "../TaskResizeHandle";

type TaskMouseEventHandler = (taskId: string, point: KonvaPoint) => void;

Expand Down Expand Up @@ -45,8 +45,6 @@ const TASK_DEFAULT_FILL = "#FFFFFF";
const TASK_DEFAULT_STROKE = "#000000";
const TASK_DEFAULT_STROKE_WIDTH = 1;

const TASK_BORDER_RADIUS = 4;

enableStrictMode(true);

/**
Expand Down Expand Up @@ -299,7 +297,7 @@ const Task = ({ data, fill = TASK_DEFAULT_FILL, onLeave, onOver, x, y, width }:
width={taskDimensions.width}
/>
{enableResize && (
<TaskResizeHandler
<TaskResizeHandle
height={taskHeight}
onResizeStart={onResizeStart}
onResizeMove={onResizeMove}
Expand All @@ -311,7 +309,7 @@ const Task = ({ data, fill = TASK_DEFAULT_FILL, onLeave, onOver, x, y, width }:
/>
)}
{enableResize && (
<TaskResizeHandler
<TaskResizeHandle
height={taskHeight}
onResizeStart={onResizeStart}
onResizeMove={onResizeMove}
Expand Down
84 changes: 84 additions & 0 deletions src/tasks/components/TaskResizeHandle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useCallback, useMemo } from "react";
import { Rect } from "react-konva";
import { KonvaEventObject } from "konva/lib/Node";

import { useTimelineContext } from "../../../timeline/TimelineContext";
import { TASK_BORDER_RADIUS } from "../../utils/tasks";

interface TaskResizeHandleProps {
height: number;
onResizeStart: (e: KonvaEventObject<DragEvent>) => void;
onResizeMove: (e: KonvaEventObject<DragEvent>, position: "lx" | "rx") => void;
onResizeEnd: (e: KonvaEventObject<DragEvent>) => void;
opacity: number;
position: "lx" | "rx";
taskId: string;
xCoordinate: number;
}

const TaskResizeHandle = ({
height,
onResizeEnd,
onResizeMove,
onResizeStart,
opacity,
position,
taskId,
xCoordinate,
}: TaskResizeHandleProps) => {
const { enableResize } = useTimelineContext();

const onDragMove = useCallback(
(e: KonvaEventObject<DragEvent>) => onResizeMove(e, position),
[onResizeMove, position]
);

const onMouseLeave = useCallback(
(e: KonvaEventObject<MouseEvent>) => {
e.cancelBubble = true;
const stage = e.target.getStage();
if (!stage || !enableResize) {
return;
}

stage.container().style.cursor = "default";
},
[enableResize]
);

const onMouseOver = useCallback(
(e: KonvaEventObject<MouseEvent>) => {
e.cancelBubble = true;
const stage = e.target.getStage();
if (!stage || !enableResize) {
return;
}

const mouseCursor = `${position === "lx" ? "w" : "e"}-resize`;
stage.container().style.cursor = mouseCursor;
},
[enableResize, position]
);

const handleId = useMemo(() => `${taskId}-resize-${position}`, [position, taskId]);

return (
<Rect
id={handleId}
draggable={enableResize}
fill="transparent"
height={height}
onDragStart={onResizeStart}
onDragMove={onDragMove}
onDragEnd={onResizeEnd}
onMouseOver={onMouseOver}
onMouseLeave={onMouseLeave}
opacity={opacity}
width={TASK_BORDER_RADIUS}
x={xCoordinate}
y={0}
/>
);
};

export default TaskResizeHandle;
65 changes: 0 additions & 65 deletions src/tasks/components/TaskResizeHandler/index.tsx

This file was deleted.

2 changes: 2 additions & 0 deletions src/tasks/utils/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type FilteredTasks = Operation<TaskData<InternalTimeRange>>;

const TASK_OFFSET_Y = 0.1;

export const TASK_BORDER_RADIUS = 4;

/**
* Gets task Y coordinate
* @param rowIndex the row index
Expand Down
19 changes: 16 additions & 3 deletions src/timeline/TimelineContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export type TimelineProviderProps = PropsWithChildren<TimelineInput> & {
* Enables resize operation on tasks
*/
enableResize?: boolean;
/**
* Initial date time to scroll to
*/
initialDateTime?: number | string;
/**
* Callback invoked when errors are thrown
*/
Expand Down Expand Up @@ -63,6 +67,7 @@ type TimelineContextType = Required<
drawRange: InternalTimeRange;
enableDrag: boolean;
enableResize: boolean;
initialDateTime?: number;
interval: Interval;
onErrors?: (errors: KonvaTimelineError[]) => void;
onTaskClick?: (task: TaskData) => void;
Expand Down Expand Up @@ -93,6 +98,7 @@ export const TimelineProvider = ({
enableDrag = true,
enableResize = true,
hideResources = false,
initialDateTime: externalInitialDateTime,
onErrors,
onTaskClick,
onTaskChange,
Expand All @@ -103,9 +109,6 @@ export const TimelineProvider = ({
rowHeight: externalRowHeight,
theme: externalTheme = "light",
}: TimelineProviderProps) => {
// logWarn("TimelineProvider", `Debug ${debug ? "ON" : "OFF"}`);
// window.__MELFORE_KONVA_TIMELINE_DEBUG__ = debug;

const [drawRange, setDrawRange] = useState(DEFAULT_DRAW_RANGE);

useEffect(() => {
Expand All @@ -121,6 +124,15 @@ export const TimelineProvider = ({
return { start, end };
}, [externalRange]);

const initialDateTime = useMemo(() => {
let initial = !externalInitialDateTime ? DateTime.now().toMillis() : getValidTime(externalInitialDateTime);
if (initial < range.start || initial > range.end) {
return;
}

return initial;
}, [externalInitialDateTime, range]);

const validTasks = useMemo(() => validateTasks(externalTasks, range), [externalTasks, range]);

const interval = useMemo(
Expand Down Expand Up @@ -235,6 +247,7 @@ export const TimelineProvider = ({
enableDrag,
enableResize,
hideResources,
initialDateTime,
interval,
onErrors,
onTaskClick,
Expand Down
14 changes: 14 additions & 0 deletions src/timeline/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { CSSProperties, FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Stage } from "react-konva";
import Konva from "konva";
import { DateTime } from "luxon";

import GridLayer from "../grid/Layer";
import ResourcesLayer from "../resources/components/Layer";
Expand All @@ -23,8 +24,11 @@ const DEFAULT_STAGE_SIZE: StageSize = { height: 0, width: 0 };
const Timeline: FC<TimelineProps> = () => {
const {
hideResources,
initialDateTime,
interval: { start: intervalStart },
columnWidth,
resourcesContentHeight,
resolution,
setDrawRange,
theme: { color: themeColor },
timeBlocks,
Expand Down Expand Up @@ -90,6 +94,16 @@ const Timeline: FC<TimelineProps> = () => {
onWindowResize();
}, [hideResources, onWindowResize]);

useEffect(() => {
if (!wrapper.current || !initialDateTime) {
return;
}

const timeStart = DateTime.fromMillis(initialDateTime);
const startOffsetInUnit = timeStart.diff(intervalStart!).as(resolution.unit);
wrapper.current.scrollTo({ left: (startOffsetInUnit * columnWidth) / resolution.sizeInUnits });
}, [columnWidth, initialDateTime, intervalStart, resolution.sizeInUnits, resolution.unit]);

const fullTimelineWidth = useMemo(() => columnWidth * timeBlocks.length, [columnWidth, timeBlocks]);

// const stageHeight = useMemo(() => size.height, [size]);
Expand Down

0 comments on commit 20b4c9c

Please sign in to comment.