fix: view can be displayed in data menu

This commit is contained in:
chenos 2020-12-15 22:44:20 +08:00
parent 67e18352b6
commit b2801a00dc
9 changed files with 113 additions and 13 deletions

View File

@ -11,7 +11,7 @@ function pathcamp(path1: string, path2: string) {
} }
export default (props: any) => { export default (props: any) => {
const { items = [], ...restProps } = props; const { items = [], hideChildren, ...restProps } = props;
const location = useLocation(); const location = useLocation();
let paths = items.map(item => item.path); let paths = items.map(item => item.path);
return ( return (
@ -20,11 +20,29 @@ export default (props: any) => {
defaultOpenKeys={paths.filter(path => pathcamp(location.pathname, path)).concat(location.pathname)} defaultOpenKeys={paths.filter(path => pathcamp(location.pathname, path)).concat(location.pathname)}
{...restProps} {...restProps}
> >
{items.map(item => item.showInMenu && ( {items.map(item => {
<Menu.Item key={item.path}> if (!item.showInMenu) {
<Link to={item.path}><Icon type={item.icon}/> {item.title}</Link> return null;
</Menu.Item> }
))} const { children = [] } = item;
const subItems = children.filter(child => child.showInMenu);
if (!hideChildren && subItems.length > 1) {
return (
<Menu.SubMenu key={`${item.path}`} title={<><Icon type={item.icon}/> {item.title}</>}>
{subItems.map((child: any) => (
<Menu.Item key={child.path}>
<Link to={child.path}>{child.title}</Link>
</Menu.Item>
))}
</Menu.SubMenu>
)
}
return (
<Menu.Item key={item.path}>
<Link to={item.path}><Icon type={item.icon}/> {item.title}</Link>
</Menu.Item>
)
})}
</Menu> </Menu>
); );
}; };

View File

@ -5,6 +5,7 @@ import { useRequest, request, Spin } from '@nocobase/client';
import { getPathName } from './utils'; import { getPathName } from './utils';
export function CollectionIndex(props) { export function CollectionIndex(props) {
const { lastPage } = props;
const { viewName, collection } = props.match.params; const { viewName, collection } = props.match.params;
const { title, defaultViewName } = props.collection; const { title, defaultViewName } = props.collection;
@ -31,7 +32,7 @@ export function CollectionIndex(props) {
<div className={'collection-content'}> <div className={'collection-content'}>
<ViewFactory <ViewFactory
{...props} {...props}
viewName={viewName||defaultViewName} viewName={lastPage.viewName||viewName||defaultViewName}
resourceName={collection} resourceName={collection}
/> />
</div> </div>

View File

@ -12,7 +12,7 @@ export function TopMenuLayout(props: any) {
<Layout style={{ height: '100vh' }}> <Layout style={{ height: '100vh' }}>
<Layout.Header style={{height: 48, lineHeight: '48px', padding: 0}} className="nb-header"> <Layout.Header style={{height: 48, lineHeight: '48px', padding: 0}} className="nb-header">
<div className="logo" style={{width: 200, height: 20, float: 'left'}}><CodeOutlined /> NocoBase</div> <div className="logo" style={{width: 200, height: 20, float: 'left'}}><CodeOutlined /> NocoBase</div>
<Menu items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark" mode="horizontal"> <Menu hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark" mode="horizontal">
</Menu> </Menu>
<AvatarDropdown/> <AvatarDropdown/>
</Layout.Header> </Layout.Header>

View File

@ -87,6 +87,8 @@ export function SimpleTable(props: SimpleTableProps) {
}, },
}); });
await refresh(); await refresh();
// @ts-ignore
window.routesReload && window.routesReload();
console.log('destroy.onTrigger', selectedRowKeys); console.log('destroy.onTrigger', selectedRowKeys);
}, },
}} }}

View File

@ -88,6 +88,8 @@ export function Table(props: TableProps) {
}, },
}); });
await refresh(); await refresh();
// @ts-ignore
window.routesReload && window.routesReload();
console.log('destroy.onTrigger', selectedRowKeys); console.log('destroy.onTrigger', selectedRowKeys);
} }
}} }}

View File

@ -10,10 +10,10 @@ function pages2routes(pages: Array<any>) {
const route: any = { const route: any = {
...restProps, ...restProps,
}; };
if (page.type === 'layout' && !page.redirect && children.length) { // page.type === 'layout' &&
if (!page.redirect && children.length) {
const items = children.sort((a, b) => a.order - b.order); const items = children.sort((a, b) => a.order - b.order);
const segmentId = get(items, [0, 'segments', 0, 'id']); route.redirect = items[0].path;
route.redirect = segmentId ? `${items[0].path}/segments/${segmentId}` : items[0].path;
} }
if (page.type === 'layout' && children.length) { if (page.type === 'layout' && children.length) {
route.menu = children.map(child => ({ route.menu = children.map(child => ({

View File

@ -153,7 +153,10 @@ export default async (ctx, next) => {
['sort', 'asc'], ['sort', 'asc'],
] ]
}); });
const actionNames = view.get('actionNames') || []; let actionNames = view.get('actionNames') || [];
if (actionNames.length === 0) {
actionNames = ['filter', 'create', 'destroy'];
}
if (view.get('type') === 'table') { if (view.get('type') === 'table') {
const defaultTabs = await collection.getTabs({ const defaultTabs = await collection.getTabs({
where: { where: {

View File

@ -182,6 +182,15 @@ export default {
type: 'drawerSelect', type: 'drawerSelect',
}, },
}, },
{
interface: 'number',
type: 'integer',
name: 'viewId',
title: '视图ID',
component: {
type: 'number',
},
},
{ {
interface: 'json', interface: 'json',
type: 'json', type: 'json',

View File

@ -19,7 +19,7 @@ export default async function (options = {}) {
resourcer.registerActionHandler('getPageInfo', getPageInfo); resourcer.registerActionHandler('getPageInfo', getPageInfo);
resourcer.registerActionHandler('pages:getRoutes', getRoutes); resourcer.registerActionHandler('pages:getRoutes', getRoutes);
const [Collection, Page] = database.getModels(['collections', 'pages']); const [Collection, Page, View] = database.getModels(['collections', 'pages', 'views']);
async function createCollectionPage(model, options) { async function createCollectionPage(model, options) {
// const { // const {
@ -76,4 +76,69 @@ export default async function (options = {}) {
}, },
}); });
}); });
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();
return;
}
let page = await Page.findOne({
transaction,
where: {
collection: model.get('collection_name'),
path: currentPath,
},
});
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) => {
console.log('beforeValidate');
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'),
},
});
});
} }