fix: 修改优先级中和低的bugs

This commit is contained in:
xinxin.wu 2024-05-24 19:38:22 +08:00 committed by Craftsman
parent 4e2b49a6e3
commit 5cca0ba48d
21 changed files with 201 additions and 128 deletions

View File

@ -134,6 +134,7 @@
no-disable
class="mt-[16px]"
v-on="propsEvent"
@filter-change="filterChange"
>
<template #num="{ record }">
<a-tooltip :content="`${record.num}`">
@ -149,6 +150,10 @@
<ExecuteStatusTag v-if="record.lastExecuteResult" :execute-result="record.lastExecuteResult" />
<span v-else>-</span>
</template>
<!-- 用例等级 -->
<template #[FilterSlotNameEnum.CASE_MANAGEMENT_CASE_LEVEL]="{ filterContent }">
<caseLevel :case-level="filterContent.value" />
</template>
<!-- 评审结果 -->
<template #reviewStatus="{ record }">
<MsIcon
@ -219,6 +224,7 @@
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { initGetModuleCountFunc, type RequestModuleEnum } from './utils';
import { casePriorityOptions } from '@/views/api-test/components/config';
import { executionResultMap, statusIconMap } from '@/views/case-management/caseManagementFeature/components/utils';
const router = useRouter();
@ -385,7 +391,11 @@
title: 'ms.case.associate.caseLevel',
dataIndex: 'caseLevel',
slotName: 'caseLevel',
width: 90,
width: 150,
filterConfig: {
options: casePriorityOptions,
filterSlotName: FilterSlotNameEnum.CASE_MANAGEMENT_CASE_LEVEL,
},
},
];
}
@ -676,6 +686,7 @@
sourceType: caseType.value,
...props.tableParams,
...props.moduleCountParams,
filter: propsRes.value.filter,
};
modulesCount.value = await initGetModuleCountFunc(props.type, params);
} catch (error) {
@ -814,6 +825,10 @@
}
);
function filterChange() {
initModuleCount();
}
defineExpose({
initModules,
});

View File

@ -8,7 +8,7 @@
>
<slot>
<div :class="['ms-more-action-trigger-content', visible ? 'ms-more-action-trigger-content--focus' : '']">
<MsButton type="text" size="mini" class="more-icon-btn" @click="visible = !visible">
<MsButton v-if="isHasAllPermission" type="text" size="mini" class="more-icon-btn" @click="visible = !visible">
<MsIcon type="icon-icon_more_outlined" size="16" class="text-[var(--color-text-4)]" />
</MsButton>
</div>
@ -91,6 +91,11 @@
return result;
});
//
const isHasAllPermission = computed(() => {
return props.list.some((item: ActionsItem) => hasAnyPermission(item.permission || []));
});
function selectHandler(value: SelectedValue) {
const item = props.list.find((e: ActionsItem) => e.eventTag === value);
emit('select', item);

View File

@ -52,7 +52,7 @@ const TestPlan: AppRouteRecordRaw = {
},
{
name: TestPlanRouteEnum.TEST_PLAN_REPORT_DETAIL,
locale: 'menu.testPlan.testPlanDetail',
locale: 'menu.apiTest.reportDetail',
},
],
},

View File

