Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gi-sdk): slot-driven component tree rendering and global state management enhancements #542

Merged
merged 5 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
plugins: [
require.resolve('prettier-plugin-organize-imports'),
require.resolve('prettier-plugin-packagejson'),
],
printWidth: 120,
arrowParens: 'avoid',
proseWrap: 'never',
singleQuote: true,
trailingComma: 'all',
overrides: [
{
files: '*.md',
options: {
proseWrap: 'preserve',
},
},
],
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@
"eslint-plugin-jsdoc": "^48.2.7",
"husky": "^9.0.11",
"prettier": "^3.3.0",
"prettier-plugin-organize-imports": "^4.0.0",
"prettier-plugin-packagejson": "^2.5.1",
"typescript": "^5.3.3",
"vite": "^5.0.12"
},
"license": "MIT",

"commitlint": {
"extends": [
"@commitlint/config-conventional"
Expand Down
2 changes: 1 addition & 1 deletion packages/gi-sdk/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ dist
es
lib
node_modules
tests
tests
20 changes: 20 additions & 0 deletions packages/gi-sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<h1 align="center">GISDK</h1>

<div align="center">

SDK for Graph Insight App.

## 🔨 快速使用

```jsx | pure
import React from 'react';
import { GISDK } from '@antv/gi-sdk';
import { myAssetPackage } from './assets';
import { config } from './config';

export default () => {
const assets = [myAssetPackage];

return <GISDK className="my-graph-application" style={{ height: '80vh' }} config={config} assets={assets}></GISDK>;
};
```
32 changes: 32 additions & 0 deletions packages/gi-sdk/docs/assets/CustomCanvasComponent/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { CanvasEvent, NodeEvent } from '@antv/g6';
import type { ImplementWidgetProps } from '@antv/gi-sdk';
import { useGlobalModel, useGraph } from '@antv/gi-sdk';
import React, { useEffect } from 'react';

export const CustomCanvasComponent: React.FC<ImplementWidgetProps> = () => {
const [, setGlobalModel] = useGlobalModel();
const [graph] = useGraph();

useEffect(() => {
if (!graph || graph.destroyed) return;

const clickNode = (e) => {
const nodeId = e.target.id;
setGlobalModel({ currentNode: graph?.getNodeData(nodeId), panel: true });
};

const clickCanvas = () => {
setGlobalModel({ currentNode: null, panel: false });
};

graph.on(NodeEvent.CLICK, clickNode);
graph.on(CanvasEvent.CLICK, clickCanvas);

return () => {
graph.off(NodeEvent.CLICK, clickNode);
graph.off(CanvasEvent.CLICK, clickCanvas);
};
}, [graph]);

return null;
};
12 changes: 12 additions & 0 deletions packages/gi-sdk/docs/assets/CustomCanvasComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ImplementWidget, ImplementWidgetProps } from '@antv/gi-sdk';
import { CustomCanvasComponent as CustomCanvasComponent2 } from './Component';

export const CustomCanvasComponent: ImplementWidget<ImplementWidgetProps> = {
version: 'v0.1',
metadata: {
name: 'CustomCanvasComponent',
displayName: '自定义图表组件',
description: '这是一个自定义图表组件',
},
component: CustomCanvasComponent2,
};
24 changes: 24 additions & 0 deletions packages/gi-sdk/docs/assets/CustomPanel/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ImplementWidgetProps, useGlobalModel } from '@antv/gi-sdk';
import React from 'react';
import { fontStyle } from '../../constant';

export interface CustomPanelProps extends ImplementWidgetProps {
count: number;
}

export const CustomPanel: React.FC<CustomPanelProps> = (props) => {
const { count } = props;
const [{ currentNode }] = useGlobalModel();

const isSiderOpen = true;

return (
<div>
<p style={fontStyle}>{count}...</p>
<p>Sider {isSiderOpen ? <b style={fontStyle}>opened</b> : <b style={fontStyle}>closed</b>}</p>
<p>
current node: <b style={fontStyle}>{currentNode?.id}</b>
</p>
</div>
);
};
16 changes: 16 additions & 0 deletions packages/gi-sdk/docs/assets/CustomPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { ImplementWidget } from '@antv/gi-sdk';
import type { CustomPanelProps } from './Component';
import { CustomPanel as CustomPanelComponent } from './Component';

