refactor: Refactor project detail quota codes
1. Refactor project quota in project detail page 2. Add keypair quota display in overview/project detail quota page Change-Id: I40e5925909d767a87eadd09cfb9c11ea1624cead
This commit is contained in:
parent
e182d62b34
commit
ae266d3d74
@ -885,6 +885,7 @@
|
|||||||
"Kernel ID": "Kernel ID",
|
"Kernel ID": "Kernel ID",
|
||||||
"Kernel Image": "Kernel Image",
|
"Kernel Image": "Kernel Image",
|
||||||
"Key": "Key",
|
"Key": "Key",
|
||||||
|
"Key Pair": "Key Pair",
|
||||||
"Key Pairs": "Key Pairs",
|
"Key Pairs": "Key Pairs",
|
||||||
"Key Size (bits)": "Key Size (bits)",
|
"Key Size (bits)": "Key Size (bits)",
|
||||||
"Keypair": "Keypair",
|
"Keypair": "Keypair",
|
||||||
@ -1791,7 +1792,6 @@
|
|||||||
"compute hosts": "compute hosts",
|
"compute hosts": "compute hosts",
|
||||||
"compute services": "compute services",
|
"compute services": "compute services",
|
||||||
"connect subnet": "connect subnet",
|
"connect subnet": "connect subnet",
|
||||||
"core": "core",
|
|
||||||
"create DSCP marking rule": "create DSCP marking rule",
|
"create DSCP marking rule": "create DSCP marking rule",
|
||||||
"create a new network/subnet": "create a new network/subnet",
|
"create a new network/subnet": "create a new network/subnet",
|
||||||
"create a new security group": "create a new security group",
|
"create a new security group": "create a new security group",
|
||||||
@ -1925,7 +1925,6 @@
|
|||||||
"qoS policy": "qoS policy",
|
"qoS policy": "qoS policy",
|
||||||
"qos specs": "qos specs",
|
"qos specs": "qos specs",
|
||||||
"quota set to -1 means there is no quota limit on the current resource": "quota set to -1 means there is no quota limit on the current resource",
|
"quota set to -1 means there is no quota limit on the current resource": "quota set to -1 means there is no quota limit on the current resource",
|
||||||
"ram": "ram",
|
|
||||||
"reboot instance": "reboot instance",
|
"reboot instance": "reboot instance",
|
||||||
"rebuild instance": "rebuild instance",
|
"rebuild instance": "rebuild instance",
|
||||||
"recover instance": "recover instance",
|
"recover instance": "recover instance",
|
||||||
|
@ -885,6 +885,7 @@
|
|||||||
"Kernel ID": "内核ID",
|
"Kernel ID": "内核ID",
|
||||||
"Kernel Image": "Kernel镜像",
|
"Kernel Image": "Kernel镜像",
|
||||||
"Key": "键",
|
"Key": "键",
|
||||||
|
"Key Pair": "密钥",
|
||||||
"Key Pairs": "密钥",
|
"Key Pairs": "密钥",
|
||||||
"Key Size (bits)": "密钥大小(比特)",
|
"Key Size (bits)": "密钥大小(比特)",
|
||||||
"Keypair": "SSH密钥对",
|
"Keypair": "SSH密钥对",
|
||||||
@ -1791,7 +1792,6 @@
|
|||||||
"compute hosts": "计算节点",
|
"compute hosts": "计算节点",
|
||||||
"compute services": "计算服务",
|
"compute services": "计算服务",
|
||||||
"connect subnet": "连接子网",
|
"connect subnet": "连接子网",
|
||||||
"core": "虚拟CPU",
|
|
||||||
"create DSCP marking rule": "创建DSCP标记规则",
|
"create DSCP marking rule": "创建DSCP标记规则",
|
||||||
"create a new network/subnet": "新建网络/子网",
|
"create a new network/subnet": "新建网络/子网",
|
||||||
"create a new security group": "新建安全组",
|
"create a new security group": "新建安全组",
|
||||||
@ -1925,7 +1925,6 @@
|
|||||||
"qoS policy": "QoS策略",
|
"qoS policy": "QoS策略",
|
||||||
"qos specs": "QoS规格",
|
"qos specs": "QoS规格",
|
||||||
"quota set to -1 means there is no quota limit on the current resource": "配额为设为 -1 时表示当前资源无配额限制",
|
"quota set to -1 means there is no quota limit on the current resource": "配额为设为 -1 时表示当前资源无配额限制",
|
||||||
"ram": "内存(GB)",
|
|
||||||
"reboot instance": "重启云主机",
|
"reboot instance": "重启云主机",
|
||||||
"rebuild instance": "重建云主机",
|
"rebuild instance": "重建云主机",
|
||||||
"recover instance": "恢复云主机",
|
"recover instance": "恢复云主机",
|
||||||
|
@ -16,7 +16,6 @@ import React, { Component } from 'react';
|
|||||||
import { Badge, Card, Col, List, Progress, Row, Spin, Tooltip } from 'antd';
|
import { Badge, Card, Col, List, Progress, Row, Spin, Tooltip } from 'antd';
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import globalVolumeTypeStore from 'stores/cinder/volume-type';
|
import globalVolumeTypeStore from 'stores/cinder/volume-type';
|
||||||
import globalKeypairStore from 'stores/nova/keypair';
|
|
||||||
import globalProjectStore from 'stores/keystone/project';
|
import globalProjectStore from 'stores/keystone/project';
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import styles from '../style.less';
|
import styles from '../style.less';
|
||||||
@ -36,6 +35,7 @@ export const quotaCardList = [
|
|||||||
{ text: t('vCPUs'), key: 'cores' },
|
{ text: t('vCPUs'), key: 'cores' },
|
||||||
{ text: t('Memory'), key: 'ram' },
|
{ text: t('Memory'), key: 'ram' },
|
||||||
{ text: t('Server Group'), key: 'server_groups' },
|
{ text: t('Server Group'), key: 'server_groups' },
|
||||||
|
{ text: t('Key Pair'), key: 'key_pairs' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -85,6 +85,9 @@ export class QuotaOverview extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
};
|
};
|
||||||
|
const { projectStore, volumeTypeStore } = props;
|
||||||
|
this.projectStore = projectStore || globalProjectStore;
|
||||||
|
this.volumeTypeStore = volumeTypeStore || globalVolumeTypeStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -92,20 +95,29 @@ export class QuotaOverview extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getData() {
|
async getData() {
|
||||||
|
const { getData } = this.props;
|
||||||
|
if (getData) {
|
||||||
|
await getData();
|
||||||
|
} else {
|
||||||
const { user } = this.props.rootStore;
|
const { user } = this.props.rootStore;
|
||||||
const { project: { id: projectId = '' } = {} } = user;
|
const { project: { id: projectId = '' } = {} } = user;
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
globalProjectStore.fetchProjectQuota({ project_id: projectId }),
|
this.projectStore.fetchProjectQuota({ project_id: projectId }),
|
||||||
globalVolumeTypeStore.fetchList(),
|
this.volumeTypeStore.fetchList(),
|
||||||
globalKeypairStore.fetchList(),
|
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get volumeTypeData() {
|
||||||
|
const { volumeTypeData } = this.props;
|
||||||
|
return volumeTypeData || this.volumeTypeStore.list.data;
|
||||||
|
}
|
||||||
|
|
||||||
get volumeTypesQuota() {
|
get volumeTypesQuota() {
|
||||||
const volumeTypes = globalVolumeTypeStore.list.data.map((item, index) => {
|
const volumeTypes = this.volumeTypeData.map((item, index) => {
|
||||||
return {
|
return {
|
||||||
index,
|
index,
|
||||||
value: [
|
value: [
|
||||||
@ -211,7 +223,7 @@ export class QuotaOverview extends Component {
|
|||||||
return <Spin />;
|
return <Spin />;
|
||||||
}
|
}
|
||||||
return this.renderQuotaCart(
|
return this.renderQuotaCart(
|
||||||
globalProjectStore.quota,
|
this.projectStore.quota,
|
||||||
this.getFilteredValue(item.value)
|
this.getFilteredValue(item.value)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -238,7 +250,7 @@ export class QuotaOverview extends Component {
|
|||||||
<Row key={item.index} gutter={[16]}>
|
<Row key={item.index} gutter={[16]}>
|
||||||
{item.value.map((i) => (
|
{item.value.map((i) => (
|
||||||
<Col span={8} key={i.text}>
|
<Col span={8} key={i.text}>
|
||||||
{this.getItemInfo(globalProjectStore.quota, i)}
|
{this.getItemInfo(this.projectStore.quota, i)}
|
||||||
</Col>
|
</Col>
|
||||||
))}
|
))}
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -55,8 +55,63 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bottom {
|
.right {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.project {
|
||||||
|
position: relative;
|
||||||
|
.meta {
|
||||||
|
padding-bottom: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border-bottom: 1px dashed #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.ant-descriptions-item-label {
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.role_button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.ant-card-head {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.outer {
|
||||||
|
width: 100%;
|
||||||
|
height: 10rem;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
//margin: 16px 0;
|
//margin: 16px 0;
|
||||||
|
|
||||||
:global {
|
:global {
|
||||||
@ -120,59 +175,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.project {
|
|
||||||
position: relative;
|
|
||||||
.meta {
|
|
||||||
padding-bottom: 16px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
border-bottom: 1px dashed #e8e8e8;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-descriptions-item-label {
|
|
||||||
width: 130px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.role_button {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
right: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-card-head {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.outer {
|
|
||||||
width: 100%;
|
|
||||||
height: 10rem;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
font-size: 12px;
|
|
||||||
|
|
||||||
.inner {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -12,181 +12,44 @@
|
|||||||
// 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 React, { Component } from 'react';
|
||||||
import { observer, inject } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import QuotaOverview from 'pages/base/containers/Overview/components/QuotaOverview';
|
||||||
import globalProjectStore from 'stores/keystone/project';
|
|
||||||
import { Card, Col, Row, List } from 'antd';
|
|
||||||
import Progress from 'components/ProjectProgress';
|
|
||||||
import classnames from 'classnames';
|
|
||||||
import { VolumeTypeStore } from 'stores/cinder/volume-type';
|
import { VolumeTypeStore } from 'stores/cinder/volume-type';
|
||||||
|
import { ProjectStore } from 'stores/keystone/project';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
export class Quota extends React.Component {
|
export class Quota extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {};
|
this.projectStore = new ProjectStore();
|
||||||
this.init();
|
this.volumeTypeStore = new VolumeTypeStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
get volumeTypeData() {
|
||||||
this.getData();
|
return this.volumeTypeStore.projectVolumeTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
getData = async () => {
|
getData = async () => {
|
||||||
const { id: project_id } = this.props.match.params;
|
const { id: project_id } = this.props.match.params;
|
||||||
await this.store.fetchProjectQuota({
|
return Promise.all([
|
||||||
|
this.projectStore.fetchProjectQuota({
|
||||||
project_id,
|
project_id,
|
||||||
});
|
}),
|
||||||
await this.volumeTypeStore.fetchProjectVolumeTypes(project_id);
|
this.volumeTypeStore.fetchProjectVolumeTypes(project_id),
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
getItemInfo = (i) => {
|
|
||||||
const { quota } = this.store;
|
|
||||||
const resource = quota[i.key];
|
|
||||||
return <Progress resource={resource} name={i.text} nameSpan={8} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.store = globalProjectStore;
|
|
||||||
this.volumeTypeStore = new VolumeTypeStore();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderVolumeTypes = (listData) => (
|
|
||||||
<List
|
|
||||||
itemLayout="vertical"
|
|
||||||
size="large"
|
|
||||||
pagination={{
|
|
||||||
hideOnSinglePage: true,
|
|
||||||
pageSize: 5,
|
|
||||||
size: 'small',
|
|
||||||
}}
|
|
||||||
dataSource={listData}
|
|
||||||
renderItem={(item) => (
|
|
||||||
<Row key={item.index} gutter={[16]}>
|
|
||||||
{item.value.map((i) => (
|
|
||||||
<Col span={8} key={i.text}>
|
|
||||||
{this.getItemInfo(i)}
|
|
||||||
</Col>
|
|
||||||
))}
|
|
||||||
</Row>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { quota } = this.store;
|
|
||||||
const volumeTypes = [];
|
|
||||||
this.volumeTypeStore.projectVolumeTypes.forEach((item, index) => {
|
|
||||||
volumeTypes.push({
|
|
||||||
index,
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
text: t('{name} type', { name: item.name }),
|
|
||||||
key: `volumes_${item.name}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: t('{name} type gigabytes(GB)', { name: item.name }),
|
|
||||||
key: `gigabytes_${item.name}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: t('{name} type snapshots', { name: item.name }),
|
|
||||||
key: `snapshots_${item.name}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames(styles.wrapper, this.className)}>
|
<div className={styles.wrapper}>
|
||||||
<Card>
|
<QuotaOverview
|
||||||
{quota.instances ? (
|
getData={this.getData}
|
||||||
<div>
|
projectStore={this.projectStore}
|
||||||
<Row>
|
volumeTypeStore={this.volumeTypeStore}
|
||||||
<Col xs={{ span: 8, offset: 1 }} lg={{ span: 8 }}>
|
volumeTypeData={this.volumeTypeData}
|
||||||
<div style={{ fontSize: 16, marginBottom: 12 }}>
|
|
||||||
{t('Compute')}
|
|
||||||
</div>
|
|
||||||
<Progress resource={quota.instances} name={t('instance')} />
|
|
||||||
<Progress resource={quota.cores} name={t('core')} />
|
|
||||||
<Progress resource={quota.ram} name={t('ram')} />
|
|
||||||
{/* <Progress resource={quota.key_pairs} name={t('keypair')} /> */}
|
|
||||||
<div>
|
|
||||||
<p style={{ float: 'right' }}>
|
|
||||||
( {t('Member in group')} :{' '}
|
|
||||||
{quota.server_group_members &&
|
|
||||||
quota.server_group_members.limit === -1
|
|
||||||
? t('Unlimit')
|
|
||||||
: quota.server_group_members.limit}{' '}
|
|
||||||
)
|
|
||||||
</p>
|
|
||||||
<Progress
|
|
||||||
resource={quota.server_groups}
|
|
||||||
name={t('Server Group')}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <Progress resource={quota.server_group_members} name={t('Server Group Member')} /> */}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
{quota.volumes ? (
|
|
||||||
<div>
|
|
||||||
<Row style={{ marginTop: 30 }}>
|
|
||||||
<Col xs={{ span: 8, offset: 1 }} lg={{ span: 8 }}>
|
|
||||||
<div style={{ fontSize: 16, marginBottom: 12 }}>
|
|
||||||
{t('Storage')}
|
|
||||||
</div>
|
|
||||||
<Progress name={t('Volume')} resource={quota.volumes} />
|
|
||||||
<Progress
|
|
||||||
name={`${t('gigabytes')}(GB)`}
|
|
||||||
resource={quota.gigabytes}
|
|
||||||
/>
|
|
||||||
<Progress name={t('backups')} resource={quota.backups} />
|
|
||||||
<Progress
|
|
||||||
name={t('Backup Capacity')}
|
|
||||||
resource={quota.backup_gigabytes}
|
|
||||||
/>
|
|
||||||
<Progress name={t('Snapshot')} resource={quota.snapshots} />
|
|
||||||
</Col>
|
|
||||||
<Col xs={{ span: 8, offset: 1 }} lg={{ span: 8, offset: 6 }}>
|
|
||||||
<div style={{ fontSize: 16, marginBottom: 12 }}>
|
|
||||||
{t('Network')}
|
|
||||||
</div>
|
|
||||||
<Progress resource={quota.router} name={t('router')} />
|
|
||||||
<Progress resource={quota.network} name={t('network')} />
|
|
||||||
<Progress resource={quota.subnet} name={t('subnet')} />
|
|
||||||
<Progress
|
|
||||||
resource={quota.floatingip}
|
|
||||||
name={t('floatingip')}
|
|
||||||
/>
|
|
||||||
<Progress resource={quota.port} name={t('port')} />
|
|
||||||
<Progress
|
|
||||||
name={t('security_group')}
|
|
||||||
resource={quota.security_group}
|
|
||||||
/>
|
|
||||||
<Progress
|
|
||||||
name={t('Security Group Rule')}
|
|
||||||
resource={quota.security_group_rule}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
{volumeTypes[0] ? (
|
|
||||||
<div>
|
|
||||||
<Row style={{ marginTop: 30 }}>
|
|
||||||
<Col xs={{ span: 22, offset: 1 }} lg={{ span: 22 }}>
|
|
||||||
<div style={{ fontSize: 16, marginBottom: 12 }}>
|
|
||||||
{t('Storage Types')}
|
|
||||||
</div>
|
|
||||||
{this.renderVolumeTypes(volumeTypes)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
min-height: calc(100vh - 108px);
|
min-height: calc(100vh - 108px);
|
||||||
padding: 0 @body-padding;
|
padding: 0 @body-padding @body-padding @body-padding;
|
||||||
}
|
}
|
@ -1,164 +0,0 @@
|
|||||||
@import '~antd/lib/style/themes/default.less';
|
|
||||||
|
|
||||||
.container {
|
|
||||||
height: 100%;
|
|
||||||
padding: 16px 12px;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-card {
|
|
||||||
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.09);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.top {
|
|
||||||
|
|
||||||
.title {
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: bottom;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
font-size: 21px;
|
|
||||||
color: #252525;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #000000;
|
|
||||||
margin-left: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
margin: 16px 0;
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-card {
|
|
||||||
box-shadow: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
.text {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #252525;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
margin-left: 22px;
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-badge-status-dot {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-badge-status-text {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #0068FF;
|
|
||||||
float: right;
|
|
||||||
margin-top: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
|
|
||||||
.card {
|
|
||||||
padding: 8px;
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-card-head {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress_title {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.top {
|
|
||||||
.meta {
|
|
||||||
padding-bottom: 16px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
border-bottom: 1px dashed #e8e8e8;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-descriptions-item-label {
|
|
||||||
width: 130px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.money {
|
|
||||||
color: #0068FF;
|
|
||||||
line-height: 42px;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.middle {
|
|
||||||
margin-top: 1.33rem;
|
|
||||||
background-color: #ffffff;
|
|
||||||
|
|
||||||
.row {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.alert_value {
|
|
||||||
font-size: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert_key {
|
|
||||||
color: #252525;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
margin-top: 1.33rem;
|
|
||||||
background-color: #ffffff;
|
|
||||||
|
|
||||||
.timeline {
|
|
||||||
|
|
||||||
.time {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #0068FF;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bulletin {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #252525;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.ant-card-head {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user