fix(缺陷管理&测试用例): 附件编辑&详情上传按钮位置调整&补充操作权限限制

This commit is contained in:
xinxin.wu 2024-09-18 19:11:41 +08:00 committed by Craftsman
parent 6ed59b1275
commit d6332fd1f8
8 changed files with 216 additions and 49 deletions

View File

@ -43,7 +43,7 @@
<div class="m-b[2px] flex items-center">
<a-tooltip :content="item.file.name">
<div class="show-file-name">
<div class="file-name-first one-line-text max-w-[421px] pl-[4px] font-normal">
<div class="file-name-first one-line-text max-w-[300px] pl-[4px] font-normal">
{{ item.file.name.slice(0, item.file.name.indexOf('.')) }}
</div>
<span class="font-normal text-[var(--color-text-1)]">

View File

@ -85,28 +85,32 @@
}"
:upload-func="uploadOrAssociationFile"
:handle-delete="deleteFileHandler"
:show-delete="props.allowEdit"
:init-file-save-tips="t('ms.upload.waiting_save')"
:show-delete="false"
@finish="uploadFileOver"
>
<template #actions="{ item }">
<div>
<!-- 本地文件 -->
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
<div v-if="item.local || item.status === 'init'" class="flex items-center font-normal">
<MsButton
v-if="item.status !== 'init' && item.status !== 'uploading' && item.file.type.includes('image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<a-divider
v-if="item.status !== 'init' && item.status !== 'uploading' && item.file.type.includes('image')"
direction="vertical"
/>
<MsButton
v-if="item.status === 'done' && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="transferHandler(item)"
>
{{ t('caseManagement.featureCase.storage') }}
@ -121,45 +125,73 @@
source-id-key="bugId"
@finish="emit('updateSuccess')"
/>
<a-divider
v-if="item.status === 'done' && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
direction="vertical"
/>
<MsButton
v-if="item.status === 'done'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="downloadFile(item)"
>
{{ t('caseManagement.featureCase.download') }}
</MsButton>
<a-divider v-if="item.status === 'done'" direction="vertical" />
<MsButton
v-if="item.status !== 'uploading' && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mx-0"
@click="deleteFileHandler(item)"
>
{{ t(item.deleteContent) || t('ms.upload.delete') }}
</MsButton>
</div>
<!-- 关联文件 -->
<div v-else class="flex flex-nowrap">
<div v-else class="flex items-center font-normal">
<MsButton
v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<a-divider v-if="item.status !== 'init' && item.file.type.includes('image')" direction="vertical" />
<MsButton
v-if="item.status === 'done'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="downloadFile(item)"
>
{{ t('caseManagement.featureCase.download') }}
</MsButton>
<a-divider v-if="item.status === 'done'" direction="vertical" />
<MsButton
v-if="item.isUpdateFlag && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="handleUpdateFile(item)"
>
{{ t('common.update') }}
</MsButton>
<a-divider v-if="item.isUpdateFlag && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])" direction="vertical" />
<MsButton
v-if="item.status === 'done' && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mx-0"
@click="deleteFileHandler(item)"
>
{{ t(item.deleteContent) }}
</MsButton>
</div>
</div>
</template>

View File

