feat(测试计划): 测试计划报告用例明细设置优化

This commit is contained in:
xinxin.wu 2024-10-08 18:28:50 +08:00 committed by Craftsman
parent b94b8ade44
commit 44285e389a
8 changed files with 399 additions and 23 deletions

View File

@ -109,6 +109,7 @@
:is-simple="(attrs.isSimpleSetting as boolean)"
:only-page-size="!!attrs.onlyPageSize"
:show-pagination="!!attrs.showPagination"
:is-hidden-setting="!!attrs.isHiddenSetting"
@show-setting="handleShowSetting"
@init-data="handleInitColumn"
@page-size-change="pageSizeChange"

View File

@ -7,7 +7,7 @@
trigger="click"
@hide="handleCancel"
>
<icon-settings class="setting-icon" />
<icon-settings :class="`setting-icon ${props.isHiddenSetting ? 'invisible' : 'visible'}`" />
<template #content>
<div class="flex items-center justify-between p-[16px]">
<div class="text-[16px] font-medium text-[var(--color-text-1)]">{{ t('msTable.columnSetting.display') }}</div>
@ -74,7 +74,11 @@
</div>
</template>
</a-popover>
<icon-settings v-else class="setting-icon" @click="handleShowSetting" />
<icon-settings
v-else
:class="`setting-icon ${props.isHiddenSetting ? 'invisible' : 'visible'}`"
@click="handleShowSetting"
/>
</template>
<script setup lang="ts">
@ -112,6 +116,7 @@
isSimple: boolean;
onlyPageSize?: boolean;
showPagination?: boolean;
isHiddenSetting?: boolean; //
}>();
const emit = defineEmits<{

View File

@ -135,6 +135,7 @@ export interface MsTableProps<T> {
rowSelectionDisabledConfig?: MsTableRowSelectionDisabledConfig;
sorter?: Record<string, any>; // 排序
hoverable?: boolean; // 是否展示hover效果
isHiddenSetting?: boolean; // 是否隐藏设置
[key: string]: any;
}

View File

@ -212,6 +212,7 @@
heightUsed: 236,
showSetting: props.isPreview,
isSimpleSetting: true,
isHiddenSetting: props.enabledTestSet,
paginationSize: 'mini',
});
@ -223,6 +224,7 @@
showSetting: props.isPreview,
heightUsed: 236,
isSimpleSetting: true,
isHiddenSetting: props.enabledTestSet,
paginationSize: 'mini',
});
@ -230,7 +232,16 @@
return props.activeType === ReportCardTypeEnum.API_CASE_DETAIL ? useApiTable : useScenarioTable;
});
async function setCurrentPageSize() {
const pageSize = await tableStore.getPageSize(tableKey.value);
const { propsRes } = currentCaseTable.value;
if (propsRes.value.msPagination && propsRes.value.msPagination.pageSize) {
propsRes.value.msPagination.pageSize = pageSize;
}
}
async function loadCaseList() {
setCurrentPageSize();
currentCaseTable.value.setLoadListParams({
reportId: props.reportId,
shareId: props.shareId ?? undefined,
@ -308,7 +319,9 @@
loadCaseList,
});
await tableStore.initColumn(tableKey.value, columns.value, 'drawer');
if (!props.enabledTestSet) {
await tableStore.initColumn(tableKey.value, columns.value, 'drawer');
}
</script>
<style lang="less" scoped></style>

View File

@ -1,6 +1,6 @@
<template>
<div :class="`${props.enabledTestSet ? 'test-set-wrapper' : ''}`">
<MsBaseTable v-bind="propsRes" :row-class="getRowClass" v-on="propsEvent">
<MsBaseTable ref="tableRef" v-bind="propsRes" :row-class="getRowClass" v-on="propsEvent">
<template #num="{ record }">
<MsButton :disabled="!props.isPreview" type="text" @click="toDetail(record)">{{ record.num }}</MsButton>
</template>
@ -211,6 +211,7 @@
}
return TableKeyEnum.TEST_PLAN_REPORT_FUNCTIONAL_TABLE_NOT_PREVIEW;
});
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(reportFeatureCaseList(), {
tableKey: tableKey.value,
columns: columns.value,
@ -218,11 +219,21 @@
heightUsed: 236,
showSetting: props.isPreview,
isSimpleSetting: true,
isHiddenSetting: props.enabledTestSet,
paginationSize: 'mini',
showSelectorAll: false,
});
async function setCurrentPageSize() {
const pageSize = await tableStore.getPageSize(tableKey.value);
if (propsRes.value.msPagination && propsRes.value.msPagination.pageSize) {
propsRes.value.msPagination.pageSize = pageSize;
}
}
const tableRef = ref();
async function loadCaseList() {
await setCurrentPageSize();
setLoadListParams({
reportId: props.reportId,
keyword: innerKeyword.value,
@ -239,21 +250,6 @@
});
}
watch(
() => props.reportId,
(val) => {
if (val) {
loadCaseList();
}
}
);
onMounted(() => {
if (props.isPreview && props.reportId) {
loadCaseList();
}
});
const showDetailVisible = ref<boolean>(false);
const executeReportId = ref<string>('');
@ -300,11 +296,28 @@
}
);
watch(
() => props.reportId,
(val) => {
if (val) {
loadCaseList();
}
}
);
onMounted(() => {
if (props.isPreview && props.reportId) {
loadCaseList();
}
});
defineExpose({
loadCaseList,
});
await tableStore.initColumn(tableKey.value, columns.value, 'drawer');
if (!props.enabledTestSet) {
await tableStore.initColumn(tableKey.value, columns.value, 'drawer');
}
</script>
<style lang="less" scoped></style>

