nocobase/packages/core/client/src/block-provider/GanttBlockProvider.tsx
被雨水过滤的空气-Rain 29bf187fbf
chore: optimize locators (#2833)
* test(e2e): better locators for designer buttons

* fix: make test passing

* refactor: remove DesignerControl

* chore: better locators

* fix: should not disable add-menu-item

* chore: better test id for block

* chore: optimize Action

* chore: remove role in BlockItem

* feat: improve locators

* chore: menu & add block

* chore: initializer

* chore: testid -> aria label

* chore: tabs

* chore: designers

* refactor: optimize schemaInitializer

* refactor: rename

* chore: add collectionName

* chore: block item

* chore: action

* fix: avoid crashting

* chore(e2e): add __E2E__

* chore: all dialog

* chore: add aria-label for block menu

* Revert "chore: add aria-label for block menu"

This reverts commit 6a840ef816ee1095484dc268b5dfa1bbe6cd8cbe.

* chore: optimize aria-label of Action

* chore: schema-initializer

* chore(e2e): increase timeout

* chore: schema settings

* chore: optimize table

* chore: workflow

* chore: plugin manager

* chore: collection manager and workflow

* chore: details of workflow

* chore: remove testid of Select

* test: fix unit-tests

* test: fix unit-tests

* test(e2e): passing tests

* test: fix unit test

* chore: should use hover

* test: passing tests

* chore: passing tests

* chore: fix CI

* chore: fix CI

* chore: increase timeout in CI

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
2023-10-27 15:32:17 +08:00

128 lines
4.0 KiB
TypeScript

import { useField } from '@formily/react';
import React, { createContext, useContext, useEffect, useState } from 'react';
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>({});
const formatData = (
data = [],
fieldNames,
tasks: any[] = [],
projectId: any = undefined,
hideChildren = false,
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] ?? undefined),
end: new Date(item[fieldNames.end] ?? undefined),
name: item[fieldNames.title],
id: item.id + '',
type: 'project',
progress: percent > 100 ? 100 : percent || 0,
hideChildren: hideChildren,
project: projectId,
color: item.color,
isDisabled: disable,
});
formatData(item.children, fieldNames, tasks, item.id + '', hideChildren, checkPermassion);
} else {
tasks.push({
start: item[fieldNames.start] ? new Date(item[fieldNames.start]) : undefined,
end: new Date(item[fieldNames.end] || item[fieldNames.start]),
name: item[fieldNames.title],
id: item.id + '',
type: fieldNames.end ? 'task' : 'milestone',
progress: percent > 100 ? 100 : percent || 0,
project: projectId,
color: item.color,
isDisabled: disable,
});
}
});
return tasks;
};
const InternalGanttBlockProvider = (props) => {
const { fieldNames, timeRange, resource } = props;
const field = useField();
const { service } = useBlockRequestContext();
// if (service.loading) {
// return <Spin />;
// }
return (
<GanttBlockContext.Provider
value={{
field,
service,
resource,
fieldNames,
timeRange,
}}
>
{props.children}
</GanttBlockContext.Provider>
);
};
export const GanttBlockProvider = (props) => {
const params = { filter: props.params.filter, tree: true, paginate: false, sort: props.fieldNames.start };
return (
<BlockProvider name="gantt" {...props} params={params}>
<TableBlockProvider {...props} params={params}>
<InternalGanttBlockProvider {...props} />
</TableBlockProvider>
</BlockProvider>
);
};
export const useGanttBlockContext = () => {
return useContext(GanttBlockContext);
};
export const useGanttBlockProps = () => {
const ctx = useGanttBlockContext();
const [tasks, setTasks] = useState<any>([]);
const { getPrimaryKey, name, template, writableView } = useCollection();
const { parseAction } = useACLRoleContext();
const primaryKey = getPrimaryKey();
const checkPermission = (record) => {
const actionPath = `${name}:update`;
const schema = {};
const recordPkValue = record?.[primaryKey];
const params = parseAction(actionPath, { schema, recordPkValue });
return (template === 'view' && !writableView) || !params;
};
const onExpanderClick = (task: any) => {
const data = ctx.field.data;
const tasksData = data.map((t: any) => (t.id === task.id ? task : t));
setTasks(tasksData);
ctx.field.data = tasksData;
};
const expandAndCollapseAll = (flag) => {
const data = formatData(ctx.service.data?.data, ctx.fieldNames, [], undefined, flag, checkPermission);
setTasks(data);
ctx.field.data = data;
};
useEffect(() => {
if (!ctx?.service?.loading) {
const data = formatData(ctx.service.data?.data, ctx.fieldNames, [], undefined, false, checkPermission);
setTasks(data);
ctx.field.data = data;
}
}, [ctx?.service?.loading]);
return {
fieldNames: ctx.fieldNames,
timeRange: ctx.timeRange,
onExpanderClick,
expandAndCollapseAll,
tasks,
};
};