fix: tree gantt block does not display correctly (#2123)

* fix: tree gantt block display error

* fix: tree gantt block display error

* refactor: code improve

* refactor: code improve
This commit is contained in:
katherinehhh 2023-06-26 14:14:22 +08:00 committed by GitHub
parent 6d80593f27
commit f042a2307a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 52 additions and 60 deletions

View File

@ -1,9 +1,9 @@
import { useField } from '@formily/react';
import React, { createContext, useContext, useEffect, useState } from 'react';
import { BlockProvider, useBlockRequestContext } from './BlockProvider';
import { TableBlockProvider } from './TableBlockProvider';
import { useACLRoleContext } from '../acl/ACLProvider';
import { useCollection } from '../collection-manager/hooks';
import { BlockProvider, useBlockRequestContext } from './BlockProvider';
import { TableBlockProvider } from './TableBlockProvider';
export const GanttBlockContext = createContext<any>({});
@ -13,15 +13,15 @@ const formatData = (
tasks: any[] = [],
projectId: any = undefined,
hideChildren = false,
checkPermassion?: Function,
checkPermassion?: (any) => boolean,
) => {
data.forEach((item: any) => {
const disable = checkPermassion(item);
const percent = item[fieldNames.progress] * 100;
if (item.children && item.children.length) {
tasks.push({
start: new Date(item[fieldNames.start]),
end: new Date(item[fieldNames.end]),
start: new Date(item[fieldNames.start] ?? undefined),
end: new Date(item[fieldNames.end] ?? undefined),
name: item[fieldNames.title],
id: item.id + '',
type: 'project',

View File

@ -1,29 +1,50 @@
import { ArrayField, createForm } from '@formily/core';
import { FormContext, useField, useFieldSchema } from '@formily/react';
import { boolean } from 'mathjs';
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { useCollectionManager } from '../collection-manager';
import { useFilterBlock } from '../filter-provider/FilterProvider';
import { useRecord } from '../record-provider';
import { FixedBlockWrapper, SchemaComponentOptions, removeNullCondition } from '../schema-component';
import { FixedBlockWrapper, removeNullCondition, SchemaComponentOptions } from '../schema-component';
import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestContext } from './BlockProvider';
import { mergeFilter } from './SharedFilterProvider';
import { findFilterTargets } from './hooks';
import { mergeFilter } from './SharedFilterProvider';
export const TableBlockContext = createContext<any>({});
export function getIdsWithChildren(nodes) {
const ids = [];
if (nodes) {
for (const node of nodes) {
if (node?.children && node.children.length > 0) {
ids.push(node.id);
ids.push(...getIdsWithChildren(node?.children));
}
}
}
return ids;
}
interface Props {
params?: any;
showIndex?: boolean;
dragSort?: boolean;
rowKey?: string;
childrenColumnName: any;
fieldNames?: any;
}
const InternalTableBlockProvider = (props: Props) => {
const { params, showIndex, dragSort, rowKey, childrenColumnName } = props;
const { params, showIndex, dragSort, rowKey, childrenColumnName, fieldNames } = props;
const field: any = useField();
const { resource, service } = useBlockRequestContext();
const [expandFlag, setExpandFlag] = useState(false);
const fieldSchema = useFieldSchema();
const { treeTable } = fieldSchema?.['x-decorator-props'] || {};
const [expandFlag, setExpandFlag] = useState(fieldNames ? true : false);
const allIncludesChildren = useMemo(() => {
if (treeTable !== false) {
const keys = getIdsWithChildren(service?.data?.data);
return keys || [];
}
}, [service?.loading]);
return (
<FixedBlockWrapper>
<TableBlockContext.Provider
@ -37,6 +58,7 @@ const InternalTableBlockProvider = (props: Props) => {
rowKey,
expandFlag,
childrenColumnName,
allIncludesChildren,
setExpandFlag: () => setExpandFlag(!expandFlag),
}}
>

View File

@ -133,7 +133,6 @@ export const Gantt: any = (props: any) => {
useEffect(() => {
tableCtx.field.onExpandClick = handleTableExpanderClick;
tableCtx.field.onRowSelect = handleRowSelect;
tableCtx.setExpandFlag(true);
}, []);
useEffect(() => {
expandAndCollapseAll?.(!expandFlag);

View File

@ -1,9 +1,9 @@
import React, { ReactChild } from 'react';
import { cx } from '@emotion/css';
import { Task } from '../../types/public-types';
import { addToDate } from '../../helpers/date-helper';
import { gridRowLine, gridRow, gridTick, gridHeightRow } from './style';
import { uid } from '@nocobase/utils/client';
import React, { ReactChild } from 'react';
import { addToDate } from '../../helpers/date-helper';
import { Task } from '../../types/public-types';
import { gridHeightRow, gridRow, gridRowLine, gridTick } from './style';
export type GridBodyProps = {
tasks: Task[];

View File

@ -1,9 +1,9 @@
import React from 'react';
import { cx } from '@emotion/css';
import React from 'react';
import { getProgressPoint } from '../../../helpers/bar-helper';
import { TaskItemProps } from '../task-item';
import { BarDisplay } from './bar-display';
import { BarProgressHandle } from './bar-progress-handle';
import { TaskItemProps } from '../task-item';
import { barWrapper } from './style';
export const BarSmall: React.FC<TaskItemProps> = ({

View File

@ -102,7 +102,9 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
className={isProjectBar ? cx(projectLabel) : isTextInside ? cx(barLabel) : cx(barLabel) && cx(barLabelOutside)}
ref={textRef}
>
{isProjectBar ? `${task.name}: ${getYmd(task.start)} ~ ${getYmd(task.end)}` : task.name}
{isProjectBar && getYmd(task.start) && getYmd(task.end)
? `${task.name}: ${getYmd(task.start)} ~ ${getYmd(task.end)}`
: task.name}
</text>
</g>
);

View File

@ -1,6 +1,6 @@
import { Task } from '../types/public-types';
import { BarTask, TaskTypeInternal } from '../types/bar-task';
import { BarMoveAction } from '../types/gantt-task-actions';
import { Task } from '../types/public-types';
export const convertToBarTasks = (
tasks: Task[],
@ -161,7 +161,7 @@ const convertToBar = (
let typeInternal: TaskTypeInternal = task.type;
if (typeInternal === 'task' && x2 - x1 < handleWidth * 2) {
typeInternal = 'smalltask';
x2 = x1 + handleWidth * 2;
x2 = x1 > 0 ? x1 + handleWidth * 2 : x1;
}
const [progressWidth, progressX] = progressWithByParams(x1, x2, task.progress, rtl);
@ -244,20 +244,19 @@ const convertToMilestone = (
const taskXCoordinate = (xDate: Date, dates: Date[], columnWidth: number) => {
const index = dates.findIndex((d) => d?.getTime() >= xDate?.getTime()) - 1;
const remainderMillis = xDate?.getTime() - dates[index]?.getTime();
const percentOfInterval = remainderMillis / (dates[index + 1]?.getTime() - dates[index]?.getTime());
const x = index * columnWidth + percentOfInterval * columnWidth;
return x;
return isNaN(x) ? 0 : x;
};
const taskXCoordinateRTL = (xDate: Date, dates: Date[], columnWidth: number) => {
let x = taskXCoordinate(xDate, dates, columnWidth);
x += columnWidth;
return x;
return isNaN(x) ? 0 : x;
};
const taskYCoordinate = (index: number, rowHeight: number, taskHeight: number) => {
const y = index * rowHeight + (rowHeight - taskHeight) / 2;
return y;
return isNaN(y) ? 0 : y;
};
export const progressWithByParams = (taskX1: number, taskX2: number, progress: number, rtl: boolean) => {

View File

@ -57,5 +57,7 @@ export const sortTasks = (taskA: Task, taskB: Task) => {
};
export const getYmd = (date: Date) => {
return date.getFullYear() + '/' + `${date.getMonth() + 1}` + '/' + date.getDate();
if (!isNaN(date.getTime())) {
return date.getFullYear() + '/' + `${date.getMonth() + 1}` + '/' + date.getDate();
}
};

View File

@ -3,7 +3,7 @@ import { SortableContext, useSortable } from '@dnd-kit/sortable';
import { css } from '@emotion/css';
import { ArrayField, Field } from '@formily/core';
import { spliceArrayState } from '@formily/core/esm/shared/internals';
import { RecursionField, Schema, observer, useField, useFieldSchema } from '@formily/react';
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
import { action, reaction } from '@formily/reactive';
import { useMemoizedFn } from 'ahooks';
import { Table as AntdTable, TableColumnProps } from 'antd';
@ -19,7 +19,7 @@ import {
useTableSelectorContext,
} from '../../../';
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
import { extractIndex, getIdsWithChildren, isCollectionFieldComponent, isColumnComponent } from './utils';
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
const useArrayField = (props) => {
const field = useField<ArrayField>();
@ -213,18 +213,14 @@ export const Table: any = observer(
const schema = useFieldSchema();
const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider';
const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext();
const { expandFlag } = ctx;
const { expandFlag, allIncludesChildren } = ctx;
const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => {}));
const paginationProps = usePaginationProps(pagination1, pagination2);
// const requiredValidator = field.required || required;
const { treeTable } = schema?.parent?.['x-decorator-props'] || {};
const [expandedKeys, setExpandesKeys] = useState([]);
const [allIncludesChildren, setAllIncludesChildren] = useState([]);
const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>(field?.data?.selectedRowKeys || []);
const [selectedRow, setSelectedRow] = useState([]);
const dataSource = field?.value?.slice?.()?.filter?.(Boolean) || [];
const isRowSelect = rowSelection?.type !== 'none';
let onRow = null,
highlightRow = '';
@ -244,21 +240,6 @@ export const Table: any = observer(
`;
}
// useEffect(() => {
// field.setValidator((value) => {
// if (requiredValidator) {
// return Array.isArray(value) && value.length > 0 ? null : 'The field value is required';
// }
// return;
// });
// }, [requiredValidator]);
useEffect(() => {
if (treeTable !== false) {
const keys = getIdsWithChildren(field.value?.slice?.());
setAllIncludesChildren(keys);
}
}, [field.value]);
useEffect(() => {
if (expandFlag) {
setExpandesKeys(allIncludesChildren);

View File

@ -17,16 +17,3 @@ export function extractIndex(str) {
});
return numbers.join('.');
}
export function getIdsWithChildren(nodes) {
const ids = [];
if (nodes) {
for (const node of nodes) {
if (node?.children && node.children.length > 0) {
ids.push(node.id);
ids.push(...getIdsWithChildren(node?.children));
}
}
}
return ids;
}