export const CustomPanel: ImplementWidget<CustomPanelProps> = {
version: 'v0.1',
metadata: {
name: 'CustomPanel',
displayName: '自定义面板',
description: '这是一个自定义面板',
},
component: CustomPanelComponent,
defaultProperties: {
count: 200,
},
};
41 changes: 41 additions & 0 deletions packages/gi-sdk/docs/assets/CustomSiderbar/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { ImplementWidgetProps } from '@antv/gi-sdk';
import { useGlobalModel, useGraphOptions, useWidgetProps } from '@antv/gi-sdk';
import { Button } from 'antd';
import React from 'react';
import { fontStyle } from '../../constant';

export const CustomSidebar: React.FC<ImplementWidgetProps> = (props) => {
const { slotElements } = props;
const [{ panel }, setGlobalModel] = useGlobalModel();
const [, updatePanelProperties] = useWidgetProps('custom-panel');
const [, updateOptions] = useGraphOptions();

const openPanel = () => {
setGlobalModel({ panel: true });
};

return (
<div>
<p>Sider</p>
<p>
Panel <b style={fontStyle}>{panel ? 'opened' : 'closed'}</b>
</p>
<Button onClick={openPanel}>Open Panel</Button>
<Button
onClick={() => {
updatePanelProperties({ count: Math.floor(Math.random() * 1000) });
}}
>
Change panel Count
</Button>
<b style={fontStyle}>{slotElements.default}</b>
<Button
onClick={() => {
updateOptions((options) => ({ ...options, layout: { type: 'dagre' } }));
}}
>
Change Layout
</Button>
</div>
);
};
12 changes: 12 additions & 0 deletions packages/gi-sdk/docs/assets/CustomSiderbar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ImplementWidget, ImplementWidgetProps } from '@antv/gi-sdk';
import { CustomSidebar as CustomSidebarComponent } from './Component';

export const CustomSidebar: ImplementWidget<ImplementWidgetProps> = {
version: 'v0.1',
metadata: {
name: 'CustomSidebar',
displayName: '自定义右侧栏',
description: '这是一个自定义右侧栏',
},
component: CustomSidebarComponent,
};
Empty file.
27 changes: 27 additions & 0 deletions packages/gi-sdk/docs/assets/MyAppLayout/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { GraphContainer, type ImplementWidgetProps } from '@antv/gi-sdk';
import React from 'react';
import { PREFIX } from '../../constant';
import { Header, Panel, Sider } from './components';

type Slot = 'header' | 'sider' | 'panel' | 'canvas';

export interface MyAppLayoutProps extends ImplementWidgetProps<Slot> {
showHeader: boolean;
}

