mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-09 15:39:24 +08:00
Merge branch 'feat/tree-collection' into feat/gantt-block
This commit is contained in:
commit
a0120d4163
@ -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);
|
||||
}, []);
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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} />}
|
||||
|
@ -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>
|
||||
);
|
||||
});
|
||||
|
@ -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>;
|
||||
};
|
||||
|
@ -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} />;
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user