hide related feature

This commit is contained in:
MaTeMaTuK committed 2021-08-09 22:21:18 +03:00
1 parent 3343a10c32
commit 49c013f3d7
12 files changed
+156 -69

No files matched your search

+12 -4
View File
@@ -1,5 +1,5 @@
import React, { useState, SyntheticEvent, useRef, useEffect } from "react";
import { ViewMode, GanttProps } from "../../types/public-types";
import { ViewMode, GanttProps, Task } from "../../types/public-types";
import { GridProps } from "../grid/grid";
import { ganttDateRange, seedDates } from "../../helpers/date-helper";
import { CalendarProps } from "../calendar/calendar";
@@ -16,6 +16,7 @@ import { GanttEvent } from "../../types/gantt-task-actions";
import { DateSetup } from "../../types/date-setup";
import styles from "./gantt.module.css";
import { HorizontalScroll } from "../other/horizontal-scroll";
import { removeHiddenTasks } from "../../helpers/other-helper";
export const Gantt: React.FunctionComponent<GanttProps> = ({
tasks,
@@ -54,6 +55,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
onDoubleClick,
onDelete,
onSelect,
onExpanderClick,
}) => {
const wrapperRef = useRef<HTMLDivElement>(null);
const taskListRef = useRef<HTMLDivElement>(null);
@@ -83,7 +85,8 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
// task change events
useEffect(() => {
const [startDate, endDate] = ganttDateRange(tasks, viewMode);
const filteredTasks = removeHiddenTasks(tasks);
const [startDate, endDate] = ganttDateRange(filteredTasks, viewMode);
let newDates = seedDates(startDate, endDate, viewMode);
if (rtl) {
newDates = newDates.reverse();
@@ -94,7 +97,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
setDateSetup({ dates: newDates, viewMode });
setBarTasks(
convertToBarTasks(
tasks,
filteredTasks,
newDates,
columnWidth,
rowHeight,
@@ -322,7 +325,11 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
}
setSelectedTask(newSelectedTask);
};
const handleExpanderClick = (task: Task) => {
if (onExpanderClick && task.hideChildren !== undefined) {
onExpanderClick({ ...task, hideChildren: !task.hideChildren });
}
};
const gridProps: GridProps = {
columnWidth,
svgWidth,
@@ -380,6 +387,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
selectedTask,
taskListRef,
setSelectedTask: handleSelectedTask,
onExpanderClick: handleExpanderClick,
TaskListHeader,
TaskListTable,
};
@@ -20,3 +20,19 @@
overflow: hidden;
text-overflow: ellipsis;
}
.taskListNameWrapper {
display: flex;
}
.taskListExpander {
color: rgb(86 86 86);
font-size: 0.6rem;
padding: 0.15rem 0.2rem 0rem 0.2rem;
user-select: none;
cursor: pointer;
}
.taskListEmptyExpander {
font-size: 0.6rem;
padding-left: 1rem;
user-select: none;
}
+30 -2
View File
@@ -11,7 +11,16 @@ export const TaskListTableDefault: React.FC<{
tasks: Task[];
selectedTaskId: string;
setSelectedTask: (taskId: string) => void;
}> = ({ rowHeight, rowWidth, tasks, fontFamily, fontSize, locale }) => {
onExpanderClick: (task: Task) => void;
}> = ({
rowHeight,
rowWidth,
tasks,
fontFamily,
fontSize,
locale,
onExpanderClick,
}) => {
const dateTimeOptions: Intl.DateTimeFormatOptions = {
weekday: "short",
year: "numeric",
@@ -27,6 +36,13 @@ export const TaskListTableDefault: React.FC<{
}}
>
{tasks.map(t => {
let expanderSymbol = "";
if (t.hideChildren === false) {
expanderSymbol = "▼";
} else if (t.hideChildren === true) {
expanderSymbol = "▶";
}
return (
<div
className={styles.taskListTableRow}
@@ -41,7 +57,19 @@ export const TaskListTableDefault: React.FC<{
}}
title={t.name}
>
&nbsp;{t.name}
<div className={styles.taskListNameWrapper}>
<div
className={
expanderSymbol
? styles.taskListExpander
: styles.taskListEmptyExpander
}
onClick={() => onExpanderClick(t)}
>
{expanderSymbol}
</div>
<div>{t.name}</div>
</div>
</div>
<div
className={styles.taskListCell}
+4
View File
@@ -16,6 +16,7 @@ export type TaskListProps = {
horizontalContainerClass?: string;
selectedTask: BarTask | undefined;
setSelectedTask: (task: string) => void;
onExpanderClick: (task: Task) => void;
TaskListHeader: React.FC<{
headerHeight: number;
rowWidth: string;
@@ -31,6 +32,7 @@ export type TaskListProps = {
tasks: Task[];
selectedTaskId: string;
setSelectedTask: (taskId: string) => void;
onExpanderClick: (task: Task) => void;
}>;
};
@@ -44,6 +46,7 @@ export const TaskList: React.FC<TaskListProps> = ({
tasks,
selectedTask,
setSelectedTask,
onExpanderClick,
locale,
ganttHeight,
taskListRef,
@@ -74,6 +77,7 @@ export const TaskList: React.FC<TaskListProps> = ({
locale,
selectedTaskId: selectedTaskId,
setSelectedTask,
onExpanderClick,
};
return (
+13
View File
@@ -63,6 +63,19 @@ export const convertToBarTasks = (
}
return task;
});
// normalize flags for hideChildren
barTasks = barTasks.map(task => {
if (task.barChildren.length > 0) {
if (!task.hideChildren) {
task.hideChildren = false;
}
} else if (!task.hideChildren && task.type === "project") {
task.hideChildren = false;
} else if (!task.hideChildren) {
task.hideChildren = undefined;
}
return task;
});
return barTasks;
};
+30
View File
@@ -16,3 +16,33 @@ export function isMouseEvent(
export function isBarTask(task: Task | BarTask): task is BarTask {
return (task as BarTask).x1 !== undefined;
}
export function removeHiddenTasks(tasks: Task[]) {
const groupedTasks = tasks.filter(t => t.hideChildren);
if (groupedTasks.length > 0) {
for (let i = 0; groupedTasks.length > i; i++) {
const groupedTask = groupedTasks[i];
const children = getChildren(tasks, groupedTask);
tasks = tasks.filter(t => children.indexOf(t) === -1);
}
}
return tasks;
}
function getChildren(taskList: Task[], task: Task) {
let tasks: Task[] = [];
if (task.type !== "project") {
tasks = taskList.filter(
t => t.dependencies && t.dependencies.indexOf(task.id) !== -1
);
} else {
tasks = taskList.filter(t => t.project && t.project === task.id);
}
const taskChildren = tasks.reduce(
(children: Task[], t) =>
children.concat(children, getChildren(taskList, t)),
[]
);
tasks = tasks.concat(tasks, taskChildren);
return tasks;
}
-26
View File
@@ -1,26 +0,0 @@
export function foo() {
return 1;
}
// import { BarTask } from "../types/bar-task";
// export type TaskListAction =
// | { type: GanttContentMoveAction; task: BarTask }
// | { type: "update"; tasks: BarTask[] };
// export type TaskListState = {
// tasks: BarTask[];
// changedTask?: BarTask;
// originalTask?: BarTask;
// selectedTask?: BarTask;
// activeAction: GanttContentMoveAction;
// };
// export function taskListReducer(state: TaskListState, action: TaskListAction) {
// switch (action.type) {
// case "update":
// return { ...state, tasks: action.tasks };
// case "select":
// return { ...state, selectedTask: action.task };
// default:
// return state;
// }
// }
+6
View File
@@ -26,6 +26,7 @@ export interface Task {
isDisabled?: boolean;
project?: string;
dependencies?: string[];
hideChildren?: boolean;
}
export interface EventOption {
@@ -57,6 +58,10 @@ export interface EventOption {
* Invokes on delete selected task. Chart undoes operation if method return false or error.
*/
onDelete?: (task: Task) => void | boolean | Promise<void> | Promise<boolean>;
/**
* Invokes on expander on task list
*/
onExpanderClick?: (task: Task) => void;
}
export interface DisplayOption {
@@ -119,6 +124,7 @@ export interface StylingOption {
* Sets selected task by id
*/
setSelectedTask: (taskId: string) => void;
onExpanderClick: (task: Task) => void;
}>;
}