diff --git a/.gitignore b/.gitignore index 0b36a1d7c..442d4de10 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ lib/ .DS_Store package-lock.json yarn.lock +!/yarn.lock yarn-error.log lerna-debug.log packages/database/package-lock.json diff --git a/package.json b/package.json index ae4ac7777..414129944 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,7 @@ "start:app:server": "cd packages/app && nodemon", "start-server": "yarn nodemon", "bootstrap": "lerna bootstrap --no-ci", - "build": "npm run build-father-build && node packages/father-build/bin/father-build.js", - "build-father-build": "cd packages/father-build && npm run build", + "build": "father-build", "clean": "lerna clean", "db:start": "docker-compose up -d", "lint": "eslint --ext .ts,.tsx,.js \"packages/*/src/**.@(ts|tsx|js)\" --fix", @@ -36,7 +35,7 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", - "father-build": "^1.18.5", + "father-build": "^1.19.2", "jest": "^26.1.0", "koa": "^2.13.0", "koa-bodyparser": "^4.3.0", diff --git a/packages/actions/package.json b/packages/actions/package.json index 76af01999..514277bfc 100644 --- a/packages/actions/package.json +++ b/packages/actions/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/actions", - "version": "0.3.0-alpha.0", + "version": "0.4.0-alpha.0", "description": "", "main": "./lib/index.js", "types": "./lib/index.d.ts", @@ -8,8 +8,8 @@ }, "license": "MIT", "dependencies": { - "@nocobase/database": "^0.3.0-alpha.0", - "@nocobase/resourcer": "^0.3.0-alpha.0" + "@nocobase/database": "^0.4.0-alpha.0", + "@nocobase/resourcer": "^0.4.0-alpha.0" }, "devDependencies": { "koa": "^2.13.0", diff --git a/packages/actions/src/actions/common.ts b/packages/actions/src/actions/common.ts index 747bee9eb..22c794920 100644 --- a/packages/actions/src/actions/common.ts +++ b/packages/actions/src/actions/common.ts @@ -286,6 +286,7 @@ export async function get(ctx: Context, next: Next) { resourceKeyAttribute, fields = [] } = ctx.action.params; + console.log({associated, resourceField}) if (associated && resourceField) { const AssociatedModel = ctx.db.getModel(associatedName); if (!(associated instanceof AssociatedModel)) { @@ -297,7 +298,16 @@ export async function get(ctx: Context, next: Next) { fields, }); if (resourceField instanceof HASONE || resourceField instanceof BELONGSTO) { - const model: Model = await associated[getAccessor]({ ...options, context: ctx }); + let model: Model = await associated[getAccessor]({ context: ctx }); + if (model) { + model = await TargetModel.findOne({ + ...options, + context: ctx, + where: { + [TargetModel.primaryKeyAttribute]: model[TargetModel.primaryKeyAttribute], + }, + }); + } ctx.body = model; } else if (resourceField instanceof HASMANY || resourceField instanceof BELONGSTOMANY) { const [model]: Model[] = await associated[getAccessor]({ diff --git a/packages/app/package.json b/packages/app/package.json index ab5bea1b7..b9dec4ed6 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,12 +1,12 @@ { "name": "@nocobase/app", - "version": "0.3.0-alpha.0", + "version": "0.4.0-alpha.0", "private": true, "scripts": { "start": "concurrently \"nodemon\" \"umi dev\"", "start-api": "nodemon", "db-migrate": "ts-node ./src/api/migrate.ts", - "build": "father-build && umi build", + "build": "umi build", "postinstall": "umi generate tmp", "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", "test": "umi-test", @@ -26,18 +26,18 @@ "dependencies": { "@ant-design/pro-layout": "^5.0.12", "@formily/antd-components": "^1.3.6", - "@nocobase/client": "^0.3.0-alpha.0", - "@nocobase/database": "^0.3.0-alpha.0", - "@nocobase/father-build": "^0.3.0-alpha.0", - "@nocobase/plugin-action-logs": "^0.3.0-alpha.0", - "@nocobase/plugin-china-region": "^0.3.0-alpha.0", - "@nocobase/plugin-collections": "^0.3.0-alpha.0", - "@nocobase/plugin-pages": "^0.3.0-alpha.0", - "@nocobase/server": "^0.3.0-alpha.0", + "@nocobase/client": "^0.4.0-alpha.0", + "@nocobase/database": "^0.4.0-alpha.0", + "@nocobase/plugin-action-logs": "^0.4.0-alpha.0", + "@nocobase/plugin-china-region": "^0.4.0-alpha.0", + "@nocobase/plugin-collections": "^0.4.0-alpha.0", + "@nocobase/plugin-pages": "^0.4.0-alpha.0", + "@nocobase/server": "^0.4.0-alpha.0", "@types/react-big-calendar": "^0.24.8", "@umijs/preset-react": "1.x", "@umijs/test": "^3.2.23", "ahooks": "^2.9.3", + "antd": "^4.13.0", "array-move": "^3.0.1", "clean-deep": "^3.4.0", "concurrently": "^5.3.0", @@ -48,6 +48,7 @@ "react": "16.14.0", "react-big-calendar": "^0.30.0", "react-dom": "16.14.0", + "react-drag-listview": "^0.1.8", "react-image-lightbox": "^5.1.1", "react-sortable-hoc": "^1.11.0", "styled-components": "^5.2.1", diff --git a/packages/app/src/api-client.ts b/packages/app/src/api-client.ts index e9848e2d6..145b4d397 100644 --- a/packages/app/src/api-client.ts +++ b/packages/app/src/api-client.ts @@ -40,6 +40,7 @@ class ApiClient { options.params = restParams; } else { options.method = 'post'; + options.params = restParams; options.data = values; } if (associatedKey) { diff --git a/packages/app/src/api/migrations/add-menus.ts b/packages/app/src/api/migrations/add-menus.ts new file mode 100644 index 000000000..26ea5d7ec --- /dev/null +++ b/packages/app/src/api/migrations/add-menus.ts @@ -0,0 +1,181 @@ +import api from '../app'; +import Database from '@nocobase/database'; +import views_v2 from '@nocobase/plugin-pages/src/collections/views_v2'; +import { Op } from 'sequelize'; + +(async () => { + await api.loadPlugins(); + const database: Database = api.database; + + await api.database.sync(); + await api.database.getModel('collections').load({skipExisting: true}); + + const [Collection, Field, Page, Menu, View] = database.getModels(['collections', 'fields', 'pages_v2', 'menus', 'views_v2']); + + // await Collection.import(require('./collections/authors').default, { update: true }); + // await Collection.import(require('./collections/books').default, { update: true }); + + await Menu.truncate(); + await Page.destroy({ + where: { + id: { + [Op.not]: null, + }, + } + }); + await View.destroy({ + where: { + id: { + [Op.not]: null, + }, + } + }); + + const collection = await Collection.findOne({ + where: { + name: 'views_v2', + } + }); + + await collection.updateAssociations({ + fields: views_v2.fields, + views_v2: views_v2.views_v2, + }); + + // const authors = require('./collections/authors').default; + + console.log('views_v2.fields', views_v2.fields.map(field=>field.name)); + + // await collection.updateAssociations({ + // views_v2: authors.views_v2, + // }); + + + + const tables = database.getTables([ + 'collections', + 'fields', + 'menus', + 'pages_v2', + 'views_v2', + 'pages_views_v2', + 'automations', + 'automations_jobs', + 'action_logs', + 'users', + 'roles', + 'scopes', + 'views_actions_v2', + 'views_pages_v2', + 'views_fields_v2', + ]); + + for (let table of tables) { + console.log(table.getName()); + await Collection.import(table.getOptions(), { update: true, migrate: false }); + } + + const menus = [ + { + title: '仪表盘', + icon: 'DashboardOutlined', + type: 'group', + children: [ + { + title: '欢迎光临', + icon: 'DatabaseOutlined', + type: 'page', + pageName: 'welcome' + }, + ], + }, + { + title: '数据', + icon: 'DatabaseOutlined', + type: 'group', + children: [ + { + title: '作者', + icon: 'DatabaseOutlined', + type: 'page', + pageName: 'authors.all', + }, + { + title: '申请表单', + icon: 'DatabaseOutlined', + type: 'page', + pageName: 'authors.form', + }, + ], + }, + { + title: '用户', + icon: 'TeamOutlined', + type: 'group', + children: [ + { + title: '用户管理', + icon: 'DatabaseOutlined', + type: 'page', + pageName: 'users.all', + }, + ], + }, + { + title: '动态', + icon: 'NotificationOutlined', + type: 'group', + children: [ + { + title: '操作日志', + icon: 'DatabaseOutlined', + type: 'page', + pageName: 'action_logs.all', + }, + ], + }, + { + title: '配置', + icon: 'SettingOutlined', + type: 'group', + children: [ + { + title: '数据表配置', + icon: 'DatabaseOutlined', + type: 'page', + pageName: 'collections.all', + }, + { + title: '菜单配置', + icon: 'MenuOutlined', + type: 'page', + pageName: 'menus.all', + }, + { + title: '页面配置', + icon: 'MenuOutlined', + type: 'page', + pageName: 'pages_v2.globals', + }, + { + title: '权限配置', + icon: 'MenuOutlined', + type: 'page', + pageName: 'roles.all', + }, + { + title: '自动化配置', + icon: 'MenuOutlined', + type: 'page', + pageName: 'automations.all', + }, + ], + }, + ]; + + for (const item of menus) { + const menu = await Menu.create(item); + await menu.updateAssociations(item); + } + +})(); diff --git a/packages/app/src/api/migrations/collections/authors.ts b/packages/app/src/api/migrations/collections/authors.ts index a568a3726..b67436a13 100644 --- a/packages/app/src/api/migrations/collections/authors.ts +++ b/packages/app/src/api/migrations/collections/authors.ts @@ -39,17 +39,19 @@ export default { showInForm: true, }, }, - // { - // interface: 'linkTo', - // title: '书籍', - // target: 'books', - // labelField: 'name', - // component: { - // showInTable: true, - // showInDetail: true, - // showInForm: true, - // }, - // }, + { + interface: 'linkTo', + type: 'belongsToMany', + title: '书籍', + name: 'books', + target: 'books', + labelField: 'name', + component: { + showInTable: true, + showInDetail: true, + showInForm: true, + }, + }, { interface: 'createdBy', title: '创建人', @@ -87,4 +89,87 @@ export default { }, } ], + views_v2: [ + { + type: 'table', + name: 'table', + title: '全部数据', + labelField: 'name', + actions: [ + { + name: 'filter', + type: 'filter', + title: '过滤', + fields: [ + 'name', + ], + // viewName: 'form', + }, + { + name: 'create', + type: 'create', + title: '新增', + viewName: 'form', + }, + { + name: 'destroy', + type: 'destroy', + title: '删除', + }, + ], + fields: ['name'], + detailsOpenMode: 'drawer', // window + details: ['descriptions', 'books'], + sort: ['id'], + }, + { + type: 'descriptions', + name: 'descriptions', + title: '详情', + fields: ['name'], + actions: [ + { + name: 'update', + type: 'update', + title: '编辑', + viewName: 'form', + }, + ], + }, + { + type: 'form', + name: 'form', + title: '表单', + fields: ['name'], + }, + { + type: 'association', + name: 'books', + title: '书籍', + targetViewName: 'table', + targetFieldName: 'books', + }, + ], + pages_v2: [ + { + title: '全部数据', + name: 'all', + views: ['table'], + }, + { + title: '详情', + name: 'descriptions', + views: ['descriptions'], + }, + { + title: '表单', + name: 'form', + views: ['form'], + }, + { + title: '书籍', + name: 'books', + views: ['books'], + }, + ], }; diff --git a/packages/app/src/api/migrations/collections/books.ts b/packages/app/src/api/migrations/collections/books.ts index 5f651e94b..71c34eb35 100644 --- a/packages/app/src/api/migrations/collections/books.ts +++ b/packages/app/src/api/migrations/collections/books.ts @@ -74,4 +74,75 @@ export default { }, } ], + views_v2: [ + { + type: 'table', + name: 'table', + title: '全部数据', + labelField: 'name', + actions: [ + { + name: 'filter', + type: 'filter', + title: '过滤', + fields: [ + 'name', + ], + // viewName: 'form', + }, + { + name: 'create', + type: 'create', + title: '新增', + viewName: 'form', + }, + { + name: 'destroy', + type: 'destroy', + title: '删除', + }, + ], + fields: ['name'], + detailsOpenMode: 'drawer', // window + details: ['descriptions', 'form'], + sort: ['id'], + }, + { + type: 'descriptions', + name: 'descriptions', + title: '详情', + fields: ['name'], + actions: [ + { + name: 'update', + type: 'update', + title: '编辑', + viewName: 'form', + }, + ], + }, + { + type: 'form', + name: 'form', + title: '表单', + fields: ['name'], + }, + ], + pages_v2: [ + { + title: '全部数据', + name: 'all', + views: ['table'], + }, + { + title: '详情', + name: 'descriptions', + views: ['descriptions'], + }, + { + title: '表单', + name: 'form', + views: ['form'], + }, + ], }; diff --git a/packages/app/src/api/migrations/init.ts b/packages/app/src/api/migrations/init.ts index 24c2fd149..fc7c80002 100644 --- a/packages/app/src/api/migrations/init.ts +++ b/packages/app/src/api/migrations/init.ts @@ -17,134 +17,15 @@ const data = [ type: 'layout', template: 'TopMenuLayout', sort: 10, - children: [ - { - title: '仪表盘', - type: 'page', - path: '/dashboard', - icon: 'DashboardOutlined', - template: 'page1', - sort: 20, - showInMenu: true, - }, - { - title: '数据', - type: 'layout', - path: '/collections', - icon: 'DatabaseOutlined', - template: 'SideMenuLayout', - sort: 30, - showInMenu: true, - children: [ - // { - // title: '页面3', - // type: 'page', - // path: '/collections/page3', - // icon: 'dashboard', - // template: 'page3', - // sort: 40, - // }, - // { - // title: '页面4', - // type: 'page', - // path: '/collections/page4', - // icon: 'dashboard', - // template: 'page4', - // sort: 50, - // }, - ] - }, - { - title: '用户', - type: 'layout', - path: '/users', - icon: 'TeamOutlined', - template: 'SideMenuLayout', - sort: 70, - showInMenu: true, - children: [ - { - title: '用户管理', - type: 'collection', - path: '/users/users', - icon: 'UserOutlined', - template: 'collection', - collection: 'users', - sort: 80, - showInMenu: true, - }, - ] - }, - { - title: '动态', - type: 'layout', - path: '/activity', - icon: 'NotificationOutlined', - template: 'SideMenuLayout', - sort: 85, - showInMenu: true, - children: [ - { - title: '操作记录', - type: 'collection', - path: '/activity/logs', - icon: 'HistoryOutlined', - template: 'collection', - collection: 'action_logs', - sort: 80, - showInMenu: true, - }, - ] - }, - { - title: '配置', - type: 'layout', - path: '/settings', - icon: 'SettingOutlined', - template: 'SideMenuLayout', - sort: 90, - showInMenu: true, - children: [ - { - title: '页面与菜单', - type: 'collection', - collection: 'pages', - path: '/settings/pages', - icon: 'MenuOutlined', - sort: 100, - developerMode: true, - showInMenu: true, - }, - { - title: '数据表配置', - type: 'collection', - collection: 'collections', - path: '/settings/collections', - icon: 'TableOutlined', - sort: 110, - showInMenu: true, - }, - { - title: '权限组配置', - type: 'collection', - collection: 'roles', - path: '/settings/roles', - icon: 'TableOutlined', - sort: 120, - showInMenu: true, - }, - { - title: '自动化配置', - type: 'collection', - collection: 'automations', - path: '/settings/automations', - icon: 'TableOutlined', - sort: 130, - showInMenu: true, - }, - ] - }, - ], + redirect: '/admin', + }, + { + title: '后台', + path: '/admin', + type: 'page', + inherit: false, + template: 'AdminLoader', + order: 230, }, { title: '登录页面', @@ -161,7 +42,7 @@ const data = [ inherit: false, template: 'register', order: 130, - } + }, ]; (async () => { @@ -190,6 +71,7 @@ const data = [ nickname: "超级管理员", password: "admin", username: "admin", + email: 'dev@nocobase.com', token: "38979f07e1fca68fb3d2", }); } @@ -221,14 +103,16 @@ const data = [ }); } const Role = database.getModel('roles'); - const roles = await Role.bulkCreate([ - { title: '系统开发组', type: -1 }, - { title: '匿名用户组', type: 0 }, - { title: '普通用户组', default: true }, - ]); - await roles[0].updateAssociations({ - users: user - }); + if (Role) { + const roles = await Role.bulkCreate([ + { title: '系统开发组', type: -1 }, + // { title: '匿名用户组', type: 0 }, + { title: '普通用户组', default: true }, + ]); + await roles[0].updateAssociations({ + users: user + }); + } const Action = database.getModel('actions'); // 全局 @@ -238,8 +122,116 @@ const data = [ // 导入地域数据 await chinaRegionSeederInit(api); - await database.getModel('collections').import(require('./collections/example').default); - await database.getModel('collections').import(require('./collections/authors').default); - await database.getModel('collections').import(require('./collections/books').default); + // await database.getModel('collections').import(require('./collections/example').default); + // await database.getModel('collections').import(require('./collections/authors').default); + // await database.getModel('collections').import(require('./collections/books').default); + + const Menu = database.getModel('menus'); + + const menus = [ + { + title: '仪表盘', + icon: 'DashboardOutlined', + type: 'group', + children: [ + { + title: '欢迎光临', + icon: 'DatabaseOutlined', + type: 'page', + views: [], + name: 'welcome', + }, + ], + }, + { + title: '数据', + icon: 'DatabaseOutlined', + type: 'group', + children: [], + }, + { + title: '用户', + icon: 'TeamOutlined', + type: 'group', + children: [ + { + title: '用户管理', + icon: 'DatabaseOutlined', + type: 'page', + views: ['users.table'], + name: 'users', + }, + ], + }, + { + title: '动态', + icon: 'NotificationOutlined', + type: 'group', + developerMode: true, + children: [ + { + title: '操作日志', + icon: 'DatabaseOutlined', + type: 'page', + views: ['action_logs.table'], + developerMode: true, + name: 'auditing', + }, + ], + }, + { + title: '配置', + icon: 'SettingOutlined', + type: 'group', + developerMode: true, + children: [ + { + name: 'system_settings', + title: '系统配置', + icon: 'DatabaseOutlined', + type: 'page', + views: ['system_settings.descriptions'], + developerMode: true, + }, + { + name: 'collections', + title: '数据表配置', + icon: 'DatabaseOutlined', + type: 'page', + views: ['collections.table'], + developerMode: true, + }, + { + name: 'menus', + title: '菜单和页面配置', + icon: 'MenuOutlined', + type: 'page', + views: ['menus.table'], + developerMode: true, + }, + { + name: 'permissions', + title: '权限配置', + icon: 'MenuOutlined', + type: 'page', + views: ['roles.table'], + developerMode: true, + }, + { + name: 'automations', + title: '自动化配置', + icon: 'MenuOutlined', + type: 'page', + views: ['automations.table'], + developerMode: true, + }, + ], + }, + ]; + + for (const item of menus) { + const menu = await Menu.create(item); + await menu.updateAssociations(item); + } await database.close(); })(); diff --git a/packages/app/src/app.ts b/packages/app/src/app.ts index 16a18babc..bc329dcc7 100644 --- a/packages/app/src/app.ts +++ b/packages/app/src/app.ts @@ -35,6 +35,9 @@ export const request: RequestConfig = { export async function getInitialState() { const { pathname, search } = location; console.log(location); + const { data: systemSettings = {} } = await umiRequest('/system_settings:get?fields[appends]=logo,logo.storage', { + method: 'get', + }); let redirect = ''; // if (href.includes('?')) { redirect = `?redirect=${pathname}${search}`; @@ -49,11 +52,13 @@ export async function getInitialState() { if (!data.id) { history.push('/login' + redirect); return { + systemSettings, currentUser: {}, }; } return { + systemSettings, currentUser: data, }; } catch (error) { @@ -62,5 +67,8 @@ export async function getInitialState() { } } - return {}; + return { + systemSettings, + currentUser: {}, + }; } \ No newline at end of file diff --git a/packages/app/src/components/actions/style.less b/packages/app/src/components/actions/style.less index 3a699ce2b..0b1edb723 100644 --- a/packages/app/src/components/actions/style.less +++ b/packages/app/src/components/actions/style.less @@ -1,12 +1,11 @@ .action-buttons { display: flex; - justify-content: flex-end; + // justify-content: flex-end; min-height: 32px; + flex-direction: row-reverse; + align-items: flex-start; .action-button { - margin-right: 8px; - &:last-child { - margin-right: 0; - } + margin-left: 8px; } .filter-action-button { position: absolute; diff --git a/packages/app/src/components/form.fields/cascader/index.tsx b/packages/app/src/components/form.fields/cascader/index.tsx index 1f094399b..210d6e393 100644 --- a/packages/app/src/components/form.fields/cascader/index.tsx +++ b/packages/app/src/components/form.fields/cascader/index.tsx @@ -24,17 +24,40 @@ export const Cascader = connect({ })(function (props) { const { disabled, - target, - labelField, - valueField = 'id', - parentField, - maxLevel, - changeOnSelect, + // target, + // labelField, + // valueField = 'id', + // parentField, + // maxLevel, + // changeOnSelect, value = [], onChange, + schema = {}, // TODO(feature): 增加静态数据支持 // dataSource: [] } = props; + const { + target, + targetKey: valueField, + // 值字段 + // valueField: 'code', + // 名称字段 + labelField, + // TODO(refactor): 等 toWhere 重构完成后要改成 parent + // 上级字段名 + parentField, + maxLevel, + // valueField = 'id', + // 深度限制,默认:-1(代表不控制,即如果是数据表,则无限加载) + // limit: -1, + // 可选层级,默认:-1(代表可选的最深层级) + // maxLevel: null, + // 是否可以不选择到最深一级 + // 'x-component-props': { changeOnSelect: true } + incompletely: changeOnSelect, + + } = schema; + const fieldNames = { label: labelField, value: valueField, diff --git a/packages/app/src/components/form.fields/drawer-select/index.tsx b/packages/app/src/components/form.fields/drawer-select/index.tsx index 638f96c86..b11ec0eda 100644 --- a/packages/app/src/components/form.fields/drawer-select/index.tsx +++ b/packages/app/src/components/form.fields/drawer-select/index.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { connect } from '@formily/react-schema-renderer' -import { Select, Drawer, Button, Space } from 'antd' +import { Select, Button, Space } from 'antd' import { mapStyledProps, mapTextComponent, @@ -9,13 +9,15 @@ import { isArr } from '../shared' import ViewFactory from '@/components/views' +import Drawer from '@/components/pages/AdminLoader/Drawer'; +import View from '@/components/pages/AdminLoader/View'; function transform({value, multiple, labelField, valueField = 'id'}) { let selectedKeys = []; let selectedValue = []; - const values = Array.isArray(value) ? value : []; - selectedKeys = values.map(item => item[valueField]); - selectedValue = values.map(item => { + const values = Array.isArray(value) ? value : [value]; + selectedKeys = values.filter(item => item).map(item => item[valueField]); + selectedValue = values.filter(item => item).map(item => { return { value: item[valueField], label: item[labelField], @@ -27,14 +29,13 @@ function transform({value, multiple, labelField, valueField = 'id'}) { return [selectedKeys, selectedValue]; } -function DrawerSelectComponent(props) { - const { disabled, target, multiple, filter, resourceName, associatedKey, labelField, valueField = 'id', value, onChange } = props; +export function DrawerSelectComponent(props) { + const { __parent, size, schema = {}, disabled, viewName, target, multiple, filter, resourceName, associatedKey, labelField, valueField = 'id', value, onChange } = props; const [selectedKeys, selectedValue] = transform({value, multiple, labelField, valueField }); - const [visible, setVisible] = useState(false); const [selectedRowKeys, setSelectedRowKeys] = useState(multiple ? selectedKeys : [selectedKeys]); const [selectedRows, setSelectedRows] = useState(selectedValue); const [options, setOptions] = useState(selectedValue); - // console.log('valuevaluevaluevaluevaluevalue', value); + const { title = '' } = schema; return ( <> - { - setVisible(false); - }} - footer={[ -
- - - - -
- - ]} - > - { - // 需要返回的是 array - const [selectedKeys, selectedValue] = transform({value: values, multiple: true, labelField, valueField }); - setSelectedRows(selectedValue); - setSelectedRowKeys(selectedKeys); - // console.log('valuevaluevaluevaluevaluevalue', {values, selectedKeys, selectedValue}); - }} - // associatedKey={} - // associatedName={associatedName} - viewName={'table'} - /> -
); } diff --git a/packages/app/src/components/form.fields/filter/index.tsx b/packages/app/src/components/form.fields/filter/index.tsx index 95a349da4..173cac2a4 100644 --- a/packages/app/src/components/form.fields/filter/index.tsx +++ b/packages/app/src/components/form.fields/filter/index.tsx @@ -480,7 +480,7 @@ export const Filter = connect({ ], }; const { value, onChange, associatedKey, filter = {}, sourceName, sourceFilter = {}, fields = [], ...restProps } = props; - + console.log('filter', {associatedKey}) const { data = [], loading = true } = useRequest(() => { return associatedKey ? api.resource(`collections.fields`).list({ associatedKey, diff --git a/packages/app/src/components/form.fields/form-description/index.tsx b/packages/app/src/components/form.fields/form-description/index.tsx index b230926f3..9e2fb54d7 100644 --- a/packages/app/src/components/form.fields/form-description/index.tsx +++ b/packages/app/src/components/form.fields/form-description/index.tsx @@ -6,12 +6,14 @@ import { markdown } from '@/components/views/Field' export const FormDescription = createVirtualBox( 'description', - styled(({ children, className, ...props }) => { + styled(({ schema = {}, children, className, ...props }) => { + const { title, tooltip } = schema as any; + console.log({schema}) return ( - - {typeof children === 'string' && children &&
} + {typeof tooltip === 'string' && tooltip &&
}
) })` diff --git a/packages/app/src/components/form.fields/permissions/index.tsx b/packages/app/src/components/form.fields/permissions/index.tsx index 77d1bbda4..bdba2294f 100644 --- a/packages/app/src/components/form.fields/permissions/index.tsx +++ b/packages/app/src/components/form.fields/permissions/index.tsx @@ -9,6 +9,7 @@ import findIndex from 'lodash/findIndex'; import get from 'lodash/get'; import set from 'lodash/set'; import { Scope } from './Scope'; +import { DrawerSelectComponent } from '../drawer-select'; export const Permissions = {} as {Actions: any, Fields: any, Tabs: any}; @@ -70,11 +71,15 @@ Permissions.Actions = connect({ } const values = [...value||[]]; const index = findIndex(values, (item: any) => item && item.name === `${resourceKey}:${record.name}`); + console.log(values, index, `${resourceKey}:${record.name}`, get(values, [index, 'scope'])); return ( - + // { + // const values = [...value||[]]; + // const index = findIndex(values, (item: any) => item && item.name === `${resourceKey}:${record.name}`); + // if (index === -1) { + // values.push({ + // name: `${resourceKey}:${record.name}`, + // scope_id: data, + // }); + // } else { + // set(values, [index, 'scope_id'], data); + // } + // console.log('valvalvalvalval', {values}) + // onChange(values); + // console.log('valvalvalvalval', data); + // }} + // /> ) } }, diff --git a/packages/app/src/components/form.fields/registry.ts b/packages/app/src/components/form.fields/registry.ts index 192938940..e00ae8d79 100644 --- a/packages/app/src/components/form.fields/registry.ts +++ b/packages/app/src/components/form.fields/registry.ts @@ -24,6 +24,8 @@ import { Permissions } from './permissions' import { DraggableTable } from './draggable-table' import { Values } from './values' import { Automations } from './automations' +import { VirtualTable } from './virtual-table' +import { Wysiwyg } from './wysiwyg' export const setup = () => { registerFormFields({ @@ -44,6 +46,7 @@ export const setup = () => { month: DatePicker.MonthPicker, week: DatePicker.WeekPicker, string: Input, + select: Input, icon: Icon, textarea: Input.TextArea, number: NumberPicker, @@ -60,11 +63,13 @@ export const setup = () => { subTable: SubTable, draggableTable: DraggableTable, values: Values, + wysiwyg: Wysiwyg, 'permissions.actions': Permissions.Actions, 'permissions.fields': Permissions.Fields, 'permissions.tabs': Permissions.Tabs, 'automations.datetime': Automations.DateTime, 'automations.endmode': Automations.EndMode, 'automations.cron': Automations.Cron, + 'virtualTable': VirtualTable, }); } diff --git a/packages/app/src/components/form.fields/remote-select/index.tsx b/packages/app/src/components/form.fields/remote-select/index.tsx index 9d22b73d5..56d202d4f 100644 --- a/packages/app/src/components/form.fields/remote-select/index.tsx +++ b/packages/app/src/components/form.fields/remote-select/index.tsx @@ -12,9 +12,26 @@ import { import { useRequest } from 'umi'; import api from '@/api-client'; import { Spin } from '@nocobase/client' +import get from 'lodash/get'; function RemoteSelectComponent(props) { - const { value, onChange, disabled, resourceName, associatedKey, filter, labelField, valueField = 'id', objectValue, placeholder, multiple } = props; + let { schema = {}, value, onChange, disabled, resourceName, associatedKey, filter, labelField, valueField, objectValue, placeholder, multiple } = props; + console.log({schema}); + if (!resourceName) { + resourceName = get(schema, 'component.resourceName'); + } + if (!filter) { + filter = get(schema, 'component.filter'); + } + if (!labelField) { + labelField = get(schema, 'component.labelField'); + } + if (!valueField) { + valueField = get(schema, 'component.valueField'); + } + if (!valueField) { + valueField = 'id'; + } const { data = [], loading = true } = useRequest(() => { return api.resource(resourceName).list({ associatedKey, @@ -27,6 +44,7 @@ function RemoteSelectComponent(props) { if (multiple) { selectProps.mode = 'multiple' } + console.log({ data, props, associatedKey }) return ( <>