fix: Update volume type hint when create volume by snapshot
1. Auto select correct volume type when change snapshot 2. Show confirm modal when first change volume type used by snapshot Change-Id: I37a70414e835c8c187ce5edd858b83c2273d5ca8
This commit is contained in:
parent
f1c3df26a4
commit
d422bd59aa
@ -125,7 +125,18 @@ export default class SelectTable extends React.Component {
|
||||
this.sortOrder = props.defaultSortOrder;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!isEqual(prevProps.backendPageStore, this.props.backendPageStore)) {
|
||||
this.getData();
|
||||
}
|
||||
const { selectedRowKeys: newKeys } = this.state;
|
||||
const { selectedRowKeys: oldKeys } = prevState;
|
||||
if (!isEqual(newKeys, oldKeys)) {
|
||||
this.onChange({ selectedRowKeys: newKeys });
|
||||
}
|
||||
}
|
||||
|
||||
getData() {
|
||||
const { backendPageStore, pageSize } = this.props;
|
||||
if (backendPageStore) {
|
||||
this.handleFooterPaginationChange(1, pageSize);
|
||||
@ -343,15 +354,10 @@ export default class SelectTable extends React.Component {
|
||||
handleSelectRow = (selectedRowKeys) => {
|
||||
const newKeys = this.getRealSelectedKeys(selectedRowKeys);
|
||||
const selectedRows = this.getSelectedRows(newKeys);
|
||||
this.setState(
|
||||
{
|
||||
selectedRowKeys: newKeys,
|
||||
selectedRows,
|
||||
},
|
||||
() => {
|
||||
this.onChange({ selectedRowKeys: newKeys });
|
||||
}
|
||||
);
|
||||
this.setState({
|
||||
selectedRowKeys: newKeys,
|
||||
selectedRows,
|
||||
});
|
||||
};
|
||||
|
||||
handleFilterInput = (tags) => {
|
||||
@ -560,15 +566,10 @@ export default class SelectTable extends React.Component {
|
||||
const { selectedRowKeys } = this.state;
|
||||
const newKeys = selectedRowKeys.filter((it) => it !== getItemKey(item));
|
||||
const selectedRows = this.getSelectedRows(newKeys);
|
||||
this.setState(
|
||||
{
|
||||
selectedRowKeys: newKeys,
|
||||
selectedRows,
|
||||
},
|
||||
() => {
|
||||
this.onChange({ selectedRowKeys: newKeys });
|
||||
}
|
||||
);
|
||||
this.setState({
|
||||
selectedRowKeys: newKeys,
|
||||
selectedRows,
|
||||
});
|
||||
};
|
||||
|
||||
initTabChange() {
|
||||
|
@ -741,6 +741,7 @@
|
||||
"If no gateway is specified, the first IP address will be defaulted.": "If no gateway is specified, the first IP address will be defaulted.",
|
||||
"If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.": "If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.",
|
||||
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.",
|
||||
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).",
|
||||
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project",
|
||||
"If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.": "If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.",
|
||||
"If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting, or create a snapshot for instance.": "If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting, or create a snapshot for instance.",
|
||||
@ -1022,6 +1023,7 @@
|
||||
"Not select": "Not select",
|
||||
"Not yet bound": "Not yet bound",
|
||||
"Not yet selected": "Not yet selected",
|
||||
"Note: Are you sure you need to modify the volume type?": "Note: Are you sure you need to modify the volume type?",
|
||||
"Note: The security group you use will act on all virtual adapters of the instance.": "Note: The security group you use will act on all virtual adapters of the instance.",
|
||||
"Number Of Ports": "Number Of Ports",
|
||||
"Number of GPU": "Number of GPU",
|
||||
@ -1547,6 +1549,7 @@
|
||||
"The user has been disabled, please contact the administrator": "The user has been disabled, please contact the administrator",
|
||||
"The user needs to ensure that the input is a shell script that can run completely and normally.": "The user needs to ensure that the input is a shell script that can run completely and normally.",
|
||||
"The volume associated with the backup is not available, unable to restore.": "The volume associated with the backup is not available, unable to restore.",
|
||||
"The volume type needs to be consistent with the volume type when the snapshot is created.": "The volume type needs to be consistent with the volume type when the snapshot is created.",
|
||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.",
|
||||
"The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.",
|
||||
"The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.",
|
||||
|
@ -741,6 +741,7 @@
|
||||
"If no gateway is specified, the first IP address will be defaulted.": "如果不指定网关IP,默认是第一个地址。",
|
||||
"If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.": "如果计算节点上的nova-compute被禁用,将禁止其作为目标节点。",
|
||||
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "如果云硬盘容量较大,修改云硬盘类型可能需要花费几个小时,请您谨慎操作。",
|
||||
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "若快照关联的云硬盘修改过云硬盘类型,请手动修改此选项;若快照关联的云硬盘保持云硬盘类型不变,请忽略此选项(不需要做变更)。",
|
||||
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "您未被授权访问任何项目,或您参与中的项目已被删除或禁用,可联系平台管理员重新分配项目",
|
||||
"If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.": "如不填写cpus、memory_mb、local_gb、cpu_arch等参数,您可以通过执行“自动检测”操作来自动注入物理机的配置和 Mac 地址。",
|
||||
"If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting, or create a snapshot for instance.": "如果您仍想保留云硬盘数据,建议您在删除之前为云硬盘创建快照,或者为云主机创建快照。",
|
||||
@ -1022,6 +1023,7 @@
|
||||
"Not select": "不选择",
|
||||
"Not yet bound": "尚未绑定",
|
||||
"Not yet selected": "尚未选择",
|
||||
"Note: Are you sure you need to modify the volume type?": "注意:确定需要修改云硬盘类型?",
|
||||
"Note: The security group you use will act on all virtual adapters of the instance.": "注:您所用的安全组将作用于云主机的全部虚拟网卡。",
|
||||
"Number Of Ports": "端口数量",
|
||||
"Number of GPU": "GPU数量",
|
||||
@ -1547,6 +1549,7 @@
|
||||
"The user has been disabled, please contact the administrator": "",
|
||||
"The user needs to ensure that the input is a shell script that can run completely and normally.": "请确保输入的是能完整正常运行的 shell 脚本。",
|
||||
"The volume associated with the backup is not available, unable to restore.": "云硬盘不处于可用状态,不支持恢复备份操作。",
|
||||
"The volume type needs to be consistent with the volume type when the snapshot is created.": "创建云硬盘的云硬盘类型需要和创建快照时间点的云硬盘类型保持一致。",
|
||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "云硬盘类型需在元数据中设置\"multiattach\",才可支持共享盘属性。",
|
||||
"The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "{action}指令已下发,实例名称:{name}。 \n 您可等待几秒关注列表数据的变更或是手动刷新数据,以获取最终展示结果。",
|
||||
"The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "{action}指令已下发。 \n 您可等待几秒关注列表数据的变更或是手动刷新数据,以获取最终展示结果。",
|
||||
|
@ -14,8 +14,9 @@
|
||||
|
||||
import React from 'react';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import Confirm from 'components/Confirm';
|
||||
import { getSinceTime } from 'utils/time';
|
||||
import { volumeStatus, multiTip } from 'resources/volume';
|
||||
import { volumeStatus, multiTip, snapshotTypeTip } from 'resources/volume';
|
||||
import globalSnapshotStore from 'stores/cinder/snapshot';
|
||||
import globalImageStore from 'stores/glance/image';
|
||||
import globalVolumeStore from 'stores/cinder/volume';
|
||||
@ -53,6 +54,7 @@ export default class Create extends FormAction {
|
||||
...this.state,
|
||||
count: 1,
|
||||
sharedDisabled: false,
|
||||
confirmCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@ -142,7 +144,7 @@ export default class Create extends FormAction {
|
||||
}
|
||||
|
||||
get volumeTypes() {
|
||||
return this.volumeTypeStore.list.data || [];
|
||||
return toJS(this.volumeTypeStore.list.data || []);
|
||||
}
|
||||
|
||||
get backups() {
|
||||
@ -225,22 +227,54 @@ export default class Create extends FormAction {
|
||||
}
|
||||
|
||||
getVolumeTypeExtra() {
|
||||
if (this.sourceTypeIsSnapshot) {
|
||||
return snapshotTypeTip;
|
||||
}
|
||||
const { multiattach = false } = this.state;
|
||||
return multiattach ? multiTip : undefined;
|
||||
}
|
||||
|
||||
onConfirmCancel = () => {
|
||||
const { initVolumeType } = this.state;
|
||||
const { selectedRows, selectedRowKeys, snapshotId } = initVolumeType;
|
||||
const newValue = {
|
||||
selectedRows,
|
||||
selectedRowKeys,
|
||||
snapshotId: `${snapshotId}-1`,
|
||||
};
|
||||
this.setState({
|
||||
initVolumeType: newValue,
|
||||
});
|
||||
};
|
||||
|
||||
onVolumeTypeChange = (value) => {
|
||||
const { selectedRows = [] } = value;
|
||||
if (selectedRows.length > 0) {
|
||||
const { extra_specs: { multiattach = 'False' } = {} } = selectedRows[0];
|
||||
this.setState({
|
||||
multiattach: multiattach === '<is> True',
|
||||
});
|
||||
} else {
|
||||
if (selectedRows.length === 0) {
|
||||
this.setState({
|
||||
multiattach: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { id, extra_specs: { multiattach = 'False' } = {} } = selectedRows[0];
|
||||
if (this.sourceTypeIsSnapshot) {
|
||||
const {
|
||||
initVolumeType: { selectedRowKeys = [] },
|
||||
confirmCount = 0,
|
||||
} = this.state;
|
||||
if (id !== selectedRowKeys[0] && confirmCount < 1) {
|
||||
Confirm.warn({
|
||||
title: t('Note: Are you sure you need to modify the volume type?'),
|
||||
content: snapshotTypeTip,
|
||||
onCancel: this.onConfirmCancel,
|
||||
});
|
||||
this.setState({
|
||||
confirmCount: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
multiattach: multiattach === '<is> True',
|
||||
});
|
||||
};
|
||||
|
||||
get sourceTypeIsImage() {
|
||||
@ -266,16 +300,34 @@ export default class Create extends FormAction {
|
||||
return Math.max(imageSize, 1);
|
||||
}
|
||||
|
||||
onSnapshotChange = (value) => {
|
||||
const { selectedRows = [] } = value || {};
|
||||
if (selectedRows.length) {
|
||||
const { origin_data: { volume_type_id } = {}, id } =
|
||||
selectedRows[0] || {};
|
||||
const volumeType = this.volumeTypes.find(
|
||||
(it) => it.id === volume_type_id
|
||||
);
|
||||
if (volumeType) {
|
||||
const newValue = {
|
||||
selectedRowKeys: [volume_type_id],
|
||||
selectedRows: [volumeType],
|
||||
snapshotId: id,
|
||||
};
|
||||
this.setState({
|
||||
initVolumeType: newValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
get nameForStateUpdate() {
|
||||
return ['source', 'image', 'snapshot'];
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
const { source, initVolumeType } = this.state;
|
||||
const sourceTypesIsImage = source === this.sourceTypes[1].value;
|
||||
const sourceTypeIsSnapshot = source === this.sourceTypes[2].value;
|
||||
const { initVolumeType } = this.state;
|
||||
const minSize = this.getDiskMinSize();
|
||||
// const sourceTypeIsBackup = source === this.sourceTypes[3].value;
|
||||
return [
|
||||
{
|
||||
name: 'project',
|
||||
@ -308,9 +360,9 @@ export default class Create extends FormAction {
|
||||
label: t('Operating System'),
|
||||
type: 'select-table',
|
||||
datas: this.images,
|
||||
required: sourceTypesIsImage,
|
||||
required: this.sourceTypeIsImage,
|
||||
isMulti: false,
|
||||
hidden: !sourceTypesIsImage,
|
||||
hidden: !this.sourceTypeIsImage,
|
||||
filterParams: [
|
||||
{
|
||||
label: t('Name'),
|
||||
@ -328,12 +380,13 @@ export default class Create extends FormAction {
|
||||
label: t('Snapshot'),
|
||||
type: 'select-table',
|
||||
backendPageStore: this.snapshotStore,
|
||||
required: sourceTypeIsSnapshot,
|
||||
required: this.sourceTypeIsSnapshot,
|
||||
isMulti: false,
|
||||
hidden: !sourceTypeIsSnapshot,
|
||||
hidden: !this.sourceTypeIsSnapshot,
|
||||
isSortByBack: true,
|
||||
defaultSortKey: 'created_at',
|
||||
defaultSortOrder: 'descend',
|
||||
onChange: this.onSnapshotChange,
|
||||
filterParams: [
|
||||
{
|
||||
label: t('Name'),
|
||||
|
@ -212,3 +212,18 @@ export const volumeSelectTablePropsBackend = {
|
||||
filterParams: volumeFilters,
|
||||
columns: volumeColumns,
|
||||
};
|
||||
|
||||
export const snapshotTypeTip = (
|
||||
<>
|
||||
<p style={{ marginTop: 10 }}>
|
||||
{t(
|
||||
'The volume type needs to be consistent with the volume type when the snapshot is created.'
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{t(
|
||||
'If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).'
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user