Merge "feat: Show quota info when create server group"
This commit is contained in:
commit
b8caadf202
@ -74,8 +74,8 @@ export default class BaseForm extends React.Component {
|
||||
this.unMountActions && this.unMountActions();
|
||||
}
|
||||
|
||||
get canSubmit() {
|
||||
return true;
|
||||
get disableSubmit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get name() {
|
||||
@ -534,7 +534,7 @@ export default class BaseForm extends React.Component {
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!this.canSubmit}
|
||||
disabled={this.disableSubmit}
|
||||
type="primary"
|
||||
className={styles.submit}
|
||||
onClick={this.onClickSubmit}
|
||||
@ -651,6 +651,9 @@ export default class BaseForm extends React.Component {
|
||||
}
|
||||
|
||||
renderRightTopExtra() {
|
||||
if (this.isModal) {
|
||||
return null;
|
||||
}
|
||||
const content = this.renderQuota();
|
||||
if (!content) {
|
||||
return null;
|
||||
@ -663,6 +666,17 @@ export default class BaseForm extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderModalRightExtra() {
|
||||
if (!this.isModal) {
|
||||
return null;
|
||||
}
|
||||
const content = this.renderQuota();
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
return <div className={styles['modal-right-extra-wrapper']}>{content}</div>;
|
||||
}
|
||||
|
||||
render() {
|
||||
const wrapperPadding =
|
||||
this.listUrl || this.isStep || (this.isModal && this.tips)
|
||||
@ -679,18 +693,31 @@ export default class BaseForm extends React.Component {
|
||||
formStyle.height = `calc(100% - ${tipHeight}px)`;
|
||||
}
|
||||
}
|
||||
|
||||
const formDiv = (
|
||||
<Spin spinning={this.isSubmitting} tip={this.renderSubmittingTip()}>
|
||||
{tips}
|
||||
{this.renderRightTopExtra()}
|
||||
<div className={classnames(styles.form, 'sl-form')} style={formStyle}>
|
||||
{this.renderForms()}
|
||||
</div>
|
||||
{this.renderFooter()}
|
||||
</Spin>
|
||||
);
|
||||
const onlyForm = !this.isModal || (this.isModal && !this.showQuota);
|
||||
const modalInner =
|
||||
this.isModal && !onlyForm ? (
|
||||
<Row justify="space-between" align="top">
|
||||
<Col span={18}>{formDiv}</Col>
|
||||
<Col span={6}>{this.renderModalRightExtra()}</Col>
|
||||
</Row>
|
||||
) : null;
|
||||
return (
|
||||
<div
|
||||
className={classnames(styles.wrapper, wrapperPadding, this.className)}
|
||||
>
|
||||
<Spin spinning={this.isSubmitting} tip={this.renderSubmittingTip()}>
|
||||
{tips}
|
||||
{this.renderRightTopExtra()}
|
||||
<div className={classnames(styles.form, 'sl-form')} style={formStyle}>
|
||||
{this.renderForms()}
|
||||
</div>
|
||||
{this.renderFooter()}
|
||||
</Spin>
|
||||
{onlyForm && formDiv}
|
||||
{modalInner}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -139,3 +139,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-right-extra-wrapper {
|
||||
border-left: solid 2px @gray-2;
|
||||
}
|
||||
|
@ -429,16 +429,18 @@ export class ActionButton extends Component {
|
||||
callback();
|
||||
};
|
||||
|
||||
getModalWidth = (size) => {
|
||||
getModalWidth = (action) => {
|
||||
const { modalSize: size, showQuota = false } = action;
|
||||
const multi = showQuota ? 1.25 : 1;
|
||||
switch (size) {
|
||||
case 'small':
|
||||
return 520;
|
||||
return 520 * multi;
|
||||
case 'middle':
|
||||
return 720;
|
||||
return 720 * multi;
|
||||
case 'large':
|
||||
return 1200;
|
||||
return 1200 * multi;
|
||||
default:
|
||||
return 520;
|
||||
return 520 * multi;
|
||||
}
|
||||
};
|
||||
|
||||
@ -455,8 +457,15 @@ export class ActionButton extends Component {
|
||||
}
|
||||
const { title, action, item, containerProps, items } = this.props;
|
||||
const ActionComponent = action;
|
||||
const { modalSize, okText, cancelText, id, className, readOnly } = action;
|
||||
const width = this.getModalWidth(modalSize);
|
||||
const {
|
||||
okText,
|
||||
cancelText,
|
||||
id,
|
||||
className,
|
||||
readOnly,
|
||||
disableSubmit = false,
|
||||
} = action;
|
||||
const width = this.getModalWidth(action);
|
||||
const modalProps = {
|
||||
title,
|
||||
visible,
|
||||
@ -464,6 +473,9 @@ export class ActionButton extends Component {
|
||||
width,
|
||||
onOk: () => this.onClickModalActionOk(),
|
||||
onCancel: this.onClickModalActionCancel,
|
||||
okButtonProps: {
|
||||
disabled: disableSubmit,
|
||||
},
|
||||
confirmLoading: submitLoading,
|
||||
okText,
|
||||
cancelText,
|
||||
|
@ -42,6 +42,14 @@ export default class ModalAction extends BaseForm {
|
||||
return 'small';
|
||||
}
|
||||
|
||||
static get showQuota() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get showQuota() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get labelCol() {
|
||||
const size = this.getModalSize();
|
||||
if (size === 'large') {
|
||||
|
@ -17,6 +17,7 @@ import { inject, observer } from 'mobx-react';
|
||||
import globalServerGroupStore from 'stores/nova/server-group';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import policyType from 'resources/nova/server-group';
|
||||
import globalProjectStore from 'src/stores/keystone/project';
|
||||
|
||||
export class Create extends ModalAction {
|
||||
static id = 'create';
|
||||
@ -24,7 +25,11 @@ export class Create extends ModalAction {
|
||||
static title = t('Create Server Group');
|
||||
|
||||
init() {
|
||||
this.state.quota = {};
|
||||
this.state.quotaLoading = true;
|
||||
this.store = globalServerGroupStore;
|
||||
this.projectStore = globalProjectStore;
|
||||
this.getQuota();
|
||||
}
|
||||
|
||||
get name() {
|
||||
@ -35,6 +40,45 @@ export class Create extends ModalAction {
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
static get disableSubmit() {
|
||||
const { novaQuota: { server_groups: { left = 0 } = {} } = {} } =
|
||||
globalProjectStore;
|
||||
return left === 0;
|
||||
}
|
||||
|
||||
static get showQuota() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get showQuota() {
|
||||
return true;
|
||||
}
|
||||
|
||||
async getQuota() {
|
||||
const result = await this.projectStore.fetchProjectNovaQuota();
|
||||
const { server_groups: quota = {} } = result || {};
|
||||
this.setState({
|
||||
quota,
|
||||
quotaLoading: false,
|
||||
});
|
||||
}
|
||||
|
||||
get quotaInfo() {
|
||||
const { quota = {}, quotaLoading } = this.state;
|
||||
if (quotaLoading) {
|
||||
return [];
|
||||
}
|
||||
const { left = 0 } = quota;
|
||||
const add = left === 0 ? 0 : 1;
|
||||
const data = {
|
||||
...quota,
|
||||
add,
|
||||
name: 'server_groups',
|
||||
title: t('Server Group'),
|
||||
};
|
||||
return [data];
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
const policies = Object.keys(policyType).map((it) => ({
|
||||
value: it,
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { getGiBValue } from 'utils/index';
|
||||
import { isNil, isEmpty } from 'lodash';
|
||||
import { isNil, isEmpty, isObject } from 'lodash';
|
||||
import client from 'client';
|
||||
import Base from 'stores/base';
|
||||
import globalRootStore from 'stores/root';
|
||||
@ -23,6 +23,9 @@ export class ProjectStore extends Base {
|
||||
@observable
|
||||
quota = {};
|
||||
|
||||
@observable
|
||||
novaQuota = {};
|
||||
|
||||
@observable
|
||||
groupRoleList = [];
|
||||
|
||||
@ -261,14 +264,9 @@ export class ProjectStore extends Base {
|
||||
...neutronQuota,
|
||||
...renameShareQuota,
|
||||
};
|
||||
const quotaKey = Object.keys(quota);
|
||||
quotaKey.forEach((it) => {
|
||||
if (quota[it].in_use !== undefined) {
|
||||
quota[it].used = quota[it].in_use;
|
||||
}
|
||||
});
|
||||
this.quota = quota;
|
||||
return quota;
|
||||
const newQuota = this.updateQuotaData(quota);
|
||||
this.quota = newQuota;
|
||||
return newQuota;
|
||||
}
|
||||
|
||||
omitNil = (obj) => {
|
||||
@ -437,6 +435,36 @@ export class ProjectStore extends Base {
|
||||
const result = await this.client.groups.roles.delete(id, groupId, roleId);
|
||||
return result;
|
||||
}
|
||||
|
||||
getLeftQuotaData = (data) => {
|
||||
const { used = 0, limit = 0, reserved = 0 } = data;
|
||||
if (limit === -1) {
|
||||
return -1;
|
||||
}
|
||||
return limit - used - reserved;
|
||||
};
|
||||
|
||||
updateQuotaData = (quota) => {
|
||||
const newData = JSON.parse(JSON.stringify(quota));
|
||||
Object.keys(newData).forEach((it) => {
|
||||
if (isObject(newData[it])) {
|
||||
if (newData[it].in_use !== undefined) {
|
||||
newData[it].used = newData[it].in_use;
|
||||
}
|
||||
newData[it].left = this.getLeftQuotaData(newData[it]);
|
||||
}
|
||||
});
|
||||
return newData;
|
||||
};
|
||||
|
||||
@action
|
||||
async fetchProjectNovaQuota() {
|
||||
const result = await this.novaQuotaClient.detail(this.currentProjectId);
|
||||
const { quota_set: quota } = result;
|
||||
const novaQuota = this.updateQuotaData(quota);
|
||||
this.novaQuota = novaQuota;
|
||||
return novaQuota;
|
||||
}
|
||||
}
|
||||
|
||||
const globalProjectStore = new ProjectStore();
|
||||
|
Loading…
Reference in New Issue
Block a user