diff --git a/.github/workflows/deploy-client-docs.yml b/.github/workflows/deploy-client-docs.yml
new file mode 100644
index 000000000..cb1a4991f
--- /dev/null
+++ b/.github/workflows/deploy-client-docs.yml
@@ -0,0 +1,23 @@
+name: deploy client docs
+on: [push]
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: "18"
+ - run: yarn install
+ - name: Build
+ run: yarn doc build core/client
+ - name: copy files via ssh
+ uses: appleboy/scp-action@v0.1.4
+ with:
+ host: ${{ secrets.CN_CLIENT_HOST }}
+ username: ${{ secrets.CN_CLIENT_USERNAME }}
+ key: ${{ secrets.CN_CLIENT_KEY }}
+ port: ${{ secrets.CN_CLIENT_PORT }}
+ source: "packages/core/client/dist/*"
+ target: ${{ secrets.CN_CLIENT_TARGET }}/${{ github.ref_name }}
diff --git a/packages/core/client/.dumirc.ts b/packages/core/client/.dumirc.ts
index 18cf515ab..7be56e346 100644
--- a/packages/core/client/.dumirc.ts
+++ b/packages/core/client/.dumirc.ts
@@ -1,18 +1,6 @@
-import { defineConfig } from 'dumi';
-import { defineThemeConfig } from 'dumi-theme-nocobase'
import { getUmiConfig } from '@nocobase/devtools/umiConfig';
-import fs from 'fs';
-import path from 'path';
-
-const contributingPath = path.resolve(__dirname, './contributing.md');
-const docsContributingPath = path.resolve(__dirname, './docs/contributing.md');
-
-// check if the target path already exists, and remove it if it does
-if (fs.existsSync(docsContributingPath)) {
- fs.unlinkSync(docsContributingPath);
-}
-
-fs.copyFileSync(contributingPath, docsContributingPath);
+import { defineConfig } from 'dumi';
+import { defineThemeConfig } from 'dumi-theme-nocobase';
const umiConfig = getUmiConfig();
@@ -23,34 +11,106 @@ export default defineConfig({
},
resolve: {
atomDirs: [
- { type: 'component', dir: 'src' },
- { type: 'component', dir: 'src/schema-component/antd' },
- { type: 'component', dir: 'src/route-switch/antd' },
- ]
+ { type: 'api', dir: 'src' },
+ { type: 'api', dir: 'src/schema-component/antd' },
+ { type: 'api', dir: 'src/route-switch/antd' },
+ ],
},
themeConfig: defineThemeConfig({
title: 'NocoBase',
logo: 'https://www.nocobase.com/images/logo.png',
github: 'https://github.com/nocobase/nocobase',
footer: 'nocobase | Copyright © 2022',
- sidebarGroupModePath: ['/components'],
+ // sidebarGroupModePath: ['/components'],
nav: [
{
- title: 'Intro',
- link: '/intro',
+ title: 'API',
+ link: '/apis/application',
},
- {
- title: 'Client',
- link: '/components/acl',
- },
- {
- title: 'Develop',
- link: '/develop',
- },
- {
- title: 'Contributing',
- link: '/contributing',
- }
- ]
- })
+ ],
+ sidebarEnhance: {
+ '/apis': [
+ {
+ title: 'Core',
+ type: 'group',
+ children: [
+ {
+ title: 'Application',
+ children: [
+ {
+ title: 'Application',
+ link: '/apis/application',
+ },
+ {
+ title: 'APIClient',
+ link: '/apis/api-client',
+ },
+ {
+ title: 'SettingsCenter',
+ link: '#',
+ },
+ ],
+ },
+ {
+ title: 'UI schema designer',
+ children: [
+ {
+ title: 'SchemaComponent',
+ link: '#',
+ },
+ {
+ title: 'SchemaInitializer',
+ link: '#',
+ },
+ {
+ title: 'SchemaSettings',
+ link: '#',
+ },
+ {
+ title: 'DNDContext & DragHandler',
+ link: '#',
+ },
+ ],
+ },
+ {
+ title: 'Collection Manager',
+ link: '#',
+ },
+ {
+ title: 'BlockProvider',
+ link: '#',
+ },
+ {
+ title: 'RecordProvider',
+ link: '#',
+ },
+ ],
+ },
+ {
+ title: 'React components',
+ type: 'group',
+ children: [
+ {
+ title: 'Board',
+ link: '#',
+ },
+ {
+ title: 'Icon',
+ link: '#',
+ },
+ ],
+ },
+ {
+ title: 'Schema components',
+ type: 'group',
+ children: [
+ {
+ title: 'Input',
+ link: '#',
+ },
+ ],
+ },
+ ],
+ },
+ }),
});
diff --git a/packages/core/client/contributing.md b/packages/core/client/contributing.md
deleted file mode 100644
index 1f4f1b8a1..000000000
--- a/packages/core/client/contributing.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-toc: menu
----
-
-# 参与贡献
-
-客户端的模块都在 `src` 目录下,各自模块独立。
-
-## 客户端模块
-
-最小单元模块化,一个完整的模块包含:
-
-```bash
-|- /__tests__/ # 测试文件目录
-|- /demos/ # demo 目录
-|- index.ts # 最好不要直接在 index.ts 文件里写代码,index 文件只负责 export
-|- index.md # 文档,默认为英文
-|- index.zh-CN.md # 中文文档,可缺失,可以先都写到 index.md 里
-```
-
-## 测试
-
-详细文档见 [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/)
-
-```tsx | pure
-import React from 'react';
-import { render } from '@testing-library/react';
-import { compose } from '../';
-
-describe('compose', () => {
- it('case 1', () => {
- const A: React.FC = (props) => (
-
-
A
- {props.children}
-
- );
- const App = compose(A)();
- const { container } = render();
- expect(container).toMatchSnapshot();
- });
-});
-```
-
-## Demo
-
-组件 Demo 见 [dumi](https://d.umijs.org/guide/basic#write-component-demo),可以直接写在文档里,如:
-
-
-```jsx
-import React from 'react';
-
-export default () => Hello NocoBase!
;
-```
-
-
-也可以引用 demo 文件
-
-```markdown
-
-```
diff --git a/packages/core/client/docs/index.md b/packages/core/client/docs/index.md
new file mode 100644
index 000000000..bc0930d2d
--- /dev/null
+++ b/packages/core/client/docs/index.md
@@ -0,0 +1 @@
+
diff --git a/packages/core/client/src/acl/index.md b/packages/core/client/src/acl/index.md
deleted file mode 100644
index 4de99929a..000000000
--- a/packages/core/client/src/acl/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-group:
- title: Client
- order: 1
----
-
-# ACL
-
-访问控制列表,plugin-acl 的前端模块,详细文档待补充。
diff --git a/packages/core/client/src/antd-config-provider/demos/demo1.tsx b/packages/core/client/src/antd-config-provider/demos/demo1.tsx
deleted file mode 100644
index dd79a424e..000000000
--- a/packages/core/client/src/antd-config-provider/demos/demo1.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from 'react';
-import { Table } from 'antd';
-import { i18n, compose, APIClient, APIClientProvider, AntdConfigProvider } from '@nocobase/client';
-import MockAdapter from 'axios-mock-adapter';
-import { I18nextProvider } from 'react-i18next';
-
-const apiClient = new APIClient({
- baseURL: `${location.protocol}//${location.host}/api/`,
-});
-
-const mock = new MockAdapter(apiClient.axios);
-
-mock.onGet('/app:getLang').reply(200, {
- data: { lang: 'zh-CN' },
-});
-
-const providers = [
- [APIClientProvider, { apiClient }],
- [I18nextProvider, { i18n }],
- [AntdConfigProvider, { remoteLocale: true }],
-];
-
-export default compose(...providers)(() => {
- return ;
-});
diff --git a/packages/core/client/src/antd-config-provider/index.md b/packages/core/client/src/antd-config-provider/index.md
deleted file mode 100644
index f773165e6..000000000
--- a/packages/core/client/src/antd-config-provider/index.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-group:
- title: Client
- order: 1
----
-
-# AntdConfigProvider
-
-为 antd 组件提供统一的全局化配置
-
-
diff --git a/packages/core/client/src/appInfo/index.md b/packages/core/client/src/appInfo/index.md
new file mode 100644
index 000000000..4f297ea84
--- /dev/null
+++ b/packages/core/client/src/appInfo/index.md
@@ -0,0 +1 @@
+# AppInfo
\ No newline at end of file
diff --git a/packages/core/client/src/application/demos/demo1.tsx b/packages/core/client/src/application/demos/demo1.tsx
index 722e5f9d2..e724d1201 100644
--- a/packages/core/client/src/application/demos/demo1.tsx
+++ b/packages/core/client/src/application/demos/demo1.tsx
@@ -1,7 +1,6 @@
+import { Application, Plugin } from '@nocobase/client';
import React, { FC } from 'react';
import { Link, Outlet, useLocation } from 'react-router-dom';
-import { Application } from '../Application';
-import { Plugin } from '../Plugin';
const Root = () => {
return (
diff --git a/packages/core/client/src/application/demos/demo2.tsx b/packages/core/client/src/application/demos/demo2.tsx
index e68cac3f3..50f7a816b 100644
--- a/packages/core/client/src/application/demos/demo2.tsx
+++ b/packages/core/client/src/application/demos/demo2.tsx
@@ -1,9 +1,6 @@
+import { Application, Plugin, RouterManager, useApp } from '@nocobase/client';
import React, { useMemo } from 'react';
import { Link, Navigate, Outlet, useParams } from 'react-router-dom';
-import { Application } from '../Application';
-import { useApp } from '../hooks';
-import { Plugin } from '../Plugin';
-import { RouterManager } from '../RouterManager';
const Root = () => {
return (
diff --git a/packages/core/client/src/application/index.md b/packages/core/client/src/application/index.md
index 27f9d321f..b6677d9e3 100644
--- a/packages/core/client/src/application/index.md
+++ b/packages/core/client/src/application/index.md
@@ -1,6 +1,6 @@
---
group:
- title: Client
+ title: core
order: 1
---
diff --git a/packages/core/client/src/async-data-provider/demos/demo1.tsx b/packages/core/client/src/async-data-provider/demos/demo1.tsx
deleted file mode 100644
index f8c2dc224..000000000
--- a/packages/core/client/src/async-data-provider/demos/demo1.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import React, { createContext, useContext } from 'react';
-import MockAdapter from 'axios-mock-adapter';
-import { APIClient, APIClientProvider, compose, AsyncDataProvider, useAsyncData } from '@nocobase/client';
-
-const apiClient = new APIClient();
-
-const mock = new MockAdapter(apiClient.axios);
-
-mock.onGet('/users/1').reply(200, {
- data: { id: 1, name: 'John Smith' },
-});
-
-const providers = [
- [APIClientProvider, { apiClient }],
- [AsyncDataProvider, { request: { url: '/users/1' } }],
-];
-
-export default compose(...providers)(() => {
- const { data } = useAsyncData();
- console.log(data);
- return {data?.data?.name}
;
-});
diff --git a/packages/core/client/src/async-data-provider/demos/demo2.tsx b/packages/core/client/src/async-data-provider/demos/demo2.tsx
deleted file mode 100644
index 7e1938e19..000000000
--- a/packages/core/client/src/async-data-provider/demos/demo2.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { APIClient, APIClientProvider, SchemaComponent, SchemaComponentProvider, useRequest } from '@nocobase/client';
-import { Table } from 'antd';
-import MockAdapter from 'axios-mock-adapter';
-import React from 'react';
-
-const apiClient = new APIClient();
-
-const mock = new MockAdapter(apiClient.axios);
-
-mock.onGet('/users').reply(200, {
- data: [
- { id: 1, name: 'John Smith' },
- { id: 2, name: 'Mike' },
- ],
-});
-
-const TableView = (props) => {
- const { request, ...others } = props;
- const callback = () => props.dataSource || [];
- const { data, loading } = useRequest<{
- data: any;
- }>(props.request || callback);
- return ;
-};
-
-export default () => {
- return (
-
-
-
-
-
- );
-};
diff --git a/packages/core/client/src/async-data-provider/demos/demo3.tsx b/packages/core/client/src/async-data-provider/demos/demo3.tsx
deleted file mode 100644
index b35ad6ba0..000000000
--- a/packages/core/client/src/async-data-provider/demos/demo3.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import {
- APIClient,
- APIClientProvider,
- AsyncDataProvider,
- SchemaComponent,
- SchemaComponentProvider,
- useAsyncData,
-} from '@nocobase/client';
-import { Table } from 'antd';
-import MockAdapter from 'axios-mock-adapter';
-import React from 'react';
-
-const apiClient = new APIClient();
-
-const mock = new MockAdapter(apiClient.axios);
-
-mock.onGet('/users').reply(200, {
- data: [
- { id: 1, name: 'John Smith' },
- { id: 2, name: 'Mike' },
- ],
-});
-
-const TableView = (props) => {
- const { data, loading } = useAsyncData();
- return ;
-};
-
-const AsyncDataTableView = (props) => {
- const { request, ...others } = props;
- return (
-
-
-
- );
-};
-
-export default () => {
- return (
-
-
-
-
-
- );
-};
diff --git a/packages/core/client/src/async-data-provider/index.md b/packages/core/client/src/async-data-provider/index.md
deleted file mode 100644
index 1b10926d5..000000000
--- a/packages/core/client/src/async-data-provider/index.md
+++ /dev/null
@@ -1,154 +0,0 @@
----
-group:
- title: Client
- order: 1
----
-
-# AsyncDataProvider
-
-利用 Formily 提供的 [Effect Hooks](https://core.formilyjs.org/zh-CN/api/entry/form-effect-hooks) 或 [x-reactions](https://react.formilyjs.org/zh-CN/api/shared/schema#schemareactions) 协议能一定程度的解决某些场景的异步数据源问题,但是如果只用来处理异步请求,并不会很好用,而且局限于 Formily 体系内。为了更灵活的处理异步请求的各种需求,NocoBase 提供了非常好用的可配置化的 [useRequest()](api-client#userequest),用于配置各种异步请求。与此同时,又提供了 `` 组件,可以将请求结果共享给子组件,方便处理其他更复杂的需求。以平时最常见,但却可能非常复杂的表格为例。表格的使用场景有:
-
-- TableView 只作为表格视图
-- RowSelection 动态数据的勾选项
-- TableField 表格字段
-
-各自的 schema 可以这么表示:
-
-```js
-// 表格视图,type 为 void,无 default 默认值,无 field.value,
-// dataSource 直接写在组件的 props 里
-{
- type: 'void',
- 'x-component': 'TableView',
- 'x-component-props': {
- columns: [
- {
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- },
- ],
- dataSource: [
- { id: 1, name: 'Name1' },
- { id: 2, name: 'Name2' },
- ],
- },
-}
-
-// 单选(表格视图),类似于 Radio.Group 字段,可选项由表格视图提供
-{
- type: 'number',
- 'x-component': 'RowSelection',
- 'x-component-props': {
- rowSelection: {
- type: 'radio',
- },
- columns: [
- {
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- },
- ],
- dataSource: [
- { id: 1, name: 'Name1' },
- { id: 2, name: 'Name2' },
- ],
- },
- default: 1,
-}
-
-// 多选(表格视图),类似于 Checkbox.Group 字段,可选项由表格视图提供
-{
- type: 'array',
- 'x-component': 'RowSelection',
- 'x-component-props': {
- rowSelection: {
- type: 'checkbox',
- },
- columns: [
- {
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- },
- ],
- dataSource: [
- { id: 1, name: 'Name1' },
- { id: 2, name: 'Name2' },
- ],
- },
- default: [1],
-}
-
-// 表格字段,数据由表单提供,schema 层面可以配置默认值
-// 与表格视图的方式不同,dataSource 和 columns 不适合直接配置在 x-component-props 里,怎么处理先忽略。
-{
- type: 'array',
- 'x-component': 'TableField',
- 'x-component-props': {},
- default: [
- { id: 1, name: 'Name1' },
- { id: 2, name: 'Name2' },
- ],
-}
-```
-
-大多数实际应用中,表格视图的 dataSource 是异步获取的,可能也需要过滤和分页,这样一来直接在 x-component-props 里写 dataSource 并不合适。为了解决这个问题,可以给组件扩展一个 request 属性,用于请求远程数据,例子如下:
-
-
-
-上述例子的 `` 组件就是一个 React Component,可以正常使用,而不局限于 SchemaComponent 场景。更进一步,为了处理过滤表单、分页等问题,建议将 request 通过 `` 共享给 `` 组件。
-
-```tsx | pure
-const result = useRequest(props.request);
-
-
-
-```
-
-或者直接将 request 交给 AsyncDataProvider
-
-```tsx | pure
-
-
-
-```
-
-在 `` 的子组件里就可以通过 `useAsyncData()` 来获取 result,可用于处理过滤、分页等。
-
-```ts
-const { data, loading, params, run, refresh, parent } = useAsyncData();
-```
-
-转化为 Schema 时,可以将 AsyncDataProvider 放在 `x-decorator` 里,也可以将重新组合的 AsyncDataProvider + TableView,放在 `x-component` 里。
-
-
-
-将 AsyncDataProvider 独立出来,放到 x-decorator 里的另一个好处,例子如下:
-
-```tsx | pure
-
- {/* 从 CollectionProvider 里获取资源请求参数,并将请求结果同时共享给 DesignableBar 和 TableView */}
-
-
-
-
-
- {/* 从 CollectionFieldProvider 里获取关系资源请求参数,并将请求结果同时共享给子组件 */}
-
- {/* 组件 */}
-
-
-
-
-
-
-```
-
-上面例子嵌套了两层 AsyncDataProvider,在子 AsyncDataProvider 里,也可以获取到更上一级的请求结果,如:
-
-```ts
-const { parent } = useAsyncData();
-parent.refresh();
-```
diff --git a/packages/core/client/src/block-provider/index.md b/packages/core/client/src/block-provider/index.md
new file mode 100644
index 000000000..a277e3d54
--- /dev/null
+++ b/packages/core/client/src/block-provider/index.md
@@ -0,0 +1 @@
+# BlockProvider
\ No newline at end of file
diff --git a/packages/core/client/src/i18n/index.md b/packages/core/client/src/i18n/index.md
deleted file mode 100644
index d2fc8b50c..000000000
--- a/packages/core/client/src/i18n/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-group:
- title: Client
- order: 1
----
-
-# I18n
-
-提供国际化解决方案。
diff --git a/packages/core/client/src/route-switch/antd/admin-layout/index.md b/packages/core/client/src/route-switch/antd/admin-layout/index.md
deleted file mode 100644
index 9f7fbeb31..000000000
--- a/packages/core/client/src/route-switch/antd/admin-layout/index.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-group:
- title: Route Components
- order: 2
----
-
-# AdminLayout 待定
-
-结构
-
-- Layout
-- Layout.Header
- - SiteTitle
- - Menu(SchemaComponent)
- - PluginManager.Toolbar
- - DesignableAction
- - CollectionManager.Action
- - ACL.Action
- - SystemSettings.Action
- - CurrentUser.Dropdown
-- Layout.Sider
- - SideMenu(随 Menu 联动的)
-- Layout.Content
- - PageTitle
- - SchemaComponent
diff --git a/packages/core/client/src/route-switch/antd/auth-layout/index.md b/packages/core/client/src/route-switch/antd/auth-layout/index.md
deleted file mode 100644
index ddbd32856..000000000
--- a/packages/core/client/src/route-switch/antd/auth-layout/index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-group:
- title: Route Components
- order: 2
----
-
-# AuthLayout
-
diff --git a/packages/core/client/src/schema-settings/index.md b/packages/core/client/src/schema-settings/index.md
new file mode 100644
index 000000000..a7700ee3c
--- /dev/null
+++ b/packages/core/client/src/schema-settings/index.md
@@ -0,0 +1 @@
+# SchemaSettings
\ No newline at end of file
diff --git a/packages/core/client/src/system-settings/demos/demo1.tsx b/packages/core/client/src/system-settings/demos/demo1.tsx
deleted file mode 100644
index a4bec09ff..000000000
--- a/packages/core/client/src/system-settings/demos/demo1.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import {
- AntdSchemaComponentProvider,
- APIClient,
- APIClientProvider,
- SchemaComponentProvider,
- SystemSettingsProvider,
- useSystemSettings,
-} from '@nocobase/client';
-import MockAdapter from 'axios-mock-adapter';
-import React from 'react';
-
-const apiClient = new APIClient();
-
-const mock = new MockAdapter(apiClient.axios);
-
-mock.onGet('/systemSettings:get/1').reply(200, {
- data: {
- title: 'NocoBase',
- },
-});
-
-const Demo = () => {
- const { data } = useSystemSettings();
- return (
-
-
以下为测试内容
- System title: {data?.data?.title}
-
- );
-};
-
-export default () => {
- return (
-
-
-
-
-
-
-
-
-
- );
-};
diff --git a/packages/core/client/src/system-settings/index.md b/packages/core/client/src/system-settings/index.md
deleted file mode 100644
index bca6a4e9b..000000000
--- a/packages/core/client/src/system-settings/index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-group:
- title: Client
- order: 1
----
-
-# SystemSettings
-
-## SystemSettingsProvider
-
-## SystemSettingsShortcut
-
-## useSystemSettings
-
-```ts
-const { data, loading, refresh } = useSystemSettings();
-```
-
-## Examples
-
-