View File

@ -23,21 +23,41 @@
<template #empty>
<span></span>
</template>
<template #outContent>
<span></span>
</template>
<template #operation>
<ColumnSelectorIcon
:table-key="props.tableKey"
:is-simple="true"
:only-page-size="false"
:show-pagination="true"
@init-data="handleInitColumn"
@page-size-change="pageSizeChange"
/>
</template>
</MsBaseTable>
</template>
<script setup lang="ts">
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import ColumnSelectorIcon from '@/components/pure/ms-table/columnSelectorIcon.vue';
import type { MsTableColumn } from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import ApiAndScenarioTable from '@/views/test-plan/report/detail/component/system-card/apiAndScenarioTable.vue';
import FeatureCaseTable from '@/views/test-plan/report/detail/component/system-card/featureCaseTable.vue';
import { getCollectApiPage, getCollectFunctionalPage, getCollectScenarioPage } from '@/api/modules/test-plan/report';
import useTableStore from '@/hooks/useTableStore';
import type { SelectedReportCardTypes } from '@/models/testPlan/testPlanReport';
import { TableKeyEnum } from '@/enums/tableEnum';
import { ReportCardTypeEnum } from '@/enums/testPlanReportEnum';
import { getApiDetailColumn, getFeatureColumns } from '@/views/test-plan/report/utils';
const tableStore = useTableStore();
const props = defineProps<{
enabledTestSet: boolean;
activeType: ReportCardTypeEnum; //
@ -45,9 +65,18 @@
reportId: string;
shareId?: string;
isPreview?: boolean;
tableKey: TableKeyEnum;
}>();
const expandedKeys = ref<string[]>([]);
const emit = defineEmits<{
(e: 'pageSizeChange', pageSize: number): void;
(e: 'initColumn'): void;
}>();
const expandedKeys = defineModel<string[]>('expandedKeys', {
required: true,
});
const isGroup = inject<Ref<boolean>>('isPlanGroup', ref(false));
const expandable = reactive({
@ -119,6 +148,20 @@
showDrag: true,
width: 300,
},
{
title: '',
dataIndex: 'other',
slotName: 'other',
showInTable: true,
showDrag: true,
width: 300,
},
{
title: '',
titleSlotName: 'operation',
slotName: 'outContent',
width: 30,
},
];
}
return [
@ -146,6 +189,20 @@
showDrag: true,
width: 300,
},
{
title: '',
dataIndex: 'empty',
slotName: 'empty',
showInTable: true,
showDrag: true,
width: 300,
},
{
title: '',
titleSlotName: 'operation',
slotName: 'outContent',
width: 30,
},
];
});
@ -163,6 +220,7 @@
columns: columns.value,
scroll: { x: '100%' },
heightUsed: 320,
isSimpleSetting: true,
showSelectorAll: false,
});
@ -189,6 +247,34 @@
}
);
//
async function pageSizeChange(pageSize: number) {
emit('pageSizeChange', pageSize);
}
//
async function handleInitColumn() {
emit('initColumn');
}
function getTestSetColumns(): MsTableColumn | undefined {
const apiAndScenarioDetail = [ReportCardTypeEnum.API_CASE_DETAIL, ReportCardTypeEnum.SCENARIO_CASE_DETAIL];
if (props.activeType === ReportCardTypeEnum.FUNCTIONAL_DETAIL) {
return getFeatureColumns(isGroup.value, props.isPreview);
}
if (apiAndScenarioDetail.includes(props.activeType)) {
return getApiDetailColumn(isGroup.value, props.isPreview);
}
}
async function initSetColumnConfig() {
const detailColumns = await getTestSetColumns();
if (detailColumns && props.enabledTestSet) {
await tableStore.initColumn(props.tableKey, detailColumns, 'drawer');
}
}
initSetColumnConfig();
defineExpose({
loadCaseList,
});

