feat: support backup quota info when volume create backup

1. Add backups and backup gigabytes quota when volume create backup
2. Disable click submit button when left backups quota is zero or left backup gigabytes quota is not enough
3. Refactor create backup, extract common function
4. Update Form right extra info span size, support small span for large
modal, also support custom span size

Change-Id: Ib76e6de287f8f84eecc36471dee3b8cce456b17b
This commit is contained in:
Jingwei.Zhang 2022-06-28 14:13:48 +08:00
parent e7a225635c
commit 78cb485068
5 changed files with 124 additions and 64 deletions

View File

@ -268,6 +268,13 @@ export default class BaseForm extends React.Component {
return null; return null;
} }
getRightExtraSpan() {
return {
left: 18,
right: 6,
};
}
getSubmitData(data) { getSubmitData(data) {
return { ...data }; return { ...data };
} }
@ -709,11 +716,12 @@ export default class BaseForm extends React.Component {
</Spin> </Spin>
); );
const onlyForm = !this.isModal || (this.isModal && !this.showQuota); const onlyForm = !this.isModal || (this.isModal && !this.showQuota);
const { left, right } = this.getRightExtraSpan();
const modalInner = const modalInner =
this.isModal && !onlyForm ? ( this.isModal && !onlyForm ? (
<Row justify="space-between" align="top"> <Row justify="space-between" align="top">
<Col span={18}>{formDiv}</Col> <Col span={left}>{formDiv}</Col>
<Col span={6}>{this.renderModalRightExtra()}</Col> <Col span={right}>{this.renderModalRightExtra()}</Col>
</Row> </Row>
) : null; ) : null;
return ( return (

View File

@ -42,6 +42,17 @@ export default class ModalAction extends BaseForm {
return 'small'; return 'small';
} }
getRightExtraSpan() {
const size = this.getModalSize();
const isLargeSize = size === 'large';
const left = isLargeSize ? 20 : 18;
const right = isLargeSize ? 4 : 6;
return {
left,
right,
};
}
static get showQuota() { static get showQuota() {
return false; return false;
} }

View File

@ -16,34 +16,20 @@ 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';
import globalBackupStore from 'stores/cinder/backup'; import globalBackupStore from 'stores/cinder/backup';
import { createTip, backupModeList, modeTip } from 'resources/cinder/backup'; import {
createTip,
backupModeList,
modeTip,
fetchQuota,
getQuota,
getQuotaInfo,
checkQuotaDisable,
} from 'resources/cinder/backup';
import { import {
isAvailableOrInUse, isAvailableOrInUse,
isInUse, isInUse,
volumeSelectTablePropsBackend, volumeSelectTablePropsBackend,
} from 'resources/cinder/volume'; } from 'resources/cinder/volume';
import globalProjectStore from 'stores/keystone/project';
export const getQuota = (cinderQuota) => {
const { backups = {}, backup_gigabytes: gigabytes = {} } = cinderQuota || {};
return {
backups,
gigabytes,
};
};
export const getAdd = (cinderQuota) => {
const { backups, gigabytes } = getQuota(cinderQuota);
const { left = 0 } = backups || {};
const { left: sizeLeft = 0, limit } = gigabytes || {};
const { currentVolumeSize = 0 } = globalBackupStore;
const add =
left !== 0 && (limit === -1 || sizeLeft >= currentVolumeSize) ? 1 : 0;
return {
add,
addSize: add === 1 ? currentVolumeSize : 0,
};
};
export class Create extends ModalAction { export class Create extends ModalAction {
static id = 'create'; static id = 'create';
@ -66,10 +52,7 @@ export class Create extends ModalAction {
globalBackupStore.setCurrentVolume({}); globalBackupStore.setCurrentVolume({});
this.store = globalBackupStore; this.store = globalBackupStore;
this.volumeStore = globalVolumeStore; this.volumeStore = globalVolumeStore;
this.state.quota = {}; fetchQuota(this);
this.state.quotaLoading = true;
this.projectStore = globalProjectStore;
this.getQuota();
} }
get tips() { get tips() {
@ -87,9 +70,7 @@ export class Create extends ModalAction {
static allowed = () => Promise.resolve(true); static allowed = () => Promise.resolve(true);
static get disableSubmit() { static get disableSubmit() {
const { cinderQuota = {} } = globalProjectStore; return checkQuotaDisable();
const { add } = getAdd(cinderQuota);
return add === 0;
} }
static get showQuota() { static get showQuota() {
@ -100,38 +81,8 @@ export class Create extends ModalAction {
return true; return true;
} }
async getQuota() {
this.setState({
quotaLoading: true,
});
const result = await this.projectStore.fetchProjectCinderQuota();
this.setState({
quota: result,
quotaLoading: false,
});
}
get quotaInfo() { get quotaInfo() {
const { quota = {}, quotaLoading } = this.state; return getQuotaInfo(this);
if (quotaLoading) {
return [];
}
const { backups = {}, gigabytes = {} } = getQuota(quota);
const { add, addSize } = getAdd(quota);
const backupData = {
...backups,
add,
name: 'backup',
title: t('Backup'),
};
const sizeData = {
...gigabytes,
add: addSize,
name: 'gigabytes',
title: t('Backup gigabytes (GiB)'),
type: 'line',
};
return [backupData, sizeData];
} }
onVolumeChange = (value) => { onVolumeChange = (value) => {

View File

@ -16,7 +16,14 @@ import { inject, observer } from 'mobx-react';
import { ModalAction } from 'containers/Action'; import { ModalAction } from 'containers/Action';
import globalBackupStore from 'stores/cinder/backup'; import globalBackupStore from 'stores/cinder/backup';
import { isAvailableOrInUse, isInUse } from 'resources/cinder/volume'; import { isAvailableOrInUse, isInUse } from 'resources/cinder/volume';
import { createTip, backupModeList, modeTip } from 'resources/cinder/backup'; import {
createTip,
backupModeList,
modeTip,
getQuotaInfo,
checkQuotaDisable,
fetchQuota,
} from 'resources/cinder/backup';
export class CreateBackup extends ModalAction { export class CreateBackup extends ModalAction {
static id = 'create-backup'; static id = 'create-backup';
@ -70,6 +77,24 @@ export class CreateBackup extends ModalAction {
init() { init() {
this.store = globalBackupStore; this.store = globalBackupStore;
globalBackupStore.setCurrentVolume(this.item);
fetchQuota(this);
}
static get disableSubmit() {
return checkQuotaDisable();
}
static get showQuota() {
return true;
}
get showQuota() {
return true;
}
get quotaInfo() {
return getQuotaInfo(this);
} }
onSubmit = (values) => { onSubmit = (values) => {

View File

@ -15,6 +15,8 @@
import React from 'react'; import React from 'react';
import { getOptions } from 'utils/index'; import { getOptions } from 'utils/index';
import { FolderOutlined, FolderAddOutlined } from '@ant-design/icons'; import { FolderOutlined, FolderAddOutlined } from '@ant-design/icons';
import globalProjectStore from 'stores/keystone/project';
import globalBackupStore from 'stores/cinder/backup';
export const backupStatus = { export const backupStatus = {
available: t('Available'), available: t('Available'),
@ -140,3 +142,66 @@ export const restoreTip = (
</p> </p>
</span> </span>
); );
// deal with quota
export async function fetchQuota(self) {
self.setState({
quota: {},
quotaLoading: true,
});
const result = await globalProjectStore.fetchProjectCinderQuota();
self.setState({
quota: result,
quotaLoading: false,
});
}
export const getQuota = (cinderQuota) => {
const { backups = {}, backup_gigabytes: gigabytes = {} } = cinderQuota || {};
return {
backups,
gigabytes,
};
};
export const getAdd = (cinderQuota) => {
const { backups, gigabytes } = getQuota(cinderQuota);
const { left = 0 } = backups || {};
const { left: sizeLeft = 0, limit } = gigabytes || {};
const { currentVolumeSize = 0 } = globalBackupStore;
const add =
left !== 0 && (limit === -1 || sizeLeft >= currentVolumeSize) ? 1 : 0;
return {
add,
addSize: add === 1 ? currentVolumeSize : 0,
};
};
export const getQuotaInfo = (self) => {
const { quota = {}, quotaLoading } = self.state;
if (quotaLoading) {
return [];
}
const { backups = {}, gigabytes = {} } = getQuota(quota);
const { add, addSize } = getAdd(quota);
const backupData = {
...backups,
add,
name: 'backup',
title: t('Backup'),
};
const sizeData = {
...gigabytes,
add: addSize,
name: 'gigabytes',
title: t('Backup gigabytes (GiB)'),
type: 'line',
};
return [backupData, sizeData];
};
export const checkQuotaDisable = () => {
const { cinderQuota = {} } = globalProjectStore;
const { add } = getAdd(cinderQuota);
return add === 0;
};