feat: pages actions & tabs

This commit is contained in:
chenos 2020-12-12 16:36:02 +08:00
parent 2dbbe29223
commit 4decab86be
7 changed files with 63 additions and 39 deletions

View File

@ -3,6 +3,7 @@ import dotenv from 'dotenv';
import path from 'path'; import path from 'path';
import actions from '../../../actions/src'; import actions from '../../../actions/src';
import associated from '../../../actions/src/middlewares/associated'; import associated from '../../../actions/src/middlewares/associated';
import { Op } from 'sequelize';
const sync = { const sync = {
force: true, force: true,
@ -37,8 +38,9 @@ const api = Api.create({
api.resourcer.use(async (ctx, next) => { api.resourcer.use(async (ctx, next) => {
const { resourceName } = ctx.action.params; const { resourceName } = ctx.action.params;
const table = ctx.db.getTable(resourceName); const table = ctx.db.getTable(resourceName);
// ctx.state.developerMode = {[Op.not]: null};
ctx.state.developerMode = false; ctx.state.developerMode = false;
if (table && table.hasField('developerMode')) { if (table && table.hasField('developerMode') && ctx.state.developerMode === false) {
ctx.action.setParam('filter.developerMode', ctx.state.developerMode); ctx.action.setParam('filter.developerMode', ctx.state.developerMode);
} }
await next(); await next();

View File

@ -25,6 +25,7 @@ export default {
type: 'string', type: 'string',
name: 'title', name: 'title',
title: '名称', title: '名称',
required: true,
component: { component: {
type: 'string', type: 'string',
className: 'drag-visible', className: 'drag-visible',
@ -52,7 +53,7 @@ export default {
title: '类型', title: '类型',
dataSource: [ dataSource: [
{ label: '详情数据', value: 'details' }, { label: '详情数据', value: 'details' },
{ label: '相关数据', value: 'association' }, { label: '相关数据', value: 'association', disabled: true },
{ label: '模块组合', value: 'module', disabled: true }, { label: '模块组合', value: 'module', disabled: true },
], ],
component: { component: {
@ -60,6 +61,13 @@ export default {
showInTable: true, showInTable: true,
showInDetail: true, showInDetail: true,
showInForm: true, showInForm: true,
"x-linkages": [
{
"type": "value:visible",
"target": "association",
"condition": "{{ $self.value === 'association' }}"
},
],
}, },
}, },
{ {
@ -90,8 +98,8 @@ export default {
interface: 'boolean', interface: 'boolean',
type: 'boolean', type: 'boolean',
name: 'enabled', name: 'enabled',
title: '启', title: '启',
defaultValue: false, defaultValue: true,
component: { component: {
type: 'checkbox', type: 'checkbox',
showInTable: true, showInTable: true,

View File

@ -46,19 +46,19 @@ const defaultValues = {
actionNames: ['update'], actionNames: ['update'],
developerMode: true, developerMode: true,
}, },
{ // {
type: 'table', // type: 'table',
name: 'simple', // name: 'simple',
title: '简易模式', // title: '简易模式',
template: 'SimpleTable', // template: 'SimpleTable',
actionNames: ['create', 'destroy'], // actionNames: ['create', 'destroy'],
detailsViewName: 'details', // detailsViewName: 'details',
updateViewName: 'form', // updateViewName: 'form',
}, // },
{ {
type: 'table', type: 'table',
name: 'table', name: 'table',
title: '列表', title: '全部数据',
template: 'Table', template: 'Table',
actionNames: ['filter', 'create', 'destroy'], actionNames: ['filter', 'create', 'destroy'],
default: true, default: true,

View File

@ -1,6 +1,4 @@
import { Model, ModelCtor } from '@nocobase/database'; import { Model, ModelCtor } from '@nocobase/database';
import { ResourceOptions } from '@nocobase/resourcer';
import { get } from 'lodash';
export default async (ctx, next) => { export default async (ctx, next) => {
const { resourceName, resourceKey } = ctx.action.params; const { resourceName, resourceKey } = ctx.action.params;
@ -9,19 +7,18 @@ export default async (ctx, next) => {
filter: { filter: {
name: resourceName, name: resourceName,
}, },
// fields: {
// // appends: ['tabs'],
// },
})); }));
const views = await collection.getViews({ const defaultView = await collection.getViews({
where: { where: {
default: true, default: true,
}, },
limit: 1,
plain: true,
}); });
collection.setDataValue('defaultViewId', get(views, [0, 'id'])); collection.setDataValue('defaultViewName', defaultView.get('name'));
collection.setDataValue('defaultViewName', get(views, [0, 'name']));
const tabs = await collection.getTabs({ const tabs = await collection.getTabs({
where: { where: {
enabled: true,
developerMode: ctx.state.developerMode, developerMode: ctx.state.developerMode,
}, },
order: [['sort', 'asc']], order: [['sort', 'asc']],
@ -29,23 +26,19 @@ export default async (ctx, next) => {
const tabItems = []; const tabItems = [];
for (const tab of tabs) { for (const tab of tabs) {
const itemTab = { const itemTab = {
...tab.toJSON(), ...tab.get(),
...tab.options,
}; };
if (itemTab.type === 'details' && !itemTab.viewName) {
itemTab.viewName = 'details';
}
if (itemTab.type == 'association') { if (itemTab.type == 'association') {
const field = await Field.findOne({ itemTab.field = await collection.getFields({
where: { where: {
collection_name: itemTab.collection_name,
name: itemTab.association, name: itemTab.association,
}, },
limit: 1,
plain: true,
}); });
itemTab.field = field ? {
...field.toJSON(),
...field.options,
} : {};
itemTab.viewCollectionName = itemTab.association;
} else {
itemTab.viewCollectionName = itemTab.collection_name;
} }
tabItems.push(itemTab); tabItems.push(itemTab);
} }

View File

@ -14,7 +14,7 @@ export default async (ctx, next) => {
order: [['sort', 'asc']], order: [['sort', 'asc']],
}); });
ctx.body = { ctx.body = {
pageTitle: field ? model.get(field.get('name')) : model.get(M.primaryKeyAttribute), pageTitle: field ? (model.get(field.get('name')) || `#${model.get(M.primaryKeyAttribute)} 无标题`) : model.get(M.primaryKeyAttribute),
...model.toJSON(), ...model.toJSON(),
}; };
await next(); await next();

View File

@ -6,12 +6,12 @@ const transforms = {
table: async (fields: Model[], context?: any) => { table: async (fields: Model[], context?: any) => {
const arr = []; const arr = [];
for (const field of fields) { for (const field of fields) {
if (!get(field.component, 'showInTable')) { if (!field.get('component.showInTable')) {
continue; continue;
} }
arr.push({ arr.push({
...field.toJSON(), ...field.get(),
...field.options, sorter: field.get('sortable'),
dataIndex: field.name, dataIndex: field.name,
}); });
} }

View File

@ -21,16 +21,22 @@ export default async function (options = {}) {
const [Collection, Page] = database.getModels(['collections', 'pages']); const [Collection, Page] = database.getModels(['collections', 'pages']);
async function createCollectionPage(model) { async function createCollectionPage(model, options) {
// const {
// transaction = await database.sequelize.transaction(),
// } = options;
if (model.get('internal')) { if (model.get('internal')) {
return; return;
} }
const transaction = await database.sequelize.transaction();
const parent = await Page.findOne({ const parent = await Page.findOne({
transaction,
where: { where: {
path: '/collections', path: '/collections',
} }
}); });
let page = await Page.findOne({ let page = await Page.findOne({
transaction,
where: { where: {
collection: model.get('name'), collection: model.get('name'),
path: `/collections/${model.get('name')}`, path: `/collections/${model.get('name')}`,
@ -43,6 +49,8 @@ export default async function (options = {}) {
path: `/collections/${model.get('name')}`, path: `/collections/${model.get('name')}`,
sort: 100, sort: 100,
parent_id: parent.id, parent_id: parent.id,
}, {
transaction,
}); });
} }
page.set({ page.set({
@ -50,9 +58,22 @@ export default async function (options = {}) {
icon: model.get('icon'), icon: model.get('icon'),
showInMenu: !!model.get('showInDataMenu'), showInMenu: !!model.get('showInDataMenu'),
}); });
page.save(); await page.save({
transaction,
});
await transaction.commit();
} }
Collection.addHook('afterCreate', createCollectionPage); Collection.addHook('afterCreate', createCollectionPage);
Collection.addHook('afterUpdate', createCollectionPage); Collection.addHook('afterUpdate', createCollectionPage);
Collection.addHook('afterDestroy', async (model, options) => {
const { transaction } = options;
console.log('afterDestroy', model);
await Page.destroy({
transaction,
where: {
path: `/collections/${model.get('name')}`,
},
});
});
} }