@ -52,6 +52,7 @@
@change="changeHandler"
@module-change="initData"
@cell-click="handleCellClick"
@filter-change="filterChange"
>
<template #num="{ record }">
<span type="text" class="one-line-text cursor-pointer px-0 text-[rgb(var(--primary-5))]">
@ -885,6 +886,7 @@
...tableParams,
current: propsRes.value.msPagination?.current,
pageSize: propsRes.value.msPagination?.pageSize,
filter: propsRes.value.filter,
});
}
@ -1466,6 +1468,10 @@
}
});
function filterChange() {
emitTableParams();
}
onMounted(async () => {
if (route.query.id) {
showCaseDetail(route.query.id as string, 0);

View File

@ -16,6 +16,7 @@
<a-form ref="formRef" :model="form" layout="vertical">
<a-form-item
field="title"
asterisk-position="end"
:label="t('bugManagement.bugName')"
:rules="[{ required: true, message: t('bugManagement.edit.nameIsRequired') }]"
:placeholder="t('bugManagement.edit.pleaseInputBugName')"

View File

@ -4,13 +4,15 @@
<span type="text" class="one-line-text cursor-pointer px-0 text-[rgb(var(--primary-5))]">{{ record.num }}</span>
</template>
<template #name="{ record }">
<div class="one-line-text flex max-w-[150px] flex-nowrap items-center"> {{ characterLimit(record.name) }}</div>
<a-popover title="" position="right" style="width: 480px">
<div class="ml-1 text-[rgb(var(--primary-5))]">{{ t('caseManagement.featureCase.preview') }}</div>
<template #content>
<div v-dompurify-html="record.content" class="markdown-body" style="margin-left: 48px"> </div>
</template>
</a-popover>
<div class="flex flex-nowrap items-center">
<div class="one-line-text max-w-[200px] flex-auto items-center"> {{ characterLimit(record.name) }}</div>
<a-popover class="bug-content-popover" title="" position="right" style="width: 480px">
<span class="ml-1 text-[rgb(var(--primary-5))]">{{ t('caseManagement.featureCase.preview') }}</span>
<template #content>
<div v-dompurify-html="record.content" class="markdown-body bug-content"> </div>
</template>
</a-popover>
</div>
</template>
<template #statusName="{ record }">
<div class="one-line-text">{{ record.statusName || '-' }}</div>
@ -149,4 +151,12 @@
});
</script>
<style scoped></style>
<style lang="less">
.bug-content-popover {
.arco-popover-content {
overflow: auto;
max-height: 400px;
.ms-scroll-bar();
}
}
</style>

View File

@ -38,13 +38,17 @@
v-on="propsEvent"
>
<template #name="{ record }">
<span class="one-line-text max-w-[300px]"> {{ record.name }}</span>
<a-popover title="" position="right" style="width: 480px">
<span class="ml-1 text-[rgb(var(--primary-5))]">{{ t('caseManagement.featureCase.preview') }}</span>
<template #content>
<div v-dompurify-html="record.content" class="markdown-body" style="margin-left: 48px"> </div>
</template>
</a-popover>
<div class="flex flex-nowrap items-center">
<div class="one-line-text max-w-[200px] flex-auto items-center"> {{ characterLimit(record.name) }}</div>
<a-popover class="bug-content-popover" title="" position="right" style="width: 480px">
<div class="ml-1 flex-auto text-[rgb(var(--primary-5))]">{{
t('caseManagement.featureCase.preview')
}}</div>
<template #content>
<div v-dompurify-html="record.content" class="markdown-body"> </div>
</template>
</a-popover>
</div>
</template>
</ms-base-table>
</div>
@ -62,6 +66,7 @@
import { getDrawerDebugPage } from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
import { characterLimit } from '@/utils';
import { TableKeyEnum } from '@/enums/tableEnum';
@ -77,7 +82,7 @@
visible: boolean;
caseId: string;
drawerLoading: boolean;
showSelectorAll: boolean;
showSelectorAll?: boolean;
}>(),
{
showSelectorAll: true,
@ -101,7 +106,7 @@
dataIndex: 'name',
showInTable: true,
showTooltip: true,
width: 200,
width: 300,
ellipsis: true,
showDrag: false,
},
@ -157,6 +162,7 @@
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
getDrawerDebugPage,
{
scroll: { x: 'auto' },
columns,
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEFECT,
selectable: true,
@ -229,4 +235,12 @@
);
</script>
<style scoped></style>
<style lang="less">
.bug-content-popover {
.arco-popover-content {
overflow: auto;
max-height: 400px;
.ms-scroll-bar();
}
}
</style>

View File

@ -205,7 +205,7 @@
dataIndex: 'name',
showInTable: true,
showTooltip: false,
width: 250,
width: 300,
ellipsis: true,
showDrag: false,
},

View File

@ -65,7 +65,7 @@
>
<div class="flex items-center justify-between">
<div
><span class="font-medium">{{ getPlatName() }}</span
><span class="font-medium">{{ platName }}</span
><span class="ml-1 text-[var(--color-text-4)]">({{ propsRes?.msPagination?.total || 0 }})</span></div
>
<a-input-search
@ -126,6 +126,8 @@
import type { CreateOrUpdateDemand, DemandItem } from '@/models/caseManagement/featureCase';
import { TableKeyEnum } from '@/enums/tableEnum';
import { getPlatName } from '@/views/case-management/caseManagementFeature/components/utils';
const { t } = useI18n();
const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId);
@ -207,7 +209,7 @@
scroll: { x: '100%' },
heightUsed: 290,
selectable: true,
showSelectorAll: true,
showSelectorAll: false,
showSetting: false,
});
@ -411,32 +413,9 @@
initPlatform();
});
// watch(
// () => activeTab.value,
// async (val) => {
// if (val === 'requirement') {
// try {
// const result = await getCaseRelatedInfo(currentProjectId.value);
// if (result && result.platform_key) {
// platformInfo.value = { ...result };
// }
// } catch (error) {
// console.log(error);
// }
// }
// }
// );
function getPlatName() {
switch (platformInfo.value.platform_key) {
case 'zentao':
return t('caseManagement.featureCase.zentao');
case 'jira':
return t('caseManagement.featureCase.jira');
default:
break;
}
}
const platName = computed(() => {
return getPlatName(platformInfo.value.platform_key);
});
</script>
<style scoped></style>

