feat: improve view mode

This commit is contained in:
chenos 2021-01-07 09:31:26 +08:00
parent ee6cc5a665
commit 551f8bad8d
7 changed files with 110 additions and 35 deletions

View File

@ -71,21 +71,21 @@ api.resourcer.use(async (ctx: actions.Context, next) => {
} }
if (table && ['get', 'list'].includes(actionName)) { if (table && ['get', 'list'].includes(actionName)) {
const except = fields.except || []; const except = fields.except || [];
const appends = fields.appends || []; // const appends = fields.appends || [];
for (const [name, field] of table.getFields()) { for (const [name, field] of table.getFields()) {
if (field.options.hidden) { if (field.options.hidden) {
except.push(field.options.name); except.push(field.options.name);
} }
if (field.options.appends) { // if (field.options.appends) {
appends.push(field.options.name); // appends.push(field.options.name);
} // }
} }
if (except.length) { if (except.length) {
ctx.action.setParam('fields.except', except); ctx.action.setParam('fields.except', except);
} }
if (appends.length) { // if (appends.length) {
ctx.action.setParam('fields.appends', appends); // ctx.action.setParam('fields.appends', appends);
} // }
// console.log('ctx.action.params.fields', ctx.action.params.fields, except, appends); // console.log('ctx.action.params.fields', ctx.action.params.fields, except, appends);
} }
await next(); await next();
@ -120,6 +120,10 @@ api.registerPlugin('plugin-file-manager', [path.resolve(__dirname, '../../../plu
(async () => { (async () => {
await api.loadPlugins(); await api.loadPlugins();
api.database.getModel('users').addHook('beforeUpdate', function (model) {
console.log('users.beforeUpdate', model.get(), model.changed('password' as any));
});
api.resourcer.use(async (ctx, next) => { api.resourcer.use(async (ctx, next) => {
if (process.env.NOCOBASE_ENV !== 'demo') { if (process.env.NOCOBASE_ENV !== 'demo') {
return next(); return next();

View File

@ -7,7 +7,7 @@ import Database from '@nocobase/database';
await api.database.sync({ await api.database.sync({
tables: ['views'], tables: ['views'],
}); });
const [Collection, Page, User] = database.getModels(['collections', 'pages', 'users']); const [Collection, View, User] = database.getModels(['collections', 'views', 'users']);
const table = database.getTable('views'); const table = database.getTable('views');
const collection = await Collection.findByName('views'); const collection = await Collection.findByName('views');
console.log(table.getOptions().fields); console.log(table.getOptions().fields);
@ -16,4 +16,16 @@ import Database from '@nocobase/database';
}, { }, {
migrate: false, migrate: false,
}); });
const views = await View.findAll();
for (const view of views) {
if (!view.get('mode')) {
if (view.get('template') === 'SimpleTable') {
view.set('mode', 'simple');
} else {
view.set('mode', 'default');
}
await view.save();
}
}
})(); })();

View File

@ -1,6 +1,7 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Table as AntdTable, Card, Pagination } from 'antd'; import { Table as AntdTable, Card, Pagination } from 'antd';
import { Actions } from '@/components/actions'; import { Actions } from '@/components/actions';
import { redirectTo } from '@/components/pages/CollectionLoader/utils';
import ViewFactory from '@/components/views'; import ViewFactory from '@/components/views';
import { useRequest } from 'umi'; import { useRequest } from 'umi';
import api from '@/api-client'; import api from '@/api-client';
@ -56,7 +57,7 @@ export function Calendar(props: CalendarProps) {
multiple = true, multiple = true,
selectedRowKeys: srk, selectedRowKeys: srk,
} = props; } = props;
const { rowKey = 'id', labelField, startDateField, endDateField, name: viewName, actionDefaultParams = {}, fields = [], rowViewName, actions = [], paginated = true, defaultPerPage = 10 } = schema; const { rowKey = 'id', mode, defaultTabName, labelField, startDateField, endDateField, name: viewName, actionDefaultParams = {}, fields = [], rowViewName, actions = [], paginated = true, defaultPerPage = 10 } = schema;
const { filter: defaultFilter = {} } = actionDefaultParams; const { filter: defaultFilter = {} } = actionDefaultParams;
const { sourceKey = 'id' } = activeTab.field||{}; const { sourceKey = 'id' } = activeTab.field||{};
const drawerRef = useRef<any>(); const drawerRef = useRef<any>();
@ -210,6 +211,19 @@ export function Calendar(props: CalendarProps) {
setFormMode('update'); setFormMode('update');
drawerRef.current.setVisible(true); drawerRef.current.setVisible(true);
drawerRef.current.getData(event[rowKey]); drawerRef.current.getData(event[rowKey]);
if (mode === 'simple') {
drawerRef.current.setVisible(true);
drawerRef.current.getData(event[rowKey]);
} else {
redirectTo({
...props.match.params,
[activeTab ? 'newItem' : 'lastItem']: {
itemId: event[rowKey]||event.id,
tabName: defaultTabName,
},
});
}
// drawerRef.current. // drawerRef.current.
}} }}
onRangeChange={(range) => { onRangeChange={(range) => {

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { Table as AntdTable, Card, Pagination } from 'antd'; import { Table as AntdTable, Card, Pagination } from 'antd';
import { redirectTo } from '@/components/pages/CollectionLoader/utils'; import { redirectTo } from '@/components/pages/CollectionLoader/utils';
import { Actions } from '@/components/actions'; import { Actions } from '@/components/actions';
@ -6,6 +6,7 @@ import { request, useRequest } from 'umi';
import api from '@/api-client'; import api from '@/api-client';
import { components, fields2columns } from './SortableTable'; import { components, fields2columns } from './SortableTable';
import { LoadingOutlined } from '@ant-design/icons'; import { LoadingOutlined } from '@ant-design/icons';
import ViewFactory from '@/components/views';
export const icon = <LoadingOutlined style={{ fontSize: 36 }} spin />; export const icon = <LoadingOutlined style={{ fontSize: 36 }} spin />;
@ -30,7 +31,18 @@ export function Table(props: TableProps) {
multiple = true, multiple = true,
selectedRowKeys: srk, selectedRowKeys: srk,
} = props; } = props;
const { name: viewName, fields, actionDefaultParams = {}, defaultTabName, rowKey = 'id', actions = [], paginated = true, defaultPerPage = 10 } = schema; const {
name: viewName,
mode = 'default',
rowViewName = 'form',
fields,
actionDefaultParams = {},
defaultTabName,
rowKey = 'id',
actions = [],
paginated = true,
defaultPerPage = 10,
} = schema;
// const { data, mutate } = useRequest(() => api.resource(name).list({ // const { data, mutate } = useRequest(() => api.resource(name).list({
// associatedKey, // associatedKey,
// })); // }));
@ -70,6 +82,7 @@ export function Table(props: TableProps) {
defaultPageSize: defaultPerPage, defaultPageSize: defaultPerPage,
}); });
const { sourceKey = 'id' } = activeTab.field||{}; const { sourceKey = 'id' } = activeTab.field||{};
const drawerRef = useRef<any>();
console.log(props); console.log(props);
const [selectedRowKeys, setSelectedRowKeys] = useState(srk||[]); const [selectedRowKeys, setSelectedRowKeys] = useState(srk||[]);
const onChange = (selectedRowKeys: React.ReactText[], selectedRows: React.ReactText[]) => { const onChange = (selectedRowKeys: React.ReactText[], selectedRows: React.ReactText[]) => {
@ -120,6 +133,17 @@ export function Table(props: TableProps) {
} }
}} }}
/> />
{mode === 'simple' && (
<ViewFactory
{...props}
mode={'update'}
viewName={rowViewName}
reference={drawerRef}
onFinish={() => {
refresh();
}}
/>
)}
<AntdTable <AntdTable
size={'middle'} size={'middle'}
rowKey={rowKey} rowKey={rowKey}
@ -157,13 +181,18 @@ export function Table(props: TableProps) {
if (isFieldComponent) { if (isFieldComponent) {
return; return;
} }
redirectTo({ if (mode === 'simple') {
...props.match.params, drawerRef.current.setVisible(true);
[activeTab ? 'newItem' : 'lastItem']: { drawerRef.current.getData(data[rowKey]);
itemId: data[rowKey]||data.id, } else {
tabName: defaultTabName, redirectTo({
}, ...props.match.params,
}); [activeTab ? 'newItem' : 'lastItem']: {
itemId: data[rowKey]||data.id,
tabName: defaultTabName,
},
});
}
}, },
})} })}
pagination={false} pagination={false}

