feat: support fuzzy query port when create port forwarding
1. Support fuzzy query port by name/fixed ip/server name when create/edit port forwarding and floating ip associate port: the API filtering method is used to filter data precisely. It is changed to: After the front-end obtains all data, it filters data based on the input content. 2. Add port status filter when create/edit port forwarding 3. Fix the port forwarding display in the floating ip list page: when the number of port forwardings is less than the page size(10), the list will not show the pagination. Change-Id: Iea0d19db42de2557167c444ad9454d6b8300795e
This commit is contained in:
parent
07d6a51bf2
commit
5d457caf83
@ -17,8 +17,12 @@ import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import { isNull, isObject } from 'lodash';
|
||||
import { getCanReachSubnetIdsWithRouterIdInComponent } from 'resources/neutron/router';
|
||||
import { PortStore } from 'stores/neutron/port';
|
||||
import { getPortFormItem, getPortsAndReasons } from 'resources/neutron/port';
|
||||
import { PortStore } from 'stores/neutron/port-extension';
|
||||
import {
|
||||
getPortFormItem,
|
||||
getPortsAndReasons,
|
||||
getPortsForPortFormItem,
|
||||
} from 'resources/neutron/port';
|
||||
import { getInterfaceWithReason } from 'resources/neutron/floatingip';
|
||||
import globalPortForwardingStore from 'stores/neutron/port-forwarding';
|
||||
import { enablePFW } from 'resources/neutron/neutron';
|
||||
@ -53,6 +57,7 @@ export class CreatePortForwarding extends ModalAction {
|
||||
routerIdWithExternalNetworkInfo: [],
|
||||
supportRange: true,
|
||||
};
|
||||
this.getPorts();
|
||||
this.getRangeSupport();
|
||||
this.getFipAlreadyUsedPorts();
|
||||
getCanReachSubnetIdsWithRouterIdInComponent.call(this, (router) => {
|
||||
@ -155,6 +160,14 @@ export class CreatePortForwarding extends ModalAction {
|
||||
return ['protocol'];
|
||||
}
|
||||
|
||||
get portDeviceOwner() {
|
||||
return ['compute:nova', ''];
|
||||
}
|
||||
|
||||
getPorts() {
|
||||
getPortsForPortFormItem.call(this, this.portDeviceOwner);
|
||||
}
|
||||
|
||||
async getRangeSupport() {
|
||||
try {
|
||||
await globalPortForwardingStore.fetchListByPage({
|
||||
@ -565,10 +578,7 @@ export class CreatePortForwarding extends ModalAction {
|
||||
extra: internalPortExtra,
|
||||
},
|
||||
];
|
||||
const [virtualAdapterItem, fixedIpItem] = getPortFormItem.call(this, [
|
||||
'compute:nova',
|
||||
'',
|
||||
]);
|
||||
const [virtualAdapterItem, fixedIpItem] = getPortFormItem.call(this);
|
||||
virtualAdapterItem.label = t('Target Port');
|
||||
fixedIpItem.label = t('Target IP Address');
|
||||
fixedIpItem.onChange = this.onFixedIpChange;
|
||||
|
@ -14,10 +14,14 @@
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import globalPortForwardingStore from 'stores/neutron/port-forwarding';
|
||||
import globalPortStore, { PortStore } from 'stores/neutron/port';
|
||||
import globalPortStore, { PortStore } from 'stores/neutron/port-extension';
|
||||
import { getCanReachSubnetIdsWithRouterIdInComponent } from 'resources/neutron/router';
|
||||
import { getInterfaceWithReason } from 'resources/neutron/floatingip';
|
||||
import { getPortFormItem, getPortsAndReasons } from 'resources/neutron/port';
|
||||
import {
|
||||
getPortFormItem,
|
||||
getPortsAndReasons,
|
||||
getPortsForPortFormItem,
|
||||
} from 'resources/neutron/port';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
|
||||
export class Edit extends ModalAction {
|
||||
@ -45,6 +49,7 @@ export class Edit extends ModalAction {
|
||||
this.getInitialPortFixedIPs();
|
||||
});
|
||||
this.getFipAlreadyUsedPorts();
|
||||
this.getPorts();
|
||||
this.state = {
|
||||
alreadyUsedPorts: [],
|
||||
instanceFixedIPs: [],
|
||||
@ -54,6 +59,14 @@ export class Edit extends ModalAction {
|
||||
};
|
||||
}
|
||||
|
||||
get portDeviceOwner() {
|
||||
return ['compute:nova', ''];
|
||||
}
|
||||
|
||||
getPorts() {
|
||||
getPortsForPortFormItem.call(this, this.portDeviceOwner);
|
||||
}
|
||||
|
||||
async getFipAlreadyUsedPorts() {
|
||||
const detail = await globalPortForwardingStore.fetchList({
|
||||
fipId: this.item.fip.id,
|
||||
@ -296,7 +309,7 @@ export class Edit extends ModalAction {
|
||||
},
|
||||
},
|
||||
];
|
||||
const extraColumn = getPortFormItem.call(this, ['compute:nova', '']);
|
||||
const extraColumn = getPortFormItem.call(this);
|
||||
const portIndex = extraColumn.findIndex(
|
||||
(i) => i.name === 'virtual_adapter'
|
||||
);
|
||||
|
@ -26,7 +26,11 @@ import {
|
||||
import globalFloatingIpsStore from 'stores/neutron/floatingIp';
|
||||
import { PortStore } from 'stores/neutron/port';
|
||||
import { instanceSelectTablePropsBackend } from 'resources/nova/instance';
|
||||
import { getPortFormItem, getPortsAndReasons } from 'resources/neutron/port';
|
||||
import {
|
||||
getPortFormItem,
|
||||
getPortsAndReasons,
|
||||
getPortsForPortFormItem,
|
||||
} from 'resources/neutron/port';
|
||||
import {
|
||||
getInterfaceWithReason,
|
||||
disableFIPAssociate,
|
||||
@ -58,6 +62,7 @@ export class Associate extends ModalAction {
|
||||
canReachSubnetIdsWithRouterId: [],
|
||||
routerIdWithExternalNetworkInfo: [],
|
||||
};
|
||||
this.getPorts();
|
||||
}
|
||||
|
||||
get instanceName() {
|
||||
@ -106,6 +111,14 @@ export class Associate extends ModalAction {
|
||||
return value;
|
||||
}
|
||||
|
||||
get portDeviceOwner() {
|
||||
return [''];
|
||||
}
|
||||
|
||||
getPorts() {
|
||||
getPortsForPortFormItem.call(this, this.portDeviceOwner);
|
||||
}
|
||||
|
||||
onValuesChange = (changedFields) => {
|
||||
if (has(changedFields, 'resourceType')) {
|
||||
const { resourceType } = changedFields;
|
||||
@ -391,7 +404,7 @@ export class Associate extends ModalAction {
|
||||
);
|
||||
break;
|
||||
case 'port':
|
||||
ret.push(...getPortFormItem.call(this, ['']));
|
||||
ret.push(...getPortFormItem.call(this, false));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -183,8 +183,7 @@ export class FloatingIps extends Base {
|
||||
return null;
|
||||
}
|
||||
const pageSize = 10;
|
||||
const zeroLength =
|
||||
length > pageSize ? pageSize - (length % pageSize) : pageSize;
|
||||
const zeroLength = length > pageSize ? pageSize - (length % pageSize) : 0;
|
||||
const zeroData = Array.from({ length: zeroLength }, (i) => ({
|
||||
key: `zero-${i}`,
|
||||
}));
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { ipValidate } from 'utils/validate';
|
||||
import { getOptions } from 'utils/index';
|
||||
|
||||
const { isIPv4 } = ipValidate;
|
||||
|
||||
@ -83,8 +84,102 @@ export function getPortsAndReasons(
|
||||
});
|
||||
}
|
||||
|
||||
export function getPortFormItem(device_owner) {
|
||||
export function getPortsForPortFormItem(device_owner) {
|
||||
this.portStore.fetchList({ device_owner, project_id: this.currentProjectId });
|
||||
}
|
||||
|
||||
export function getPortFormItem(withResourceNameAndStatusFilter = true) {
|
||||
const { portFixedIPs, fixedIpLoading } = this.state;
|
||||
const portFilters = [
|
||||
{
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
{
|
||||
label: t('Fixed IP'),
|
||||
name: 'fixed_ips',
|
||||
filterFunc: (record, val) => {
|
||||
return (record || []).some((it) => it.ip_address.includes(val));
|
||||
},
|
||||
},
|
||||
];
|
||||
if (withResourceNameAndStatusFilter) {
|
||||
portFilters.push(
|
||||
...[
|
||||
{
|
||||
label: t('Bind Resource Name'),
|
||||
name: 'server_name',
|
||||
},
|
||||
{
|
||||
label: t('Status'),
|
||||
name: 'status',
|
||||
options: getOptions(portStatus).filter((it) =>
|
||||
['ACTIVE', 'DOWN'].includes(it.key)
|
||||
),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
const portColumns = [
|
||||
{
|
||||
title: t('ID/Name'),
|
||||
dataIndex: 'name',
|
||||
routeName: this.getRouteName('portDetail'),
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: t('Fixed IPs'),
|
||||
dataIndex: 'fixed_ips',
|
||||
render: (data) => (
|
||||
<>
|
||||
{data.map((d, idx) => (
|
||||
<div key={`ip_address_${idx}`}>{d.ip_address}</div>
|
||||
))}
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'sinceTime',
|
||||
},
|
||||
];
|
||||
if (withResourceNameAndStatusFilter) {
|
||||
const extraColumns = [
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => portStatus[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Bind Resource'),
|
||||
dataIndex: 'server_name',
|
||||
render: (server_name, item) => {
|
||||
const { device_id } = item;
|
||||
if (!device_id) {
|
||||
return '-';
|
||||
}
|
||||
const link = this.getLinkRender(
|
||||
'instanceDetail',
|
||||
device_id,
|
||||
{ id: device_id },
|
||||
{ tab: 'interface' }
|
||||
);
|
||||
return (
|
||||
<>
|
||||
{link}
|
||||
<br />
|
||||
{server_name || '-'}
|
||||
</>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
portColumns.splice(4, 0, ...extraColumns);
|
||||
}
|
||||
return [
|
||||
{
|
||||
name: 'virtual_adapter',
|
||||
@ -92,58 +187,13 @@ export function getPortFormItem(device_owner) {
|
||||
type: 'select-table',
|
||||
required: true,
|
||||
rowKey: 'id',
|
||||
backendPageStore: this.portStore,
|
||||
data: this.portStore.list.data || [],
|
||||
isLoading: this.portStore.list.isLoading,
|
||||
disabledFunc: this.portsDisableFunc,
|
||||
onChange: this.handlePortSelect,
|
||||
extraParams: { device_owner, project_id: this.currentProjectId },
|
||||
isMulti: false,
|
||||
...portSortProps,
|
||||
filterParams: [
|
||||
{
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
{
|
||||
label: t('Fixed IP'),
|
||||
name: 'fixedIP',
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
title: t('ID/Name'),
|
||||
dataIndex: 'name',
|
||||
routeName: this.getRouteName('portDetail'),
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
sorter: false,
|
||||
},
|
||||
{
|
||||
title: t('Fixed IPs'),
|
||||
dataIndex: 'fixed_ips',
|
||||
sorter: false,
|
||||
render: (data) => (
|
||||
<>
|
||||
{data.map((d, idx) => (
|
||||
<div key={`ip_address_${idx}`}>{d.ip_address}</div>
|
||||
))}
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => portStatus[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'sinceTime',
|
||||
isHideable: true,
|
||||
sorter: false,
|
||||
},
|
||||
],
|
||||
filterParams: portFilters,
|
||||
columns: portColumns,
|
||||
},
|
||||
{
|
||||
name: 'fixed_ip_address',
|
||||
|
Loading…
Reference in New Issue
Block a user