View File

@ -20,11 +20,15 @@
v-if="showSetTable"
ref="testSetTableRef"
v-model:keyword="keyword"
v-model:expandedKeys="expandedKeys"
:active-type="props.activeType"
:report-id="props.reportId"
:share-id="props.shareId"
:is-preview="props.isPreview"
:enabled-test-set="enabledTestSet"
:table-key="tableKey"
@page-size-change="pageSizeChange"
@init-column="handleInitColumn"
/>
<!-- 功能用例明细 -->
<FeatureCaseTable
@ -55,8 +59,10 @@
import FeatureCaseTable from '@/views/test-plan/report/detail/component/system-card/featureCaseTable.vue';
import { useI18n } from '@/hooks/useI18n';
import useTableStore from '@/hooks/useTableStore';
import useTestPlanReportStore from '@/store/modules/testPlan/testPlanReport';
import { TableKeyEnum } from '@/enums/tableEnum';
import { ReportCardTypeEnum } from '@/enums/testPlanReportEnum';
const props = defineProps<{
@ -68,12 +74,14 @@
}>();
const { t } = useI18n();
const testPlanReportStore = useTestPlanReportStore();
const tableStore = useTableStore();
const keyword = ref<string>('');
const expandedKeys = ref<string[]>([]);
const testSetTableRef = ref<InstanceType<typeof TestSetTable>>();
const featureCaseTableRef = ref<InstanceType<typeof TestSetTable>>();
const apiAndScenarioTableRef = ref<InstanceType<typeof TestSetTable>>();
const featureCaseTableRef = ref<InstanceType<typeof FeatureCaseTable>>();
const apiAndScenarioTableRef = ref<InstanceType<typeof ApiAndScenarioTable>>();
const isGroup = inject<Ref<boolean>>('isPlanGroup', ref(false));
const enabledTestSet = computed({
@ -94,6 +102,32 @@
}
}
const tableKeyMap: Record<string, Record<string, TableKeyEnum>> = {
[ReportCardTypeEnum.FUNCTIONAL_DETAIL]: {
GROUP: TableKeyEnum.TEST_PLAN_REPORT_FUNCTIONAL_TABLE_GROUP,
TEST_PLAN: TableKeyEnum.TEST_PLAN_REPORT_FUNCTIONAL_TABLE,
NOT_PREVIEW: TableKeyEnum.TEST_PLAN_REPORT_FUNCTIONAL_TABLE_NOT_PREVIEW,
},
[ReportCardTypeEnum.API_CASE_DETAIL]: {
GROUP: TableKeyEnum.TEST_PLAN_REPORT_API_TABLE_GROUP,
TEST_PLAN: TableKeyEnum.TEST_PLAN_REPORT_API_TABLE,
NOT_PREVIEW: TableKeyEnum.TEST_PLAN_REPORT_API_TABLE_NOT_PREVIEW,
},
[ReportCardTypeEnum.SCENARIO_CASE_DETAIL]: {
GROUP: TableKeyEnum.TEST_PLAN_REPORT_SCENARIO_TABLE_GROUP,
TEST_PLAN: TableKeyEnum.TEST_PLAN_REPORT_SCENARIO_TABLE,
NOT_PREVIEW: TableKeyEnum.TEST_PLAN_REPORT_API_TABLE_NOT_PREVIEW,
},
};
const tableKey = computed(() => {
if (props.isPreview) {
const groupKey = isGroup.value ? 'GROUP' : 'TEST_PLAN';
return tableKeyMap[props.activeType][groupKey];
}
return tableKeyMap[props.activeType].NOT_PREVIEW;
});
function clearHandler() {
keyword.value = '';
searchList();
@ -126,6 +160,18 @@
keyword.value = '';
testPlanReportStore.setTestStatus(isGroup.value, value, props.activeType);
}
//
async function pageSizeChange(pageSize: number) {
await tableStore.setPageSize(tableKey.value, pageSize);
}
//
async function handleInitColumn() {
if (enabledTestSet.value) {
expandedKeys.value = [];
}
}
</script>
<style lang="less" scoped>

View File

