diff --git a/docs/en/develop/3-1-BaseList-introduction.md b/docs/en/develop/3-1-BaseList-introduction.md index d3379977..f8fca269 100644 --- a/docs/en/develop/3-1-BaseList-introduction.md +++ b/docs/en/develop/3-1-BaseList-introduction.md @@ -175,7 +175,7 @@ English | [Chinese](../../zh/develop/3-1-BaseList-introduction.md) { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/compute/${this.getUrl('image')}/detail`, + routeName: this.getRouteName('imageDetail'), }, { title: t('Project ID/Name'), @@ -526,7 +526,7 @@ English | [Chinese](../../zh/develop/3-1-BaseList-introduction.md) - Is the current page a "management platform" page - `hasAdminRole` - Whether the logged-in user role has an administrator role -- `getUrl` +- `getRoutePath` - Function to generate page URL - For example, it is necessary to provide a jump function to the associated resources of the list page. Using this function, you can jump to the corresponding address of the console in the console, and jump to the corresponding address of the management platform in the management platform. - `params` diff --git a/docs/en/develop/3-2-BaseTabList-introduction.md b/docs/en/develop/3-2-BaseTabList-introduction.md index 39f87b18..ed51347c 100644 --- a/docs/en/develop/3-2-BaseTabList-introduction.md +++ b/docs/en/develop/3-2-BaseTabList-introduction.md @@ -114,7 +114,7 @@ English | [Chinese](../../zh/develop/3-2-BaseTabList-introduction.md) - Is the current page a "management platform" page - `hasAdminRole` - Whether the logged-in user role has an administrator role -- `getUrl` +- `getRoutePath` - Function to generate page URL - For example, it is necessary to provide a jump function for the associated resources of the list page. Using this function, you can jump to the corresponding address of the console in the console, and jump to the corresponding address of the management platform in the management platform. diff --git a/docs/en/develop/3-3-BaseDetail-introduction.md b/docs/en/develop/3-3-BaseDetail-introduction.md index cb640fb4..bad891ba 100644 --- a/docs/en/develop/3-3-BaseDetail-introduction.md +++ b/docs/en/develop/3-3-BaseDetail-introduction.md @@ -72,7 +72,7 @@ English | [Chinese](../../zh/develop/3-3-BaseDetail-introduction.md) ```javascript get listUrl() { - return this.getUrl('/storage/volume'); + return this.getRoutePath('volume'); } ``` @@ -241,7 +241,7 @@ English | [Chinese](../../zh/develop/3-3-BaseDetail-introduction.md) - `id` in routing information - `isAdminPage` - Is the current page a "management platform" page -- `getUrl` +- `getRoutePath` - Function to generate page URL - For example, it is necessary to provide a jump function to the associated resource. Using this function, you can jump to the corresponding address of the console in the console, and jump to the corresponding address of the management platform in the management platform. - `routing` diff --git a/docs/en/develop/3-4-BaseDetailInfo-introduction.md b/docs/en/develop/3-4-BaseDetailInfo-introduction.md index db0cd1bf..642e75b4 100644 --- a/docs/en/develop/3-4-BaseDetailInfo-introduction.md +++ b/docs/en/develop/3-4-BaseDetailInfo-introduction.md @@ -131,7 +131,7 @@ English | [Chinese](../../zh/develop/3-4-BaseDetailInfo-introduction.md) - `id` in routing information - `isAdminPage` - Is the current page a "management platform" page -- `getUrl` +- `getRoutePath` - Function to generate page URL - For example, it is necessary to provide a jump function to the associated resource. Using this function, you can jump to the corresponding address of the console in the console, and jump to the corresponding address of the management platform in the management platform. - `routing` diff --git a/docs/en/develop/3-6-FormAction-introduction.md b/docs/en/develop/3-6-FormAction-introduction.md index 8e8e63d5..54c283d0 100644 --- a/docs/en/develop/3-6-FormAction-introduction.md +++ b/docs/en/develop/3-6-FormAction-introduction.md @@ -147,7 +147,7 @@ English | [Chinese](../../zh/develop/3-6-FormAction-introduction.md) ```javascript get listUrl() { - return this.getUrl('/storage/volume'); + return this.getRoutePath('volume'); } ``` @@ -381,7 +381,7 @@ English | [Chinese](../../zh/develop/3-6-FormAction-introduction.md) - After the form is successfully validated, the updated form value - `isAdminPage` - Is the current page a "management platform" page -- `getUrl` +- `getRoutePath` - Function to generate page URL - For example, it is necessary to provide a jump function to the associated resource. Using this function, you can jump to the corresponding address of the console in the console, and jump to the corresponding address of the management platform in the management platform. diff --git a/docs/en/develop/3-9-StepAction-introduction.md b/docs/en/develop/3-9-StepAction-introduction.md index e0d18538..11954094 100644 --- a/docs/en/develop/3-9-StepAction-introduction.md +++ b/docs/en/develop/3-9-StepAction-introduction.md @@ -286,7 +286,7 @@ English | [简体中文](../../zh/develop/3-9-StepAction-introduction.md) - `isAdminPage` - Whether current page is a "management platform" page -- `getUrl` +- `getRoutePath` - Generate function of page URL - Such as: need to provide a ability of jump to the associated resource, use this function, you can jump to the corresponding address of the `console platform` in the `console platform`, and jump to the corresponding address of the `management platform` in the `management platform`. diff --git a/docs/zh/develop/3-1-BaseList-introduction.md b/docs/zh/develop/3-1-BaseList-introduction.md index 369cb3cc..d9525caf 100644 --- a/docs/zh/develop/3-1-BaseList-introduction.md +++ b/docs/zh/develop/3-1-BaseList-introduction.md @@ -175,7 +175,7 @@ { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/compute/${this.getUrl('image')}/detail`, + routeName: this.getRouteName('imageDetail'), }, { title: t('Project ID/Name'), @@ -526,7 +526,7 @@ - 当前页面是否是“管理平台”的页面 - `hasAdminRole` - 登录的用户角色是否具有管理员角色 -- `getUrl` +- `getRoutePath` - 生成页面 Url 的函数 - 如:需要给列表页的关联资源提供跳转功能,使用该函数,可以在控制台跳转到控制台的相应地址,在管理平台跳转到管理平台的相应地址 - `params` diff --git a/docs/zh/develop/3-2-BaseTabList-introduction.md b/docs/zh/develop/3-2-BaseTabList-introduction.md index fa3a2924..14b28d7a 100644 --- a/docs/zh/develop/3-2-BaseTabList-introduction.md +++ b/docs/zh/develop/3-2-BaseTabList-introduction.md @@ -114,7 +114,7 @@ - 当前页面是否是“管理平台”的页面 - `hasAdminRole` - 登录的用户角色是否具有管理员角色 -- `getUrl` +- `getRoutePath` - 生成页面 Url 的函数 - 如:需要给列表页的关联资源提供跳转功能,使用该函数,可以在控制台跳转到控制台的相应地址,在管理平台跳转到管理平台的相应地址 diff --git a/docs/zh/develop/3-3-BaseDetail-introduction.md b/docs/zh/develop/3-3-BaseDetail-introduction.md index 04f7b7ea..15078bb8 100644 --- a/docs/zh/develop/3-3-BaseDetail-introduction.md +++ b/docs/zh/develop/3-3-BaseDetail-introduction.md @@ -72,7 +72,7 @@ ```javascript get listUrl() { - return this.getUrl('/storage/volume'); + return this.getRoutePath('volume'); } ``` @@ -241,7 +241,7 @@ - 路由信息中的`id` - `isAdminPage` - 当前页面是否是“管理平台”的页面 -- `getUrl` +- `getRoutePath` - 生成页面 Url 的函数 - 如:需要给关联资源提供跳转功能,使用该函数,可以在控制台跳转到控制台的相应地址,在管理平台跳转到管理平台的相应地址 - `routing` diff --git a/docs/zh/develop/3-4-BaseDetailInfo-introduction.md b/docs/zh/develop/3-4-BaseDetailInfo-introduction.md index 0f65e40f..d8454b37 100644 --- a/docs/zh/develop/3-4-BaseDetailInfo-introduction.md +++ b/docs/zh/develop/3-4-BaseDetailInfo-introduction.md @@ -131,7 +131,7 @@ - 路由信息中的`id` - `isAdminPage` - 当前页面是否是“管理平台”的页面 -- `getUrl` +- `getRoutePath` - 生成页面 Url 的函数 - 如:需要给关联资源提供跳转功能,使用该函数,可以在控制台跳转到控制台的相应地址,在管理平台跳转到管理平台的相应地址 - `routing` diff --git a/docs/zh/develop/3-6-FormAction-introduction.md b/docs/zh/develop/3-6-FormAction-introduction.md index 9f3aec80..594f221f 100644 --- a/docs/zh/develop/3-6-FormAction-introduction.md +++ b/docs/zh/develop/3-6-FormAction-introduction.md @@ -147,7 +147,7 @@ ```javascript get listUrl() { - return this.getUrl('/storage/volume'); + return this.getRoutePath('volume'); } ``` @@ -381,7 +381,7 @@ - 表单验证成功后,更新的表单值 - `isAdminPage` - 当前页面是否是“管理平台”的页面 -- `getUrl` +- `getRoutePath` - 生成页面 Url 的函数 - 如:需要给关联资源提供跳转功能,使用该函数,可以在控制台跳转到控制台的相应地址,在管理平台跳转到管理平台的相应地址 diff --git a/docs/zh/develop/3-9-StepAction-introduction.md b/docs/zh/develop/3-9-StepAction-introduction.md index 0925c59e..3292a1e0 100644 --- a/docs/zh/develop/3-9-StepAction-introduction.md +++ b/docs/zh/develop/3-9-StepAction-introduction.md @@ -282,7 +282,7 @@ - 表单验证成功后,更新的表单值 - `isAdminPage` - 当前页面是否是“管理平台”的页面 -- `getUrl` +- `getRoutePath` - 生成页面 Url 的函数 - 如:需要给关联资源提供跳转功能,使用该函数,可以在控制台跳转到控制台的相应地址,在管理平台跳转到管理平台的相应地址 diff --git a/src/components/Form/index.jsx b/src/components/Form/index.jsx index 1af0f841..c321c8d3 100644 --- a/src/components/Form/index.jsx +++ b/src/components/Form/index.jsx @@ -22,6 +22,7 @@ import { isAdminPage, firstUpperCase, unescapeHtml } from 'utils/index'; import { parse } from 'qs'; import FormItem from 'components/FormItem'; import { CancelToken } from 'axios'; +import { getPath, getLinkRender } from 'utils/route-map'; import styles from './index.less'; export default class BaseForm extends React.Component { @@ -137,6 +138,20 @@ export default class BaseForm extends React.Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + + getLinkRender(routeName, value, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getLinkRender({ key: realName, params, query, value }); + } + get isStep() { return false; } diff --git a/src/components/FormItem/MemberAllocator/index.jsx b/src/components/FormItem/MemberAllocator/index.jsx index 0c2d3dfc..ccfa5c91 100644 --- a/src/components/FormItem/MemberAllocator/index.jsx +++ b/src/components/FormItem/MemberAllocator/index.jsx @@ -18,8 +18,8 @@ import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; import SelectTable from 'components/FormItem/SelectTable'; import { ipValidate } from 'utils/validate'; import { isAdminPage } from 'utils/index'; -import { Link } from 'react-router-dom'; import { Address4, Address6 } from 'ip-address'; +import { getLinkRender } from 'utils/route-map'; import Item from './Item'; const { isIPv4, isIpv6 } = ipValidate; @@ -34,9 +34,11 @@ const MemberAllocator = ({ componentProps, formItemProps }) => { onChange && onChange(data); }; - function getUrl(path, adminStr) { + function getLink(routerName, item) { const { pathname } = window.location; - return isAdminPage(pathname) ? `${path}${adminStr || '-admin'}` : path; + const key = isAdminPage(pathname) ? `${routerName}Admin` : routerName; + const { id } = item; + return getLinkRender({ key, params: { id }, value: id }); } let addOuter = () => {}; @@ -60,16 +62,7 @@ const MemberAllocator = ({ componentProps, formItemProps }) => { dataIndex: 'name', render: (n, record) => (
-
- - {record.id} - -
+
{getLink('virtualAdapterDetail', record)}
{n || '-'}
), diff --git a/src/components/FormItem/NetworkSelectTable/index.jsx b/src/components/FormItem/NetworkSelectTable/index.jsx index aeb32766..bfaede27 100644 --- a/src/components/FormItem/NetworkSelectTable/index.jsx +++ b/src/components/FormItem/NetworkSelectTable/index.jsx @@ -19,6 +19,7 @@ import { NetworkStore } from 'stores/neutron/network'; import { yesNoOptions } from 'utils/constants'; import { networkColumns, networkSortProps } from 'resources/network'; import { isAdminPage } from 'utils/index'; +import { getPath } from 'utils/route-map'; export class NetworkSelectTable extends Component { constructor(props) { @@ -87,8 +88,13 @@ export class NetworkSelectTable extends Component { ...networkSortProps, }); - getUrl(path, adminStr) { - return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); } getColumns = (tab) => { diff --git a/src/components/FormItem/VolumeSelectTable/index.jsx b/src/components/FormItem/VolumeSelectTable/index.jsx index 75020075..f3043b73 100644 --- a/src/components/FormItem/VolumeSelectTable/index.jsx +++ b/src/components/FormItem/VolumeSelectTable/index.jsx @@ -67,8 +67,6 @@ export default class VolumeSelectTable extends Component { ...volumeSortProps, }); - getUrl = () => {}; - getColumns = (tab) => { const columns = volumeColumns; const { key } = tab; diff --git a/src/components/StepForm/index.jsx b/src/components/StepForm/index.jsx index 51c71eea..4998c20c 100644 --- a/src/components/StepForm/index.jsx +++ b/src/components/StepForm/index.jsx @@ -20,6 +20,7 @@ import classnames from 'classnames'; import { firstUpperCase, unescapeHtml } from 'utils/index'; import { parse } from 'qs'; import NotFound from 'components/Cards/NotFound'; +import { getPath, getLinkRender } from 'utils/route-map'; import styles from './index.less'; export default class BaseStepForm extends React.Component { @@ -92,7 +93,7 @@ export default class BaseStepForm extends React.Component { } get listUrl() { - return '/base/tmp'; + return ''; } get checkEndpoint() { @@ -212,6 +213,20 @@ export default class BaseStepForm extends React.Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + + getLinkRender(routeName, value, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getLinkRender({ key: realName, params, query, value }); + } + getPrevBtn() { const { current } = this.state; if (current === 0) { diff --git a/src/components/TableButton/RuleButton.jsx b/src/components/TableButton/RuleButton.jsx index 543906fd..3dbe853c 100644 --- a/src/components/TableButton/RuleButton.jsx +++ b/src/components/TableButton/RuleButton.jsx @@ -15,6 +15,7 @@ import React, { Component } from 'react'; import TableButton from 'components/TableButton'; import { getSelfColumns } from 'resources/security-group-rule'; +import { getPath } from 'utils/route-map'; export default class RuleButton extends Component { getUrl(path, adminStr) { @@ -22,7 +23,10 @@ export default class RuleButton extends Component { } getDetailUrl(id) { - return `${this.getUrl('/network/security-group')}/detail/${id}`; + const key = this.isAdminPage + ? 'securityGroupDetailAdmin' + : 'securityGroupDetail'; + return getPath({ key, params: { id } }); } render() { diff --git a/src/components/Tables/Base/index.jsx b/src/components/Tables/Base/index.jsx index a5d9c85b..58532cf5 100644 --- a/src/components/Tables/Base/index.jsx +++ b/src/components/Tables/Base/index.jsx @@ -17,7 +17,6 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import isEqual from 'react-fast-compare'; import { toJS } from 'mobx'; -import { Link } from 'react-router-dom'; import { includes, get, isArray, isString } from 'lodash'; import { Button, Table, Dropdown, Input, Typography, Tooltip } from 'antd'; import MagicInput from 'components/MagicInput'; @@ -39,10 +38,13 @@ import { getStatusRender, getRender, getValueRenderFunc, + getNameRenderByRouter, + getNameRender, + columnRender, } from 'utils/table'; import { getNoValue } from 'utils/index'; -import { columnRender } from 'utils/render'; import { getLocalStorageItem, setLocalStorageItem } from 'utils/local-storage'; +import { getLinkRender } from 'utils/route-map'; import { inject } from 'mobx-react'; import globalRootStore from 'stores/root'; import CustomColumns from './CustomColumns'; @@ -50,6 +52,7 @@ import ItemActionButtons from './ItemActionButtons'; import PrimaryActionButtons from './PrimaryActionButtons'; import BatchActionButtons from './BatchActionButtons'; import Download from './Download'; + import styles from './index.less'; @inject('rootStore') @@ -330,16 +333,14 @@ export default class BaseTable extends React.Component { if (!projectId) { return '-'; } - const url = `/identity/project-admin/detail/${projectId}`; + const link = getLinkRender({ + key: 'projectDetailAdmin', + params: { id: projectId }, + value: projectId, + }); return ( <> -
- {globalRootStore.hasAdminRole ? ( - {projectId} - ) : ( - projectId - )} -
+
{globalRootStore.hasAdminRole ? link : projectId}
{value || '-'}
); @@ -353,63 +354,6 @@ export default class BaseTable extends React.Component { return (value) => getNoValue(value); }; - getLinkUrl = (prefix, id) => { - if (!prefix) { - return null; - } - if (prefix[prefix.length - 1] === '/') { - return `${prefix}${id}`; - } - return `${prefix}/${id}`; - }; - - getNameRender = (render, column) => { - if (render) { - return render; - } - const { - linkPrefix, - dataIndex, - idKey, - linkPrefixFunc, - linkFunc, - hasNoDetail = false, - } = column; - const { rowKey } = this.props; - return (value, record) => { - const idValue = get(record, idKey || rowKey); - let url = null; - if (linkFunc) { - url = linkFunc(value, record); - } else { - const linkValue = linkPrefixFunc - ? linkPrefixFunc(value, record) - : linkPrefix; - url = this.getLinkUrl(linkValue, idValue); - } - const nameValue = value || get(record, dataIndex) || '-'; - if (hasNoDetail) { - return ( -
-
{idValue}
-
{nameValue}
-
- ); - } - if (!url && !hasNoDetail) { - return nameValue; - } - return ( -
-
- {idValue} -
-
{nameValue}
-
- ); - }; - }; - // eslint-disable-next-line no-unused-vars getPriceRender = (render, column) => { if (render) { @@ -469,6 +413,9 @@ export default class BaseTable extends React.Component { tip, isStatus, isName, + isLink, + routeName, + linkPrefix, isPrice, ...rest } = column; @@ -485,8 +432,12 @@ export default class BaseTable extends React.Component { if (dataIndex === 'project_name') { newRender = this.getProjectRender(newRender); } - if (dataIndex === 'name' || isName) { - newRender = this.getNameRender(newRender, column); + if ((dataIndex === 'name' && routeName) || isLink) { + const { rowKey } = this.props; + newRender = getNameRenderByRouter(newRender, column, rowKey); + } + if ((dataIndex === 'name' && linkPrefix) || isName) { + newRender = getNameRender(newRender, column); } if (dataIndex === 'cost' || isPrice) { newRender = this.getPriceRender(newRender, column); diff --git a/src/containers/Action/FormAction/index.jsx b/src/containers/Action/FormAction/index.jsx index 5d69db52..378b4981 100644 --- a/src/containers/Action/FormAction/index.jsx +++ b/src/containers/Action/FormAction/index.jsx @@ -13,6 +13,7 @@ // limitations under the License. import BaseForm from 'components/Form'; +import { getPath } from 'utils/route-map'; export default class FormAction extends BaseForm { static id = 'formAction'; @@ -36,4 +37,13 @@ export default class FormAction extends BaseForm { getUrl(path, adminStr) { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } } diff --git a/src/containers/Action/StepAction/index.jsx b/src/containers/Action/StepAction/index.jsx index 82567452..f5745b1f 100644 --- a/src/containers/Action/StepAction/index.jsx +++ b/src/containers/Action/StepAction/index.jsx @@ -32,12 +32,4 @@ export default class StepAction extends StepForm { get hasConfirmStep() { return true; } - - // get isAdminPage() { - // return this.props.isAdminPage || false; - // } - - // getUrl(path, adminStr) { - // return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; - // } } diff --git a/src/containers/BaseDetail/index.jsx b/src/containers/BaseDetail/index.jsx index 096bc5c8..c3a9fd60 100644 --- a/src/containers/BaseDetail/index.jsx +++ b/src/containers/BaseDetail/index.jsx @@ -18,6 +18,7 @@ import Card from 'components/DetailCard'; import { toJS } from 'mobx'; import { has } from 'lodash'; import { isAdminPage } from 'utils/index'; +import { getPath, getLinkRender } from 'utils/route-map'; import styles from './index.less'; export default class BaseDetail extends React.Component { @@ -86,6 +87,20 @@ export default class BaseDetail extends React.Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + + getLinkRender(routeName, value, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getLinkRender({ key: realName, params, query, value }); + } + fetchData = (params) => { if (this.shouldFetchDetail && this.store.fetchDetail) { this.store diff --git a/src/containers/List/index.jsx b/src/containers/List/index.jsx index ef3aedb6..519a23c0 100644 --- a/src/containers/List/index.jsx +++ b/src/containers/List/index.jsx @@ -34,6 +34,7 @@ import { checkTimeIn } from 'utils/time'; import checkItemPolicy from 'resources/policy'; import NotFound from 'components/Cards/NotFound'; import { getTags } from 'components/MagicInput'; +import { getPath, getLinkRender } from 'utils/route-map'; import styles from './index.less'; const tabOtherHeight = 326; @@ -169,6 +170,20 @@ export default class BaseList extends React.Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + + getLinkRender(routeName, value, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getLinkRender({ key: realName, params, query, value }); + } + get prefix() { return this.props.match.url; } @@ -1064,7 +1079,7 @@ export default class BaseList extends React.Component { } catch (e) { // eslint-disable-next-line no-console console.log(e); - const link = this.getUrl('/base/overview'); + const link = this.getRoutePath('overview'); return ; } } @@ -1155,7 +1170,7 @@ export default class BaseList extends React.Component { render() { if (this.endpointError) { - const link = this.getUrl('/base/overview'); + const link = this.getRoutePath('overview'); return ; } const table = this.renderTable(); diff --git a/src/containers/TabDetail/index.jsx b/src/containers/TabDetail/index.jsx index 829a4e16..06d41fdb 100644 --- a/src/containers/TabDetail/index.jsx +++ b/src/containers/TabDetail/index.jsx @@ -26,6 +26,7 @@ import { toJS } from 'mobx'; import checkItemPolicy from 'resources/policy'; import ItemActionButtons from 'components/Tables/Base/ItemActionButtons'; import { emptyActionConfig } from 'utils/constants'; +import { getPath, getLinkRender } from 'utils/route-map'; import styles from './index.less'; export default class DetailBase extends React.Component { @@ -71,6 +72,20 @@ export default class DetailBase extends React.Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + + getLinkRender(routeName, value, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getLinkRender({ key: realName, params, query, value }); + } + get tabs() { return []; } @@ -166,7 +181,7 @@ export default class DetailBase extends React.Component { } get listUrl() { - return '/base/tmp'; + return ''; } get detailData() { diff --git a/src/containers/TabList/index.jsx b/src/containers/TabList/index.jsx index 271b79f4..ec59b855 100644 --- a/src/containers/TabList/index.jsx +++ b/src/containers/TabList/index.jsx @@ -17,6 +17,7 @@ import { parse } from 'qs'; import classnames from 'classnames'; import { Tabs } from 'antd'; import { isAdminPage } from 'utils/index'; +import { getPath, getLinkRender } from 'utils/route-map'; import NotFound from 'components/Cards/NotFound'; import styles from './index.less'; @@ -67,6 +68,20 @@ export default class TabList extends Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + + getLinkRender(routeName, value, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getLinkRender({ key: realName, params, query, value }); + } + get tabs() { const tabs = [ { @@ -137,7 +152,7 @@ export default class TabList extends Component { return null; } if (this.endpointError) { - const link = this.getUrl('/base/overview'); + const link = this.getRoutePath('overview'); return ; } // if (this.tabs.length === 1) { diff --git a/src/layouts/Base/Menu.jsx b/src/layouts/Base/Menu.jsx index 4ab1f320..560ebf10 100644 --- a/src/layouts/Base/Menu.jsx +++ b/src/layouts/Base/Menu.jsx @@ -21,6 +21,7 @@ import { toJS } from 'mobx'; import classnames from 'classnames'; import logoSmall from 'asset/image/logo-small.svg'; import logoExtend from 'asset/image/logo-extend.svg'; +import { getPath } from 'utils/route-map'; import styles from './index.less'; const { SubMenu } = Menu; @@ -47,6 +48,15 @@ export class LayoutMenu extends Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + get rootStore() { return this.props.rootStore; } @@ -217,7 +227,7 @@ export class LayoutMenu extends Component { const { collapsed, hover } = this.state; const isExtend = !collapsed || hover; const imageSvg = this.getImage(isExtend); - const homeUrl = this.getUrl('/base/overview'); + const homeUrl = this.getRoutePath('overview'); return (
{ const { currentRoutes = [] } = this.props; if (currentRoutes.length === 0) { @@ -123,21 +133,12 @@ class Right extends Component { return ( ); } try { - // const { currentRoutes = [] } = this.props; - // if (currentRoutes.length === 0) { - // return ( - // - // ); - // } const children = (
{renderRoutes(this.routes, extraProps)} @@ -147,13 +148,8 @@ class Right extends Component { } catch (e) { // eslint-disable-next-line no-console console.log(e); - return ( - - ); + const path = this.getRoutePath('overview'); + return ; } }; diff --git a/src/layouts/Base/index.jsx b/src/layouts/Base/index.jsx index 8b7707de..8ac914ce 100644 --- a/src/layouts/Base/index.jsx +++ b/src/layouts/Base/index.jsx @@ -21,6 +21,7 @@ import { BellOutlined } from '@ant-design/icons'; import checkItemPolicy from 'resources/policy'; import { Layout } from 'antd'; import GlobalHeader from 'components/Layout/GlobalHeader'; +import { setRouteMap, getPath } from 'utils/route-map'; import renderAdminMenu from '../admin-menu'; import renderMenu from '../menu'; import renderUserMenu from '../user-menu'; @@ -100,6 +101,15 @@ export class BaseLayout extends Component { return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; } + getRouteName(routeName) { + return this.isAdminPage ? `${routeName}Admin` : routeName; + } + + getRoutePath(routeName, params = {}, query = {}) { + const realName = this.getRouteName(routeName); + return getPath({ key: realName, params, query }); + } + filterMenuByHidden = (menu = []) => { if (menu.length === 0) { return menu; @@ -208,6 +218,7 @@ export class BaseLayout extends Component { window.location.href = '/base/overview'; } this.routes = this.props.route.routes; + setRouteMap(this.menu); } renderNotice() { diff --git a/src/layouts/admin-menu.jsx b/src/layouts/admin-menu.jsx index e0d036dd..7ec48768 100644 --- a/src/layouts/admin-menu.jsx +++ b/src/layouts/admin-menu.jsx @@ -32,7 +32,7 @@ const renderMenu = (t) => { { path: '/base/overview-admin', name: t('Home'), - key: '/home', + key: 'overviewAdmin', icon: , level: 0, hasBreadcrumb: false, @@ -41,19 +41,20 @@ const renderMenu = (t) => { { path: '/compute', name: t('Compute'), - key: '/compute', + key: 'computeAdmin', icon: , children: [ { path: '/compute/instance-admin', name: t('Instance'), - key: '/compute/instance-admin', + key: 'instanceAdmin', level: 1, children: [ { path: /^\/compute\/instance-admin\/detail\/.[^/]+$/, name: t('Instance Detail'), - key: 'instance-detail', + key: 'instanceDetailAdmin', + routePath: '/compute/instance-admin/detail/:id', level: 2, }, ], @@ -61,19 +62,20 @@ const renderMenu = (t) => { { path: '/compute/flavor-admin', name: t('Flavor'), - key: '/compute/flavor', + key: 'flavorAdmin', level: 1, children: [ { path: '/compute/flavor-admin/create', name: t('Create Flavor'), - key: 'flavor-create', + key: 'flavorCreateAdmin', level: 2, }, { path: /^\/compute\/flavor-admin\/detail\/[^/]+$/, name: t('Flavor Detail'), - key: 'flavor-detail', + key: 'flavorDetailAdmin', + routePath: '/compute/flavor-admin/detail/:id', level: 2, }, ], @@ -81,13 +83,14 @@ const renderMenu = (t) => { { path: '/compute/server-group-admin', name: t('Server Group'), - key: '/compute/server-group-admin', + key: 'serverGroupAdmin', level: 1, children: [ { path: /^\/compute\/server-group-admin\/detail\/.[^/]+$/, name: t('Server Group Detail'), - key: 'server-group-detail', + key: 'serverGroupDetailAdmin', + routePath: '/compute/server-group-admin/detail/:id', level: 2, }, ], @@ -95,19 +98,20 @@ const renderMenu = (t) => { { path: '/compute/image-admin', name: t('Image'), - key: '/compute/image-admin', + key: 'imageAdmin', level: 1, children: [ { path: /^\/compute\/image-admin\/detail\/.[^/]+$/, name: t('Image Detail'), - key: 'image-detail', + key: 'imageDetailAdmin', + routePath: '/compute/image-admin/detail/:id', level: 2, }, { path: '/compute/image-admin/create', name: t('Create Image'), - key: 'image-create', + key: 'imageCreateAdmin', level: 2, }, ], @@ -115,13 +119,14 @@ const renderMenu = (t) => { { path: '/compute/hypervisors-admin', name: t('Hypervisors'), - key: '/compute/hypervisors', + key: 'hypervisorAdmin', level: 1, children: [ { path: /^\/compute\/hypervisors-admin\/detail\/.[^/]+$/, name: t('Hypervisor Detail'), - key: 'hypervisor-detail', + key: 'hypervisorDetailAdmin', + routePath: '/compute/hypervisors-admin/detail/:id', level: 2, }, ], @@ -129,32 +134,34 @@ const renderMenu = (t) => { { path: '/compute/aggregates-admin', name: t('Host Aggregates'), - key: '/compute/aggregates', + key: 'aggregateAdmin', level: 1, children: [], }, { path: '/compute/baremetal-node-admin', name: t('Bare Metal Setting'), - key: '/compute/baremetal-node', + key: 'baremetalNodeAdmin', level: 1, children: [ { path: /^\/compute\/baremetal-node-admin\/detail\/.[^/]+$/, name: t('Bare Metal Node Detail'), - key: 'baremetal-node-detail', + key: 'baremetaNodeDetailAdmin', + routePath: '/compute/baremetal-node-admin/detail/:id', level: 2, }, { path: /^\/compute\/baremetal-node-admin\/create$/, name: t('Create Bare Metal Node'), - key: 'baremetal-node-create', + key: 'baremetalNodeCreateAdmin', level: 2, }, { path: /^\/compute\/baremetal-node-admin\/edit\/.[^/]+$/, name: t('Bare Metal Node Edit'), - key: 'baremetal-node-edit', + key: 'baremetalNodeEditAdmin', + routePath: '/compute/baremetal-node-admin/detail/:id', level: 2, }, ], @@ -164,75 +171,80 @@ const renderMenu = (t) => { { path: '/storage', name: t('Storage'), - key: '/storage', + key: 'storageAdmin', icon: , children: [ { path: '/storage/volume-admin', name: t('Volume'), - key: '/storage/volume', + key: 'volumeAdmin', level: 1, children: [ { path: /^\/storage\/volume-admin\/detail\/.[^/]+$/, name: t('Volume Detail'), - key: 'volume-detail', + key: 'volumeDetailAdmin', level: 2, + routePath: '/storage/volume-admin/detail/:id', }, ], }, { path: '/storage/backup-admin', name: t('Backups'), - key: '/storage/backup', + key: 'backupAdmin', level: 1, children: [ { path: /^\/storage\/backup-admin\/detail\/.[^/]+$/, name: t('Backup Detail'), - key: 'backup-detail', + key: 'backupDetailAdmin', level: 2, + routePath: '/storage/backup-admin/detail/:id', }, ], }, { path: '/storage/snapshot-admin', name: t('Volume Snapshot'), - key: '/storage/snapshot', + key: 'snapshotAdmin', level: 1, children: [ { path: /^\/storage\/snapshot-admin\/detail\/.[^/]+$/, name: t('Snapshot Detail'), - key: 'snapshot-detail', + key: 'snapshotDetailAdmin', level: 2, + routePath: '/storage/snapshot-admin/detail/:id', }, ], }, { path: '/storage/volume-type-admin', name: t('Volume Type'), - key: '/storage/volume-type', + key: 'volumeTypeAdmin', level: 1, children: [ { path: /^\/storage\/volume-type-admin\/detail\/.[^/]+$/, name: t('Volume Type Detail'), - key: 'volume-type-detail', + key: 'volumeTypeDetailAdmin', level: 2, + routePath: '/storage/volume-type-admin/detail/:id', }, { path: /^\/storage\/volume-type-admin\/qos\/detail\/.[^/]+$/, name: t('QoS Detail'), - key: 'volume-type-qos-detail', + key: 'volumeTypeQosDetailAdmin', level: 2, + routePath: '/storage/volume-type-admin/qos/detail/:id', }, ], }, { path: '/storage/storage-admin', name: t('Storage Backend'), - key: '/storage/storage', + key: 'storageBackendAdmin', level: 1, children: [], }, @@ -241,130 +253,141 @@ const renderMenu = (t) => { { path: '/network', name: t('Network'), - key: '/network', + key: '/networkAdmin', icon: , children: [ { path: '/network/networks-admin', name: t('Networks'), - key: '/network/networks', + key: 'networkAdmin', level: 1, children: [ { path: /^\/network\/networks-admin\/detail\/.[^/]+$/, name: t('Network Detail'), - key: 'network_detail', + key: 'networkDetailAdmin', level: 2, + routePath: '/network/networks-admin/detail/:id', }, ], }, { path: '/network/virtual_adapter_admin', name: t('Virtual Adapter'), - key: '/network/virtual_adapter_admin', + key: 'virtualAdapterAdmin', level: 1, children: [ { path: /^\/network\/virtual_adapter_admin\/detail\/.[^/]+$/, name: t('Virtual Adapter Detail'), - key: 'virtual_adapter-detail', + key: 'virtualAdapterDetailAdmin', level: 2, + routePath: '/network/virtual_adapter_admin/detail/:id', }, ], }, { path: '/network/qos-policy-admin', name: t('QoS Policy'), - key: '/network/qos-policy-admin', + key: 'networkQosAdmin', level: 1, children: [ { path: /^\/network\/qos-policy-admin\/detail\/.[^/]+$/, name: t('QoS Policy Detail'), - key: 'qos-policy-detail', + key: 'networkQosDetailAdmin', level: 2, + routePath: '/network/qos-policy-admin/detail/:id', }, ], }, { path: '/network/router-admin', name: t('Routers'), - key: '/network/router-admin', + key: 'routerAdmin', level: 1, children: [ { path: /^\/network\/router-admin\/detail\/.[^/]+$/, name: t('Router Detail'), - key: 'router-detail', + key: 'routerDetailAdmin', level: 2, + routePath: '/network/router-admin/detail/:id', }, { path: /^\/network\/router-admin\/.[^/]+\/port\/.[^/]+$/, name: t('Port Detail'), - key: 'port-detail', + key: 'routerPortDetailAdmin', level: 2, + routePath: '/network/router-admin/:routerId/port/:id', }, ], }, { path: '/network/floatingip-admin', name: t('Floating IPs'), - key: '/network/floatingip-admin', + key: 'fipAdmin', level: 1, children: [ { path: /^\/network\/floatingip-admin\/detail\/.[^/]+$/, name: t('Floating Ip Detail'), - key: 'floatingip-detail', + key: 'fipDetailAdmin', level: 2, + routePath: '/network/floatingip-admin/detail/:id', }, ], }, { path: '/network/load-balancers-admin', name: t('Load Balancers'), - key: '/network/load-balancers-admin', + key: 'lbAdmin', level: 1, children: [ { path: /^\/network\/load-balancers-admin\/detail\/.[^/]+$/, name: t('Load Balancer Detail'), - key: 'load-balancer-detail', + key: 'lbDetailAdmin', level: 2, + routePath: '/network/load-balancers-admin/detail/:id', }, { path: /^\/network\/load-balancers-admin\/.[^/]+\/listener\/.[^/]+$/, name: t('Listener Detail'), - key: 'listener-detail', + key: 'lbListenerDetailAdmin', level: 2, + routePath: + '/network/load-balancers-admin/:loadBalancerId/listener/:id', }, ], }, { path: '/network/vpn-admin', name: t('VPN'), - key: '/network/vpn-admin', + key: 'vpnAdmin', level: 1, children: [ { path: /^\/network\/ipsec-site-connection-admin\/detail\/.[^/]+$/, name: t('IPsec site connection Detail'), - key: 'ipsec-site-connection-detail', + key: 'ipsecDetailAdmin', level: 2, + routePath: '/network/ipsec-site-connection-admin/detail/:id', }, ], }, { path: '/network/security-group-admin', name: t('Security Groups'), - key: '/network/security-group', + key: 'securityGroupAdmin', level: 1, children: [ { path: /^\/network\/security-group-admin\/detail\/.[^/]+$/, name: t('Security Group Detail'), - key: 'security-group-detail', + key: 'securityGroupDetailAdmin', level: 2, + routePath: '/network/security-group-admin/detail/:id', }, ], }, @@ -379,118 +402,127 @@ const renderMenu = (t) => { { path: '/identity/domain-admin', name: t('Domains'), - key: '/identity/domain', + key: 'domainAdmin', level: 1, children: [ { path: '/identity/domain-admin/create', name: t('Create Domain'), - key: 'domain-create', + key: 'domainCreateAdmin', level: 2, }, { path: /^\/identity\/domain-admin\/edit\/.[^/]+$/, name: t('Domain Edit'), - key: 'domain-edit', + key: 'domainEditAdmin', level: 2, + routePath: '/identity/domain-admin/edit/:id', }, { path: /^\/identity\/domain-admin\/detail\/.[^/]+$/, name: t('Domain Detail'), - key: 'domain-detail', + key: 'domainDetailAdmin', level: 2, + routePath: '/identity/domain-admin/detail/:id', }, ], }, { path: '/identity/project-admin', name: t('Projects'), - key: '/identity/project', + key: 'projectAdmin', level: 1, children: [ { path: /^\/identity\/project-admin\/detail\/.[^/]+$/, name: t('Project Detail'), - key: 'project-detail', + key: 'projectDetailAdmin', level: 2, + routePath: '/identity/project-admin/detail/:id', }, { path: '/identity/project-admin/create', name: t('Create Project'), - key: 'project-create', + key: 'projectCreateAdmin', level: 2, }, { path: /^\/identity\/project-admin\/edit\/.[^/]+$/, name: t('Edit Project'), - key: 'project-edit', + key: 'projectEditAdmin', level: 2, + routePath: '/identity/project-admin/edit/:id', }, ], }, { path: '/identity/user-admin', name: t('Users'), - key: '/identity/user', + key: 'userAdmin', level: 1, children: [ { path: /^\/identity\/user-admin\/detail\/.[^/]+$/, name: t('User Detail'), - key: 'user-detail', + key: 'userDetailAdmin', level: 2, + routePath: '/identity/user-admin/detail/:id', }, { path: '/identity/user-admin/create', name: t('Create User'), - key: 'user-create', + key: 'userCreateAdmin', level: 2, }, { path: /^\/identity\/user-admin\/edit\/.[^/]+$/, name: t('User Edit'), - key: 'user-edit', + key: 'userEditAdmin', level: 2, + routePath: '/identity/user-admin/edit/:id', }, ], }, { path: '/identity/user-group-admin', name: t('User Groups'), - key: '/identity/user-group', + key: 'userGroupAdmin', level: 1, children: [ { path: /^\/identity\/user-group-admin\/detail\/.[^/]+$/, name: t('User Group Detail'), - key: 'project-detail', + key: 'userGroupDetailAdmin', level: 2, + routePath: '/identity/user-group-admin/detail/:id', }, { path: '/identity/user-group-admin/create', name: t('Create User Group'), - key: 'user-group-create', + key: 'userGroupCreateAdmin', level: 2, }, { path: /^\/identity\/user-group-admin\/edit\/.[^/]+$/, name: t('Edit User Group'), - key: 'user-group-edit', + key: 'userGroupEditAdmin', level: 2, + routePath: '/identity/user-group-admin/edit/:id', }, ], }, { path: '/identity/role-admin', name: t('Roles'), - key: '/identity/role-admin', + key: 'roleAdmin', level: 1, children: [ { path: /^\/identity\/role-admin\/detail\/.[^/]+$/, name: t('Role Detail'), - key: 'role-detail', + key: 'roleDetailAdmin', level: 2, + routePath: '/identity/role-admin/detail/:id', }, ], }, @@ -505,14 +537,15 @@ const renderMenu = (t) => { // { // path: '/management/recycle-bin-admin', // name: t('Recycle Bin'), - // key: '/management/recycle-bin-admin', + // key: 'recycleBinAdmin', // level: 1, // children: [ // { // path: /^\/management\/recycle-bin-admin\/detail\/.[^/]+$/, // name: t('Instance Detail'), - // key: 'recycle-bin-detail', + // key: 'recycleBinDetailAdmin', // level: 2, + // routePath: '/management/recycle-bin-admin/detail/:id', // }, // ], // }, @@ -521,32 +554,34 @@ const renderMenu = (t) => { { path: '/heat', name: t('Orchestration'), - key: '/heat', + key: 'heatAdmin', icon: , children: [ { path: '/heat/stack-admin', name: t('Stacks'), - key: '/heat/stack-admin', + key: 'stackAdmin', level: 1, children: [ { path: /^\/heat\/stack-admin\/detail\/.[^/]+\/.[^/]+$/, name: t('Stack Detail'), - key: 'stack-detail', + key: 'stackDetailAdmin', level: 2, + routePath: '/heat/stack-admin/detail/:id/:name', }, { path: '/heat/stack-admin/create', name: t('Create Stack'), - key: 'stack-create', + key: 'stackCreateAdmin', level: 2, }, { path: /^\/heat\/stack-admin\/edit\/.[^/]+\/.[^/]+$/, name: t('Update Template'), - key: 'stack-edit', + key: 'stackEditAdmin', level: 2, + routePath: '/heat/stack-admin/edit/:id/:name', }, ], }, @@ -555,40 +590,42 @@ const renderMenu = (t) => { { path: '/configuration-admin', name: t('Global Setting'), - key: '/configuration-admin', + key: 'configurationAdmin', icon: , children: [ { path: '/configuration-admin/info', name: t('System Info'), - key: '/configuration-admin/info', + key: 'systemInfoAdmin', level: 1, children: [ { path: /^\/configuration-admin\/neutron\/detail\/.[^/]+$/, name: t('Neutron Agent Detail'), - key: 'neutron-detail', + key: 'neutronAgentDetailAdmin', level: 2, + routePath: '/configuration-admin/neutron/detail/:id', }, ], }, { path: '/configuration-admin/setting', name: t('System Config'), - key: '/configuration-admin/setting', + key: 'settingAdmin', level: 1, }, { path: '/configuration-admin/metadata', name: t('Metadata Definitions'), - key: '/configuration-admin/metadata', + key: 'metadataAdmin', level: 1, children: [ { path: /^\/configuration-admin\/metadata\/detail\/.[^/]+$/, name: t('Metadata Detail'), - key: 'metadata-detail', + key: 'metadataDetailAdmin', level: 2, + routePath: '/configuration-admin/metadata/detail/:id', }, ], }, diff --git a/src/layouts/menu.jsx b/src/layouts/menu.jsx index f2782781..81a06a07 100644 --- a/src/layouts/menu.jsx +++ b/src/layouts/menu.jsx @@ -30,7 +30,7 @@ const renderMenu = (t) => { { path: '/base/overview', name: t('Home'), - key: '/home', + key: 'overview', icon: , level: 0, hasBreadcrumb: false, @@ -39,31 +39,32 @@ const renderMenu = (t) => { { path: '/compute', name: t('Compute'), - key: '/compute', + key: 'compute', icon: , children: [ { path: '/compute/instance', name: t('Instance'), - key: '/compute/instance', + key: 'instance', level: 1, children: [ { path: /^\/compute\/instance\/detail\/.[^/]+$/, name: t('Instance Detail'), - key: 'instance-detail', + key: 'instanceDetail', level: 2, + routePath: '/compute/instance/detail/:id', }, { path: '/compute/instance/create', name: t('Create Instance'), - key: 'instance-create', + key: 'instanceCreate', level: 2, }, { path: '/compute/ironic-instance/create', name: t('Create Ironic Instance'), - key: 'ironic-instance-create', + key: 'ironicCreate', level: 2, }, ], @@ -71,47 +72,50 @@ const renderMenu = (t) => { { path: '/compute/flavor', name: t('Flavor'), - key: '/compute/flavor', + key: 'flavor', level: 1, children: [ { path: /^\/compute\/flavor\/detail\/.[^/]+$/, name: t('Flavor Detail'), - key: 'flavor-detail', + key: 'flavorDetail', level: 2, + routePath: '/compute/flavor/detail/:id', }, ], }, { path: '/compute/server-group', name: t('Server Group'), - key: '/compute/server-group', + key: 'serverGroup', level: 1, children: [ { path: /^\/compute\/server-group\/detail\/.[^/]+$/, name: t('Server Group Detail'), - key: 'server-group-detail', + key: 'serverGroupDetail', level: 2, + routePath: '/compute/server-group/detail/:id', }, ], }, { path: '/compute/image', name: t('Image'), - key: '/compute/image', + key: 'image', level: 1, children: [ { path: /^\/compute\/image\/detail\/.[^/]+$/, name: t('Image Detail'), - key: 'image-detail', + key: 'imageDetail', level: 2, + routePath: '/compute/image/detail/:id', }, { path: '/compute/image/create', name: t('Create Image'), - key: 'image-create', + key: 'imageCreate', level: 2, }, ], @@ -119,14 +123,15 @@ const renderMenu = (t) => { { path: '/compute/keypair', name: t('Key Pairs'), - key: '/compute/keypair', + key: 'keypair', level: 1, children: [ { path: /^\/compute\/keypair\/detail\/.[^/]*$/, name: t('Keypair Detail'), - key: 'keypair-detail', + key: 'keypairDetail', level: 2, + routePath: '/compute/keypair/detail/:id', }, ], }, @@ -135,54 +140,57 @@ const renderMenu = (t) => { { path: '/storage', name: t('Storage'), - key: '/storage', + key: 'storage', icon: , children: [ { path: '/storage/volume', name: t('Volume'), - key: '/storage/volume', + key: 'volume', level: 1, children: [ { path: '/storage/volume/create', name: t('Create Volume'), - key: 'volume-create', + key: 'volumeCreate', level: 2, }, { path: /^\/storage\/volume\/detail\/.[^/]+$/, name: t('Volume Detail'), - key: 'volume-detail', + key: 'volumeDetail', level: 2, + routePath: '/storage/volume/detail/:id', }, ], }, { path: '/storage/backup', name: t('Backups'), - key: '/storage/backup', + key: 'backup', level: 1, children: [ { path: /^\/storage\/backup\/detail\/.[^/]+$/, name: t('Backup Detail'), - key: 'backup-detail', + key: 'backupDetail', level: 2, + routePath: '/storage/backup/detail/:id', }, ], }, { path: '/storage/snapshot', name: t('Volume Snapshot'), - key: '/storage/snapshot', + key: 'snapshot', level: 1, children: [ { path: /^\/storage\/snapshot\/detail\/.[^/]+$/, name: t('Snapshot Detail'), - key: 'snapshot-detail', + key: 'snapshotDetail', level: 2, + routePath: '/storage/snapshot/detail/:id', }, ], }, @@ -197,137 +205,147 @@ const renderMenu = (t) => { { path: '/network/networks', name: t('Networks'), - key: '/network/networks', + key: 'network', level: 1, children: [ { path: /^\/network\/networks\/detail\/.[^/]+$/, name: t('Network Detail'), - key: 'network_detail', + key: 'networkDetail', level: 2, + routePath: '/network/networks/detail/:id', }, ], }, { path: '/network/virtual_adapter', name: t('Virtual Adapter'), - key: '/network/virtual_adapter', + key: 'virtualAdapter', level: 1, children: [ { path: /^\/network\/virtual_adapter\/detail\/.[^/]+$/, name: t('Virtual Adapter Detail'), - key: 'virtual_adapter-detail', + key: 'virtualAdapterDetail', level: 2, + routePath: '/network/virtual_adapter/detail/:id', }, ], }, { path: '/network/qos-policy', name: t('QoS Policy'), - key: '/network/qos-policy', + key: 'networkQos', level: 1, children: [ { path: /^\/network\/qos-policy\/detail\/.[^/]+$/, name: t('QoS Policy Detail'), - key: 'qos-policy-detail', + key: 'networkQosDetail', level: 2, + routePath: '/network/qos-policy/detail/:id', }, ], }, { path: '/network/router', name: t('Routers'), - key: '/network/router', + key: 'router', level: 1, children: [ { path: /^\/network\/router\/detail\/.[^/]+$/, name: t('Router Detail'), - key: 'router-detail', + key: 'routerDetail', level: 2, + routePath: '/network/router/detail/:id', }, { path: /^\/network\/router\/.[^/]+\/port\/.[^/]+$/, name: t('Port Detail'), - key: 'port-detail', + key: 'routerPortDetail', level: 2, + routePath: '/network/router/:routerId/port/:id', }, ], }, { path: '/network/floatingip', name: t('Floating IPs'), - key: '/network/floatingip', + key: 'floatingip', level: 1, children: [ { path: /^\/network\/floatingip\/detail\/.[^/]+$/, name: t('Floating Ip Detail'), - key: 'floatingip-detail', + key: 'fipDetail', level: 2, + routePath: '/network/floatingip/detail/:id', }, ], }, { path: '/network/topo', name: t('Topology'), - key: '/network/topo', + key: 'networkTopo', level: 1, children: [], }, { path: '/network/load-balancers', name: t('Load Balancers'), - key: '/network/load-balancers', + key: 'lb', level: 1, children: [ { path: '/network/load-balancers/create', name: t('Create Loadbalancer'), - key: 'load-balancer-create', + key: 'lbCreate', level: 2, }, { path: /^\/network\/load-balancers\/detail\/.[^/]+$/, name: t('Load Balancer Detail'), - key: 'load-balancer-detail', + key: 'lbDetail', level: 2, + routePath: '/network/load-balancers/detail/:id', }, { path: /^\/network\/load-balancers\/.[^/]+\/listener\/.[^/]+$/, name: t('Listener Detail'), - key: 'listener-detail', + key: 'lbListenerDetail', level: 2, + routePath: '/network/load-balancers/:loadBalancerId/listener/:id', }, ], }, { path: '/network/vpn', name: t('VPN'), - key: '/network/vpn', + key: 'vpn', level: 1, children: [ { path: /^\/network\/ipsec-site-connection\/detail\/.[^/]+$/, name: t('IPsec site connection Detail'), - key: 'ipsec-site-connection-detail', + key: 'ipsecDetail', level: 2, + routePath: '/network/ipsec-site-connection/detail/:id', }, ], }, { path: '/network/security-group', name: t('Security Groups'), - key: '/network/security-group', + key: 'securityGroup', level: 1, children: [ { path: /^\/network\/security-group\/detail\/.[^/]+$/, name: t('Security Group Detail'), - key: 'security-group-detail', + key: 'securityGroupDetail', level: 2, + routePath: '/network/security-group/detail/:id', }, ], }, @@ -342,14 +360,15 @@ const renderMenu = (t) => { // { // path: '/management/recycle-bin', // name: t('Recycle Bin'), - // key: '/management/recycle-bin', + // key: 'recycleBin', // level: 1, // children: [ // { // path: /^\/management\/recycle-bin\/detail\/.[^/]+$/, // name: t('Instance Detail'), - // key: 'recycle-bin-detail', + // key: 'recycleBinDetail', // level: 2, + // routePath: '/management/recycle-bin/detail/:id', // }, // ], // }, @@ -358,32 +377,34 @@ const renderMenu = (t) => { { path: '/heat', name: t('Orchestration'), - key: '/heat', + key: 'heat', icon: , children: [ { path: '/heat/stack', name: t('Stacks'), - key: '/heat/stack', + key: 'stack', level: 1, children: [ { path: /^\/heat\/stack\/detail\/.[^/]+\/.[^/]+$/, name: t('Stack Detail'), - key: 'stack-detail', + key: 'stackDetail', level: 2, + routePath: '/heat/stack/detail/:id/:name', }, { path: '/heat/stack/create', name: t('Create Stack'), - key: 'stack-create', + key: 'stackCreate', level: 2, }, { path: /^\/heat\/stack\/edit\/.[^/]+\/.[^/]+$/, name: t('Update Template'), - key: 'stack-edit', + key: 'stackEdit', level: 2, + routePath: '/heat/stack/edit/:id/:name', }, ], }, diff --git a/src/pages/compute/containers/BareMetalNode/Detail/index.jsx b/src/pages/compute/containers/BareMetalNode/Detail/index.jsx index ed53eaec..b01d0854 100644 --- a/src/pages/compute/containers/BareMetalNode/Detail/index.jsx +++ b/src/pages/compute/containers/BareMetalNode/Detail/index.jsx @@ -34,7 +34,7 @@ export default class Detail extends Base { } get listUrl() { - return '/compute/baremetal-node-admin'; + return this.getRoutePath('baremetalNode'); } get actionConfigs() { diff --git a/src/pages/compute/containers/BareMetalNode/actions/Create/index.jsx b/src/pages/compute/containers/BareMetalNode/actions/Create/index.jsx index 18215149..a9e84ba5 100644 --- a/src/pages/compute/containers/BareMetalNode/actions/Create/index.jsx +++ b/src/pages/compute/containers/BareMetalNode/actions/Create/index.jsx @@ -42,7 +42,7 @@ export default class Create extends StepAction { } get listUrl() { - return '/compute/baremetal-node-admin'; + return this.getRoutePath('baremetalNode'); } get name() { diff --git a/src/pages/compute/containers/BareMetalNode/actions/Edit.jsx b/src/pages/compute/containers/BareMetalNode/actions/Edit.jsx index 8aa469c3..c41a9417 100644 --- a/src/pages/compute/containers/BareMetalNode/actions/Edit.jsx +++ b/src/pages/compute/containers/BareMetalNode/actions/Edit.jsx @@ -27,7 +27,7 @@ export default class Edit extends Create { static path = (item) => `/compute/baremetal-node-admin/edit/${item.uuid}`; get listUrl() { - return '/compute/baremetal-node-admin'; + return this.getRoutePath('baremetalNode'); } get name() { diff --git a/src/pages/compute/containers/BareMetalNode/index.jsx b/src/pages/compute/containers/BareMetalNode/index.jsx index 5cce1a0a..695f9395 100644 --- a/src/pages/compute/containers/BareMetalNode/index.jsx +++ b/src/pages/compute/containers/BareMetalNode/index.jsx @@ -54,8 +54,7 @@ export default class BareMetalNode extends Base { { title: t('Node ID/Name'), dataIndex: 'name', - idKey: 'uuid', - linkPrefix: '/compute/baremetal-node-admin/detail', + routerName: 'baremetalNodeDetail', }, { title: t('Ironic Instance Name'), diff --git a/src/pages/compute/containers/Flavor/Detail/index.jsx b/src/pages/compute/containers/Flavor/Detail/index.jsx index 8bbd37f6..dd970373 100644 --- a/src/pages/compute/containers/Flavor/Detail/index.jsx +++ b/src/pages/compute/containers/Flavor/Detail/index.jsx @@ -32,7 +32,7 @@ export class Detail extends Base { } get listUrl() { - return this.getUrl('/compute/flavor'); + return this.getRoutePath('flavor'); } get actionConfigs() { diff --git a/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx b/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx index 5cbab4c1..5611c889 100644 --- a/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx +++ b/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx @@ -50,10 +50,8 @@ class StepCreate extends StepAction { get listUrl() { const { architecture } = this.values || {}; - if (architecture) { - return `/compute/flavor-admin?tab=${architecture}`; - } - return `/compute/flavor-admin?tab=${this.tab}`; + const tab = architecture || this.tab; + return this.getRoutePath('flavor', null, { tab }); } get name() { @@ -126,7 +124,7 @@ class StepCreate extends StepAction { ram: memoryGb * 1024, disk: 0, }; - const isPublic = accessType === 'public' + const isPublic = accessType === 'public'; body['os-flavor-access:is_public'] = isPublic; if (categoryHasEphemeral) { body['OS-FLV-EXT-DATA:ephemeral'] = ephemeral; diff --git a/src/pages/compute/containers/Hypervisors/Hypervisor/Detail/index.jsx b/src/pages/compute/containers/Hypervisors/Hypervisor/Detail/index.jsx index 7f57a3ec..f433878e 100644 --- a/src/pages/compute/containers/Hypervisors/Hypervisor/Detail/index.jsx +++ b/src/pages/compute/containers/Hypervisors/Hypervisor/Detail/index.jsx @@ -29,7 +29,7 @@ export class HypervisorDetail extends Base { } get listUrl() { - return '/compute/hypervisors-admin'; + return this.getRoutePath('hypervisor'); } get detailInfos() { diff --git a/src/pages/compute/containers/Hypervisors/Hypervisor/index.jsx b/src/pages/compute/containers/Hypervisors/Hypervisor/index.jsx index 5b8c1782..9026e605 100644 --- a/src/pages/compute/containers/Hypervisors/Hypervisor/index.jsx +++ b/src/pages/compute/containers/Hypervisors/Hypervisor/index.jsx @@ -47,8 +47,8 @@ export class Hypervisors extends Base { columns[0] = { title: t('ID/Name'), dataIndex: 'hypervisor_hostname', - linkPrefix: '/compute/hypervisors-admin/detail', - isName: true, + routeName: 'hypervisorDetailAdmin', + isLink: true, }; return columns; }; diff --git a/src/pages/compute/containers/Image/Detail/BaseDetail.jsx b/src/pages/compute/containers/Image/Detail/BaseDetail.jsx index 96692edc..bf432562 100644 --- a/src/pages/compute/containers/Image/Detail/BaseDetail.jsx +++ b/src/pages/compute/containers/Image/Detail/BaseDetail.jsx @@ -12,13 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { toJS } from 'mobx'; import { inject, observer } from 'mobx-react'; import { imageProperties, imageVisibility, imageOS } from 'resources/image'; import Base from 'containers/BaseDetail'; import { isObject, isArray } from 'lodash'; -import { Link } from 'react-router-dom'; export class BaseDetail extends Base { get isImageDetail() { @@ -122,15 +120,14 @@ export class BaseDetail extends Base { return '-'; } if (value.server_name) { - return ( - - {value.server_name} - + const { server_id, server_name } = value; + const link = this.getLinkRender( + 'instanceDetail', + server_name, + { id: server_id }, + { tab: 'snapshots' } ); + return link; } return value.server_id; }, diff --git a/src/pages/compute/containers/Image/Detail/index.jsx b/src/pages/compute/containers/Image/Detail/index.jsx index fb979a17..73735679 100644 --- a/src/pages/compute/containers/Image/Detail/index.jsx +++ b/src/pages/compute/containers/Image/Detail/index.jsx @@ -34,7 +34,7 @@ export class ImageDetail extends Base { } get listUrl() { - return this.getUrl('/compute/image'); + return this.getRoutePath('image'); } get actionConfigs() { diff --git a/src/pages/compute/containers/Image/Image.jsx b/src/pages/compute/containers/Image/Image.jsx index 0bea08a8..1e9feb07 100644 --- a/src/pages/compute/containers/Image/Image.jsx +++ b/src/pages/compute/containers/Image/Image.jsx @@ -120,7 +120,7 @@ export class Image extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/compute/${this.getUrl('image')}/detail`, + routeName: this.getRouteName('imageDetail'), }, { title: t('Project ID/Name'), diff --git a/src/pages/compute/containers/Image/actions/Create.jsx b/src/pages/compute/containers/Image/actions/Create.jsx index 21e5cf96..1d7275a0 100644 --- a/src/pages/compute/containers/Image/actions/Create.jsx +++ b/src/pages/compute/containers/Image/actions/Create.jsx @@ -46,7 +46,7 @@ export class CreateForm extends FormAction { }; get listUrl() { - return this.getUrl('/compute/image'); + return this.getRoutePath('image'); } get name() { diff --git a/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx b/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx index c17e811e..c3ed4879 100644 --- a/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx +++ b/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx @@ -146,7 +146,7 @@ export class BaseDetail extends Base { get imageCard() { const item = this.detailData.itemInList || {}; const { image, image_name } = item; - const url = `${this.getUrl('/compute/image')}/detail/${image}`; + const url = this.getRoutePath('imageDetail', { id: image }); const options = [ { label: t('Name'), diff --git a/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx b/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx index 427c4c8a..03118827 100644 --- a/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx +++ b/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx @@ -34,6 +34,7 @@ import { CaretRightOutlined } from '@ant-design/icons'; import ItemActionButtons from 'components/Tables/Base/ItemActionButtons'; import { getSelfColumns } from 'resources/security-group-rule'; import { isAdminPage } from 'utils/index'; +import { getPath } from 'utils/route-map'; import styles from './index.less'; import Detach from './action/Detach'; import ManageSecurityGroup from './action/ManageSecurityGroup'; @@ -68,12 +69,11 @@ export class SecurityGroup extends React.Component { return !this.isAdminPage; } - getUrl(path, adminStr) { - return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; - } - getDetailUrl(id) { - return `${this.getUrl('/network/security-group')}/detail/${id}`; + const key = this.isAdminPage + ? 'securityGroupDetailAdmin' + : 'securityGroupDetail'; + return getPath({ key, params: { id } }); } actionCallback = async (first) => { diff --git a/src/pages/compute/containers/Instance/Detail/index.jsx b/src/pages/compute/containers/Instance/Detail/index.jsx index c2efe7ff..d5d2de15 100644 --- a/src/pages/compute/containers/Instance/Detail/index.jsx +++ b/src/pages/compute/containers/Instance/Detail/index.jsx @@ -46,9 +46,9 @@ export class InstanceDetail extends Base { get listUrl() { if (this.isRecycleBinDetail) { - return this.getUrl('/management/recycle-bin'); + return this.getRoutePath('recycleBin'); } - return this.getUrl('/compute/instance'); + return this.getRoutePath('instance'); } get actionConfigs() { @@ -63,9 +63,8 @@ export class InstanceDetail extends Base { get detailData() { const { id, status } = this.store.detail; if (id && status === 'soft_deleted' && !this.isRecycleBinDetail) { - this.routing.push( - `${this.getUrl('/management/recycle-bin')}/detail/${id}` - ); + const path = this.getRoutePath('recycleBinDetail', { id }); + this.routing.push(path); } return toJS(this.store.detail) || {}; } diff --git a/src/pages/compute/containers/Instance/actions/CreateIronic/index.jsx b/src/pages/compute/containers/Instance/actions/CreateIronic/index.jsx index 7471fbaa..e7f5ef4f 100644 --- a/src/pages/compute/containers/Instance/actions/CreateIronic/index.jsx +++ b/src/pages/compute/containers/Instance/actions/CreateIronic/index.jsx @@ -88,15 +88,15 @@ export class CreateIronic extends StepAction { get listUrl() { const { image, volume, servergroup } = this.locationParams; if (image) { - return '/compute/image'; + return this.getRoutePath('image'); } if (volume) { - return '/storage/volume'; + return this.getRoutePath('volume'); } if (servergroup) { - return `/compute/server-group/detail/${servergroup}`; + return this.getRoutePath('serverGroupDetail', { id: servergroup }); } - return '/compute/instance'; + return this.getRoutePath('instance'); } get checkEndpoint() { diff --git a/src/pages/compute/containers/Instance/actions/StepCreate/index.jsx b/src/pages/compute/containers/Instance/actions/StepCreate/index.jsx index 15a2518b..3e2e1ef9 100644 --- a/src/pages/compute/containers/Instance/actions/StepCreate/index.jsx +++ b/src/pages/compute/containers/Instance/actions/StepCreate/index.jsx @@ -83,15 +83,15 @@ export class StepCreate extends StepAction { get listUrl() { const { image, volume, servergroup } = this.locationParams; if (image) { - return '/compute/image'; + return this.getRoutePath('image'); } if (volume) { - return '/storage/volume'; + return this.getRoutePath('volume'); } if (servergroup) { - return `/compute/server-group/detail/${servergroup}`; + return this.getRoutePath('serverGroupDetail', { id: servergroup }); } - return '/compute/instance'; + return this.getRoutePath('instance'); } get hasConfirmStep() { diff --git a/src/pages/compute/containers/Instance/index.jsx b/src/pages/compute/containers/Instance/index.jsx index 435866c6..111bf18a 100644 --- a/src/pages/compute/containers/Instance/index.jsx +++ b/src/pages/compute/containers/Instance/index.jsx @@ -131,7 +131,7 @@ export class Instance extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/compute/${this.getUrl('instance')}/detail`, + routeName: this.getRouteName('instanceDetail'), sortKey: 'display_name', }, { diff --git a/src/pages/compute/containers/Keypair/Detail/index.jsx b/src/pages/compute/containers/Keypair/Detail/index.jsx index f132362b..8337c975 100644 --- a/src/pages/compute/containers/Keypair/Detail/index.jsx +++ b/src/pages/compute/containers/Keypair/Detail/index.jsx @@ -30,7 +30,7 @@ export default class KeypairDetail extends Base { } get listUrl() { - return '/compute/keypair'; + return this.getRoutePath('keypair'); } get actionConfigs() { diff --git a/src/pages/compute/containers/Keypair/index.jsx b/src/pages/compute/containers/Keypair/index.jsx index 80ea9030..2c082047 100644 --- a/src/pages/compute/containers/Keypair/index.jsx +++ b/src/pages/compute/containers/Keypair/index.jsx @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import keypairStore from 'stores/nova/keypair'; -import { Link } from 'react-router-dom'; import actionConfigs from './actions'; @inject('rootStore') @@ -50,14 +48,8 @@ export default class Keypair extends Base { { title: t('Name'), dataIndex: 'name', - render: (name, record) => { - if (name) { - return ( - {name} - ); - } - return '-'; - }, + idKey: 'name', + routeName: this.getRouteName('keypairDetail'), }, { title: t('Fingerprint'), diff --git a/src/pages/compute/containers/ServerGroup/Detail/index.jsx b/src/pages/compute/containers/ServerGroup/Detail/index.jsx index cf7233b9..1b1e370e 100644 --- a/src/pages/compute/containers/ServerGroup/Detail/index.jsx +++ b/src/pages/compute/containers/ServerGroup/Detail/index.jsx @@ -31,7 +31,7 @@ export default class ServerGroupDetail extends Base { } get listUrl() { - return this.getUrl('/compute/server-group'); + return this.getRoutePath('serverGroup'); } get actionConfigs() { diff --git a/src/pages/compute/containers/ServerGroup/index.jsx b/src/pages/compute/containers/ServerGroup/index.jsx index f6998958..e8fd7969 100644 --- a/src/pages/compute/containers/ServerGroup/index.jsx +++ b/src/pages/compute/containers/ServerGroup/index.jsx @@ -44,7 +44,7 @@ export default class ServerGroup extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/compute/${this.getUrl('server-group')}/detail`, + routeName: this.getRouteName('serverGroupDetail'), }, { title: t('Project ID/Name'), diff --git a/src/pages/configuration/containers/Metadata/Detail/index.jsx b/src/pages/configuration/containers/Metadata/Detail/index.jsx index e9a8842e..e70baacf 100644 --- a/src/pages/configuration/containers/Metadata/Detail/index.jsx +++ b/src/pages/configuration/containers/Metadata/Detail/index.jsx @@ -30,7 +30,7 @@ export default class MetadataDetail extends Base { } get listUrl() { - return '/configuration-admin/metadata'; + return this.getRoutePath('metadata'); } get actionConfigs() { diff --git a/src/pages/configuration/containers/SystemInfo/NeutronAgent/Detail/index.jsx b/src/pages/configuration/containers/SystemInfo/NeutronAgent/Detail/index.jsx index 1a90eadf..9a326805 100644 --- a/src/pages/configuration/containers/SystemInfo/NeutronAgent/Detail/index.jsx +++ b/src/pages/configuration/containers/SystemInfo/NeutronAgent/Detail/index.jsx @@ -36,7 +36,7 @@ export default class KeypairDetail extends Base { } get listUrl() { - return '/configuration-admin/info?tab=neutronAgent'; + return this.getRoutePath('systemInfo', null, { tab: 'neutronAgent' }); } get actionConfigs() { diff --git a/src/pages/configuration/containers/SystemInfo/NeutronAgent/index.jsx b/src/pages/configuration/containers/SystemInfo/NeutronAgent/index.jsx index b0d1aa82..51f59bf2 100644 --- a/src/pages/configuration/containers/SystemInfo/NeutronAgent/index.jsx +++ b/src/pages/configuration/containers/SystemInfo/NeutronAgent/index.jsx @@ -48,8 +48,8 @@ export default class NeutronAgent extends Base { { title: t('ID/Name'), dataIndex: 'binary', - isName: true, - linkPrefix: '/configuration-admin/neutron/detail', + isLink: true, + routeName: 'neutronAgentDetailAdmin', }, { title: t('Type'), diff --git a/src/pages/heat/containers/Stack/Detail/Resource.jsx b/src/pages/heat/containers/Stack/Detail/Resource.jsx index 50450ab3..f94fff26 100644 --- a/src/pages/heat/containers/Stack/Detail/Resource.jsx +++ b/src/pages/heat/containers/Stack/Detail/Resource.jsx @@ -12,12 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import { StackResourceStore } from 'stores/heat/resource'; import { stackStatus } from 'resources/stack'; -import { Link } from 'react-router-dom'; export class Resource extends Base { init() { @@ -41,138 +39,112 @@ export class Resource extends Base { { key: 'OS::Cinder::EncryptedVolumeType', isAdmin: true, - getUrl: (value) => - `${this.getUrl('/storage/volume-type')}/detail/${value}`, + routeName: 'volumeTypeDetail', }, { key: 'OS::Cinder::QoSAssociation', isAdmin: true, - getUrl: (value) => - `${this.getUrl('/storage/volume-type')}/qos/detail/${value}`, + routeName: 'volumeTypeQosDetail', }, { key: 'OS::Cinder::QoSSpecs', isAdmin: true, - getUrl: (value) => - `${this.getUrl('/storage/volume-type')}/qos/detail/${value}`, + routeName: 'volumeTypeQosDetail', }, { key: 'OS::Cinder::Volume', - getUrl: (value) => `${this.getUrl('/storage/volume')}/detail/${value}`, + routeName: 'volumeDetail', }, { key: 'OS::Cinder::VolumeType', isAdmin: true, - getUrl: (value) => - `${this.getUrl('/storage/volume-type')}/detail/${value}`, + routeName: 'volumeTypeDetail', }, { key: 'OS::Glance::WebImage', - getUrl: (value) => `${this.getUrl('/compute/image')}/detail/${value}`, - }, - { - key: 'OS::Glance::WebImage', - getUrl: (value) => `${this.getUrl('/compute/image')}/detail/${value}`, + routeName: 'imageDetail', }, { key: 'OS::Heat::Stack', - getUrl: (value) => `${this.getUrl('/heat/stack')}/detail/${value}`, + routeName: 'stackDetail', }, { key: 'OS::Ironic::Port', - getUrl: (value) => - `${this.getUrl( - '/network/virtual_adapter', - '_admin' - )}/detail/${value}`, + routeName: 'virtualAdapterDetail', }, { key: 'OS::Keystone::Domain', + routeName: 'domainDetail', isAdmin: true, - getUrl: (value) => `${this.getUrl('/identity/domain')}/detail/${value}`, }, { key: 'OS::Keystone::Group', + routeName: 'userGroupDetail', isAdmin: true, - getUrl: (value) => - `${this.getUrl('/identity/user-group')}/detail/${value}`, }, { key: 'OS::Keystone::Project', + routeName: 'projectDetail', isAdmin: true, - getUrl: (value) => - `${this.getUrl('/identity/project')}/detail/${value}`, }, { key: 'OS::Keystone::Role', + routeName: 'roleDetail', isAdmin: true, - getUrl: (value) => `${this.getUrl('/identity/role')}/detail/${value}`, }, { key: 'OS::Keystone::User', + routeName: 'userDetail', isAdmin: true, - getUrl: (value) => `${this.getUrl('/identity/user')}/detail/${value}`, }, { key: 'OS::Neutron::FloatingIP', - getUrl: (value) => - `${this.getUrl('/network/floatingip')}/detail/${value}`, + routeName: 'fipDetail', }, { key: 'OS::Neutron::LBaaS::LoadBalancer', - getUrl: (value) => - `${this.getUrl('/network/load-balancers')}/detail/${value}`, + routeName: 'lbDetail', }, { key: 'OS::Neutron::Net', - getUrl: (value) => - `${this.getUrl('/network/networks')}/detail/${value}`, + routeName: 'networkDetail', }, { key: 'OS::Neutron::Port', - getUrl: (value) => - `${this.getUrl( - '/network/virtual_adapter', - '_admin' - )}/detail/${value}`, + routeName: 'virtualAdapterDetail', }, { key: 'OS::Neutron::QoSPolicy', - getUrl: (value) => - `${this.getUrl('/network/qos-policy')}/detail/${value}`, + routeName: 'networkQosDetail', }, { key: 'OS::Neutron::Router', - getUrl: (value) => `${this.getUrl('/network/router')}/detail/${value}`, + routeName: 'routerDetail', }, { key: 'OS::Neutron::SecurityGroup', - getUrl: (value) => - `${this.getUrl('/network/security-group')}/detail/${value}`, + routeName: 'securityGroupDetail', }, { key: 'OS::Nova::Flavor', isAdmin: true, - getUrl: (value) => `${this.getUrl('/compute/flavor')}/detail/${value}`, + routeName: 'flavorDetail', }, { key: 'OS::Nova::KeyPair', - getUrl: (value) => `/compute/keypair/detail/${value}`, + routeName: 'keypairDetail', }, { key: 'OS::Nova::Server', - getUrl: (value) => - `${this.getUrl('/compute/instance')}/detail/${value}`, + routeName: 'instanceDetail', }, { key: 'OS::Nova::ServerGroup', - getUrl: (value) => - `${this.getUrl('/compute/server-group')}/detail/${value}`, + routeName: 'serverGroupDetail', }, { key: 'OS::Octavia::LoadBalancer', - getUrl: (value) => - `${this.getUrl('/network/load-balancers')}/detail/${value}`, + routeName: 'lbDetail', }, ]; } @@ -186,16 +158,13 @@ export class Resource extends Base { if (!item) { return value; } - const { isAdmin, getUrl } = item; + const { isAdmin, routeName } = item; + const link = this.getLinkRender(routeName, value, { id: value }); if (isAdmin) { - return this.isAdminPage ? ( - {value} - ) : ( - value - ); + return this.isAdminPage ? link : value; } - if (getUrl) { - return {value}; + if (routeName) { + return link; } return value; }; diff --git a/src/pages/heat/containers/Stack/Detail/index.jsx b/src/pages/heat/containers/Stack/Detail/index.jsx index af7efeeb..80988739 100644 --- a/src/pages/heat/containers/Stack/Detail/index.jsx +++ b/src/pages/heat/containers/Stack/Detail/index.jsx @@ -32,7 +32,7 @@ export class StackDetail extends Base { } get listUrl() { - return this.getUrl('/heat/stack'); + return this.getRoutePath('stack'); } init() { diff --git a/src/pages/heat/containers/Stack/actions/Create/index.jsx b/src/pages/heat/containers/Stack/actions/Create/index.jsx index b9b7c5c9..5e28fa33 100644 --- a/src/pages/heat/containers/Stack/actions/Create/index.jsx +++ b/src/pages/heat/containers/Stack/actions/Create/index.jsx @@ -37,7 +37,7 @@ export class StepCreate extends StepAction { } get listUrl() { - return this.getUrl('/heat/stack'); + return this.getRoutePath('stack'); } get name() { diff --git a/src/pages/heat/containers/Stack/actions/Edit.jsx b/src/pages/heat/containers/Stack/actions/Edit.jsx index c821b0d3..51247449 100644 --- a/src/pages/heat/containers/Stack/actions/Edit.jsx +++ b/src/pages/heat/containers/Stack/actions/Edit.jsx @@ -13,6 +13,7 @@ // limitations under the License. import { inject, observer } from 'mobx-react'; +import { getPath } from 'utils/route-map'; import Create from './Create'; @inject('rootStore') @@ -24,14 +25,13 @@ export default class Edit extends Create { static path = (item, containerProp) => { const { isAdminPage } = containerProp; - const prefix = isAdminPage - ? '/heat/stack-admin/edit/' - : '/heat/stack/edit/'; - return `${prefix}${item.id}/${item.stack_name}`; + const key = isAdminPage ? 'stackEditAdmin' : 'stackEdit'; + const { id, stack_name: name } = item; + return getPath({ key, params: { id, name } }); }; get listUrl() { - return this.getUrl('/heat/stack'); + return this.getRoutePath('stack'); } get name() { diff --git a/src/pages/heat/containers/Stack/index.jsx b/src/pages/heat/containers/Stack/index.jsx index 146d22a9..0652f5eb 100644 --- a/src/pages/heat/containers/Stack/index.jsx +++ b/src/pages/heat/containers/Stack/index.jsx @@ -59,9 +59,14 @@ export class Stack extends Base { { title: t('ID/Name'), dataIndex: 'stack_name', - linkFunc: (value, record) => - `/heat/${this.getUrl('stack')}/detail/${record.id}/${value}`, - isName: true, + routeName: this.getRouteName('stackDetail'), + routeParamsFunc: (data) => { + return { + id: data.id, + name: data.stack_name, + }; + }, + isLink: true, }, { title: t('Project ID/Name'), diff --git a/src/pages/identity/containers/Domain/Detail/index.jsx b/src/pages/identity/containers/Domain/Detail/index.jsx index 184dd41e..7249a9b2 100644 --- a/src/pages/identity/containers/Domain/Detail/index.jsx +++ b/src/pages/identity/containers/Domain/Detail/index.jsx @@ -31,7 +31,7 @@ export default class DomainDetail extends Base { } get listUrl() { - return '/identity/domain-admin'; + return this.getRoutePath('domain'); } get detailInfos() { diff --git a/src/pages/identity/containers/Domain/actions/Create.jsx b/src/pages/identity/containers/Domain/actions/Create.jsx index 4405ded9..4e9dfe54 100644 --- a/src/pages/identity/containers/Domain/actions/Create.jsx +++ b/src/pages/identity/containers/Domain/actions/Create.jsx @@ -37,7 +37,7 @@ class CreateForm extends FormAction { } get listUrl() { - return '/identity/domain-admin'; + return this.getRoutePath('domain'); } get name() { diff --git a/src/pages/identity/containers/Domain/actions/Edit.jsx b/src/pages/identity/containers/Domain/actions/Edit.jsx index 67ab0a31..19d16545 100644 --- a/src/pages/identity/containers/Domain/actions/Edit.jsx +++ b/src/pages/identity/containers/Domain/actions/Edit.jsx @@ -46,7 +46,7 @@ class EditForm extends FormAction { } get listUrl() { - return '/identity/domain-admin'; + return this.getRoutePath('domain'); } get data() { diff --git a/src/pages/identity/containers/Domain/index.jsx b/src/pages/identity/containers/Domain/index.jsx index ca9d1bc9..26f32b3c 100644 --- a/src/pages/identity/containers/Domain/index.jsx +++ b/src/pages/identity/containers/Domain/index.jsx @@ -43,8 +43,7 @@ export default class Domains extends Base { { title: t('Domain ID/Name'), dataIndex: 'name', - // isHideable: true, - linkPrefix: '/identity/domain-admin/detail', + routeName: 'domainDetailAdmin', }, { title: t('Member Num'), diff --git a/src/pages/identity/containers/Project/Detail/index.jsx b/src/pages/identity/containers/Project/Detail/index.jsx index 20e53b98..85852b3d 100644 --- a/src/pages/identity/containers/Project/Detail/index.jsx +++ b/src/pages/identity/containers/Project/Detail/index.jsx @@ -32,7 +32,7 @@ export class Detail extends Base { } get listUrl() { - return this.getUrl('/identity/project'); + return this.getRoutePath('project'); } get actionConfigs() { diff --git a/src/pages/identity/containers/Project/index.jsx b/src/pages/identity/containers/Project/index.jsx index 6cd71faa..7ec6f3ab 100644 --- a/src/pages/identity/containers/Project/index.jsx +++ b/src/pages/identity/containers/Project/index.jsx @@ -66,7 +66,7 @@ export class Projects extends Base { { title: t('Project ID/Name'), dataIndex: 'name', - linkPrefix: `/identity/${this.getUrl('project')}/detail`, + routeName: 'projectDetailAdmin', }, { title: t('Role'), diff --git a/src/pages/identity/containers/Role/Detail/index.jsx b/src/pages/identity/containers/Role/Detail/index.jsx index b89395fa..18b17751 100644 --- a/src/pages/identity/containers/Role/Detail/index.jsx +++ b/src/pages/identity/containers/Role/Detail/index.jsx @@ -29,7 +29,7 @@ export class RoleDetail extends Base { } get listUrl() { - return '/identity/role-admin'; + return this.getRoutePath('role'); } init() { diff --git a/src/pages/identity/containers/Role/index.jsx b/src/pages/identity/containers/Role/index.jsx index 1bd41ffd..46c20007 100644 --- a/src/pages/identity/containers/Role/index.jsx +++ b/src/pages/identity/containers/Role/index.jsx @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import { Link } from 'react-router-dom'; import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import globalRoleStore from 'stores/keystone/role'; @@ -45,15 +43,7 @@ export default class Role extends Base { { title: t('Role Name'), dataIndex: 'name', - linkPrefix: '/identity/role-admin/detail', - render: (name, record) => { - if (name) { - return ( - {name} - ); - } - return '-'; - }, + routeName: 'roleDetailAdmin', }, { title: t('ID'), diff --git a/src/pages/identity/containers/User/Detail/index.jsx b/src/pages/identity/containers/User/Detail/index.jsx index b850cc2e..dd211849 100644 --- a/src/pages/identity/containers/User/Detail/index.jsx +++ b/src/pages/identity/containers/User/Detail/index.jsx @@ -33,7 +33,7 @@ export class UserDetail extends Base { } get listUrl() { - return '/identity/user-admin'; + return this.getRoutePath('user'); } get actionConfigs() { diff --git a/src/pages/identity/containers/User/actions/Create.jsx b/src/pages/identity/containers/User/actions/Create.jsx index bf08be92..fcc4ae23 100644 --- a/src/pages/identity/containers/User/actions/Create.jsx +++ b/src/pages/identity/containers/User/actions/Create.jsx @@ -93,7 +93,7 @@ export class CreateForm extends FormAction { } get listUrl() { - return '/identity/user-admin'; + return this.getRoutePath('user'); } get defaultValue() { diff --git a/src/pages/identity/containers/User/index.jsx b/src/pages/identity/containers/User/index.jsx index ab49e8da..a46b0d6d 100644 --- a/src/pages/identity/containers/User/index.jsx +++ b/src/pages/identity/containers/User/index.jsx @@ -81,7 +81,7 @@ export class User extends Base { { title: t('User ID/Name'), dataIndex: 'name', - linkPrefix: `/identity/${this.getUrl('user')}/detail`, + routeName: 'userDetailAdmin', }, { title: t('Project Scope'), diff --git a/src/pages/identity/containers/UserGroup/Detail/index.jsx b/src/pages/identity/containers/UserGroup/Detail/index.jsx index 17f20080..20944a30 100644 --- a/src/pages/identity/containers/UserGroup/Detail/index.jsx +++ b/src/pages/identity/containers/UserGroup/Detail/index.jsx @@ -36,7 +36,7 @@ export default class Detail extends Base { } get listUrl() { - return '/identity/user-group-admin'; + return this.getRoutePath('userGroup'); } get actionConfigs() { diff --git a/src/pages/identity/containers/UserGroup/index.jsx b/src/pages/identity/containers/UserGroup/index.jsx index 721687a4..619eb198 100644 --- a/src/pages/identity/containers/UserGroup/index.jsx +++ b/src/pages/identity/containers/UserGroup/index.jsx @@ -51,7 +51,7 @@ export default class UserGroups extends Base { { title: t('User Group ID/Name'), dataIndex: 'name', - linkPrefix: '/identity/user-group-admin/detail', + routeName: 'userGroupDetailAdmin', }, { title: t('Project Scope'), diff --git a/src/pages/management/containers/RecycleBin/index.jsx b/src/pages/management/containers/RecycleBin/index.jsx index 7c17040a..07b3e0bf 100644 --- a/src/pages/management/containers/RecycleBin/index.jsx +++ b/src/pages/management/containers/RecycleBin/index.jsx @@ -60,7 +60,7 @@ export default class RecycleBin extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/management/${this.getUrl('recycle-bin')}/detail`, + routeName: this.getRouteName('recycleBinDetail'), sortKey: 'display_name', }, { diff --git a/src/pages/network/containers/FloatingIp/Detail/BaseDetail.jsx b/src/pages/network/containers/FloatingIp/Detail/BaseDetail.jsx index b5dfccfe..72ccc14e 100644 --- a/src/pages/network/containers/FloatingIp/Detail/BaseDetail.jsx +++ b/src/pages/network/containers/FloatingIp/Detail/BaseDetail.jsx @@ -12,10 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { inject, observer } from 'mobx-react'; import { FloatingIpStore } from 'stores/neutron/floatingIp'; -import { Link } from 'react-router-dom'; import Base from 'containers/BaseDetail'; export class BaseDetail extends Base { @@ -70,12 +68,11 @@ export class BaseDetail extends Base { if (router_name === '-' && network_name === '-') { return data; } - return ( - - {`${data}`} - {router_name && `(${router_name})`} - - ); + const value = router_name ? `${data} (${router_name})` : data; + const link = this.getLinkRender('routerDetail', value, { + id: data, + }); + return link; } return '-'; }, diff --git a/src/pages/network/containers/FloatingIp/Detail/index.jsx b/src/pages/network/containers/FloatingIp/Detail/index.jsx index d11af786..017cb193 100644 --- a/src/pages/network/containers/FloatingIp/Detail/index.jsx +++ b/src/pages/network/containers/FloatingIp/Detail/index.jsx @@ -31,7 +31,7 @@ export class FloatingIpDetail extends Base { } get listUrl() { - return this.getUrl('/network/floatingip'); + return this.getRoutePath('floatingip'); } get actionConfigs() { diff --git a/src/pages/network/containers/FloatingIp/index.jsx b/src/pages/network/containers/FloatingIp/index.jsx index 9557e134..61010862 100644 --- a/src/pages/network/containers/FloatingIp/index.jsx +++ b/src/pages/network/containers/FloatingIp/index.jsx @@ -17,7 +17,6 @@ import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import { floatingIpStatus, transitionStatuses } from 'resources/floatingip'; import { FloatingIpStore } from 'stores/neutron/floatingIp'; -import { Link } from 'react-router-dom'; import { emptyActionConfig } from 'utils/constants'; import { Col, Popover, Row } from 'antd'; import { FileTextOutlined } from '@ant-design/icons'; @@ -122,17 +121,15 @@ export class FloatingIps extends Base { { title: t('ID/Floating IP'), dataIndex: 'floating_ip_address', - isName: true, - linkPrefix: `/network/${this.getUrl('floatingip')}/detail`, + isLink: true, + routeName: this.getRouteName('fipDetail'), }, { title: t('QoS Policy'), dataIndex: 'qos_policy_id', - render: (value) => ( - - {value} - - ), + isLink: true, + routeName: 'qosPolicyDetail', + idKey: 'qos_policy_id', hidden: !this.qosEndpoint, }, { diff --git a/src/pages/network/containers/LoadBalancers/Listener/Detail/index.jsx b/src/pages/network/containers/LoadBalancers/Listener/Detail/index.jsx index db94b558..e408ca2d 100644 --- a/src/pages/network/containers/LoadBalancers/Listener/Detail/index.jsx +++ b/src/pages/network/containers/LoadBalancers/Listener/Detail/index.jsx @@ -32,8 +32,8 @@ export default class ListenerDetail extends Base { } get listUrl() { - const { loadBalancerId } = this.params; - return `/network/${this.getUrl('load-balancers')}/detail/${loadBalancerId}`; + const { loadBalancerId: id } = this.params; + return this.getRoutePath('lbDetail', { id }); } get actionConfigs() { diff --git a/src/pages/network/containers/LoadBalancers/Listener/index.jsx b/src/pages/network/containers/LoadBalancers/Listener/index.jsx index 57938572..71912d6e 100644 --- a/src/pages/network/containers/LoadBalancers/Listener/index.jsx +++ b/src/pages/network/containers/LoadBalancers/Listener/index.jsx @@ -61,11 +61,13 @@ export default class Listeners extends Base { { title: t('ID/Name'), dataIndex: 'name', - isName: true, - linkPrefix: `/network/${this.getUrl('load-balancers')}/${ - this.id - }/listener/`, - idKey: 'id', + routeName: this.getRouteName('lbDetail'), + routeParamsFunc: (data) => { + return { + loadBalancerId: this.id, + id: data.id, + }; + }, }, { title: t('Status'), diff --git a/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/Detail/index.jsx b/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/Detail/index.jsx index e5a0653f..8c8b9cab 100644 --- a/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/Detail/index.jsx +++ b/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/Detail/index.jsx @@ -42,7 +42,7 @@ export default class LoadBalancerDetail extends Base { }; get listUrl() { - return this.getUrl('/network/load-balancers'); + return this.getRoutePath('lb'); } get actionConfigs() { diff --git a/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/actions/StepCreate/index.jsx b/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/actions/StepCreate/index.jsx index 99eb2722..5f20eeff 100644 --- a/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/actions/StepCreate/index.jsx +++ b/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/actions/StepCreate/index.jsx @@ -46,7 +46,7 @@ class StepCreate extends StepAction { } get listUrl() { - return '/network/load-balancers'; + return this.getRoutePath('lb'); } get hasConfirmStep() { diff --git a/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/index.jsx b/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/index.jsx index 5b29b64a..81ee8426 100644 --- a/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/index.jsx +++ b/src/pages/network/containers/LoadBalancers/LoadBalancerInstance/index.jsx @@ -89,9 +89,7 @@ export default class LoadBalancerInstance extends Base { { title: t('ID/Name'), dataIndex: 'name', - isName: true, - linkPrefix: `/network/${this.getUrl('load-balancers')}/detail/`, - idKey: 'id', + routeName: this.getRouteName('lbDetail'), }, { title: t('Project ID/Name'), diff --git a/src/pages/network/containers/Network/Detail/index.jsx b/src/pages/network/containers/Network/Detail/index.jsx index a8da05a2..9d1c0c35 100644 --- a/src/pages/network/containers/Network/Detail/index.jsx +++ b/src/pages/network/containers/Network/Detail/index.jsx @@ -32,7 +32,7 @@ export class NetworkDetail extends Base { } get listUrl() { - return this.getUrl('/network/networks'); + return this.getRoutePath('network'); } get actionConfigs() { diff --git a/src/pages/network/containers/QoSPolicy/Detail/index.jsx b/src/pages/network/containers/QoSPolicy/Detail/index.jsx index 75987bb5..c88a895d 100644 --- a/src/pages/network/containers/QoSPolicy/Detail/index.jsx +++ b/src/pages/network/containers/QoSPolicy/Detail/index.jsx @@ -30,7 +30,7 @@ export default class QoSPolicyDetail extends Base { } get listUrl() { - return this.getUrl('/network/qos-policy'); + return this.getRoutePath('qosPolicy'); } get actionConfigs() { diff --git a/src/pages/network/containers/Router/Detail/index.jsx b/src/pages/network/containers/Router/Detail/index.jsx index 98eb7faa..bbb61316 100644 --- a/src/pages/network/containers/Router/Detail/index.jsx +++ b/src/pages/network/containers/Router/Detail/index.jsx @@ -33,7 +33,7 @@ export class RouterDetail extends Base { } get listUrl() { - return this.getUrl('/network/router'); + return this.getRoutePath('router'); } get actionConfigs() { diff --git a/src/pages/network/containers/Router/Port/Detail/index.jsx b/src/pages/network/containers/Router/Port/Detail/index.jsx index 821e78fc..9e9b3c52 100644 --- a/src/pages/network/containers/Router/Port/Detail/index.jsx +++ b/src/pages/network/containers/Router/Port/Detail/index.jsx @@ -29,9 +29,11 @@ export class PortDetail extends Base { get listUrl() { const { routerId } = this.params; - return `/network/${this.getUrl( - 'router' - )}/detail/${routerId}?tab=interfaces`; + return this.getRoutePath( + 'routerDetail', + { id: routerId }, + { tab: 'interfaces' } + ); } get detailInfos() { diff --git a/src/pages/network/containers/Router/Port/index.jsx b/src/pages/network/containers/Router/Port/index.jsx index b96f40d6..d8995cca 100644 --- a/src/pages/network/containers/Router/Port/index.jsx +++ b/src/pages/network/containers/Router/Port/index.jsx @@ -51,8 +51,12 @@ export default class Ports extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/network/${this.getUrl('router')}/${this.id}/port`, stringify: (name, record) => name || record.id, + routeName: this.getRouteName('routerPortDetail'), + routeParamsFunc: (data) => ({ + routeId: this.id, + id: data.id, + }), }, { title: t('IP Address'), diff --git a/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx b/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx index 3c140a50..af2c22a7 100644 --- a/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx +++ b/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx @@ -16,6 +16,7 @@ import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import globalSecurityGroupRuleStore from 'stores/neutron/security-rule'; import { filterParams, getSelfColumns } from 'resources/security-group-rule'; +import { getPath } from 'utils/route-map'; import actionConfigs from './actions'; export class Rule extends Base { @@ -32,7 +33,10 @@ export class Rule extends Base { } getDetailUrl(id) { - return `${this.getUrl('/network/security-group')}/detail/${id}`; + const key = this.isAdminPage + ? 'securityGroupDetailAdmin' + : 'securityGroupDetail'; + return getPath({ key, params: { id } }); } getColumns = () => getSelfColumns(this); diff --git a/src/pages/network/containers/SecurityGroup/Detail/index.jsx b/src/pages/network/containers/SecurityGroup/Detail/index.jsx index eaa9a910..78748f1d 100644 --- a/src/pages/network/containers/SecurityGroup/Detail/index.jsx +++ b/src/pages/network/containers/SecurityGroup/Detail/index.jsx @@ -29,7 +29,7 @@ export class SecurityGroupDetail extends Base { } get listUrl() { - return this.getUrl('/network/security-group'); + return this.getRoutePath('securityGroup'); } get actionConfigs() { diff --git a/src/pages/network/containers/SecurityGroup/index.jsx b/src/pages/network/containers/SecurityGroup/index.jsx index 7be43a02..54cd75b9 100644 --- a/src/pages/network/containers/SecurityGroup/index.jsx +++ b/src/pages/network/containers/SecurityGroup/index.jsx @@ -60,15 +60,11 @@ export class SecurityGroups extends Base { return true; } - get detailLink() { - return `/network/${this.getUrl('security-group')}/detail`; - } - getColumns = () => [ { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: this.detailLink, + routeName: this.getRouteName('securityGroupDetail'), }, { title: t('Project ID/Name'), diff --git a/src/pages/network/containers/VPN/EndpointGroup/actions/Create.js b/src/pages/network/containers/VPN/EndpointGroup/actions/Create.js index 4b4d1e5f..1eb14a73 100644 --- a/src/pages/network/containers/VPN/EndpointGroup/actions/Create.js +++ b/src/pages/network/containers/VPN/EndpointGroup/actions/Create.js @@ -165,7 +165,8 @@ export default class Create extends ModalAction { { title: t('Name'), dataIndex: 'name', - isName: true, + // todo: what? + isLink: true, }, { title: t('CIDR'), diff --git a/src/pages/network/containers/VPN/IPsecSiteConnection/Detail/index.jsx b/src/pages/network/containers/VPN/IPsecSiteConnection/Detail/index.jsx index 623d2ead..bcc3f016 100644 --- a/src/pages/network/containers/VPN/IPsecSiteConnection/Detail/index.jsx +++ b/src/pages/network/containers/VPN/IPsecSiteConnection/Detail/index.jsx @@ -34,7 +34,7 @@ export default class IPsecSiteConnection extends Base { } get listUrl() { - return `${this.getUrl('/network/vpn')}?tab=ipsec_site_connections`; + return this.getRoutePath('vpn', null, { tab: 'ipsec_site_connections' }); } get actionConfigs() { diff --git a/src/pages/network/containers/VPN/IPsecSiteConnection/index.jsx b/src/pages/network/containers/VPN/IPsecSiteConnection/index.jsx index 7364bf95..31bac8a1 100644 --- a/src/pages/network/containers/VPN/IPsecSiteConnection/index.jsx +++ b/src/pages/network/containers/VPN/IPsecSiteConnection/index.jsx @@ -58,8 +58,7 @@ export default class Index extends Base { { title: t('ID/Name'), dataIndex: 'name', - isName: true, - linkPrefix: `/network/${this.getUrl('ipsec-site-connection')}/detail`, + routeName: this.getRouteName('ipsecDetail'), }, { title: t('Project ID/Name'), diff --git a/src/pages/network/containers/VirtualAdapter/Detail/BaseDetail/index.jsx b/src/pages/network/containers/VirtualAdapter/Detail/BaseDetail/index.jsx index a0279dc8..21efe3ab 100644 --- a/src/pages/network/containers/VirtualAdapter/Detail/BaseDetail/index.jsx +++ b/src/pages/network/containers/VirtualAdapter/Detail/BaseDetail/index.jsx @@ -43,15 +43,14 @@ export default class BaseDetail extends Base { const { itemInList: { device_id, device_owner, server_name } = {} } = record; if (device_id && device_owner === 'compute:nova') { - return ( - - {`${device_id}`} - {server_name && `(${server_name})`} - + const value = server_name + ? `${device_id} (${server_name})` + : device_id; + return this.getLinkRender( + 'instanceDetail', + value, + { id: device_id }, + { tab: 'interface' } ); } return data || '-'; diff --git a/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx b/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx index 373bb2f8..62355ff9 100644 --- a/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx +++ b/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx @@ -25,6 +25,7 @@ import PrimaryActionButtons from 'components/Tables/Base/PrimaryActionButtons'; import ItemActionButtons from 'components/Tables/Base/ItemActionButtons'; import { getSelfColumns } from 'resources/security-group-rule'; import { isAdminPage } from 'utils/index'; +import { getPath } from 'utils/route-map'; import Detach from './actions/Detach'; import styles from './index.less'; @@ -40,12 +41,11 @@ export class SecurityGroup extends React.Component { this.refreshSecurityGroup(); } - getUrl(path, adminStr) { - return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path; - } - getDetailUrl(id) { - return `${this.getUrl('/network/security-group')}/detail/${id}`; + const key = this.isAdminPage + ? 'securityGroupDetailAdmin' + : 'securityGroupDetail'; + return getPath({ key, params: { id } }); } get portId() { diff --git a/src/pages/network/containers/VirtualAdapter/Detail/index.jsx b/src/pages/network/containers/VirtualAdapter/Detail/index.jsx index c8c11755..65095d88 100644 --- a/src/pages/network/containers/VirtualAdapter/Detail/index.jsx +++ b/src/pages/network/containers/VirtualAdapter/Detail/index.jsx @@ -32,7 +32,7 @@ export class VirtualAdapterDetail extends Base { } get listUrl() { - return this.getUrl('/network/virtual_adapter', '_admin'); + return this.getRoutePath('virtualAdapter'); } get actionConfigs() { diff --git a/src/pages/network/containers/VirtualAdapter/index.jsx b/src/pages/network/containers/VirtualAdapter/index.jsx index 7403cd6a..1c7a656d 100644 --- a/src/pages/network/containers/VirtualAdapter/index.jsx +++ b/src/pages/network/containers/VirtualAdapter/index.jsx @@ -13,7 +13,6 @@ // limitations under the License. import React from 'react'; -import { Link } from 'react-router-dom'; import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import { VirtualAdapterStore } from 'stores/neutron/virtual-adapter'; @@ -120,10 +119,7 @@ export class VirtualAdapter extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/network/${this.getUrl( - 'virtual_adapter', - '_admin' - )}/detail`, + routeName: this.getRouteName('virtualAdapterDetail'), }, { title: t('Project ID/Name'), @@ -145,18 +141,22 @@ export class VirtualAdapter extends Base { `; }, render: (server_name, item) => { - if (item.device_id && item.device_owner === 'compute:nova') { + const { device_id, device_owner } = item; + if (device_id && device_owner === 'compute:nova') { + const value = server_name + ? `${device_id} (${server_name})` + : device_id; + const link = this.getLinkRender( + 'instanceDetail', + value, + { id: item.device_id }, + { tab: 'interface' } + ); return ( <> {item.device_owner}
- - {`${item.device_id}`} - {server_name && `(${server_name})`} - + {link} ); } @@ -174,8 +174,8 @@ export class VirtualAdapter extends Base { { title: t('Owned Network'), dataIndex: 'network_name', - isName: true, - linkPrefix: `/network/${this.getUrl('networks')}/detail`, + isLink: true, + routeName: this.getRouteName('networkDetail'), idKey: 'network_id', sorter: false, }, diff --git a/src/pages/storage/containers/Backup/Detail/BaseDetail.jsx b/src/pages/storage/containers/Backup/Detail/BaseDetail.jsx index cc1d0737..90a87136 100644 --- a/src/pages/storage/containers/Backup/Detail/BaseDetail.jsx +++ b/src/pages/storage/containers/Backup/Detail/BaseDetail.jsx @@ -12,10 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { inject, observer } from 'mobx-react'; import Base from 'containers/BaseDetail'; -import { Link } from 'react-router-dom'; @inject('rootStore') @observer @@ -33,11 +31,8 @@ export default class BaseDetail extends Base { copyable: { text: this.detailData.volume_id, }, - render: (value) => ( - - {value} - - ), + render: (value) => + this.getLinkRender('volumeDetail', value, { id: value }), }, { label: t('Volume'), diff --git a/src/pages/storage/containers/Backup/Detail/index.jsx b/src/pages/storage/containers/Backup/Detail/index.jsx index d2a5d9f2..f68d72a7 100644 --- a/src/pages/storage/containers/Backup/Detail/index.jsx +++ b/src/pages/storage/containers/Backup/Detail/index.jsx @@ -31,7 +31,7 @@ export default class Detail extends Base { } get listUrl() { - return this.getUrl('/storage/backup'); + return this.getRoutePath('backup'); } get actionConfigs() { diff --git a/src/pages/storage/containers/Backup/index.jsx b/src/pages/storage/containers/Backup/index.jsx index 2110309d..1943b1ed 100644 --- a/src/pages/storage/containers/Backup/index.jsx +++ b/src/pages/storage/containers/Backup/index.jsx @@ -71,7 +71,7 @@ export default class Backup extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/storage/${this.getUrl('backup')}/detail`, + routeName: this.getRouteName('backupDetail'), sortKey: 'id', }, { @@ -83,11 +83,9 @@ export default class Backup extends Base { { title: t('Volume ID/Name'), dataIndex: 'volume_name', - isName: true, - linkFunc: (value, record) => - `/storage/${this.getUrl('volume')}/detail/${ - record.volume_id - }?tab=backup`, + isLink: true, + routeQuery: { tab: 'backup' }, + routeName: this.getRouteName('volumeDetail'), idKey: 'volume_id', sortKey: 'volume_id', }, diff --git a/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx b/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx index 437b4e2a..29cdfd57 100644 --- a/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx +++ b/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import { Link } from 'react-router-dom'; import { inject, observer } from 'mobx-react'; import Base from 'containers/BaseDetail'; @@ -32,13 +30,13 @@ export class BaseDetail extends Base { return '-'; } const { id, name } = value; - return ( - - {name || id} - + const link = this.getLinkRender( + 'volumeDetail', + name || id, + { id }, + { tab: 'snapshot' } ); + return link; }, }, ]; diff --git a/src/pages/storage/containers/Snapshot/Detail/index.jsx b/src/pages/storage/containers/Snapshot/Detail/index.jsx index 9e577354..1840513e 100644 --- a/src/pages/storage/containers/Snapshot/Detail/index.jsx +++ b/src/pages/storage/containers/Snapshot/Detail/index.jsx @@ -29,7 +29,7 @@ export class Detail extends Base { } get listUrl() { - return this.getUrl('/storage/snapshot'); + return this.getRoutePath('snapshot'); } get actionConfigs() { diff --git a/src/pages/storage/containers/Snapshot/index.jsx b/src/pages/storage/containers/Snapshot/index.jsx index 452fc0fc..69d7fbbc 100644 --- a/src/pages/storage/containers/Snapshot/index.jsx +++ b/src/pages/storage/containers/Snapshot/index.jsx @@ -83,7 +83,7 @@ export class Snapshots extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/storage/${this.getUrl('snapshot')}/detail`, + routeName: this.getRouteName('snapshotDetail'), }, { title: t('Project ID/Name'), @@ -114,12 +114,10 @@ export class Snapshots extends Base { { title: t('Volume ID/Name'), dataIndex: 'volume_name', - isName: true, + isLink: true, idKey: 'volume_id', - linkFunc: (_, record) => - `${this.getUrl('/storage/volume')}/detail/${ - record.volume_id - }?tab=snapshot`, + routeName: this.getRouteName('volumeDetail'), + routeQuery: { tab: 'snapshot' }, isHideable: true, sorter: false, }, diff --git a/src/pages/storage/containers/Volume/Detail/BaseDetail.jsx b/src/pages/storage/containers/Volume/Detail/BaseDetail.jsx index 0310a55d..7e214aec 100644 --- a/src/pages/storage/containers/Volume/Detail/BaseDetail.jsx +++ b/src/pages/storage/containers/Volume/Detail/BaseDetail.jsx @@ -13,7 +13,6 @@ // limitations under the License. import React from 'react'; -import { Link } from 'react-router-dom'; import { inject, observer } from 'mobx-react'; import Base from 'containers/BaseDetail'; @@ -41,13 +40,12 @@ export class BaseDetail extends Base { return value.map((it) => (
{it.device} on{' '} - - {it.server_name} - + {this.getLinkRender( + 'instanceDetail', + it.server_name, + { id: it.server_id }, + { tab: 'volumes' } + )}
)); }, @@ -67,11 +65,8 @@ export class BaseDetail extends Base { { label: t('Image'), dataIndex: 'volume_image_metadata.image_name', - render: () => ( - - {image_name} - - ), + render: () => + this.getLinkRender('imageDetail', image_name, { id: image_id }, null), }, ]; diff --git a/src/pages/storage/containers/Volume/Detail/index.jsx b/src/pages/storage/containers/Volume/Detail/index.jsx index 73e7c99b..c08e0a46 100644 --- a/src/pages/storage/containers/Volume/Detail/index.jsx +++ b/src/pages/storage/containers/Volume/Detail/index.jsx @@ -31,7 +31,7 @@ export class VolumeDetail extends Base { } get listUrl() { - return this.getUrl('/storage/volume'); + return this.getRoutePath('volume'); } getActionData() { diff --git a/src/pages/storage/containers/Volume/actions/Create/index.jsx b/src/pages/storage/containers/Volume/actions/Create/index.jsx index 6f1b3bcf..c52011f4 100644 --- a/src/pages/storage/containers/Volume/actions/Create/index.jsx +++ b/src/pages/storage/containers/Volume/actions/Create/index.jsx @@ -64,7 +64,7 @@ export class Create extends FormAction { static path = '/storage/volume/create'; get listUrl() { - return '/storage/volume'; + return this.getRoutePath('volume'); } get name() { diff --git a/src/pages/storage/containers/VolumeType/QosSpec/Detail/index.jsx b/src/pages/storage/containers/VolumeType/QosSpec/Detail/index.jsx index a0937e8a..643e1740 100644 --- a/src/pages/storage/containers/VolumeType/QosSpec/Detail/index.jsx +++ b/src/pages/storage/containers/VolumeType/QosSpec/Detail/index.jsx @@ -31,7 +31,7 @@ export default class Detail extends Base { } get listUrl() { - return '/storage/volume-type-admin?tab=qos'; + return this.getRoutePath('volumeType', null, { tab: 'qos' }); } get actionConfigs() { diff --git a/src/pages/storage/containers/VolumeType/QosSpec/index.jsx b/src/pages/storage/containers/VolumeType/QosSpec/index.jsx index 0ff75d54..e87cf074 100644 --- a/src/pages/storage/containers/VolumeType/QosSpec/index.jsx +++ b/src/pages/storage/containers/VolumeType/QosSpec/index.jsx @@ -46,7 +46,7 @@ export default class QosSpecs extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: '/storage/volume-type-admin/qos/detail', + routeName: 'volumeTypeQosDetailAdmin', }, { title: t('Consumer'), diff --git a/src/pages/storage/containers/VolumeType/VolumeType/Detail/index.jsx b/src/pages/storage/containers/VolumeType/VolumeType/Detail/index.jsx index 5bc4d855..92c2b630 100644 --- a/src/pages/storage/containers/VolumeType/VolumeType/Detail/index.jsx +++ b/src/pages/storage/containers/VolumeType/VolumeType/Detail/index.jsx @@ -32,7 +32,7 @@ export default class Detail extends Base { } get listUrl() { - return '/storage/volume-type-admin'; + return this.getRoutePath('volumeType'); } get actionConfigs() { diff --git a/src/pages/storage/containers/VolumeType/VolumeType/index.jsx b/src/pages/storage/containers/VolumeType/VolumeType/index.jsx index 5e076286..15aaf0bd 100644 --- a/src/pages/storage/containers/VolumeType/VolumeType/index.jsx +++ b/src/pages/storage/containers/VolumeType/VolumeType/index.jsx @@ -72,7 +72,7 @@ export default class VolumeType extends Base { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: '/storage/volume-type-admin/detail', + routeName: 'volumeTypeDetailAdmin', }, { title: t('Description'), @@ -83,8 +83,8 @@ export default class VolumeType extends Base { { title: t('Associated QoS Spec'), dataIndex: 'qos_specs_name', - isName: true, - linkPrefix: '/storage/volume-type-admin/qos/detail/', + isLink: true, + routeName: 'volumeTypeQosDetailAdmin', idKey: 'qos_specs_id', }, { diff --git a/src/pages/user-center/containers/Credentials/actions/Create.jsx b/src/pages/user-center/containers/Credentials/actions/Create.jsx index 32b7855a..84728282 100644 --- a/src/pages/user-center/containers/Credentials/actions/Create.jsx +++ b/src/pages/user-center/containers/Credentials/actions/Create.jsx @@ -100,7 +100,9 @@ export class Create extends ModalAction { label: t('Roles'), type: 'check-group', options: this.roleOptions, - extra: t('If not provided, the roles assigned to the application credential will be the same as the roles in the current token.'), + extra: t( + 'If not provided, the roles assigned to the application credential will be the same as the roles in the current token.' + ), span: 12, }, { diff --git a/src/resources/flavor.js b/src/resources/flavor.js index 23c6ac66..2b727b04 100644 --- a/src/resources/flavor.js +++ b/src/resources/flavor.js @@ -137,7 +137,7 @@ export const getBaseColumns = (self) => [ { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: self ? `/compute/${self.getUrl('flavor')}/detail` : '', + routeName: self ? self.getRouteName('flavorDetail') : '', }, { title: t('Category'), diff --git a/src/resources/instance.jsx b/src/resources/instance.jsx index 6ab10526..eb4a0441 100644 --- a/src/resources/instance.jsx +++ b/src/resources/instance.jsx @@ -18,7 +18,6 @@ import { getLocalTimeStr } from 'utils/time'; import { Table, Popover } from 'antd'; import globalActionLogStore from 'stores/nova/action-log'; import { ironicOriginEndpoint } from 'client/client/constants'; -import { Link } from 'react-router-dom'; import lockSvg from 'asset/image/lock.svg'; import unlockSvg from 'asset/image/unlock.svg'; @@ -607,11 +606,8 @@ export const actionColumn = (self) => { dataIndex: 'user_id', isHideable: true, hidden: !self.isAdminPage, - render: (value) => ( - - {value} - - ), + render: (value) => + self.getLinkRender('userDetail', value, { id: value }, null), }, ]; }; diff --git a/src/resources/network.jsx b/src/resources/network.jsx index cd4a4aee..8e0ad9cf 100644 --- a/src/resources/network.jsx +++ b/src/resources/network.jsx @@ -33,7 +33,7 @@ export const networkColumns = (self) => [ { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/network/${self.getUrl('networks')}/detail`, + routeName: self.getRouteName('networkDetail'), }, { title: t('Is Current Project'), diff --git a/src/resources/port.jsx b/src/resources/port.jsx index fa0a85d5..fd0463bd 100644 --- a/src/resources/port.jsx +++ b/src/resources/port.jsx @@ -108,10 +108,7 @@ export function getPortFormItem(device_owner) { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/network/${this.getUrl( - 'virtual_adapter', - '_admin' - )}/detail`, + routeName: this.getRouteName('virtualAdapterDetail'), }, { title: t('Description'), diff --git a/src/resources/qos-policy.jsx b/src/resources/qos-policy.jsx index 7dd6bb44..e922f8b1 100644 --- a/src/resources/qos-policy.jsx +++ b/src/resources/qos-policy.jsx @@ -35,7 +35,7 @@ export const getQosPolicyColumns = ({ self, all = false }) => { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/network/${self.getUrl('qos-policy')}/detail`, + routeName: self.getRouteName('networkQosDetail'), }, { title: t('Description'), diff --git a/src/resources/router.jsx b/src/resources/router.jsx index 96ea724a..935cc769 100644 --- a/src/resources/router.jsx +++ b/src/resources/router.jsx @@ -13,7 +13,6 @@ // limitations under the License. import React from 'react'; -import { Link } from 'react-router-dom'; import globalRouterStore from 'stores/neutron/router'; import { getPortsWithFixedIPs, getSubnetToRouter } from 'resources/floatingip'; @@ -33,7 +32,7 @@ export const getRouterColumns = (self) => [ { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/network/${self.getUrl('router')}/detail`, + routeName: self.getRouteName('routerDetail'), }, { title: t('Project ID/Name'), @@ -59,11 +58,8 @@ export const getRouterColumns = (self) => [ dataIndex: 'externalNetworkId', isHideable: true, sorter: false, - render: (value) => ( - - {value} - - ), + render: (value) => + self.getLinkRender('networkDetail', value, { id: value }), }, { title: t('External Fixed IP'), diff --git a/src/resources/volume.jsx b/src/resources/volume.jsx index 46499fb6..c5ede8b7 100644 --- a/src/resources/volume.jsx +++ b/src/resources/volume.jsx @@ -15,7 +15,6 @@ import React from 'react'; import { yesNoOptions } from 'utils/constants'; import { toLocalTimeFilter } from 'utils/index'; -import { Link } from 'react-router-dom'; export const volumeStatus = { available: t('Available'), @@ -236,7 +235,7 @@ export const getVolumnColumnsList = (self) => { { title: t('ID/Name'), dataIndex: 'name', - linkPrefix: `/storage/${self.getUrl('volume')}/detail`, + routeName: self.getRouteName('volumeDetail'), stringify: (name, record) => name || record.id, sortKey: 'name', }, @@ -289,13 +288,12 @@ export const getVolumnColumnsList = (self) => { return value.map((it) => (
{it.device} on{' '} - - {it.server_name} - + {self.getLinkRender( + 'instanceDetail', + it.server_name, + { id: it.server_id }, + { tab: 'volumes' } + )}
)); } diff --git a/src/utils/render.js b/src/utils/render.js deleted file mode 100644 index a16b23f6..00000000 --- a/src/utils/render.js +++ /dev/null @@ -1,21 +0,0 @@ -import { isBoolean, isNil, isObjectLike } from 'lodash'; - -export function getStringValue(value) { - if ( - isNil(value) || - (isObjectLike(value) && Object.keys(value).length === 0) - ) { - return '-'; - } - if (isBoolean(value)) { - return value.toString(); - } - return value; -} - -export function columnRender(render, value, record) { - if (render) { - return getStringValue(render(value, record)); - } - return getStringValue(value); -} diff --git a/src/utils/route-map.jsx b/src/utils/route-map.jsx new file mode 100644 index 00000000..1fe507a5 --- /dev/null +++ b/src/utils/route-map.jsx @@ -0,0 +1,62 @@ +import { get } from 'lodash'; +import qs from 'qs'; +import React from 'react'; +import { Link } from 'react-router-dom'; + +const routeMap = {}; + +const normalizeRoute = (record) => { + return { + path: record.routePath || record.path, + // redirect: record.redirect, + key: record.key, + // meta: record.meta || {}, + // beforeEnter: record.beforeEnter, + children: record.children || [], + }; +}; + +const insertRouteMap = (record = {}) => { + const item = normalizeRoute(record); + if (item.key) { + routeMap[item.key] = item; + } + if (item.children.length) { + item.children.forEach((child) => insertRouteMap(child)); + } +}; + +export const setRouteMap = (routes = []) => { + routes.forEach((r) => insertRouteMap(r)); + return routeMap; +}; + +const generatePath = (record, params) => { + const { path } = record; + if (!params) { + return path; + } + let newPath = path; + Object.keys(params).forEach((key) => { + newPath = newPath.replace(`:${key}`, params[key]); + }); + return newPath; +}; + +export const getPath = ({ key, params, query = {} }) => { + const record = get(routeMap, key); + if (!record) { + return '/'; + } + const path = generatePath(record, params); + const str = qs.stringify(query); + return str ? `${path}?${str}` : path; +}; + +export const getLinkRender = ({ key, params, query = {}, value }) => { + if (!value) { + return null; + } + const path = getPath({ key, params, query }); + return {value}; +}; diff --git a/src/utils/route-map.spec.js b/src/utils/route-map.spec.js new file mode 100644 index 00000000..70da6693 --- /dev/null +++ b/src/utils/route-map.spec.js @@ -0,0 +1,55 @@ +// Copyright 2021 99cloud +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { setRouteMap, getPath } from './route-map'; + +describe('test route map', () => { + const routes = [ + { + path: '/base/overview', + key: 'overview', + }, + { + path: '/compute', + key: 'compute', + children: [ + { + path: '/compute/instance', + key: 'instance', + children: [ + { + path: /^\/compute\/instance\/detail\/.[^/]+$/, + key: 'instanceDetail', + routePath: '/compute/instance/detail/:id', + }, + ], + }, + ], + }, + ]; + + it('setRouteMap', () => { + const routeMap = setRouteMap(routes); + expect(Object.keys(routeMap).length).toEqual(4); + }); + + it('getPath', () => { + const overivewPath = getPath({ key: 'overview' }); + expect(overivewPath).toBe('/base/overview'); + const detailPath = getPath({ key: 'instanceDetail', params: { id: 1 } }); + expect(detailPath).toBe('/compute/instance/detail/1'); + const queryPath = getPath({ key: 'instance', query: { status: 'stop' } }); + expect(queryPath).toBe('/compute/instance?status=stop'); + }); +}); diff --git a/src/utils/table.jsx b/src/utils/table.jsx index 44f930b3..ff3ed7f2 100644 --- a/src/utils/table.jsx +++ b/src/utils/table.jsx @@ -13,9 +13,31 @@ // limitations under the License. import React from 'react'; -import { isArray, get, isString } from 'lodash'; +import { Link } from 'react-router-dom'; +import { isArray, get, isString, isBoolean, isNil, isObjectLike } from 'lodash'; import Status from 'components/Status'; import { renderFilterMap } from 'utils/index'; +import { getLinkRender } from 'utils/route-map'; + +export function getStringValue(value) { + if ( + isNil(value) || + (isObjectLike(value) && Object.keys(value).length === 0) + ) { + return '-'; + } + if (isBoolean(value)) { + return value.toString(); + } + return value; +} + +export function columnRender(render, value, record) { + if (render) { + return getStringValue(render(value, record)); + } + return getStringValue(value); +} export const getDefaultSorter = (dataIndex) => (a, b) => { const dIndex = isArray(dataIndex) ? dataIndex.join('.') : dataIndex; @@ -106,3 +128,97 @@ export const projectRender = (value, record) => (
{value || '-'}
); + +const getLinkUrl = (prefix, id) => { + if (!prefix) { + return null; + } + if (prefix[prefix.length - 1] === '/') { + return `${prefix}${id}`; + } + return `${prefix}/${id}`; +}; + +export const getNameRender = (render, column) => { + if (render) { + return render; + } + const { + linkPrefix, + dataIndex, + idKey, + linkPrefixFunc, + linkFunc, + hasNoDetail = false, + } = column; + const { rowKey } = this.props; + return (value, record) => { + const idValue = get(record, idKey || rowKey); + let url = null; + if (linkFunc) { + url = linkFunc(value, record); + } else { + const linkValue = linkPrefixFunc + ? linkPrefixFunc(value, record) + : linkPrefix; + url = getLinkUrl(linkValue, idValue); + } + const nameValue = value || get(record, dataIndex) || '-'; + if (hasNoDetail) { + return ( +
+
{idValue}
+
{nameValue}
+
+ ); + } + if (!url && !hasNoDetail) { + return nameValue; + } + return ( +
+
+ {idValue} +
+
{nameValue}
+
+ ); + }; +}; + +export const getNameRenderByRouter = (render, column, rowKey) => { + if (render) { + return render; + } + const { + dataIndex, + idKey, + routeName, + routeParamsKey = 'id', + routeQuery = {}, + routeParamsFunc, + } = column; + return (value, record) => { + const nameValue = value || get(record, dataIndex) || '-'; + if (!routeName) { + return nameValue; + } + const idValue = get(record, idKey || rowKey); + const params = routeParamsFunc + ? routeParamsFunc(record) + : { [routeParamsKey]: idValue }; + const query = routeQuery; + const link = getLinkRender({ + key: routeName, + params, + query, + value: idValue, + }); + return ( +
+
{link}
+
{nameValue}
+
+ ); + }; +}; diff --git a/src/utils/render.test.js b/src/utils/table.test.js similarity index 95% rename from src/utils/render.test.js rename to src/utils/table.test.js index 92e63671..01ba5120 100644 --- a/src/utils/render.test.js +++ b/src/utils/table.test.js @@ -1,6 +1,6 @@ -import { columnRender } from './render'; +import { columnRender } from './table'; -describe('render test', () => { +describe('column render test', () => { it('column render', () => { expect(columnRender(undefined, 'normal')).toBe('normal'); expect(columnRender(undefined, 0)).toBe(0);