Merge "fix: fix some resource items to select-table"

This commit is contained in:
Zuul 2022-07-06 14:06:01 +00:00 committed by Gerrit Code Review
commit 1170f73dd5
4 changed files with 230 additions and 90 deletions

View File

@ -83,6 +83,7 @@ export default class SelectTable extends React.Component {
defaultSortOrder: PropTypes.string, defaultSortOrder: PropTypes.string,
onRow: PropTypes.func, onRow: PropTypes.func,
childrenColumnName: PropTypes.string, childrenColumnName: PropTypes.string,
imageTabAuto: PropTypes.bool,
}; };
static defaultProps = { static defaultProps = {
@ -107,6 +108,7 @@ export default class SelectTable extends React.Component {
defaultSortKey: '', defaultSortKey: '',
defaultSortOrder: '', defaultSortOrder: '',
childrenColumnName: 'children', childrenColumnName: 'children',
imageTabAuto: false,
}; };
constructor(props) { constructor(props) {
@ -706,12 +708,16 @@ export default class SelectTable extends React.Component {
} }
renderImageTabs() { renderImageTabs() {
const { tabs, defaultTabValue } = this.props; const { tabs, defaultTabValue, imageTabAuto } = this.props;
const { tab } = this.state; const { tab } = this.state;
const items = tabs.map((it) => { const items = tabs.map((it) => {
const { value, image, component, label } = it; const { value, image, component, label } = it;
return ( return (
<Radio.Button className={styles['image-tab']} value={value} key={value}> <Radio.Button
className={imageTabAuto ? '' : styles['image-tab']}
value={value}
key={value}
>
{image && <img src={image} alt={label} />} {image && <img src={image} alt={label} />}
{component} {component}
<span className={styles['image-tab-label']}>{label}</span> <span className={styles['image-tab-label']}>{label}</span>

View File

@ -12,14 +12,19 @@
// 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 Base from 'components/Form'; import Base from 'components/Form';
import { inject, observer } from 'mobx-react'; import { inject, observer } from 'mobx-react';
import globalNetworkStore from 'src/stores/neutron/network'; import { NetworkStore } from 'src/stores/neutron/network';
import globalSubnetStore from 'src/stores/neutron/subnet'; import { SubnetStore } from 'src/stores/neutron/subnet';
import { getLinkRender } from 'utils/route-map';
import { networkColumns } from 'resources/neutron/network';
export class StepNetwork extends Base { export class StepNetwork extends Base {
async init() { async init() {
this.getNetworkList(); this.externalNetworkStore = new NetworkStore();
this.privateNetworkStore = new NetworkStore();
this.subnetNetworkStore = new SubnetStore();
this.getSubnetList(); this.getSubnetList();
} }
@ -39,48 +44,16 @@ export class StepNetwork extends Base {
return !!this.props.extra; return !!this.props.extra;
} }
async getNetworkList() {
await globalNetworkStore.fetchList();
}
get externalNetworks() {
return (globalNetworkStore.list.data || [])
.filter(
(it) =>
it['router:external'] === true &&
it.project_id === this.currentProjectId
)
.map((it) => ({
value: it.id,
label: it.name,
}));
}
get privateNetworks() {
return (globalNetworkStore.list.data || [])
.filter(
(it) =>
it['router:external'] === false &&
it.project_id === this.currentProjectId
)
.map((it) => ({
value: it.id,
label: it.name,
}));
}
async getSubnetList() { async getSubnetList() {
await globalSubnetStore.fetchList(); await this.subnetNetworkStore.fetchList();
this.updateDefaultValue();
} }
get subnetList() { get subnetList() {
const { fixed_network } = this.state; const { fixedNetwork: { selectedRowKeys = [] } = {} } = this.state;
return (globalSubnetStore.list.data || []) return (this.subnetNetworkStore.list.data || []).filter(
.filter((it) => fixed_network === it.network_id) (it) => selectedRowKeys[0] === it.network_id
.map((it) => ({ );
value: it.id,
label: it.name,
}));
} }
get networkDrivers() { get networkDrivers() {
@ -103,7 +76,7 @@ export class StepNetwork extends Base {
} }
get nameForStateUpdate() { get nameForStateUpdate() {
return ['fixed_network']; return ['fixedNetwork'];
} }
get defaultValue() { get defaultValue() {
@ -129,19 +102,40 @@ export class StepNetwork extends Base {
http_proxy, http_proxy,
https_proxy, https_proxy,
no_proxy, no_proxy,
external_network_id, externalNetwork: {
selectedRowKeys: [external_network_id],
},
fixed_network, fixed_network,
fixed_subnet, fixed_subnet,
dns_nameserver, dns_nameserver,
master_lb_enabled, master_lb_enabled,
floating_ip_enabled, floating_ip_enabled,
}; };
if (fixed_network) {
values.fixedNetwork = {
selectedRowKeys: [fixed_network],
};
}
if (fixed_subnet) {
const { subnetInitValue } = this.state;
if (subnetInitValue) {
values.fixedSubnet = subnetInitValue;
} else {
values.fixedSubnet = {
selectedRowKeys: [fixed_subnet],
};
}
}
} }
return values; return values;
} }
get formItems() { get formItems() {
const { extra: { network_driver } = {} } = this.props; const { extra: { network_driver } = {} } = this.props;
const { subnetInitValue } = this.state;
return [ return [
{ {
name: 'network_driver', name: 'network_driver',
@ -170,30 +164,100 @@ export class StepNetwork extends Base {
type: 'input', type: 'input',
}, },
{ {
name: 'external_network_id', name: 'externalNetwork',
label: t('External Network'), label: t('External Network'),
placeholder: t('Choose a External Network'), type: 'select-table',
type: 'select', backendPageStore: this.externalNetworkStore,
options: this.externalNetworks, extraParams: {
disabled: this.isEdit, 'router:external': true,
project_id: this.currentProjectId,
},
required: true, required: true,
loading: this.externalNetworkStore.list.isLoading,
filterParams: [
{
label: t('Name'),
name: 'name',
},
],
columns: networkColumns(this),
}, },
{ {
name: 'fixed_network', name: 'fixedNetwork',
label: t('Fixed Network'), label: t('Fixed Network'),
placeholder: t('Choose a Private Network'), type: 'select-table',
type: 'select', backendPageStore: this.privateNetworkStore,
options: this.privateNetworks, extraParams: {
onChange: () => { 'router:external': false,
this.updateFormValue('fixed_subnet', null); project_id: this.currentProjectId,
},
loading: this.privateNetworkStore.list.isLoading,
header: (
<div>
{t(' You can go to the console to ')}
{getLinkRender({
key: 'network',
value: `${t('create a new network/subnet')} > `,
})}
</div>
),
filterParams: [
{
label: t('Name'),
name: 'name',
},
],
columns: networkColumns(this),
onChange: (value) => {
this.setState(
{
fixedNetwork: value,
subnetInitValue: {
selectedRowKeys: [],
selectedRows: [],
},
},
() => {
this.formRef.current.resetFields(['fixedSubnet']);
}
);
}, },
}, },
{ {
name: 'fixed_subnet', name: 'fixedSubnet',
label: t('Fixed Subnet'), label: t('Fixed Subnet'),
placeholder: t('Choose a Private Network at first'), type: 'select-table',
type: 'select', data: this.subnetList,
options: this.subnetList, initValue: subnetInitValue,
filterParams: [
{
label: t('Name'),
name: 'name',
},
],
columns: [
{
title: t('Name'),
dataIndex: 'name',
},
{
title: t('CIDR'),
dataIndex: 'cidr',
},
{
title: t('Gateway IP'),
dataIndex: 'gateway_ip',
},
{
title: t('IP Version'),
dataIndex: 'ip_version',
},
{
title: t('Created At'),
dataIndex: 'created_at',
valueRender: 'toLocalTime',
},
],
}, },
{ {
name: 'dns_nameserver', name: 'dns_nameserver',

View File

@ -12,17 +12,21 @@
// 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 { inject, observer } from 'mobx-react';
import Base from 'components/Form';
import globalImageStore from 'src/stores/glance/image'; import globalImageStore from 'src/stores/glance/image';
import globalKeypairStore from 'src/stores/nova/keypair'; import globalKeypairStore from 'src/stores/nova/keypair';
import Base from 'components/Form';
import { inject, observer } from 'mobx-react';
import React from 'react';
import FlavorSelectTable from 'src/pages/compute/containers/Instance/components/FlavorSelectTable'; import FlavorSelectTable from 'src/pages/compute/containers/Instance/components/FlavorSelectTable';
import {
getImageColumns,
getImageSystemTabs,
getImageOS,
} from 'resources/glance/image';
export class StepNodeSpec extends Base { export class StepNodeSpec extends Base {
init() { init() {
this.getImageList(); this.getImageList();
this.getKeypairsList();
} }
get title() { get title() {
@ -43,9 +47,10 @@ export class StepNodeSpec extends Base {
async getImageList() { async getImageList() {
await globalImageStore.fetchList(); await globalImageStore.fetchList();
this.updateDefaultValue();
} }
get imageList() { get acceptedImageOs() {
const { context: { coe = '' } = {} } = this.props; const { context: { coe = '' } = {} } = this.props;
let acceptedOs = []; let acceptedOs = [];
if (coe === 'kubernetes') { if (coe === 'kubernetes') {
@ -55,28 +60,33 @@ export class StepNodeSpec extends Base {
} else if (['mesos', 'dcos'].includes(coe)) { } else if (['mesos', 'dcos'].includes(coe)) {
acceptedOs = ['ubuntu']; acceptedOs = ['ubuntu'];
} }
return acceptedOs;
}
get imageColumns() {
return getImageColumns(this);
}
get systemTabs() {
const imageTabs = getImageSystemTabs();
return imageTabs.filter((it) => this.acceptedImageOs.includes(it.value));
}
onImageTabChange = (value) => {
this.setState({
imageTab: value,
});
};
get imageList() {
const { imageTab } = this.state;
return (globalImageStore.list.data || []) return (globalImageStore.list.data || [])
.filter( .filter(
(it) => (it) =>
it.owner === this.currentProjectId && it.owner === this.currentProjectId &&
acceptedOs.includes(it.os_distro) this.acceptedImageOs.includes(it.os_distro)
) )
.map((it) => ({ .filter((it) => getImageOS(it) === imageTab);
value: it.id,
label: it.name,
}));
}
async getKeypairsList() {
await globalKeypairStore.fetchList();
}
get keypairsList() {
return (globalKeypairStore.list.data || []).map((it) => ({
value: it.name,
label: it.name,
}));
} }
get volumeDrivers() { get volumeDrivers() {
@ -112,8 +122,6 @@ export class StepNodeSpec extends Base {
} = {}, } = {},
} = this.props; } = this.props;
values = { values = {
image_id,
keypair_id,
volume_driver, volume_driver,
docker_storage_driver, docker_storage_driver,
docker_volume_size, docker_volume_size,
@ -124,6 +132,12 @@ export class StepNodeSpec extends Base {
if (master_flavor_id) { if (master_flavor_id) {
values.masterFlavor = { selectedRowKeys: [master_flavor_id] }; values.masterFlavor = { selectedRowKeys: [master_flavor_id] };
} }
if (image_id) {
values.images = { selectedRowKeys: [image_id] };
}
if (keypair_id) {
values.keypairs = { selectedRowKeys: [keypair_id] };
}
} }
return values; return values;
} }
@ -140,17 +154,49 @@ export class StepNodeSpec extends Base {
get formItems() { get formItems() {
return [ return [
{ {
name: 'image_id', name: 'images',
label: t('Image'), label: t('Image'),
type: 'select', type: 'select-table',
options: this.imageList, data: this.imageList,
required: true, required: true,
isLoading: globalImageStore.list.isLoading,
filterParams: [
{
label: t('Name'),
name: 'name',
},
],
columns: this.imageColumns,
tabs: this.systemTabs,
defaultTabValue: this.systemTabs[0].value,
onTabChange: this.onImageTabChange,
imageTabAuto: true,
}, },
{ {
name: 'keypair_id', name: 'keypairs',
label: t('Keypair'), label: t('Keypair'),
type: 'select', type: 'select-table',
options: this.keypairsList, data: this.keypairsList,
isLoading: globalKeypairStore.list.isLoading,
tip: t(
'The SSH key is a way to remotely log in to the instance. The cloud platform only helps to keep the public key. Please keep your private key properly.'
),
filterParams: [
{
label: t('Name'),
name: 'name',
},
],
columns: [
{
title: t('Name'),
dataIndex: 'name',
},
{
title: t('Fingerprint'),
dataIndex: 'fingerprint',
},
],
}, },
{ {
name: 'flavor', name: 'flavor',
@ -197,6 +243,7 @@ export class StepNodeSpec extends Base {
label: t('Docker Volume Size (GiB)'), label: t('Docker Volume Size (GiB)'),
type: 'input-int', type: 'input-int',
min: this.minVolumeSize, min: this.minVolumeSize,
required: this.minVolumeSize === 3,
placeholder: t('Spec'), placeholder: t('Spec'),
validator: (rule, value) => { validator: (rule, value) => {
if ( if (

View File

@ -93,7 +93,17 @@ export class StepCreate extends StepAction {
} }
onSubmit = (values) => { onSubmit = (values) => {
const { flavor, masterFlavor, additionalLabels, ...rest } = values; const {
flavor,
masterFlavor,
additionalLabels,
images,
keypairs,
externalNetwork,
fixedNetwork,
fixedSubnet,
...rest
} = values;
const requestLabels = {}; const requestLabels = {};
if (additionalLabels) { if (additionalLabels) {
additionalLabels.forEach((item) => { additionalLabels.forEach((item) => {
@ -105,6 +115,7 @@ export class StepCreate extends StepAction {
const body = { const body = {
labels: requestLabels, labels: requestLabels,
external_network_id: externalNetwork.selectedRowKeys[0],
...rest, ...rest,
}; };
if (flavor) { if (flavor) {
@ -113,6 +124,18 @@ export class StepCreate extends StepAction {
if (masterFlavor) { if (masterFlavor) {
body.master_flavor_id = masterFlavor.selectedRowKeys[0]; body.master_flavor_id = masterFlavor.selectedRowKeys[0];
} }
if (images) {
body.image_id = images.selectedRowKeys[0];
}
if (keypairs) {
body.keypair_id = keypairs.selectedRowKeys[0];
}
if (fixedNetwork) {
body.fixed_network = fixedNetwork.selectedRowKeys[0];
}
if (fixedSubnet) {
body.fixed_subnet = fixedSubnet.selectedRowKeys[0];
}
if (this.isEdit) { if (this.isEdit) {
return this.store.update({ id: this.params.id }, body); return this.store.update({ id: this.params.id }, body);
} }