feat(缺陷管理): 缺陷管理回收站增加部分筛选字段和排序字段

--bug=1036456 --user=宋天阳 【缺陷管理】回收站列表,部分字段表头需支持筛选和排序 https://www.tapd.cn/55049933/s/1472938
This commit is contained in:
song-tianyang 2024-03-11 18:38:04 +08:00 committed by 刘瑞斌
parent da550b75f7
commit 0a902b5781
4 changed files with 292 additions and 27 deletions

View File

@ -169,6 +169,16 @@
and b.handle_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<!-- 删除人 -->
<when test="key == 'deleteUser'">
and b.delete_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<!-- 更新人 -->
<when test="key == 'updateUser'">
and b.update_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<!-- 创建人 -->
<when test="key == 'createUser'">
and b.create_user in

View File

@ -758,12 +758,6 @@
sort.value = sortObj;
}
async function searchData() {
// eslint-disable-next-line no-use-before-define
setLoadListParams(initTableParams());
await loadList();
}
function initTableParams() {
const filterParams = {
status: statusFilterValue.value,
@ -782,6 +776,12 @@
},
};
}
function searchData() {
setLoadListParams(initTableParams());
loadList();
}
watchEffect(() => {
setProps({ heightUsed: heightUsed.value });
});

View File

@ -28,26 +28,120 @@
}}</MsButton>
</div>
</template>
<template #createUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="createUserFilterVisible"
v-model:status-filters="createUserFilterValue"
:title="(columnConfig.title as string)"
:list="createUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #updateUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="updateUserFilterVisible"
v-model:status-filters="updateUserFilterValue"
:title="(columnConfig.title as string)"
:list="updateUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #deleteUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="deleteUserFilterVisible"
v-model:status-filters="deleteUserFilterValue"
:title="(columnConfig.title as string)"
:list="deleteUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #handleUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #statusFilter="{ columnConfig }">
<TableFilter
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #severityFilter="{ columnConfig }">
<TableFilter
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #empty> </template>
</MsBaseTable>
</MsCard>
</template>
<script lang="ts" async setup>
import { Message } from '@arco-design/web-vue';
import dayjs from 'dayjs';
import { ref } from 'vue';
import { Message, TableData } from '@arco-design/web-vue';
import { MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
import { FilterFormItem, FilterType } from '@/components/pure/ms-advance-filter/type';
import { BackEndEnum, FilterFormItem, FilterType } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsCard from '@/components/pure/ms-card/index.vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue';
import {
deleteBatchByRecycle,
deleteSingleByRecycle,
getCustomFieldHeader,
getCustomOptionHeader,
getRecycleList,
recoverBatchByRecycle,
recoverSingleByRecycle,
@ -55,9 +149,14 @@
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import { useAppStore, useTableStore } from '@/store';
import { characterLimit, tableParamsToRequestParams } from '@/utils';
import {
characterLimit,
customFieldDataToTableData,
customFieldToColumns,
tableParamsToRequestParams,
} from '@/utils';
import { BugListItem } from '@/models/bug-management';
import { BugEditCustomField, BugListItem, BugOptionItem } from '@/models/bug-management';
import { TableKeyEnum } from '@/enums/tableEnum';
const { t } = useI18n();
@ -68,6 +167,8 @@
const filterVisible = ref(false);
const filterRowCount = ref(0);
const keyword = ref('');
//
const customFields = ref<BugEditCustomField[]>([]);
const filterConfigList = reactive<FilterFormItem[]>([
{
title: 'bugManagement.ID',
@ -76,11 +177,9 @@
},
{
title: 'bugManagement.bugName',
dataIndex: 'name',
type: FilterType.SELECT,
selectProps: {
mode: 'static',
},
dataIndex: 'title',
type: FilterType.INPUT,
backendType: BackEndEnum.STRING,
},
{
title: 'bugManagement.createTime',
@ -89,6 +188,27 @@
},
]);
//
const createUserFilterOptions = ref<BugOptionItem[]>([]);
const createUserFilterVisible = ref(false);
const createUserFilterValue = ref<string[]>([]);
const updateUserFilterOptions = ref<BugOptionItem[]>([]);
const updateUserFilterVisible = ref(false);
const updateUserFilterValue = ref<string[]>([]);
const handleUserFilterOptions = ref<BugOptionItem[]>([]);
const handleUserFilterVisible = ref(false);
const handleUserFilterValue = ref<string[]>([]);
const deleteUserFilterOptions = ref<BugOptionItem[]>([]);
const deleteUserFilterVisible = ref(false);
const deleteUserFilterValue = ref<string[]>([]);
const statusFilterOptions = ref<BugOptionItem[]>([]);
const statusFilterVisible = ref(false);
const statusFilterValue = ref<string[]>([]);
const severityFilterOptions = ref<BugOptionItem[]>([]);
const severityFilterVisible = ref(false);
const severityFilterValue = ref<string[]>([]);
const severityColumnId = ref('');
const heightUsed = computed(() => 286 + (filterVisible.value ? 160 + (filterRowCount.value - 1) * 60 : 0));
const columns: MsTableColumn = [
@ -96,12 +216,22 @@
title: 'bugManagement.recycle.deleteTime',
dataIndex: 'deleteTime',
showDrag: true,
width: 180,
width: 199,
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
showInTable: true,
},
{
title: 'bugManagement.recycle.deleteMan',
dataIndex: 'deleteUserName',
width: 112,
showDrag: true,
slotName: 'deleteUser',
showTooltip: true,
titleSlotName: 'deleteUserFilter',
showInTable: true,
},
{
title: 'bugManagement.ID',
@ -128,21 +258,72 @@
columnSelectorDisabled: true,
},
{
title: 'bugManagement.creator',
dataIndex: 'createUserName',
showDrag: true,
title: 'bugManagement.handleMan',
dataIndex: 'handleUser',
slotName: 'handleUser',
showTooltip: true,
titleSlotName: 'handleUserFilter',
width: 112,
showDrag: true,
showInTable: true,
},
{
title: 'bugManagement.creator',
dataIndex: 'createUser',
slotName: 'createUser',
width: 112,
showTooltip: true,
showDrag: true,
titleSlotName: 'createUserFilter',
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
showInTable: true,
},
{
title: 'bugManagement.createTime',
dataIndex: 'createTime',
showDrag: true,
width: 180,
width: 199,
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
showInTable: true,
},
{
title: 'bugManagement.updateUser',
dataIndex: 'updateUser',
width: 112,
showTooltip: true,
showDrag: true,
titleSlotName: 'updateUserFilter',
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
showInTable: true,
},
{
title: 'bugManagement.updateTime',
dataIndex: 'updateTime',
showDrag: true,
width: 199,
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
showInTable: true,
},
{
title: 'bugManagement.status',
dataIndex: 'statusName',
width: 84,
slotName: 'status',
titleSlotName: 'statusFilter',
showDrag: true,
showInTable: true,
},
{
title: 'bugManagement.handleMan',
@ -153,6 +334,7 @@
{
title: 'bugManagement.tag',
showDrag: true,
width: 456,
isStringTag: true,
dataIndex: 'tags',
},
@ -164,7 +346,42 @@
width: 150,
},
];
await tableStore.initColumn(TableKeyEnum.BUG_MANAGEMENT_RECYCLE, columns, 'drawer');
//
const getCustomFieldColumns = async () => {
const res = await getCustomFieldHeader(projectId.value);
customFields.value = res;
// filters
customFields.value.forEach((item) => {
if ((item.fieldName === '严重程度' || item.fieldName === 'Bug Degree') && item.options) {
severityFilterOptions.value = [];
severityColumnId.value = `custom_single_${item.fieldId}`;
item.options.forEach((option) => {
severityFilterOptions.value.push({
value: option.value,
text: option.text,
});
});
}
});
return customFieldToColumns(res);
};
const customColumns = await getCustomFieldColumns();
customColumns.forEach((item) => {
if (item.title === '严重程度' || item.title === 'Bug Degree') {
item.showInTable = true;
item.titleSlotName = 'severityFilter';
item.slotName = 'severity';
} else {
item.showInTable = false;
}
});
await tableStore.initColumn(TableKeyEnum.BUG_MANAGEMENT_RECYCLE, columns.concat(customColumns), 'drawer');
const { propsRes, propsEvent, loadList, setKeyword, setLoadListParams, setProps } = useTable(
getRecycleList,
@ -175,10 +392,13 @@
showSetting: true,
scroll: { x: '1900px' },
},
(record) => {
record.deleteTime = dayjs(record.deleteTime).format('YYYY-MM-DD HH:mm:ss');
return record;
}
(record: TableData) => ({
...record,
handleUser: record.handleUserName,
createUser: record.createUserName,
updateUser: record.updateUserName,
...customFieldDataToTableData(record.customFields, customFields.value),
})
);
const tableAction = {
@ -280,8 +500,43 @@
}
}
function initTableParams() {
const filterParams = {
status: statusFilterValue.value,
handleUser: handleUserFilterValue.value,
updateUser: updateUserFilterValue.value,
createUser: createUserFilterValue.value,
deleteUser: deleteUserFilterValue.value,
};
filterParams[severityColumnId.value] = severityFilterValue.value;
return {
keyword: keyword.value,
projectId: projectId.value,
filter: { ...filterParams },
condition: {
keyword: keyword.value,
filter: propsRes.value.filter,
},
};
}
function searchData() {
setLoadListParams(initTableParams());
loadList();
}
async function initFilterOptions() {
const res = await getCustomOptionHeader(appStore.currentProjectId);
createUserFilterOptions.value = res.userOption;
updateUserFilterOptions.value = res.userOption;
deleteUserFilterOptions.value = res.userOption;
handleUserFilterOptions.value = res.handleUserOption;
statusFilterOptions.value = res.statusOption;
}
onMounted(() => {
setLoadListParams({ projectId: projectId.value });
initFilterOptions();
fetchData();
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<a-trigger v-model:popup-visible="innerVisible" trigger="click" @popup-visible-change="handleFilterHidden">
<a-button type="text" class="arco-btn-text--secondary p-[8px_4px]" @click="innerVisible = true">
<a-button type="text" class="arco-btn-text--secondary p-[8px_4px]" @click.stop="innerVisible = true">
<div class="font-medium">
{{ t(props.title) }}
</div>