refactor: refactor create volume
1. Refactor create volume 2. Disable click submit button when quota is insufficient Change-Id: I16c28f5b6041d575c2b27cf7fa815ab248971187
This commit is contained in:
parent
ef8024f50b
commit
15503b110a
@ -20,17 +20,25 @@ import {
|
|||||||
volumeStatus,
|
volumeStatus,
|
||||||
multiTip,
|
multiTip,
|
||||||
snapshotTypeTip,
|
snapshotTypeTip,
|
||||||
|
getQuotaInfo,
|
||||||
|
getAdd,
|
||||||
|
fetchQuota,
|
||||||
|
getQuota,
|
||||||
|
onVolumeSizeChange,
|
||||||
|
setCreateVolumeCount,
|
||||||
|
setCreateVolumeSize,
|
||||||
|
setCreateVolumeType,
|
||||||
} from 'resources/cinder/volume';
|
} from 'resources/cinder/volume';
|
||||||
import globalSnapshotStore from 'stores/cinder/snapshot';
|
import globalSnapshotStore from 'stores/cinder/snapshot';
|
||||||
import globalImageStore from 'stores/glance/image';
|
import globalImageStore from 'stores/glance/image';
|
||||||
import globalVolumeStore from 'stores/cinder/volume';
|
import globalVolumeStore from 'stores/cinder/volume';
|
||||||
import globalVolumeTypeStore from 'stores/cinder/volume-type';
|
import globalVolumeTypeStore from 'stores/cinder/volume-type';
|
||||||
|
import globalProjectStore from 'stores/keystone/project';
|
||||||
import globalBackupStore from 'stores/cinder/backup';
|
import globalBackupStore from 'stores/cinder/backup';
|
||||||
import { InputNumber, Badge, message as $message } from 'antd';
|
import { InputNumber, message as $message } from 'antd';
|
||||||
import { toJS } from 'mobx';
|
import { toJS } from 'mobx';
|
||||||
import { FormAction } from 'containers/Action';
|
import { FormAction } from 'containers/Action';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { isEmpty, isObject } from 'lodash';
|
|
||||||
import {
|
import {
|
||||||
getImageSystemTabs,
|
getImageSystemTabs,
|
||||||
getImageOS,
|
getImageOS,
|
||||||
@ -44,6 +52,14 @@ import styles from './index.less';
|
|||||||
|
|
||||||
export class Create extends FormAction {
|
export class Create extends FormAction {
|
||||||
init() {
|
init() {
|
||||||
|
this.state = {
|
||||||
|
...this.state,
|
||||||
|
quotaLoading: true,
|
||||||
|
count: 1,
|
||||||
|
sharedDisabled: false,
|
||||||
|
confirmCount: 0,
|
||||||
|
};
|
||||||
|
this.message = '';
|
||||||
this.snapshotStore = globalSnapshotStore;
|
this.snapshotStore = globalSnapshotStore;
|
||||||
this.imageStore = globalImageStore;
|
this.imageStore = globalImageStore;
|
||||||
this.volumeStore = globalVolumeStore;
|
this.volumeStore = globalVolumeStore;
|
||||||
@ -53,12 +69,6 @@ export class Create extends FormAction {
|
|||||||
this.getAvailZones();
|
this.getAvailZones();
|
||||||
this.getImages();
|
this.getImages();
|
||||||
this.getVolumeTypes();
|
this.getVolumeTypes();
|
||||||
this.state = {
|
|
||||||
...this.state,
|
|
||||||
count: 1,
|
|
||||||
sharedDisabled: false,
|
|
||||||
confirmCount: 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static id = 'volume-create';
|
static id = 'volume-create';
|
||||||
@ -81,6 +91,23 @@ export class Create extends FormAction {
|
|||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get disableSubmit() {
|
||||||
|
const { quotaLoading } = this.state;
|
||||||
|
if (quotaLoading) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const { cinderQuota = {} } = globalProjectStore;
|
||||||
|
const { add, error } = getAdd(cinderQuota);
|
||||||
|
const disable = add === 0;
|
||||||
|
if (!disable) {
|
||||||
|
this.message = '';
|
||||||
|
} else if (error !== this.message) {
|
||||||
|
$message.error(error);
|
||||||
|
this.message = error;
|
||||||
|
}
|
||||||
|
return disable;
|
||||||
|
}
|
||||||
|
|
||||||
get instanceName() {
|
get instanceName() {
|
||||||
const { name } = this.values || {};
|
const { name } = this.values || {};
|
||||||
const { count = 1 } = this.state;
|
const { count = 1 } = this.state;
|
||||||
@ -94,7 +121,7 @@ export class Create extends FormAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get errorText() {
|
get errorText() {
|
||||||
if (this.msg) {
|
if (this.message) {
|
||||||
return t(
|
return t(
|
||||||
'Unable to create volume: insufficient quota to create resources.'
|
'Unable to create volume: insufficient quota to create resources.'
|
||||||
);
|
);
|
||||||
@ -107,79 +134,23 @@ export class Create extends FormAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getVolumeQuota() {
|
getVolumeQuota() {
|
||||||
const quotaAll = toJS(this.volumeStore.quotaSet) || {};
|
const { quota = {} } = this.state;
|
||||||
if (isEmpty(quotaAll)) {
|
return getQuota(quota);
|
||||||
return [];
|
|
||||||
}
|
|
||||||
Object.values(quotaAll).forEach((it) => {
|
|
||||||
if (isObject(it)) {
|
|
||||||
it.used = it.in_use;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const { volume_type } = this.state;
|
|
||||||
const { name } = volume_type || {};
|
|
||||||
const result = {
|
|
||||||
volumes: quotaAll.volumes,
|
|
||||||
gigabytes: quotaAll.gigabytes,
|
|
||||||
};
|
|
||||||
if (name) {
|
|
||||||
result[`volumes_${name}`] = quotaAll[`volumes_${name}`];
|
|
||||||
result[`gigabytes_${name}`] = quotaAll[`gigabytes_${name}`];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get quotaInfo() {
|
get quotaInfo() {
|
||||||
const quota = this.getVolumeQuota();
|
return getQuotaInfo(this);
|
||||||
const { volumes = {}, gigabytes = {} } = quota;
|
}
|
||||||
const { limit } = volumes || {};
|
|
||||||
if (!limit) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const { volume_type, size = 0, count = 1 } = this.state;
|
get defaultSize() {
|
||||||
const { name } = volume_type || {};
|
return this.quotaIsLimit && this.maxSize < 10 ? this.maxSize : 10;
|
||||||
const volume = {
|
|
||||||
...volumes,
|
|
||||||
add: count,
|
|
||||||
name: 'volume',
|
|
||||||
title: t('Volume'),
|
|
||||||
};
|
|
||||||
const sizeInfo = {
|
|
||||||
...gigabytes,
|
|
||||||
add: count * size,
|
|
||||||
name: 'gigabytes',
|
|
||||||
title: t('volume gigabytes'),
|
|
||||||
type: 'line',
|
|
||||||
};
|
|
||||||
if (!name) {
|
|
||||||
return [volume, sizeInfo];
|
|
||||||
}
|
|
||||||
const typeQuota = quota[`volumes_${name}`] || {};
|
|
||||||
const typeSizeQuota = quota[`gigabytes_${name}`] || {};
|
|
||||||
const detailInfo = {
|
|
||||||
...typeQuota,
|
|
||||||
add: count,
|
|
||||||
name: `volumes_${name}`,
|
|
||||||
title: t('{name} type', { name }),
|
|
||||||
type: 'line',
|
|
||||||
};
|
|
||||||
const detailSizeInfo = {
|
|
||||||
...typeSizeQuota,
|
|
||||||
add: count * size,
|
|
||||||
name: `gigabytes_${name}`,
|
|
||||||
title: t('{name} type gigabytes', { name }),
|
|
||||||
type: 'line',
|
|
||||||
};
|
|
||||||
return [volume, sizeInfo, detailInfo, detailSizeInfo];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get defaultValue() {
|
get defaultValue() {
|
||||||
const size = this.quotaIsLimit && this.maxSize < 10 ? this.maxSize : 10;
|
|
||||||
const { initVolumeType } = this.state;
|
const { initVolumeType } = this.state;
|
||||||
const values = {
|
const values = {
|
||||||
source: this.sourceTypes[0],
|
source: this.sourceTypes[0],
|
||||||
size,
|
size: this.defaultSize,
|
||||||
project: this.currentProjectName,
|
project: this.currentProjectName,
|
||||||
availableZone: (this.availableZones[0] || []).value,
|
availableZone: (this.availableZones[0] || []).value,
|
||||||
volume_type: initVolumeType,
|
volume_type: initVolumeType,
|
||||||
@ -237,20 +208,14 @@ export class Create extends FormAction {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get quota() {
|
|
||||||
const { volumes = {} } = this.getVolumeQuota();
|
|
||||||
return volumes;
|
|
||||||
}
|
|
||||||
|
|
||||||
get quotaIsLimit() {
|
get quotaIsLimit() {
|
||||||
const { gigabytes: { limit } = {} } = this.getVolumeQuota();
|
const { gigabytes: { limit } = {} } = this.getVolumeQuota();
|
||||||
return limit !== -1;
|
return limit !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
get maxSize() {
|
get maxSize() {
|
||||||
const { gigabytes: { limit = 10, in_use = 0, reserved = 0 } = {} } =
|
const { gigabytes: { left = 0 } = {} } = this.getVolumeQuota();
|
||||||
this.getVolumeQuota();
|
return left === -1 ? 1000 : left;
|
||||||
return limit !== -1 ? limit - in_use - reserved : 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvailZones() {
|
getAvailZones() {
|
||||||
@ -264,14 +229,17 @@ export class Create extends FormAction {
|
|||||||
async getVolumeTypes() {
|
async getVolumeTypes() {
|
||||||
const types = await this.volumeTypeStore.fetchList();
|
const types = await this.volumeTypeStore.fetchList();
|
||||||
if (types.length > 0) {
|
if (types.length > 0) {
|
||||||
|
const defaultType = types[0];
|
||||||
|
const { id, name } = defaultType;
|
||||||
const initVolumeType = {
|
const initVolumeType = {
|
||||||
selectedRowKeys: [types[0].id],
|
selectedRowKeys: [id],
|
||||||
selectedRows: [types[0]],
|
selectedRows: [defaultType],
|
||||||
};
|
};
|
||||||
|
setCreateVolumeType(name);
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
initVolumeType,
|
initVolumeType,
|
||||||
volume_type: types[0],
|
volume_type: defaultType,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.updateFormValue('volume_type', initVolumeType);
|
this.updateFormValue('volume_type', initVolumeType);
|
||||||
@ -282,7 +250,8 @@ export class Create extends FormAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getQuota() {
|
async getQuota() {
|
||||||
await this.volumeStore.fetchQuota();
|
await fetchQuota(this, 0);
|
||||||
|
setCreateVolumeSize(this.defaultSize);
|
||||||
this.onCountChange(1);
|
this.onCountChange(1);
|
||||||
this.updateDefaultValue();
|
this.updateDefaultValue();
|
||||||
}
|
}
|
||||||
@ -321,12 +290,18 @@ export class Create extends FormAction {
|
|||||||
onVolumeTypeChange = (value) => {
|
onVolumeTypeChange = (value) => {
|
||||||
const { selectedRows = [] } = value;
|
const { selectedRows = [] } = value;
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
|
setCreateVolumeType('');
|
||||||
this.setState({
|
this.setState({
|
||||||
multiattach: false,
|
multiattach: false,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { id, extra_specs: { multiattach = 'False' } = {} } = selectedRows[0];
|
const {
|
||||||
|
id,
|
||||||
|
extra_specs: { multiattach = 'False' } = {},
|
||||||
|
name,
|
||||||
|
} = selectedRows[0];
|
||||||
|
setCreateVolumeType(name);
|
||||||
if (this.sourceTypeIsSnapshot) {
|
if (this.sourceTypeIsSnapshot) {
|
||||||
const {
|
const {
|
||||||
initVolumeType: { selectedRowKeys = [] },
|
initVolumeType: { selectedRowKeys = [] },
|
||||||
@ -520,6 +495,7 @@ export class Create extends FormAction {
|
|||||||
description: `${minSize}GiB-${this.maxSize}GiB`,
|
description: `${minSize}GiB-${this.maxSize}GiB`,
|
||||||
required: this.quotaIsLimit,
|
required: this.quotaIsLimit,
|
||||||
hidden: !this.quotaIsLimit,
|
hidden: !this.quotaIsLimit,
|
||||||
|
onChange: onVolumeSizeChange,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'size',
|
name: 'size',
|
||||||
@ -528,6 +504,7 @@ export class Create extends FormAction {
|
|||||||
min: minSize,
|
min: minSize,
|
||||||
hidden: this.quotaIsLimit,
|
hidden: this.quotaIsLimit,
|
||||||
required: !this.quotaIsLimit,
|
required: !this.quotaIsLimit,
|
||||||
|
onChange: onVolumeSizeChange,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
@ -549,6 +526,7 @@ export class Create extends FormAction {
|
|||||||
onCountChangeCallback() {}
|
onCountChangeCallback() {}
|
||||||
|
|
||||||
onCountChange = (value) => {
|
onCountChange = (value) => {
|
||||||
|
setCreateVolumeCount(value);
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
count: value,
|
count: value,
|
||||||
@ -561,69 +539,12 @@ export class Create extends FormAction {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
checkQuotaDetail = (quota) => {
|
|
||||||
if (!quota || isEmpty(quota)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const { limit, add, reserved = 0 } = quota || {};
|
|
||||||
if (limit === -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return limit >= add + reserved;
|
|
||||||
};
|
|
||||||
|
|
||||||
getQuotaErrorMsg = (quota) => {
|
|
||||||
const { limit, used, reserved, add, title } = quota;
|
|
||||||
const left = limit - used - reserved;
|
|
||||||
return t(
|
|
||||||
'Quota: Insufficient { name } quota to create resources, please adjust resource quantity or quota(left { left }, input { input }).',
|
|
||||||
{
|
|
||||||
name: title,
|
|
||||||
left,
|
|
||||||
input: add,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
checkQuotaAll = () => {
|
|
||||||
const results = this.quotaInfo;
|
|
||||||
if (!results.length) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const [quota = {}, sizeQuota = {}, typeQuota = {}, typeSizeQuota = {}] =
|
|
||||||
results;
|
|
||||||
let msg = '';
|
|
||||||
const quotas = [quota, sizeQuota, typeQuota, typeSizeQuota];
|
|
||||||
const errorQuota = quotas.find((it) => !this.checkQuotaDetail(it));
|
|
||||||
if (errorQuota) {
|
|
||||||
msg = this.getQuotaErrorMsg(errorQuota);
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
renderBadge() {
|
|
||||||
const msg = this.checkQuotaAll();
|
|
||||||
if (!msg) {
|
|
||||||
this.msg = '';
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (msg && this.msg !== msg) {
|
|
||||||
$message.error(msg);
|
|
||||||
this.msg = msg;
|
|
||||||
}
|
|
||||||
return <Badge status="error" text={msg} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderExtra() {
|
|
||||||
return this.renderBadge();
|
|
||||||
}
|
|
||||||
|
|
||||||
getCountMax = () => {
|
getCountMax = () => {
|
||||||
const { limit, used, reserved } = this.quota;
|
const { volumes: { left = 0 } = {} } = this.getVolumeQuota();
|
||||||
if (!limit || limit === -1) {
|
if (left === -1) {
|
||||||
return 100;
|
return Infinity;
|
||||||
}
|
}
|
||||||
return limit - used - reserved;
|
return left;
|
||||||
};
|
};
|
||||||
|
|
||||||
renderFooterLeft() {
|
renderFooterLeft() {
|
||||||
@ -644,15 +565,14 @@ export class Create extends FormAction {
|
|||||||
value={count}
|
value={count}
|
||||||
className={classnames(styles.input, 'volume-count')}
|
className={classnames(styles.input, 'volume-count')}
|
||||||
/>
|
/>
|
||||||
{this.renderExtra()}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit = (data) => {
|
onSubmit = (data) => {
|
||||||
const { count } = this.state;
|
const { count } = this.state;
|
||||||
if (this.msg) {
|
if (this.message) {
|
||||||
return Promise.reject(this.msg);
|
return Promise.reject(this.message);
|
||||||
}
|
}
|
||||||
const {
|
const {
|
||||||
backup,
|
backup,
|
||||||
|
Loading…
Reference in New Issue
Block a user