onSelect has changed

This commit is contained in:
unknown 2020-09-15 00:10:58 +03:00
parent bee361ed5d
commit 895c49ce68
3 changed files with 58 additions and 49 deletions

View File

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

View File

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

View File

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