feat(缺陷管理): 高级筛选-缺陷首页
This commit is contained in:
parent
250f7dd894
commit
f72c08f4e8
|
@ -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)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -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',
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue