feat: 修改table过滤筛选样式和新增过滤筛选自定义内容(还未统一替换完)_测试计划
This commit is contained in:
parent
725f46d0f0
commit
a3394c7a24
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2 3C2 2.44772 2.44772 2 3 2H13C13.5523 2 14 2.44772 14 3V4.78597L9.75 7.28597V14H6.25V7.28597L2 4.78597V3ZM13 3H3V4.21403L7.25 6.71403V13H8.75V6.71403L13 4.21403V3Z" fill="#783887"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 296 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2 3C2 2.44772 2.44772 2 3 2H13C13.5523 2 14 2.44772 14 3V4.78597L9.75 7.28597V14H6.25V7.28597L2 4.78597V3ZM13 3H3V4.21403L7.25 6.71403V13H8.75V6.71403L13 4.21403V3Z" fill="#7D7D7F"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 296 B |
|
@ -66,7 +66,9 @@
|
||||||
:sortable="item.sortable"
|
:sortable="item.sortable"
|
||||||
:filterable="item.filterable"
|
:filterable="item.filterable"
|
||||||
:cell-class="item.cellClass"
|
:cell-class="item.cellClass"
|
||||||
:header-cell-class="item.headerCellClass"
|
:header-cell-class="`${
|
||||||
|
item.headerCellClass || (item.filterConfig && isHeighten) ? 'header-cell-filter' : ''
|
||||||
|
}`"
|
||||||
:body-cell-class="item.bodyCellClass"
|
:body-cell-class="item.bodyCellClass"
|
||||||
:summary-cell-class="item.summaryCellClass"
|
:summary-cell-class="item.summaryCellClass"
|
||||||
:cell-style="item.cellStyle"
|
:cell-style="item.cellStyle"
|
||||||
|
@ -80,7 +82,13 @@
|
||||||
<template #title>
|
<template #title>
|
||||||
<div :class="{ 'flex w-full flex-row flex-nowrap items-center gap-[4px]': !item.align }">
|
<div :class="{ 'flex w-full flex-row flex-nowrap items-center gap-[4px]': !item.align }">
|
||||||
<slot :name="item.titleSlotName" :column-config="item">
|
<slot :name="item.titleSlotName" :column-config="item">
|
||||||
<div v-if="item.title" class="text-[var(--color-text-3)]">{{ t(item.title as string) }}</div>
|
<div
|
||||||
|
v-if="item.title"
|
||||||
|
:class="`${
|
||||||
|
item.filterConfig && isHeighten ? 'text-[rgb(var(--primary-5))]' : 'text-[var(--color-text-3)]'
|
||||||
|
} pl-1`"
|
||||||
|
>{{ t(item.title as string) }}</div
|
||||||
|
>
|
||||||
</slot>
|
</slot>
|
||||||
<columnSelectorIcon
|
<columnSelectorIcon
|
||||||
v-if="
|
v-if="
|
||||||
|
@ -92,22 +100,18 @@
|
||||||
@show-setting="handleShowSetting"
|
@show-setting="handleShowSetting"
|
||||||
@init-data="handleInitColumn"
|
@init-data="handleInitColumn"
|
||||||
/>
|
/>
|
||||||
<slot v-else-if="item.filterConfig" :name="item.filterConfig.filterSlotName">
|
<DefaultFilter
|
||||||
<!-- <DefaultFilter
|
v-else-if="item.filterConfig"
|
||||||
class="ml-[4px]"
|
class="ml-[4px]"
|
||||||
:options="item.filterConfig.options"
|
:options="item.filterConfig.options"
|
||||||
@handle-confirm="(v) => handleFilterConfirm(v, item.dataIndex as string, item.isCustomParam || false)"
|
@handle-confirm="(v) => handleFilterConfirm(v, item.dataIndex as string, item.isCustomParam || false)"
|
||||||
/> -->
|
@show="showFilter(true)"
|
||||||
<!-- TODO 待办 过滤选项不生效 -->
|
@hide="showFilter(false)"
|
||||||
<!-- <TableFilter
|
>
|
||||||
v-bind="item.filterConfig"
|
<template #item="{ filterItem }">
|
||||||
@handle-confirm="(v) => handleFilterConfirm(v, item.dataIndex as string,item.isCustomParam || false)"
|
<slot :name="item.filterConfig.filterSlotName" :filter-content="filterItem"> </slot>
|
||||||
>
|
</template>
|
||||||
<template #item="{ item: itemValue, index }">
|
</DefaultFilter>
|
||||||
<slot name="filter-content" :item="itemValue" :index="index"> </slot>
|
|
||||||
</template>
|
|
||||||
</TableFilter> -->
|
|
||||||
</slot>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #cell="{ column, record, rowIndex }">
|
<template #cell="{ column, record, rowIndex }">
|
||||||
|
@ -280,9 +284,7 @@
|
||||||
import BatchAction from './batchAction.vue';
|
import BatchAction from './batchAction.vue';
|
||||||
import ColumnSelector from './columnSelector.vue';
|
import ColumnSelector from './columnSelector.vue';
|
||||||
import columnSelectorIcon from './columnSelectorIcon.vue';
|
import columnSelectorIcon from './columnSelectorIcon.vue';
|
||||||
// TODO待办
|
import DefaultFilter from './comp/defaultFilter.vue';
|
||||||
// import DefaultFilter from './comp/defaultFilter.vue';
|
|
||||||
// import TableFilter from './comp/tableFilter.vue';
|
|
||||||
import SelectALL from './select-all.vue';
|
import SelectALL from './select-all.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
@ -628,15 +630,20 @@
|
||||||
columnSelectorVisible.value = true;
|
columnSelectorVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// const handleFilterConfirm = (value: (string | number)[], dataIndex: string, isCustomParam: boolean) => {
|
const handleFilterConfirm = (value: (string | number)[], dataIndex: string, isCustomParam: boolean) => {
|
||||||
// emit('filterChange', dataIndex, value, isCustomParam);
|
emit('filterChange', dataIndex, value, isCustomParam);
|
||||||
// };
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await initColumn();
|
await initColumn();
|
||||||
batchLeft.value = getBatchLeft();
|
batchLeft.value = getBatchLeft();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isHeighten = ref<boolean>(false);
|
||||||
|
function showFilter(visible: boolean) {
|
||||||
|
isHeighten.value = visible;
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.columns,
|
() => props.columns,
|
||||||
() => {
|
() => {
|
||||||
|
@ -809,6 +816,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
:deep(.header-cell-filter) {
|
||||||
|
.arco-table-cell-with-filter {
|
||||||
|
float: left;
|
||||||
|
border-radius: 4px;
|
||||||
|
.arco-table-th-title {
|
||||||
|
border-radius: 4px;
|
||||||
|
color: rgb(var(--primary-5));
|
||||||
|
background: rgb(var(--primary-1)) content-box;
|
||||||
|
.filter-icon {
|
||||||
|
color: rgb(var(--primary-5)) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|
|
@ -1,24 +1,36 @@
|
||||||
<template>
|
<template>
|
||||||
<a-trigger v-model:popup-visible="visible" trigger="click">
|
<a-trigger v-model:popup-visible="visible" trigger="click">
|
||||||
<a-button type="text" @click="visible = true">
|
<span class="cursor-pointer pr-[2px]" @click="visible = true">
|
||||||
<template #icon>
|
<svg-icon
|
||||||
<icon-filter class="text-[var(--color-text-4)]" />
|
width="16px"
|
||||||
</template>
|
height="16px"
|
||||||
</a-button>
|
:name="visible ? 'filter-icon-color' : 'filter-icon'"
|
||||||
|
class="text-[12px] font-medium text-[rgb(var(--danger-6))]"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="arco-table-filters-content">
|
<div class="arco-table-filters-content">
|
||||||
<div class="arco-table-filters-content-list">
|
<div class="arco-table-filters-content-list">
|
||||||
<div class="max-h-[300px] overflow-y-auto px-[12px] py-[4px]">
|
<div class="max-h-[300px] overflow-y-auto px-[12px] py-[4px]">
|
||||||
<a-checkbox-group v-if="props.multiple" v-model="checkedList" size="mini" direction="vertical">
|
<a-checkbox-group v-model="checkedList" size="mini" direction="vertical">
|
||||||
<a-checkbox v-for="item in props.options" :key="item.value" :value="item.value">
|
<a-checkbox
|
||||||
{{ item.label }}
|
v-for="(item, index) of props.options"
|
||||||
|
:key="item[props.valueKey || 'value']"
|
||||||
|
:value="item[props.valueKey || 'value']"
|
||||||
|
>
|
||||||
|
<a-tooltip
|
||||||
|
:content="item[props.labelKey || 'label']"
|
||||||
|
:mouse-enter-delay="300"
|
||||||
|
:disabled="!item[props.labelKey || 'label']"
|
||||||
|
>
|
||||||
|
<div class="one-line-text max-w-[120px]">
|
||||||
|
<slot name="item" :filter-item="item" :index="index">
|
||||||
|
<div class="one-line-text max-w-[120px]">{{ item[props.labelKey || 'label'] }}</div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</a-tooltip>
|
||||||
</a-checkbox>
|
</a-checkbox>
|
||||||
</a-checkbox-group>
|
</a-checkbox-group>
|
||||||
<a-radio-group v-else v-model="checkedValue" size="mini" direction="vertical">
|
|
||||||
<a-radio v-for="item in props.options" :key="item.value" :value="item.value">
|
|
||||||
{{ item.label }}
|
|
||||||
</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="arco-table-filters-bottom">
|
<div class="arco-table-filters-bottom">
|
||||||
<a-button size="mini" type="secondary" @click="handleFilterReset">
|
<a-button size="mini" type="secondary" @click="handleFilterReset">
|
||||||
|
@ -38,9 +50,14 @@
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
export interface FilterListItem {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
multiple: boolean;
|
options?: FilterListItem[];
|
||||||
options?: { label: string; value: string | number }[];
|
valueKey?: string;
|
||||||
|
labelKey?: string;
|
||||||
}>();
|
}>();
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'handleConfirm', value: (string | number)[]): void;
|
(e: 'handleConfirm', value: (string | number)[]): void;
|
||||||
|
@ -49,24 +66,15 @@
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
|
||||||
const checkedList = ref<(string | number)[]>([]);
|
const checkedList = ref<(string | number)[]>([]);
|
||||||
const checkedValue = ref<string | number>('');
|
|
||||||
|
|
||||||
const handleFilterReset = () => {
|
const handleFilterReset = () => {
|
||||||
if (props.multiple) {
|
checkedList.value = [];
|
||||||
checkedList.value = [];
|
|
||||||
} else {
|
|
||||||
checkedValue.value = '';
|
|
||||||
}
|
|
||||||
emit('handleConfirm', []);
|
emit('handleConfirm', []);
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilterSubmit = () => {
|
const handleFilterSubmit = () => {
|
||||||
if (props.multiple) {
|
emit('handleConfirm', checkedList.value);
|
||||||
emit('handleConfirm', checkedList.value);
|
|
||||||
} else {
|
|
||||||
emit('handleConfirm', checkedValue.value ? [checkedValue.value] : []);
|
|
||||||
}
|
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { TableQueryParams } from '@/models/common';
|
import type { TableQueryParams } from '@/models/common';
|
||||||
import { ColumnEditTypeEnum, SelectAllEnum, TableKeyEnum } from '@/enums/tableEnum';
|
import { ColumnEditTypeEnum, SelectAllEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||||
|
|
||||||
import type { TableChangeExtra, TableColumnData, TableData, TableDraggable } from '@arco-design/web-vue';
|
import type { TableChangeExtra, TableColumnData, TableData, TableDraggable } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
@ -15,13 +16,10 @@ export interface MsPaginationI {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MsTableColumnFilterConfig {
|
export interface MsTableColumnFilterConfig {
|
||||||
filterSlotName?: string; // 筛选组件的slotName
|
filterSlotName?: FilterSlotNameEnum; // 筛选组件的slotName @desc 定义枚举是为了table组件内的插槽的filterSlotName 可以精确的让外部组件使用的时候可以拿到插槽作用域的值
|
||||||
multiple?: boolean; // 是否多选
|
options?: Record<string, any>[]; // 筛选数据
|
||||||
// 筛选数据
|
valueKey?: string;
|
||||||
options?: {
|
labelKey?: string;
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
}[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MsTableColumnData extends TableColumnData {
|
export interface MsTableColumnData extends TableColumnData {
|
||||||
|
@ -51,6 +49,8 @@ export interface MsTableColumnData extends TableColumnData {
|
||||||
columnTitle?: string;
|
columnTitle?: string;
|
||||||
// 是否是自定义字段
|
// 是否是自定义字段
|
||||||
isCustomParam?: boolean;
|
isCustomParam?: boolean;
|
||||||
|
// 插槽表格过滤筛选数据item
|
||||||
|
filterItem?: any;
|
||||||
// 自定义属性
|
// 自定义属性
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
export enum FilterSlotNameEnum {
|
||||||
|
TEST_PLAN_STATUS_FILTER = 'TEST_PLAN_STATUS_FILTER',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {};
|
|
@ -96,40 +96,9 @@
|
||||||
</a-tooltip></div
|
</a-tooltip></div
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #statusFilter="{ columnConfig }">
|
<template #[FilterSlotNameEnum.TEST_PLAN_STATUS_FILTER]="{ filterContent }">
|
||||||
<a-trigger v-model:popup-visible="statusFilterVisible" trigger="click" @popup-visible-change="handleFilterHidden">
|
<statusTag :status="filterContent.value" />
|
||||||
<a-button type="text" class="arco-btn-text--secondary" @click="statusFilterVisible = true">
|
|
||||||
{{ t(columnConfig.title as string) }}
|
|
||||||
<icon-down :class="statusFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
|
||||||
</a-button>
|
|
||||||
<template #content>
|
|
||||||
<div class="arco-table-filters-content">
|
|
||||||
<div class="flex items-center justify-center px-[6px] py-[2px]">
|
|
||||||
<a-checkbox-group v-model:model-value="statusFilters" direction="vertical" size="small">
|
|
||||||
<a-checkbox v-for="key of Object.keys(planStatusMap)" :key="key" :value="key">
|
|
||||||
<a-tag
|
|
||||||
:color="planStatusMap[key as planStatusType].color"
|
|
||||||
:class="[planStatusMap[key as planStatusType].class, 'px-[4px]']"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
{{ t(planStatusMap[key as planStatusType].label) }}
|
|
||||||
</a-tag>
|
|
||||||
</a-checkbox>
|
|
||||||
</a-checkbox-group>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button">
|
|
||||||
<a-button size="mini" class="mr-[8px]" @click="resetStatusFilter">
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="primary" size="mini" @click="handleFilterHidden(false)">
|
|
||||||
{{ t('system.orgTemplate.confirm') }}
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-trigger>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<statusTag :status="record.status" />
|
<statusTag :status="record.status" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -298,9 +267,10 @@
|
||||||
import type { planStatusType, TestPlanItem } from '@/models/testPlan/testPlan';
|
import type { planStatusType, TestPlanItem } from '@/models/testPlan/testPlan';
|
||||||
import { TestPlanRouteEnum } from '@/enums/routeEnum';
|
import { TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||||
import { testPlanTypeEnum } from '@/enums/testPlanEnum';
|
import { testPlanTypeEnum } from '@/enums/testPlanEnum';
|
||||||
|
|
||||||
import { planStatusMap } from '../config';
|
import { planStatusOptions } from '../config';
|
||||||
|
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
@ -358,7 +328,10 @@
|
||||||
title: 'testPlan.testPlanIndex.executionResult',
|
title: 'testPlan.testPlanIndex.executionResult',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
slotName: 'status',
|
slotName: 'status',
|
||||||
titleSlotName: 'statusFilter',
|
filterConfig: {
|
||||||
|
options: planStatusOptions,
|
||||||
|
filterSlotName: FilterSlotNameEnum.TEST_PLAN_STATUS_FILTER,
|
||||||
|
},
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
width: 150,
|
width: 150,
|
||||||
|
@ -610,7 +583,6 @@
|
||||||
selectAll: !!batchParams.value?.selectAll,
|
selectAll: !!batchParams.value?.selectAll,
|
||||||
selectIds: batchParams.value.selectedIds || [],
|
selectIds: batchParams.value.selectedIds || [],
|
||||||
keyword: keyword.value,
|
keyword: keyword.value,
|
||||||
filter: {},
|
|
||||||
condition: {
|
condition: {
|
||||||
keyword: keyword.value,
|
keyword: keyword.value,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
import type { planStatusType } from '@/models/testPlan/testPlan';
|
import type { planStatusType } from '@/models/testPlan/testPlan';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
export type PlanStatusMap = Record<
|
export type PlanStatusMap = Record<
|
||||||
planStatusType,
|
planStatusType,
|
||||||
{
|
{
|
||||||
|
@ -8,6 +12,7 @@ export type PlanStatusMap = Record<
|
||||||
class: string;
|
class: string;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export const planStatusMap: PlanStatusMap = {
|
export const planStatusMap: PlanStatusMap = {
|
||||||
PREPARED: {
|
PREPARED: {
|
||||||
label: 'caseManagement.caseReview.unStart',
|
label: 'caseManagement.caseReview.unStart',
|
||||||
|
@ -30,3 +35,22 @@ export const planStatusMap: PlanStatusMap = {
|
||||||
class: '!text-[var(--color-text-4)]',
|
class: '!text-[var(--color-text-4)]',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const planStatusOptions: { value: planStatusType; label: string }[] = [
|
||||||
|
{
|
||||||
|
value: 'PREPARED',
|
||||||
|
label: t('caseManagement.caseReview.unStart'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'UNDERWAY',
|
||||||
|
label: t('caseManagement.caseReview.going'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'COMPLETED',
|
||||||
|
label: t('caseManagement.caseReview.unStart'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'ARCHIVED',
|
||||||
|
label: t('caseManagement.caseReview.going'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
Loading…
Reference in New Issue