334 lines
9.7 KiB
Plaintext
334 lines
9.7 KiB
Plaintext
<template>
|
|
<a-tooltip trigger="hover">
|
|
<template #title>
|
|
<span>列设置</span>
|
|
</template>
|
|
<div class="cursor-pointer table-toolbar-right-icon">
|
|
<a-popover
|
|
:overlayStyle="{ width: getPopoverWidth, maxHeight: '50vh', padding: 0 }"
|
|
overlayClassName="toolbar-popover"
|
|
placement="rightBottom"
|
|
trigger="click"
|
|
>
|
|
<SettingOutlined />
|
|
|
|
<template #content>
|
|
<div class="table-toolbar-inner-popover-title">
|
|
<div class="w-full flex justify-between items-center">
|
|
<a-checkbox
|
|
v-model:checked="checkAll"
|
|
:indeterminate="!checkAll && checkPart"
|
|
@change="onCheckAll"
|
|
>列展示
|
|
</a-checkbox>
|
|
<!-- <a-checkbox v-model:checked="selection" @update:checked="onSelection"-->
|
|
<!-- >勾选列-->
|
|
<!-- </a-checkbox>-->
|
|
<a-button class="mt-1" size="small" type="link" @click="resetColumns">重置 </a-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-toolbar-inner">
|
|
<a-checkbox-group v-model:value="checkList" @change="onChange">
|
|
<Draggable
|
|
v-model="basicColumns"
|
|
animation="300"
|
|
item-key="key"
|
|
filter=".no-draggable"
|
|
:move="onMove"
|
|
@end="draggableEnd"
|
|
>
|
|
<template #item="{ element }">
|
|
<div
|
|
v-if="element.type != 'selection' && element.type != 'expand'"
|
|
:class="{
|
|
'table-toolbar-inner-checkbox-dark': getDarkTheme === true,
|
|
'no-draggable': element.draggable === false,
|
|
}"
|
|
class="table-toolbar-inner-checkbox"
|
|
>
|
|
<span class="drag-icon">
|
|
<DragOutlined style="font-size: 18px" />
|
|
</span>
|
|
<a-checkbox :value="element.key">{{ element.title }}</a-checkbox>
|
|
<div class="fixed-item">
|
|
<a-tooltip placement="top" trigger="hover">
|
|
<template #title>
|
|
<span>固定到左侧</span>
|
|
</template>
|
|
<span
|
|
:color="element.fixed === 'left' ? '#1e6fff' : undefined"
|
|
class="cursor-pointer"
|
|
size="18"
|
|
@click="fixedColumn(element, 'left')"
|
|
>
|
|
<VerticalRightOutlined />
|
|
</span>
|
|
</a-tooltip>
|
|
<a-divider type="vertical" />
|
|
<a-tooltip placement="top" trigger="hover">
|
|
<template #title>
|
|
<span>固定到右侧</span>
|
|
</template>
|
|
<span
|
|
:color="element.fixed === 'right' ? '#1e6fff' : undefined"
|
|
class="cursor-pointer"
|
|
size="18"
|
|
@click="fixedColumn(element, 'right')"
|
|
>
|
|
<VerticalLeftOutlined />
|
|
</span>
|
|
</a-tooltip>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</Draggable>
|
|
</a-checkbox-group>
|
|
</div>
|
|
</template>
|
|
</a-popover>
|
|
</div>
|
|
</a-tooltip>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, unref, toRaw, watchEffect, computed } from 'vue';
|
|
import { useTableContext } from '../../hooks/useTableContext';
|
|
import { cloneDeep } from 'lodash-es';
|
|
import {
|
|
SettingOutlined,
|
|
DragOutlined,
|
|
VerticalRightOutlined,
|
|
VerticalLeftOutlined,
|
|
} from '@ant-design/icons-vue';
|
|
import Draggable from 'vuedraggable/src/vuedraggable';
|
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
|
import type { TableSetting } from '../../types/table';
|
|
|
|
interface Options {
|
|
title: string;
|
|
key: string;
|
|
fixed?: boolean | 'left' | 'right';
|
|
}
|
|
|
|
const props = defineProps({
|
|
tableSetting: {
|
|
type: Object as PropType<TableSetting>,
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(['columnsChange']);
|
|
|
|
const getPopoverWidth = computed(() => {
|
|
return props.tableSetting?.width + 'px';
|
|
});
|
|
|
|
const { getDarkTheme } = useProjectSetting();
|
|
const table: any = useTableContext();
|
|
const basicColumns = ref<Options[]>([]);
|
|
const cacheColumnsList = ref<Options[]>([]);
|
|
|
|
const selection = ref(false);
|
|
const checkAll = ref(true);
|
|
const checkPart = ref(false);
|
|
const checkList = ref<string[]>([]);
|
|
const defaultCheckList = ref([]);
|
|
|
|
watchEffect(() => {
|
|
const columns = table.getColumns();
|
|
if (columns.length) {
|
|
init();
|
|
}
|
|
});
|
|
|
|
//初始化
|
|
function init() {
|
|
const columns: any[] = getColumns();
|
|
//同时兼容 全选 反选,单选
|
|
const checkListArr: any =
|
|
!checkAll.value && !checkPart.value && checkList.value.length
|
|
? checkList.value
|
|
: columns.map((item) => item.key);
|
|
//重新赋值
|
|
checkList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;
|
|
defaultCheckList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;
|
|
|
|
const newColumns = columns.filter(
|
|
(item) => item.type != 'selection' && item.key != 'action' && item.title != '操作',
|
|
);
|
|
if (!basicColumns.value.length) {
|
|
basicColumns.value = cloneDeep(newColumns);
|
|
cacheColumnsList.value = cloneDeep(newColumns);
|
|
}
|
|
}
|
|
|
|
//切换
|
|
function onChange(list) {
|
|
if (selection.value) {
|
|
list.unshift('selection');
|
|
}
|
|
const filterColumns = basicColumns.value.filter((item) => {
|
|
return list.includes(item.key);
|
|
});
|
|
const isAction = list.includes('action');
|
|
const len = isAction ? list.length - 1 : list.length;
|
|
checkPart.value = basicColumns.value.length != len;
|
|
checkAll.value = basicColumns.value.length == len;
|
|
setColumns(filterColumns);
|
|
table.isShowTable.value = true;
|
|
emit('columnsChange', table.getColumns());
|
|
}
|
|
|
|
//设置
|
|
function setColumns(columns) {
|
|
table.setColumns(columns);
|
|
}
|
|
|
|
//获取
|
|
function getColumns() {
|
|
let newRet: any[] = [];
|
|
table.getColumns().forEach((item) => {
|
|
item.key = item.key || item.dataIndex;
|
|
newRet.push({ ...item });
|
|
});
|
|
return newRet;
|
|
}
|
|
|
|
function onMove(e) {
|
|
if (e.draggedContext.element.draggable === false) return false;
|
|
return true;
|
|
}
|
|
|
|
//重置
|
|
function resetColumns() {
|
|
checkList.value = [...defaultCheckList.value];
|
|
checkAll.value = true;
|
|
let cacheColumnsKeys: any[] = table.getCacheColumns();
|
|
let newColumns = cacheColumnsKeys.map((item) => {
|
|
return {
|
|
...item,
|
|
fixed: undefined,
|
|
};
|
|
});
|
|
setColumns(newColumns);
|
|
basicColumns.value = newColumns;
|
|
table.isShowTable.value = true;
|
|
emit('columnsChange', table.getColumns());
|
|
}
|
|
|
|
//全选
|
|
function onCheckAll(e) {
|
|
let checkList = table.getCacheColumns();
|
|
checkPart.value = false;
|
|
if (e.target.checked) {
|
|
setColumns(checkList);
|
|
checkAll.value = true;
|
|
checkList.value = checkList;
|
|
table.isShowTable.value = true;
|
|
} else {
|
|
table.isShowTable.value = false;
|
|
checkList.value = [];
|
|
checkAll.value = false;
|
|
setColumns([]);
|
|
}
|
|
emit('columnsChange', table.getColumns());
|
|
}
|
|
|
|
//拖拽排序
|
|
function draggableEnd() {
|
|
const newColumns = toRaw(unref(basicColumns));
|
|
basicColumns.value = newColumns;
|
|
const filterColumns = newColumns.filter((item) => {
|
|
return checkList.value.includes(item.key);
|
|
});
|
|
checkList.value = filterColumns.map((item) => item.key);
|
|
setColumns(filterColumns);
|
|
emit('columnsChange', table.getColumns());
|
|
}
|
|
|
|
//勾选列
|
|
// function onSelection(e) {
|
|
// let checkList = table.getCacheColumns();
|
|
// if (e) {
|
|
// checkList.unshift({ type: 'selection', key: 'selection' });
|
|
// setColumns(checkList);
|
|
// } else {
|
|
// checkList.splice(0, 1);
|
|
// setColumns(checkList);
|
|
// }
|
|
// }
|
|
|
|
//固定
|
|
function fixedColumn(item, fixed) {
|
|
if (!unref(checkList).includes(item.key as never)) return;
|
|
let columns = getColumns();
|
|
const isFixed = item.fixed === fixed ? undefined : fixed;
|
|
let index = columns.findIndex((res) => res.key === item.key);
|
|
if (index !== -1) {
|
|
columns[index].fixed = isFixed;
|
|
}
|
|
table.setCacheColumnsField(item.key, { fixed: isFixed });
|
|
basicColumns.value[index].fixed = isFixed;
|
|
setColumns(columns);
|
|
emit('columnsChange', table.getColumns());
|
|
}
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.table-toolbar {
|
|
&-inner-popover-title {
|
|
border-bottom: 1px solid #eee;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
&-right {
|
|
&-icon {
|
|
margin-left: 12px;
|
|
font-size: 16px;
|
|
color: var(--text-color);
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
&-inner {
|
|
margin-top: 5px;
|
|
.ant-checkbox-group {
|
|
width: 100%;
|
|
}
|
|
&-checkbox {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 10px;
|
|
|
|
&:hover {
|
|
background: #e6f7ff;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.drag-icon {
|
|
display: inline-flex;
|
|
margin-right: 8px;
|
|
cursor: move;
|
|
}
|
|
|
|
.fixed-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
margin-left: auto;
|
|
}
|
|
|
|
.ant-checkbox-wrapper {
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
&-checkbox-dark {
|
|
&:hover {
|
|
background: hsla(0, 0%, 100%, 0.08);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|