View File

@ -28,7 +28,7 @@ registerView('DrawerForm', DrawerForm);
registerView('PermissionForm', DrawerForm); registerView('PermissionForm', DrawerForm);
registerView('Form', Form); registerView('Form', Form);
registerView('Table', Table); registerView('Table', Table);
registerView('SimpleTable', SimpleTable); registerView('SimpleTable', Table);
registerView('Details', Details); registerView('Details', Details);
registerView('Login', Login); registerView('Login', Login);
registerView('Register', Register); registerView('Register', Register);

View File

@ -201,18 +201,37 @@ export default {
{ {
interface: 'radio', interface: 'radio',
type: 'string', type: 'string',
name: 'template', name: 'mode',
title: '查看和编辑模式', title: '查看和编辑模式',
required: true, required: true,
dataSource: [ dataSource: [
// { label: '表单', value: 'DrawerForm' }, { label: '常规模式', value: 'default' },
{ label: '常规模式', value: 'Table' }, { label: '快捷模式', value: 'simple' },
{ label: '快捷模式', value: 'SimpleTable' },
// { label: '日历模板', value: 'Calendar' },
], ],
component: { component: {
tooltip: "{{ html('常规模式:点击数据进入查看界面,再次点击进入编辑界面<br/>快捷模式:点击数据直接打开编辑界面') }}", tooltip: "常规模式:点击数据进入查看界面,再次点击进入编辑界面<br/>快捷模式:点击数据直接打开编辑界面",
type: 'radio', type: 'radio',
default: 'default',
showInTable: true,
showInDetail: true,
showInForm: true,
},
},
{
interface: 'select',
type: 'string',
name: 'template',
title: '模板',
required: true,
developerMode: true,
dataSource: [
{ label: '表单', value: 'DrawerForm' },
{ label: '常规表格', value: 'Table' },
{ label: '简易表格', value: 'SimpleTable' },
{ label: '日历模板', value: 'Calendar' },
],
component: {
type: 'select',
default: 'Table', default: 'Table',
showInTable: true, showInTable: true,
showInDetail: true, showInDetail: true,

View File

@ -230,15 +230,12 @@ export default async (ctx, next) => {
if (actionNames.length === 0) { if (actionNames.length === 0) {
actionNames = ['filter', 'create', 'destroy']; actionNames = ['filter', 'create', 'destroy'];
} }
const defaultTabs = await collection.getTabs({
if (view.get('type') === 'table') { where: {
const defaultTabs = await collection.getTabs({ default: true,
where: { },
default: true, });
}, view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name']));
});
view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name']));
}
if (view.get('type') === 'table') { if (view.get('type') === 'table') {
view.setDataValue('rowViewName', 'form'); view.setDataValue('rowViewName', 'form');
} }
@ -268,7 +265,7 @@ export default async (ctx, next) => {
const appends = []; const appends = [];
for (const field of fields) { for (const field of fields) {
if (!['subTable', 'linkTo', 'attachment'].includes(field.get('interface'))) { if (!['subTable', 'linkTo', 'attachment', 'createdBy', 'updatedBy'].includes(field.get('interface'))) {
continue; continue;
} }
let showInKey; let showInKey;