教程地址:添加数据区块 Data Block
显示:
代码:
component/HTree.tsx
import React, { useCallback, useState } from "react";
// import { CollapseProps, Collapse, Tree, TreeDataNode, TreeProps } from 'antd';
import { withDynamicSchemaProps } from '@nocobase/client';
import { BlockName } from '../constants';
import Tree, { TreeProps } from 'react-d3-tree';
import styles from './HTree.less';
export interface HTreeProps {
collectionName: string;
data?: any[];
}
const renderForeignObjectNode = ({
nodeDatum,
toggleNode,
foreignObjectProps,
className
}) => (
<g>
<rect fill='white' stroke='white' width="10" height="10" />
<foreignObject {...foreignObjectProps}>
<div className={className} onClick={toggleNode}>
<h3 style={{ textAlign: "center", margin: 0 }}>{nodeDatum.name}</h3>
</div>
</foreignObject>
</g>
);
function useCenteredTree() {
const [translate, setTranslate] = useState({x:0,y:0});
const containerRef = useCallback((containerElem) => {
if (containerElem !== null) {
const {width, height} = containerElem.getBoundingClientRect();
setTranslate({x: width/2, y: height/2});
}
}, []);
return [translate, containerRef];
}
export const HTree = withDynamicSchemaProps(({ collectionName, data }) => {
const nodeSize = { x: 500, y: 100 };
// const foreignObjectProps = { width: 220, height: nodeSize.y, x: -100, y: -30 };
// const className = styles.bluecard;
// const [translate, containerRef] = useCenteredTree();
return (
<div style={{ height: '100vh' }}>
<div>collection: {collectionName}</div>
<div>data list: <pre>{JSON.stringify(data, null, 2)}</pre></div>
{/* <Tree
nodeSize={nodeSize}
data={orgChart}
renderCustomNodeElement={(rd3tProps) =>
renderForeignObjectNode({ ...rd3tProps, foreignObjectProps, className })
}
/> */}
</div>
)
}, {displayName: BlockName});
schema/index.ts
import { useFieldSchema } from '@formily/react';
import { ISchema, useCollection, useDataBlockRequest } from '@nocobase/client';
import { HTreeProps } from '../component';
import { useT } from '../locale';
import { ActionName, BlockName, BlockNameLowercase } from '../constants';
import { documentActionSettings } from '../settings';
export function useHTreeProps(): HTreeProps {
const collection = useCollection();
const { data } = useDataBlockRequest<any[]>();
return {
collectionName: collection.name,
data: data?.data,
}
}
export function getHTreeSchema({ dataSource = 'main', collection }) {
return {
type: 'void',
'x-decorator': 'DataBlockProvider',
'x-decorator-props': {
dataSource, collection, action: 'list',
},
'x-component': 'CardItem',
'x-toolbar': 'BlockSchemaToolbar',
properties: {
[BlockNameLowercase]: {
type: 'void',
'x-component': BlockName,
'x-use-component-props': 'useHTreeProps'
}
}
}
}
index.tsx
import React, { Component } from 'react';
import { Link, Outlet, useLocation } from 'react-router-dom';
import { Application, ISchema, Plugin, SchemaComponent, SchemaSettingsModalItem, useSchemaSettings } from '@nocobase/client';
import { createDocumentActionSchema, getHTreeSchema, useDocumentActionProps, useHTreeProps } from './schema';
import { documentActionSettings } from './settings';
import { createDocumentActionInitializerItem } from './initializer';
import { HTree } from './component';
const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;
const Layout = () => {
return (
<div>
<div>
<Link to={'/'}>Home</Link>, <Link to={'/about'}>About</Link>
</div>
<div>
<Link to={'/admin'}>ADMIN PAGE</Link>
</div>
<div>
<Link to={'/admin/document-action-schema'}>Schema测试页面</Link>
</div>
<Outlet />
</div>
);
};
export class PluginHelloClient extends Plugin {
async afterAdd() {
// await this.app.pm.add()
}
async beforeLoad() { }
// You can get and modify the app instance here
async load() {
console.log(this.app);
this.app.addComponents({ HTree });
this.app.addScopes({ useHTreeProps });
this.app.router.add('tree-demo', {
path: '/admin/tree-demo',
// element: <HTree collectionName='test' data={[{id:1}, {id:2}]} />,
Component: () => {
return <>
<div style={{ marginTop: 20, marginBottom: 20 }}>
<SchemaComponent schema={{ properties: { test4: getHTreeSchema({ collection: 'airport' }) } }} />
</div>
<div style={{ marginTop: 20, marginBottom: 20 }}>
<SchemaComponent schema={{ properties: { test3: getHTreeSchema({ collection: 'users' }) } }} />
</div>
</>
}
});
}
}
export default PluginHelloClient;