feat(测试计划): 测试计划表补充遗漏&细节
This commit is contained in:
parent
a872b43c9d
commit
4358a82355
|
@ -28,6 +28,8 @@ export default {
|
|||
'common.updateSuccess': 'Update success',
|
||||
'common.updateFailed': 'Update failed',
|
||||
'common.deleteConfirm': 'Delete confirm',
|
||||
'common.deleteConfirmTitle': 'Delete confirm {name} 吗',
|
||||
'common.archiveConfirmTitle': 'Archive confirm {name} 吗',
|
||||
'common.deleteSuccess': 'Delete success',
|
||||
'common.deleteFailed': 'Delete failed',
|
||||
'common.addSuccess': 'Added successfully',
|
||||
|
@ -121,6 +123,7 @@ export default {
|
|||
'common.move': 'Move',
|
||||
'common.moveSuccess': 'Move successful',
|
||||
'common.batchMove': 'Batch move',
|
||||
'common.batchArchiveSuccess': 'Archive successful',
|
||||
'common.batchCopy': 'Batch copy',
|
||||
'common.batchCopySuccess': 'Batch copy successful',
|
||||
'common.batchMoveSuccess': 'Batch move successful',
|
||||
|
|
|
@ -30,6 +30,7 @@ export default {
|
|||
'common.updateFailed': '更新失败',
|
||||
'common.deleteConfirm': '确认删除?',
|
||||
'common.deleteConfirmTitle': '确认删除 {name} 吗',
|
||||
'common.archiveConfirmTitle': '确认归档 {name} 吗',
|
||||
'common.deleteSuccess': '删除成功',
|
||||
'common.deleteFailed': '删除失败',
|
||||
'common.addSuccess': '添加成功',
|
||||
|
@ -122,6 +123,7 @@ export default {
|
|||
'common.move': '移动',
|
||||
'common.moveSuccess': '移动成功',
|
||||
'common.batchMove': '批量移动',
|
||||
'common.batchArchiveSuccess': '归档成功!',
|
||||
'common.batchCopy': '批量复制',
|
||||
'common.batchCopySuccess': '批量复制成功',
|
||||
'common.batchMoveSuccess': '批量移动成功',
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { BatchApiParams } from '../common';
|
||||
|
||||
export type planStatusType = 'PREPARED' | 'UNDERWAY' | 'COMPLETED' | 'ARCHIVED';
|
||||
|
||||
// 计划分页
|
||||
export interface TestPlanItem {
|
||||
id?: string;
|
||||
projectId: string;
|
||||
num: number;
|
||||
name: string;
|
||||
status: string;
|
||||
status: planStatusType;
|
||||
type: string;
|
||||
tags: string[];
|
||||
schedule: string; // 是否定时
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="showModalVisible"
|
||||
class="ms-modal-form ms-modal-no-padding ms-modal-small"
|
||||
unmount-on-close
|
||||
title-align="start"
|
||||
:mask="true"
|
||||
:mask-closable="false"
|
||||
@close="cancelHandler"
|
||||
>
|
||||
<template #title>
|
||||
<div class="flex items-center justify-start">
|
||||
<MsIcon type="icon-icon_close_colorful" class="mr-[8px] text-[rgb(var(--danger-6))]" size="16" />
|
||||
<div class="text-[var(--color-text-1)]">
|
||||
{{ t('common.deleteConfirmTitle', { name: characterLimit(record?.name) }) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
{{ contentTip }}
|
||||
<template #footer>
|
||||
<div class="flex justify-end">
|
||||
<a-button type="secondary" :disabled="confirmLoading" @click="cancelHandler">
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
<a-button class="ml-3" type="primary" status="danger" :loading="confirmLoading" @click="confirmHandler(true)">
|
||||
{{ t('common.confirmDelete') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
v-if="props.record?.status === 'COMPLETED'"
|
||||
:loading="confirmLoading"
|
||||
class="ml-3"
|
||||
type="primary"
|
||||
@click="confirmHandler(false)"
|
||||
>
|
||||
{{ t('common.archive') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import type { TestPlanItem } from '@/models/testPlan/testPlan';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
// isScheduled: boolean; // TODO 这个版本不做有无定时任务区分
|
||||
record: TestPlanItem | undefined; // 表record
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', val: boolean): void;
|
||||
}>();
|
||||
|
||||
const showModalVisible = useVModel(props, 'visible', emit);
|
||||
|
||||
function cancelHandler() {
|
||||
showModalVisible.value = false;
|
||||
}
|
||||
|
||||
const confirmLoading = ref<boolean>(false);
|
||||
function confirmHandler(isDelete: boolean) {
|
||||
try {
|
||||
Message.success(isDelete ? t('common.deleteSuccess') : t('common.batchArchiveSuccess'));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function getDeleteTip() {
|
||||
switch (props.record && props.record.status) {
|
||||
case 'ARCHIVED':
|
||||
return t('testPlan.testPlanIndex.deleteArchivedPlan');
|
||||
case 'UNDERWAY':
|
||||
return t('testPlan.testPlanIndex.deleteRunningPlan');
|
||||
case 'COMPLETED':
|
||||
return t('testPlan.testPlanIndex.deleteCompletedPlan');
|
||||
default:
|
||||
return t('testPlan.testPlanIndex.deletePendingPlan');
|
||||
}
|
||||
}
|
||||
|
||||
const contentTip = computed(() => {
|
||||
return getDeleteTip();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.ms-modal-form .arco-modal-body) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,180 @@
|
|||
<template>
|
||||
<MsDialog
|
||||
v-model:visible="isVisible"
|
||||
dialog-size="small"
|
||||
:title="t('testPlan.testPlanIndex.batchEdit', { number: props.batchParams.currentSelectCount })"
|
||||
ok-text="common.update"
|
||||
:confirm="confirmHandler"
|
||||
:close="closeHandler"
|
||||
unmount-on-close
|
||||
:switch-props="{
|
||||
switchName: t('caseManagement.featureCase.appendTag'),
|
||||
switchTooltip: t('caseManagement.featureCase.enableTags'),
|
||||
showSwitch: form.selectedAttrsId === 'tags' ? true : false,
|
||||
enable: form.append,
|
||||
}"
|
||||
>
|
||||
<div class="form">
|
||||
<a-form ref="formRef" class="rounded-[4px]" :model="form" layout="vertical">
|
||||
<a-form-item
|
||||
field="selectedAttrsId"
|
||||
:label="t('apiTestManagement.chooseAttr')"
|
||||
:rules="[{ required: true, message: t('apiTestManagement.attrRequired') }]"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-select v-model="form.selectedAttrsId" :placeholder="t('common.pleaseSelect')">
|
||||
<a-option v-for="item of attrOptions" :key="item.value" :value="item.value">
|
||||
{{ t(item.name) }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="form.selectedAttrsId === 'tags'"
|
||||
field="values"
|
||||
:label="t('apiTestManagement.batchUpdate')"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
:rules="[{ required: true, message: t('apiTestManagement.valueRequired') }]"
|
||||
asterisk-position="end"
|
||||
class="mb-0"
|
||||
required
|
||||
>
|
||||
<MsTagsInput
|
||||
v-model:model-value="form.tags"
|
||||
placeholder="common.tagsInputPlaceholder"
|
||||
allow-clear
|
||||
unique-value
|
||||
retain-input-value
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-else
|
||||
field="value"
|
||||
:label="t('apiTestManagement.batchUpdate')"
|
||||
:rules="[{ required: true, message: t('apiTestManagement.valueRequired') }]"
|
||||
asterisk-position="end"
|
||||
class="mb-0"
|
||||
>
|
||||
<a-select
|
||||
v-model="form.value"
|
||||
:placeholder="t('common.pleaseSelect')"
|
||||
:disabled="form.selectedAttrsId === ''"
|
||||
>
|
||||
<a-option v-for="item of valueOptions" :key="item.value" :value="item.value">
|
||||
{{ t(item.label) }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</MsDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { FormInstance } from '@arco-design/web-vue';
|
||||
|
||||
import MsDialog from '@/components/pure/ms-dialog/index.vue';
|
||||
import type { BatchActionQueryParams } from '@/components/pure/ms-table/type';
|
||||
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import { TableQueryParams } from '@/models/common';
|
||||
|
||||
import Message from '@arco-design/web-vue/es/message';
|
||||
|
||||
const isVisible = ref<boolean>(false);
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
batchParams: BatchActionQueryParams;
|
||||
activeFolder: string;
|
||||
offspringIds: string[];
|
||||
condition?: TableQueryParams;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
(e: 'success'): void;
|
||||
}>();
|
||||
|
||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||
const initForm = {
|
||||
selectedAttrsId: '',
|
||||
append: false,
|
||||
tags: [],
|
||||
value: '',
|
||||
};
|
||||
const form = ref({ ...initForm });
|
||||
|
||||
const attrOptions = [
|
||||
{
|
||||
name: 'common.tag',
|
||||
value: 'tags',
|
||||
},
|
||||
];
|
||||
|
||||
const formRef = ref<FormInstance | null>(null);
|
||||
|
||||
function closeHandler() {
|
||||
isVisible.value = false;
|
||||
formRef.value?.resetFields();
|
||||
form.value = { ...initForm };
|
||||
form.value.tags = [];
|
||||
}
|
||||
|
||||
async function confirmHandler(enable: boolean | undefined) {
|
||||
await formRef.value?.validate().then(async (error) => {
|
||||
if (!error) {
|
||||
try {
|
||||
const customField = {
|
||||
fieldId: '',
|
||||
value: '',
|
||||
};
|
||||
const { selectedIds, selectAll, excludeIds } = props.batchParams;
|
||||
const params: TableQueryParams = {
|
||||
selectIds: selectedIds || [],
|
||||
selectAll: !!selectAll,
|
||||
excludeIds: excludeIds || [],
|
||||
projectId: currentProjectId.value,
|
||||
append: enable as boolean,
|
||||
tags: form.value.tags,
|
||||
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
|
||||
customField: form.value.selectedAttrsId === 'systemTags' ? {} : customField,
|
||||
condition: {
|
||||
...props.condition,
|
||||
},
|
||||
};
|
||||
Message.success(t('caseManagement.featureCase.editSuccess'));
|
||||
closeHandler();
|
||||
emits('success');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const valueOptions = ref<{ value: string; label: string }[]>([]);
|
||||
|
||||
watch(
|
||||
() => isVisible.value,
|
||||
(val) => {
|
||||
emits('update:visible', val);
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(val) => {
|
||||
isVisible.value = val;
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -10,31 +10,47 @@
|
|||
@refresh="fetchData"
|
||||
>
|
||||
<template #left>
|
||||
<a-radio-group v-model="showType" type="button" class="file-show-type mr-2">
|
||||
<!-- TODO 这个版本不上 -->
|
||||
<!-- <a-radio-group v-model="showType" type="button" class="file-show-type mr-2">
|
||||
<a-radio :value="testPlanTypeEnum.ALL" class="show-type-icon p-[2px]">{{
|
||||
t('testPlan.testPlanIndex.all')
|
||||
}}</a-radio>
|
||||
<a-radio :value="testPlanTypeEnum.TEST_PLAN" class="show-type-icon p-[2px]">{{
|
||||
t('testPlan.testPlanIndex.testPlan')
|
||||
}}</a-radio>
|
||||
<!-- <a-radio value="testPlanGroup" class="show-type-icon p-[2px]">{{
|
||||
t('testPlan.testPlanIndex.testPlanGroup')
|
||||
}}</a-radio> -->
|
||||
</a-radio-group>
|
||||
<a-radio value="testPlanGroup" class="show-type-icon p-[2px]">{{
|
||||
t('testPlan.testPlanIndex.testPlanGroup')
|
||||
}}</a-radio>
|
||||
</a-radio-group> -->
|
||||
<a-popover title="" position="bottom">
|
||||
<div class="flex">
|
||||
<div class="one-line-text mr-1 max-h-[32px] max-w-[116px] text-[var(--color-text-1)]">
|
||||
{{ props.activeFolder === 'all' ? t('testPlan.testPlanIndex.allTestPlan') : props.nodeName }}
|
||||
</div>
|
||||
<span class="text-[var(--color-text-4)]"> ({{ props.modulesCount[props.activeFolder] || 0 }})</span>
|
||||
</div>
|
||||
<template #content>
|
||||
<div class="max-w-[400px] text-[14px] font-medium text-[var(--color-text-1)]">
|
||||
{{ props.nodeName }}
|
||||
<span class="text-[var(--color-text-4)]">({{ props.modulesCount[props.activeFolder] || 0 }})</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</template>
|
||||
</MsAdvanceFilter>
|
||||
<MsBaseTable
|
||||
v-bind="propsRes"
|
||||
ref="tableRef"
|
||||
class="mt-4"
|
||||
:action-config="tableBatchActions"
|
||||
:expanded-keys="expandedKeys"
|
||||
:action-config="testPlanBatchActions"
|
||||
filter-icon-align-left
|
||||
v-on="propsEvent"
|
||||
@batch-action="handleTableBatch"
|
||||
>
|
||||
<!-- :expanded-keys="expandedKeys" -->
|
||||
<template #num="{ record }">
|
||||
<div class="flex items-center">
|
||||
<!-- TODO 这个版本不做 -->
|
||||
<!-- <div class="flex items-center">
|
||||
<div v-if="record.childrenCount" class="mr-2 flex items-center" @click="expandHandler(record)">
|
||||
<MsIcon
|
||||
type="icon-icon_split-turn-down-left"
|
||||
|
@ -56,17 +72,30 @@
|
|||
<div>
|
||||
<div>{{ t('testPlan.testPlanIndex.scheduledTaskOpened') }}</div>
|
||||
<div>{{ t('testPlan.testPlanIndex.nextExecutionTime') }}</div>
|
||||
<!-- TODO 缺少字段 -->
|
||||
<div>---</div>
|
||||
</div>
|
||||
<!-- TODO 缺少字段 -->
|
||||
<!-- <div> {{ t('testPlan.testPlanIndex.scheduledTaskUnEnable') }} </div> -->
|
||||
<div> {{ t('testPlan.testPlanIndex.scheduledTaskUnEnable') }} </div>
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="flex items-center">
|
||||
<div class="one-line-text cursor-pointer text-[rgb(var(--primary-5))]">{{ record.num }}</div>
|
||||
<a-tooltip position="right" :disabled="!record.schedule" :mouse-enter-delay="300">
|
||||
<MsTag v-if="record.schedule" size="small" type="link" theme="outline" class="ml-2">{{
|
||||
t('testPlan.testPlanIndex.timing')
|
||||
}}</MsTag>
|
||||
<template #content>
|
||||
<div>
|
||||
<div>{{ t('testPlan.testPlanIndex.scheduledTaskOpened') }}</div>
|
||||
<div>{{ t('testPlan.testPlanIndex.nextExecutionTime') }}</div>
|
||||
</div>
|
||||
<div> {{ t('testPlan.testPlanIndex.scheduledTaskUnEnable') }} </div>
|
||||
</template>
|
||||
</a-tooltip></div
|
||||
>
|
||||
</template>
|
||||
<template #statusFilter="{ columnConfig }">
|
||||
<a-trigger v-model:popup-visible="statusFilterVisible" trigger="click" @popup-visible-change="handleFilterHidden">
|
||||
<a-trigger v-model:popup-visible="statusFilterVisible" @popup-visible-change="handleFilterHidden">
|
||||
<a-button type="text" class="arco-btn-text--secondary" @click="statusFilterVisible = true">
|
||||
{{ t(columnConfig.title as string) }}
|
||||
<icon-down :class="statusFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
||||
|
@ -75,13 +104,13 @@
|
|||
<div class="arco-table-filters-content">
|
||||
<div class="flex items-center justify-center px-[6px] py-[2px]">
|
||||
<a-checkbox-group v-model:model-value="statusFilters" direction="vertical" size="small">
|
||||
<a-checkbox v-for="key of Object.keys(reviewStatusMap)" :key="key" :value="key">
|
||||
<a-checkbox v-for="key of Object.keys(planStatusMap)" :key="key" :value="key">
|
||||
<a-tag
|
||||
:color="reviewStatusMap[key as ReviewStatus].color"
|
||||
:class="[reviewStatusMap[key as ReviewStatus].class, 'px-[4px]']"
|
||||
:color="planStatusMap[key as planStatusType].color"
|
||||
:class="[planStatusMap[key as planStatusType].class, 'px-[4px]']"
|
||||
size="small"
|
||||
>
|
||||
{{ t(reviewStatusMap[key as ReviewStatus].label) }}
|
||||
{{ t(planStatusMap[key as planStatusType].label) }}
|
||||
</a-tag>
|
||||
</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
|
@ -103,38 +132,33 @@
|
|||
<statusTag :status="record.status" />
|
||||
</template>
|
||||
|
||||
<template #passRate="{ record }">
|
||||
<!-- <template #passRate="{ record }">
|
||||
<div class="mr-[8px] w-[100px]">
|
||||
<StatusProgress :status-detail="record.statusDetail" height="5px" />
|
||||
</div>
|
||||
<div class="text-[var(--color-text-1)]">
|
||||
{{ `${record.passRate || 0}%` }}
|
||||
</div>
|
||||
</template>
|
||||
</template> -->
|
||||
<template #passRateTitleSlot="{ columnConfig }">
|
||||
<div class="flex items-center text-[var(--color-text-3)]">
|
||||
{{ t(columnConfig.title as string) }}
|
||||
<a-tooltip position="right">
|
||||
<a-tooltip position="right" :content="t('testPlan.testPlanIndex.passRateTitleTip')">
|
||||
<icon-question-circle
|
||||
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
|
||||
class="ml-[4px] text-[var(--color-text-4)] hover:text-[rgb(var(--primary-5))]"
|
||||
size="16"
|
||||
/>
|
||||
<template #content>
|
||||
<!-- TODO 需要提供文案 -->
|
||||
<!-- <div>{{ t('apiTestDebug.encodeTip1') }}</div>
|
||||
<div>{{ t('apiTestDebug.encodeTip2') }}</div> -->
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<template #useCount="{ record }">
|
||||
<!-- <template #useCount="{ record }">
|
||||
<a-popover position="bottom" content-class="p-[16px]" trigger="click">
|
||||
<div>{{ record.useCaseCount.caseCount }}</div>
|
||||
<template #content>
|
||||
<table class="min-w-[144px]">
|
||||
<tr>
|
||||
<td class="popover-label-td">
|
||||
<div>{{ t('project.testPlanIndex.TotalCases') }}</div>
|
||||
<div>{{ t('testPlan.testPlanIndex.TotalCases') }}</div>
|
||||
</td>
|
||||
<td class="popover-value-td">
|
||||
{{ record.useCaseCount.caseCount }}
|
||||
|
@ -142,7 +166,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="popover-label-td">
|
||||
<div class="text-[var(--color-text-1)]">{{ t('project.testPlanIndex.functionalUseCase') }}</div>
|
||||
<div class="text-[var(--color-text-1)]">{{ t('testPlan.testPlanIndex.functionalUseCase') }}</div>
|
||||
</td>
|
||||
<td class="popover-value-td">
|
||||
{{ record.useCaseCount.caseCount }}
|
||||
|
@ -150,7 +174,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="popover-label-td">
|
||||
<div class="text-[var(--color-text-1)]">{{ t('project.testPlanIndex.apiCase') }}</div>
|
||||
<div class="text-[var(--color-text-1)]">{{ t('testPlan.testPlanIndex.apiCase') }}</div>
|
||||
</td>
|
||||
<td class="popover-value-td">
|
||||
{{ record.useCaseCount.caseCount }}
|
||||
|
@ -158,7 +182,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="popover-label-td">
|
||||
<div class="text-[var(--color-text-1)]">{{ t('project.testPlanIndex.apiScenarioCase') }}</div>
|
||||
<div class="text-[var(--color-text-1)]">{{ t('testPlan.testPlanIndex.apiScenarioCase') }}</div>
|
||||
</td>
|
||||
<td class="popover-value-td">
|
||||
{{ record.useCaseCount.caseCount }}
|
||||
|
@ -167,7 +191,7 @@
|
|||
</table>
|
||||
</template>
|
||||
</a-popover>
|
||||
</template>
|
||||
</template> -->
|
||||
|
||||
<template #operation="{ record }">
|
||||
<div class="flex items-center">
|
||||
|
@ -218,37 +242,51 @@
|
|||
@save="handleMoveOrCopy"
|
||||
/>
|
||||
<ScheduledModal v-model:visible="showScheduledTaskModal" />
|
||||
<ActionModal v-model:visible="showStatusDeleteModal" :record="activeRecord" />
|
||||
<BatchEditModal
|
||||
v-model:visible="showEditModel"
|
||||
:batch-params="batchParams"
|
||||
:active-folder="props.activeFolder"
|
||||
:offspring-ids="props.offspringIds"
|
||||
:condition="conditionParams"
|
||||
@success="successHandler"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import { MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
|
||||
import { FilterFormItem } from '@/components/pure/ms-advance-filter/type';
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import ActionModal from './actionModal.vue';
|
||||
import BatchEditModal from './batchEditModal.vue';
|
||||
import BatchMoveOrCopy from './batchMoveOrCopy.vue';
|
||||
import ScheduledModal from './scheduledModal.vue';
|
||||
import StatusProgress from './statusProgress.vue';
|
||||
import statusTag from '@/views/case-management/caseReview/components/statusTag.vue';
|
||||
|
||||
import { getTestPlanList, getTestPlanModule } from '@/api/modules/test-plan/testPlan';
|
||||
import { reviewStatusMap } from '@/config/caseManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import { ReviewStatus } from '@/models/caseManagement/caseReview';
|
||||
import type { planStatusType, TestPlanItem } from '@/models/testPlan/testPlan';
|
||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { testPlanTypeEnum } from '@/enums/testPlanEnum';
|
||||
|
||||
import { planStatusMap } from '../config';
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
|
@ -259,6 +297,7 @@
|
|||
activeFolderType: 'folder' | 'module';
|
||||
offspringIds: string[]; // 当前选中文件夹的所有子孙节点id
|
||||
modulesCount: Record<string, number>; // 模块数量
|
||||
nodeName: string; // 选中模块名称
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@ -413,13 +452,20 @@
|
|||
const keyword = ref<string>('');
|
||||
const statusFilterVisible = ref(false);
|
||||
const statusFilters = ref<string[]>([]);
|
||||
const showType = ref<keyof typeof testPlanTypeEnum>(testPlanTypeEnum.TEST_PLAN);
|
||||
|
||||
const tableBatchActions = {
|
||||
const testPlanBatchActions = {
|
||||
baseAction: [
|
||||
// TODO 批量执行不上这个版本
|
||||
// {
|
||||
// label: 'testPlan.testPlanIndex.execute',
|
||||
// eventTag: 'execute',
|
||||
// permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
|
||||
// },
|
||||
{
|
||||
label: 'testPlan.testPlanIndex.execute',
|
||||
eventTag: 'execute',
|
||||
permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
|
||||
label: 'common.edit',
|
||||
eventTag: 'edit',
|
||||
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'common.copy',
|
||||
|
@ -430,23 +476,23 @@
|
|||
// label: 'common.export',
|
||||
// eventTag: 'export',
|
||||
// },
|
||||
],
|
||||
moreAction: [
|
||||
// {
|
||||
// label: 'testPlan.testPlanIndex.openTimingTask',
|
||||
// eventTag: 'openTimingTask',
|
||||
// permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
|
||||
// },
|
||||
// {
|
||||
// label: 'testPlan.testPlanIndex.closeTimingTask',
|
||||
// eventTag: 'closeTimingTask',
|
||||
// permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
|
||||
// },
|
||||
{
|
||||
label: 'common.move',
|
||||
eventTag: 'move',
|
||||
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
|
||||
},
|
||||
],
|
||||
moreAction: [
|
||||
{
|
||||
label: 'testPlan.testPlanIndex.openTimingTask',
|
||||
eventTag: 'openTimingTask',
|
||||
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'testPlan.testPlanIndex.closeTimingTask',
|
||||
eventTag: 'closeTimingTask',
|
||||
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'common.archive',
|
||||
eventTag: 'archive',
|
||||
|
@ -469,14 +515,15 @@
|
|||
label: 'common.copy',
|
||||
eventTag: 'copy',
|
||||
},
|
||||
{
|
||||
label: 'testPlan.testPlanIndex.createScheduledTask',
|
||||
eventTag: 'createScheduledTask',
|
||||
},
|
||||
{
|
||||
label: 'testPlan.testPlanIndex.configuration',
|
||||
eventTag: 'config',
|
||||
},
|
||||
// TODO 这个版本不上
|
||||
// {
|
||||
// label: 'testPlan.testPlanIndex.createScheduledTask',
|
||||
// eventTag: 'createScheduledTask',
|
||||
// },
|
||||
// {
|
||||
// label: 'testPlan.testPlanIndex.configuration',
|
||||
// eventTag: 'config',
|
||||
// },
|
||||
{
|
||||
label: 'common.archive',
|
||||
eventTag: 'archive',
|
||||
|
@ -497,7 +544,7 @@
|
|||
projectId: 'string',
|
||||
num: '100944',
|
||||
name: '系统示例',
|
||||
status: 'PREPARED',
|
||||
status: 'COMPLETED',
|
||||
tags: ['string'],
|
||||
schedule: 'string',
|
||||
createUser: 'string',
|
||||
|
@ -522,74 +569,74 @@
|
|||
apiCount: 3,
|
||||
scenarioCount: 3,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
id: '100945',
|
||||
projectId: 'string',
|
||||
num: '100945',
|
||||
name: '系统示例',
|
||||
status: 'COMPLETED',
|
||||
tags: ['string'],
|
||||
schedule: 'string',
|
||||
createUser: 'string',
|
||||
createTime: 'string',
|
||||
moduleName: 'string',
|
||||
moduleId: 'string',
|
||||
testPlanItem: [],
|
||||
testPlanGroupId: 'string',
|
||||
passCount: 0,
|
||||
unPassCount: 0,
|
||||
reviewedCount: 0,
|
||||
underReviewedCount: 0,
|
||||
childrenCount: 0,
|
||||
useCaseCount: {
|
||||
caseCount: 3,
|
||||
apiCount: 3,
|
||||
scenarioCount: 3,
|
||||
},
|
||||
statusDetail: {
|
||||
tolerance: 100,
|
||||
UNPENDING: 100,
|
||||
RUNNING: 30,
|
||||
SUCCESS: 30,
|
||||
ERROR: 30,
|
||||
executionProgress: '100%',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '100955',
|
||||
projectId: 'string',
|
||||
num: '100955',
|
||||
name: '系统示例',
|
||||
status: 'COMPLETED',
|
||||
tags: ['string'],
|
||||
schedule: 'string',
|
||||
createUser: 'string',
|
||||
createTime: 'string',
|
||||
moduleName: 'string',
|
||||
moduleId: 'string',
|
||||
testPlanItem: [],
|
||||
testPlanGroupId: 'string',
|
||||
passCount: 0,
|
||||
unPassCount: 0,
|
||||
reviewedCount: 0,
|
||||
underReviewedCount: 0,
|
||||
childrenCount: 0,
|
||||
useCaseCount: {
|
||||
caseCount: 3,
|
||||
apiCount: 3,
|
||||
scenarioCount: 3,
|
||||
},
|
||||
statusDetail: {
|
||||
tolerance: 100,
|
||||
UNPENDING: 100,
|
||||
RUNNING: 30,
|
||||
SUCCESS: 30,
|
||||
ERROR: 30,
|
||||
executionProgress: '100%',
|
||||
},
|
||||
},
|
||||
],
|
||||
// children: [
|
||||
// {
|
||||
// id: '100945',
|
||||
// projectId: 'string',
|
||||
// num: '100945',
|
||||
// name: '系统示例',
|
||||
// status: 'COMPLETED',
|
||||
// tags: ['string'],
|
||||
// schedule: 'string',
|
||||
// createUser: 'string',
|
||||
// createTime: 'string',
|
||||
// moduleName: 'string',
|
||||
// moduleId: 'string',
|
||||
// testPlanItem: [],
|
||||
// testPlanGroupId: 'string',
|
||||
// passCount: 0,
|
||||
// unPassCount: 0,
|
||||
// reviewedCount: 0,
|
||||
// underReviewedCount: 0,
|
||||
// childrenCount: 0,
|
||||
// useCaseCount: {
|
||||
// caseCount: 3,
|
||||
// apiCount: 3,
|
||||
// scenarioCount: 3,
|
||||
// },
|
||||
// statusDetail: {
|
||||
// tolerance: 100,
|
||||
// UNPENDING: 100,
|
||||
// RUNNING: 30,
|
||||
// SUCCESS: 30,
|
||||
// ERROR: 30,
|
||||
// executionProgress: '100%',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// id: '100955',
|
||||
// projectId: 'string',
|
||||
// num: '100955',
|
||||
// name: '系统示例',
|
||||
// status: 'COMPLETED',
|
||||
// tags: ['string'],
|
||||
// schedule: 'string',
|
||||
// createUser: 'string',
|
||||
// createTime: 'string',
|
||||
// moduleName: 'string',
|
||||
// moduleId: 'string',
|
||||
// testPlanItem: [],
|
||||
// testPlanGroupId: 'string',
|
||||
// passCount: 0,
|
||||
// unPassCount: 0,
|
||||
// reviewedCount: 0,
|
||||
// underReviewedCount: 0,
|
||||
// childrenCount: 0,
|
||||
// useCaseCount: {
|
||||
// caseCount: 3,
|
||||
// apiCount: 3,
|
||||
// scenarioCount: 3,
|
||||
// },
|
||||
// statusDetail: {
|
||||
// tolerance: 100,
|
||||
// UNPENDING: 100,
|
||||
// RUNNING: 30,
|
||||
// SUCCESS: 30,
|
||||
// ERROR: 30,
|
||||
// executionProgress: '100%',
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -623,8 +670,6 @@
|
|||
combine: {},
|
||||
});
|
||||
|
||||
const showType = ref<keyof typeof testPlanTypeEnum>('ALL');
|
||||
|
||||
async function initTableParams() {
|
||||
conditionParams.value = {
|
||||
keyword: keyword.value,
|
||||
|
@ -740,7 +785,7 @@
|
|||
title: t('testPlan.testPlanIndex.confirmBatchArchivePlan', {
|
||||
count: batchParams.value.currentSelectCount,
|
||||
}),
|
||||
content: t('testPlan.testPlanIndex.confirmBatchDeletePlanContentTip'),
|
||||
content: t('testPlan.testPlanIndex.confirmBatchArchivePlanContent'),
|
||||
okText: t('common.archive'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
|
@ -749,7 +794,7 @@
|
|||
onBeforeOk: async () => {
|
||||
try {
|
||||
const { selectedIds, selectAll, excludeIds } = batchParams.value;
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
Message.success(t('common.batchArchiveSuccess'));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@ -759,7 +804,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* 归档
|
||||
* 删除
|
||||
*/
|
||||
function handleDelete() {
|
||||
openModal({
|
||||
|
@ -767,7 +812,7 @@
|
|||
title: t('testPlan.testPlanIndex.confirmBatchDeletePlan', {
|
||||
count: batchParams.value.currentSelectCount,
|
||||
}),
|
||||
content: t('testPlan.testPlanIndex.confirmBatchDeletePlanContentTip'),
|
||||
content: t('testPlan.testPlanIndex.confirmBatchDeletePlanContent'),
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
|
@ -786,6 +831,19 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量编辑
|
||||
*/
|
||||
const showEditModel = ref<boolean>(false);
|
||||
|
||||
function handleEdit() {
|
||||
showEditModel.value = true;
|
||||
}
|
||||
|
||||
function successHandler() {
|
||||
fetchData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作
|
||||
*/
|
||||
|
@ -813,6 +871,9 @@
|
|||
case 'delete':
|
||||
handleDelete();
|
||||
break;
|
||||
case 'edit':
|
||||
handleEdit();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -828,7 +889,36 @@
|
|||
showScheduledTaskModal.value = true;
|
||||
}
|
||||
|
||||
function handleMoreActionSelect(item: ActionsItem, record: any) {
|
||||
const showStatusDeleteModal = ref<boolean>(false);
|
||||
const activeRecord = ref<TestPlanItem>();
|
||||
function deleteStatusHandler(record: TestPlanItem) {
|
||||
activeRecord.value = cloneDeep(record);
|
||||
showStatusDeleteModal.value = true;
|
||||
}
|
||||
|
||||
function archiveHandle(record: TestPlanItem) {
|
||||
openModal({
|
||||
type: 'warning',
|
||||
title: t('common.archiveConfirmTitle', { name: characterLimit(record.name) }),
|
||||
content: t('testPlan.testPlanIndex.confirmArchivePlan'),
|
||||
okText: t('common.archive'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'normal',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
Message.success(t('common.batchArchiveSuccess'));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
function handleMoreActionSelect(item: ActionsItem, record: TestPlanItem) {
|
||||
switch (item.eventTag) {
|
||||
case 'copy':
|
||||
copyHandler();
|
||||
|
@ -836,6 +926,12 @@
|
|||
case 'createScheduledTask':
|
||||
handleScheduledTask();
|
||||
break;
|
||||
case 'delete':
|
||||
deleteStatusHandler(record);
|
||||
break;
|
||||
case 'archive':
|
||||
archiveHandle(record);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -843,17 +939,18 @@
|
|||
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
|
||||
function expandHandler(record: any) {
|
||||
if (expandedKeys.value.includes(record.id)) {
|
||||
expandedKeys.value = expandedKeys.value.filter((key) => key !== record.id);
|
||||
} else {
|
||||
expandedKeys.value = [...expandedKeys.value, record.id];
|
||||
}
|
||||
}
|
||||
|
||||
function getIconClass(record: any) {
|
||||
return expandedKeys.value.includes(record.id) ? 'text-[rgb(var(--primary-5))]' : 'text-[var(--color-text-4)]';
|
||||
}
|
||||
// TODO先不做展开折叠
|
||||
// function expandHandler(record: any) {
|
||||
// if (expandedKeys.value.includes(record.id)) {
|
||||
// expandedKeys.value = expandedKeys.value.filter((key) => key !== record.id);
|
||||
// } else {
|
||||
// expandedKeys.value = [...expandedKeys.value, record.id];
|
||||
// }
|
||||
// }
|
||||
// TODO先不做展开折叠
|
||||
// function getIconClass(record: any) {
|
||||
// return expandedKeys.value.includes(record.id) ? 'text-[rgb(var(--primary-5))]' : 'text-[var(--color-text-4)]';
|
||||
// }
|
||||
|
||||
function handleFilterHidden(val: boolean) {
|
||||
if (!val) {
|
||||
|
@ -893,11 +990,6 @@
|
|||
}
|
||||
);
|
||||
|
||||
// TODO 临时数据模拟
|
||||
// onMounted(() => {
|
||||
// setProps({ data });
|
||||
// });
|
||||
|
||||
onBeforeMount(() => {
|
||||
fetchData();
|
||||
});
|
||||
|
@ -906,18 +998,16 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.arco-table-cell-expand-icon .arco-table-cell-inline-icon) {
|
||||
display: none;
|
||||
}
|
||||
:deep(.arco-table-cell-align-left) > span:first-child {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
.arrowIcon {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
:deep(.ms-modal-form .arco-modal-body) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
// TODO先不做展开折叠
|
||||
// :deep(.arco-table-cell-expand-icon .arco-table-cell-inline-icon) {
|
||||
// display: none;
|
||||
// }
|
||||
// :deep(.arco-table-cell-align-left) > span:first-child {
|
||||
// padding-left: 0 !important;
|
||||
// }
|
||||
// .arrowIcon {
|
||||
// transform: scaleX(-1);
|
||||
// }
|
||||
.popover-label-td {
|
||||
@apply flex items-center;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<template #footer>
|
||||
<div class="mb-[6px] mt-[4px] p-[3px_8px]">
|
||||
<MsButton type="text" class="text-[rgb(var(--primary-5))]" @click="createCustomFrequency">
|
||||
{{ t('project.testPlanIndex.customFrequency') }}
|
||||
{{ t('testPlan.testPlanIndex.customFrequency') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -28,14 +28,14 @@
|
|||
</a-form-item>
|
||||
<a-radio-group v-model="form.env" class="mb-4">
|
||||
<a-radio value="">
|
||||
{{ t('project.testPlanIndex.defaultEnv') }}
|
||||
{{ t('testPlan.testPlanIndex.defaultEnv') }}
|
||||
<span class="float-right mx-1 mt-[1px]">
|
||||
<a-tooltip :content="t('testPlan.testPlanIndex.envTip')" position="top">
|
||||
<IconQuestionCircle class="h-[16px] w-[16px] text-[--color-text-4] hover:text-[rgb(var(--primary-5))]"
|
||||
/></a-tooltip>
|
||||
</span>
|
||||
</a-radio>
|
||||
<a-radio value="new"> {{ t('project.testPlanIndex.newEnv') }}</a-radio>
|
||||
<a-radio value="new"> {{ t('testPlan.testPlanIndex.newEnv') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<a-radio-group v-model="form.methods">
|
||||
<a-radio value="serial">{{ t('testPlan.testPlanIndex.serial') }}</a-radio>
|
||||
|
@ -59,7 +59,7 @@
|
|||
<span class="text-[var(--color-text-4)]">CPU</span>
|
||||
<span class="mx-2"> {{ item.cpuRate }}</span>
|
||||
<MsTag theme="outline" :type="item.status ? 'link' : 'success'" size="small">
|
||||
{{ item.status ? t('project.testPlanIndex.doing') : t('project.testPlanIndex.inFreeTime') }}
|
||||
{{ item.status ? t('testPlan.testPlanIndex.doing') : t('testPlan.testPlanIndex.inFreeTime') }}
|
||||
</MsTag>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<table class="min-w-[144px]">
|
||||
<tr>
|
||||
<td class="popover-label-td">
|
||||
<div>{{ t('project.testPlanIndex.tolerance') }}</div>
|
||||
<div>{{ t('testPlan.testPlanIndex.tolerance') }}</div>
|
||||
</td>
|
||||
<td class="popover-value-td">
|
||||
{{ props.statusDetail.tolerance }}
|
||||
|
@ -12,7 +12,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="popover-label-td">
|
||||
<div>{{ t('project.testPlanIndex.executionProgress') }}</div>
|
||||
<div>{{ t('testPlan.testPlanIndex.executionProgress') }}</div>
|
||||
</td>
|
||||
<td class="popover-value-td">
|
||||
{{ props.statusDetail.executionProgress }}
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
modulesCount?: Record<string, number>; // 模块数量统计对象
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['update:selectedKeys', 'planTreeNodeSelect', 'init', 'dragUpdate']);
|
||||
const emits = defineEmits(['update:selectedKeys', 'planTreeNodeSelect', 'init', 'dragUpdate', 'getNodeName']);
|
||||
|
||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||
|
||||
|
@ -213,7 +213,7 @@
|
|||
offspringIds.push(e.id);
|
||||
return e;
|
||||
});
|
||||
emits('planTreeNodeSelect', selectedKeys, offspringIds);
|
||||
emits('planTreeNodeSelect', selectedKeys, offspringIds, node.name);
|
||||
};
|
||||
|
||||
// 用例树节点更多事件
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import type { planStatusType } from '@/models/testPlan/testPlan';
|
||||
|
||||
export type PlanStatusMap = Record<
|
||||
planStatusType,
|
||||
{
|
||||
label: string;
|
||||
color: string;
|
||||
class: string;
|
||||
}
|
||||
>;
|
||||
export const planStatusMap: PlanStatusMap = {
|
||||
PREPARED: {
|
||||
label: 'caseManagement.caseReview.unStart',
|
||||
color: 'var(--color-text-n8)',
|
||||
class: '!text-[var(--color-text-1)]',
|
||||
},
|
||||
UNDERWAY: {
|
||||
label: 'caseManagement.caseReview.going',
|
||||
color: 'rgb(var(--link-2))',
|
||||
class: '!text-[rgb(var(--link-6))]',
|
||||
},
|
||||
COMPLETED: {
|
||||
label: 'caseManagement.caseReview.finished',
|
||||
color: 'rgb(var(--success-2))',
|
||||
class: '!text-[rgb(var(--success-6))]',
|
||||
},
|
||||
ARCHIVED: {
|
||||
label: 'caseManagement.caseReview.archived',
|
||||
color: 'var(--color-text-n8)',
|
||||
class: '!text-[var(--color-text-4)]',
|
||||
},
|
||||
};
|
|
@ -82,6 +82,7 @@
|
|||
:offspring-ids="offspringIds"
|
||||
:active-folder-type="activeCaseType"
|
||||
:modules-count="modulesCount"
|
||||
:node-name="nodeName"
|
||||
@init="initModulesCount"
|
||||
/>
|
||||
</div>
|
||||
|
@ -177,11 +178,14 @@
|
|||
const activeCaseType = ref<'folder' | 'module'>('folder'); // 激活计划树类型
|
||||
|
||||
const offspringIds = ref<string[]>([]);
|
||||
const nodeName = ref<string>('');
|
||||
|
||||
// 处理计划树节点选中
|
||||
function planNodeSelect(keys: string[], _offspringIds: string[]) {
|
||||
function planNodeSelect(keys: string[], _offspringIds: string[], moduleName: string) {
|
||||
[activeFolder.value] = keys;
|
||||
activeCaseType.value = 'module';
|
||||
offspringIds.value = [..._offspringIds];
|
||||
nodeName.value = moduleName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -196,7 +200,7 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* 右侧表格数据刷新后,若当前展示的是模块,则刷新模块树的统计数量
|
||||
* 刷新模块树的统计数量
|
||||
*/
|
||||
function initModulesCount(params: any) {}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ export default {
|
|||
'testPlan.testPlanIndex.confirmBatchDeletePlan': 'Are you sure to delete {count} test plans?',
|
||||
'testPlan.testPlanIndex.confirmBatchDeletePlanContentTip':
|
||||
'Only sub-plans within the test plan and plan group are deleted',
|
||||
'testPlan.testPlanIndex.confirmBatchDeletePlanContent': 'After delete, data unrecoverable, please careful operation.',
|
||||
'testPlan.testPlanIndex.confirmBatchArchivePlan': 'Are you sure to archive {count} test plans?',
|
||||
'testPlan.testPlanIndex.confirmBatchArchivePlanContent':
|
||||
'Only completed test plans can be archived! \n after filing, implement information no longer update and editing, data unrecoverable, please careful operation.',
|
||||
|
@ -49,17 +50,28 @@ export default {
|
|||
'testPlan.testPlanIndex.timingState': 'Timing state',
|
||||
'testPlan.testPlanIndex.timingStateEnable': 'Enable: Executes scheduled tasks',
|
||||
'testPlan.testPlanIndex.timingStateClose': 'Close: Stops a scheduled task',
|
||||
'project.testPlanIndex.customFrequency': 'Custom frequency',
|
||||
'project.testPlanIndex.doing': 'Doing',
|
||||
'project.testPlanIndex.inFreeTime': 'In free time',
|
||||
'project.testPlanIndex.defaultEnv': 'Default Environment',
|
||||
'project.testPlanIndex.newEnv': 'New Environment',
|
||||
'project.testPlanIndex.executionProgress': 'Execution progress',
|
||||
'project.testPlanIndex.tolerance': 'tolerance',
|
||||
'project.testPlanIndex.TotalCases': 'Total use cases',
|
||||
'project.testPlanIndex.functionalUseCase': 'case',
|
||||
'project.testPlanIndex.apiCase': 'Api use case',
|
||||
'project.testPlanIndex.apiScenarioCase': 'Api scenario use cases',
|
||||
'testPlan.testPlanIndex.customFrequency': 'Custom frequency',
|
||||
'testPlan.testPlanIndex.doing': 'Doing',
|
||||
'testPlan.testPlanIndex.inFreeTime': 'In free time',
|
||||
'testPlan.testPlanIndex.defaultEnv': 'Default Environment',
|
||||
'testPlan.testPlanIndex.newEnv': 'New Environment',
|
||||
'testPlan.testPlanIndex.executionProgress': 'Execution progress',
|
||||
'testPlan.testPlanIndex.tolerance': 'tolerance',
|
||||
'testPlan.testPlanIndex.TotalCases': 'Total use cases',
|
||||
'testPlan.testPlanIndex.functionalUseCase': 'case',
|
||||
'testPlan.testPlanIndex.apiCase': 'Api use case',
|
||||
'testPlan.testPlanIndex.apiScenarioCase': 'Api scenario use cases',
|
||||
'testPlan.testPlanIndex.deleteArchivedPlan':
|
||||
'After the program has been archived, delete data unrecoverable, please careful operation.',
|
||||
'testPlan.testPlanIndex.deletePendingPlan':
|
||||
'The plan is not executed, the data cannot be recovered after deletion, please operate carefully!',
|
||||
'testPlan.testPlanIndex.deleteRunningPlan':
|
||||
'Scheduled tasks are stopped and deleted. Exercise caution when performing this operation',
|
||||
'testPlan.testPlanIndex.deleteCompletedPlan':
|
||||
'The proposed plan is completed, the option is archived, and the use case information and execution results are retained;If you continue to delete, the data will not be restored, please be careful!',
|
||||
'testPlan.testPlanIndex.confirmArchivePlan':
|
||||
'After filing, implement information no longer update and editing, data unrecoverable, please careful operation!',
|
||||
'testPlan.testPlanIndex.passRateTitleTip': 'Passed use cases/all use cases *100%',
|
||||
'testPlan.planForm.namePlaceholder': 'Please enter the name of the test plan',
|
||||
'testPlan.planForm.nameRequired': 'Test plan name cannot be empty',
|
||||
'testPlan.planForm.planStartAndEndTime': 'Planned start and end time',
|
||||
|
|
|
@ -36,9 +36,10 @@ export default {
|
|||
'testPlan.testPlanIndex.parallel': '并行',
|
||||
'testPlan.testPlanIndex.confirmBatchDeletePlan': '确认删除 {count} 个测试计划吗?',
|
||||
'testPlan.testPlanIndex.confirmBatchDeletePlanContentTip': '仅删除测试计划和计划组内的子计划',
|
||||
'testPlan.testPlanIndex.confirmBatchDeletePlanContent': '删除后,数据不可恢复,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.confirmBatchArchivePlan': '确认归档 {count} 个测试计划吗?',
|
||||
'testPlan.testPlanIndex.confirmBatchArchivePlanContent':
|
||||
'仅 已完成 测试计划可归档!\n 归档后,执行信息不再更新且不可编辑,数据不可恢复,请谨慎操作!',
|
||||
'仅 已完成 测试计划可归档!\r\n 归档后,执行信息不再更新且不可编辑,数据不可恢复,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.selectedCount': '(已选 {count} 项数据)',
|
||||
'testPlan.testPlanIndex.createScheduledTask': '创建定时任务',
|
||||
'testPlan.testPlanIndex.updateScheduledTask': '更新定时任务',
|
||||
|
@ -49,17 +50,26 @@ export default {
|
|||
'testPlan.testPlanIndex.timingState': '定时状态',
|
||||
'testPlan.testPlanIndex.timingStateEnable': '开启:执行定时任务',
|
||||
'testPlan.testPlanIndex.timingStateClose': '关闭:停止定时任务',
|
||||
'project.testPlanIndex.customFrequency': '自定义频率',
|
||||
'project.testPlanIndex.doing': '进行中',
|
||||
'project.testPlanIndex.inFreeTime': '空闲中',
|
||||
'project.testPlanIndex.defaultEnv': '默认环境',
|
||||
'project.testPlanIndex.newEnv': '新环境',
|
||||
'project.testPlanIndex.executionProgress': '执行进度',
|
||||
'project.testPlanIndex.tolerance': '容错率',
|
||||
'project.testPlanIndex.TotalCases': '用例总数',
|
||||
'project.testPlanIndex.functionalUseCase': '功能用例',
|
||||
'project.testPlanIndex.apiCase': '接口用例',
|
||||
'project.testPlanIndex.apiScenarioCase': '接口场景用例',
|
||||
'testPlan.testPlanIndex.customFrequency': '自定义频率',
|
||||
'testPlan.testPlanIndex.doing': '进行中',
|
||||
'testPlan.testPlanIndex.inFreeTime': '空闲中',
|
||||
'testPlan.testPlanIndex.defaultEnv': '默认环境',
|
||||
'testPlan.testPlanIndex.newEnv': '新环境',
|
||||
'testPlan.testPlanIndex.executionProgress': '执行进度',
|
||||
'testPlan.testPlanIndex.tolerance': '容错率',
|
||||
'testPlan.testPlanIndex.TotalCases': '用例总数',
|
||||
'testPlan.testPlanIndex.functionalUseCase': '功能用例',
|
||||
'testPlan.testPlanIndex.apiCase': '接口用例',
|
||||
'testPlan.testPlanIndex.apiScenarioCase': '接口场景用例',
|
||||
'testPlan.testPlanIndex.deleteArchivedPlan': '计划 已归档,删除后数据不可恢复,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.deletePendingPlan': '计划 未执行,删除后数据不可恢复,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.deleteRunningPlan':
|
||||
'计划 进行中,删除后,终止执行且不可恢复,定时任务停止并删除,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.deleteCompletedPlan':
|
||||
'建议计划 已完成 ,选择归档,用例信息及执行结果都将被保留;若继续删除,数据将不会恢复,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.confirmArchivePlan': '归档后,执行信息不再更新且不可编辑,数据不可恢复,请谨慎操作!',
|
||||
'testPlan.testPlanIndex.passRateTitleTip': '已通过用例/全部用例*100%',
|
||||
'testPlan.testPlanIndex.batchEdit': '批量编辑 (已选 { number } 项数据)',
|
||||
'testPlan.planForm.namePlaceholder': '请输入测试计划名称',
|
||||
'testPlan.planForm.nameRequired': '测试计划名称不能为空',
|
||||
'testPlan.planForm.planStartAndEndTime': '计划起止时间',
|
||||
|
|
Loading…
Reference in New Issue