@ -59,24 +59,26 @@
v-model:file-list="fileList"
:init-file-save-tips="t('ms.upload.waiting_save')"
mode="static"
:show-delete="false"
>
<template #actions="{ item }">
<!-- 本地文件 -->
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
<div v-if="item.local || item.status === 'init'" class="flex items-center font-normal">
<MsButton
v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<a-divider v-if="item.status !== 'init' && item.file.type.includes('image')" direction="vertical" />
<MsButton
v-if="item.status !== 'init'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="transferFile(item)"
>
{{ t('caseManagement.featureCase.storage') }}
@ -90,43 +92,67 @@
source-id-key="bugId"
@finish="getDetailInfo()"
/>
<a-divider v-if="item.status !== 'init'" direction="vertical" />
<MsButton
v-if="item.status !== 'init'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="downloadFile(item)"
>
{{ t('common.download') }}
</MsButton>
<a-divider v-if="item.status !== 'init'" direction="vertical" />
<MsButton
v-if="item.status !== 'uploading'"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mx-0"
@click="deleteFile(item)"
>
{{ t(item.deleteContent) || t('ms.upload.delete') }}
</MsButton>
</div>
<!-- 关联文件 -->
<div v-else class="flex flex-nowrap">
<div v-else class="flex items-center font-normal">
<MsButton
v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mx-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<MsButton v-if="bugId" type="button" status="primary" class="!mr-[4px]" @click="downloadFile(item)">
<a-divider v-if="item.status !== 'init' && item.file.type.includes('image')" direction="vertical" />
<MsButton v-if="bugId" type="button" status="primary" class="!mx-0" @click="downloadFile(item)">
{{ t('common.download') }}
</MsButton>
<a-divider v-if="bugId" direction="vertical" />
<MsButton
v-if="bugId && item.isUpdateFlag"
type="button"
class="!mx-0"
status="primary"
@click="handleUpdateFile(item)"
>
{{ t('common.update') }}
</MsButton>
<a-divider v-if="bugId && item.isUpdateFlag" direction="vertical" />
<MsButton
v-if="item.status !== 'uploading'"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mx-0"
@click="deleteFile(item)"
>
{{ t(item.deleteContent) }}
</MsButton>
</div>
</template>
<template #title="{ item }">
<span v-if="item.isUpdateFlag" class="ml-4 flex items-center font-normal text-[rgb(var(--warning-6))]"
><icon-exclamation-circle-fill /> <span>{{ t('caseManagement.featureCase.fileIsUpdated') }}</span>
<span v-if="item.isUpdateFlag" class="ml-4 flex items-center font-normal text-[rgb(var(--warning-6))]">
<icon-exclamation-circle-fill /> <span>{{ t('caseManagement.featureCase.fileIsUpdated') }}</span>
</span>
</template>
</MsFileList>
@ -789,6 +815,13 @@
}
};
function deleteFile(item: MsFileItem) {
const index = fileList.value.findIndex((e) => e.uid === item.uid);
if (index !== -1) {
fileList.value.splice(index, 1);
}
}
// formCreate
watch(
() => formRules.value,

View File

@ -79,6 +79,14 @@
</a-tooltip>
</div>
</template>
<template #description="{ record }">
<a-tooltip position="tl" class="ms-tooltip-white">
<div v-dompurify-html="record.description || '-'"></div>
<template #content>
<div v-dompurify-html="record.description || '-'"></div>
</template>
</a-tooltip>
</template>
</MsBaseTable>
</div>
</MsCard>
@ -765,6 +773,10 @@
} else {
item.showInTable = false;
}
if (item.title === '内容') {
item.slotName = 'description';
item.showTooltip = false;
}
});
} catch (error) {
// eslint-disable-next-line no-console

View File

@ -67,19 +67,21 @@
mode="static"
:init-file-save-tips="t('ms.upload.waiting_save')"
:show-upload-type-desc="true"
:show-delete="false"
>
<template #actions="{ item }">
<!-- 本地文件 -->
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
<div v-if="item.local || item.status === 'init'" class="flex items-center font-normal">
<MsButton
v-if="item.status !== 'init' && item.file.type.includes('image/')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<a-divider v-if="item.status !== 'init' && item.file.type.includes('image/')" direction="vertical" />
<SaveAsFilePopover
v-if="item.uid === activeTransferFileParams?.uid"
v-model:visible="transferVisible"
@ -94,54 +96,72 @@
v-if="item.status !== 'init'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="transferFile(item)"
>
{{ t('caseManagement.featureCase.storage') }}
</MsButton>
<a-divider v-if="item.status !== 'init'" direction="vertical" />
<MsButton
v-if="item.status !== 'init'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="downloadFile(item)"
>
{{ t('caseManagement.featureCase.download') }}
</MsButton>
<a-divider v-if="item.status !== 'init'" direction="vertical" />
<MsButton
v-if="item.status !== 'uploading'"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mr-0"
@click="deleteFile(item)"
>
{{ t(item.deleteContent) || t('ms.upload.delete') }}
</MsButton>
</div>
<!-- 关联文件 -->
<div v-else class="flex flex-nowrap">
<div v-else class="flex items-center font-normal">
<MsButton
v-if="item.file.type.includes('/image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<MsButton
v-if="props.caseId"
type="button"
status="primary"
class="!mr-[4px]"
@click="downloadFile(item)"
>
<a-divider v-if="item.file.type.includes('/image')" direction="vertical" />
<MsButton v-if="props.caseId" type="button" status="primary" class="!mr-0" @click="downloadFile(item)">
{{ t('caseManagement.featureCase.download') }}
</MsButton>
<a-divider v-if="props.caseId" direction="vertical" />
<MsButton
v-if="props.caseId && item.isUpdateFlag"
type="button"
class="!mx-0"
status="primary"
@click="handleUpdateFile(item)"
>
{{ t('common.update') }}
</MsButton>
<a-divider v-if="props.caseId && item.isUpdateFlag" direction="vertical" />
<MsButton
v-if="item.status !== 'uploading'"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mr-0"
@click="deleteFile(item)"
>
{{ t(item.deleteContent) }}
</MsButton>
</div>
</template>
<template #title="{ item }">
<span v-if="item.isUpdateFlag" class="ml-4 flex items-center font-normal text-[rgb(var(--warning-6))]"
><icon-exclamation-circle-fill /> <span>{{ t('caseManagement.featureCase.fileIsUpdated') }}</span>
<span v-if="item.isUpdateFlag" class="ml-4 flex items-center font-normal text-[rgb(var(--warning-6))]">
<icon-exclamation-circle-fill /> <span>{{ t('caseManagement.featureCase.fileIsUpdated') }} </span>
</span>
</template>
</MsFileList>
@ -611,6 +631,13 @@
featureCaseStore.setModuleId([value]);
}
function deleteFile(item: MsFileItem) {
const index = fileList.value.findIndex((e) => e.uid === item.uid);
if (index !== -1) {
fileList.value.splice(index, 1);
}
}
//
watch(
() => fileList.value,

View File

@ -113,23 +113,23 @@
projectId: currentProjectId,
}"
:upload-func="uploadOrAssociationFile"
:handle-delete="deleteFileHandler"
:show-delete="props.allowEdit && !props.isTestPlan"
:show-delete="false"
@finish="uploadFileOver"
>
<template #actions="{ item }">
<div v-if="props.allowEdit">
<!-- 本地文件 -->
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
<div v-if="item.local || item.status === 'init'" class="flex items-center font-normal">
<MsButton
v-if="item.file.type.includes('/image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<a-divider v-if="item.file.type.includes('/image')" direction="vertical" />
<SaveAsFilePopover
v-if="!props.isTestPlan && item.uid === activeTransferFileParams?.uid"
v-model:visible="transferVisible"
@ -141,53 +141,110 @@
@finish="emit('updateSuccess')"
/>
<MsButton
v-if="!props.isTestPlan"
v-if="props.allowEdit && !props.isTestPlan && hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="transferFileHandler(item)"
>
{{ t('caseManagement.featureCase.storage') }}
</MsButton>
<a-divider
v-if="props.allowEdit && !props.isTestPlan && hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])"
direction="vertical"
/>
<MsButton
v-if="item.status === 'done'"
v-if="
item.status === 'done' &&
props.allowEdit &&
!props.isTestPlan &&
hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])
"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="downloadFile(item)"
>
{{ t('caseManagement.featureCase.download') }}
</MsButton>
<a-divider
v-if="
item.status === 'done' &&
props.allowEdit &&
!props.isTestPlan &&
hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])
"
direction="vertical"
/>
<MsButton
v-if="item.status !== 'uploading' && props.allowEdit && !props.isTestPlan"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mr-0"
@click="deleteFileHandler(item)"
>
{{ t(item.deleteContent) || t('ms.upload.delete') }}
</MsButton>
</div>
<!-- 关联文件 -->
<div v-else class="flex flex-nowrap">
<div v-else class="flex items-center font-normal">
<MsButton
v-if="item.file.type.includes('/image')"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="handlePreview(item)"
>
{{ t('ms.upload.preview') }}
</MsButton>
<a-divider v-if="item.file.type.includes('/image')" direction="vertical" />
<MsButton
v-if="item.status === 'done'"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="downloadFile(item)"
>
{{ t('caseManagement.featureCase.download') }}
</MsButton>
<a-divider v-if="item.status === 'done'" direction="vertical" />
<MsButton
v-if="item.isUpdateFlag"
v-if="
item.isUpdateFlag &&
props.allowEdit &&
!props.isTestPlan &&
hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])
"
type="button"
status="primary"
class="!mr-[4px]"
class="!mr-0"
@click="handleUpdateFile(item)"
>
{{ t('common.update') }}
</MsButton>
<a-divider
v-if="
item.isUpdateFlag &&
props.allowEdit &&
!props.isTestPlan &&
hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])
"
direction="vertical"
/>
<MsButton
v-if="
item.status !== 'uploading' &&
props.allowEdit &&
!props.isTestPlan &&
hasAllPermission(['FUNCTIONAL_CASE:READ+UPDATE'])
"
type="button"
:status="item.deleteContent ? 'primary' : 'danger'"
class="!mr-0"
@click="deleteFileHandler(item)"
>
{{ t(item.deleteContent) }}
</MsButton>
</div>
</div>
</template>
@ -262,6 +319,7 @@
import useAppStore from '@/store/modules/app';
import { characterLimit, downloadByteFile, getGenerateId, sleep } from '@/utils';
import { scrollIntoView } from '@/utils/dom';
import { hasAllPermission } from '@/utils/permission';
import type { AssociatedList, DetailCase, StepList } from '@/models/caseManagement/featureCase';
import type { TableQueryParams } from '@/models/common';

View File

@ -2,7 +2,7 @@
<MsDrawer
v-model:visible="showBugDrawer"
:mask="true"
:title="t('case.saveContinueText')"
:title="bugId ? t('bugManagement.editBug') : t('caseManagement.featureCase.createDefect')"
:ok-text="t('common.create')"
:ok-loading="drawerLoading"
:width="850"

View File

@ -39,6 +39,11 @@
<template #name="{ record }">
<BugNamePopover :name="record.name || record.title" :content="record.content || record.description || ''" />
</template>
<template #createUserName="{ record }">
<a-tooltip :content="`${record.createUserName}`" position="tl">
<div class="one-line-text">{{ record.createUserName || '-' }}</div>
</a-tooltip>
</template>
</ms-base-table>
</MsDrawer>
</template>
@ -142,7 +147,7 @@
},
{
title: 'caseManagement.featureCase.tableColumnCreateUser',
slotName: 'createUser',
slotName: 'createUserName',
dataIndex: 'createUser',
showInTable: true,
showTooltip: true,