Internal state has added.

This commit is contained in:
unknown 2020-08-11 01:16:53 +03:00
parent 674974db9f
commit 1cde2c5c0b
7 changed files with 59 additions and 74 deletions

View File

@ -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>
);

View File

@ -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 => {

View File

@ -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}

View File

@ -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,

View File

@ -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++) {

View File

@ -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;
}

View File

@ -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>;