fix: Update link generate for security group rule
1. Update link generate for security group rule 2. Update export Change-Id: I12ea81aab8ff697e1b0764ae9592d0de4ee00bc4
This commit is contained in:
parent
ca4f999c7f
commit
f21c5a6daa
@ -21,6 +21,10 @@ export default class RuleButton extends Component {
|
|||||||
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDetailUrl(id) {
|
||||||
|
return `${this.getUrl('/network/security-group')}/detail/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { item: { security_group_rules: datas = [] } = {} } = this.props;
|
const { item: { security_group_rules: datas = [] } = {} } = this.props;
|
||||||
const configs = {
|
const configs = {
|
||||||
|
@ -21,9 +21,7 @@ import { emptyActionConfig } from 'utils/constants';
|
|||||||
import actionConfigs from '../actions';
|
import actionConfigs from '../actions';
|
||||||
import BaseDetail from './BaseDetail';
|
import BaseDetail from './BaseDetail';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class Detail extends Base {
|
||||||
@observer
|
|
||||||
export default class Detail extends Base {
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('flavor');
|
return t('flavor');
|
||||||
}
|
}
|
||||||
@ -96,3 +94,5 @@ export default class Detail extends Base {
|
|||||||
this.store = new FlavorStore();
|
this.store = new FlavorStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(Detail));
|
||||||
|
@ -68,6 +68,10 @@ export class SecurityGroup extends React.Component {
|
|||||||
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDetailUrl(id) {
|
||||||
|
return `${this.getUrl('/network/security-group')}/detail/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
actionCallback = async (first) => {
|
actionCallback = async (first) => {
|
||||||
const {
|
const {
|
||||||
match: {
|
match: {
|
||||||
|
@ -19,7 +19,7 @@ import globalProjectStore from 'stores/keystone/project';
|
|||||||
import { regex } from 'utils/validate';
|
import { regex } from 'utils/validate';
|
||||||
import { statusTypes } from 'utils/constants';
|
import { statusTypes } from 'utils/constants';
|
||||||
|
|
||||||
class CreateForm extends ModalAction {
|
export class CreateForm extends ModalAction {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -17,7 +17,7 @@ import { ModalAction } from 'containers/Action';
|
|||||||
import globalProjectStore from 'stores/keystone/project';
|
import globalProjectStore from 'stores/keystone/project';
|
||||||
import { statusTypes } from 'utils/constants';
|
import { statusTypes } from 'utils/constants';
|
||||||
|
|
||||||
class EditForm extends ModalAction {
|
export class EditForm extends ModalAction {
|
||||||
init() {
|
init() {
|
||||||
this.store = globalProjectStore;
|
this.store = globalProjectStore;
|
||||||
this.store.fetchList();
|
this.store.fetchList();
|
||||||
|
@ -18,13 +18,10 @@ import { Divider, Badge, Tag, Tooltip } from 'antd';
|
|||||||
import Base from 'containers/List';
|
import Base from 'containers/List';
|
||||||
import globalProjectStore from 'stores/keystone/project';
|
import globalProjectStore from 'stores/keystone/project';
|
||||||
import { yesNoOptions, projectTagsColors } from 'utils/constants';
|
import { yesNoOptions, projectTagsColors } from 'utils/constants';
|
||||||
|
|
||||||
import actionConfigs from './actions';
|
import actionConfigs from './actions';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class Projects extends Base {
|
||||||
@observer
|
|
||||||
export default class Projects extends Base {
|
|
||||||
init() {
|
init() {
|
||||||
this.store = globalProjectStore;
|
this.store = globalProjectStore;
|
||||||
}
|
}
|
||||||
@ -222,3 +219,5 @@ export default class Projects extends Base {
|
|||||||
this.list.silent = false;
|
this.list.silent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(Projects));
|
||||||
|
@ -28,7 +28,7 @@ import {
|
|||||||
} from 'utils/validate';
|
} from 'utils/validate';
|
||||||
import { statusTypes } from 'utils/constants';
|
import { statusTypes } from 'utils/constants';
|
||||||
|
|
||||||
class CreateForm extends FormAction {
|
export class CreateForm extends FormAction {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import globalUserStore from 'stores/keystone/user';
|
|||||||
import globalDomainStore from 'stores/keystone/domain';
|
import globalDomainStore from 'stores/keystone/domain';
|
||||||
import { phoneNumberValidate, emailValidate } from 'utils/validate';
|
import { phoneNumberValidate, emailValidate } from 'utils/validate';
|
||||||
|
|
||||||
class EditForm extends ModalAction {
|
export class EditForm extends ModalAction {
|
||||||
init() {
|
init() {
|
||||||
this.store = globalUserStore;
|
this.store = globalUserStore;
|
||||||
this.domainStore = globalDomainStore;
|
this.domainStore = globalDomainStore;
|
||||||
|
@ -21,9 +21,7 @@ import actionConfigs from '../actions';
|
|||||||
import BaseDetail from './BaseDetail';
|
import BaseDetail from './BaseDetail';
|
||||||
import PortForwarding from './PortForwarding';
|
import PortForwarding from './PortForwarding';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class FloatingIpDetail extends Base {
|
||||||
@observer
|
|
||||||
export default class FloatingIpDetail extends Base {
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('floating ip');
|
return t('floating ip');
|
||||||
}
|
}
|
||||||
@ -92,3 +90,5 @@ export default class FloatingIpDetail extends Base {
|
|||||||
this.store = new FloatingIpStore();
|
this.store = new FloatingIpStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(FloatingIpDetail));
|
||||||
|
@ -31,6 +31,10 @@ export class Rule extends Base {
|
|||||||
return t('security group rules');
|
return t('security group rules');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDetailUrl(id) {
|
||||||
|
return `${this.getUrl('/network/security-group')}/detail/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
getColumns = () => getSelfColumns(this);
|
getColumns = () => getSelfColumns(this);
|
||||||
|
|
||||||
get actionConfigs() {
|
get actionConfigs() {
|
||||||
|
@ -30,9 +30,7 @@ import styles from './index.less';
|
|||||||
|
|
||||||
const { Panel } = Collapse;
|
const { Panel } = Collapse;
|
||||||
|
|
||||||
@inject('rootStore')
|
export class SecurityGroup extends React.Component {
|
||||||
@observer
|
|
||||||
export default class SecurityGroup extends React.Component {
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.store = new VirtualAdapterStore();
|
this.store = new VirtualAdapterStore();
|
||||||
@ -46,6 +44,10 @@ export default class SecurityGroup extends React.Component {
|
|||||||
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDetailUrl(id) {
|
||||||
|
return `${this.getUrl('/network/security-group')}/detail/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
get portId() {
|
get portId() {
|
||||||
const {
|
const {
|
||||||
detail: { id },
|
detail: { id },
|
||||||
@ -66,6 +68,7 @@ export default class SecurityGroup extends React.Component {
|
|||||||
const {
|
const {
|
||||||
security_groups: { data },
|
security_groups: { data },
|
||||||
} = this.store;
|
} = this.store;
|
||||||
|
const detailUrl = this.getDetailUrl(item);
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={18}>
|
<Col span={18}>
|
||||||
@ -76,10 +79,7 @@ export default class SecurityGroup extends React.Component {
|
|||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
{!this.isAdminPage && (
|
{!this.isAdminPage && (
|
||||||
<>
|
<>
|
||||||
<Link
|
<Link style={{ fontSize: 12, marginRight: 16 }} to={detailUrl}>
|
||||||
style={{ fontSize: 12, marginRight: 16 }}
|
|
||||||
to={`/network/security-group/detail/${item.id}`}
|
|
||||||
>
|
|
||||||
{t('Edit Rule')}
|
{t('Edit Rule')}
|
||||||
</Link>
|
</Link>
|
||||||
</>
|
</>
|
||||||
@ -160,3 +160,5 @@ export default class SecurityGroup extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(SecurityGroup));
|
||||||
|
@ -22,9 +22,7 @@ import AllowedAddressPair from './AllowedAddressPair';
|
|||||||
import BaseDetail from './BaseDetail';
|
import BaseDetail from './BaseDetail';
|
||||||
import actionConfigs from '../actions';
|
import actionConfigs from '../actions';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class VirtualAdapterDetail extends Base {
|
||||||
@observer
|
|
||||||
export default class VirtualAdapterDetail extends Base {
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('virtual adapter');
|
return t('virtual adapter');
|
||||||
}
|
}
|
||||||
@ -123,3 +121,5 @@ export default class VirtualAdapterDetail extends Base {
|
|||||||
this.store = new VirtualAdapterStore();
|
this.store = new VirtualAdapterStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(VirtualAdapterDetail));
|
||||||
|
@ -17,9 +17,7 @@ import { Link } from 'react-router-dom';
|
|||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import Base from 'containers/BaseDetail';
|
import Base from 'containers/BaseDetail';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class BaseDetail extends Base {
|
||||||
@observer
|
|
||||||
export default class BaseDetail extends Base {
|
|
||||||
get leftCards() {
|
get leftCards() {
|
||||||
return [this.volumeCard];
|
return [this.volumeCard];
|
||||||
}
|
}
|
||||||
@ -50,3 +48,5 @@ export default class BaseDetail extends Base {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(BaseDetail));
|
||||||
|
@ -19,9 +19,7 @@ import { volumeStatus } from 'resources/volume';
|
|||||||
import BaseDetail from './BaseDetail';
|
import BaseDetail from './BaseDetail';
|
||||||
import actionConfigs from '../actions';
|
import actionConfigs from '../actions';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class Detail extends Base {
|
||||||
@observer
|
|
||||||
export default class Detail extends Base {
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('snapshot');
|
return t('snapshot');
|
||||||
}
|
}
|
||||||
@ -84,3 +82,5 @@ export default class Detail extends Base {
|
|||||||
this.store = new SnapshotStore();
|
this.store = new SnapshotStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(Detail));
|
||||||
|
@ -16,9 +16,7 @@ import { inject, observer } from 'mobx-react';
|
|||||||
import { ModalAction } from 'containers/Action';
|
import { ModalAction } from 'containers/Action';
|
||||||
import globalVolumeStore from 'stores/cinder/volume';
|
import globalVolumeStore from 'stores/cinder/volume';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class CreateVolume extends ModalAction {
|
||||||
@observer
|
|
||||||
export default class CreateVolume extends ModalAction {
|
|
||||||
static id = 'create';
|
static id = 'create';
|
||||||
|
|
||||||
static title = t('Create Volume');
|
static title = t('Create Volume');
|
||||||
@ -36,11 +34,15 @@ export default class CreateVolume extends ModalAction {
|
|||||||
|
|
||||||
static allowed = () => Promise.resolve(true);
|
static allowed = () => Promise.resolve(true);
|
||||||
|
|
||||||
|
get volumeTypeParams() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
async getVolumeTypes() {
|
async getVolumeTypes() {
|
||||||
const { volume_id: id } = this.item;
|
const { volume_id: id } = this.item;
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const [_, volume] = await Promise.all([
|
const [_, volume] = await Promise.all([
|
||||||
this.volumeStore.fetchVolumeTypes(),
|
this.volumeStore.fetchVolumeTypes(this.volumeTypeParams),
|
||||||
this.volumeStore.fetchDetail({ id }),
|
this.volumeStore.fetchDetail({ id }),
|
||||||
]);
|
]);
|
||||||
const { volume_type: volumeType } = volume;
|
const { volume_type: volumeType } = volume;
|
||||||
@ -122,3 +124,5 @@ export default class CreateVolume extends ModalAction {
|
|||||||
return globalVolumeStore.create(body);
|
return globalVolumeStore.create(body);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(CreateVolume));
|
||||||
|
@ -18,9 +18,7 @@ import { volumeStatus, snapshotTransitionStatuses } from 'resources/volume';
|
|||||||
import globalSnapshotStore, { SnapshotStore } from 'stores/cinder/snapshot';
|
import globalSnapshotStore, { SnapshotStore } from 'stores/cinder/snapshot';
|
||||||
import actionConfigs from './actions';
|
import actionConfigs from './actions';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class Snapshots extends Base {
|
||||||
@observer
|
|
||||||
export default class Snapshots extends Base {
|
|
||||||
init() {
|
init() {
|
||||||
if (this.inDetailPage) {
|
if (this.inDetailPage) {
|
||||||
this.store = new SnapshotStore();
|
this.store = new SnapshotStore();
|
||||||
@ -150,3 +148,5 @@ export default class Snapshots extends Base {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(Snapshots));
|
||||||
|
@ -476,6 +476,8 @@ export class Create extends FormAction {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCountChangeCallback() {}
|
||||||
|
|
||||||
onCountChange = (value) => {
|
onCountChange = (value) => {
|
||||||
let msg = t('Quota: Project quotas sufficient resources can be created');
|
let msg = t('Quota: Project quotas sufficient resources can be created');
|
||||||
let status = 'success';
|
let status = 'success';
|
||||||
@ -487,10 +489,17 @@ export class Create extends FormAction {
|
|||||||
status = 'error';
|
status = 'error';
|
||||||
}
|
}
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
count: value,
|
count: value,
|
||||||
status,
|
status,
|
||||||
});
|
},
|
||||||
|
() => {
|
||||||
|
if (this.onCountChangeCallback) {
|
||||||
|
this.onCountChangeCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderBadge() {
|
renderBadge() {
|
||||||
@ -501,6 +510,10 @@ export class Create extends FormAction {
|
|||||||
return <Badge status={status} text={this.msg} />;
|
return <Badge status={status} text={this.msg} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderExtra() {
|
||||||
|
return this.renderBadge();
|
||||||
|
}
|
||||||
|
|
||||||
renderFooterLeft() {
|
renderFooterLeft() {
|
||||||
const { count = 1 } = this.state;
|
const { count = 1 } = this.state;
|
||||||
const configs = {
|
const configs = {
|
||||||
@ -518,7 +531,7 @@ export class Create extends FormAction {
|
|||||||
value={count}
|
value={count}
|
||||||
className={classnames(styles.input, 'volume-count')}
|
className={classnames(styles.input, 'volume-count')}
|
||||||
/>
|
/>
|
||||||
{this.renderBadge()}
|
{this.renderExtra()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -74,10 +74,11 @@ export class CreateBackup extends ModalAction {
|
|||||||
|
|
||||||
onSubmit = (values) => {
|
onSubmit = (values) => {
|
||||||
const { id } = this.item;
|
const { id } = this.item;
|
||||||
const { volume, ...rest } = values;
|
const { name, incremental } = values;
|
||||||
const force = isInUse(this.item);
|
const force = isInUse(this.item);
|
||||||
const body = {
|
const body = {
|
||||||
...rest,
|
name,
|
||||||
|
incremental,
|
||||||
volume_id: id,
|
volume_id: id,
|
||||||
force,
|
force,
|
||||||
};
|
};
|
||||||
|
@ -18,9 +18,7 @@ import { ModalAction } from 'containers/Action';
|
|||||||
import globalServerStore from 'stores/nova/instance';
|
import globalServerStore from 'stores/nova/instance';
|
||||||
import { isInUse, isOsDisk } from 'resources/volume';
|
import { isInUse, isOsDisk } from 'resources/volume';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class Detach extends ModalAction {
|
||||||
@observer
|
|
||||||
export default class Detach extends ModalAction {
|
|
||||||
static id = 'detach';
|
static id = 'detach';
|
||||||
|
|
||||||
static title = t('Detach');
|
static title = t('Detach');
|
||||||
@ -92,10 +90,6 @@ export default class Detach extends ModalAction {
|
|||||||
label: t('Name'),
|
label: t('Name'),
|
||||||
name: 'name',
|
name: 'name',
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// label: t('IP'),
|
|
||||||
// name: 'private_ip',
|
|
||||||
// },
|
|
||||||
],
|
],
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@ -106,36 +100,6 @@ export default class Detach extends ModalAction {
|
|||||||
title: t('Attached To'),
|
title: t('Attached To'),
|
||||||
dataIndex: 'device',
|
dataIndex: 'device',
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// title: t('Image'),
|
|
||||||
// dataIndex: ['image', 'os_distro'],
|
|
||||||
// render: value => <ImageType type={value} />,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: t('Fixed IP'),
|
|
||||||
// dataIndex: 'private_ip',
|
|
||||||
// render: private_ip => (private_ip || []).map(it => <span key={it.ip}>{it.ip}<br /></span>),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: t('Floating IP'),
|
|
||||||
// dataIndex: 'addresses',
|
|
||||||
// render: (addresses) => {
|
|
||||||
// if (!addresses || !addresses['pub-net']) {
|
|
||||||
// return '-';
|
|
||||||
// }
|
|
||||||
// return addresses['pub-net'].map(it => <span key={it.addr}>{it.addr}<br /></span>);
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 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));
|
||||||
|
@ -78,7 +78,7 @@ export class ExtendVolume extends ModalAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSubmit = async (values) => {
|
onSubmit = async (values) => {
|
||||||
const { volume, ...rest } = values;
|
const { new_size } = values;
|
||||||
const { id } = this.item;
|
const { id } = this.item;
|
||||||
|
|
||||||
const instanceId = get(this.item, 'attachments[0].server_id');
|
const instanceId = get(this.item, 'attachments[0].server_id');
|
||||||
@ -99,7 +99,7 @@ export class ExtendVolume extends ModalAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.store.extendSize(id, rest);
|
return this.store.extendSize(id, { new_size });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,27 +12,19 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { observer, inject } from 'mobx-react';
|
import { observer, inject } from 'mobx-react';
|
||||||
import Base from 'containers/List';
|
import Base from 'containers/List';
|
||||||
import {
|
import {
|
||||||
volumeStatus,
|
|
||||||
diskTag,
|
|
||||||
volumeTransitionStatuses,
|
volumeTransitionStatuses,
|
||||||
bootableType,
|
|
||||||
volumeFilters,
|
volumeFilters,
|
||||||
multiTip,
|
getVolumnColumnsList,
|
||||||
} from 'resources/volume';
|
} from 'resources/volume';
|
||||||
import globalVolumeStore, { VolumeStore } from 'stores/cinder/volume';
|
import globalVolumeStore, { VolumeStore } from 'stores/cinder/volume';
|
||||||
import { InstanceVolumeStore } from 'stores/nova/instance-volume';
|
import { InstanceVolumeStore } from 'stores/nova/instance-volume';
|
||||||
import { toLocalTimeFilter } from 'utils/index';
|
|
||||||
import { emptyActionConfig } from 'utils/constants';
|
import { emptyActionConfig } from 'utils/constants';
|
||||||
import actionConfigs from './actions';
|
import actionConfigs from './actions';
|
||||||
|
|
||||||
@inject('rootStore')
|
export class Volume extends Base {
|
||||||
@observer
|
|
||||||
export default class Volume extends Base {
|
|
||||||
init() {
|
init() {
|
||||||
if (this.inDetailPage) {
|
if (this.inDetailPage) {
|
||||||
this.store = new InstanceVolumeStore();
|
this.store = new InstanceVolumeStore();
|
||||||
@ -91,113 +83,7 @@ export default class Volume extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getColumns = () => {
|
getColumns = () => {
|
||||||
const columns = [
|
return getVolumnColumnsList(this);
|
||||||
{
|
|
||||||
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) => (
|
|
||||||
<div key={it.server_id}>
|
|
||||||
{it.device} on{' '}
|
|
||||||
<Link
|
|
||||||
to={`${this.getUrl('/compute/instance')}/detail/${
|
|
||||||
it.server_id
|
|
||||||
}?tab=volumes`}
|
|
||||||
>
|
|
||||||
{it.server_name}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
get searchFilters() {
|
get searchFilters() {
|
||||||
@ -219,3 +105,5 @@ export default class Volume extends Base {
|
|||||||
return params;
|
return params;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(Volume));
|
||||||
|
@ -88,19 +88,8 @@ export const getSelfColumns = (self) => [
|
|||||||
dataIndex: 'remote_group_id',
|
dataIndex: 'remote_group_id',
|
||||||
isHideable: true,
|
isHideable: true,
|
||||||
render: (value) => {
|
render: (value) => {
|
||||||
return (
|
const url = self.getDetailUrl(value);
|
||||||
<div>
|
return <div>{value ? <Link to={url}>{value}</Link> : '-'}</div>;
|
||||||
{value ? (
|
|
||||||
<Link
|
|
||||||
to={`/network/${self.getUrl('security-group')}/detail/${value}`}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</Link>
|
|
||||||
) : (
|
|
||||||
'-'
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { yesNoOptions } from 'utils/constants';
|
import { yesNoOptions } from 'utils/constants';
|
||||||
|
import { toLocalTimeFilter } from 'utils/index';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
export const volumeStatus = {
|
export const volumeStatus = {
|
||||||
available: t('Available'),
|
available: t('Available'),
|
||||||
@ -221,3 +223,113 @@ export const snapshotTypeTip = (
|
|||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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) => (
|
||||||
|
<div key={it.server_id}>
|
||||||
|
{it.device} on{' '}
|
||||||
|
<Link
|
||||||
|
to={`${self.getUrl('/compute/instance')}/detail/${
|
||||||
|
it.server_id
|
||||||
|
}?tab=volumes`}
|
||||||
|
>
|
||||||
|
{it.server_name}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user