diff --git a/src/components/gantt/gantt.tsx b/src/components/gantt/gantt.tsx index 785249ce..04d67049 100644 --- a/src/components/gantt/gantt.tsx +++ b/src/components/gantt/gantt.tsx @@ -87,7 +87,6 @@ import { deleteOption } from "../../context-menu-options/delete"; import { useHolidays } from "./use-holidays"; import styles from "./gantt.module.css"; -import { useTableListResize } from "./use-tablelist-resize"; const defaultColors: ColorStyles = { arrowColor: "grey", @@ -124,6 +123,7 @@ const defaultColors: ColorStyles = { evenTaskBackgroundColor: "#f5f5f5", holidayBackgroundColor: "rgba(233, 233, 233, 0.3)", selectedTaskBackgroundColor: "rgba(252, 248, 227, 0.5)", + taskDragColor: "#7474ff", todayColor: "rgba(252, 248, 227, 0.5)", contextMenuBoxShadow: "rgb(0 0 0 / 25%) 1px 1px 5px 1px", contextMenuBgColor: "#fff", @@ -757,15 +757,6 @@ export const Gantt: React.FC = ({ }); }, []); - // Manage the column and list table resizing - const [ - columns, - taskListWidth, - tableWidth, - onTableResizeStart, - onColumnResizeStart, - ] = useTableListResize(columnsProp, distances, onResizeColumn); - const getMetadata = useCallback( (changeAction: ChangeAction) => getChangeTaskMetadata({ @@ -1913,7 +1904,7 @@ export const Gantt: React.FC = ({ childTasksMap, closedTasks, colors: colorStyles, - columns, + columnsProp, cutIdsMirror, dateSetup, dependencyMap, @@ -1934,19 +1925,16 @@ export const Gantt: React.FC = ({ icons, isShowTaskNumbers, mapTaskToNestedIndex, - onColumnResizeStart, onExpanderClick: handleExpanderClick, - onTableResizeStart, scrollToBottomStep, scrollToTopStep, selectTaskOnMouseDown, selectedIdsMirror, scrollToTask, - tableWidth, taskListContainerRef, taskListRef, - taskListWidth, tasks: visibleTasks, + onResizeColumn, }; return ( @@ -1956,7 +1944,8 @@ export const Gantt: React.FC = ({ tabIndex={0} ref={wrapperRef} > - {columns.length > 0 && } + {/* {columns.length > 0 && } */} + {(!columnsProp || columnsProp.length > 0) && } { const [columnsState, setColumns] = useState(() => { if (columnsProp) { - return columnsProp; + return [...columnsProp]; } const { @@ -89,6 +89,13 @@ export const useTableListResize = ( ]; }); + useEffect(() => { + if (columnsProp) { + setColumns([...columnsProp]); + setTableWidth(columnsProp.reduce((res, { width }) => res + width, 0)); + } + }, [columnsProp]); + const [tableResizeEvent, setTableResizeEvent] = useState(null); const [columnResizeEvent, setColumnResizeEvent] = diff --git a/src/components/task-list/task-list.tsx b/src/components/task-list/task-list.tsx index b1d9915e..bdba998f 100644 --- a/src/components/task-list/task-list.tsx +++ b/src/components/task-list/task-list.tsx @@ -12,6 +12,7 @@ import { Distances, Icons, MapTaskToNestedIndex, + OnResizeColumn, Task, TaskListHeaderProps, TaskListTableProps, @@ -22,6 +23,7 @@ import { ROW_DRAG_TYPE } from "../../constants"; import { useOptimizedList } from "../../helpers/use-optimized-list"; import styles from "./task-list.module.css"; +import { useTableListResize } from "../gantt/use-tablelist-resize"; const SCROLL_DELAY = 25; @@ -31,7 +33,7 @@ export type TaskListProps = { childTasksMap: ChildByLevelMap; closedTasks: Readonly>; colors: ColorStyles; - columns: readonly Column[]; + columnsProp: readonly Column[]; cutIdsMirror: Readonly>; dateSetup: DateSetup; dependencyMap: DependencyMap; @@ -56,21 +58,18 @@ export type TaskListProps = { icons?: Partial; isShowTaskNumbers: boolean; mapTaskToNestedIndex: MapTaskToNestedIndex; - onColumnResizeStart: (columnIndex: number, clientX: number) => void; onExpanderClick: (task: Task) => void; - onTableResizeStart: (clientX: number) => void; scrollToBottomStep: () => void; scrollToTask: (task: Task) => void; scrollToTopStep: () => void; selectTaskOnMouseDown: (taskId: string, event: MouseEvent) => void; selectedIdsMirror: Readonly>; - tableWidth: number; taskListContainerRef: RefObject; taskListRef: RefObject; - taskListWidth: number; tasks: readonly TaskOrEmpty[]; TaskListHeader: ComponentType; TaskListTable: ComponentType; + onResizeColumn?: OnResizeColumn; }; const TaskListInner: React.FC = ({ @@ -79,7 +78,7 @@ const TaskListInner: React.FC = ({ childTasksMap, closedTasks, colors, - columns, + columnsProp, cutIdsMirror, dateSetup, dependencyMap, @@ -100,22 +99,28 @@ const TaskListInner: React.FC = ({ icons = undefined, isShowTaskNumbers, mapTaskToNestedIndex, - onColumnResizeStart, onExpanderClick, - onTableResizeStart, scrollToBottomStep, scrollToTask, scrollToTopStep, selectTaskOnMouseDown, selectedIdsMirror, - tableWidth, taskListContainerRef, taskListRef, - taskListWidth, tasks, TaskListHeader, TaskListTable, + onResizeColumn, }) => { + // Manage the column and list table resizing + const [ + columns, + taskListWidth, + tableWidth, + onTableResizeStart, + onColumnResizeStart, + ] = useTableListResize(columnsProp, distances, onResizeColumn); + const renderedIndexes = useOptimizedList( taskListContainerRef, "scrollTop", diff --git a/src/types/public-types.ts b/src/types/public-types.ts index a8d18be5..7bdb6d05 100644 --- a/src/types/public-types.ts +++ b/src/types/public-types.ts @@ -100,6 +100,7 @@ export interface ColorStyles { milestoneBackgroundSelectedCriticalColor: string; evenTaskBackgroundColor: string; holidayBackgroundColor: string; + taskDragColor: string; selectedTaskBackgroundColor: string; todayColor: string; contextMenuBoxShadow: string; @@ -807,6 +808,7 @@ export type ColumnProps = { }; export type Column = { + id?: string; component: ComponentType; width: number; title?: ReactNode; diff --git a/stories/CustomColumns.tsx b/stories/CustomColumns.tsx index 95508115..8808aaaf 100644 --- a/stories/CustomColumns.tsx +++ b/stories/CustomColumns.tsx @@ -6,6 +6,7 @@ import { HTML5Backend } from "react-dnd-html5-backend"; import { Column, ColumnProps, + DateEndColumn, DateStartColumn, Gantt, OnChangeTasks, @@ -17,6 +18,13 @@ import { import { initTasks, onAddTask, onEditTask } from "./helper"; import "../dist/style.css"; +import { + Checkbox, + FormControl, + ListItemText, + MenuItem, + Select, +} from "@material-ui/core"; const ProgressColumn: React.FC = ({ data: { task } }) => { if (task.type === "project" || task.type === "task") { @@ -26,28 +34,61 @@ const ProgressColumn: React.FC = ({ data: { task } }) => { return null; }; -const columns: readonly Column[] = [ - { - component: DateStartColumn, - width: 200, - title: "Date of start", - }, - { - component: TitleColumn, - width: 260, - title: "Title", - }, - { - component: ProgressColumn, - width: 80, - title: "Progress", - }, -]; - type AppProps = { ganttHeight?: number; }; +enum TaskListColumnEnum { + NAME = "Name", + FROM = "From", + TO = "To", + PROGRESS = "Progress", + ASSIGNEE = "Assignee", +} + +export const getColumns = ( + columnTypes: TaskListColumnEnum[], + displayColumns: boolean +) => { + if (!displayColumns) { + return new Map(); + } + const typeToColumn = new Map(); + columnTypes.forEach(columnType => { + if (columnType === TaskListColumnEnum.NAME) { + typeToColumn.set(columnType, { + component: TitleColumn, + width: 210, + title: "Name", + id: TaskListColumnEnum.NAME, + }); + } else if (columnType === TaskListColumnEnum.FROM) { + typeToColumn.set(columnType, { + component: DateStartColumn, + width: 150, + title: "Date of start", + id: TaskListColumnEnum.FROM, + }); + } else if (columnType === TaskListColumnEnum.TO) { + typeToColumn.set(columnType, { + component: DateEndColumn, + width: 150, + title: "Date of end", + id: TaskListColumnEnum.TO, + }); + } else if (columnType === TaskListColumnEnum.PROGRESS) { + typeToColumn.set(columnType, { + component: ProgressColumn, + width: 40, + title: "Progress", + id: TaskListColumnEnum.PROGRESS, + }); + } + }); + + return typeToColumn; +}; + export const CustomColumns: React.FC = props => { const [tasks, setTasks] = useState(initTasks()); @@ -83,18 +124,86 @@ export const CustomColumns: React.FC = props => { console.log("On Click event Id:" + task.id); }, []); + const [columnTypes, setColumnTypes] = useState([ + TaskListColumnEnum.NAME, + TaskListColumnEnum.FROM, + TaskListColumnEnum.TO, + TaskListColumnEnum.PROGRESS, + ]); + const typeToColumn: Map = getColumns( + [ + TaskListColumnEnum.NAME, + TaskListColumnEnum.FROM, + TaskListColumnEnum.TO, + TaskListColumnEnum.PROGRESS, + ], + true + ); + const [displayedColumns, setDisplayedColumns] = useState( + Array.from(typeToColumn.values()) + ); + + const allMetaColumns = [ + { type: TaskListColumnEnum.NAME, name: "Name" }, + { type: TaskListColumnEnum.FROM, name: "From" }, + { type: TaskListColumnEnum.TO, name: "To" }, + { type: TaskListColumnEnum.PROGRESS, name: "Progress" }, + ]; + + const handleChangeColumns = event => { + const columnTypes: TaskListColumnEnum[] = event.target.value; + const newMetaColumns = allMetaColumns.filter(col => + columnTypes.includes(col.type) + ); + setColumnTypes(newMetaColumns.map(col => col.type)); + + const newDisplayedColumns: Column[] = []; + + newMetaColumns.forEach(metaColumn => { + let column = displayedColumns.find(col => col.id == metaColumn.type); + if (!column) { + column = typeToColumn.get(metaColumn.type); + } + if (column) { + newDisplayedColumns.push(column); + } + }); + + setDisplayedColumns(newDisplayedColumns); + }; + return ( - - - + <> + + + + + + + ); }; diff --git a/stories/CustomPalette.tsx b/stories/CustomPalette.tsx index 004752c6..641a2120 100644 --- a/stories/CustomPalette.tsx +++ b/stories/CustomPalette.tsx @@ -162,6 +162,7 @@ export const CustomPalette: React.FC = props => { ); }; + return (