mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-02 03:58:33 +08:00
feat: 资源池finished&抽屉描述列表新增骨架屏
This commit is contained in:
parent
2dfd4588d9
commit
b58e7eb9ec
10
frontend/src/api/modules/setting/orgnization.ts
Normal file
10
frontend/src/api/modules/setting/orgnization.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import MSR from '@/api/http/index';
|
||||
import { OrganizationListItem } from '@/models/setting/orgnization';
|
||||
import { GetAllOrgUrl } from '@/api/requrls/setting/orgnization';
|
||||
|
||||
// 获取全部组织列表
|
||||
export function getAllOrgList() {
|
||||
return MSR.post<OrganizationListItem[]>({ url: GetAllOrgUrl });
|
||||
}
|
||||
|
||||
export function other() {}
|
2
frontend/src/api/requrls/setting/orgnization.ts
Normal file
2
frontend/src/api/requrls/setting/orgnization.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export const GetAllOrgUrl = '/system/organization/list-all';
|
||||
export const Other = '';
|
@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<a-descriptions :data="(props.descriptions as unknown as DescData[])" size="large" :column="1">
|
||||
<a-skeleton v-if="props.showSkeleton" :loading="props.showSkeleton" :animation="true">
|
||||
<a-space direction="vertical" class="w-[28%]" size="large">
|
||||
<a-skeleton-line :rows="props.skeletonLine" :line-height="24" />
|
||||
</a-space>
|
||||
<a-space direction="vertical" class="ml-[4%] w-[68%]" size="large">
|
||||
<a-skeleton-line :rows="props.skeletonLine" :line-height="24" />
|
||||
</a-space>
|
||||
</a-skeleton>
|
||||
<a-descriptions v-else :data="(props.descriptions as unknown as DescData[])" size="large" :column="1">
|
||||
<a-descriptions-item v-for="item of props.descriptions" :key="item.label" :label="item.label">
|
||||
<template v-if="item.isTag">
|
||||
<a-tag
|
||||
@ -30,7 +38,11 @@
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const props = defineProps<{ descriptions: Description[] }>();
|
||||
const props = defineProps<{
|
||||
showSkeleton?: boolean;
|
||||
skeletonLine?: number;
|
||||
descriptions: Description[];
|
||||
}>();
|
||||
|
||||
function handleItemClick(item: Description) {
|
||||
if (typeof item.onClick === 'function') {
|
||||
|
@ -19,7 +19,12 @@
|
||||
</slot>
|
||||
</template>
|
||||
<slot>
|
||||
<MsDescription v-if="props.descriptions?.length > 0" :descriptions="props.descriptions"></MsDescription>
|
||||
<MsDescription
|
||||
v-if="props.descriptions?.length > 0 || showDescription"
|
||||
:descriptions="props.descriptions"
|
||||
:show-skeleton="props.showSkeleton"
|
||||
:skeleton-line="10"
|
||||
></MsDescription>
|
||||
</slot>
|
||||
</a-drawer>
|
||||
</template>
|
||||
@ -39,12 +44,15 @@
|
||||
descriptions?: Description[];
|
||||
footer?: boolean;
|
||||
mask?: boolean;
|
||||
showDescription?: boolean;
|
||||
showSkeleton?: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<DrawerProps>(), {
|
||||
footer: true,
|
||||
mask: true,
|
||||
showSkeleton: false,
|
||||
});
|
||||
const emit = defineEmits(['update:visible']);
|
||||
|
||||
|
36
frontend/src/models/setting/orgnization.ts
Normal file
36
frontend/src/models/setting/orgnization.ts
Normal file
@ -0,0 +1,36 @@
|
||||
export interface OrgAdmin {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
enable: boolean;
|
||||
createTime: number;
|
||||
updateTime: number;
|
||||
language: string;
|
||||
lastOrganizationId: string; // 当前组织ID
|
||||
phone: string;
|
||||
source: string; // 来源:LOCAL OIDC CAS OAUTH2
|
||||
lastProjectId: string;
|
||||
createUser: string;
|
||||
updateUser: string;
|
||||
deleted: boolean;
|
||||
}
|
||||
|
||||
export interface OrganizationListItem {
|
||||
id: string;
|
||||
num: number; // 组织编号
|
||||
name: string;
|
||||
description: string;
|
||||
createTime: number;
|
||||
updateTime: number;
|
||||
createUser: string;
|
||||
updateUser: string;
|
||||
deleted: boolean;
|
||||
deleteUser: string;
|
||||
deleteTime: number;
|
||||
enable: boolean;
|
||||
memberCount: number;
|
||||
projectCount: number;
|
||||
orgAdmins: OrgAdmin[]; // 列表组织管理员集合
|
||||
memberIds: string[]; // 组织管理员ID集合
|
||||
}
|
@ -60,7 +60,7 @@
|
||||
multiple
|
||||
allow-clear
|
||||
>
|
||||
<a-option v-for="org of orgOptons" :key="org.id" :value="org.value">{{ org.label }}</a-option>
|
||||
<a-option v-for="org of orgOptons" :key="org.id" :value="org.id">{{ org.name }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
@ -337,7 +337,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Ref, ref, watchEffect } from 'vue';
|
||||
import { computed, onBeforeMount, Ref, ref, watchEffect, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { Message, FormInstance, SelectOptionData } from '@arco-design/web-vue';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
@ -351,6 +351,7 @@
|
||||
import { downloadStringFile, sleep } from '@/utils';
|
||||
import { scrollIntoView } from '@/utils/dom';
|
||||
import { addPool, getPoolInfo, updatePoolInfo } from '@/api/modules/setting/resourcePool';
|
||||
import { getAllOrgList } from '@/api/modules/setting/orgnization';
|
||||
|
||||
import type { MsBatchFormInstance, FormItemModel } from '@/components/bussiness/ms-batch-form/types';
|
||||
import type { UpdateResourcePoolParams, NodesListItem } from '@/models/setting/resourcePool';
|
||||
@ -406,6 +407,10 @@
|
||||
];
|
||||
const defaultGrid = 'http://selenium-hub:4444';
|
||||
|
||||
onBeforeMount(async () => {
|
||||
orgOptons.value = await getAllOrgList();
|
||||
});
|
||||
|
||||
async function initPoolInfo() {
|
||||
try {
|
||||
loading.value = true;
|
||||
@ -487,6 +492,16 @@
|
||||
() => isFillNameSpaces.value && form.value.testResourceDTO.deployName?.trim() !== ''
|
||||
);
|
||||
|
||||
watch(
|
||||
() => isShowK8SResources.value,
|
||||
(val) => {
|
||||
if (val && !form.value.testResourceDTO.jobDefinition) {
|
||||
// 在编辑场景下,如果资源池非 k8s 的话,jobDefinition 会是 null,选中 k8s 资源的时候需要赋默认值
|
||||
form.value.testResourceDTO.jobDefinition = job;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const batchFormRef = ref<MsBatchFormInstance | null>(null);
|
||||
const batchFormModels: Ref<FormItemModel[]> = ref([
|
||||
{
|
||||
|
@ -47,16 +47,18 @@
|
||||
:descriptions="activePoolDesc"
|
||||
:footer="false"
|
||||
:mask="false"
|
||||
:show-skeleton="drawerLoading"
|
||||
show-description
|
||||
>
|
||||
<template #tbutton>
|
||||
<a-button type="outline" size="mini" @click="editPool(activePool)">
|
||||
<a-button type="outline" size="mini" :disabled="drawerLoading" @click="editPool(activePool)">
|
||||
{{ t('system.resourcePool.editPool') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</MsDrawer>
|
||||
<JobTemplateDrawer
|
||||
v-model:visible="showJobDrawer"
|
||||
:default-val="activePool?.testResourceDTO.jobDefinition || ''"
|
||||
:default-val="activePool?.testResourceReturnDTO.jobDefinition || ''"
|
||||
read-only
|
||||
/>
|
||||
</div>
|
||||
@ -67,7 +69,7 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { getPoolList, delPoolInfo, togglePoolStatus } from '@/api/modules/setting/resourcePool';
|
||||
import { getPoolList, delPoolInfo, togglePoolStatus, getPoolInfo } from '@/api/modules/setting/resourcePool';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
@ -82,7 +84,8 @@
|
||||
import type { Description } from '@/components/pure/ms-description/index.vue';
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import type { ResourcePoolItem } from '@/models/setting/resourcePool';
|
||||
import type { ResourcePoolDetail } from '@/models/setting/resourcePool';
|
||||
import { sleep } from '@/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
@ -269,161 +272,172 @@
|
||||
|
||||
const showDetailDrawer = ref(false);
|
||||
const activePoolDesc: Ref<Description[]> = ref([]);
|
||||
const activePool: Ref<ResourcePoolItem | null> = ref(null);
|
||||
const activePool: Ref<ResourcePoolDetail | null> = ref(null);
|
||||
const showJobDrawer = ref(false);
|
||||
const drawerLoading = ref(false);
|
||||
/**
|
||||
* 查看资源池详情
|
||||
* @param record
|
||||
*/
|
||||
function showPoolDetail(record: any) {
|
||||
activePool.value = { ...record };
|
||||
if (activePool.value) {
|
||||
const poolUses = [
|
||||
activePool.value.loadTest ? t('system.resourcePool.usePerformance') : '',
|
||||
activePool.value.apiTest ? t('system.resourcePool.useAPI') : '',
|
||||
activePool.value.uiTest ? t('system.resourcePool.useUI') : '',
|
||||
];
|
||||
const { type, testResourceDTO, loadTest, apiTest, uiTest } = activePool.value;
|
||||
const {
|
||||
ip,
|
||||
token, // k8s token
|
||||
nameSpaces, // k8s 命名空间
|
||||
concurrentNumber, // k8s 最大并发数
|
||||
podThreads, // k8s 单pod最大线程数
|
||||
apiTestImage, // k8s api测试镜像
|
||||
deployName, // k8s api测试部署名称
|
||||
girdConcurrentNumber,
|
||||
nodesList,
|
||||
loadTestImage,
|
||||
loadTestHeap,
|
||||
uiGrid,
|
||||
} = testResourceDTO;
|
||||
// Node
|
||||
const nodeResourceDesc =
|
||||
type === 'Node'
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.detailResources'),
|
||||
value: nodesList?.map((e) => `${e.ip},${e.port},${e.monitor},${e.concurrentNumber}`),
|
||||
isTag: true,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
// K8S
|
||||
const k8sResourceDesc =
|
||||
type === 'Kubernetes'
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.ip'),
|
||||
value: ip,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.token'),
|
||||
value: token,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.nameSpaces'),
|
||||
value: nameSpaces,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.deployName'),
|
||||
value: deployName,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.apiTestImage'),
|
||||
value: apiTestImage,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.concurrentNumber'),
|
||||
value: concurrentNumber,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.podThreads'),
|
||||
value: podThreads,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
const jobTemplate =
|
||||
loadTest && type === 'Kubernetes'
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.jobTemplate'),
|
||||
value: t('system.resourcePool.customJobTemplate'),
|
||||
isButton: true,
|
||||
onClick: () => {
|
||||
showJobDrawer.value = true;
|
||||
},
|
||||
},
|
||||
]
|
||||
: [];
|
||||
// 性能测试
|
||||
const performanceDesc = loadTest
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.mirror'),
|
||||
value: loadTestImage,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testHeap'),
|
||||
value: loadTestHeap,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
// 接口测试/性能测试
|
||||
const resourceDesc = apiTest || loadTest ? [...nodeResourceDesc, ...k8sResourceDesc] : [];
|
||||
// ui 测试资源
|
||||
const uiDesc = uiTest
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.uiGrid'),
|
||||
value: uiGrid,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.concurrentNumber'),
|
||||
value: girdConcurrentNumber,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
|
||||
const detailType =
|
||||
apiTest || loadTest
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.detailType'),
|
||||
value: activePool.value.type,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
activePoolDesc.value = [
|
||||
{
|
||||
label: t('system.resourcePool.detailDesc'),
|
||||
value: activePool.value.description,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.detailUrl'),
|
||||
value: activePool.value.serverUrl,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.detailRange'),
|
||||
value: activePool.value.allOrg
|
||||
? [t('system.resourcePool.orgAll')]
|
||||
: activePool.value.testResourceDTO.orgIdNameMap.map((e) => e.name),
|
||||
isTag: true,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.detailUse'),
|
||||
value: poolUses.filter((e) => e !== ''),
|
||||
isTag: true,
|
||||
},
|
||||
...performanceDesc,
|
||||
...uiDesc,
|
||||
...detailType,
|
||||
...resourceDesc,
|
||||
...jobTemplate,
|
||||
];
|
||||
async function showPoolDetail(record: any) {
|
||||
if (activePool.value?.id === record.id && showDetailDrawer.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
drawerLoading.value = true;
|
||||
showDetailDrawer.value = true;
|
||||
try {
|
||||
const res = await getPoolInfo(record.id);
|
||||
if (res) {
|
||||
activePool.value = res;
|
||||
const poolUses = [
|
||||
activePool.value.loadTest ? t('system.resourcePool.usePerformance') : '',
|
||||
activePool.value.apiTest ? t('system.resourcePool.useAPI') : '',
|
||||
activePool.value.uiTest ? t('system.resourcePool.useUI') : '',
|
||||
];
|
||||
const { type, testResourceReturnDTO, loadTest, apiTest, uiTest } = activePool.value;
|
||||
const {
|
||||
ip,
|
||||
token, // k8s token
|
||||
nameSpaces, // k8s 命名空间
|
||||
concurrentNumber, // k8s 最大并发数
|
||||
podThreads, // k8s 单pod最大线程数
|
||||
apiTestImage, // k8s api测试镜像
|
||||
deployName, // k8s api测试部署名称
|
||||
girdConcurrentNumber,
|
||||
nodesList,
|
||||
loadTestImage,
|
||||
loadTestHeap,
|
||||
uiGrid,
|
||||
} = testResourceReturnDTO;
|
||||
// Node
|
||||
const nodeResourceDesc =
|
||||
type === 'Node'
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.detailResources'),
|
||||
value: nodesList?.map((e) => `${e.ip},${e.port},${e.monitor},${e.concurrentNumber}`),
|
||||
isTag: true,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
// K8S
|
||||
const k8sResourceDesc =
|
||||
type === 'Kubernetes'
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.ip'),
|
||||
value: ip,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.token'),
|
||||
value: token,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.nameSpaces'),
|
||||
value: nameSpaces,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.deployName'),
|
||||
value: deployName,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.apiTestImage'),
|
||||
value: apiTestImage,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.concurrentNumber'),
|
||||
value: concurrentNumber,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testResourceDTO.podThreads'),
|
||||
value: podThreads,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
const jobTemplate =
|
||||
loadTest && type === 'Kubernetes'
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.jobTemplate'),
|
||||
value: t('system.resourcePool.customJobTemplate'),
|
||||
isButton: true,
|
||||
onClick: () => {
|
||||
showJobDrawer.value = true;
|
||||
},
|
||||
},
|
||||
]
|
||||
: [];
|
||||
// 性能测试
|
||||
const performanceDesc = loadTest
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.mirror'),
|
||||
value: loadTestImage,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.testHeap'),
|
||||
value: loadTestHeap,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
// 接口测试/性能测试
|
||||
const resourceDesc = apiTest || loadTest ? [...nodeResourceDesc, ...k8sResourceDesc] : [];
|
||||
// ui 测试资源
|
||||
const uiDesc = uiTest
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.uiGrid'),
|
||||
value: uiGrid,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.concurrentNumber'),
|
||||
value: girdConcurrentNumber,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
|
||||
const detailType =
|
||||
apiTest || loadTest
|
||||
? [
|
||||
{
|
||||
label: t('system.resourcePool.detailType'),
|
||||
value: activePool.value.type,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
activePoolDesc.value = [
|
||||
{
|
||||
label: t('system.resourcePool.detailDesc'),
|
||||
value: activePool.value.description,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.detailUrl'),
|
||||
value: activePool.value.serverUrl,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.detailRange'),
|
||||
value: activePool.value.allOrg
|
||||
? [t('system.resourcePool.orgAll')]
|
||||
: activePool.value.testResourceReturnDTO.orgIdNameMap.map((e) => e.name),
|
||||
isTag: true,
|
||||
},
|
||||
{
|
||||
label: t('system.resourcePool.detailUse'),
|
||||
value: poolUses.filter((e) => e !== ''),
|
||||
isTag: true,
|
||||
},
|
||||
...performanceDesc,
|
||||
...uiDesc,
|
||||
...detailType,
|
||||
...resourceDesc,
|
||||
...jobTemplate,
|
||||
];
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
drawerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user