feat: quick create view for page

This commit is contained in:
chenos 2021-03-24 10:21:38 +08:00
parent d3fa4d3d1a
commit 388dbc5ef4
6 changed files with 189 additions and 326 deletions

View File

@ -11,18 +11,18 @@ export default {
createdAt: 'createdTime',
updatedAt: 'updatedTime',
fields: [
{
interface: 'sort',
type: 'sort',
name: 'sort',
title: '排序',
component: {
type: 'sort',
className: 'drag-visible',
width: 60,
showInTable: true,
},
},
// {
// interface: 'sort',
// type: 'sort',
// name: 'sort',
// title: '排序',
// component: {
// type: 'sort',
// className: 'drag-visible',
// width: 60,
// showInTable: true,
// },
// },
{
interface: 'string',
type: 'string',
@ -31,10 +31,6 @@ export default {
required: true,
component: {
type: 'string',
className: 'drag-visible',
showInTable: true,
showInForm: true,
showInDetail: true,
},
},
{
@ -48,128 +44,43 @@ export default {
developerMode: true,
component: {
type: 'string',
showInTable: true,
showInForm: true,
showInDetail: true,
},
},
{
interface: 'icon',
type: 'virtual',
name: 'icon',
title: '图标',
interface: 'textarea',
type: 'text',
name: 'description',
title: '数据表描述',
component: {
type: 'icon',
showInTable: true,
showInForm: true,
showInDetail: true,
type: 'textarea',
},
},
// {
// interface: 'radio',
// interface: 'boolean',
// type: 'virtual',
// name: 'defaultView',
// title: '默认视图',
// defaultValue: 'table',
// dataSource: [
// {label: '表格', value: 'table'},
// {label: '看板', value: 'kanban', disabled: true},
// {label: '日历', value: 'calendar', disabled: true},
// ],
// name: 'createdAt',
// title: '记录创建时间',
// developerMode: true,
// defaultValue: true,
// component: {
// type: 'radio',
// showInTable: true,
// type: 'checkbox',
// default: true,
// showInForm: true,
// showInDetail: true,
// },
// },
// {
// interface: 'radio',
// type: 'virtual',
// name: 'mode',
// title: '表格模式',
// defaultValue: 'default',
// dataSource: [
// {label: '常规模式', value: 'default'},
// {label: '简易模式', value: 'simple'},
// ],
// component: {
// type: 'radio',
// tooltip: `
// <p>常规模式:点击数据进入详情页进行各项查看和操作;<br/>简易模式:点击数据直接打开编辑表单</p>
// `,
// showInForm: true,
// showInDetail: true,
// },
// },
// {
// interface: 'radio',
// type: 'virtual',
// name: 'defaultPerPage',
// title: '每页显示几行数据',
// defaultValue: 50,
// dataSource: [
// {label: '20', value: 20},
// {label: '50', value: 50},
// {label: '100', value: 100},
// ],
// component: {
// type: 'radio',
// showInForm: true,
// showInDetail: true,
// },
// },
// {
// interface: 'boolean',
// type: 'virtual',
// name: 'draggable',
// title: '支持拖拽数据排序',
// showInForm: true,
// showInDetail: true,
// name: 'updatedAt',
// title: '记录修改时间',
// developerMode: true,
// defaultValue: true,
// component: {
// type: 'checkbox',
// default: true,
// showInForm: true,
// showInDetail: true,
// },
// },
{
interface: 'boolean',
type: 'boolean',
name: 'showInDataMenu',
title: '显示在“数据”菜单里',
component: {
type: 'checkbox',
showInTable: true,
showInForm: true,
showInDetail: true,
},
},
{
interface: 'boolean',
type: 'virtual',
name: 'createdAt',
title: '记录创建时间',
developerMode: true,
defaultValue: true,
component: {
type: 'checkbox',
default: true,
showInForm: true,
},
},
{
interface: 'boolean',
type: 'virtual',
name: 'updatedAt',
title: '记录修改时间',
developerMode: true,
defaultValue: true,
component: {
type: 'checkbox',
default: true,
showInForm: true,
},
},
{
interface: 'boolean',
type: 'virtual',
@ -263,48 +174,6 @@ export default {
type: 'drawerSelect',
},
},
{
interface: 'linkTo',
type: 'hasMany',
name: 'tabs',
title: '标签页',
sourceKey: 'name',
draggable: true,
actions: {
list: {
sort: 'sort',
},
destroy: {
filter: {
default: false
}
}
},
component: {
type: 'drawerSelect',
},
},
{
interface: 'linkTo',
type: 'hasMany',
name: 'views',
title: '视图',
sourceKey: 'name',
draggable: true,
actions: {
list: {
sort: 'sort',
},
destroy: {
filter: {
default: false
}
}
},
component: {
type: 'drawerSelect',
},
},
{
interface: 'linkTo',
type: 'hasMany',
@ -398,10 +267,32 @@ export default {
title: '删除',
},
],
fields: ['sort', 'title'],
fields: ['title', 'description'],
detailsOpenMode: 'window', // window
details: ['descriptions', 'fields', 'views'],
sort: ['sort'],
sort: ['id'],
},
{
developerMode: true,
type: 'form',
name: 'form',
title: '表单',
fields: ['title', 'description'],
},
{
developerMode: true,
type: 'descriptions',
name: 'descriptions',
title: '详情',
fields: ['title', 'description'],
actions: [
{
name: 'update',
type: 'update',
title: '编辑',
viewName: 'form',
},
],
},
{
developerMode: true,
@ -466,28 +357,6 @@ export default {
},
],
},
{
developerMode: true,
type: 'form',
name: 'form',
title: '表单',
fields: ['title'],
},
{
developerMode: true,
type: 'descriptions',
name: 'descriptions',
title: '详情',
fields: ['title'],
actions: [
{
name: 'update',
type: 'update',
title: '编辑',
viewName: 'form',
},
],
},
{
developerMode: true,
type: 'table',

View File

@ -186,6 +186,16 @@ export default {
labelField: 'title',
draggable: true,
actions: [
{
name: 'create',
type: 'create',
title: '新增',
transform: {
'data': 'view',
'data.title': 'title',
},
viewName: 'views_v2.form',
},
{
name: 'add',
type: 'add',

View File

@ -49,6 +49,16 @@ export default {
labelField: 'title',
draggable: true,
actions: [
{
name: 'create',
type: 'create',
title: '新增',
transform: {
'data': 'view',
'data.title': 'title',
},
viewName: 'collections.views_v2.form',
},
{
name: 'add',
type: 'add',

View File

@ -75,6 +75,9 @@ export default {
'data.title': 'title',
},
viewName: 'collections.fields.table',
componentProps: {
type: 'primary',
},
},
{
name: 'destroy',
@ -118,6 +121,9 @@ export default {
'data.title': 'title',
},
viewName: 'collections.fields.table',
componentProps: {
type: 'primary',
},
},
{
name: 'destroy',

View File

@ -15,6 +15,7 @@ import { RANDOMSTRING } from './fields/randomString';
import { registerFields, registerModels } from '@nocobase/database';
import { BaseModel } from './models/BaseModel'
import * as rolesMenusActions from './actions/roles.menus';
import _ from 'lodash';
export default async function (options = {}) {
const database: Database = this.database;
@ -50,6 +51,7 @@ export default async function (options = {}) {
resourcer.use(async (ctx, next) => {
const { actionName, resourceName, values } = ctx.action.params;
if (resourceName === 'menus' && ['create', 'update'].includes(actionName)) {
console.log({values});
if (values.parent) {
delete values.parent.children;
ctx.action.mergeParams({
@ -81,148 +83,113 @@ export default async function (options = {}) {
resourcer.registerActionHandler(`roles.menus:${actionName}`, rolesMenusActions[actionName]);
});
database.getModel('menus').addHook('beforeSave', async (model) => {
console.log(model.get('pageName'));
});
// database.getModel('pages_v2').addHook('beforeValidate', async (model) => {
// const collectionName = model.get('collection_name');
// const name = model.get('name');
// if (!model.get('path')) {
// model.set('path', `${collectionName||'global'}.${name}`);
// }
// });
// database.getModel('views_v2').addHook('beforeValidate', async (model) => {
// const collectionName = model.get('collection_name');
// const name = model.get('name');
// if (!model.get('path')) {
// model.set('path', `${collectionName||'global'}.${name}`);
// }
// });
/*
const [Collection, Page, View] = database.getModels(['collections', 'pages', 'views']);
async function createCollectionPage(model, options) {
// const {
// transaction = await database.sequelize.transaction(),
// } = options;
if (model.get('internal')) {
return;
const createDetailsViews = async (model, options) => {
const data = model.get();
const View = database.getModel('views_v2');
const tableDetials = _.get(data, 'x-table-props.details') || [];
if (tableDetials.length) {
const details = [];
for (const item of tableDetials) {
if (item.view) {
if (!item.view.id) {
const view = await View.create(item.view);
await view.updateAssociations(item.view);
item.view.id = view.id;
} else {
const view = await View.findByPk(item.view.id);
await view.update(item.view);
await view.updateAssociations(item.view);
}
const transaction = await database.sequelize.transaction();
const parent = await Page.findOne({
transaction,
where: {
path: '/collections',
}
});
let page = await Page.findOne({
transaction,
where: {
collection: model.get('name'),
path: `/collections/${model.get('name')}`,
const view = await View.findOne(View.parseApiJson({
filter: {
id: item.view.id,
},
});
if (!page) {
page = await Page.create({
type: 'collection',
collection: model.get('name'),
path: `/collections/${model.get('name')}`,
sort: 100,
parent_id: parent.id,
}, {
transaction,
});
fields: {
appends: ['collection', 'targetField', 'targetView'],
},
}));
if (view) {
console.log({view});
item.view = view.toJSON();
}
page.set({
title: model.get('title'),
icon: model.get('icon'),
showInMenu: !!model.get('showInDataMenu'),
});
await page.save({
transaction,
});
await Page.collectionPagesResort({transaction});
await transaction.commit();
}
details.push(item);
}
model.set('options.x-table-props.details', details);
}
const calendarDetials = _.get(data, 'x-calendar-props.details') || [];
if (calendarDetials.length) {
const details = [];
for (const item of calendarDetials) {
if (item.view) {
if (!item.view.id) {
const view = await View.create(item.view);
await view.updateAssociations(item.view);
item.view.id = view.id;
} else {
const view = await View.findByPk(item.view.id);
await view.update(item.view);
await view.updateAssociations(item.view);
}
const view = await View.findOne(View.parseApiJson({
filter: {
id: item.view.id,
},
fields: {
appends: ['collection', 'targetField', 'targetView'],
},
}));
if (view) {
console.log({view});
item.view = view.toJSON();
}
}
details.push(item);
}
model.set('options.x-calendar-props.details', details);
}
};
Collection.addHook('afterCreate', createCollectionPage);
Collection.addHook('afterUpdate', createCollectionPage);
Collection.addHook('afterDestroy', async (model, options) => {
database.getModel('views_v2').addHook('beforeCreate', createDetailsViews);
database.getModel('views_v2').addHook('beforeUpdate', createDetailsViews);
database.getModel('menus').addHook('beforeSave', async (model, options) => {
const { transaction } = options;
// console.log('afterDestroy', model);
await Page.destroy({
transaction,
where: {
path: `/collections/${model.get('name')}`,
},
});
await Page.collectionPagesResort({transaction});
});
async function syncViewCollectionPage(model, options) {
const transaction = await database.sequelize.transaction();
const parentPath = `/collections/${model.get('collection_name')}`;
const currentPath = `${parentPath}/views/${model.get('name')}`;
try {
const parent = await Page.findOne({
transaction,
where: {
path: parentPath,
},
});
if (!parent) {
await transaction.rollback();
// console.log('beforeSave', model.get('views'));
const items = model.get('views');
if (!Array.isArray(items)) {
return;
}
let page = await Page.findOne({
transaction,
where: {
collection: model.get('collection_name'),
path: currentPath,
const View = database.getModel('views_v2');
const views = [];
for (const item of items) {
if (item.view) {
if (!item.view.id) {
const view = await View.create(item.view);
await view.updateAssociations(item.view);
item.view.id = view.id;
} else {
const view = await View.findByPk(item.view.id);
await view.update(item.view);
await view.updateAssociations(item.view);
}
const view = await View.findOne(View.parseApiJson({
filter: {
id: item.view.id,
},
});
if (!page) {
page = await Page.create({
type: 'collection',
collection: model.get('collection_name'),
path: currentPath,
sort: 100,
parent_id: parent.id,
}, {
transaction,
});
}
page.set({
title: model.get('title'),
viewName: model.get('name'),
viewId: model.get('id'),
// icon: model.get('icon'),
showInMenu: !!model.get('showInDataMenu'),
});
await page.save({
transaction,
});
} catch (error) {
await transaction.rollback();
console.error(error);
}
await transaction.commit();
}
View.addHook('beforeValidate', (model) => {
if (model.get('default')) {
model.set('showInDataMenu', true);
}
});
View.addHook('afterCreate', syncViewCollectionPage);
View.addHook('afterUpdate', syncViewCollectionPage);
View.addHook('afterDestroy', async (model, options) => {
await Page.destroy({
where: {
viewId: model.get('id'),
fields: {
appends: ['collection', 'targetField', 'targetView'],
},
});
});
*/
}));
if (view) {
console.log({view});
item.view = view.toJSON();
}
}
views.push(item);
}
model.set('views', views);
// @ts-ignore
model.changed('views', true);
});
}

View File

@ -61,6 +61,7 @@ export const form = {
},
fields: {
...fields,
viewName: 'tableForForm',
title: '显示在表单里的字段'
},
},
@ -346,11 +347,11 @@ export const wysiwyg = {
target: 'dataSourceType',
condition: `{{ $self.value && $self.value !== 'wysiwyg' }}`,
},
{
type: "value:visible",
target: 'targetField',
condition: `{{ $self.value && $self.value !== 'wysiwyg' }}`,
},
// {
// type: "value:visible",
// target: 'targetField',
// condition: `{{ $self.value && $self.value !== 'wysiwyg' }}`,
// },
],
},
};