feat(缺陷管理): 缺陷管理回收站增加部分筛选字段和排序字段
--bug=1036456 --user=宋天阳 【缺陷管理】回收站列表,部分字段表头需支持筛选和排序 https://www.tapd.cn/55049933/s/1472938
This commit is contained in:
parent
da550b75f7
commit
0a902b5781
|
@ -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
|
||||
|
|
|
@ -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 });
|
||||
});
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue