feat(测试用例): 功能用例详情抽屉编辑变动为抽屉编辑功能
This commit is contained in:
parent
d99bde8ba9
commit
a0a297f9eb
|
@ -12,9 +12,11 @@
|
|||
<div class="flex flex-1 items-center">
|
||||
<!-- 如果设置了tooltipText,则优先展示-->
|
||||
<a-tooltip :content="props.tooltipText ? props.tooltipText : props.title" position="bottom">
|
||||
<div class="one-line-text max-w-[300px]">
|
||||
{{ props.title }}
|
||||
</div>
|
||||
<slot name="titleName">
|
||||
<div class="one-line-text max-w-[300px]">
|
||||
{{ props.title }}
|
||||
</div>
|
||||
</slot>
|
||||
</a-tooltip>
|
||||
<div class="ml-4 flex items-center">
|
||||
<slot name="titleLeft" :loading="loading" :detail="detail"></slot>
|
||||
|
|
|
@ -9,22 +9,45 @@
|
|||
:detail-id="props.detailId"
|
||||
:detail-index="props.detailIndex"
|
||||
:get-detail-func="getCaseDetail"
|
||||
:pagination="props.pagination"
|
||||
:pagination="!isEditTitle ? props.pagination : undefined"
|
||||
:table-data="props.tableData"
|
||||
:page-change="props.pageChange"
|
||||
:mask-closable="true"
|
||||
:edit-name="true"
|
||||
show-full-screen
|
||||
:unmount-on-close="true"
|
||||
@loaded="loadedCase"
|
||||
>
|
||||
<template #titleName>
|
||||
<div :class="`case-title flex items-center ${isEditTitle ? 'w-full' : ''}`">
|
||||
<a-input
|
||||
v-if="isEditTitle"
|
||||
v-model="titleName"
|
||||
:class="`edit-title w-full ${titleName.length ? '' : 'edit-title-error'}`"
|
||||
:placeholder="t('case.caseNamePlaceholder')"
|
||||
allow-clear
|
||||
:max-length="255"
|
||||
@blur="handleEditName"
|
||||
@keydown.enter="handleEditName"
|
||||
/>
|
||||
<div v-else class="flex items-center">
|
||||
<div> 【{{ detailInfo?.num }}】 </div>
|
||||
<div
|
||||
:class="`${
|
||||
hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) ? 'hover-title-name' : ''
|
||||
} one-line-text max-w-[200px]`"
|
||||
@click="clickTitleHandler"
|
||||
>{{ detailInfo.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #titleLeft>
|
||||
<div class="flex items-center"><caseLevel :case-level="caseLevels" /></div>
|
||||
<div v-if="!isEditTitle" class="flex items-center"><caseLevel :case-level="caseLevels" /></div>
|
||||
</template>
|
||||
<template #titleRight="{ loading }">
|
||||
<div class="rightButtons flex items-center">
|
||||
<MsButton
|
||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) && !isEditTitle"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
|
@ -36,7 +59,7 @@
|
|||
{{ t('common.edit') }}
|
||||
</MsButton>
|
||||
<MsButton
|
||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) && !isEditTitle"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
|
@ -48,7 +71,7 @@
|
|||
{{ t('caseManagement.featureCase.share') }}
|
||||
</MsButton>
|
||||
<MsButton
|
||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) && !isEditTitle"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
|
@ -63,7 +86,12 @@
|
|||
/>
|
||||
{{ t('caseManagement.featureCase.follow') }}
|
||||
</MsButton>
|
||||
<MsButton type="icon" status="secondary" class="mr-2 !rounded-[var(--border-radius-small)]">
|
||||
<MsButton
|
||||
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+ADD', 'FUNCTIONAL_CASE:READ+DELETE']) && !isEditTitle"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-2 !rounded-[var(--border-radius-small)]"
|
||||
>
|
||||
<a-dropdown position="br" :hide-on-select="false">
|
||||
<div class="flex items-center">
|
||||
<icon-more class="mr-2" />
|
||||
|
@ -75,10 +103,14 @@
|
|||
<!-- <a-doption>
|
||||
<a-switch class="mr-1" size="small" type="line" />{{ t('caseManagement.featureCase.addToPublic') }}
|
||||
</a-doption> -->
|
||||
<a-doption @click="updateHandler('copy')">
|
||||
<MsIcon type="icon-icon_copy_filled" class="font-[16px]" />{{ t('common.copy') }}</a-doption
|
||||
<a-doption v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+ADD'])" @click="updateHandler('copy')">
|
||||
<MsIcon type="icon-icon_copy_filled" class="font-[16px]" />{{ t('common.copy') }}
|
||||
</a-doption>
|
||||
<a-doption
|
||||
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+DELETE'])"
|
||||
class="error-6 text-[rgb(var(--danger-6))]"
|
||||
@click="deleteHandler"
|
||||
>
|
||||
<a-doption class="error-6 text-[rgb(var(--danger-6))]" @click="deleteHandler">
|
||||
<MsIcon type="icon-icon_delete-trash_outlined1" class="font-[16px] text-[rgb(var(--danger-6))]" />
|
||||
{{ t('common.delete') }}
|
||||
</a-doption>
|
||||
|
@ -110,7 +142,13 @@
|
|||
} content-wrapper w-full p-[16px] pt-4`"
|
||||
>
|
||||
<template v-if="activeTab === 'detail'">
|
||||
<TabDetail :form="detailInfo" :allow-edit="true" :form-rules="formItem" @update-success="updateSuccess" />
|
||||
<TabDetail
|
||||
:form="detailInfo"
|
||||
:allow-edit="true"
|
||||
:is-edit="props.isEdit"
|
||||
:form-rules="formItem"
|
||||
@update-success="updateSuccess"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="activeTab === 'basicInfo'">
|
||||
<BasicInfo :loading="loading" :detail="detail" @update-success="updateSuccess" />
|
||||
|
@ -187,6 +225,7 @@
|
|||
followerCaseRequest,
|
||||
getCaseDetail,
|
||||
getCaseModuleTree,
|
||||
updateCaseRequest,
|
||||
} from '@/api/modules/case-management/featureCase';
|
||||
import { PreviewEditorImageUrl } from '@/api/requrls/case-management/featureCase';
|
||||
import { defaultCaseDetail } from '@/config/caseManagement';
|
||||
|
@ -196,6 +235,7 @@
|
|||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { CustomAttributes, DetailCase, TabItemType } from '@/models/caseManagement/featureCase';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
|
@ -229,6 +269,7 @@
|
|||
tableData: any[]; // 表格数据
|
||||
pagination: MsPaginationI; // 分页器对象
|
||||
pageChange: (page: number) => Promise<void>; // 分页变更函数
|
||||
isEdit?: boolean; // 编辑状态
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['update:visible', 'success']);
|
||||
|
@ -249,6 +290,8 @@
|
|||
const tabSetting = ref<TabItemType[]>([]);
|
||||
const activeTab = ref<string | number>('detail');
|
||||
|
||||
const titleName = ref('');
|
||||
|
||||
function clickMenu(key: string | number) {
|
||||
activeTab.value = key;
|
||||
featureCaseStore.setActiveTab(key);
|
||||
|
@ -304,6 +347,7 @@
|
|||
function loadedCase(detail: DetailCase) {
|
||||
getCaseTree();
|
||||
detailInfo.value = { ...detail };
|
||||
titleName.value = detail.name;
|
||||
setCount(detail);
|
||||
customFields.value = detailInfo.value?.customFields as CustomAttributes[];
|
||||
caseLevels.value = getCaseLevels(customFields.value) as CaseLevel;
|
||||
|
@ -396,7 +440,6 @@
|
|||
const formRules = ref<FormItem[]>([]);
|
||||
const formItem = ref<FormRuleItem[]>([]);
|
||||
|
||||
const fApi = ref(null);
|
||||
// 初始化表单
|
||||
function initForm() {
|
||||
formRules.value = initFormCreate(customFields.value, ['FUNCTIONAL_CASE:READ+UPDATE']);
|
||||
|
@ -413,6 +456,59 @@
|
|||
return featureCaseStore.countMap[key] > 99 ? '99+' : `${count > 0 ? count : ''}`;
|
||||
}
|
||||
|
||||
function getParams() {
|
||||
const customFieldsArr = (formItem.value || []).map((item: any) => {
|
||||
return {
|
||||
fieldId: item.field,
|
||||
value: Array.isArray(item.value) ? JSON.stringify(item.value) : item.value,
|
||||
};
|
||||
});
|
||||
return {
|
||||
request: {
|
||||
...detailInfo.value,
|
||||
name: titleName.value,
|
||||
deleteFileMetaIds: [],
|
||||
unLinkFilesIds: [],
|
||||
newAssociateFileListIds: [],
|
||||
customFields: customFieldsArr,
|
||||
caseDetailFileIds: [],
|
||||
},
|
||||
fileList: [],
|
||||
};
|
||||
}
|
||||
|
||||
const isEditTitle = ref<boolean>(false);
|
||||
const titleLoading = ref<boolean>(false);
|
||||
|
||||
async function handleEditName() {
|
||||
if (!titleName.value.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (titleName.value === detailInfo.value.name) {
|
||||
isEditTitle.value = false;
|
||||
return;
|
||||
}
|
||||
titleLoading.value = true;
|
||||
try {
|
||||
await updateCaseRequest(getParams());
|
||||
Message.success(t('caseManagement.featureCase.editSuccess'));
|
||||
detailInfo.value.name = titleName.value;
|
||||
isEditTitle.value = false;
|
||||
updateSuccess();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
titleLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function clickTitleHandler() {
|
||||
if (hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE'])) {
|
||||
isEditTitle.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => customFields.value,
|
||||
() => {
|
||||
|
@ -432,6 +528,7 @@
|
|||
featureCaseStore.setActiveTab(activeTab.value);
|
||||
} else {
|
||||
activeTab.value = '';
|
||||
isEditTitle.value = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -622,4 +719,17 @@
|
|||
color: rgb(var(--danger-6));
|
||||
}
|
||||
}
|
||||
.edit-title-error {
|
||||
border-color: rgb(var(--danger-6));
|
||||
}
|
||||
.hover-title-name {
|
||||
padding: 4px 8px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
color: var(--color-text-1);
|
||||
@apply font-medium;
|
||||
&:hover {
|
||||
background: var(--color-text-n9);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
</template>
|
||||
<!-- 渲染自定义字段结束 -->
|
||||
<template #operation="{ record }">
|
||||
<MsButton v-permission="['FUNCTIONAL_CASE:READ+UPDATE']" class="!mr-0" @click="operateCase(record, 'edit')">
|
||||
<MsButton v-permission="['FUNCTIONAL_CASE:READ+UPDATE']" class="!mr-0" @click="operateCase(record, true)">
|
||||
{{ t('common.edit') }}
|
||||
</MsButton>
|
||||
<a-divider
|
||||
|
@ -151,7 +151,7 @@
|
|||
direction="vertical"
|
||||
:margin="8"
|
||||
></a-divider>
|
||||
<MsButton v-permission="['FUNCTIONAL_CASE:READ+ADD']" class="!mr-0" @click="operateCase(record, 'copy')">
|
||||
<MsButton v-permission="['FUNCTIONAL_CASE:READ+ADD']" class="!mr-0" @click="operateCase(record, false)">
|
||||
{{ t('caseManagement.featureCase.copy') }}
|
||||
</MsButton>
|
||||
<a-divider
|
||||
|
@ -336,6 +336,7 @@
|
|||
:table-data="propsRes.data"
|
||||
:page-change="propsEvent.pageChange"
|
||||
:pagination="propsRes.msPagination!"
|
||||
:is-edit="isEdit"
|
||||
@success="initData()"
|
||||
/>
|
||||
<AddDemandModal
|
||||
|
@ -1014,17 +1015,35 @@
|
|||
emitTableParams();
|
||||
}
|
||||
|
||||
const showDetailDrawer = ref(false);
|
||||
const activeDetailId = ref<string>('');
|
||||
const activeCaseIndex = ref<number>(0);
|
||||
|
||||
// 抽屉详情
|
||||
function showCaseDetail(id: string, index: number) {
|
||||
activeDetailId.value = id;
|
||||
activeCaseIndex.value = index;
|
||||
showDetailDrawer.value = true;
|
||||
}
|
||||
const isEdit = ref<boolean>(false);
|
||||
// 编辑&复制
|
||||
function operateCase(record: CaseManagementTable, mode: string) {
|
||||
router.push({
|
||||
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
|
||||
query: {
|
||||
id: record.id,
|
||||
},
|
||||
params: {
|
||||
mode,
|
||||
},
|
||||
});
|
||||
function operateCase(record: CaseManagementTable, operateType: boolean) {
|
||||
// TODO 这个版本暂时调整为打开详情抽屉编辑
|
||||
isEdit.value = operateType;
|
||||
if (operateType) {
|
||||
const index = propsRes.value.data.findIndex((item) => item.id === record.id);
|
||||
showCaseDetail(record.id, index);
|
||||
} else {
|
||||
router.push({
|
||||
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
|
||||
query: {
|
||||
id: record.id,
|
||||
},
|
||||
params: {
|
||||
mode: operateType ? 'edit' : 'copy',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
|
@ -1446,19 +1465,10 @@
|
|||
resetSelector();
|
||||
initData();
|
||||
}
|
||||
const showDetailDrawer = ref(false);
|
||||
const activeDetailId = ref<string>('');
|
||||
const activeCaseIndex = ref<number>(0);
|
||||
|
||||
// 抽屉详情
|
||||
function showCaseDetail(id: string, index: number) {
|
||||
activeDetailId.value = id;
|
||||
activeCaseIndex.value = index;
|
||||
showDetailDrawer.value = true;
|
||||
}
|
||||
|
||||
function handleCellClick(record: TableData) {
|
||||
const index = propsRes.value.data.findIndex((item) => item.id === record.id);
|
||||
isEdit.value = false;
|
||||
showCaseDetail(record.id, index);
|
||||
}
|
||||
|
||||
|
|
|
@ -305,9 +305,11 @@
|
|||
formRules?: FormRuleItem[]; // 编辑表单
|
||||
isTestPlan?: boolean; // 测试计划页面的
|
||||
isDisabledTestPlan?: boolean; // 测试计划页面-已归档
|
||||
isEdit?: boolean; // 是否为编辑状态
|
||||
}>(),
|
||||
{
|
||||
allowEdit: true, // 是否允许编辑
|
||||
isEdit: false,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -344,7 +346,7 @@
|
|||
},
|
||||
]);
|
||||
|
||||
const isEditPreposition = ref<boolean>(false); // 非编辑状态
|
||||
const isEditPreposition = ref<boolean>(props.isEdit); // 非编辑状态
|
||||
|
||||
// 更改类型
|
||||
const handleSelectType = (value: string | number | Record<string, any> | undefined) => {
|
||||
|
|
Loading…
Reference in New Issue