feat: overwrite table column filter

This commit is contained in:
RubyLiu 2023-11-22 19:36:42 +08:00 committed by rubylliu
parent 587e105a4f
commit 25acb2b894
6 changed files with 124 additions and 13 deletions

View File

@ -19,10 +19,11 @@
<template #columns> <template #columns>
<a-table-column v-if="attrs.selectable && props.selectedKeys" :width="60"> <a-table-column v-if="attrs.selectable && props.selectedKeys" :width="60">
<template #title> <template #title>
<select-all <SelectALL
:total="selectTotal" :total="selectTotal"
:current="selectCurrent" :current="selectCurrent"
:type="attrs.selectorType as ('checkbox' | 'radio')" :show-select-all="(attrs.showPagination as boolean)"
:disabled="(attrs.data as []).length === 0"
@change="handleSelectAllChange" @change="handleSelectAllChange"
/> />
</template> </template>
@ -65,6 +66,13 @@
class="setting-icon" class="setting-icon"
@click="handleShowSetting" @click="handleShowSetting"
/> />
<slot v-else-if="item.filterConfig" :name="item.filterConfig.filterSlotName">
<DefaultFilter
:options="item.filterConfig.options"
:multiple="(item.filterConfig.multiple as boolean)"
@handle-confirm="(v: (string | number)[]) => handleFilterConfirm(v, item.dataIndex as string)"
/>
</slot>
</div> </div>
</template> </template>
<template #cell="{ column, record, rowIndex }"> <template #cell="{ column, record, rowIndex }">
@ -209,7 +217,8 @@
import MsCheckbox from '../ms-checkbox/MsCheckbox.vue'; import MsCheckbox from '../ms-checkbox/MsCheckbox.vue';
import BatchAction from './batchAction.vue'; import BatchAction from './batchAction.vue';
import ColumnSelector from './columnSelector.vue'; import ColumnSelector from './columnSelector.vue';
import selectAll from './select-all.vue'; import DefaultFilter from './comp/defaultFilter.vue';
import SelectALL from './select-all.vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore, useTableStore } from '@/store'; import { useAppStore, useTableStore } from '@/store';
@ -256,6 +265,7 @@
(e: 'sorterChange', value: { [key: string]: string }): void; (e: 'sorterChange', value: { [key: string]: string }): void;
(e: 'expand', record: TableData): void | Promise<any>; (e: 'expand', record: TableData): void | Promise<any>;
(e: 'clearSelector'): void; (e: 'clearSelector'): void;
(e: 'filterChange', dataIndex: string, value: (string | number)[]): void;
}>(); }>();
const attrs = useAttrs(); const attrs = useAttrs();
// - // -
@ -453,6 +463,10 @@
columnSelectorVisible.value = true; columnSelectorVisible.value = true;
}; };
const handleFilterConfirm = (value: (string | number)[], dataIndex: string) => {
emit('filterChange', dataIndex, value);
};
onMounted(async () => { onMounted(async () => {
await initColumn(); await initColumn();
batchLeft.value = getBatchLeft(); batchLeft.value = getBatchLeft();

View File

@ -15,7 +15,7 @@
>{{ t(element.label as string) }}</a-button >{{ t(element.label as string) }}</a-button
> >
</template> </template>
<div v-if="props.actionConfig.moreAction" class="drop-down relative ml-[16px] inline-block"> <div v-if="moreAction?.length" class="drop-down relative ml-[16px] inline-block">
<a-dropdown position="tr" @select="handleSelect"> <a-dropdown position="tr" @select="handleSelect">
<a-button type="outline"><MsIcon type="icon-icon_more_outlined" /></a-button> <a-button type="outline"><MsIcon type="icon-icon_more_outlined" /></a-button>
<template #content> <template #content>

View File

@ -0,0 +1,73 @@
<template>
<a-trigger v-model:popup-visible="visible" trigger="click">
<a-button type="text" @click="visible = true">
<template #icon>
<icon-filter />
</template>
</a-button>
<template #content>
<div class="arco-table-filters-content">
<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 v-for="item in props.options" :key="item.value" :value="item.value">
{{ item.label }}
</a-checkbox>
</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 class="arco-table-filters-bottom">
<a-button size="mini" type="secondary" @click="handleFilterReset">
{{ t('common.reset') }}
</a-button>
<a-button size="mini" type="primary" @click="handleFilterSubmit(false)">
{{ t('common.confirm') }}
</a-button>
</div>
</div>
</template>
</a-trigger>
</template>
<script lang="ts" setup>
import { useI18n } from '@/hooks/useI18n';
const { t } = useI18n();
const props = defineProps<{
multiple: boolean;
options?: { label: string; value: string | number }[];
}>();
const emit = defineEmits<{
(e: 'handleConfirm', value: (string | number)[]): void;
}>();
const visible = ref(false);
const checkedList = ref<(string | number)[]>([]);
const checkedValue = ref<string | number>('');
const handleFilterSubmit = (isReset = false) => {
if (props.multiple) {
emit('handleConfirm', checkedList.value);
} else {
emit('handleConfirm', [checkedValue.value]);
}
if (!isReset) {
checkedList.value = [];
checkedValue.value = '';
}
visible.value = false;
};
const handleFilterReset = () => {
if (props.multiple) {
checkedList.value = [];
} else {
checkedValue.value = '';
}
handleFilterSubmit(true);
};
</script>

View File

@ -1,7 +1,13 @@
<template> <template>
<div class="ms-table-select-all"> <div class="ms-table-select-all">
<a-checkbox v-model="checked" class="text-base" :indeterminate="indeterminate" @change="handleCheckChange" /> <a-checkbox
<a-dropdown position="bl" @select="handleSelect"> v-model="checked"
:disabled="props.disabled"
class="text-base"
:indeterminate="indeterminate"
@change="handleCheckChange"
/>
<a-dropdown v-if="showSelectAll" :disable="props.disabled" position="bl" @select="handleSelect">
<MsIcon type="icon-icon_down_outlined" class="dropdown-icon" /> <MsIcon type="icon-icon_down_outlined" class="dropdown-icon" />
<template #content> <template #content>
<a-doption :value="SelectAllEnum.CURRENT">{{ t('msTable.current') }}</a-doption> <a-doption :value="SelectAllEnum.CURRENT">{{ t('msTable.current') }}</a-doption>
@ -26,10 +32,15 @@
(e: 'change', value: SelectAllEnum): void; (e: 'change', value: SelectAllEnum): void;
}>(); }>();
const props = withDefaults(defineProps<{ current: number; total: number; type: 'checkbox' | 'radio' }>(), { const props = withDefaults(
current: 0, defineProps<{ current: number; total: number; showSelectAll: boolean; disabled: boolean }>(),
total: 0, {
}); current: 0,
total: 0,
showSelectAll: true,
disabled: false,
}
);
const checked = ref(false); const checked = ref(false);
const indeterminate = ref(false); const indeterminate = ref(false);

View File

@ -14,6 +14,16 @@ export interface MsPaginationI {
simple?: boolean; simple?: boolean;
} }
export interface MsTableColumnFilterConfig {
filterSlotName?: string; // 筛选组件的slotName
multiple?: boolean; // 是否多选
// 筛选数据
options?: {
label: string;
value: string;
}[];
}
export interface MsTableColumnData extends TableColumnData { export interface MsTableColumnData extends TableColumnData {
// 是否可排序 // 是否可排序
showDrag?: boolean; showDrag?: boolean;
@ -35,6 +45,8 @@ export interface MsTableColumnData extends TableColumnData {
revokeDeletedSlot?: string; revokeDeletedSlot?: string;
// 表格列排序字段 // 表格列排序字段
sortIndex?: number; sortIndex?: number;
// 筛选配置
filterConfig?: MsTableColumnFilterConfig;
} }
export type MsTableErrorStatus = boolean | 'error' | 'empty'; export type MsTableErrorStatus = boolean | 'error' | 'empty';

View File

@ -301,7 +301,8 @@ export default function useTableProps<T>(
}, },
// 筛选触发 // 筛选触发
filterChange: (dataIndex: string, filteredValues: string[]) => { filterChange: (dataIndex: string, filteredValues: (string | number)[]) => {
console.log('filterChange', dataIndex, filteredValues);
filterItem.value = { [dataIndex]: filteredValues }; filterItem.value = { [dataIndex]: filteredValues };
loadList(); loadList();
}, },
@ -311,12 +312,12 @@ export default function useTableProps<T>(
await loadList(); await loadList();
}, },
// 修改每页显示条数 // 修改每页显示条数
pageSizeChange: (pageSize: number) => { pageSizeChange: async (pageSize: number) => {
if (propsRes.value.msPagination && typeof propsRes.value.msPagination === 'object') { if (propsRes.value.msPagination && typeof propsRes.value.msPagination === 'object') {
propsRes.value.msPagination.pageSize = pageSize; propsRes.value.msPagination.pageSize = pageSize;
if (propsRes.value.tableKey) { if (propsRes.value.tableKey) {
// 如果表格设置了tableKey缓存分页大小 // 如果表格设置了tableKey缓存分页大小
tableStore.setPageSize(propsRes.value.tableKey, pageSize); await tableStore.setPageSize(propsRes.value.tableKey, pageSize);
} }
} }
loadList(); loadList();