fix(功能用例): 修复用例详情关联接口用例协议下拉无其它协议且去掉下拉框式协议

This commit is contained in:
xinxin.wu 2024-07-19 15:05:11 +08:00 committed by Craftsman
parent f7dcfa8caa
commit ea09ed03c4
5 changed files with 81 additions and 87 deletions

View File

@ -14,6 +14,7 @@
v-model="caseType" v-model="caseType"
class="ml-2 max-w-[100px]" class="ml-2 max-w-[100px]"
:placeholder="t('caseManagement.featureCase.PleaseSelect')" :placeholder="t('caseManagement.featureCase.PleaseSelect')"
@change="changeCaseType"
> >
<a-option v-for="item of props?.moduleOptions" :key="item.value" :value="item.value"> <a-option v-for="item of props?.moduleOptions" :key="item.value" :value="item.value">
{{ t(item.label) }} {{ t(item.label) }}
@ -24,16 +25,14 @@
<div class="flex h-full"> <div class="flex h-full">
<div class="w-[292px] border-r border-[var(--color-text-n8)] p-[16px]"> <div class="w-[292px] border-r border-[var(--color-text-n8)] p-[16px]">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div <div v-if="!props.hideProjectSelect" class="w-full max-w-[259px]">
v-if="!props.hideProjectSelect"
:class="`${!props.hideProjectSelect && caseType !== 'API' ? 'max-w-[259px]' : 'max-w-[162px]'} flex-1`"
>
<a-select <a-select
v-model="innerProject" v-model="innerProject"
class="mb-[16px] w-full" class="mb-[16px] w-full"
:default-value="innerProject" :default-value="innerProject"
allow-search allow-search
:placeholder="t('common.pleaseSelect')" :placeholder="t('common.pleaseSelect')"
@change="changeProject"
> >
<template #arrow-icon> <template #arrow-icon>
<icon-caret-down /> <icon-caret-down />
@ -45,9 +44,6 @@
</a-tooltip> </a-tooltip>
</a-select> </a-select>
</div> </div>
<a-select v-if="caseType === 'API'" v-model="protocolType" class="mb-[16px] ml-2 max-w-[90px]">
<a-option v-for="item of protocolOptions" :key="item" :value="item">{{ item }}</a-option>
</a-select>
</div> </div>
<div class="mb-[8px] flex items-center gap-[8px]"> <div class="mb-[8px] flex items-center gap-[8px]">
<a-input <a-input
@ -67,23 +63,17 @@
</a-button> </a-button>
</a-tooltip> </a-tooltip>
</div> </div>
<TreeFolderAll
<div class="folder"> ref="treeFolderAllRef"
<div :class="getFolderClass('all')" @click="setActiveFolder('all')"> :protocol-key="ProtocolKeyEnum.CASE_MANAGEMENT_ASSOCIATE_PROTOCOL"
<MsIcon type="icon-icon_folder_filled1" class="folder-icon" /> :active-folder="activeFolder"
<div class="folder-name">{{ t('caseManagement.featureCase.allCase') }}</div> :folder-name="t('caseManagement.featureCase.allCase')"
<div class="folder-count">({{ modulesCount.total || modulesCount.all || 0 }})</div> :all-count="modulesCount.total || modulesCount.all || 0"
</div> :show-expand-api="false"
<!-- <div class="ml-auto flex items-center"> :not-show-operation="caseType !== 'API'"
<a-tooltip @set-active-folder="setActiveFolder"
:content="isExpandAll ? t('common.collapseAllSubModule') : t('common.expandAllSubModule')" @selected-protocols-change="selectedProtocolsChange"
> />
<MsButton type="icon" status="secondary" class="!mr-0 p-[4px]" @click="expandHandler">
<MsIcon :type="isExpandAll ? 'icon-icon_folder_collapse1' : 'icon-icon_folder_expansion1'" />
</MsButton>
</a-tooltip>
</div> -->
</div>
<a-divider class="my-[8px]" /> <a-divider class="my-[8px]" />
<a-spin class="w-full" :loading="moduleLoading"> <a-spin class="w-full" :loading="moduleLoading">
<MsTree <MsTree
@ -148,11 +138,7 @@
@filter-change="filterChange" @filter-change="filterChange"
> >
<template #num="{ record }"> <template #num="{ record }">
<a-tooltip :content="`${record.num}`"> <a-button type="text" class="px-0" @click="openDetail(record.id)">{{ record.num }} </a-button>
<a-button type="text" class="px-0" @click="openDetail(record.id)">
<div class="one-line-text max-w-[168px]">{{ record.num }}</div>
</a-button>
</a-tooltip>
</template> </template>
<template #caseLevel="{ record }"> <template #caseLevel="{ record }">
<caseLevel v-if="getCaseLevel(record)" :case-level="getCaseLevel(record)" /> <caseLevel v-if="getCaseLevel(record)" :case-level="getCaseLevel(record)" />
@ -220,6 +206,7 @@
import MsTree from '@/components/business/ms-tree/index.vue'; import MsTree from '@/components/business/ms-tree/index.vue';
import type { MsTreeNodeData } from '@/components/business/ms-tree/types'; import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
import caseLevel from './caseLevel.vue'; import caseLevel from './caseLevel.vue';
import TreeFolderAll from '@/views/api-test/components/treeFolderAll.vue';
import { getAssociatedProjectOptions, getCustomFieldsTable } from '@/api/modules/case-management/featureCase'; import { getAssociatedProjectOptions, getCustomFieldsTable } from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -229,6 +216,7 @@
import type { CaseManagementTable } from '@/models/caseManagement/featureCase'; import type { CaseManagementTable } from '@/models/caseManagement/featureCase';
import type { CommonList, ModuleTreeNode, TableQueryParams } from '@/models/common'; import type { CommonList, ModuleTreeNode, TableQueryParams } from '@/models/common';
import type { ProjectListItem } from '@/models/setting/project'; import type { ProjectListItem } from '@/models/setting/project';
import { ProtocolKeyEnum } from '@/enums/apiEnum';
import { CaseLinkEnum } from '@/enums/caseEnum'; import { CaseLinkEnum } from '@/enums/caseEnum';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
@ -252,7 +240,7 @@
getTableFunc: (params: TableQueryParams) => Promise<CommonList<CaseManagementTable>>; // getTableFunc: (params: TableQueryParams) => Promise<CommonList<CaseManagementTable>>; //
tableParams?: TableQueryParams; // tableParams?: TableQueryParams; //
okButtonDisabled?: boolean; // okButtonDisabled?: boolean; //
currentSelectCase: keyof typeof CaseLinkEnum; // currentSelectCase: CaseLinkEnum; //
moduleOptions?: { label: string; value: string }[]; // moduleOptions?: { label: string; value: string }[]; //
confirmLoading: boolean; confirmLoading: boolean;
associatedIds: string[]; // id associatedIds: string[]; // id
@ -272,7 +260,6 @@
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:visible', val: boolean): void; (e: 'update:visible', val: boolean): void;
(e: 'update:projectId', val: string): void; (e: 'update:projectId', val: string): void;
(e: 'update:currentSelectCase', val: string | number | Record<string, any> | undefined): void;
(e: 'init', val: TableQueryParams): void; // (e: 'init', val: TableQueryParams): void; //
(e: 'close'): void; (e: 'close'): void;
(e: 'save', params: any): void; // table (e: 'save', params: any): void; // table
@ -291,10 +278,6 @@
const activeFolderName = ref(t('ms.case.associate.allCase')); const activeFolderName = ref(t('ms.case.associate.allCase'));
const filterRowCount = ref(0); const filterRowCount = ref(0);
function getFolderClass(id: string) {
return activeFolder.value === id ? 'folder-text folder-text--active' : 'folder-text';
}
const moduleKeyword = ref(''); const moduleKeyword = ref('');
const folderTree = ref<ModuleTreeNode[]>([]); const folderTree = ref<ModuleTreeNode[]>([]);
const moduleLoading = ref(false); const moduleLoading = ref(false);
@ -310,20 +293,10 @@
const innerVisible = useVModel(props, 'visible', emit); const innerVisible = useVModel(props, 'visible', emit);
const innerProject = ref<string | undefined>(props.projectId); const innerProject = ref<string | undefined>(props.projectId);
const protocolType = ref('HTTP'); //
const protocolOptions = ref(['HTTP']);
const modulesCount = ref<Record<string, any>>({}); const modulesCount = ref<Record<string, any>>({});
const isExpandAll = ref(false); const isExpandAll = ref(false);
// const caseType = ref<CaseLinkEnum>(props.currentSelectCase);
const caseType = computed({
get() {
return props.currentSelectCase;
},
set(val) {
emit('update:currentSelectCase', val);
},
});
/** /**
* 初始化模块树 * 初始化模块树
@ -555,6 +528,9 @@
version: version.value, version: version.value,
}); });
const treeFolderAllRef = ref<InstanceType<typeof TreeFolderAll>>();
const selectedProtocols = computed<string[]>(() => treeFolderAllRef.value?.selectedProtocols ?? []);
function getLoadListParams() { function getLoadListParams() {
if (activeFolder.value === 'all' || !activeFolder.value) { if (activeFolder.value === 'all' || !activeFolder.value) {
searchParams.value.moduleIds = []; searchParams.value.moduleIds = [];
@ -574,6 +550,7 @@
condition: { condition: {
keyword: keyword.value, keyword: keyword.value,
}, },
protocols: caseType.value === 'API' ? selectedProtocols.value : [],
}); });
if (props.hasNotAssociatedIds && props.hasNotAssociatedIds.length > 0) { if (props.hasNotAssociatedIds && props.hasNotAssociatedIds.length > 0) {
props.hasNotAssociatedIds.forEach((hasNotAssociatedId) => { props.hasNotAssociatedIds.forEach((hasNotAssociatedId) => {
@ -701,24 +678,38 @@
} }
} }
function searchCase() {
getLoadListParams();
loadList();
initModuleCount();
}
function setAllSelectModule() {
nextTick(() => {
if (activeFolder.value !== 'all') {
setActiveFolder('all');
} else {
searchCase();
}
});
}
async function initProjectList(setDefault: boolean) { async function initProjectList(setDefault: boolean) {
try { try {
projectList.value = await getAssociatedProjectOptions(appStore.currentOrgId, caseType.value); projectList.value = await getAssociatedProjectOptions(appStore.currentOrgId, caseType.value);
if (setDefault) { if (setDefault) {
innerProject.value = projectList.value[0].id; innerProject.value = projectList.value[0].id;
} }
resetSelector();
resetFilterParams();
initModules();
setAllSelectModule();
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
} }
function searchCase() {
getLoadListParams();
loadList();
initModuleCount();
}
// //
function handleConfirm() { function handleConfirm() {
const { excludeKeys, selectedKeys, selectorStatus } = propsRes.value; const { excludeKeys, selectedKeys, selectorStatus } = propsRes.value;
@ -769,13 +760,9 @@
(val) => { (val) => {
if (val) { if (val) {
resetFilterParams(); resetFilterParams();
resetSelector();
if (!props.hideProjectSelect) { if (!props.hideProjectSelect) {
initProjectList(true); initProjectList(true);
} else {
resetSelector();
initModules();
searchCase();
initFilter();
} }
} else { } else {
cancel(); cancel();
@ -784,32 +771,39 @@
); );
watch( watch(
() => caseType.value, () => props.currentSelectCase,
(val) => { (val) => {
if (val) { caseType.value = val;
if (!props.hideProjectSelect) { },
initProjectList(true); {
} immediate: true,
resetFilterParams();
initModules(true);
searchCase();
initFilter();
}
} }
); );
watch( //
() => innerProject.value, function changeCaseType(
(val) => { value: string | number | boolean | Record<string, any> | (string | number | boolean | Record<string, any>)[]
if (val) { ) {
resetSelector(); caseType.value = value as CaseLinkEnum;
resetFilterParams(); initModules();
initModules(true); setAllSelectModule();
searchCase(); initFilter();
initFilter(); }
}
} function selectedProtocolsChange() {
); initModules();
setAllSelectModule();
initFilter();
}
//
function changeProject(
value: string | number | boolean | Record<string, any> | (string | number | boolean | Record<string, any>)[]
) {
innerProject.value = value as string;
initModules();
setAllSelectModule();
initFilter();
}
watch( watch(
() => activeFolder.value, () => activeFolder.value,

View File

@ -352,4 +352,5 @@ export enum ProtocolKeyEnum {
API_SCENARIO_CUSTOM_PROTOCOL = 'API_SCENARIO_CUSTOM_PROTOCOL', API_SCENARIO_CUSTOM_PROTOCOL = 'API_SCENARIO_CUSTOM_PROTOCOL',
API_NEW_PROTOCOL = 'API_NEW_PROTOCOL', API_NEW_PROTOCOL = 'API_NEW_PROTOCOL',
API_DEBUG_NEW_PROTOCOL = 'API_DEBUG_NEW_PROTOCOL', API_DEBUG_NEW_PROTOCOL = 'API_DEBUG_NEW_PROTOCOL',
CASE_MANAGEMENT_ASSOCIATE_PROTOCOL = 'CASE_MANAGEMENT_ASSOCIATE_PROTOCOL', // 功能用例关联用例
} }

View File

@ -65,7 +65,7 @@
</ms-base-table> </ms-base-table>
<MsCaseAssociate <MsCaseAssociate
v-model:visible="innerVisible" v-model:visible="innerVisible"
v-model:currentSelectCase="currentSelectCase" :current-select-case="currentSelectCase"
:ok-button-disabled="associateForm.reviewers.length === 0" :ok-button-disabled="associateForm.reviewers.length === 0"
:get-modules-func="getModuleTree" :get-modules-func="getModuleTree"
:modules-params="modulesTreeParams" :modules-params="modulesTreeParams"
@ -194,7 +194,6 @@
}); });
const innerVisible = ref(false); const innerVisible = ref(false);
const innerProject = ref(currentProjectId.value);
const associateForm = ref({ const associateForm = ref({
reviewers: [], reviewers: [],
@ -202,7 +201,7 @@
const associatedIds = ref<string[]>([]); const associatedIds = ref<string[]>([]);
const currentSelectCase = ref<keyof typeof CaseLinkEnum>('FUNCTIONAL'); const currentSelectCase = ref<CaseLinkEnum>(CaseLinkEnum.FUNCTIONAL);
const modulesTreeParams = ref<TableQueryParams>({}); const modulesTreeParams = ref<TableQueryParams>({});

View File

@ -53,7 +53,7 @@
<!-- TODO: 涉及接口调整放到下一个版本再替换暂时还是使用原来的 --> <!-- TODO: 涉及接口调整放到下一个版本再替换暂时还是使用原来的 -->
<MsCaseAssociate <MsCaseAssociate
v-model:visible="innerVisible" v-model:visible="innerVisible"
v-model:currentSelectCase="currentSelectCase" :current-select-case="currentSelectCase"
:ok-button-disabled="associateForm.reviewers.length === 0" :ok-button-disabled="associateForm.reviewers.length === 0"
:get-modules-func="getPublicLinkModuleTree" :get-modules-func="getPublicLinkModuleTree"
:modules-params="modulesTreeParams" :modules-params="modulesTreeParams"
@ -191,14 +191,14 @@
const associatedIds = ref<string[]>([]); const associatedIds = ref<string[]>([]);
const currentSelectCase = ref<keyof typeof CaseLinkEnum>('API'); const currentSelectCase = ref<CaseLinkEnum>(CaseLinkEnum.API);
const modulesTreeParams = ref<TableQueryParams>({}); const modulesTreeParams = ref<TableQueryParams>({});
const getTableParams = ref<TableQueryParams>({}); const getTableParams = ref<TableQueryParams>({});
function handleSelect(value: string | number | Record<string, any> | undefined) { function handleSelect(value: string | number | Record<string, any> | undefined) {
currentSelectCase.value = value as keyof typeof CaseLinkEnum; currentSelectCase.value = value as CaseLinkEnum;
innerVisible.value = true; innerVisible.value = true;
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<MsCaseAssociate <MsCaseAssociate
v-model:visible="innerVisible" v-model:visible="innerVisible"
v-model:currentSelectCase="currentSelectCase" :current-select-case="currentSelectCase"
:project-id="innerProject" :project-id="innerProject"
:ok-button-disabled="associateForm.reviewers.length === 0" :ok-button-disabled="associateForm.reviewers.length === 0"
:get-modules-func="getCaseModuleTree" :get-modules-func="getCaseModuleTree"
@ -143,7 +143,7 @@
} }
} }
const currentSelectCase = ref<keyof typeof CaseLinkEnum>('FUNCTIONAL'); const currentSelectCase = ref<CaseLinkEnum>(CaseLinkEnum.FUNCTIONAL);
// const associatedIds = useVModel(props, 'associatedIds', emit); // const associatedIds = useVModel(props, 'associatedIds', emit);
const confirmLoading = ref<boolean>(false); const confirmLoading = ref<boolean>(false);