@ -1,4 +1,13 @@
import { TableSortable } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es';
import type { MsTableColumn } from '@/components/pure/ms-table/type';
import type { countDetail } from '@/models/testPlan/testPlanReport';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
import { executionResultMap } from '@/views/case-management/caseManagementFeature/components/utils';
export function getSummaryDetail(detailCount: countDetail) {
if (detailCount) {
@ -32,4 +41,206 @@ export function getSummaryDetail(detailCount: countDetail) {
};
}
// 获取用例明细的表头
export function getFeatureColumns(isGroup: boolean, isPreview: boolean): MsTableColumn {
const sortableConfig = computed<TableSortable | undefined>(() => {
return isPreview
? {
sortDirections: ['ascend', 'descend'],
sorter: true,
}
: undefined;
});
const staticColumns: MsTableColumn = [
{
title: 'ID',
dataIndex: 'num',
slotName: 'num',
sortIndex: 1,
width: 150,
showTooltip: true,
showInTable: true,
columnSelectorDisabled: true,
},
{
title: 'case.caseName',
dataIndex: 'name',
showTooltip: true,
sortable: cloneDeep(sortableConfig.value),
width: 180,
showInTable: true,
columnSelectorDisabled: true,
},
{
title: 'common.executionResult',
dataIndex: 'executeResult',
slotName: 'lastExecResult',
filterConfig: {
valueKey: 'key',
labelKey: 'statusText',
options: isPreview ? Object.values(executionResultMap) : [],
filterSlotName: FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT,
},
showInTable: true,
showDrag: true,
width: 150,
},
];
const lastStaticColumns: MsTableColumn = [
{
title: 'common.belongModule',
dataIndex: 'moduleName',
ellipsis: true,
showTooltip: true,
showInTable: true,
showDrag: true,
width: 200,
},
{
title: 'case.caseLevel',
dataIndex: 'priority',
slotName: 'caseLevel',
showInTable: true,
showDrag: true,
width: 120,
},
{
title: 'testPlan.featureCase.executor',
dataIndex: 'executeUser',
showTooltip: true,
showInTable: true,
showDrag: true,
width: 150,
},
{
title: 'testPlan.featureCase.bugCount',
dataIndex: 'bugCount',
showInTable: true,
showDrag: true,
width: 100,
},
{
title: '',
slotName: 'operation',
dataIndex: 'operation',
width: 30,
},
];
const testPlanNameColumns: MsTableColumn = [
{
title: 'report.plan.name',
dataIndex: 'planName',
showTooltip: true,
showInTable: true,
showDrag: false,
columnSelectorDisabled: true,
width: 200,
},
];
if (isGroup) {
return [...staticColumns, ...testPlanNameColumns, ...lastStaticColumns];
}
return [...staticColumns, ...lastStaticColumns];
}
// 获取接口明细的表头
export function getApiDetailColumn(isGroup: boolean, isPreview: boolean): MsTableColumn {
const staticColumns: MsTableColumn = [
{
title: 'ID',
dataIndex: 'num',
slotName: 'num',
sortIndex: 1,
width: 100,
showInTable: true,
showTooltip: true,
columnSelectorDisabled: true,
},
{
title: 'common.name',
dataIndex: 'name',
width: 150,
showTooltip: true,
showInTable: true,
columnSelectorDisabled: true,
},
{
title: 'report.detail.level',
dataIndex: 'priority',
slotName: 'priority',
filterConfig: {
options: isPreview ? casePriorityOptions : [],
filterSlotName: FilterSlotNameEnum.CASE_MANAGEMENT_CASE_LEVEL,
},
width: 150,
showInTable: true,
showDrag: true,
},
{
title: 'common.executionResult',
dataIndex: 'executeResult',
slotName: 'lastExecResult',
filterConfig: {
options: isPreview ? lastReportStatusListOptions.value : [],
filterSlotName: FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS,
},
width: 150,
showInTable: true,
showDrag: true,
},
];
const testPlanNameColumns: MsTableColumn = [
{
title: 'report.plan.name',
dataIndex: 'planName',
showTooltip: true,
width: 200,
showInTable: true,
showDrag: false,
columnSelectorDisabled: true,
},
];
const lastStaticColumns: MsTableColumn = [
{
title: 'common.belongModule',
dataIndex: 'moduleName',
showTooltip: true,
width: 200,
showInTable: true,
showDrag: true,
},
{
title: 'testPlan.featureCase.executor',
dataIndex: 'executeUser',
showTooltip: true,
width: 130,
showInTable: true,
showDrag: true,
},
{
title: 'testPlan.featureCase.bugCount',
dataIndex: 'bugCount',
slotName: 'bugCount',
width: 100,
showInTable: true,
showDrag: true,
},
{
title: '',
slotName: 'operation',
dataIndex: 'operation',
width: 30,
},
];
if (isGroup) {
return [...staticColumns, ...testPlanNameColumns, ...lastStaticColumns];
}
return [...staticColumns, ...lastStaticColumns];
}
export default {};