Internal state has added.
This commit is contained in:
parent
674974db9f
commit
1cde2c5c0b
@ -26,38 +26,6 @@ export const GanttTableExample: React.SFC<GanttTableExampleProps> = props => {
|
|||||||
options.columnWidth = 250;
|
options.columnWidth = 250;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [tasks, setTasks] = React.useState(props.tasks);
|
|
||||||
const onTaskDateChange = async (task: Task) => {
|
|
||||||
if (props.onDateChange) {
|
|
||||||
try {
|
|
||||||
await props.onDateChange(task);
|
|
||||||
} catch (e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
setTasks(tasks.map(t => (t.id === task.id ? task : t)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onTaskProgressChange = async (task: Task) => {
|
|
||||||
if (props.onProgressChange) {
|
|
||||||
try {
|
|
||||||
await props.onProgressChange(task);
|
|
||||||
} catch (e) {
|
|
||||||
setTasks(props.tasks.slice());
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTasks(tasks.map(t => (t.id === task.id ? task : t)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onTaskItemDelete = async (task: Task) => {
|
|
||||||
if (props.onTaskDelete) {
|
|
||||||
await props.onTaskDelete(task);
|
|
||||||
setTasks(tasks.filter(t => t.id !== task.id));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Wrapper">
|
<div className="Wrapper">
|
||||||
<div
|
<div
|
||||||
@ -107,7 +75,7 @@ export const GanttTableExample: React.SFC<GanttTableExampleProps> = props => {
|
|||||||
To
|
To
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{tasks.map(t => {
|
{props.tasks.map(t => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="GanttTable-row"
|
className="GanttTable-row"
|
||||||
@ -121,14 +89,7 @@ export const GanttTableExample: React.SFC<GanttTableExampleProps> = props => {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ overflowX: "scroll" }}>
|
<div style={{ overflowX: "scroll" }}>
|
||||||
<Gantt
|
<Gantt {...props} {...options} />
|
||||||
{...options}
|
|
||||||
{...props}
|
|
||||||
tasks={tasks}
|
|
||||||
onDateChange={onTaskDateChange}
|
|
||||||
onTaskDelete={onTaskItemDelete}
|
|
||||||
onProgressChange={onTaskProgressChange}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Task } from "../../types/public-types";
|
|
||||||
import { BarProgressHandle } from "./bar-progress-handle";
|
import { BarProgressHandle } from "./bar-progress-handle";
|
||||||
import { BarDateHandle } from "./bar-date-handle";
|
import { BarDateHandle } from "./bar-date-handle";
|
||||||
import { BarDisplay } from "./bar-display";
|
import { BarDisplay } from "./bar-display";
|
||||||
@ -14,7 +13,6 @@ import { GanttContentMoveAction } from "../Gantt/gantt-content";
|
|||||||
export type BarProps = {
|
export type BarProps = {
|
||||||
task: BarTask;
|
task: BarTask;
|
||||||
arrowIndent: number;
|
arrowIndent: number;
|
||||||
onDoubleClick?: (task: Task) => any;
|
|
||||||
isProgressChangeable: boolean;
|
isProgressChangeable: boolean;
|
||||||
isDateChangeable: boolean;
|
isDateChangeable: boolean;
|
||||||
isDelete: boolean;
|
isDelete: boolean;
|
||||||
@ -28,7 +26,6 @@ export type BarProps = {
|
|||||||
export const Bar: React.FC<BarProps> = ({
|
export const Bar: React.FC<BarProps> = ({
|
||||||
task,
|
task,
|
||||||
arrowIndent,
|
arrowIndent,
|
||||||
onDoubleClick,
|
|
||||||
isProgressChangeable,
|
isProgressChangeable,
|
||||||
isDateChangeable,
|
isDateChangeable,
|
||||||
onEventStart,
|
onEventStart,
|
||||||
@ -46,8 +43,8 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
return (
|
return (
|
||||||
<g
|
<g
|
||||||
className={styles.barWrapper}
|
className={styles.barWrapper}
|
||||||
onDoubleClick={() => {
|
onDoubleClick={e => {
|
||||||
!!onDoubleClick && onDoubleClick(task);
|
onEventStart(e, "dblclick", task);
|
||||||
}}
|
}}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onKeyDown={e => {
|
onKeyDown={e => {
|
||||||
|
|||||||
@ -15,6 +15,7 @@ export type GanttContentMoveAction =
|
|||||||
| "mouseenter"
|
| "mouseenter"
|
||||||
| "mouseleave"
|
| "mouseleave"
|
||||||
| "delete"
|
| "delete"
|
||||||
|
| "dblclick"
|
||||||
| BarMoveAction;
|
| BarMoveAction;
|
||||||
export type BarEvent = {
|
export type BarEvent = {
|
||||||
selectedTask?: BarTask;
|
selectedTask?: BarTask;
|
||||||
@ -44,14 +45,15 @@ export type GanttContentProps = {
|
|||||||
fontSize: string,
|
fontSize: string,
|
||||||
fontFamily: string
|
fontFamily: string
|
||||||
) => JSX.Element;
|
) => JSX.Element;
|
||||||
|
onTasksDateChange: (tasks: Task[]) => void;
|
||||||
} & EventOption;
|
} & EventOption;
|
||||||
|
|
||||||
export const GanttContent: React.FC<GanttContentProps> = ({
|
export const GanttContent: React.FC<GanttContentProps> = ({
|
||||||
tasks,
|
tasks,
|
||||||
|
dates,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
barCornerRadius,
|
barCornerRadius,
|
||||||
columnWidth,
|
columnWidth,
|
||||||
dates,
|
|
||||||
barFill,
|
barFill,
|
||||||
barProgressColor,
|
barProgressColor,
|
||||||
barProgressSelectedColor,
|
barProgressSelectedColor,
|
||||||
@ -59,12 +61,13 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
barBackgroundSelectedColor,
|
barBackgroundSelectedColor,
|
||||||
headerHeight,
|
headerHeight,
|
||||||
handleWidth,
|
handleWidth,
|
||||||
arrowColor,
|
|
||||||
timeStep,
|
timeStep,
|
||||||
|
svg,
|
||||||
|
arrowColor,
|
||||||
|
arrowIndent,
|
||||||
fontFamily,
|
fontFamily,
|
||||||
fontSize,
|
fontSize,
|
||||||
arrowIndent,
|
onTasksDateChange,
|
||||||
svg,
|
|
||||||
onDateChange,
|
onDateChange,
|
||||||
onProgressChange,
|
onProgressChange,
|
||||||
onDoubleClick,
|
onDoubleClick,
|
||||||
@ -79,6 +82,7 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
const [xStep, setXStep] = useState(0);
|
const [xStep, setXStep] = useState(0);
|
||||||
const [initEventX1Delta, setInitEventX1Delta] = useState(0);
|
const [initEventX1Delta, setInitEventX1Delta] = useState(0);
|
||||||
const [isMoving, setIsMoving] = useState(false);
|
const [isMoving, setIsMoving] = useState(false);
|
||||||
|
|
||||||
// create xStep
|
// create xStep
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const dateDelta =
|
const dateDelta =
|
||||||
@ -94,21 +98,13 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
|
|
||||||
// generate tasks
|
// generate tasks
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const dateDelta =
|
|
||||||
dates[1].getTime() -
|
|
||||||
dates[0].getTime() -
|
|
||||||
dates[1].getTimezoneOffset() * 60 * 1000 +
|
|
||||||
dates[0].getTimezoneOffset() * 60 * 1000;
|
|
||||||
const taskHeight = (rowHeight * barFill) / 100;
|
|
||||||
|
|
||||||
setBarTasks(
|
setBarTasks(
|
||||||
convertToBarTasks(
|
convertToBarTasks(
|
||||||
tasks,
|
tasks,
|
||||||
dates,
|
dates,
|
||||||
dateDelta,
|
|
||||||
columnWidth,
|
columnWidth,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
taskHeight,
|
barFill,
|
||||||
headerHeight,
|
headerHeight,
|
||||||
barCornerRadius,
|
barCornerRadius,
|
||||||
handleWidth,
|
handleWidth,
|
||||||
@ -136,14 +132,20 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
/**
|
/**
|
||||||
* Method is Start point of task change
|
* Method is Start point of task change
|
||||||
*/
|
*/
|
||||||
const handleBarEventStart = (
|
const handleBarEventStart = async (
|
||||||
event: React.MouseEvent | React.KeyboardEvent,
|
event: React.MouseEvent | React.KeyboardEvent,
|
||||||
action: GanttContentMoveAction,
|
action: GanttContentMoveAction,
|
||||||
selectedTask: BarTask
|
selectedTask: BarTask
|
||||||
) => {
|
) => {
|
||||||
if (isKeyboardEvent(event)) {
|
if (isKeyboardEvent(event)) {
|
||||||
if (action === "delete") {
|
if (action === "delete") {
|
||||||
setBarTasks(barTasks.filter(t => t.id !== barEvent.selectedTask?.id));
|
if (onTaskDelete) {
|
||||||
|
await onTaskDelete(selectedTask);
|
||||||
|
const newTasks = barTasks.filter(
|
||||||
|
t => t.id !== barEvent.selectedTask?.id
|
||||||
|
);
|
||||||
|
onTasksDateChange(newTasks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (action === "mouseenter") {
|
} else if (action === "mouseenter") {
|
||||||
if (!barEvent.action) {
|
if (!barEvent.action) {
|
||||||
@ -161,6 +163,8 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
);
|
);
|
||||||
setInitEventX1Delta(cursor.x - selectedTask.x1);
|
setInitEventX1Delta(cursor.x - selectedTask.x1);
|
||||||
setBarEvent({ action, selectedTask });
|
setBarEvent({ action, selectedTask });
|
||||||
|
} else if (action === "dblclick") {
|
||||||
|
!!onDoubleClick && onDoubleClick(selectedTask);
|
||||||
} else {
|
} else {
|
||||||
setBarEvent({
|
setBarEvent({
|
||||||
action,
|
action,
|
||||||
@ -217,9 +221,13 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
(action === "move" || action === "end" || action === "start") &&
|
(action === "move" || action === "end" || action === "start") &&
|
||||||
onDateChange
|
onDateChange
|
||||||
) {
|
) {
|
||||||
onDateChange(changedTask);
|
await onDateChange(changedTask);
|
||||||
|
const newTasks = barTasks.map(t =>
|
||||||
|
t.id === changedTask.id ? changedTask : t
|
||||||
|
);
|
||||||
|
onTasksDateChange(newTasks);
|
||||||
} else if (onProgressChange) {
|
} else if (onProgressChange) {
|
||||||
onProgressChange(changedTask);
|
await onProgressChange(changedTask);
|
||||||
}
|
}
|
||||||
svg.current.removeEventListener("mousemove", handleMouseMove);
|
svg.current.removeEventListener("mousemove", handleMouseMove);
|
||||||
svg.current.removeEventListener("mouseup", handleMouseUp);
|
svg.current.removeEventListener("mouseup", handleMouseUp);
|
||||||
@ -275,7 +283,6 @@ export const GanttContent: React.FC<GanttContentProps> = ({
|
|||||||
task={task}
|
task={task}
|
||||||
arrowIndent={arrowIndent}
|
arrowIndent={arrowIndent}
|
||||||
isProgressChangeable={!!onProgressChange && !task.isDisabled}
|
isProgressChangeable={!!onProgressChange && !task.isDisabled}
|
||||||
onDoubleClick={onDoubleClick}
|
|
||||||
isDateChangeable={!!onDateChange && !task.isDisabled}
|
isDateChangeable={!!onDateChange && !task.isDisabled}
|
||||||
isDelete={!!onTaskDelete && !task.isDisabled}
|
isDelete={!!onTaskDelete && !task.isDisabled}
|
||||||
onEventStart={handleBarEventStart}
|
onEventStart={handleBarEventStart}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useRef } from "react";
|
import React, { useRef, useState } from "react";
|
||||||
import { ViewMode, GanttProps } from "../../types/public-types";
|
import { ViewMode, GanttProps, Task } from "../../types/public-types";
|
||||||
import { Grid, GridProps } from "../Grid/grid";
|
import { Grid, GridProps } from "../Grid/grid";
|
||||||
import { Calendar, CalendarProps } from "../Calendar/calendar";
|
import { Calendar, CalendarProps } from "../Calendar/calendar";
|
||||||
import { GanttContent, GanttContentProps } from "./gantt-content";
|
import { GanttContent, GanttContentProps } from "./gantt-content";
|
||||||
@ -31,14 +31,19 @@ export const Gantt: React.SFC<GanttProps> = ({
|
|||||||
onTaskDelete,
|
onTaskDelete,
|
||||||
getTooltipContent,
|
getTooltipContent,
|
||||||
}) => {
|
}) => {
|
||||||
const [startDate, endDate] = ganttDateRange(tasks, viewMode);
|
|
||||||
const dates = seedDates(startDate, endDate, viewMode);
|
|
||||||
const svg = useRef<SVGSVGElement>(null);
|
const svg = useRef<SVGSVGElement>(null);
|
||||||
|
const [ganttTasks, setGanttTasks] = useState<Task[]>(tasks);
|
||||||
|
const [startDate, endDate] = ganttDateRange(ganttTasks, viewMode);
|
||||||
|
const dates = seedDates(startDate, endDate, viewMode);
|
||||||
|
|
||||||
|
const handleOnTasksChange = (tasks: Task[]) => {
|
||||||
|
setGanttTasks(tasks);
|
||||||
|
};
|
||||||
|
|
||||||
const gridProps: GridProps = {
|
const gridProps: GridProps = {
|
||||||
columnWidth,
|
columnWidth,
|
||||||
gridWidth: dates.length * columnWidth,
|
gridWidth: dates.length * columnWidth,
|
||||||
tasks,
|
tasks: ganttTasks,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
headerHeight,
|
headerHeight,
|
||||||
dates,
|
dates,
|
||||||
@ -54,7 +59,7 @@ export const Gantt: React.SFC<GanttProps> = ({
|
|||||||
fontSize,
|
fontSize,
|
||||||
};
|
};
|
||||||
const barProps: GanttContentProps = {
|
const barProps: GanttContentProps = {
|
||||||
tasks,
|
tasks: ganttTasks,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
barCornerRadius,
|
barCornerRadius,
|
||||||
columnWidth,
|
columnWidth,
|
||||||
@ -66,12 +71,13 @@ export const Gantt: React.SFC<GanttProps> = ({
|
|||||||
barBackgroundSelectedColor,
|
barBackgroundSelectedColor,
|
||||||
headerHeight,
|
headerHeight,
|
||||||
handleWidth,
|
handleWidth,
|
||||||
timeStep,
|
|
||||||
arrowColor,
|
arrowColor,
|
||||||
|
timeStep,
|
||||||
fontFamily,
|
fontFamily,
|
||||||
fontSize,
|
fontSize,
|
||||||
arrowIndent,
|
arrowIndent,
|
||||||
svg,
|
svg,
|
||||||
|
onTasksDateChange: handleOnTasksChange,
|
||||||
onDateChange,
|
onDateChange,
|
||||||
onProgressChange,
|
onProgressChange,
|
||||||
onDoubleClick,
|
onDoubleClick,
|
||||||
|
|||||||
@ -4,10 +4,9 @@ import { BarTask } from "../types/bar-task";
|
|||||||
export const convertToBarTasks = (
|
export const convertToBarTasks = (
|
||||||
tasks: Task[],
|
tasks: Task[],
|
||||||
dates: Date[],
|
dates: Date[],
|
||||||
dateDelta: number,
|
|
||||||
columnWidth: number,
|
columnWidth: number,
|
||||||
rowHeight: number,
|
rowHeight: number,
|
||||||
taskHeight: number,
|
barFill: number,
|
||||||
headerHeight: number,
|
headerHeight: number,
|
||||||
barCornerRadius: number,
|
barCornerRadius: number,
|
||||||
handleWidth: number,
|
handleWidth: number,
|
||||||
@ -16,6 +15,13 @@ export const convertToBarTasks = (
|
|||||||
barBackgroundColor: string,
|
barBackgroundColor: string,
|
||||||
barBackgroundSelectedColor: string
|
barBackgroundSelectedColor: string
|
||||||
) => {
|
) => {
|
||||||
|
const dateDelta =
|
||||||
|
dates[1].getTime() -
|
||||||
|
dates[0].getTime() -
|
||||||
|
dates[1].getTimezoneOffset() * 60 * 1000 +
|
||||||
|
dates[0].getTimezoneOffset() * 60 * 1000;
|
||||||
|
const taskHeight = (rowHeight * barFill) / 100;
|
||||||
|
|
||||||
let barTasks = tasks.map((t, i) => {
|
let barTasks = tasks.map((t, i) => {
|
||||||
return convertToBarTask(
|
return convertToBarTask(
|
||||||
t,
|
t,
|
||||||
@ -35,6 +41,7 @@ export const convertToBarTasks = (
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// set dependencies
|
||||||
barTasks = barTasks.map((task, i) => {
|
barTasks = barTasks.map((task, i) => {
|
||||||
const dependencies = task.dependencies || [];
|
const dependencies = task.dependencies || [];
|
||||||
for (let j = 0; j < dependencies.length; j++) {
|
for (let j = 0; j < dependencies.length; j++) {
|
||||||
|
|||||||
@ -1,5 +1,12 @@
|
|||||||
|
import { BarTask } from "../types/bar-task";
|
||||||
|
import { Task } from "../types/public-types";
|
||||||
|
|
||||||
export function isKeyboardEvent(
|
export function isKeyboardEvent(
|
||||||
event: React.MouseEvent | React.KeyboardEvent
|
event: React.MouseEvent | React.KeyboardEvent
|
||||||
): event is React.KeyboardEvent {
|
): event is React.KeyboardEvent {
|
||||||
return (event as React.KeyboardEvent).key !== undefined;
|
return (event as React.KeyboardEvent).key !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isBarTask(task: Task | BarTask): task is BarTask {
|
||||||
|
return (task as BarTask).x1 !== undefined;
|
||||||
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export interface EventOption {
|
|||||||
* Time step value for date changes.
|
* Time step value for date changes.
|
||||||
*/
|
*/
|
||||||
timeStep?: number;
|
timeStep?: number;
|
||||||
onDoubleClick?: (task: Task) => any;
|
onDoubleClick?: (task: Task) => void;
|
||||||
onDateChange?: (task: Task) => void | Promise<any>;
|
onDateChange?: (task: Task) => void | Promise<any>;
|
||||||
onProgressChange?: (task: Task) => void | Promise<any>;
|
onProgressChange?: (task: Task) => void | Promise<any>;
|
||||||
onTaskDelete?: (task: Task) => void | Promise<any>;
|
onTaskDelete?: (task: Task) => void | Promise<any>;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user