export const MyAppLayout: React.FC<MyAppLayoutProps> = (props) => {
const { slotElements, showHeader } = props;

return (
<div className={`${PREFIX}-container`}>
{showHeader && <Header>{slotElements.header}</Header>}
<div className={`${PREFIX}-content`}>
<Sider>{slotElements.sider}</Sider>
<div className={`${PREFIX}-graph-container`}>
<GraphContainer>{slotElements.canvas}</GraphContainer>
</div>
<Panel>{slotElements.panel}</Panel>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../../global.less';
@import '../../../../global.less';

.@{prefix}-header {
height: var(--header-height);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { PropsWithChildren } from 'react';
import { PREFIX } from '../../constants';
import { PREFIX } from '../../../../constant';
import './index.less';

export const Header: React.FC<PropsWithChildren> = props => {
export const Header: React.FC<PropsWithChildren> = (props) => {
const { children } = props;

return <div className={`${PREFIX}-header`}>{children}</div>;
Expand Down
3 changes: 3 additions & 0 deletions packages/gi-sdk/docs/assets/MyAppLayout/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { Header } from './header';
export { Panel } from './panel';
export { Sider } from './sider';
21 changes: 21 additions & 0 deletions packages/gi-sdk/docs/assets/MyAppLayout/components/panel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useGlobalModel } from '@antv/gi-sdk';
import { Drawer } from 'antd';
import React, { PropsWithChildren } from 'react';
import { PREFIX } from '../../../../constant';

export const Panel: React.FC<PropsWithChildren> = (props) => {
const { children } = props;
const [{ panel }, updateGlobalModel] = useGlobalModel();

const onClose = () => {
updateGlobalModel({ panel: false });
};

return (
<div className={`${PREFIX}-panel`}>
<Drawer placement="right" onClose={onClose} open={panel} getContainer={false}>
{children}
</Drawer>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../../global.less';
@import '../../../../global.less';

.@{prefix}-sider {
display: flex;
Expand All @@ -11,7 +11,7 @@
height: 100%;
border-right: 1px solid var(--border-color);
}

.@{prefix}-sider-icon {
position: absolute;
width: 24px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React, { PropsWithChildren } from 'react';
import { DoubleLeftOutlined, DoubleRightOutlined } from '@ant-design/icons';
import { useGlobalModel } from '@antv/gi-sdk';
import React, { PropsWithChildren } from 'react';
import { CSSTransition } from 'react-transition-group';
import { PREFIX } from '../../constants';
import { useGlobalModel } from '../../context';
import { PREFIX } from '../../../../constant';
import './index.less';

export const Sider: React.FC<PropsWithChildren> = props => {
export const Sider: React.FC<PropsWithChildren> = (props) => {
const { children } = props;
const [globalModel, updateGlobalModel] = useGlobalModel();
const isSiderOpen = Boolean(globalModel.sider);
const [{ sider }, updateGlobalModel] = useGlobalModel();

return (
<React.Fragment>
Expand All @@ -17,13 +16,13 @@ export const Sider: React.FC<PropsWithChildren> = props => {
<div
className={`${PREFIX}-sider-icon`}
onClick={() => {
updateGlobalModel({ sider: !globalModel.sider });
updateGlobalModel({ sider: !sider });
}}
>
{isSiderOpen ? <DoubleLeftOutlined /> : <DoubleRightOutlined />}
{sider ? <DoubleLeftOutlined /> : <DoubleRightOutlined />}
</div>
</div>
<CSSTransition in={isSiderOpen} classNames="fade" timeout={400}>
<CSSTransition in={sider} classNames="fade" timeout={400}>
<div className={`${PREFIX}-sider-content`}>{children}</div>
</CSSTransition>
</div>
Expand Down
16 changes: 16 additions & 0 deletions packages/gi-sdk/docs/assets/MyAppLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { ImplementWidget } from '@antv/gi-sdk';
import type { MyAppLayoutProps } from './Component';
import { MyAppLayout as MyAppLayoutComponent } from './Component';

export const MyAppLayout: ImplementWidget<MyAppLayoutProps> = {
version: 'v0.1',
metadata: {
name: 'MyAppLayout',
displayName: '我的布局组件',
description: '这是一个布局组件',
},
component: MyAppLayoutComponent,
defaultProperties: {
showHeader: true,
},
};
43 changes: 43 additions & 0 deletions packages/gi-sdk/docs/assets/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { ImplementWidgetProps } from '@antv/gi-sdk';
import { AssetPackage, ImplementWidget } from '@antv/gi-sdk';
import React from 'react';
import { CustomCanvasComponent } from './CustomCanvasComponent';
import { CustomPanel } from './CustomPanel';
import { CustomSidebar } from './CustomSiderbar';
import { MyAppLayout } from './MyAppLayout';

export const CustomHeader: ImplementWidget<ImplementWidgetProps> = {
version: 'v0.1',
metadata: {
name: 'CustomHeader',
displayName: '自定义头部',
description: '这是一个自定义头部',
},
component: () => {
return <h1 style={{ height: 48, lineHeight: '48px', textAlign: 'center' }}>GI-SDK</h1>;
},
};

export const StatisticCard: ImplementWidget = {
version: 'v0.1',
metadata: {
name: 'StatisticCard',
displayName: '统计卡片',
description: '用于展示统计数据的卡片',
},
component: () => {
return <div>StatisticCard</div>;
},
};

export const myAssetPackage: AssetPackage = {
version: 'v0.1',
widgets: [
MyAppLayout,
CustomCanvasComponent,
CustomHeader,
CustomPanel,
CustomSidebar,
StatisticCard,
] as ImplementWidget<ImplementWidgetProps>[],
};
Loading