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