fix: show project id and filter data by it

Show project id and filter data by it when create nework,subnet,fip,qos in management platform

Closes-Bug: #2037275
Change-Id: I4e12b423be7662ba83f8efbf55e1b6aa0e31105d
This commit is contained in:
xusongfu 2023-09-25 18:27:22 +08:00
parent 7662ae6a09
commit ec21bd17ab
25 changed files with 279 additions and 93 deletions

View File

@ -166,7 +166,7 @@
} }
.magic-input-checks { .magic-input-checks {
min-width: 120px; min-width: 158px;
margin-left: 8px; margin-left: 8px;
line-height: 32px; line-height: 32px;
} }

View File

@ -56,7 +56,7 @@ export class ManageAccess extends ModalAction {
} }
async getProjects() { async getProjects() {
await this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue(); this.updateDefaultValue();
} }

View File

@ -48,8 +48,9 @@ export class AccessTypeSetting extends Base {
]; ];
} }
getProjects() { async getProjects() {
this.projectStore.fetchList(); this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
} }
get formItems() { get formItems() {

View File

@ -31,7 +31,7 @@ export class CreateForm extends FormAction {
init() { init() {
this.store = globalImageStore; this.store = globalImageStore;
this.projectStore = new ProjectStore(); this.projectStore = new ProjectStore();
this.getProjects(); this.isAdminPage && this.getProjects();
} }
static id = 'image-create'; static id = 'image-create';
@ -72,10 +72,9 @@ export class CreateForm extends FormAction {
return Promise.resolve(true); return Promise.resolve(true);
} }
getProjects() { async getProjects() {
if (this.isAdminPage) { await this.projectStore.fetchProjectsWithDomain();
this.projectStore.fetchList(); this.updateDefaultValue();
}
} }
get projects() { get projects() {

View File

@ -53,7 +53,7 @@ export class ManageAccess extends ModalAction {
} }
async getProjects() { async getProjects() {
await this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue(); this.updateDefaultValue();
} }

View File

@ -257,6 +257,10 @@ export class Instance extends Base {
label: t('Project Name'), label: t('Project Name'),
name: 'project_name', name: 'project_name',
}, },
{
label: t('Project ID'),
name: 'project_id',
},
] ]
: []), : []),
...(this.isAdminPage && !this.inHostDetailPage ...(this.isAdminPage && !this.inHostDetailPage

View File

@ -284,6 +284,10 @@ export class Projects extends Base {
label: t('Project Name'), label: t('Project Name'),
name: 'name', name: 'name',
}, },
{
label: t('Project ID'),
name: 'id',
},
{ {
label: t('Enabled'), label: t('Enabled'),
name: 'enabled', name: 'enabled',

View File

@ -21,6 +21,10 @@ import parsePhoneNumberFromString from 'libphonenumber-js';
export class EditForm extends ModalAction { export class EditForm extends ModalAction {
init() { init() {
this.store = globalUserStore; this.store = globalUserStore;
const {
list: { data },
} = this.store;
data.length === 0 && this.store.fetchList();
} }
static id = 'user-edit'; static id = 'user-edit';

View File

@ -22,6 +22,9 @@ import globalSubnetStore from 'stores/neutron/subnet';
import { QoSPolicyStore } from 'stores/neutron/qos-policy'; import { QoSPolicyStore } from 'stores/neutron/qos-policy';
import { getQoSPolicyTabs } from 'resources/neutron/qos-policy'; import { getQoSPolicyTabs } from 'resources/neutron/qos-policy';
import { qosEndpoint } from 'client/client/constants'; import { qosEndpoint } from 'client/client/constants';
import { projectTableOptions } from 'resources/keystone/project';
import { isAdminPage } from 'utils';
import { toJS } from 'mobx';
export class Allocate extends ModalAction { export class Allocate extends ModalAction {
static id = 'allocate'; static id = 'allocate';
@ -33,11 +36,12 @@ export class Allocate extends ModalAction {
} }
static get modalSize() { static get modalSize() {
return qosEndpoint() ? 'large' : 'small'; const { pathname } = window.location;
return qosEndpoint() || isAdminPage(pathname) ? 'large' : 'small';
} }
getModalSize() { getModalSize() {
return qosEndpoint() ? 'large' : 'small'; return qosEndpoint() || this.isAdminPage ? 'large' : 'small';
} }
get qosEndpoint() { get qosEndpoint() {
@ -63,10 +67,15 @@ export class Allocate extends ModalAction {
maxCount: 2, maxCount: 2,
}; };
this.getExternalNetworks(); this.getExternalNetworks();
this.isAdminPage && globalProjectStore.fetchList(); this.isAdminPage && this.fetchProjectList();
this.getQuota(); this.getQuota();
} }
async fetchProjectList() {
await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
}
async getExternalNetworks() { async getExternalNetworks() {
const networks = await this.networkStore.pureFetchList({ const networks = await this.networkStore.pureFetchList({
'router:external': true, 'router:external': true,
@ -80,6 +89,10 @@ export class Allocate extends ModalAction {
return false; return false;
} }
get projects() {
return toJS(this.projectStore.list.data) || [];
}
static policy = 'create_floatingip'; static policy = 'create_floatingip';
static allowed = () => Promise.resolve(true); static allowed = () => Promise.resolve(true);
@ -151,10 +164,15 @@ export class Allocate extends ModalAction {
} }
get defaultValue() { get defaultValue() {
return { const values = {
project_id: this.currentProjectId,
count: 2, count: 2,
}; };
if (this.isAdminPage) {
values.project_id = {
selectedRowKeys: [this.currentProjectId],
};
}
return values;
} }
handleNetworkChange = async (networkId) => { handleNetworkChange = async (networkId) => {
@ -181,7 +199,14 @@ export class Allocate extends ModalAction {
}); });
}; };
onSubmit = ({ subnet_id, batch_allocate, count, qos_policy_id, ...rest }) => { onSubmit = ({
subnet_id,
batch_allocate,
count,
qos_policy_id,
project_id,
...rest
}) => {
const data = rest; const data = rest;
if (subnet_id) { if (subnet_id) {
data.subnet_id = subnet_id.value; data.subnet_id = subnet_id.value;
@ -197,7 +222,12 @@ export class Allocate extends ModalAction {
} }
return Promise.all(promises); return Promise.all(promises);
} }
return this.store.create(data); return this.store.create({
...data,
project_id: project_id
? project_id.selectedRowKeys[0]
: this.currentProjectId,
});
}; };
onCountChange = (value) => { onCountChange = (value) => {
@ -207,9 +237,10 @@ export class Allocate extends ModalAction {
}; };
onProjectChange = (value) => { onProjectChange = (value) => {
const { selectedRowKeys } = value;
this.setState( this.setState(
{ {
projectId: value, projectId: selectedRowKeys[0],
}, },
() => { () => {
this.getQuota(); this.getQuota();
@ -230,10 +261,6 @@ export class Allocate extends ModalAction {
label: item.name, label: item.name,
value: item.id, value: item.id,
})); }));
const projectOptions = globalProjectStore.list.data.map((project) => ({
label: project.name,
value: project.id,
}));
return [ return [
{ {
name: 'floating_network_id', name: 'floating_network_id',
@ -246,12 +273,13 @@ export class Allocate extends ModalAction {
{ {
name: 'project_id', name: 'project_id',
label: t('Project'), label: t('Project'),
type: 'select', type: 'select-table',
showSearch: true,
hidden: !this.isAdminPage, hidden: !this.isAdminPage,
required: this.isAdminPage, required: this.isAdminPage,
options: projectOptions, isLoading: this.projectStore.list.isLoading,
data: this.projects,
onChange: this.onProjectChange, onChange: this.onProjectChange,
...projectTableOptions,
}, },
{ {
name: 'subnet_id', name: 'subnet_id',

View File

@ -22,6 +22,9 @@ import Notify from 'components/Notify';
import { checkSystemAdmin } from 'resources/skyline/policy'; import { checkSystemAdmin } from 'resources/skyline/policy';
import globalNeutronStore from 'stores/neutron/neutron'; import globalNeutronStore from 'stores/neutron/neutron';
import { subnetIpv6Tip } from 'resources/neutron/network'; import { subnetIpv6Tip } from 'resources/neutron/network';
import { projectTableOptions } from 'resources/keystone/project';
import { isAdminPage } from 'utils';
import { toJS } from 'mobx';
import networkUtil from './networkUtil'; import networkUtil from './networkUtil';
const { const {
@ -59,6 +62,15 @@ export class CreateNetwork extends ModalAction {
return t('create network'); return t('create network');
} }
static get modalSize() {
const { pathname } = window.location;
return isAdminPage(pathname) ? 'large' : 'small';
}
getModalSize() {
return this.isAdminPage ? 'large' : 'small';
}
init() { init() {
globalNetworkStore.updateCreateWithSubnet(false); globalNetworkStore.updateCreateWithSubnet(false);
this.state.networkQuota = {}; this.state.networkQuota = {};
@ -68,7 +80,7 @@ export class CreateNetwork extends ModalAction {
this.state.projectId = this.currentProjectId; this.state.projectId = this.currentProjectId;
this.projectStore = globalProjectStore; this.projectStore = globalProjectStore;
globalNeutronStore.fetchAvailableZones(); globalNeutronStore.fetchAvailableZones();
this.isAdminPage && globalProjectStore.fetchList(); this.isAdminPage && this.fetchProjectList();
this.getQuota(); this.getQuota();
} }
@ -89,6 +101,15 @@ export class CreateNetwork extends ModalAction {
return true; return true;
} }
async fetchProjectList() {
await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
}
get projects() {
return toJS(this.projectStore.list.data) || [];
}
get showQuota() { get showQuota() {
return true; return true;
} }
@ -136,8 +157,7 @@ export class CreateNetwork extends ModalAction {
} }
get defaultValue() { get defaultValue() {
return { const values = {
project_id: this.currentProjectId,
enable_dhcp: true, enable_dhcp: true,
provider_network_type: 'vxlan', provider_network_type: 'vxlan',
ip_version: 'ipv4', ip_version: 'ipv4',
@ -147,6 +167,12 @@ export class CreateNetwork extends ModalAction {
ipv6_ra_mode: 'slaac', ipv6_ra_mode: 'slaac',
ipv6_address_mode: 'slaac', ipv6_address_mode: 'slaac',
}; };
if (this.isAdminPage) {
values.project_id = {
selectedRowKeys: [this.currentProjectId],
};
}
return values;
} }
onSubmit = (values) => { onSubmit = (values) => {
@ -188,7 +214,9 @@ export class CreateNetwork extends ModalAction {
const networkAdminPageData = { const networkAdminPageData = {
'router:external': external_network, 'router:external': external_network,
project_id, project_id: project_id
? project_id.selectedRowKeys[0]
: this.currentProjectId,
'provider:network_type': provider_network_type, 'provider:network_type': provider_network_type,
'provider:physical_network': provider_physical_network, 'provider:physical_network': provider_physical_network,
'provider:segmentation_id': provider_segmentation_id, 'provider:segmentation_id': provider_segmentation_id,
@ -314,9 +342,10 @@ export class CreateNetwork extends ModalAction {
}; };
onProjectChange = (value) => { onProjectChange = (value) => {
const { selectedRowKeys } = value;
this.setState( this.setState(
{ {
projectId: value, projectId: selectedRowKeys[0],
}, },
() => { () => {
this.getQuota(); this.getQuota();
@ -339,10 +368,6 @@ export class CreateNetwork extends ModalAction {
ip_version = 'ipv4', ip_version = 'ipv4',
disable_gateway = false, disable_gateway = false,
} = this.state; } = this.state;
const projectOptions = globalProjectStore.list.data.map((project) => ({
label: project.name,
value: project.id,
}));
const hiddenPhysicalNetwork = const hiddenPhysicalNetwork =
this.isAdminPage && this.isAdminPage &&
@ -426,13 +451,13 @@ export class CreateNetwork extends ModalAction {
{ {
name: 'project_id', name: 'project_id',
label: t('Project'), label: t('Project'),
type: 'select', type: 'select-table',
showSearch: true,
hidden: !this.isAdminPage, hidden: !this.isAdminPage,
required: this.isAdminPage, required: this.isAdminPage,
options: projectOptions, isLoading: this.projectStore.list.isLoading,
data: this.projects,
onChange: this.onProjectChange, onChange: this.onProjectChange,
allowClear: false, ...projectTableOptions,
}, },
{ {
name: 'provider_network_type', name: 'provider_network_type',

View File

@ -20,6 +20,8 @@ import { isEmpty } from 'lodash';
import globalProjectStore from 'stores/keystone/project'; import globalProjectStore from 'stores/keystone/project';
import globalRootStore from 'stores/root'; import globalRootStore from 'stores/root';
import { subnetIpv6Tip } from 'resources/neutron/network'; import { subnetIpv6Tip } from 'resources/neutron/network';
import { projectTableOptions } from 'resources/keystone/project';
import { toJS } from 'mobx';
import networkUtil from './networkUtil'; import networkUtil from './networkUtil';
const { const {
@ -43,6 +45,14 @@ export class CreateSubnet extends ModalAction {
return t('Create Subnet'); return t('Create Subnet');
} }
static get modalSize() {
return globalRootStore.hasAdminRole ? 'large' : 'small';
}
getModalSize() {
return this.isSystemAdmin ? 'large' : 'small';
}
get network() { get network() {
return this.props.containerProps.detail || this.item || {}; return this.props.containerProps.detail || this.item || {};
} }
@ -52,15 +62,20 @@ export class CreateSubnet extends ModalAction {
} }
get defaultValue() { get defaultValue() {
return { const values = {
enable_dhcp: true, enable_dhcp: true,
ip_version: 'ipv4', ip_version: 'ipv4',
project_id: this.currentProjectId,
disable_gateway: false, disable_gateway: false,
more: false, more: false,
ipv6_ra_mode: 'slaac', ipv6_ra_mode: 'slaac',
ipv6_address_mode: 'slaac', ipv6_address_mode: 'slaac',
}; };
if (this.isSystemAdmin) {
values.project_id = {
selectedRowKeys: [this.currentProjectId],
};
}
return values;
} }
init() { init() {
@ -72,8 +87,13 @@ export class CreateSubnet extends ModalAction {
this.getQuota(); this.getQuota();
} }
getProjects() { async getProjects() {
this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
}
get projects() {
return toJS(this.projectStore.list.data) || [];
} }
static get disableSubmit() { static get disableSubmit() {
@ -139,7 +159,7 @@ export class CreateSubnet extends ModalAction {
}; };
onSubmit = (values) => { onSubmit = (values) => {
const { allocation_pools, host_routes, ...rest } = values; const { allocation_pools, host_routes, project_id, ...rest } = values;
const allocationPools = getAllocationPools(allocation_pools); const allocationPools = getAllocationPools(allocation_pools);
@ -147,6 +167,9 @@ export class CreateSubnet extends ModalAction {
return globalNetworkStore.createSubnet({ return globalNetworkStore.createSubnet({
...rest, ...rest,
project_id: project_id
? project_id.selectedRowKeys[0]
: this.currentProjectId,
network_id: this.network.id, network_id: this.network.id,
allocation_pools: allocationPools, allocation_pools: allocationPools,
host_routes: hostRouters, host_routes: hostRouters,
@ -180,9 +203,10 @@ export class CreateSubnet extends ModalAction {
}; };
onProjectChange = (value) => { onProjectChange = (value) => {
const { selectedRowKeys } = value;
this.setState( this.setState(
{ {
projectId: value, projectId: selectedRowKeys[0],
}, },
() => { () => {
this.getQuota(); this.getQuota();
@ -207,10 +231,6 @@ export class CreateSubnet extends ModalAction {
projectId, projectId,
} = this.state; } = this.state;
const isIpv4 = ip_version === 'ipv4'; const isIpv4 = ip_version === 'ipv4';
const projectOptions = globalProjectStore.list.data.map((project) => ({
label: project.name,
value: project.id,
}));
return [ return [
{ {
@ -223,17 +243,18 @@ export class CreateSubnet extends ModalAction {
{ {
name: 'project_id', name: 'project_id',
label: t('Project'), label: t('Project'),
type: 'select', type: 'select-table',
required: true, required: true,
hidden: !this.isSystemAdmin, hidden: !this.isSystemAdmin,
showSearch: true,
extra: extra:
projectId !== this.networkProjectId && projectId !== this.networkProjectId &&
t( t(
'The selected project is different from the project to which the network belongs. That is, the subnet to be created is not under the same project as the network. Please do not continue unless you are quit sure what you are doing.' 'The selected project is different from the project to which the network belongs. That is, the subnet to be created is not under the same project as the network. Please do not continue unless you are quit sure what you are doing.'
), ),
options: projectOptions, isLoading: this.projectStore.list.isLoading,
data: this.projects,
onChange: this.onProjectChange, onChange: this.onProjectChange,
...projectTableOptions,
}, },
{ {
name: 'ip_version', name: 'ip_version',

View File

@ -16,6 +16,9 @@ import { inject, observer } from 'mobx-react';
import { ModalAction } from 'containers/Action'; import { ModalAction } from 'containers/Action';
import globalProjectStore from 'stores/keystone/project'; import globalProjectStore from 'stores/keystone/project';
import { QoSPolicyStore } from 'stores/neutron/qos-policy'; import { QoSPolicyStore } from 'stores/neutron/qos-policy';
import { projectTableOptions } from 'resources/keystone/project';
import { isAdminPage } from 'utils';
import { toJS } from 'mobx';
export class Create extends ModalAction { export class Create extends ModalAction {
static id = 'create_qos_policy'; static id = 'create_qos_policy';
@ -26,6 +29,15 @@ export class Create extends ModalAction {
return t('Create QoS Policy'); return t('Create QoS Policy');
} }
static get modalSize() {
const { pathname } = window.location;
return isAdminPage(pathname) ? 'large' : 'small';
}
getModalSize() {
return this.isAdminPage ? 'large' : 'small';
}
static policy = 'create_policy'; static policy = 'create_policy';
static aliasPolicy = 'neutron:create_policy'; static aliasPolicy = 'neutron:create_policy';
@ -34,13 +46,28 @@ export class Create extends ModalAction {
init() { init() {
this.store = new QoSPolicyStore(); this.store = new QoSPolicyStore();
this.isAdminPage && globalProjectStore.fetchList(); this.projectStore = globalProjectStore;
this.isAdminPage && this.fetchProjectList();
}
async fetchProjectList() {
await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
}
get projects() {
return toJS(this.projectStore.list.data) || [];
} }
get defaultValue() { get defaultValue() {
return { if (this.isAdminPage) {
project_id: this.props.rootStore.user.project.id, return {
}; project_id: {
selectedRowKeys: [this.props.rootStore.user.project.id],
},
};
}
return {};
} }
onSubmit = (values) => { onSubmit = (values) => {
@ -50,16 +77,13 @@ export class Create extends ModalAction {
description, description,
shared, shared,
is_default, is_default,
project_id, project_id: project_id
? project_id.selectedRowKeys[0]
: this.props.rootStore.user.project.id,
}); });
}; };
get formItems() { get formItems() {
const projects = globalProjectStore.list.data.map((item) => ({
label: item.name,
value: item.id,
}));
return [ return [
{ {
name: 'name', name: 'name',
@ -71,11 +95,12 @@ export class Create extends ModalAction {
{ {
name: 'project_id', name: 'project_id',
label: t('Project'), label: t('Project'),
type: 'select', type: 'select-table',
showSearch: true, required: this.isAdminPage,
required: true, isLoading: globalProjectStore.list.isLoading,
options: projects, data: this.projects,
hidden: !this.isAdminPage, hidden: !this.isAdminPage,
...projectTableOptions,
}, },
{ {
name: 'description', name: 'description',

View File

@ -42,8 +42,9 @@ export class Create extends ModalAction {
this.typeStore.fetchList({ is_public: 'all' }); this.typeStore.fetchList({ is_public: 'all' });
} }
getProjects() { async getProjects() {
this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
} }
get projects() { get projects() {

View File

@ -57,7 +57,7 @@ export class ManageAccess extends ModalAction {
} }
async getProjects() { async getProjects() {
await this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue(); this.updateDefaultValue();
} }

View File

@ -60,8 +60,9 @@ export class Create extends ModalAction {
this.getProjects(); this.getProjects();
} }
getProjects() { async getProjects() {
this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
} }
get projects() { get projects() {

View File

@ -55,7 +55,7 @@ export class ManageAccess extends ModalAction {
} }
async getProjects() { async getProjects() {
await this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue(); this.updateDefaultValue();
} }

View File

@ -38,8 +38,9 @@ export class Create extends ModalAction {
// this.getServices(); // this.getServices();
} }
getProjects() { async getProjects() {
this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue();
} }
get projects() { get projects() {

View File

@ -57,7 +57,7 @@ export class ManageAccess extends ModalAction {
} }
async getProjects() { async getProjects() {
await this.projectStore.fetchList(); await this.projectStore.fetchProjectsWithDomain();
this.updateDefaultValue(); this.updateDefaultValue();
} }

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { Badge } from 'antd'; import { Badge } from 'antd';
import { getIdRender } from 'utils/table';
import globalDomainStore from 'stores/keystone/domain'; import globalDomainStore from 'stores/keystone/domain';
import globalRootStore from 'src/stores/root'; import globalRootStore from 'src/stores/root';
@ -73,15 +74,35 @@ export const enabledColumn = {
export const nameDomainColumns = [ export const nameDomainColumns = [
{ {
dataIndex: 'name', dataIndex: 'name',
title: t('Name'), title: t('Project ID/Name'),
render: (value, record) => {
return (
<>
<div>{getIdRender(record.id, true, false)}</div>
<div>{value}</div>
</>
);
},
}, },
{ {
dataIndex: 'domainName', dataIndex: 'domainName',
title: t('Domain'), title: t('Domain ID/Name'),
render: (value, record) => {
return (
<>
<div>{getIdRender(record.domain_id, true, false)}</div>
<div>{value}</div>
</>
);
},
}, },
]; ];
export const transferFilterOption = (inputValue, record) => { export const transferFilterOption = (inputValue, record) => {
const { domainName, name } = record; const { domainName, name, id } = record;
return name.includes(inputValue) || domainName.includes(inputValue); return (
id.includes(inputValue) ||
name.includes(inputValue) ||
domainName.includes(inputValue)
);
}; };

View File

@ -12,13 +12,27 @@
// 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 { yesNoOptions } from 'utils/constants'; import { yesNoOptions } from 'utils/constants';
import { getIdRender } from 'utils/table';
export const projectFilter = [ export const projectFilter = [
{ {
label: t('Project Name'), label: t('Project Name'),
name: 'name', name: 'name',
}, },
{
label: t('Project ID'),
name: 'id',
},
{
label: t('Domain Name'),
name: 'domainName',
},
{
label: t('Domain ID'),
name: 'domain_id',
},
{ {
label: t('Enabled'), label: t('Enabled'),
name: 'enabled', name: 'enabled',
@ -28,12 +42,30 @@ export const projectFilter = [
export const projectColumns = [ export const projectColumns = [
{ {
title: t('Project Name'), title: t('Project ID/Name'),
dataIndex: 'name', dataIndex: 'name',
render: (value, record) => {
const idRender = getIdRender(record.id, true, false);
return (
<>
<div>{idRender}</div>
<div>{value}</div>
</>
);
},
}, },
{ {
title: t('User Num'), title: t('Domain ID/Name'),
dataIndex: 'userCount', dataIndex: 'domainName',
render: (value, record) => {
const idRender = getIdRender(record.domain_id, true, false);
return (
<>
<div>{idRender}</div>
<div>{value}</div>
</>
);
},
}, },
{ {
title: t('Enabled'), title: t('Enabled'),

View File

@ -218,6 +218,24 @@ export class ProjectStore extends Base {
); );
} }
async fetchProjectsWithDomain() {
this.list.isLoading = true;
const [{ projects = [] }, { domains = [] }] = await Promise.all([
this.client.list(),
this.domainClient.list(),
]);
const newProjects = projects.map((pro) => {
const domain = domains.find((it) => it.id === pro.domain_id);
pro.domainName = domain?.name;
return pro;
});
this.list.update({
data: newProjects,
total: newProjects.length || 0,
isLoading: false,
});
}
get enableCinder() { get enableCinder() {
return globalRootStore.checkEndpoint('cinder'); return globalRootStore.checkEndpoint('cinder');
} }

View File

@ -50,6 +50,7 @@ describe('The Project Page', () => {
it('successfully edit quota', () => { it('successfully edit quota', () => {
cy.tableSearchText(name) cy.tableSearchText(name)
.clickActionInMore('Edit Quota') .clickActionInMore('Edit Quota')
.wait(5000)
.formInput('instances', 11) .formInput('instances', 11)
.formButtonClick('more') .formButtonClick('more')
.wait(2000) .wait(2000)

View File

@ -153,7 +153,7 @@ Cypress.Commands.add('setLanguageByPage', () => {
.find('.ant-col') .find('.ant-col')
.last() .last()
.find('button') .find('button')
.trigger('mouseover'); .trigger('mouseover', { force: true });
cy.get('.ant-dropdown-menu-light') cy.get('.ant-dropdown-menu-light')
.find('li') .find('li')
.eq(2) .eq(2)

View File

@ -39,7 +39,7 @@ Cypress.Commands.add('clickDetailActionInMore', (title, waitTime = 2000) => {
cy.get('.detail-main') cy.get('.detail-main')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
const realTitle = getTitle(title); const realTitle = getTitle(title);
cy.get('ul.ant-dropdown-menu-light') cy.get('ul.ant-dropdown-menu-light')
.contains(realTitle) .contains(realTitle)

View File

@ -56,7 +56,7 @@ Cypress.Commands.add(
cy.get('.table-header-btns') cy.get('.table-header-btns')
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.contains(moreTitle) .contains(moreTitle)
.trigger('mouseover'); .trigger('mouseover', { force: true });
cy.get('ul.ant-dropdown-menu-light') cy.get('ul.ant-dropdown-menu-light')
.last() .last()
.find('button') .find('button')
@ -95,7 +95,7 @@ Cypress.Commands.add('clickMoreActionButton', (buttonIndex) => {
cy.get('.ant-table-row') cy.get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
cy.get('ul.ant-dropdown-menu-light') cy.get('ul.ant-dropdown-menu-light')
.find('li') .find('li')
.eq(buttonIndex) .eq(buttonIndex)
@ -106,7 +106,7 @@ Cypress.Commands.add('clickActionInMore', (title, waitTime = 2000) => {
cy.get('.ant-table-row') cy.get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
const realTitle = getTitle(title); const realTitle = getTitle(title);
cy.get('ul.ant-dropdown-menu-light') cy.get('ul.ant-dropdown-menu-light')
.contains(realTitle) .contains(realTitle)
@ -118,12 +118,12 @@ Cypress.Commands.add('clickActionInMoreSub', (title, subMenu) => {
cy.get('.ant-table-row') cy.get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
const realTitle = getTitle(title); const realTitle = getTitle(title);
const realMenu = getTitle(subMenu); const realMenu = getTitle(subMenu);
cy.get('.ant-dropdown-menu-submenu-title') cy.get('.ant-dropdown-menu-submenu-title')
.contains(realMenu) .contains(realMenu)
.trigger('mouseover'); .trigger('mouseover', { force: true });
cy.get('.ant-dropdown-menu-submenu-popup') cy.get('.ant-dropdown-menu-submenu-popup')
.last() .last()
.find('button') .find('button')
@ -190,7 +190,7 @@ Cypress.Commands.add('checkActionDisabled', (title) => {
cy.get('.ant-table-row') cy.get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
cy.get('ul.ant-dropdown-menu-light').contains(realTitle).should('not.exist'); cy.get('ul.ant-dropdown-menu-light').contains(realTitle).should('not.exist');
}); });
@ -204,7 +204,7 @@ Cypress.Commands.add('checkActionDisabledInFirstRow', (title, name) => {
.get('.ant-table-row') .get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover') .trigger('mouseover', { force: true })
.get('ul.ant-dropdown-menu-light') .get('ul.ant-dropdown-menu-light')
.contains(realTitle) .contains(realTitle)
.should('not.exist'); .should('not.exist');
@ -228,7 +228,7 @@ Cypress.Commands.add('clickConfirmActionInMore', (title, waitTime) => {
cy.get('.ant-table-row') cy.get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
const realTitle = getTitle(title); const realTitle = getTitle(title);
cy.get('ul.ant-dropdown-menu-light') cy.get('ul.ant-dropdown-menu-light')
.contains(realTitle) .contains(realTitle)
@ -254,12 +254,12 @@ Cypress.Commands.add(
cy.get('.ant-table-row') cy.get('.ant-table-row')
.first() .first()
.find('.ant-dropdown-trigger') .find('.ant-dropdown-trigger')
.trigger('mouseover'); .trigger('mouseover', { force: true });
const realTitle = getTitle(title); const realTitle = getTitle(title);
const realMenu = getTitle(subMenu); const realMenu = getTitle(subMenu);
cy.get('.ant-dropdown-menu-submenu-title') cy.get('.ant-dropdown-menu-submenu-title')
.contains(realMenu) .contains(realMenu)
.trigger('mouseover'); .trigger('mouseover', { force: true });
cy.get('.ant-dropdown-menu-submenu-popup') cy.get('.ant-dropdown-menu-submenu-popup')
.last() .last()
.find('button') .find('button')