onSelect has changed
This commit is contained in:
parent
bee361ed5d
commit
895c49ce68
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gantt-task-react",
|
"name": "gantt-task-react",
|
||||||
"version": "0.1.9",
|
"version": "0.2.0",
|
||||||
"description": "Interactive Gantt Chart for React with TypeScript.",
|
"description": "Interactive Gantt Chart for React with TypeScript.",
|
||||||
"author": "MaTeMaTuK <maksym.vikarii@gmail.com>",
|
"author": "MaTeMaTuK <maksym.vikarii@gmail.com>",
|
||||||
"homepage": "https://github.com/MaTeMaTuK/gantt-task-react",
|
"homepage": "https://github.com/MaTeMaTuK/gantt-task-react",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React from "react";
|
||||||
import { BarTask } from "../../types/bar-task";
|
import { BarTask } from "../../types/bar-task";
|
||||||
import {
|
import {
|
||||||
progressWithByParams,
|
progressWithByParams,
|
||||||
@ -16,10 +16,11 @@ export type BarProps = {
|
|||||||
isProgressChangeable: boolean;
|
isProgressChangeable: boolean;
|
||||||
isDateChangeable: boolean;
|
isDateChangeable: boolean;
|
||||||
isDelete: boolean;
|
isDelete: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
onEventStart: (
|
onEventStart: (
|
||||||
event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent,
|
|
||||||
action: GanttContentMoveAction,
|
action: GanttContentMoveAction,
|
||||||
selectedTask: BarTask
|
selectedTask: BarTask,
|
||||||
|
event?: React.MouseEvent | React.KeyboardEvent
|
||||||
) => any;
|
) => any;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,9 +31,8 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
isDateChangeable,
|
isDateChangeable,
|
||||||
onEventStart,
|
onEventStart,
|
||||||
isDelete,
|
isDelete,
|
||||||
|
isSelected,
|
||||||
}) => {
|
}) => {
|
||||||
const [isSelected, setIsSelected] = useState(false);
|
|
||||||
|
|
||||||
const progressWidth = progressWithByParams(task.x1, task.x2, task.progress);
|
const progressWidth = progressWithByParams(task.x1, task.x2, task.progress);
|
||||||
const progressPoint = getProgressPoint(
|
const progressPoint = getProgressPoint(
|
||||||
progressWidth + task.x1,
|
progressWidth + task.x1,
|
||||||
@ -47,28 +47,23 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
onKeyDown={e => {
|
onKeyDown={e => {
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case "Delete": {
|
case "Delete": {
|
||||||
if (isDelete) onEventStart(e, "delete", task);
|
if (isDelete) onEventStart("delete", task, e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
onMouseEnter={e => {
|
onMouseEnter={e => {
|
||||||
onEventStart(e, "mouseenter", task);
|
onEventStart("mouseenter", task, e);
|
||||||
}}
|
}}
|
||||||
onMouseLeave={e => {
|
onMouseLeave={e => {
|
||||||
onEventStart(e, "mouseleave", task);
|
onEventStart("mouseleave", task, e);
|
||||||
}}
|
}}
|
||||||
onDoubleClick={e => {
|
onDoubleClick={e => {
|
||||||
onEventStart(e, "dblclick", task);
|
onEventStart("dblclick", task, e);
|
||||||
}}
|
}}
|
||||||
onFocus={e => {
|
onFocus={() => {
|
||||||
setIsSelected(true);
|
onEventStart("select", task);
|
||||||
onEventStart(e, "select", task);
|
|
||||||
}}
|
|
||||||
onBlur={e => {
|
|
||||||
setIsSelected(false);
|
|
||||||
onEventStart(e, "unselect", task);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BarDisplay
|
<BarDisplay
|
||||||
@ -84,7 +79,7 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
styles={task.styles}
|
styles={task.styles}
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
isDateChangeable && onEventStart(e, "move", task);
|
isDateChangeable && onEventStart("move", task, e);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<g className="handleGroup">
|
<g className="handleGroup">
|
||||||
@ -98,7 +93,7 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
height={task.height - 2}
|
height={task.height - 2}
|
||||||
barCornerRadius={task.barCornerRadius}
|
barCornerRadius={task.barCornerRadius}
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
onEventStart(e, "start", task);
|
onEventStart("start", task, e);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/* right */}
|
{/* right */}
|
||||||
@ -109,7 +104,7 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
height={task.height - 2}
|
height={task.height - 2}
|
||||||
barCornerRadius={task.barCornerRadius}
|
barCornerRadius={task.barCornerRadius}
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
onEventStart(e, "end", task);
|
onEventStart("end", task, e);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
@ -118,7 +113,7 @@ export const Bar: React.FC<BarProps> = ({
|
|||||||
<BarProgressHandle
|
<BarProgressHandle
|
||||||
progressPoint={progressPoint}
|
progressPoint={progressPoint}
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
onEventStart(e, "progress", task);
|
onEventStart("progress", task, e);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
BarMoveAction,
|
BarMoveAction,
|
||||||
} from "../../helpers/bar-helper";
|
} from "../../helpers/bar-helper";
|
||||||
import { Tooltip } from "../other/tooltip";
|
import { Tooltip } from "../other/tooltip";
|
||||||
import { isKeyboardEvent, isMouseEvent } from "../../helpers/other-helper";
|
import { isKeyboardEvent } from "../../helpers/other-helper";
|
||||||
|
|
||||||
export type GanttContentMoveAction =
|
export type GanttContentMoveAction =
|
||||||
| "mouseenter"
|
| "mouseenter"
|
||||||
@ -17,10 +17,9 @@ export type GanttContentMoveAction =
|
|||||||
| "delete"
|
| "delete"
|
||||||
| "dblclick"
|
| "dblclick"
|
||||||
| "select"
|
| "select"
|
||||||
| "unselect"
|
|
||||||
| BarMoveAction;
|
| BarMoveAction;
|
||||||
export type BarEvent = {
|
export type BarEvent = {
|
||||||
selectedTask?: BarTask;
|
changedTask?: BarTask;
|
||||||
originalTask?: BarTask;
|
originalTask?: BarTask;
|
||||||
action: GanttContentMoveAction;
|
action: GanttContentMoveAction;
|
||||||
};
|
};
|
||||||
@ -83,6 +82,7 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
action: "",
|
action: "",
|
||||||
});
|
});
|
||||||
const [barTasks, setBarTasks] = useState<BarTask[]>([]);
|
const [barTasks, setBarTasks] = useState<BarTask[]>([]);
|
||||||
|
const [selectedTask, setSelectedTask] = useState<BarTask | null>(null);
|
||||||
const [failedTask, setFailedTask] = useState<BarTask | null>(null);
|
const [failedTask, setFailedTask] = useState<BarTask | null>(null);
|
||||||
const [xStep, setXStep] = useState(0);
|
const [xStep, setXStep] = useState(0);
|
||||||
const [initEventX1Delta, setInitEventX1Delta] = useState(0);
|
const [initEventX1Delta, setInitEventX1Delta] = useState(0);
|
||||||
@ -143,7 +143,7 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleMouseMove = async (event: MouseEvent) => {
|
const handleMouseMove = async (event: MouseEvent) => {
|
||||||
if (!barEvent.selectedTask || !point || !svg?.current) return;
|
if (!barEvent.changedTask || !point || !svg?.current) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
point.x = event.clientX;
|
point.x = event.clientX;
|
||||||
@ -154,7 +154,7 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
const { isChanged, changedTask } = handleTaskBySVGMouseEvent(
|
const { isChanged, changedTask } = handleTaskBySVGMouseEvent(
|
||||||
cursor.x,
|
cursor.x,
|
||||||
barEvent.action as BarMoveAction,
|
barEvent.action as BarMoveAction,
|
||||||
barEvent.selectedTask,
|
barEvent.changedTask,
|
||||||
xStep,
|
xStep,
|
||||||
timeStep,
|
timeStep,
|
||||||
initEventX1Delta
|
initEventX1Delta
|
||||||
@ -163,12 +163,12 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
setBarTasks(
|
setBarTasks(
|
||||||
barTasks.map(t => (t.id === changedTask.id ? changedTask : t))
|
barTasks.map(t => (t.id === changedTask.id ? changedTask : t))
|
||||||
);
|
);
|
||||||
setBarEvent({ ...barEvent, selectedTask: changedTask });
|
setBarEvent({ ...barEvent, changedTask: changedTask });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseUp = async (event: MouseEvent) => {
|
const handleMouseUp = async (event: MouseEvent) => {
|
||||||
const { selectedTask, action, originalTask } = barEvent;
|
const { changedTask: selectedTask, action, originalTask } = barEvent;
|
||||||
|
|
||||||
if (!selectedTask || !point || !svg?.current || !originalTask) return;
|
if (!selectedTask || !point || !svg?.current || !originalTask) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -262,44 +262,53 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
* Method is Start point of task change
|
* Method is Start point of task change
|
||||||
*/
|
*/
|
||||||
const handleBarEventStart = async (
|
const handleBarEventStart = async (
|
||||||
event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent,
|
|
||||||
action: GanttContentMoveAction,
|
action: GanttContentMoveAction,
|
||||||
selectedTask: BarTask
|
task: BarTask,
|
||||||
|
event?: React.MouseEvent | React.KeyboardEvent
|
||||||
) => {
|
) => {
|
||||||
|
if (!event) {
|
||||||
|
if (action === "select") {
|
||||||
|
if (selectedTask && onSelect) {
|
||||||
|
onSelect(selectedTask, false);
|
||||||
|
}
|
||||||
|
setSelectedTask(task);
|
||||||
|
if (onSelect) {
|
||||||
|
onSelect(task, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Keyboard events
|
// Keyboard events
|
||||||
if (isKeyboardEvent(event)) {
|
else if (isKeyboardEvent(event)) {
|
||||||
if (action === "delete") {
|
if (action === "delete") {
|
||||||
if (onTaskDelete) {
|
if (onTaskDelete) {
|
||||||
try {
|
try {
|
||||||
const result = await onTaskDelete(selectedTask);
|
const result = await onTaskDelete(task);
|
||||||
if (result !== undefined && result) {
|
if (result !== undefined && result) {
|
||||||
const newTasks = barTasks.filter(t => t.id !== selectedTask.id);
|
const newTasks = barTasks.filter(t => t.id !== task.id);
|
||||||
onTasksChange(newTasks);
|
onTasksChange(newTasks);
|
||||||
!!onSelect && onSelect(selectedTask, false);
|
!!onSelect && onSelect(task, false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error on Delete. " + error);
|
console.error("Error on Delete. " + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!isMouseEvent(event)) {
|
|
||||||
if (action === "select") {
|
|
||||||
!!onSelect && onSelect(selectedTask, true);
|
|
||||||
} else if (action === "unselect") {
|
|
||||||
!!onSelect && onSelect(selectedTask, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Mouse Events
|
// Mouse Events
|
||||||
else if (action === "mouseenter") {
|
else if (action === "mouseenter") {
|
||||||
if (!barEvent.action) {
|
if (!barEvent.action) {
|
||||||
setBarEvent({ action, selectedTask, originalTask: selectedTask });
|
setBarEvent({
|
||||||
|
action,
|
||||||
|
changedTask: task,
|
||||||
|
originalTask: task,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (action === "mouseleave") {
|
} else if (action === "mouseleave") {
|
||||||
if (barEvent.action === "mouseenter") {
|
if (barEvent.action === "mouseenter") {
|
||||||
setBarEvent({ action: "" });
|
setBarEvent({ action: "" });
|
||||||
}
|
}
|
||||||
} else if (action === "dblclick") {
|
} else if (action === "dblclick") {
|
||||||
!!onDoubleClick && onDoubleClick(selectedTask);
|
!!onDoubleClick && onDoubleClick(task);
|
||||||
}
|
}
|
||||||
// Change task event start
|
// Change task event start
|
||||||
else if (action === "move") {
|
else if (action === "move") {
|
||||||
@ -308,13 +317,17 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
const cursor = point.matrixTransform(
|
const cursor = point.matrixTransform(
|
||||||
svg.current.getScreenCTM()?.inverse()
|
svg.current.getScreenCTM()?.inverse()
|
||||||
);
|
);
|
||||||
setInitEventX1Delta(cursor.x - selectedTask.x1);
|
setInitEventX1Delta(cursor.x - task.x1);
|
||||||
setBarEvent({ action, selectedTask, originalTask: selectedTask });
|
setBarEvent({
|
||||||
|
action,
|
||||||
|
changedTask: task,
|
||||||
|
originalTask: task,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setBarEvent({
|
setBarEvent({
|
||||||
action,
|
action,
|
||||||
selectedTask,
|
changedTask: task,
|
||||||
originalTask: selectedTask,
|
originalTask: task,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -347,17 +360,18 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
|
|||||||
isDelete={!task.isDisabled}
|
isDelete={!task.isDisabled}
|
||||||
onEventStart={handleBarEventStart}
|
onEventStart={handleBarEventStart}
|
||||||
key={task.id}
|
key={task.id}
|
||||||
|
isSelected={task.id === selectedTask?.id}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</g>
|
</g>
|
||||||
<g className="toolTip">
|
<g className="toolTip">
|
||||||
{barEvent.selectedTask && (
|
{barEvent.changedTask && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
x={barEvent.selectedTask.x2 + arrowIndent + arrowIndent * 0.5}
|
x={barEvent.changedTask.x2 + arrowIndent + arrowIndent * 0.5}
|
||||||
rowHeight={rowHeight}
|
rowHeight={rowHeight}
|
||||||
svgHeight={svgHeight}
|
svgHeight={svgHeight}
|
||||||
task={barEvent.selectedTask}
|
task={barEvent.changedTask}
|
||||||
fontFamily={fontFamily}
|
fontFamily={fontFamily}
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
TooltipContent={TooltipContent}
|
TooltipContent={TooltipContent}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user