feat: quick create view for page
This commit is contained in:
parent
d3fa4d3d1a
commit
388dbc5ef4
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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' }}`,
|
||||
// },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user