From ad648431e99dfc345864733a823df7ee56b6df57 Mon Sep 17 00:00:00 2001 From: chenos Date: Fri, 11 Feb 2022 15:16:00 +0800 Subject: [PATCH] feat: add @nocobase/plugin-ui-routes-storage --- packages/api/src/index.ts | 1 + packages/app/src/pages/mock.ts | 9 +- .../src/collections/fields.ts | 1 + packages/plugin-ui-routes-storage/.npmignore | 7 + .../plugin-ui-routes-storage/package.json | 13 ++ .../src/actions/getAccessible.ts | 18 +++ .../src/collections/uiRoutes.ts | 42 ++++++ .../plugin-ui-routes-storage/src/index.ts | 136 ++++++++++++++++++ .../src/server-hooks/hooks/remove-schema.ts | 2 +- 9 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 packages/plugin-ui-routes-storage/.npmignore create mode 100644 packages/plugin-ui-routes-storage/package.json create mode 100644 packages/plugin-ui-routes-storage/src/actions/getAccessible.ts create mode 100644 packages/plugin-ui-routes-storage/src/collections/uiRoutes.ts create mode 100644 packages/plugin-ui-routes-storage/src/index.ts diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 4cfa666b4..2874dd8f6 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -57,6 +57,7 @@ const api = new Application({ api.plugin(require('@nocobase/plugin-collection-manager').default); api.plugin(require('@nocobase/plugin-ui-schema-storage').default); +api.plugin(require('@nocobase/plugin-ui-routes-storage').default); // api.plugin(require('@nocobase/plugin-acl')); if (process.argv.length < 3) { diff --git a/packages/app/src/pages/mock.ts b/packages/app/src/pages/mock.ts index 1cc54e16d..4399306d7 100644 --- a/packages/app/src/pages/mock.ts +++ b/packages/app/src/pages/mock.ts @@ -15,7 +15,7 @@ export default (apiClient: APIClient) => { }, }); - const jsonSchema = { + const jsonSchema: any = { qqzzjakwkwl: { name: 'qqzzjakwkwl', type: 'void', @@ -109,11 +109,12 @@ export default (apiClient: APIClient) => { }; mock.onGet(/\/ui_schemas\:getJsonSchema\/(\w+)/).reply(function (config) { - const name = config.url.split('/').pop(); - console.log(name); - if (jsonSchema[name]) { + const name = config?.url?.split('/')?.pop(); + + if (name && jsonSchema[name]) { return [200, { data: jsonSchema[name] }]; } + const response = { data: { type: 'void', diff --git a/packages/plugin-collection-manager/src/collections/fields.ts b/packages/plugin-collection-manager/src/collections/fields.ts index eada95a81..b4880b919 100644 --- a/packages/plugin-collection-manager/src/collections/fields.ts +++ b/packages/plugin-collection-manager/src/collections/fields.ts @@ -54,6 +54,7 @@ export default { type: 'belongsTo', name: 'uiSchema', target: 'ui_schemas', + foreignKey: 'uiSchemaUid' }, { type: 'json', diff --git a/packages/plugin-ui-routes-storage/.npmignore b/packages/plugin-ui-routes-storage/.npmignore new file mode 100644 index 000000000..461574b2f --- /dev/null +++ b/packages/plugin-ui-routes-storage/.npmignore @@ -0,0 +1,7 @@ +node_modules +*.log +docs +__tests__ +tsconfig.json +src +.fatherrc.ts \ No newline at end of file diff --git a/packages/plugin-ui-routes-storage/package.json b/packages/plugin-ui-routes-storage/package.json new file mode 100644 index 000000000..bcacd7a8b --- /dev/null +++ b/packages/plugin-ui-routes-storage/package.json @@ -0,0 +1,13 @@ +{ + "name": "@nocobase/plugin-ui-routes-storage", + "version": "0.5.0-alpha.38", + "main": "lib/index.js", + "license": "MIT", + "dependencies": { + "flat-to-nested": "^1.1.1" + }, + "devDependencies": { + "@nocobase/test": "^0.6.0-alpha.0" + }, + "gitHead": "e7df1f93c4e23b9a666d99ee7372c02bdaec97c4" +} diff --git a/packages/plugin-ui-routes-storage/src/actions/getAccessible.ts b/packages/plugin-ui-routes-storage/src/actions/getAccessible.ts new file mode 100644 index 000000000..314c780b6 --- /dev/null +++ b/packages/plugin-ui-routes-storage/src/actions/getAccessible.ts @@ -0,0 +1,18 @@ +import { Context, Next } from '@nocobase/actions'; +import FlatToNested from 'flat-to-nested'; + +const flatToNested = new FlatToNested({ + id: 'key', + parent: 'parentKey', + children: 'routes', +}); + +export const getAccessible = async (ctx: Context, next: Next) => { + const repository = ctx.db.getRepository('uiRoutes'); + const routes = await repository.find({ + sort: ['sort'], + }); + const data = flatToNested.convert(routes.map((route) => route.toJSON())); + ctx.body = data?.routes || []; + await next(); +}; diff --git a/packages/plugin-ui-routes-storage/src/collections/uiRoutes.ts b/packages/plugin-ui-routes-storage/src/collections/uiRoutes.ts new file mode 100644 index 000000000..5c15dabe3 --- /dev/null +++ b/packages/plugin-ui-routes-storage/src/collections/uiRoutes.ts @@ -0,0 +1,42 @@ +import { defineCollection } from '@nocobase/database'; + +export default defineCollection({ + name: 'uiRoutes', + title: '前端路由表', + model: 'MagicAttributeModel', + autoGenId: false, + sortable: { + name: 'sort', + scopeKey: 'parentKey', + }, + fields: [ + { + type: 'uid', + name: 'key', + prefix: 'r_', + primaryKey: true, + }, + { + type: 'string', + name: 'type', + }, + { + type: 'hasMany', + name: 'routes', + target: 'uiRoutes', + sourceKey: 'key', + foreignKey: 'parentKey', + }, + { + type: 'belongsTo', + name: 'uiSchema', + target: 'ui_schemas', + foreignKey: 'uiSchemaUid' + }, + { + type: 'json', + name: 'options', + defaultValue: {}, + }, + ], +}); diff --git a/packages/plugin-ui-routes-storage/src/index.ts b/packages/plugin-ui-routes-storage/src/index.ts new file mode 100644 index 000000000..f9de3d064 --- /dev/null +++ b/packages/plugin-ui-routes-storage/src/index.ts @@ -0,0 +1,136 @@ +import { MagicAttributeModel } from '@nocobase/database'; +import { Plugin } from '@nocobase/server'; +import { resolve } from 'path'; +import { getAccessible } from './actions/getAccessible'; + +export class UiRoutesStoragePlugin extends Plugin { + beforeLoad() { + this.app.on('installing', async () => { + const repository = this.app.db.getRepository('uiRoutes'); + const routes = [ + { + type: 'redirect', + from: '/', + to: '/admin', + exact: true, + }, + { + type: 'route', + uiSchema: { + type: 'void', + 'x-component': 'Menu', + 'x-component-props': { + mode: 'mix', + theme: 'dark', + // defaultSelectedUid: 'u8', + onSelect: '{{ onSelect }}', + sideMenuRefScopeKey: 'sideMenuRef', + }, + properties: { + item3: { + type: 'void', + title: 'SubMenu u3', + 'x-component': 'Menu.SubMenu', + 'x-component-props': {}, + properties: { + item6: { + type: 'void', + title: 'SubMenu u6', + 'x-component': 'Menu.SubMenu', + 'x-component-props': {}, + properties: { + item7: { + type: 'void', + title: 'Menu Item u7', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item8: { + type: 'void', + title: 'Menu Item u8', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + }, + }, + item4: { + type: 'void', + title: 'Menu Item u4', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item5: { + type: 'void', + title: 'Menu Item u5', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + }, + }, + item1: { + type: 'void', + title: 'Menu Item u1', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item2: { + type: 'void', + title: 'Menu Item u2', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item9: { + type: 'void', + title: 'SubMenu u9', + 'x-component': 'Menu.SubMenu', + 'x-component-props': {}, + properties: { + item10: { + type: 'void', + title: 'Menu Item u10', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + }, + }, + }, + }, + path: '/admin/:name(.+)?', + component: 'AdminLayout', + title: 'NocoBase Admin', + }, + { + type: 'route', + component: 'AuthLayout', + routes: [ + { + type: 'route', + path: '/signin', + component: 'SigninPage', + }, + { + type: 'route', + path: '/signup', + component: 'SignupPage', + }, + ], + }, + ]; + for (const values of routes) { + await repository.create({ + values, + }); + } + }); + } + + async load() { + this.app.resourcer.registerActionHandler('uiRoutes:getAccessible', getAccessible); + this.app.db.registerModels({ MagicAttributeModel }); + this.app.db.import({ + directory: resolve(__dirname, 'collections'), + }); + } +} + +export default UiRoutesStoragePlugin; diff --git a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts index 5fab3af3f..449f66e05 100644 --- a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts +++ b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts @@ -1,4 +1,4 @@ -import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage'; +import { UiSchemaRepository } from '../../'; export async function removeSchema({ schemaInstance, options, db, params }) { const { transaction } = options;