Merge branch 'feat/tree-collection' into feat/gantt-block

This commit is contained in:
katherinehhh 2023-03-15 23:09:22 +08:00
commit a0120d4163
7 changed files with 153 additions and 121 deletions

View File

@ -7,6 +7,7 @@ import { useCollection } from '../collection-manager';
import { RecordProvider, useRecord } from '../record-provider';
import { useDesignable } from '../schema-component';
import { BlockProvider, useBlockRequestContext } from './BlockProvider';
import { useActionContext } from '../schema-component';
export const FormBlockContext = createContext<any>({});
@ -78,6 +79,18 @@ export const useFormBlockContext = () => {
export const useFormBlockProps = () => {
const ctx = useFormBlockContext();
const record = useRecord();
const { fieldSchema } = useActionContext();
const { addChild } = fieldSchema['x-component-props'];
useEffect(() => {
if (addChild) {
ctx.form.query('parent').take((field) => {
field.disabled = true;
field.value = new Proxy({ ...record }, {});
});
}
});
useEffect(() => {
ctx.form.setInitialValues(ctx.service?.data?.data);
}, []);

View File

@ -1,10 +1,11 @@
import { ArrayField, createForm } from '@formily/core';
import { FormContext, Schema, useField, useFieldSchema } from '@formily/react';
import uniq from 'lodash/uniq';
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { useCollectionManager, useCollection } from '../collection-manager';
import React, { createContext, useMemo, useState, useContext,useEffect } from 'react';
import { useCollectionManager } from '../collection-manager';
import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestContext } from './BlockProvider';
import { useFixedSchema } from '../schema-component';
import { SchemaComponentOptions } from '../..';
export const TableBlockContext = createContext<any>({});
@ -89,7 +90,7 @@ export const TableBlockProvider = (props) => {
const form = useMemo(() => createForm(), []);
const fieldSchema = useFieldSchema();
const { getCollection } = useCollectionManager();
const collection=getCollection(props.collection)
const collection = getCollection(props.collection);
const { treeTable } = fieldSchema['x-decorator-props'];
if (props.dragSort) {
params['sort'] = ['sort'];
@ -101,11 +102,13 @@ export const TableBlockProvider = (props) => {
params['appends'] = appends;
}
return (
<FormContext.Provider value={form}>
<BlockProvider {...props} params={params}>
<InternalTableBlockProvider {...props} params={params} />
</BlockProvider>
</FormContext.Provider>
<SchemaComponentOptions scope={{ treeTable }}>
<FormContext.Provider value={form}>
<BlockProvider {...props} params={params}>
<InternalTableBlockProvider {...props} params={params} />
</BlockProvider>
</FormContext.Provider>
</SchemaComponentOptions>
);
};

View File

@ -50,6 +50,7 @@ export const ActionDesigner = (props) => {
const actionType = fieldSchema['x-action'] ?? '';
const isLinkageAction = Object.keys(useFormBlockContext()).length > 0 && Object.keys(useRecord()).length > 0;
const isChildCollectionAction = getChildrenCollections(name).length > 0 && fieldSchema['x-action'] === 'create';
const isSupportEditButton = fieldSchema['x-action'] !== 'expandAll';
useEffect(() => {
const schemaUid = uid();
const schema: ISchema = {
@ -85,6 +86,7 @@ export const ActionDesigner = (props) => {
title: t('Button title'),
default: fieldSchema.title,
'x-component-props': {},
'x-visible': isSupportEditButton,
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
},
icon: {
@ -93,6 +95,7 @@ export const ActionDesigner = (props) => {
title: t('Button icon'),
default: fieldSchema?.['x-component-props']?.icon,
'x-component-props': {},
'x-visible': isSupportEditButton,
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
},
type: {
@ -114,27 +117,25 @@ export const ActionDesigner = (props) => {
} as ISchema
}
onSubmit={({ title, icon, type }) => {
if (title) {
fieldSchema.title = title;
field.title = title;
field.componentProps.icon = icon;
field.componentProps.danger = type === 'danger';
field.componentProps.type = type;
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
fieldSchema['x-component-props'].icon = icon;
fieldSchema['x-component-props'].danger = type === 'danger';
fieldSchema['x-component-props'].type = type;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
title,
'x-component-props': {
...fieldSchema['x-component-props'],
},
fieldSchema.title = title;
field.title = title;
field.componentProps.icon = icon;
field.componentProps.danger = type === 'danger';
field.componentProps.type = type;
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
fieldSchema['x-component-props'].icon = icon;
fieldSchema['x-component-props'].danger = type === 'danger';
fieldSchema['x-component-props'].type = type;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
title,
'x-component-props': {
...fieldSchema['x-component-props'],
},
});
dn.refresh();
}
},
});
dn.refresh();
}}
/>
{isLinkageAction && <SchemaSettings.LinkageRules collectionName={name} />}

View File

@ -10,13 +10,7 @@ import { default as classNames, default as cls } from 'classnames';
import React, { RefCallback, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { DndContext, useDesignable } from '../..';
import {
RecordIndexProvider,
RecordProvider,
useSchemaInitializer,
useTableBlockContext,
SchemaComponentOptions,
} from '../../../';
import { RecordIndexProvider, RecordProvider, useSchemaInitializer, useTableBlockContext } from '../../../';
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
import { isCollectionFieldComponent, isColumnComponent, extractIndex, getIdsWithChildren } from './utils';
@ -418,57 +412,55 @@ export const Table: any = observer((props: any) => {
};
return (
<SchemaComponentOptions scope={{ treeTable }}>
<div
ref={mountedRef}
className={css`
<div
ref={mountedRef}
className={css`
height: 100%;
overflow: hidden;
.ant-table-wrapper {
height: 100%;
overflow: hidden;
.ant-table-wrapper {
height: 100%;
}
.ant-table {
overflow-x: auto;
overflow-y: hidden;
}
`}
>
<SortableWrapper>
<AntdTable
ref={(ref) => {
const headerHeight = ref?.querySelector('.ant-table-header')?.getBoundingClientRect().height || 0;
const paginationHeight = ref?.querySelector('.ant-table-pagination')?.getBoundingClientRect().height || 0;
setHeaderAndPaginationHeight(Math.ceil(headerHeight + paginationHeight + 16));
}}
rowKey={rowKey ?? defaultRowKey}
{...others}
{...restProps}
pagination={paginationProps}
components={components}
onChange={(pagination, filters, sorter, extra) => {
onTableChange?.(pagination, filters, sorter, extra);
}}
tableLayout={'auto'}
scroll={scroll}
columns={columns}
expandable={{
onExpand: (flag, record) => {
const newKeys = flag ? [...expandedKeys, record.id] : expandedKeys.filter((i) => record.id !== i);
setExpandesKeys(newKeys);
},
expandedRowKeys: expandedKeys,
}}
dataSource={field?.value?.slice?.()}
/>
</SortableWrapper>
{field.errors.length > 0 && (
<div className="ant-formily-item-error-help ant-formily-item-help ant-formily-item-help-enter ant-formily-item-help-enter-active">
{field.errors.map((error) => {
return error.messages.map((message) => <div>{message}</div>);
})}
</div>
)}
</div>
</SchemaComponentOptions>
}
.ant-table {
overflow-x: auto;
overflow-y: hidden;
}
`}
>
<SortableWrapper>
<AntdTable
ref={(ref) => {
const headerHeight = ref?.querySelector('.ant-table-header')?.getBoundingClientRect().height || 0;
const paginationHeight = ref?.querySelector('.ant-table-pagination')?.getBoundingClientRect().height || 0;
setHeaderAndPaginationHeight(Math.ceil(headerHeight + paginationHeight + 16));
}}
rowKey={rowKey ?? defaultRowKey}
{...others}
{...restProps}
pagination={paginationProps}
components={components}
onChange={(pagination, filters, sorter, extra) => {
onTableChange?.(pagination, filters, sorter, extra);
}}
tableLayout={'auto'}
scroll={scroll}
columns={columns}
expandable={{
onExpand: (flag, record) => {
const newKeys = flag ? [...expandedKeys, record.id] : expandedKeys.filter((i) => record.id !== i);
setExpandesKeys(newKeys);
},
expandedRowKeys: expandedKeys,
}}
dataSource={field?.value?.slice?.()}
/>
</SortableWrapper>
{field.errors.length > 0 && (
<div className="ant-formily-item-error-help ant-formily-item-help ant-formily-item-help-enter ant-formily-item-help-enter-active">
{field.errors.map((error) => {
return error.messages.map((message) => <div>{message}</div>);
})}
</div>
)}
</div>
);
});

View File

@ -1,9 +1,7 @@
import React from 'react';
import { useFieldSchema } from '@formily/react';
import { SchemaComponentOptions } from '../../schema-component';
import { ActionInitializer } from './ActionInitializer';
export const CreateChildInitializer = (props) => {
const schema = {
type: 'void',
title: '{{ t("Add Child") }}',
@ -55,10 +53,3 @@ export const CreateChildInitializer = (props) => {
};
return <ActionInitializer {...props} schema={schema} />;
};
export const CreateChildProvider = (props) => {
const schema = useFieldSchema();
const { treeTable } = schema?.parent?.['x-decorator-props'];
console.log(props, schema);
return <SchemaComponentOptions>{props.children}</SchemaComponentOptions>;
};

View File

@ -16,18 +16,3 @@ export const CreateSubmitActionInitializer = (props) => {
};
return <ActionInitializer {...props} schema={schema} />;
};
export const CreateChildSubmitActionInitializer = (props) => {
const schema = {
title: '{{ t("Submit") }}',
'x-action': 'submit',
'x-component': 'Action',
'x-designer': 'Action.Designer',
'x-component-props': {
type: 'primary',
htmlType: 'submit',
useProps: '{{ useCreateChildActionProps }}',
},
};
return <ActionInitializer {...props} schema={schema} />;
};

View File

@ -1,9 +1,11 @@
import React from 'react';
import { Button } from 'antd';
import { ActionInitializer } from './ActionInitializer';
import { css } from '@emotion/css';
import { useTranslation } from 'react-i18next';
import { ActionInitializer } from './ActionInitializer';
import { useTableBlockContext } from '../../';
import { NodeCollapseOutlined, NodeExpandOutlined } from '@ant-design/icons';
export const ExpandActionInitializer = (props) => {
const schema = {
'x-action': 'expandAll',
@ -23,17 +25,62 @@ export const ExpandActionInitializer = (props) => {
return <ActionInitializer {...props} schema={schema} />;
};
export const ExpandActionComponent = () => {
export const actionDesignerCss = css`
position: relative;
&:hover {
.general-schema-designer {
display: block;
}
}
.general-schema-designer {
position: absolute;
z-index: 999;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: none;
background: rgba(241, 139, 98, 0.06);
border: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
pointer-events: none;
> .general-schema-designer-icons {
position: absolute;
right: 2px;
top: 2px;
line-height: 16px;
pointer-events: all;
.ant-space-item {
background-color: #f18b62;
color: #fff;
line-height: 16px;
width: 16px;
padding-left: 1px;
}
}
}
`;
export const ExpandActionComponent = (props) => {
const { t } = useTranslation();
const ctx = useTableBlockContext();
return (
<Button
onClick={() => {
ctx?.setExpandFlag();
}}
icon={ctx?.expandFlag ? <NodeCollapseOutlined /> : <NodeExpandOutlined />}
>
{ctx?.expandFlag ? t('Collapse all') : t('Expand all')}
</Button>
<div className={actionDesignerCss}>
{ctx.params['tree'] && (
<Button
onClick={() => {
ctx?.setExpandFlag();
}}
icon={ctx?.expandFlag ? <NodeCollapseOutlined /> : <NodeExpandOutlined />}
type={props.type}
>
{props.children[1]}
<span style={{ marginLeft: 10 }}>{ctx?.expandFlag ? t('Collapse all') : t('Expand all')}</span>
</Button>
)}
</div>
);
};