feat: 资源池finished&抽屉描述列表新增骨架屏
This commit is contained in:
parent
2dfd4588d9
commit
b58e7eb9ec
|
@ -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() {}
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const GetAllOrgUrl = '/system/organization/list-all';
|
||||||
|
export const Other = '';
|
|
@ -1,5 +1,13 @@
|
||||||
<template>
|
<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">
|
<a-descriptions-item v-for="item of props.descriptions" :key="item.label" :label="item.label">
|
||||||
<template v-if="item.isTag">
|
<template v-if="item.isTag">
|
||||||
<a-tag
|
<a-tag
|
||||||
|
@ -30,7 +38,11 @@
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{ descriptions: Description[] }>();
|
const props = defineProps<{
|
||||||
|
showSkeleton?: boolean;
|
||||||
|
skeletonLine?: number;
|
||||||
|
descriptions: Description[];
|
||||||
|
}>();
|
||||||
|
|
||||||
function handleItemClick(item: Description) {
|
function handleItemClick(item: Description) {
|
||||||
if (typeof item.onClick === 'function') {
|
if (typeof item.onClick === 'function') {
|
||||||
|
|
|
@ -19,7 +19,12 @@
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
<slot>
|
<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>
|
</slot>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -39,12 +44,15 @@
|
||||||
descriptions?: Description[];
|
descriptions?: Description[];
|
||||||
footer?: boolean;
|
footer?: boolean;
|
||||||
mask?: boolean;
|
mask?: boolean;
|
||||||
|
showDescription?: boolean;
|
||||||
|
showSkeleton?: boolean;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DrawerProps>(), {
|
const props = withDefaults(defineProps<DrawerProps>(), {
|
||||||
footer: true,
|
footer: true,
|
||||||
mask: true,
|
mask: true,
|
||||||
|
showSkeleton: false,
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['update:visible']);
|
const emit = defineEmits(['update:visible']);
|
||||||
|
|
||||||
|
|
|
@ -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
|
multiple
|
||||||
allow-clear
|
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-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
|
@ -337,7 +337,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 { useRoute, useRouter } from 'vue-router';
|
||||||
import { Message, FormInstance, SelectOptionData } from '@arco-design/web-vue';
|
import { Message, FormInstance, SelectOptionData } from '@arco-design/web-vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
@ -351,6 +351,7 @@
|
||||||
import { downloadStringFile, sleep } from '@/utils';
|
import { downloadStringFile, sleep } from '@/utils';
|
||||||
import { scrollIntoView } from '@/utils/dom';
|
import { scrollIntoView } from '@/utils/dom';
|
||||||
import { addPool, getPoolInfo, updatePoolInfo } from '@/api/modules/setting/resourcePool';
|
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 { MsBatchFormInstance, FormItemModel } from '@/components/bussiness/ms-batch-form/types';
|
||||||
import type { UpdateResourcePoolParams, NodesListItem } from '@/models/setting/resourcePool';
|
import type { UpdateResourcePoolParams, NodesListItem } from '@/models/setting/resourcePool';
|
||||||
|
@ -406,6 +407,10 @@
|
||||||
];
|
];
|
||||||
const defaultGrid = 'http://selenium-hub:4444';
|
const defaultGrid = 'http://selenium-hub:4444';
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
orgOptons.value = await getAllOrgList();
|
||||||
|
});
|
||||||
|
|
||||||
async function initPoolInfo() {
|
async function initPoolInfo() {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
@ -487,6 +492,16 @@
|
||||||
() => isFillNameSpaces.value && form.value.testResourceDTO.deployName?.trim() !== ''
|
() => 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 batchFormRef = ref<MsBatchFormInstance | null>(null);
|
||||||
const batchFormModels: Ref<FormItemModel[]> = ref([
|
const batchFormModels: Ref<FormItemModel[]> = ref([
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,16 +47,18 @@
|
||||||
:descriptions="activePoolDesc"
|
:descriptions="activePoolDesc"
|
||||||
:footer="false"
|
:footer="false"
|
||||||
:mask="false"
|
:mask="false"
|
||||||
|
:show-skeleton="drawerLoading"
|
||||||
|
show-description
|
||||||
>
|
>
|
||||||
<template #tbutton>
|
<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') }}
|
{{ t('system.resourcePool.editPool') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
<JobTemplateDrawer
|
<JobTemplateDrawer
|
||||||
v-model:visible="showJobDrawer"
|
v-model:visible="showJobDrawer"
|
||||||
:default-val="activePool?.testResourceDTO.jobDefinition || ''"
|
:default-val="activePool?.testResourceReturnDTO.jobDefinition || ''"
|
||||||
read-only
|
read-only
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,7 +69,7 @@
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
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 useModal from '@/hooks/useModal';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
import MsBaseTable from '@/components/pure/ms-table/base-table.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 { Description } from '@/components/pure/ms-description/index.vue';
|
||||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
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 { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -269,21 +272,29 @@
|
||||||
|
|
||||||
const showDetailDrawer = ref(false);
|
const showDetailDrawer = ref(false);
|
||||||
const activePoolDesc: Ref<Description[]> = ref([]);
|
const activePoolDesc: Ref<Description[]> = ref([]);
|
||||||
const activePool: Ref<ResourcePoolItem | null> = ref(null);
|
const activePool: Ref<ResourcePoolDetail | null> = ref(null);
|
||||||
const showJobDrawer = ref(false);
|
const showJobDrawer = ref(false);
|
||||||
|
const drawerLoading = ref(false);
|
||||||
/**
|
/**
|
||||||
* 查看资源池详情
|
* 查看资源池详情
|
||||||
* @param record
|
* @param record
|
||||||
*/
|
*/
|
||||||
function showPoolDetail(record: any) {
|
async function showPoolDetail(record: any) {
|
||||||
activePool.value = { ...record };
|
if (activePool.value?.id === record.id && showDetailDrawer.value) {
|
||||||
if (activePool.value) {
|
return;
|
||||||
|
}
|
||||||
|
drawerLoading.value = true;
|
||||||
|
showDetailDrawer.value = true;
|
||||||
|
try {
|
||||||
|
const res = await getPoolInfo(record.id);
|
||||||
|
if (res) {
|
||||||
|
activePool.value = res;
|
||||||
const poolUses = [
|
const poolUses = [
|
||||||
activePool.value.loadTest ? t('system.resourcePool.usePerformance') : '',
|
activePool.value.loadTest ? t('system.resourcePool.usePerformance') : '',
|
||||||
activePool.value.apiTest ? t('system.resourcePool.useAPI') : '',
|
activePool.value.apiTest ? t('system.resourcePool.useAPI') : '',
|
||||||
activePool.value.uiTest ? t('system.resourcePool.useUI') : '',
|
activePool.value.uiTest ? t('system.resourcePool.useUI') : '',
|
||||||
];
|
];
|
||||||
const { type, testResourceDTO, loadTest, apiTest, uiTest } = activePool.value;
|
const { type, testResourceReturnDTO, loadTest, apiTest, uiTest } = activePool.value;
|
||||||
const {
|
const {
|
||||||
ip,
|
ip,
|
||||||
token, // k8s token
|
token, // k8s token
|
||||||
|
@ -297,7 +308,7 @@
|
||||||
loadTestImage,
|
loadTestImage,
|
||||||
loadTestHeap,
|
loadTestHeap,
|
||||||
uiGrid,
|
uiGrid,
|
||||||
} = testResourceDTO;
|
} = testResourceReturnDTO;
|
||||||
// Node
|
// Node
|
||||||
const nodeResourceDesc =
|
const nodeResourceDesc =
|
||||||
type === 'Node'
|
type === 'Node'
|
||||||
|
@ -407,7 +418,7 @@
|
||||||
label: t('system.resourcePool.detailRange'),
|
label: t('system.resourcePool.detailRange'),
|
||||||
value: activePool.value.allOrg
|
value: activePool.value.allOrg
|
||||||
? [t('system.resourcePool.orgAll')]
|
? [t('system.resourcePool.orgAll')]
|
||||||
: activePool.value.testResourceDTO.orgIdNameMap.map((e) => e.name),
|
: activePool.value.testResourceReturnDTO.orgIdNameMap.map((e) => e.name),
|
||||||
isTag: true,
|
isTag: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -422,8 +433,11 @@
|
||||||
...jobTemplate,
|
...jobTemplate,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
showDetailDrawer.value = true;
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
drawerLoading.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue