diff --git a/packages/core/client/src/schema-component/antd/gantt/components/gantt/task-gantt-content.tsx b/packages/core/client/src/schema-component/antd/gantt/components/gantt/task-gantt-content.tsx
index 0b07d03029..4e5b56e59d 100644
--- a/packages/core/client/src/schema-component/antd/gantt/components/gantt/task-gantt-content.tsx
+++ b/packages/core/client/src/schema-component/antd/gantt/components/gantt/task-gantt-content.tsx
@@ -1,16 +1,14 @@
-import React, { useEffect, useState } from "react";
-import { EventOption } from "../../types/public-types";
-import { BarTask } from "../../types/bar-task";
-import { Arrow } from "../other/arrow";
-import { handleTaskBySVGMouseEvent } from "../../helpers/bar-helper";
-import { isKeyboardEvent } from "../../helpers/other-helper";
-import { TaskItem } from "../task-item/task-item";
-import {
- BarMoveAction,
- GanttContentMoveAction,
- GanttEvent,
-} from "../../types/gantt-task-actions";
+import React, { useEffect, useState } from 'react';
+import { EventOption } from '../../types/public-types';
+import { BarTask } from '../../types/bar-task';
+import { Arrow } from '../other/arrow';
+import { handleTaskBySVGMouseEvent } from '../../helpers/bar-helper';
+import { isKeyboardEvent } from '../../helpers/other-helper';
+import { TaskItem } from '../task-item/task-item';
+import { BarMoveAction, GanttContentMoveAction, GanttEvent } from '../../types/gantt-task-actions';
+let lastAction = null;
+let lastStart = null;
export type TaskGanttContentProps = {
tasks: BarTask[];
dates: Date[];
@@ -78,9 +76,7 @@ export const TaskGanttContent: React.FC
= ({
event.preventDefault();
point.x = event.clientX;
- const cursor = point.matrixTransform(
- svg?.current.getScreenCTM()?.inverse()
- );
+ const cursor = point.matrixTransform(svg?.current.getScreenCTM()?.inverse());
const { isChanged, changedTask } = handleTaskBySVGMouseEvent(
cursor.x,
@@ -89,7 +85,7 @@ export const TaskGanttContent: React.FC = ({
xStep,
timeStep,
initEventX1Delta,
- rtl
+ rtl,
);
if (isChanged) {
setGanttEvent({ action: ganttEvent.action, changedTask });
@@ -98,14 +94,11 @@ export const TaskGanttContent: React.FC = ({
const handleMouseUp = async (event: MouseEvent) => {
const { action, originalSelectedTask, changedTask } = ganttEvent;
- if (!changedTask || !point || !svg?.current || !originalSelectedTask)
- return;
+ if (!changedTask || !point || !svg?.current || !originalSelectedTask) return;
event.preventDefault();
point.x = event.clientX;
- const cursor = point.matrixTransform(
- svg?.current.getScreenCTM()?.inverse()
- );
+ const cursor = point.matrixTransform(svg?.current.getScreenCTM()?.inverse());
const { changedTask: newChangedTask } = handleTaskBySVGMouseEvent(
cursor.x,
action as BarMoveAction,
@@ -113,7 +106,7 @@ export const TaskGanttContent: React.FC = ({
xStep,
timeStep,
initEventX1Delta,
- rtl
+ rtl,
);
const isNotLikeOriginal =
@@ -122,23 +115,16 @@ export const TaskGanttContent: React.FC = ({
originalSelectedTask.progress !== newChangedTask.progress;
// remove listeners
- svg.current.removeEventListener("mousemove", handleMouseMove);
- svg.current.removeEventListener("mouseup", handleMouseUp);
- setGanttEvent({ action: "" });
+ svg.current.removeEventListener('mousemove', handleMouseMove);
+ svg.current.removeEventListener('mouseup', handleMouseUp);
+ setGanttEvent({ action: '' });
setIsMoving(false);
// custom operation start
- let operationSuccess:any = true;
- if (
- (action === "move" || action === "end" || action === "start") &&
- onDateChange &&
- isNotLikeOriginal
- ) {
+ let operationSuccess: any = true;
+ if ((action === 'move' || action === 'end' || action === 'start') && onDateChange && isNotLikeOriginal) {
try {
- const result = await onDateChange(
- newChangedTask,
- newChangedTask.barChildren
- );
+ const result = await onDateChange(newChangedTask, newChangedTask.barChildren);
if (result !== undefined) {
operationSuccess = result;
}
@@ -147,10 +133,7 @@ export const TaskGanttContent: React.FC = ({
}
} else if (onProgressChange && isNotLikeOriginal) {
try {
- const result = await onProgressChange(
- newChangedTask,
- newChangedTask.barChildren
- );
+ const result = await onProgressChange(newChangedTask, newChangedTask.barChildren);
if (result !== undefined) {
operationSuccess = result;
}
@@ -167,14 +150,14 @@ export const TaskGanttContent: React.FC = ({
if (
!isMoving &&
- (ganttEvent.action === "move" ||
- ganttEvent.action === "end" ||
- ganttEvent.action === "start" ||
- ganttEvent.action === "progress") &&
+ (ganttEvent.action === 'move' ||
+ ganttEvent.action === 'end' ||
+ ganttEvent.action === 'start' ||
+ ganttEvent.action === 'progress') &&
svg?.current
) {
- svg.current.addEventListener("mousemove", handleMouseMove);
- svg.current.addEventListener("mouseup", handleMouseUp);
+ svg.current.addEventListener('mousemove', handleMouseMove);
+ svg.current.addEventListener('mouseup', handleMouseUp);
setIsMoving(true);
}
}, [
@@ -198,16 +181,16 @@ export const TaskGanttContent: React.FC = ({
const handleBarEventStart = async (
action: GanttContentMoveAction,
task: BarTask,
- event?: React.MouseEvent | React.KeyboardEvent
+ event?: React.MouseEvent | React.KeyboardEvent,
) => {
if (!event) {
- if (action === "select") {
+ if (action === 'select') {
setSelectedTask(task.id);
}
}
// Keyboard events
else if (isKeyboardEvent(event)) {
- if (action === "delete") {
+ if (action === 'delete') {
if (onDelete) {
try {
const result = await onDelete(task);
@@ -215,13 +198,13 @@ export const TaskGanttContent: React.FC = ({
setGanttEvent({ action, changedTask: task });
}
} catch (error) {
- console.error("Error on Delete. " + error);
+ console.error('Error on Delete. ' + error);
}
}
}
}
// Mouse Events
- else if (action === "mouseenter") {
+ else if (action === 'mouseenter') {
if (!ganttEvent.action) {
setGanttEvent({
action,
@@ -229,22 +212,20 @@ export const TaskGanttContent: React.FC = ({
originalSelectedTask: task,
});
}
- } else if (action === "mouseleave") {
- if (ganttEvent.action === "mouseenter") {
- setGanttEvent({ action: "" });
+ } else if (action === 'mouseleave') {
+ if (ganttEvent.action === 'mouseenter') {
+ setGanttEvent({ action: '' });
}
- } else if (action === "dblclick") {
+ } else if (action === 'dblclick') {
!!onDoubleClick && onDoubleClick(task);
- } else if (action === "click") {
+ } else if (action === 'click') {
!!onClick && onClick(task);
}
// Change task event start
- else if (action === "move") {
+ else if (action === 'move') {
if (!svg?.current || !point) return;
point.x = event.clientX;
- const cursor = point.matrixTransform(
- svg.current.getScreenCTM()?.inverse()
- );
+ const cursor = point.matrixTransform(svg.current.getScreenCTM()?.inverse());
setInitEventX1Delta(cursor.x - task.x1);
setGanttEvent({
action,
@@ -260,11 +241,27 @@ export const TaskGanttContent: React.FC = ({
}
};
+ const handleBarEvent = (action, task, event) => {
+ if (['click'].includes(action)) {
+ if (!['start', 'end', 'progress'].includes(lastAction) && (!lastStart || lastStart === task.start)) {
+ handleBarEventStart(action, task, event);
+ }
+ lastAction = null;
+ lastStart = null;
+ } else if (['move', 'select'].includes(action)) {
+ lastStart = task.start;
+ handleBarEventStart(action, task, event);
+ } else {
+ lastStart = task.start;
+ lastAction = action;
+ handleBarEventStart(action, task, event);
+ }
+ };
return (
- {tasks.map(task => {
- return task.barChildren.map(child => {
+ {tasks.map((task) => {
+ return task.barChildren.map((child) => {
return (
= ({
})}
- {tasks.map(task => {
+ {tasks.map((task) => {
return (
= ({
isProgressChangeable={!!onProgressChange && !task.isDisabled}
isDateChangeable={!!onDateChange && !task.isDisabled}
isDelete={!task.isDisabled}
- onEventStart={handleBarEventStart}
+ onEventStart={handleBarEvent}
key={task.id}
isSelected={!!selectedTask && task.id === selectedTask.id}
rtl={rtl}
diff --git a/packages/core/client/src/schema-component/antd/gantt/index.ts b/packages/core/client/src/schema-component/antd/gantt/index.ts
index 9b63d55846..01b30a830c 100644
--- a/packages/core/client/src/schema-component/antd/gantt/index.ts
+++ b/packages/core/client/src/schema-component/antd/gantt/index.ts
@@ -1,13 +1,14 @@
import { ActionBar } from '../action';
import { Gantt } from './components/gantt/gantt';
import { GanttDesigner } from './Gantt.Designer';
-
import { ViewMode } from './types/public-types';
+import {Event} from './components/gantt/Event';
Gantt.ActionBar = ActionBar;
Gantt.ViewMode = ViewMode;
Gantt.Designer = GanttDesigner;
+Gantt.Event = Event;
// const GanttV2 = Gantt;
diff --git a/packages/core/client/src/schema-initializer/utils.ts b/packages/core/client/src/schema-initializer/utils.ts
index 8e080abda5..c59b8d2653 100644
--- a/packages/core/client/src/schema-initializer/utils.ts
+++ b/packages/core/client/src/schema-initializer/utils.ts
@@ -1100,6 +1100,45 @@ export const createGanttBlockSchema = (options) => {
},
},
},
+ detail: {
+ type: 'void',
+ 'x-component': 'Gantt.Event',
+ properties: {
+ drawer: {
+ type: 'void',
+ 'x-component': 'Action.Drawer',
+ 'x-component-props': {
+ className: 'nb-action-popup',
+ },
+ title: '{{ t("View record") }}',
+ properties: {
+ tabs: {
+ type: 'void',
+ 'x-component': 'Tabs',
+ 'x-component-props': {},
+ 'x-initializer': 'TabPaneInitializers',
+ properties: {
+ tab1: {
+ type: 'void',
+ title: '{{t("Details")}}',
+ 'x-component': 'Tabs.TabPane',
+ 'x-designer': 'Tabs.Designer',
+ 'x-component-props': {},
+ properties: {
+ grid: {
+ type: 'void',
+ 'x-component': 'Grid',
+ 'x-initializer': 'RecordBlockInitializers',
+ properties: {},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
},
},
},