feat(缺陷管理): 高级筛选-缺陷首页

This commit is contained in:
teukkk 2024-10-12 16:23:38 +08:00 committed by Craftsman
parent 250f7dd894
commit f72c08f4e8
3 changed files with 149 additions and 33 deletions

View File

@ -150,6 +150,9 @@ export const CustomTypeMaps: Record<string, any> = {
TEXTAREA: { TEXTAREA: {
type: 'TEXTAREA', type: 'TEXTAREA',
}, },
RICH_TEXT: {
type: 'TEXTAREA',
},
MULTIPLE_INPUT: { MULTIPLE_INPUT: {
type: 'TAGS_INPUT', type: 'TAGS_INPUT',
propsKey: 'numberProps', propsKey: 'numberProps',
@ -166,15 +169,15 @@ export function getFilterCustomFields(result: any[]) {
const formObject = CustomTypeMaps[item.type]; const formObject = CustomTypeMaps[item.type];
const { props: formProps } = formObject; const { props: formProps } = formObject;
const currentItem: any = { const currentItem: any = {
title: item.name, title: item.name ?? item.fieldName,
dataIndex: item.id, dataIndex: item.id ?? item.fieldId,
type: FilterType[FilterTypeKey], type: FilterType[FilterTypeKey],
customField: true, customField: true,
customFieldType: item.type, customFieldType: item.type,
}; };
if (formObject.propsKey) { if (formObject.propsKey) {
if (item.options) { if (item.options || item.platformOptionJson) {
formProps.options = item.options; formProps.options = item.options ?? JSON.parse(item.platformOptionJson);
} }
currentItem[formObject.propsKey] = { currentItem[formObject.propsKey] = {
...formProps, ...formProps,
@ -194,6 +197,9 @@ export function getAllDataDefaultConditions(viewType: ViewTypeEnum) {
if ([ViewTypeEnum.API_DEFINITION, ViewTypeEnum.PLAN_API_CASE].includes(viewType)) { if ([ViewTypeEnum.API_DEFINITION, ViewTypeEnum.PLAN_API_CASE].includes(viewType)) {
conditions.push({ name: 'protocol', operator: OperatorEnum.BELONG_TO }); conditions.push({ name: 'protocol', operator: OperatorEnum.BELONG_TO });
} }
if ([ViewTypeEnum.BUG, ViewTypeEnum.PLAN_BUG, ViewTypeEnum.PLAN_BUG_DRAWER].includes(viewType)) {
conditions.push({ name: 'title', operator: OperatorEnum.CONTAINS });
}
if ( if (
[ViewTypeEnum.PLAN_API_SCENARIO, ViewTypeEnum.PLAN_API_CASE, ViewTypeEnum.PLAN_FUNCTIONAL_CASE].includes(viewType) [ViewTypeEnum.PLAN_API_SCENARIO, ViewTypeEnum.PLAN_API_CASE, ViewTypeEnum.PLAN_FUNCTIONAL_CASE].includes(viewType)
) { ) {

View File

@ -36,4 +36,7 @@ export enum ViewTypeEnum {
PLAN_API_SCENARIO = 'plan-api-scenario', PLAN_API_SCENARIO = 'plan-api-scenario',
PLAN_API_CASE = 'plan-api-case', PLAN_API_CASE = 'plan-api-case',
PLAN_FUNCTIONAL_CASE = 'plan-functional-case', PLAN_FUNCTIONAL_CASE = 'plan-functional-case',
BUG = 'bug',
PLAN_BUG = 'plan-bug',
PLAN_BUG_DRAWER = 'plan-bug-drawer',
} }

View File

@ -2,11 +2,15 @@
<MsCard simple no-content-padding> <MsCard simple no-content-padding>
<div class="h-full p-[16px]"> <div class="h-full p-[16px]">
<MsAdvanceFilter <MsAdvanceFilter
ref="msAdvanceFilterRef"
v-model:keyword="keyword" v-model:keyword="keyword"
:search-placeholder="t('caseManagement.featureCase.searchByNameAndId')" :view-type="ViewTypeEnum.BUG"
:filter-config-list="filterConfigList" :filter-config-list="filterConfigList"
@keyword-search="fetchData" :custom-fields-config-list="searchCustomFields"
@refresh="searchData" :search-placeholder="t('caseManagement.featureCase.searchByNameAndId')"
@keyword-search="fetchData()"
@adv-search="handleAdvSearch"
@refresh="searchData()"
> >
<template #left> <template #left>
<div class="flex gap-[12px]"> <div class="flex gap-[12px]">
@ -28,6 +32,7 @@
class="mt-[16px]" class="mt-[16px]"
v-bind="propsRes" v-bind="propsRes"
:action-config="tableBatchActions" :action-config="tableBatchActions"
:not-show-table-filter="isAdvancedSearchMode"
v-on="propsEvent" v-on="propsEvent"
@batch-action="handleTableBatch" @batch-action="handleTableBatch"
@sorter-change="saveSort" @sorter-change="saveSort"
@ -167,8 +172,8 @@
import { useIntervalFn } from '@vueuse/core'; import { useIntervalFn } from '@vueuse/core';
import { Message, TableData } from '@arco-design/web-vue'; import { Message, TableData } from '@arco-design/web-vue';
import { MsAdvanceFilter, timeSelectOptions } from '@/components/pure/ms-advance-filter'; import { getFilterCustomFields, MsAdvanceFilter, timeSelectOptions } from '@/components/pure/ms-advance-filter';
import { FilterFormItem } from '@/components/pure/ms-advance-filter/type'; import { FilterFormItem, FilterResult } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
import { MsExportDrawerMap, MsExportDrawerOption } from '@/components/pure/ms-export-drawer/types'; import { MsExportDrawerMap, MsExportDrawerOption } from '@/components/pure/ms-export-drawer/types';
@ -192,6 +197,7 @@
getSyncStatus, getSyncStatus,
syncBugEnterprise, syncBugEnterprise,
} from '@/api/modules/bug-management'; } from '@/api/modules/bug-management';
import { getPlatformOptions } from '@/api/modules/project-management/menuManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
import router from '@/router'; import router from '@/router';
@ -201,7 +207,9 @@
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';
import { BugEditCustomField, BugListItem, BugOptionItem } from '@/models/bug-management'; import { BugEditCustomField, BugListItem, BugOptionItem } from '@/models/bug-management';
import { FilterType } from '@/enums/advancedFilterEnum'; import { PoolOption } from '@/models/projectManagement/menuManagement';
import { FilterType, ViewTypeEnum } from '@/enums/advancedFilterEnum';
import { MenuEnum } from '@/enums/commonEnum';
import { RouteEnum } from '@/enums/routeEnum'; import { RouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
@ -219,7 +227,6 @@
const tableStore = useTableStore(); const tableStore = useTableStore();
const appStore = useAppStore(); const appStore = useAppStore();
const projectId = computed(() => appStore.currentProjectId); const projectId = computed(() => appStore.currentProjectId);
const filterVisible = ref(false);
const syncVisible = ref(false); const syncVisible = ref(false);
const exportVisible = ref(false); const exportVisible = ref(false);
const exportOptionData = ref<MsExportDrawerMap>({}); const exportOptionData = ref<MsExportDrawerMap>({});
@ -255,28 +262,16 @@
const handleSyncCancel = () => { const handleSyncCancel = () => {
syncVisible.value = false; syncVisible.value = false;
}; };
const filterConfigList = reactive<FilterFormItem[]>([
{ const searchCustomFields = ref<FilterFormItem[]>([]);
title: 'bugManagement.ID',
dataIndex: 'num',
type: FilterType.INPUT,
},
{
title: 'bugManagement.bugName',
dataIndex: 'title',
type: FilterType.INPUT,
},
{
title: 'bugManagement.createTime',
dataIndex: 'createTime',
type: FilterType.DATE_PICKER,
},
]);
// //
const getCustomFieldColumns = async () => { const getCustomFieldColumns = async () => {
const res = await getCustomFieldHeader(projectId.value); const res = await getCustomFieldHeader(projectId.value);
customFields.value = res; customFields.value = res;
searchCustomFields.value = getFilterCustomFields(
res.filter((item: BugEditCustomField) => item.fieldId !== 'title')
);
// filters // filters
customFields.value.forEach((item) => { customFields.value.forEach((item) => {
@ -431,7 +426,17 @@
}, },
]; ];
const { propsRes, propsEvent, setKeyword, setAdvanceFilter, setLoadListParams, resetSelector, loadList } = useTable( const {
propsRes,
propsEvent,
viewId,
advanceFilter,
setAdvanceFilter,
setKeyword,
setLoadListParams,
resetSelector,
loadList,
} = useTable(
getBugList, getBugList,
{ {
tableKey: TableKeyEnum.BUG_MANAGEMENT, tableKey: TableKeyEnum.BUG_MANAGEMENT,
@ -471,14 +476,15 @@
], ],
}; };
const msAdvanceFilterRef = ref<InstanceType<typeof MsAdvanceFilter>>();
const isAdvancedSearchMode = computed(() => msAdvanceFilterRef.value?.isAdvancedSearchMode);
function initTableParams() { function initTableParams() {
return { return {
keyword: keyword.value, keyword: keyword.value,
projectId: projectId.value, projectId: projectId.value,
condition: { viewId: viewId.value,
keyword: keyword.value, combineSearch: advanceFilter,
filter: propsRes.value.filter,
},
}; };
} }
@ -492,6 +498,103 @@
searchData(); searchData();
}; };
const statusOption = ref<BugOptionItem[]>([]);
const platformOption = ref<PoolOption[]>([]);
const initPlatformOption = async () => {
try {
const res = await getPlatformOptions(appStore.currentOrgId, MenuEnum.bugManagement);
platformOption.value = [...res, { id: 'Local', name: 'Local' }];
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
};
const filterConfigList = computed<FilterFormItem[]>(() => [
{
title: 'bugManagement.ID',
dataIndex: 'num',
type: FilterType.INPUT,
},
{
title: 'bugManagement.bugName',
dataIndex: 'title',
type: FilterType.INPUT,
},
{
title: 'bugManagement.belongPlatform',
dataIndex: 'platform',
type: FilterType.SELECT,
selectProps: {
multiple: true,
labelKey: 'name',
valueKey: 'id',
options: platformOption.value,
},
},
{
title: 'bugManagement.status',
dataIndex: 'status',
type: FilterType.SELECT,
selectProps: {
multiple: true,
labelKey: 'text',
options: statusOption.value,
},
},
{
title: 'bugManagement.numberOfCase',
dataIndex: 'relationCaseCount',
type: FilterType.NUMBER,
numberProps: {
min: 0,
precision: 0,
},
},
{
title: 'bugManagement.handleMan',
dataIndex: 'handleUser',
type: FilterType.MEMBER,
},
{
title: 'common.tag',
dataIndex: 'tags',
type: FilterType.TAGS_INPUT,
numberProps: {
min: 0,
precision: 0,
},
},
{
title: 'common.creator',
dataIndex: 'createUser',
type: FilterType.MEMBER,
},
{
title: 'common.createTime',
dataIndex: 'createTime',
type: FilterType.DATE_PICKER,
},
{
title: 'apiScenario.table.columns.updateUser',
dataIndex: 'updateUser',
type: FilterType.MEMBER,
},
{
title: 'common.updateTime',
dataIndex: 'updateTime',
type: FilterType.DATE_PICKER,
},
]);
//
const handleAdvSearch = (filter: FilterResult, id: string) => {
resetSelector();
keyword.value = '';
setAdvanceFilter(filter, id);
searchData(); //
};
const exportConfirm = async (option: MsExportDrawerOption[]) => { const exportConfirm = async (option: MsExportDrawerOption[]) => {
try { try {
exportLoading.value = true; exportLoading.value = true;
@ -708,6 +811,8 @@
const condition = { const condition = {
keyword: keyword.value, keyword: keyword.value,
filter: propsRes.value.filter, filter: propsRes.value.filter,
viewId: viewId.value,
combineSearch: advanceFilter,
}; };
currentSelectParams.value = { currentSelectParams.value = {
excludeIds: params.excludeIds, excludeIds: params.excludeIds,
@ -734,6 +839,7 @@
async function initFilterOptions() { async function initFilterOptions() {
const res = await getCustomOptionHeader(appStore.currentProjectId); const res = await getCustomOptionHeader(appStore.currentProjectId);
statusOption.value = res.statusOption;
const filterOptionsMaps: Record<string, any> = { const filterOptionsMaps: Record<string, any> = {
status: res.statusOption, status: res.statusOption,
handleUser: res.handleUserOption, handleUser: res.handleUserOption,
@ -786,6 +892,7 @@
await getColumnHeaders(); await getColumnHeaders();
await initFilterOptions(); await initFilterOptions();
await initPlatformOption();
await tableStore.initColumn(TableKeyEnum.BUG_MANAGEMENT, columns.concat(customColumns), 'drawer'); await tableStore.initColumn(TableKeyEnum.BUG_MANAGEMENT, columns.concat(customColumns), 'drawer');
function mountedLoad() { function mountedLoad() {