New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[项目] 导航菜单 & 路由管理功能 #2031
Comments
导航配置iceworks 导航配置生成 menuConfig(headerMenuConfig 和 asideMenuConfig) 数据字段如下: {
name: 'ice',
path: 'https://alibaba.github.io/ice',
// 是否是外链
external: true,
// 是否新打开窗口
newWindow: true,
// icon 先用 string,未来是否扩展 component 方案待定
icon: 'help',
// 导航组下有 children
children: []
} 路由配置iceworks 路由配置生成 routerConfig 数据字段如下: {
path: '/dashboard/monitor',
component: Dashboard
} 链路方案
布局配置(TODO)布局方案这块还需要确定 UI 规范以及组件,这次版本不会增加布局配置的能力,未来确定了方案再拿出来讨论。 |
|
+1 |
路由配置背景
技术方案routerConfig.js 实例如下: import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
import Page3 from './pages/Page3';
import Page4 from './pages/Page4';
import Page5 from './pages/Page5';
import Layout1 from './layouts/layout1';
import Layout2 from './layouts/layout2';
import Layout3 from './layouts/layout3';
import Layout4 from './layouts/layout4';
export default [
{
path: '/project/admin',
component: Page4,
layout: Layout3
},
{
path: '/project/user',
component: Page5,
layout: Layout4
},
{
path: '/project',
layout: layout1,
children: [
{
path: '/detail',
component: Page1
},
{
path: '/list',
component: Page2
}
]
},
{
path: '/help',
component: Page3,
layout: Layout2
},
]; router.jsx 代码如下: /**
* 定义应用路由
*/
import { Switch, Route } from 'react-router-dom';
import React from 'react';
import routerConfig from './routerConfig';
const router = () => {
return (
<Switch>
{routerConfig.map((router) => {
const { layout: Layout, component: Component } = router;
// 判断是否为组
if (router.children) {
return (
<Route path={router.path} component={router.layout}>
{router.children.map((routeChild) => {
return <Route path={routeChild.path} component={routeChild.component} />;
})}
</Route>
);
}
return <Route path={router.path} component={() => {
return (
<Layout>
<Component />
</Layout>
);
}} />;
})}
</Switch>
);
};
export default router; 技术问题
Action
|
还需要考虑现有用户项目的识别和迁移问题 |
@chenbin92 已有项目不能使用路由配置功能,在 iceworks 面板上指引用户迁移。 |
导航配置
技术方案导航组件实现一个数据驱动的导航组件 IceNav <IceNav config={[
{
name: '反馈',
path: 'https://github.com/alibaba/ice',
external: true,
newWindow: true,
icon: 'email',
},
{
name: '帮助',
path: 'https://alibaba.github.io/ice',
external: true,
newWindow: true,
icon: 'help',
},
]} /> Layout 中引入 menuConfig 以及显示导航headerMenuConfig 显示在 LayoutHeader, asideMenuConfig 显示在 LayoutAside import { asideMenuConfig, headerMenuConfig } from '../../menuConfig';
const App = () => {
render() {
return (
<Layout>
<Layout.Header>
<IceNav config={headerMenuConfig} />
</Layout.Header>
<Layout.Section>
<Layout.Aside>
<IceNav config={asideMenuConfig} direction="ver" />
</Layout.Aside>
<Layout.Main>{this.props.children}</Layout.Main>
</Layout.Section>
</Layout>
);
}; Action
|
这个不能够吧。 |
import { asideMenuConfig, headerMenuConfig } from '../../menuConfig';
const App = () => {
render() {
return (
<Layout>
<Layout.Header>
<IceNav config={asideMenuConfig} />
<IceNav config={headerMenuConfig} />
</Layout.Header>
<Layout.Main>{this.props.children}</Layout.Main>
</Layout>
);
}
};
<Layout.Header>
<IceNav config={asideMenuConfig} />
<IceNav config={headerMenuConfig} />
</Layout.Header> |
iceworks 上面交互图是怎样的,补充一下基本的交互草图吧 |
想到一个问题,在实际项目里,很可能出现 90% 的页面都是一个 Layout,然后由另外 1-2 个页面是其他 Layout,这时候这样的路由分层感觉就不太合理了: import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
import Page3 from './pages/Page3';
import Page4 from './pages/Page4';
import Page5 from './pages/Page5';
import Layout1 from './layouts/layout1';
import Layout2 from './layouts/layout2';
export default [
{
path: '/help',
component: Page3,
layout: Layout2
},
{
path: '/about',
component: Page3,
layout: Layout2
},
{
path: '/',
layout: layout1,
children: [
{
path: '/project/list',
component: Page1
},
{
path: '/project/:id',
component: Page2
},
{
path: '/user/list',
component: Page3
},
{
path: '/user/:id',
component: Page4
},
{
path: '/page/list',
component: Page5
},
{
path: '/page/:id',
component: Page6
}
]
},
]; |
介绍iceworks 项目中有两个文件
针对协议的设计列了以下三种方式: 第一种: routerConfig.js import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
import Page3 from './pages/Page3';
import Page4 from './pages/Page4';
import Page5 from './pages/Page5';
import Layout1 from './layouts/layout1';
import Layout2 from './layouts/layout2';
import Layout3 from './layouts/layout3';
export default [
{
path: '/help',
component: Page3,
layout: Layout2
},
{
path: '/about',
component: Page3,
layout: Layout2
},
{
path: '/project/list',
component: Page1,
layout: Layout1
},
{
path: '/project/:id',
component: Page2,
layout: Layout1
},
{
path: '/user/list',
component: Page3,
layout: Layout3
},
{
path: '/user/:id',
component: Page4,
layout: Layout3
},
{
path: '/page/list',
component: Page5,
layout: Layout3
},
{
path: '/page/:id',
component: Page6,
layout: Layout3
}
]; router.js 如下: import routerConfig from './routerConfig';
import React from 'react';
/**
* 根据路由信息扁平化地生成如下 Route 节点
*
* <Switch>
* <Route path="/help" component={Layout2+Component} />
* <Route path="/about" component={Layout2+Component} />
* <Route path="/project/list" component={Layout1+Component} />
* <Route path="/project/:id" component={Layout1+Component} />
* <Route path="/user/list" component={Layout3+Component} />
* <Route path="/user/:id" component={Layout3+Component} />
* <Route path="/page/list" component={Layou3+Component} />
* <Route path="/page/:id" component={Layout3+Component} />
* </Switch>
*/
const App = () => {
render() {
return (
<Switch>
{routerConfig.map((item) => {
return (
<Route exact={item.exact} path={item.path} component={() => {
const Layout = item.layout;
const Component = item.Component;
return (
<Layout>
<Component />
</Layout>
);
}} />
);
})}
</Switch>
);
}
};
export default App; 优点
缺点
第二种: routerConfig.js 协议和上面一样 import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
import Page3 from './pages/Page3';
import Page4 from './pages/Page4';
import Page5 from './pages/Page5';
import Layout1 from './layouts/layout1';
import Layout2 from './layouts/layout2';
import Layout3 from './layouts/layout3';
export default [
{
path: '/help',
component: Page3,
layout: Layout2
},
{
path: '/about',
component: Page3,
layout: Layout2
},
{
path: '/project/list',
component: Page1,
layout: Layout1
},
{
path: '/project/:id',
component: Page2,
layout: Layout1
},
{
path: '/user/list',
component: Page3,
layout: Layout3
},
{
path: '/user/:id',
component: Page4,
layout: Layout3
},
{
path: '/page/list',
component: Page5,
layout: Layout3
},
{
path: '/page/:id',
component: Page6,
layout: Layout3
}
]; router.js 如下: import routerConfig from './routerConfig';
import React from 'react';
/**
* 根据 layout 分组路由,生成如下带父子路由的结构
*
* <Switch>
* <Route path="/help" component={Layout2+Component} />
* <Route path="/about" component={Layout2+Component} />
* <Route path="/" component={Layout1}>
* <Route path="/project/list" component={ProjectList} />
* <Route path="/project/:id" component={ProjectDetail} />
* </Route>
* <Route path="/" component={Layout3}>
* <Route path="/user/list" component={UserList} />
* <Route path="/user/:id" component={User} />
* <Route path="/page/list" component={PageList} />
* <Route path="/page/:id" component={PageDetail} />
* </Route>
* </Switch>
*/
const App = () => {
render() {
return (
<Switch>
// 实现部分略
</Switch>
);
}
};
export default App; 优点
缺点
第三种: routerConfig.js 如下: import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
import Page3 from './pages/Page3';
import Page4 from './pages/Page4';
import Page5 from './pages/Page5';
import Layout1 from './layouts/layout1';
import Layout2 from './layouts/layout2';
import Layout3 from './layouts/layout3';
export default [
{
path: '/help',
component: Page3,
layout: Layout2
},
{
path: '/about',
component: Page3,
layout: Layout2
},
{
path: '/project',
layout: Layout1,
children: [
{
path: '/project/list',
component: Page1
},
{
path: '/project/:id',
component: Page2
},
]
},
{
path: '/user',
layout: Layout3,
children: [
{
path: '/user/list',
component: Page3
},
{
path: '/user/:id',
component: Page4
},
{
path: '/page/list',
component: Page5
},
{
path: '/page/:id',
component: Page6
}
]
}
]; router.js 如下: import routerConfig from './routerConfig';
import React from 'react';
/**
* 路由结构和 routerConfig 协议保持一致
*
* <Switch>
* <Route path="/help" component={Layout2+Component} />
* <Route path="/about" component={Layout2+Component} />
* <Route path="/project" component={Layout1}>
* <Route path="/project/list" component={ProjectList} />
* <Route path="/project/:id" component={ProjectDetail} />
* </Route>
* <Route path="/user" component={Layout3}>
* <Route path="/user/list" component={UserList} />
* <Route path="/user/:id" component={User} />
* <Route path="/page/list" component={PageList} />
* <Route path="/page/:id" component={PageDetail} />
* </Route>
* </Switch>
*/
const App = () => {
render() {
return (
<Switch>
// 实现部分略
</Switch>
);
}
};
export default App; 优点
缺点 |
@chenbin92 试了下不用 |
第二种实现代码如下:
export default function Layout1(props) {
return (
<div>
<div>Layout1</div>
{props.children}
</div>
);
}
export default function Layout2(props) {
return (
<div>
<div>Layout2</div>
{props.children}
</div>
);
}
export default function Layout3(props) {
return (
<div>
<div>Layout2</div>
{props.children}
</div>
);
}
import Index from './pages/index';
import Home from './pages/Home';
import About from './pages/About';
import Layout1 from './layouts/Layout1';
import Layout2 from './layouts/Layout2';
import Layout3 from './layouts/Layout3';
/*
* @TODO: 这里未来做一件事:需要保证路由顺序,如 /project、/project/list,需要把 /project/list 提前(或者这步算法放到 iceworks 中实现)
*/
const routerConfig = [
{
path: '/',
component: Index,
exact: true,
},
{
path: '/home',
component: Home,
layout: Layout1
},
{
path: '/about',
component: About,
layout: Layout1
},
{
path: '/project/list',
component: ProjectList,
layout: Layout2,
exact: true,
},
{
path: '/project/:id(\\d+)',
component: ProjectDetail,
layout: Layout2
},
{
path: '/user/list',
component: UserList,
layout: Layout3
},
{
path: '/user/:id(\\d+)',
component: UserDetail,
layout: Layout3
},
{
path: '/page/list',
component: PageList,
layout: Layout3
},
{
path: '/page/:id(\\d+)',
component: PageDetail,
layout: Layout3
}
];
export default routerConfig;
import React from 'react';
import { Switch, Route, Link } from 'react-router-dom';
import routerConfig from './routerConfig';
const routerConfigGroup = groupByLayout(routerConfig);
export default function App() {
return (
<Switch>
{routerConfigGroup.map((group) => {
return (
<Route component={group.layout}>
{group.children.map((item) => {
return (
<Route exact={item.exact} path={item.path} component={item.component} />
);
})}
</Route>
);
})}
</Switch>
);
}
/**
* 先分组生成如下结构
* [{
* layout: Layout1,
* children: [{
* path: '/page/list',
* component: PageList
* }]
* }]
**/
function groupByLayout(list) {
return list.reduce((reduceList, item) => {
const findParentLayout = reduceList.find(reduceItem => reduceItem.layout === item.layout);
if (findParentLayout) {
findParentLayout.children.push({
path: item.path,
component: item.component,
});
} else {
reduceList.push({
layout: item.layout,
children: [{
path: item.path,
component: item.component,
exact: item.exact,
}]
});
}
return reduceList;
}, []);
}; |
|
就是没有 Layout 就只渲染当前组件吧,有的话就进行分组归类。 没问题了 |
翻到一个 stackoverflow 关于 layout 共用以及嵌套路由的讨论 以及官方也给出了共用 layout 的例子,得出路由第四种方案:
import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
import Page3 from './pages/Page3';
import Page4 from './pages/Page4';
import Page5 from './pages/Page5';
import Layout1 from './layouts/layout1';
import Layout3 from './layouts/layout3';
export default [
{
path: '/help',
component: Page3,
},
{
path: '/about',
component: Page3,
},
{
path: '/project',
component: Layout1,
routes: [
{
path: '/project/list',
component: Page1
},
{
path: '/project/:id',
component: Page2
},
]
},
{
path: '/user',
component: Layout3,
routes: [
{
path: '/user/list',
component: Page3
},
{
path: '/user/:id',
component: Page4
},
{
path: '/user/page/list',
component: Page5
},
{
path: '/user/page/:id',
component: Page6
}
]
}
];
具体实现参考 例子 优点
缺点
|
路由数据定义: // src/config/routes.js
import BasicLayout from '@/layouts/BasicLayout';
import Home from '@/pages/Home';
import ProjectList from '@/pages/ProjectList';
import ProjectDetail from '@/pages/ProjectDetail';
const routes = [{
path: '/',
component: Home,
layout: BasicLayout,
exact: true,
}, {
path: '/project',
layout: BasicLayout,
children: [{
path: '/detail',
component: ProjectDetail,
}, {
path: '/list',
component: ProjectList,
}],
}];
export default routes; 路由定义与渲染: // src/router.jsx
<Router basename={getBasename()}>
<Switch>
{routes.map((route, id) => {
const { component, layout, children, ...others } = route;
if (!children) {
const RouteLayout = layout;
const RouteComponent = component;
return (
<Route
{...others}
component={(props) => {
return (
<RouteLayout key={id}>
<RouteComponent {...props} />
</RouteLayout>
);
}}
/>
);
} else {
const RouteLayout = component;
return (
<RouteLayout key={id}>
<Switch>
{route.children.map((routeChild, idx) => {
routeChild.path = path.join(route.path, routeChild.path);
const RouteComponent = routeChild.component;
return (
<Route
key={`${id}-${idx}`}
{...routeChild}
component={RouteComponent}
/>
);
})}
</Switch>
</RouteLayout>
);
}
})}
</Switch>
</Router> |
* feat: add navigation and router config #2031 * chore: lint error * refactor: add routes to router * chore: change cn to cx * fix: fix routeConfig bug and code lint * chore: change navgation global scss * feat: add router and navigation when create page (#2173) * feat: add router and navigation when create page * chore: first create page * chore: fix code lint * chore: fix code lint * chore: improve interaction * style: change menu tree style * chore: fix code lint * chore: change style inject
config中还缺少Redirect和未匹配路由的配置,写了个提案,大家看下 @imsobear @boiawang @chenbin92 @alvinhui 在config中增加以下两种配置:
config配置: const routerConfig = [
{
path: '/user',
component: UserLayout,
routes: [
{
path: '/login',
component: UserLogin,
},
{
component: NotFound, // 无path代表未匹配路由
}
]
},
{
path: '/',
component: BasicLayout,
routes: [
{
path: '/dashboard/monitor',
component: Dashboard,
},
{
path: '/', // 有redirect属性渲染为Redirect,可配置多个
redirect: '/dashboard/monitor'
},
{
path: '/login',
redirect: '/user/login'
},
{
component: NotFound, // 无path代表未匹配路由
}
}
] router.js渲染逻辑: <Router>
<Switch>
{routes.map((route, id) => {
const { component, children, ...others } = route;
const RouteComponent = component;
return (
<Route
key={id}
{...others}
component={(props) => {
return (
<RouteComponent key={id} {...props}>
{children && (
<Switch>
{/* 普通路由 */}
{children.filter(routeChild => routeChild.path && routeChild.component)
.map((routeChild, idx) => {
const { component } = routeChild;
return (
<Route
key={`route-${id}-${idx}`}
component={component}
path={path.join(route.path, routeChild.path)}
/>
);
})}
{/* Redirect路由 */}
{children.filter(routeChild => routeChild.redirect)
.map((routeChild, idx) => {
const { redirect } = routeChild;
return (
<Redirect
key={`redirect-${id}-${idx}`}
exact
from={path.join(route.path, routeChild.path)}
to={redirect}
/>
);
})}
{/* 未匹配路由 */}
{children.filter(routeChild => !routeChild.path)
.map((routeChild, idx) => {
const { component } = routeChild;
return (
<Route
key={`notfound-${id}-${idx}`}
component={component}
/>
);
})}
</Switch>
)}
</RouteComponent>
);
}}
/>
);
})}
</Switch>
</Router> 该方案有个缺点是由于layout分组的存在,未匹配路由需要在每个分组下定义一次,如果定义在与layout平级,由于BasicLayout的路由是'/',路由会进入BasiceLayout走不到未匹配路由。 另外layout这个字段感觉对用户有一定理解成本,直接用component代替是否更好,也可以再讨论下。 |
第一种方案,在 children 中增加 redirect 类型: const routerConfig = [
{
path: '/user',
component: UserLayout,
children: [
{
path: '/login',
component: UserLogin,
},
{
path: '/',
redirect: '/user/login'
},
{
component: NotFound, // 无path代表未匹配路由
}
]
},
{
path: '/',
component: BasicLayout,
children: [
{
path: '/dashboard/monitor',
component: Dashboard,
},
{
path: '/', // 有from和to属性渲染为Redirect,可配置多个
redirect: '/dashboard/monitor'
},
{
component: NotFound, // 无path代表未匹配路由
}
]
}
]; 第二种方案: 这个方案有个问题,需要在 const routerConfig = [
{
path: '/user',
component: UserLayout,
children: [
{
path: '/login',
component: UserLogin,
},
{
component: NotFound, // 无path代表未匹配路由
}
]
},
{
path: '/',
component: BasicLayout,
children: [
{
path: '/dashboard/monitor',
component: Dashboard,
},
{
component: NotFound, // 无path代表未匹配路由
}
]
}
];
const redirectConfig = [
{
from: '/', // 需要根据 from 匹配到 routerConfig 哪一组,将 Redirect 塞到某个 layout 下
to: '/dashboard/monitor',
},
{
from: '/user',
to: '/user/login'
},
]; 第三种方案: 需要有个理解成本,redirectConfig 是根节点的 redirects,每个 layout 有自己的 redirects const routerConfig = [
{
path: '/user',
component: UserLayout,
// layout 下有自己的 redirects
redirects: [
{
from: '/user',
to: '/user/login'
},
],
children: [
{
path: '/login',
component: UserLogin,
},
{
component: NotFound, // 无path代表未匹配路由
}
]
},
{
path: '/',
component: BasicLayout,
redirects: [
{
from: '/',
to: '/dashboard/monitor',
},
],
children: [
{
path: '/dashboard/monitor',
component: Dashboard,
},
{
component: NotFound, // 无path代表未匹配路由
}
]
},
{
path: '/list',
component: List
},
];
// 这里放根节点的 redirects
const redirectConfig = [
{
from: '/a',
to: '/list',
},
]; 以上方案,我比较支持第一种,有更好的方案可以提供。 |
最终方案如下:
import React from 'react';
import UserLayout from './layouts/UserLayout';
import BasicLayout from './layouts/BasicLayout';
const UserLogin = React.lazy(() => import('./pages/UserLogin'));
const UserRegister = React.lazy(() => import('./pages/UserRegister'));
const Dashboard = React.lazy(() => import('./pages/Dashboard'));
const Charts = React.lazy(() => import('./pages/Charts'));
const BasicCharts = React.lazy(() => import('./pages/BasicCharts'));
const Terms = React.lazy(() => import('./pages/Terms'));
const Result = React.lazy(() => import('./pages/Result'));
const BasicList = React.lazy(() => import('./pages/BasicList'));
const ProjectList = React.lazy(() => import('./pages/ProjectList'));
const BasicTable = React.lazy(() => import('./pages/BasicTable'));
const GeneralTable = React.lazy(() => import('./pages/GeneralTable'));
const Profile = React.lazy(() => import('./pages/Profile'));
const Setting = React.lazy(() => import('./pages/Setting'));
const Fail = React.lazy(() => import('./pages/Fail'));
const Empty = React.lazy(() => import('./pages/Empty'));
const Forbidden = React.lazy(() => import('./pages/Forbidden'));
const NotFound = React.lazy(() => import('./pages/NotFound'));
const ServerError = React.lazy(() => import('./pages/ServerError'));
const routerConfig = [
{
path: '/user',
component: UserLayout,
children: [
{
path: '/login',
component: UserLogin,
},
{
path: '/register',
component: UserRegister,
},
{
path: '/',
redirect: '/user/login',
},
{
component: NotFound,
},
],
},
{
path: '/',
component: BasicLayout,
children: [
{
path: '/dashboard/monitor',
component: Dashboard,
},
{
path: '/chart/general',
component: Charts,
},
{
path: '/chart/basic',
component: BasicCharts,
},
{
path: '/list/basic',
component: BasicList,
},
{
path: '/list/general',
component: ProjectList,
},
{
path: '/result/success',
component: Result,
},
{
path: '/result/fail',
component: Fail,
},
{
path: '/table/basic',
component: BasicTable,
},
{
path: '/profile/basic',
component: Profile,
},
{
path: '/profile/general',
component: Terms,
},
{
path: '/table/general',
component: GeneralTable,
},
{
path: '/account/setting',
component: Setting,
},
{
path: '/exception/500',
component: ServerError,
},
{
path: '/exception/403',
component: Forbidden,
},
{
path: '/exception/204',
component: Empty,
},
{
path: '/exception/404',
component: NotFound,
},
{
// Redirect 重定向
path: '/',
redirect: '/dashboard/monitor',
},
{
// 404 没有匹配到的路由
component: NotFound,
},
],
},
];
export default routerConfig;
import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
import React, { Suspense } from 'react';
import path from 'path';
import routes from '@/routerConfig';
import PageLoading from '@/components/PageLoading';
const RouteItem = (props) => {
const { redirect, path: routePath, component, key } = props;
if (redirect) {
return (
<Redirect
exact
key={key}
from={routePath}
to={redirect}
/>
);
}
return (
<Route
key={key}
component={component}
path={routePath}
/>
);
};
const router = () => {
return (
<Router>
<Switch>
{routes.map((route, id) => {
const { component: RouteComponent, children, ...others } = route;
return (
<Route
key={id}
{...others}
component={(props) => {
return (
children ? (
<RouteComponent key={id} {...props}>
<Suspense fallback={<PageLoading />}>
<Switch>
{children.map((routeChild, idx) => {
const { redirect, path: childPath, component } = routeChild;
return RouteItem({
key: `${id}-${idx}`,
redirect,
path: childPath && path.join(route.path, childPath),
component,
});
})}
</Switch>
</Suspense>
</RouteComponent>
) : (
<Suspense fallback={<PageLoading />}>
{
RouteItem({
key: id,
...props,
})
}
</Suspense>
)
);
}}
/>
);
})}
</Switch>
</Router>
);
};
export default router; |
* feat: add navigation and router config #2031 * chore: lint error * refactor: add routes to router * chore: change cn to cx * fix: fix routeConfig bug and code lint * chore: change navgation global scss * feat: add router and navigation when create page (#2173) * feat: add router and navigation when create page * chore: first create page * chore: fix code lint * chore: fix code lint * chore: improve interaction * style: change menu tree style * feat: add header menu config tab * chore: change return type * chore: remove external link text * chore: remove useless file * chore: flat datasource in menustore * chore: change create router interaction * chore: layout do not use lazy * chore: remove page remove router and menu * fix: remove path must exist * fix: lint * chore: lint code * chore: fix disabled boolean * chore: intl optimization
* feat: stark biz template support * feat: stark biz template support * fix: update template package * chore: fix lint * chore: code optim * refactor: code optim * fix: catch open editor error * refacotr: refactor socket logic * fix: add some tips in material page * fix: repeat listen * fix: use NoData component * fix: fix typos (#2191) * fix: fix typos * fix: use injectIntl instead FormattedMessage * fix: fix tslint & code style * [iceworks]feat: add navigation and router config #2031 (#2107) * feat: add navigation and router config #2031 * chore: lint error * refactor: add routes to router * chore: change cn to cx * fix: fix routeConfig bug and code lint * chore: change navgation global scss * feat: add router and navigation when create page (#2173) * feat: add router and navigation when create page * chore: first create page * chore: fix code lint * chore: fix code lint * chore: improve interaction * style: change menu tree style * chore: fix code lint * chore: change style inject * refactor: remove panel setting * refactor: remove env * refactor: rename guide to quick start * refactor: Slimming Server (#2192) * refactor: storage for adapter * refactor: keep adapter module method params as same * refactor: socket emit * refactor: remove controller * refactor: rename API project to adapter * refactor: rewrite by review * chore: merge router and menu * refactor: router and menu * refactor: project.adapter * chore: code style * fix: event name (#2206) * fix: same of warning (#2208) * fix: add rename to set (#2211) * fix: array type * feat: add start guide * feat: support dark theme in material page (#2210) * refactor: material category (#2215) * refactor: category define in server * chore: rename api * chore: a to span * chore: lint * feat: write log to global * feature: project panels settings * feat: init panel settings * feat: set panel is available * feat: sortable for panels * feat: style for panel settings * feat: filter panel settings * chore: rename * feat: refresh panel store when panel is set to available * feat: add infos to Router and Menu * fix: merge bug * fix: same of warning * fix: add rename to set * refactor: category define in server * chore: rename api * chore: a to span * chore: lint * refactor: useProject * fix: do not need map twice time * chore: rename * fix: sort panel * refactor: refactor panel setting * refacotr: separate panle config * feat: todo panel (#2213) * feat: todo panel * fix: use reddir & fix code * fix: add file filter * feat: show start guide panel * feat: todo config support * [优化] Icon 优化 (#2225) * chore: icon upgrade * fix: code lint * fix: task setting * chore: remove log * feature: page builder * fix: fix theme init bug & locale (#2232) * fix: fix locale * fix: fix theme init * fix: remove locale * refactor: style checking (#2233) * chore: fix icon bug * chore: icon tooltip upgrade * chore: create router error tips * feat: add changeId && bug fix * chore: add changeId for app.ts * feat: server i18n (#2246) * refactor: refactor adapter * fix: dev start error due to teminal not initiated * fix: upperCamelCase module name * chore: remove unnecessary field * fix: add interface * fix: dev status lost * fix: adapter middleware error * fix: dev status lost * fix: dev start error due to teminal not initiated (#2259) * fix: PR review * fix: lint * fix: dev status lost (#2262) * fix: dev start error due to teminal not initiated * fix: dev status lost * fix: dev status lost * fix: PR review * fix: lint * fix: remame adapter (#2268) * feat: hide settings when ice.config.js not found * fix: user refresh would trigger setState which will lead to infinite render * fix: fix module name (#2271) * feat: dynamic load adapter * fix: change lodash import (#2272) * feat: add react v1,v2, v3 adapter * feat: no adapter hint * chore: remove unused dependencies * feat: start web server for iceworks * fix: router adapter path * chore: base adpater use kit v3.0 structure * fix: lint * feat: revert icestore related PR * fix: fix todo icon (#2279) * chore: remove unused field * chore: update default adapter * fix: PR review suggestions * [Iceworks]vue adapter (#2280) * feat: add vue adapter * fix: change doc name * feat: adapter support extends * fix: fix config * fix: fix type & filename * fix: limit project name length * feat: show current theme * feat: support xterm closed * fix: different task's status save in global (#2288) * feat: navigation optim * feat: add navigation and router config #2031 * chore: lint error * refactor: add routes to router * chore: change cn to cx * fix: fix routeConfig bug and code lint * chore: change navgation global scss * feat: add router and navigation when create page (#2173) * feat: add router and navigation when create page * chore: first create page * chore: fix code lint * chore: fix code lint * chore: improve interaction * style: change menu tree style * feat: add header menu config tab * chore: change return type * chore: remove external link text * chore: remove useless file * chore: flat datasource in menustore * chore: change create router interaction * chore: layout do not use lazy * chore: remove page remove router and menu * fix: remove path must exist * fix: lint * chore: lint code * chore: fix disabled boolean * chore: intl optimization * fix: display none style which result to xterm width not 100% (#2289) * feature: 前台一些异步操作后的 UI 处理 (#2290) * feat: global bar state as store * feat: async show log * refactor: use store.writeLog * chore: lint * feat: add node remote log * fix: fix comment * chore: folder structure optimize * fix: getRecommendScaffolds * fix: project name overflow * fix: icestore dependency & user data fetch * fix: do not show panel setting when no projects * fix: Git 面板相关 Bug (#2298) * fix: git status handle error * fix: refresh git store after updated remote url * fix: git get branches * feat: show tip when no file changes * feat: support theme * feat: support multiple languages for the guide panel * feat: add interaction effects * chore: rename setting panel * refactor: refactor task logic * chore: move task modal * feat: quick run task support * fix: material page bugfix (#2231) * fix: force check lazyload components after category change * feat: delete material confirm * fix: fix linter error * chore: update english tips * chore: fix typo * feat: i18n support * chore: add @babel/runtime * fix: lint error (#2306) * feature: refactor panel head * refactor: title & description for panels * feat: panel head * chore: remove title * refactor: remove style * refactor: change PanelHead props * fix: use current theme * fix: set xterm height * chore: add onBeforeunload * fix: ast parse error * chore: fix typo * fix: larger tab size (#2312) * refactor: refactor theme * chore: fix lint * chore: code optim * chore: fix lint * fix: fix dev task * refactor: refactor panel head * refactor: refactor register store * refactor: load adapter optim * fix: remove adapter router * fix: add package error * feat: add goldlog * feat: browser delect * feat: optimize tip icon (#2320) * [iceworks] feat i18n log (#2314) * feat: i18n log replace * fix: fix plugin load * fix: fix vue config * feat: add en-us config * fix: fix adapter update * fix: fix type * refactor: status rename to isWorking * refactor: refactor writeGlobalLog * Fix vue adapter (#2323) * fix: fix vue config * fix: rm des * fix: add quick task config * fix: clear log error * fix: hide categories panel when only one category (#2328) * fix: hide categories when categories.length <=1 * chore: add MaterialPanel component * fix: engineering configuration write failed * fix: hide the build panel by default * fix: kill process pid * fix: fix i18n setting (#2332) * fix: fix git panel bug * feat: add log * chore: rename gloglog to goldlog * fix: add scripts files * iceworks/cli (#2336) * chore: fix typo * feat: add log * chore: rename gloglog to goldlog * Adapter 根据条件决定前端面板是否显示 (#2319) * chore: notes of method * feat: filter panels * chore: remove console * chore: simple code * feat: dynamic set port * fix: page panel bugs * fix: fix git branch * chore: rename * fix: block dir * chore: fix lint * [iceworks] optimization routerConfig * chore: optimization style * chore: routerConfig import support @ * feat: create page do not display router group when no groups * fix: fix lint * chore: code optim * feat: reload adapter support * feat: i18n * feat: add adapter docs * chore: fix lint * chore: fix typo * feat: need to pass parameter --sticky when starting the cluster * chore: remove mock data * chore: code optim * fix: no need * Project panel bug fix (#2347) * fix: repeated listen * fix: set reset modal if project is verified * fix: page form style * fix: fix tarball download * feature: refresh project panel when page is visible (#2348) * fix: repeated listen * fix: set reset modal if project is verified * fix: page form style * feat: useVisibilityChange * feat: set notes * [iceworks] fix: adpater-react-v1 getConfCLI error (#2353) * fix: adpater-react-v1 getConf error * fix: lint * feat: refactor log data structure * chore: code optim * feat: refresh adapter's locale * fix: always ensure consistency of return values of functions * fix: fix open editor bug (#2360) * chore: adjust style * feat: new materials (#2366) * style: code formatting * feat: generate project (#2364) * [iceworks] add loading and error status to async actions (#2349) * feat: add ActionStatus Component used to render async actions' status * fix: action return * feat: add catch for refresh * fix: new store logic * fix: set reset modal is projectStore is validate * chore: hasProjects * feat: use modal loading for async * fix: if project refresh error do not refresh panels * feat: page set loading and error * feat: showMessage * fix: typo * fix: typo * feat: loading && error for layout * feat: loading && error for menu * feat: loading && error for git * refactor: use showMessage * refactor: use showMessage * refactor: use showMessage * refactor: use showMessage * chore: lint * feat: add catch and error handler * feat: loading and error for dependency * fix: add timeout for error * feat: add errorType * feat: add notFound & redirect path * feat: create router add global valid * fix: state modify error * fix: lint * fix: router store * fix: MenuPanel children proptype * fix: remove page remove routers * fix: lint * feat: loading for buildPage * fix: lint * feat: add loading theme * fix: define isLoading * fix: error message style * fix: lint * feat: adjust code * chore: remove useless * fix: err fix * chore: release 3.0-beta (#2363) * chore: update package version * chore: update version
背景
原先方案存在的问题:
路由方案
最终方案如下:
src/config/routes.js
文件内容src/router.jsx
可视化管理路由
功能
路由管理
菜单管理
The text was updated successfully, but these errors were encountered: