diff --git a/src/components/QuotaChart/Ring.jsx b/src/components/QuotaChart/Ring.jsx
index 4986ae31..253e9bed 100644
--- a/src/components/QuotaChart/Ring.jsx
+++ b/src/components/QuotaChart/Ring.jsx
@@ -22,6 +22,7 @@ import {
Annotation,
Tooltip,
} from 'bizcharts';
+import { Tooltip as AntTooltip } from 'antd';
export const typeColors = {
used: '#5B8FF9',
@@ -59,7 +60,10 @@ export default function Ring(props) {
const showTip = isLimit;
const limitNumber = !isLimit ? Infinity : limit;
const limitStr = !isLimit ? t('Infinity') : limit;
- const left = !isLimit ? 1 : limit - used - reserved - add;
+ let left = !isLimit ? 1 : limit - used - reserved - add;
+ if (left < 0) {
+ left = 0;
+ }
const data = [
{
type: t('Used'),
@@ -93,53 +97,71 @@ export default function Ring(props) {
const allCount = used + add + reserved;
const percent = isLimit ? (allCount / limitNumber) * 100 : 0;
- return (
-
-
-
-
- {/* 绘制图形 */}
-
-
-
-
-
-
-
-
-
+ let tipTitle = '';
+ if (!isLimit) {
+ const usedTip = `${t('Used')}: ${used}`;
+ const reservedTip = reserved ? '' : `${t('Reserved')}: ${reserved}`;
+ const newTip = `${t('New')}: ${add}`;
+ const tips = [usedTip, newTip];
+ if (reserved) {
+ tips.splice(1, 0, reservedTip);
+ }
+ tipTitle = tips.join(' / ');
+ }
+
+ const chart = (
+
+
+
+ {/* 绘制图形 */}
+
+
+
+
+
+
+
+
);
+
+ const content = isLimit ? (
+ chart
+ ) : (
+ {chart}
+ );
+
+ return {content}
;
}
diff --git a/src/locales/en.json b/src/locales/en.json
index 9aa2f0ef..29e8f32f 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -1812,6 +1812,7 @@
"Quota exceeded": "Quota exceeded",
"Quota is not enough for extend share.": "Quota is not enough for extend share.",
"Quota is not enough for extend volume.": "Quota is not enough for extend volume.",
+ "Quota of key pair means: the number of allowed key pairs for each user.": "Quota of key pair means: the number of allowed key pairs for each user.",
"Quota: Insufficient quota to create resources, please adjust resource quantity or quota(left { quota }, input { input }).": "Quota: Insufficient quota to create resources, please adjust resource quantity or quota(left { quota }, input { input }).",
"Quota: Insufficient { name } quota to create resources, please adjust resource quantity or quota(left { left }, input { input }).": "Quota: Insufficient { name } quota to create resources, please adjust resource quantity or quota(left { left }, input { input }).",
"Quota: Project quotas sufficient resources can be created": "Quota: Project quotas sufficient resources can be created",
diff --git a/src/locales/zh.json b/src/locales/zh.json
index 2ec060c2..89c3c9d3 100644
--- a/src/locales/zh.json
+++ b/src/locales/zh.json
@@ -1812,6 +1812,7 @@
"Quota exceeded": "配额用尽",
"Quota is not enough for extend share.": "配额不足以扩容共享。",
"Quota is not enough for extend volume.": "配额不足以扩容云硬盘。",
+ "Quota of key pair means: the number of allowed key pairs for each user.": "密钥的配额表示:每个用户允许创建的密钥数量。",
"Quota: Insufficient quota to create resources, please adjust resource quantity or quota(left { quota }, input { input }).": "配额:项目配额不足,无法创建资源,请进行资源数量或配额的调整(剩余{ quota },输入{ input })。",
"Quota: Insufficient { name } quota to create resources, please adjust resource quantity or quota(left { left }, input { input }).": "配额:{ name } 配额不足,无法创建资源,请进行资源数量或配额的调整(剩余{ left },输入{ input })。",
"Quota: Project quotas sufficient resources can be created": "配额:项目配额充足,可创建资源",
@@ -2241,7 +2242,7 @@
"The name should start with upper letter, lower letter, and be a string of 3 to 63, characters can only contain \"0-9, a-z, A-Z, -\".": "名称应以大写字母,小写字母开头,长度为3-63字符,且只包含“0-9, a-z, A-Z, -”。",
"The new password cannot be identical to the current password.": "用户新密码不能与原密码相同。",
"The no_proxy address to use for nodes in cluster": "用于集群中节点的 no_proxy 地址",
- "The number of allowed key pairs for each user.": "每个用户允许创建的配额数量",
+ "The number of allowed key pairs for each user.": "每个用户允许创建的密钥数量",
"The number of vCPU cores should not exceed the maximum number of CPU cores of the physical node. Otherwise it will cause fail to schedule to any physical node when creating instance.": "vCPU核数不应该超过物理节点的最大CPU核数,否则会导致云主机创建时无法调度到任何物理节点。",
"The number of virtual cpu for this container": "容器的虚拟 CPU 数量",
"The password must not be the same as the previous": "新密码不能与以前的密码相同",
diff --git a/src/pages/base/containers/Overview/components/QuotaOverview.jsx b/src/pages/base/containers/Overview/components/QuotaOverview.jsx
index 86c4180d..c51748d4 100644
--- a/src/pages/base/containers/Overview/components/QuotaOverview.jsx
+++ b/src/pages/base/containers/Overview/components/QuotaOverview.jsx
@@ -31,10 +31,7 @@ const colors = {
const keyPairTitle = (
{t('Key Pair')}
- node.parentNode}
- >
+
diff --git a/src/pages/compute/containers/Keypair/actions/Create.jsx b/src/pages/compute/containers/Keypair/actions/Create.jsx
index f39acf8d..070a6ddc 100644
--- a/src/pages/compute/containers/Keypair/actions/Create.jsx
+++ b/src/pages/compute/containers/Keypair/actions/Create.jsx
@@ -15,8 +15,23 @@
import { inject, observer } from 'mobx-react';
import { ModalAction } from 'containers/Action';
import globalKeypairStore from 'stores/nova/keypair';
+import globalProjectStore from 'stores/keystone/project';
import FileSaver from 'file-saver';
+const getUsed = () => {
+ const { total = 0, data = [] } = globalKeypairStore.list || {};
+ return total || data.length;
+};
+
+const getAdd = (quota) => {
+ const { limit = 0 } = quota || {};
+ if (limit === -1) {
+ return 1;
+ }
+ const used = getUsed();
+ return limit > used ? 1 : 0;
+};
+
export class CreateKeypair extends ModalAction {
static id = 'create-keypair';
@@ -26,6 +41,64 @@ export class CreateKeypair extends ModalAction {
return t('Create Keypair');
}
+ init() {
+ this.state.quota = {};
+ this.state.quotaLoading = true;
+ this.projectStore = globalProjectStore;
+ this.getQuota();
+ }
+
+ get tips() {
+ return t(
+ 'Quota of key pair means: the number of allowed key pairs for each user.'
+ );
+ }
+
+ static get disableSubmit() {
+ const {
+ novaQuota: { key_pairs: quota = {} },
+ } = globalProjectStore;
+ const add = getAdd(quota);
+ return add === 0;
+ }
+
+ static get showQuota() {
+ return true;
+ }
+
+ get showQuota() {
+ return true;
+ }
+
+ async getQuota() {
+ this.setState({
+ quotaLoading: true,
+ });
+ const result = await this.projectStore.fetchProjectNovaQuota();
+ const { key_pairs: quota = {} } = result || {};
+ this.setState({
+ quota,
+ quotaLoading: false,
+ });
+ }
+
+ get quotaInfo() {
+ const { quota = {}, quotaLoading } = this.state;
+ if (quotaLoading) {
+ return [];
+ }
+ const add = getAdd(quota);
+ const used = getUsed();
+ const data = {
+ ...quota,
+ add,
+ used,
+ name: 'key_pair',
+ title: t('Key Pair'),
+ };
+ return [data];
+ }
+
onSubmit = (values) => {
const { name, public_key } = values;
const params = {