View File

@ -14,7 +14,7 @@
>
<div class="flex items-center justify-between">
<div
><span class="font-medium">{{ getPlatName() }}</span
><span class="font-medium">{{ platName }}</span
><span class="ml-1 text-[var(--color-text-4)]">({{ propsRes?.msPagination?.total || 0 }})</span></div
>
<a-input-search
@ -58,6 +58,8 @@
import type { CreateOrUpdateDemand, DemandItem } from '@/models/caseManagement/featureCase';
import { TableKeyEnum } from '@/enums/tableEnum';
import { getPlatName } from '@/views/case-management/caseManagementFeature/components/utils';
const { t } = useI18n();
const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId);
@ -138,16 +140,9 @@
return filteredData;
});
function getPlatName() {
switch (props.platformInfo.platform_key) {
case 'zentao':
return t('caseManagement.featureCase.zentao');
case 'jira':
return t('caseManagement.featureCase.jira');
default:
break;
}
}
const platName = computed(() => {
return getPlatName(props.platformInfo.value.platform_key);
});
async function handleDrawerConfirm() {
const demandList = tableSelected.value.map((item) => {

View File

@ -449,6 +449,7 @@
function getParams() {
const steps = stepData.value.map((item, index) => {
return {
id: item.id,
num: index,
desc: item.step,
result: item.expected,

View File

@ -280,10 +280,6 @@ export function initFormCreate(customFields: CustomAttributes[], permission: str
}
export function makeColumns(optionsMap: Record<string, any>, columnData: MsTableColumn) {
// const optionsMap: Record<string, any> = {
// status: statusFilterOptions.value,
// handleUser: handleUserFilterOptions.value,
// };
return columnData.map((e) => {
if (Object.prototype.hasOwnProperty.call(optionsMap, e.dataIndex as string)) {
return {
@ -297,3 +293,14 @@ export function makeColumns(optionsMap: Record<string, any>, columnData: MsTable
return { ...e };
});
}
export function getPlatName(platformKey: string) {
switch (platformKey) {
case 'zentao':
return t('caseManagement.featureCase.zentao');
case 'jira':
return t('caseManagement.featureCase.jira');
default:
break;
}
}

View File

@ -264,6 +264,7 @@ export default {
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
'caseManagement.featureCase.zentao': 'ZenTao',
'caseManagement.featureCase.jira': 'JIRA',
'caseManagement.featureCase.tapd': 'TAPD',
'caseManagement.featureCase.searchPlaceholder': 'Search by ID, name, or tag',
'caseManagement.featureCase.ModuleOwned': 'Module owned',
'caseManagement.featureCase.excelImportTip': 'Only xls/xlsx files are supported',

View File

@ -260,6 +260,7 @@ export default {
'caseManagement.featureCase.sortSuccess': '排序成功',
'caseManagement.featureCase.zentao': '禅道',
'caseManagement.featureCase.jira': 'JIRA',
'caseManagement.featureCase.tapd': 'TAPD',
'caseManagement.featureCase.searchPlaceholder': '通过ID、名称或标签搜索',
'caseManagement.featureCase.ModuleOwned': '所属模块',
'caseManagement.featureCase.excelImportTip': '仅支持 xls/xlsx 格式的文件',

View File

@ -72,7 +72,7 @@
</template>
<script lang="ts" setup>
import { FormInstance } from '@arco-design/web-vue';
import { FormInstance, Message } from '@arco-design/web-vue';
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import MsFormCreate from '@/components/pure/ms-form-create/ms-form-create.vue';
@ -168,6 +168,7 @@
{ ...form, DEMAND_PLATFORM_CONFIG: JSON.stringify(formData) },
currentProjectId.value
);
Message.success(t('common.linkSuccess'));
handleCancel(true);
emit('ok');
} catch (error) {

View File

@ -47,6 +47,7 @@
:selectable="hasOperationPermission"
v-on="propsEvent"
@batch-action="handleTableBatch"
@filter-change="filterChange"
>
<!-- :expanded-keys="expandedKeys" -->
<template #num="{ record }">
@ -624,18 +625,15 @@
currentSelectCount: 0,
});
const conditionParams = ref({
keyword: '',
filter: {},
combine: {},
});
async function initTableParams(isSetDefaultKey = false) {
conditionParams.value = {
const conditionParams = computed(() => {
return {
keyword: keyword.value,
filter: propsRes.value.filter,
combine: batchParams.value.condition,
};
});
async function initTableParams(isSetDefaultKey = false) {
let moduleIds =
props.activeFolder && props.activeFolder !== 'all' ? [props.activeFolder, ...props.offspringIds] : [];
if (isSetDefaultKey) {
@ -671,6 +669,7 @@
...tableParams,
current: propsRes.value.msPagination?.current,
pageSize: propsRes.value.msPagination?.pageSize,
filter: propsRes.value.filter,
});
}
@ -1026,6 +1025,10 @@
}
);
function filterChange() {
emitTableParams();
}
defineExpose({
fetchData,
emitTableParams,

View File

@ -47,7 +47,13 @@
@confirm="addSubModule"
@cancel="resetFocusNodeKey"
>
<MsButton type="icon" size="mini" class="ms-tree-node-extra__btn !mr-0" @click="setFocusKey(nodeData)">
<MsButton
v-if="hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD'])"
type="icon"
size="mini"
class="ms-tree-node-extra__btn !mr-0"
@click="setFocusKey(nodeData)"
>
<MsIcon type="icon-icon_add_outlined" size="14" class="text-[var(--color-text-4)]" />
</MsButton>
</MsPopConfirm>
@ -134,11 +140,13 @@
{
label: 'caseManagement.featureCase.rename',
eventTag: 'rename',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
{
label: 'caseManagement.featureCase.delete',
eventTag: 'delete',
danger: true,
permission: ['PROJECT_TEST_PLAN:READ+DELETE'],
},
];

View File

@ -1,51 +1,62 @@
<template>
<div>
<div class="mb-4 flex items-center justify-between">
<a-dropdown-button
v-if="hasAnyPermission(['PROJECT_BUG:READ']) && total"
type="primary"
@click="handleSelect('associated')"
>
{{ t('common.associated') }}
<template #icon>
<icon-down />
</template>
<template #content>
<a-doption v-permission="['PROJECT_BUG:READ+ADD']" value="new" @click="handleSelect('new')">
{{ t('common.newCreate') }}
</a-doption>
</template>
</a-dropdown-button>
<a-dropdown-button
v-if="hasAnyPermission(['PROJECT_BUG:READ+ADD']) && !total"
type="primary"
@click="handleSelect('new')"
>
{{ t('common.newCreate') }}
<template #icon>
<icon-down />
</template>
<template #content>
<a-popover title="" position="right">
<a-doption value="associated" :disabled="!total" @click="handleSelect('associated')">
{{ t('common.associated') }}
<div class="mb-4 grid grid-cols-3">
<div>
<a-dropdown-button
v-if="hasAnyPermission(['PROJECT_BUG:READ']) && total"
type="primary"
@click="handleSelect('associated')"
>
{{ t('common.associated') }}
<template #icon>
<icon-down />
</template>
<template #content>
<a-doption :disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])" value="new" @click="handleSelect('new')">
{{ t('common.newCreate') }}
</a-doption>
<template #content>
<div class="flex items-center text-[14px]">
<span class="text-[var(--color-text-4)]">{{ t('testPlan.featureCase.noBugDataTooltip') }}</span>
<MsButton type="text" @click="handleSelect('new')">
{{ t('testPlan.featureCase.noBugDataNewBug') }}
</MsButton>
</div>
</template>
</a-popover>
</template>
</a-dropdown-button>
</template>
</a-dropdown-button>
<a-dropdown-button
v-if="hasAnyPermission(['PROJECT_BUG:READ+ADD']) && !total"
type="primary"
@click="handleSelect('new')"
>
{{ t('common.newCreate') }}
<template #icon>
<icon-down />
</template>
<template #content>
<a-popover title="" position="right">
<a-doption
value="associated"
:disabled="!total && !hasAnyPermission(['PROJECT_BUG:READ'])"
@click="handleSelect('associated')"
>
{{ t('common.associated') }}
</a-doption>
<template #content>
<div class="flex items-center text-[14px]">
<span class="text-[var(--color-text-4)]">{{ t('testPlan.featureCase.noBugDataTooltip') }}</span>
<MsButton
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
type="text"
@click="handleSelect('new')"
>
{{ t('testPlan.featureCase.noBugDataNewBug') }}
</MsButton>
</div>
</template>
</a-popover>
</template>
</a-dropdown-button>
</div>
<a-input-search
v-model:model-value="keyword"
:placeholder="t('caseManagement.featureCase.searchByName')"
allow-clear
class="mx-[8px] w-[240px]"
class="col-span-2 col-end-7 mx-[8px] w-[240px]"
@search="initData"
@press-enter="initData"
@clear="resetHandler"

View File

@ -127,20 +127,26 @@
<span class="ml-1 text-[rgb(var(--danger-6))]">{{ caseDetail.bugListCount }}</span>
</MsTag>
<a-dropdown @select="handleSelect">
<a-button type="outline" size="mini" class="ml-1">
<a-button v-if="hasAnyPermission(['PROJECT_BUG:READ'])" type="outline" size="mini" class="ml-1">
<template #icon> <icon-plus class="text-[12px]" /> </template>
</a-button>
<template #content>
<a-doption v-permission="['PROJECT_BUG:READ+ADD']" value="new">{{
t('common.newCreate')
}}</a-doption>
<a-doption v-if="createdBugCount > 0 && hasAnyPermission(['PROJECT_BUG:READ'])" value="link">{{
t('common.associated')
}}</a-doption>
<a-doption
v-permission="['PROJECT_BUG:READ+ADD']"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
value="new"
>{{ t('common.newCreate') }}</a-doption
>
<a-doption
v-if="createdBugCount > 0 && hasAnyPermission(['PROJECT_BUG:READ'])"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ'])"
value="link"
>{{ t('common.associated') }}</a-doption
>
<a-popover v-else title="" position="left">
<a-doption
v-if="createdBugCount < 1 && hasAnyPermission(['PROJECT_BUG:READ'])"
:disabled="true"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ'])"
value="link"
>{{ t('common.associated') }}</a-doption
>
@ -149,7 +155,11 @@
<span class="text-[var(--color-text-4)]">{{
t('testPlan.featureCase.noBugDataTooltip')
}}</span>
<MsButton type="text" @click="handleSelect('new')">
<MsButton
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
type="text"
@click="handleSelect('new')"
>
{{ t('testPlan.featureCase.noBugDataNewBug') }}
</MsButton>
</div>
@ -238,7 +248,7 @@
import { testPlanDefaultDetail } from '@/config/testPlan';
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import { hasAnyPermission } from '@/utils/permission';
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
import type { TableQueryParams } from '@/models/common';
import type { PlanDetailFeatureCaseItem, TestPlanDetail } from '@/models/testPlan/testPlan';

View File

@ -56,7 +56,11 @@
/>
{{ t(detail.followFlag ? 'common.forked' : 'common.fork') }}
</MsButton>
<MsTableMoreAction :list="moreAction" @select="handleMoreSelect">
<MsButton v-if="detail.status === 'ARCHIVED'" status="danger" type="button" @click="deleteHandler">
<MsIcon type="icon-icon_delete-trash_outlined" class="mr-[8px] text-[rgb(var(--danger-6))]" />
<span class="text-[rgb(var(--danger-6))]"> {{ t('common.delete') }}</span>
</MsButton>
<MsTableMoreAction v-else :list="moreAction" @select="handleMoreSelect">
<MsButton v-permission="['PROJECT_TEST_PLAN:READ+DELETE']" type="button" status="default">
<MsIcon type="icon-icon_more_outlined" class="mr-[8px]" />
{{ t('common.more') }}

View File

@ -50,7 +50,7 @@
}"
@confirm="confirmHandler"
>
<MsButton type="icon" class="!mr-0 p-[2px]">
<MsButton v-permission="['PROJECT_TEST_PLAN:READ+ADD']" type="icon" class="!mr-0 p-[2px]">
<MsIcon
type="icon-icon_create_planarity"
size="18"
@ -119,6 +119,7 @@
import { createPlanModuleTree, getPlanModulesCount } from '@/api/modules/test-plan/testPlan';
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import { hasAnyPermission } from '@/utils/permission';
import type { CreateOrUpdateModule } from '@/models/caseManagement/featureCase';
import { ModuleTreeNode, TableQueryParams } from '@/models/common';