From f21c5a6daa935d362367e8e4cedf723113a589b8 Mon Sep 17 00:00:00 2001
From: "Jingwei.Zhang"
Date: Mon, 6 Sep 2021 16:18:06 +0800
Subject: [PATCH] fix: Update link generate for security group rule
1. Update link generate for security group rule
2. Update export
Change-Id: I12ea81aab8ff697e1b0764ae9592d0de4ee00bc4
---
src/components/TableButton/RuleButton.jsx | 4 +
.../compute/containers/Flavor/Arm/index.jsx | 2 +-
.../containers/Flavor/Detail/index.jsx | 6 +-
.../Instance/Detail/SecurityGroup/index.jsx | 4 +
.../containers/Project/actions/Create.jsx | 2 +-
.../containers/Project/actions/Edit.jsx | 2 +-
.../identity/containers/Project/index.jsx | 7 +-
.../containers/User/actions/Create.jsx | 2 +-
.../identity/containers/User/actions/Edit.jsx | 2 +-
.../containers/FloatingIp/Detail/index.jsx | 6 +-
.../FloatingIp/actions/Allocate.jsx | 2 +-
src/pages/network/containers/Router/index.jsx | 2 +-
.../SecurityGroup/Detail/Rule/index.jsx | 4 +
.../Detail/SecurityGroups/index.jsx | 16 ++-
.../VirtualAdapter/Detail/index.jsx | 6 +-
.../containers/Snapshot/Detail/BaseDetail.jsx | 6 +-
.../containers/Snapshot/Detail/index.jsx | 6 +-
.../Snapshot/actions/CreateVolume.jsx | 12 +-
.../storage/containers/Snapshot/index.jsx | 6 +-
.../Volume/actions/Create/index.jsx | 23 +++-
.../Volume/actions/CreateBackup.jsx | 5 +-
.../containers/Volume/actions/Detach.jsx | 40 +-----
.../Volume/actions/ExtendVolume.jsx | 4 +-
src/pages/storage/containers/Volume/index.jsx | 122 +-----------------
src/resources/security-group-rule.jsx | 15 +--
src/resources/volume.jsx | 112 ++++++++++++++++
26 files changed, 202 insertions(+), 216 deletions(-)
diff --git a/src/components/TableButton/RuleButton.jsx b/src/components/TableButton/RuleButton.jsx
index 5f3e3962..f6eff753 100644
--- a/src/components/TableButton/RuleButton.jsx
+++ b/src/components/TableButton/RuleButton.jsx
@@ -21,6 +21,10 @@ export default class RuleButton extends Component {
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
}
+ getDetailUrl(id) {
+ return `${this.getUrl('/network/security-group')}/detail/${id}`;
+ }
+
render() {
const { item: { security_group_rules: datas = [] } = {} } = this.props;
const configs = {
diff --git a/src/pages/compute/containers/Flavor/Arm/index.jsx b/src/pages/compute/containers/Flavor/Arm/index.jsx
index f4241ba4..4fc05ced 100644
--- a/src/pages/compute/containers/Flavor/Arm/index.jsx
+++ b/src/pages/compute/containers/Flavor/Arm/index.jsx
@@ -68,4 +68,4 @@ export class Flavor extends Base {
}
}
-export default inject('rootStore')(observer(Flavor));
\ No newline at end of file
+export default inject('rootStore')(observer(Flavor));
diff --git a/src/pages/compute/containers/Flavor/Detail/index.jsx b/src/pages/compute/containers/Flavor/Detail/index.jsx
index 84654bcd..ca174d58 100644
--- a/src/pages/compute/containers/Flavor/Detail/index.jsx
+++ b/src/pages/compute/containers/Flavor/Detail/index.jsx
@@ -21,9 +21,7 @@ import { emptyActionConfig } from 'utils/constants';
import actionConfigs from '../actions';
import BaseDetail from './BaseDetail';
-@inject('rootStore')
-@observer
-export default class Detail extends Base {
+export class Detail extends Base {
get name() {
return t('flavor');
}
@@ -96,3 +94,5 @@ export default class Detail extends Base {
this.store = new FlavorStore();
}
}
+
+export default inject('rootStore')(observer(Detail));
diff --git a/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx b/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx
index 5ab5cb92..4ab63dc1 100644
--- a/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx
+++ b/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx
@@ -68,6 +68,10 @@ export class SecurityGroup extends React.Component {
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
}
+ getDetailUrl(id) {
+ return `${this.getUrl('/network/security-group')}/detail/${id}`;
+ }
+
actionCallback = async (first) => {
const {
match: {
diff --git a/src/pages/identity/containers/Project/actions/Create.jsx b/src/pages/identity/containers/Project/actions/Create.jsx
index a5c4daa4..ae66e9ed 100644
--- a/src/pages/identity/containers/Project/actions/Create.jsx
+++ b/src/pages/identity/containers/Project/actions/Create.jsx
@@ -19,7 +19,7 @@ import globalProjectStore from 'stores/keystone/project';
import { regex } from 'utils/validate';
import { statusTypes } from 'utils/constants';
-class CreateForm extends ModalAction {
+export class CreateForm extends ModalAction {
constructor(props) {
super(props);
this.state = {
diff --git a/src/pages/identity/containers/Project/actions/Edit.jsx b/src/pages/identity/containers/Project/actions/Edit.jsx
index 85cf2b06..52609f94 100644
--- a/src/pages/identity/containers/Project/actions/Edit.jsx
+++ b/src/pages/identity/containers/Project/actions/Edit.jsx
@@ -17,7 +17,7 @@ import { ModalAction } from 'containers/Action';
import globalProjectStore from 'stores/keystone/project';
import { statusTypes } from 'utils/constants';
-class EditForm extends ModalAction {
+export class EditForm extends ModalAction {
init() {
this.store = globalProjectStore;
this.store.fetchList();
diff --git a/src/pages/identity/containers/Project/index.jsx b/src/pages/identity/containers/Project/index.jsx
index 0fe086a7..aec7d65e 100644
--- a/src/pages/identity/containers/Project/index.jsx
+++ b/src/pages/identity/containers/Project/index.jsx
@@ -18,13 +18,10 @@ import { Divider, Badge, Tag, Tooltip } from 'antd';
import Base from 'containers/List';
import globalProjectStore from 'stores/keystone/project';
import { yesNoOptions, projectTagsColors } from 'utils/constants';
-
import actionConfigs from './actions';
import styles from './index.less';
-@inject('rootStore')
-@observer
-export default class Projects extends Base {
+export class Projects extends Base {
init() {
this.store = globalProjectStore;
}
@@ -222,3 +219,5 @@ export default class Projects extends Base {
this.list.silent = false;
}
}
+
+export default inject('rootStore')(observer(Projects));
diff --git a/src/pages/identity/containers/User/actions/Create.jsx b/src/pages/identity/containers/User/actions/Create.jsx
index 88796866..bf08be92 100644
--- a/src/pages/identity/containers/User/actions/Create.jsx
+++ b/src/pages/identity/containers/User/actions/Create.jsx
@@ -28,7 +28,7 @@ import {
} from 'utils/validate';
import { statusTypes } from 'utils/constants';
-class CreateForm extends FormAction {
+export class CreateForm extends FormAction {
constructor(props) {
super(props);
diff --git a/src/pages/identity/containers/User/actions/Edit.jsx b/src/pages/identity/containers/User/actions/Edit.jsx
index 3e670d3c..6744e7bf 100644
--- a/src/pages/identity/containers/User/actions/Edit.jsx
+++ b/src/pages/identity/containers/User/actions/Edit.jsx
@@ -18,7 +18,7 @@ import globalUserStore from 'stores/keystone/user';
import globalDomainStore from 'stores/keystone/domain';
import { phoneNumberValidate, emailValidate } from 'utils/validate';
-class EditForm extends ModalAction {
+export class EditForm extends ModalAction {
init() {
this.store = globalUserStore;
this.domainStore = globalDomainStore;
diff --git a/src/pages/network/containers/FloatingIp/Detail/index.jsx b/src/pages/network/containers/FloatingIp/Detail/index.jsx
index 4b9c9fc2..d11af786 100644
--- a/src/pages/network/containers/FloatingIp/Detail/index.jsx
+++ b/src/pages/network/containers/FloatingIp/Detail/index.jsx
@@ -21,9 +21,7 @@ import actionConfigs from '../actions';
import BaseDetail from './BaseDetail';
import PortForwarding from './PortForwarding';
-@inject('rootStore')
-@observer
-export default class FloatingIpDetail extends Base {
+export class FloatingIpDetail extends Base {
get name() {
return t('floating ip');
}
@@ -92,3 +90,5 @@ export default class FloatingIpDetail extends Base {
this.store = new FloatingIpStore();
}
}
+
+export default inject('rootStore')(observer(FloatingIpDetail));
diff --git a/src/pages/network/containers/FloatingIp/actions/Allocate.jsx b/src/pages/network/containers/FloatingIp/actions/Allocate.jsx
index e8603daa0..4d7700d8 100644
--- a/src/pages/network/containers/FloatingIp/actions/Allocate.jsx
+++ b/src/pages/network/containers/FloatingIp/actions/Allocate.jsx
@@ -226,4 +226,4 @@ export class Allocate extends ModalAction {
}
}
-export default inject('rootStore')(observer(Allocate));
\ No newline at end of file
+export default inject('rootStore')(observer(Allocate));
diff --git a/src/pages/network/containers/Router/index.jsx b/src/pages/network/containers/Router/index.jsx
index c682a2b7..a4361951 100644
--- a/src/pages/network/containers/Router/index.jsx
+++ b/src/pages/network/containers/Router/index.jsx
@@ -61,4 +61,4 @@ export class Routes extends Base {
}
}
-export default inject('rootStore')(observer(Routes));
\ No newline at end of file
+export default inject('rootStore')(observer(Routes));
diff --git a/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx b/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx
index a7527f35..3c140a50 100644
--- a/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx
+++ b/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx
@@ -31,6 +31,10 @@ export class Rule extends Base {
return t('security group rules');
}
+ getDetailUrl(id) {
+ return `${this.getUrl('/network/security-group')}/detail/${id}`;
+ }
+
getColumns = () => getSelfColumns(this);
get actionConfigs() {
diff --git a/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx b/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx
index d70cce7e..373bb2f8 100644
--- a/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx
+++ b/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx
@@ -30,9 +30,7 @@ import styles from './index.less';
const { Panel } = Collapse;
-@inject('rootStore')
-@observer
-export default class SecurityGroup extends React.Component {
+export class SecurityGroup extends React.Component {
constructor(props) {
super(props);
this.store = new VirtualAdapterStore();
@@ -46,6 +44,10 @@ export default class SecurityGroup extends React.Component {
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
}
+ getDetailUrl(id) {
+ return `${this.getUrl('/network/security-group')}/detail/${id}`;
+ }
+
get portId() {
const {
detail: { id },
@@ -66,6 +68,7 @@ export default class SecurityGroup extends React.Component {
const {
security_groups: { data },
} = this.store;
+ const detailUrl = this.getDetailUrl(item);
return (
@@ -76,10 +79,7 @@ export default class SecurityGroup extends React.Component {
{!this.isAdminPage && (
<>
-
+
{t('Edit Rule')}
>
@@ -160,3 +160,5 @@ export default class SecurityGroup extends React.Component {
);
}
}
+
+export default inject('rootStore')(observer(SecurityGroup));
diff --git a/src/pages/network/containers/VirtualAdapter/Detail/index.jsx b/src/pages/network/containers/VirtualAdapter/Detail/index.jsx
index bac7764d..c8c11755 100644
--- a/src/pages/network/containers/VirtualAdapter/Detail/index.jsx
+++ b/src/pages/network/containers/VirtualAdapter/Detail/index.jsx
@@ -22,9 +22,7 @@ import AllowedAddressPair from './AllowedAddressPair';
import BaseDetail from './BaseDetail';
import actionConfigs from '../actions';
-@inject('rootStore')
-@observer
-export default class VirtualAdapterDetail extends Base {
+export class VirtualAdapterDetail extends Base {
get name() {
return t('virtual adapter');
}
@@ -123,3 +121,5 @@ export default class VirtualAdapterDetail extends Base {
this.store = new VirtualAdapterStore();
}
}
+
+export default inject('rootStore')(observer(VirtualAdapterDetail));
diff --git a/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx b/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx
index 4a26e37c..437b4e2a 100644
--- a/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx
+++ b/src/pages/storage/containers/Snapshot/Detail/BaseDetail.jsx
@@ -17,9 +17,7 @@ import { Link } from 'react-router-dom';
import { inject, observer } from 'mobx-react';
import Base from 'containers/BaseDetail';
-@inject('rootStore')
-@observer
-export default class BaseDetail extends Base {
+export class BaseDetail extends Base {
get leftCards() {
return [this.volumeCard];
}
@@ -50,3 +48,5 @@ export default class BaseDetail extends Base {
};
}
}
+
+export default inject('rootStore')(observer(BaseDetail));
diff --git a/src/pages/storage/containers/Snapshot/Detail/index.jsx b/src/pages/storage/containers/Snapshot/Detail/index.jsx
index f69e758f..9e577354 100644
--- a/src/pages/storage/containers/Snapshot/Detail/index.jsx
+++ b/src/pages/storage/containers/Snapshot/Detail/index.jsx
@@ -19,9 +19,7 @@ import { volumeStatus } from 'resources/volume';
import BaseDetail from './BaseDetail';
import actionConfigs from '../actions';
-@inject('rootStore')
-@observer
-export default class Detail extends Base {
+export class Detail extends Base {
get name() {
return t('snapshot');
}
@@ -84,3 +82,5 @@ export default class Detail extends Base {
this.store = new SnapshotStore();
}
}
+
+export default inject('rootStore')(observer(Detail));
diff --git a/src/pages/storage/containers/Snapshot/actions/CreateVolume.jsx b/src/pages/storage/containers/Snapshot/actions/CreateVolume.jsx
index a38fd77c..01dce20a 100644
--- a/src/pages/storage/containers/Snapshot/actions/CreateVolume.jsx
+++ b/src/pages/storage/containers/Snapshot/actions/CreateVolume.jsx
@@ -16,9 +16,7 @@ import { inject, observer } from 'mobx-react';
import { ModalAction } from 'containers/Action';
import globalVolumeStore from 'stores/cinder/volume';
-@inject('rootStore')
-@observer
-export default class CreateVolume extends ModalAction {
+export class CreateVolume extends ModalAction {
static id = 'create';
static title = t('Create Volume');
@@ -36,11 +34,15 @@ export default class CreateVolume extends ModalAction {
static allowed = () => Promise.resolve(true);
+ get volumeTypeParams() {
+ return {};
+ }
+
async getVolumeTypes() {
const { volume_id: id } = this.item;
// eslint-disable-next-line no-unused-vars
const [_, volume] = await Promise.all([
- this.volumeStore.fetchVolumeTypes(),
+ this.volumeStore.fetchVolumeTypes(this.volumeTypeParams),
this.volumeStore.fetchDetail({ id }),
]);
const { volume_type: volumeType } = volume;
@@ -122,3 +124,5 @@ export default class CreateVolume extends ModalAction {
return globalVolumeStore.create(body);
};
}
+
+export default inject('rootStore')(observer(CreateVolume));
diff --git a/src/pages/storage/containers/Snapshot/index.jsx b/src/pages/storage/containers/Snapshot/index.jsx
index 1b5e260e..452fc0fc 100644
--- a/src/pages/storage/containers/Snapshot/index.jsx
+++ b/src/pages/storage/containers/Snapshot/index.jsx
@@ -18,9 +18,7 @@ import { volumeStatus, snapshotTransitionStatuses } from 'resources/volume';
import globalSnapshotStore, { SnapshotStore } from 'stores/cinder/snapshot';
import actionConfigs from './actions';
-@inject('rootStore')
-@observer
-export default class Snapshots extends Base {
+export class Snapshots extends Base {
init() {
if (this.inDetailPage) {
this.store = new SnapshotStore();
@@ -150,3 +148,5 @@ export default class Snapshots extends Base {
];
}
}
+
+export default inject('rootStore')(observer(Snapshots));
diff --git a/src/pages/storage/containers/Volume/actions/Create/index.jsx b/src/pages/storage/containers/Volume/actions/Create/index.jsx
index 828f7eb5..4e84c0b3 100644
--- a/src/pages/storage/containers/Volume/actions/Create/index.jsx
+++ b/src/pages/storage/containers/Volume/actions/Create/index.jsx
@@ -476,6 +476,8 @@ export class Create extends FormAction {
];
}
+ onCountChangeCallback() {}
+
onCountChange = (value) => {
let msg = t('Quota: Project quotas sufficient resources can be created');
let status = 'success';
@@ -487,10 +489,17 @@ export class Create extends FormAction {
status = 'error';
}
this.msg = msg;
- this.setState({
- count: value,
- status,
- });
+ this.setState(
+ {
+ count: value,
+ status,
+ },
+ () => {
+ if (this.onCountChangeCallback) {
+ this.onCountChangeCallback();
+ }
+ }
+ );
};
renderBadge() {
@@ -501,6 +510,10 @@ export class Create extends FormAction {
return ;
}
+ renderExtra() {
+ return this.renderBadge();
+ }
+
renderFooterLeft() {
const { count = 1 } = this.state;
const configs = {
@@ -518,7 +531,7 @@ export class Create extends FormAction {
value={count}
className={classnames(styles.input, 'volume-count')}
/>
- {this.renderBadge()}
+ {this.renderExtra()}
);
}
diff --git a/src/pages/storage/containers/Volume/actions/CreateBackup.jsx b/src/pages/storage/containers/Volume/actions/CreateBackup.jsx
index 49bf643e..c9ed0611 100644
--- a/src/pages/storage/containers/Volume/actions/CreateBackup.jsx
+++ b/src/pages/storage/containers/Volume/actions/CreateBackup.jsx
@@ -74,10 +74,11 @@ export class CreateBackup extends ModalAction {
onSubmit = (values) => {
const { id } = this.item;
- const { volume, ...rest } = values;
+ const { name, incremental } = values;
const force = isInUse(this.item);
const body = {
- ...rest,
+ name,
+ incremental,
volume_id: id,
force,
};
diff --git a/src/pages/storage/containers/Volume/actions/Detach.jsx b/src/pages/storage/containers/Volume/actions/Detach.jsx
index 3a3b38f3..ac9a6cef 100644
--- a/src/pages/storage/containers/Volume/actions/Detach.jsx
+++ b/src/pages/storage/containers/Volume/actions/Detach.jsx
@@ -18,9 +18,7 @@ import { ModalAction } from 'containers/Action';
import globalServerStore from 'stores/nova/instance';
import { isInUse, isOsDisk } from 'resources/volume';
-@inject('rootStore')
-@observer
-export default class Detach extends ModalAction {
+export class Detach extends ModalAction {
static id = 'detach';
static title = t('Detach');
@@ -92,10 +90,6 @@ export default class Detach extends ModalAction {
label: t('Name'),
name: 'name',
},
- // {
- // label: t('IP'),
- // name: 'private_ip',
- // },
],
columns: [
{
@@ -106,36 +100,6 @@ export default class Detach extends ModalAction {
title: t('Attached To'),
dataIndex: 'device',
},
- // {
- // title: t('Image'),
- // dataIndex: ['image', 'os_distro'],
- // render: value => ,
- // },
- // {
- // title: t('Fixed IP'),
- // dataIndex: 'private_ip',
- // render: private_ip => (private_ip || []).map(it => {it.ip}
),
- // },
- // {
- // title: t('Floating IP'),
- // dataIndex: 'addresses',
- // render: (addresses) => {
- // if (!addresses || !addresses['pub-net']) {
- // return '-';
- // }
- // return addresses['pub-net'].map(it => {it.addr}
);
- // },
- // },
- // {
- // title: t('Flavor'),
- // dataIndex: 'flavor',
- // render: flavor => `${flavor.disk}G/${Number.parseInt(flavor.ram / 1024, 10)}G`,
- // },
- // {
- // title: t('Created At'),
- // dataIndex: 'created',
- // valueRender: 'sinceTime',
- // },
],
},
];
@@ -151,3 +115,5 @@ export default class Detach extends ModalAction {
);
};
}
+
+export default inject('rootStore')(observer(Detach));
diff --git a/src/pages/storage/containers/Volume/actions/ExtendVolume.jsx b/src/pages/storage/containers/Volume/actions/ExtendVolume.jsx
index 4cc7e138..afbc1ec2 100644
--- a/src/pages/storage/containers/Volume/actions/ExtendVolume.jsx
+++ b/src/pages/storage/containers/Volume/actions/ExtendVolume.jsx
@@ -78,7 +78,7 @@ export class ExtendVolume extends ModalAction {
}
onSubmit = async (values) => {
- const { volume, ...rest } = values;
+ const { new_size } = values;
const { id } = this.item;
const instanceId = get(this.item, 'attachments[0].server_id');
@@ -99,7 +99,7 @@ export class ExtendVolume extends ModalAction {
return;
}
}
- return this.store.extendSize(id, rest);
+ return this.store.extendSize(id, { new_size });
};
}
diff --git a/src/pages/storage/containers/Volume/index.jsx b/src/pages/storage/containers/Volume/index.jsx
index 3401668c..17e4968a 100644
--- a/src/pages/storage/containers/Volume/index.jsx
+++ b/src/pages/storage/containers/Volume/index.jsx
@@ -12,27 +12,19 @@
// 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 {
- volumeStatus,
- diskTag,
volumeTransitionStatuses,
- bootableType,
volumeFilters,
- multiTip,
+ getVolumnColumnsList,
} from 'resources/volume';
import globalVolumeStore, { VolumeStore } from 'stores/cinder/volume';
import { InstanceVolumeStore } from 'stores/nova/instance-volume';
-import { toLocalTimeFilter } from 'utils/index';
import { emptyActionConfig } from 'utils/constants';
import actionConfigs from './actions';
-@inject('rootStore')
-@observer
-export default class Volume extends Base {
+export class Volume extends Base {
init() {
if (this.inDetailPage) {
this.store = new InstanceVolumeStore();
@@ -91,113 +83,7 @@ export default class Volume extends Base {
}
getColumns = () => {
- const columns = [
- {
- title: t('ID/Name'),
- dataIndex: 'name',
- linkPrefix: `/storage/${this.getUrl('volume')}/detail`,
- stringify: (name, record) => name || record.id,
- sortKey: 'name',
- },
- {
- title: t('Project ID/Name'),
- dataIndex: 'project_name',
- hidden: !this.isAdminPage,
- isHideable: true,
- sorter: false,
- },
- {
- title: t('Host'),
- dataIndex: 'host',
- isHideable: true,
- hidden: !this.isAdminPage,
- sorter: false,
- },
- {
- title: t('Size'),
- dataIndex: 'size',
- isHideable: true,
- render: (value) => `${value}GB`,
- },
- {
- title: t('Status'),
- dataIndex: 'status',
- render: (value) => volumeStatus[value] || '-',
- },
- {
- title: t('Type'),
- dataIndex: 'volume_type',
- isHideable: true,
- width: 100,
- sorter: false,
- },
- {
- title: t('Disk Tag'),
- dataIndex: 'disk_tag',
- isHideable: true,
- render: (value) => diskTag[value] || '-',
- sorter: false,
- },
- {
- title: t('Attached To'),
- dataIndex: 'attachments',
- isHideable: true,
- sorter: false,
- render: (value) => {
- if (value && value.length > 0) {
- return value.map((it) => (
-
- {it.device} on{' '}
-
- {it.server_name}
-
-
- ));
- }
- return '-';
- },
- stringify: (value) => {
- if (value && value.length) {
- return value
- .map((it) => `${it.server_name}(${it.server_id})`)
- .join(',');
- }
- return '-';
- },
- },
- {
- title: t('Bootable'),
- titleTip: t(
- 'When the volume is "bootable" and the status is "available", it can be used as a startup source to create an instance.'
- ),
- dataIndex: 'bootable',
- isHideable: true,
- render: (value) => bootableType[value] || '-',
- },
- {
- title: t('Shared'),
- dataIndex: 'multiattach',
- valueRender: 'yesNo',
- titleTip: multiTip,
- width: 80,
- sorter: false,
- },
- {
- title: t('Created At'),
- dataIndex: 'created_at',
- isHideable: true,
- valueRender: 'sinceTime',
- stringify: (value) => toLocalTimeFilter(value),
- },
- ];
- if (this.inDetailPage) {
- return columns.filter((it) => it.dataIndex !== 'attachments');
- }
- return columns;
+ return getVolumnColumnsList(this);
};
get searchFilters() {
@@ -219,3 +105,5 @@ export default class Volume extends Base {
return params;
};
}
+
+export default inject('rootStore')(observer(Volume));
diff --git a/src/resources/security-group-rule.jsx b/src/resources/security-group-rule.jsx
index 0d895ff8..e9182b02 100644
--- a/src/resources/security-group-rule.jsx
+++ b/src/resources/security-group-rule.jsx
@@ -88,19 +88,8 @@ export const getSelfColumns = (self) => [
dataIndex: 'remote_group_id',
isHideable: true,
render: (value) => {
- return (
-
- {value ? (
-
- {value}
-
- ) : (
- '-'
- )}
-
- );
+ const url = self.getDetailUrl(value);
+ return {value ? {value} : '-'}
;
},
},
{
diff --git a/src/resources/volume.jsx b/src/resources/volume.jsx
index 69c2cb4d..225848ae 100644
--- a/src/resources/volume.jsx
+++ b/src/resources/volume.jsx
@@ -14,6 +14,8 @@
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'),
@@ -221,3 +223,113 @@ export const snapshotTypeTip = (
>
);
+
+export const getVolumnColumnsList = (self) => {
+ const columns = [
+ {
+ title: t('ID/Name'),
+ dataIndex: 'name',
+ linkPrefix: `/storage/${self.getUrl('volume')}/detail`,
+ stringify: (name, record) => name || record.id,
+ sortKey: 'name',
+ },
+ {
+ title: t('Project ID/Name'),
+ dataIndex: 'project_name',
+ hidden: !self.isAdminPage,
+ isHideable: true,
+ sorter: false,
+ },
+ {
+ title: t('Host'),
+ dataIndex: 'host',
+ isHideable: true,
+ hidden: !self.isAdminPage,
+ sorter: false,
+ },
+ {
+ title: t('Size'),
+ dataIndex: 'size',
+ isHideable: true,
+ render: (value) => `${value}GB`,
+ },
+ {
+ title: t('Status'),
+ dataIndex: 'status',
+ render: (value) => volumeStatus[value] || '-',
+ },
+ {
+ title: t('Type'),
+ dataIndex: 'volume_type',
+ isHideable: true,
+ width: 100,
+ sorter: false,
+ },
+ {
+ title: t('Disk Tag'),
+ dataIndex: 'disk_tag',
+ isHideable: true,
+ render: (value) => diskTag[value] || '-',
+ sorter: false,
+ },
+ {
+ title: t('Attached To'),
+ dataIndex: 'attachments',
+ isHideable: true,
+ sorter: false,
+ render: (value) => {
+ if (value && value.length > 0) {
+ return value.map((it) => (
+
+ {it.device} on{' '}
+
+ {it.server_name}
+
+
+ ));
+ }
+ return '-';
+ },
+ stringify: (value) => {
+ if (value && value.length) {
+ return value
+ .map((it) => `${it.server_name}(${it.server_id})`)
+ .join(',');
+ }
+ return '-';
+ },
+ },
+ {
+ title: t('Bootable'),
+ titleTip: t(
+ 'When the volume is "bootable" and the status is "available", it can be used as a startup source to create an instance.'
+ ),
+ dataIndex: 'bootable',
+ isHideable: true,
+ render: (value) => bootableType[value] || '-',
+ },
+ {
+ title: t('Shared'),
+ dataIndex: 'multiattach',
+ valueRender: 'yesNo',
+ titleTip: multiTip,
+ width: 80,
+ sorter: false,
+ },
+ {
+ title: t('Created At'),
+ dataIndex: 'created_at',
+ isHideable: true,
+ valueRender: 'sinceTime',
+ stringify: (value) => toLocalTimeFilter(value),
+ },
+ ];
+ if (self.inDetailPage) {
+ return columns.filter((it) => it.dataIndex !== 'attachments');
+ }
+ return columns;
+};