提交 | 用户 | age
|
8b3a4d
|
1 |
<template> |
V |
2 |
<div class="table-settings"> |
|
3 |
<Divider type="vertical" /> |
|
4 |
|
|
5 |
<Tooltip placement="top" v-if="getSetting.redo"> |
|
6 |
<template #title> |
dc09de
|
7 |
<span>{{ t('settingRedo') }}</span> |
8b3a4d
|
8 |
</template> |
V |
9 |
<RedoOutlined @click="redo" /> |
|
10 |
</Tooltip> |
|
11 |
|
|
12 |
<Tooltip placement="top" v-if="getSetting.size"> |
|
13 |
<template #title> |
dc09de
|
14 |
<span>{{ t('settingDens') }}</span> |
8b3a4d
|
15 |
</template> |
V |
16 |
<Dropdown placement="bottomCenter" :trigger="['click']"> |
|
17 |
<ColumnHeightOutlined /> |
|
18 |
<template #overlay> |
|
19 |
<Menu @click="handleTitleClick" selectable v-model:selectedKeys="selectedKeysRef"> |
|
20 |
<MenuItem key="default"> |
dc09de
|
21 |
<span>{{ t('settingDensDefault') }}</span> |
8b3a4d
|
22 |
</MenuItem> |
V |
23 |
<MenuItem key="middle"> |
dc09de
|
24 |
<span>{{ t('settingDensMiddle') }}</span> |
8b3a4d
|
25 |
</MenuItem> |
V |
26 |
<MenuItem key="small"> |
dc09de
|
27 |
<span>{{ t('settingDensSmall') }}</span> |
8b3a4d
|
28 |
</MenuItem> |
V |
29 |
</Menu> |
|
30 |
</template> |
|
31 |
</Dropdown> |
|
32 |
</Tooltip> |
|
33 |
|
|
34 |
<Tooltip placement="top" v-if="getSetting.setting"> |
|
35 |
<template #title> |
dc09de
|
36 |
<span>{{ t('settingColumn') }}</span> |
8b3a4d
|
37 |
</template> |
V |
38 |
<Popover |
|
39 |
placement="bottomLeft" |
|
40 |
trigger="click" |
|
41 |
overlayClassName="table-settings__cloumn-list" |
|
42 |
> |
|
43 |
<template #content> |
|
44 |
<CheckboxGroup v-model:value="checkedList" @change="onChange"> |
|
45 |
<template v-for="item in plainOptions" :key="item.value"> |
|
46 |
<div class="table-settings__check-item"> |
|
47 |
<Checkbox :value="item.value"> |
|
48 |
{{ item.label }} |
|
49 |
</Checkbox> |
|
50 |
</div> |
|
51 |
</template> |
|
52 |
</CheckboxGroup> |
|
53 |
</template> |
|
54 |
<template #title> |
|
55 |
<div class="table-settings__popover-title"> |
|
56 |
<Checkbox |
|
57 |
:indeterminate="indeterminate" |
|
58 |
v-model:checked="checkAll" |
|
59 |
@change="onCheckAllChange" |
|
60 |
> |
dc09de
|
61 |
{{ t('settingColumnShow') }} |
8b3a4d
|
62 |
</Checkbox> |
dc09de
|
63 |
<a-button size="small" type="link" @click="reset"> {{ t('settingReset') }}</a-button> |
8b3a4d
|
64 |
</div> |
V |
65 |
</template> |
|
66 |
<SettingOutlined /> |
|
67 |
</Popover> |
|
68 |
</Tooltip> |
|
69 |
|
|
70 |
<Tooltip placement="top" v-if="getSetting.fullScreen"> |
|
71 |
<template #title> |
dc09de
|
72 |
<span>{{ t('settingFullScreen') }}</span> |
8b3a4d
|
73 |
</template> |
V |
74 |
<FullscreenOutlined @click="handleFullScreen" v-if="!isFullscreenRef" /> |
|
75 |
<FullscreenExitOutlined @click="handleFullScreen" v-else /> |
|
76 |
</Tooltip> |
|
77 |
</div> |
|
78 |
</template> |
|
79 |
<script lang="ts"> |
54d140
|
80 |
import { defineComponent, ref, reactive, toRefs, PropType, computed, watchEffect } from 'vue'; |
8b3a4d
|
81 |
import { injectTable } from '../hooks/useProvinceTable'; |
V |
82 |
import { Tooltip, Divider, Dropdown, Menu, Popover, Checkbox } from 'ant-design-vue'; |
|
83 |
import { |
|
84 |
RedoOutlined, |
|
85 |
ColumnHeightOutlined, |
|
86 |
FullscreenOutlined, |
|
87 |
FullscreenExitOutlined, |
|
88 |
SettingOutlined, |
|
89 |
} from '@ant-design/icons-vue'; |
|
90 |
import { useFullscreen } from '/@/hooks/web/useFullScreen'; |
|
91 |
|
|
92 |
import type { SizeType, TableSetting } from '../types/table'; |
dc09de
|
93 |
import { useI18n } from '/@/hooks/web/useI18n'; |
8b3a4d
|
94 |
|
V |
95 |
interface Options { |
|
96 |
label: string; |
|
97 |
value: string; |
|
98 |
} |
|
99 |
interface State { |
|
100 |
indeterminate: boolean; |
|
101 |
checkAll: boolean; |
|
102 |
// defaultColumns: BasicColumn[]; |
|
103 |
// columns: BasicColumn[]; |
|
104 |
checkedList: string[]; |
|
105 |
defaultCheckList: string[]; |
|
106 |
} |
|
107 |
export default defineComponent({ |
|
108 |
name: 'TableSetting', |
|
109 |
components: { |
|
110 |
RedoOutlined, |
|
111 |
ColumnHeightOutlined, |
|
112 |
FullscreenExitOutlined, |
|
113 |
FullscreenOutlined, |
|
114 |
SettingOutlined, |
|
115 |
Popover, |
|
116 |
Tooltip, |
|
117 |
Divider, |
|
118 |
Dropdown, |
|
119 |
Checkbox, |
|
120 |
CheckboxGroup: Checkbox.Group, |
|
121 |
Menu, |
|
122 |
MenuItem: Menu.Item, |
|
123 |
}, |
|
124 |
props: { |
|
125 |
setting: { |
|
126 |
type: Object as PropType<TableSetting>, |
|
127 |
default: {}, |
|
128 |
}, |
|
129 |
}, |
|
130 |
setup(props) { |
|
131 |
const table = injectTable(); |
|
132 |
const { toggleFullscreen, isFullscreenRef } = useFullscreen(table.wrapRef); |
|
133 |
const selectedKeysRef = ref<SizeType[]>([table.getSize()]); |
|
134 |
|
54d140
|
135 |
const plainOptions = ref<Options[]>([]); |
8b3a4d
|
136 |
const state = reactive<State>({ |
V |
137 |
indeterminate: false, |
|
138 |
checkAll: true, |
|
139 |
checkedList: [], |
|
140 |
defaultCheckList: [], |
|
141 |
}); |
dc09de
|
142 |
|
V |
143 |
const { t } = useI18n('component.table'); |
8b3a4d
|
144 |
|
54d140
|
145 |
watchEffect(() => { |
V |
146 |
const columns = table.getColumns(); |
|
147 |
if (columns.length) { |
|
148 |
init(); |
|
149 |
} |
|
150 |
}); |
8b3a4d
|
151 |
function init() { |
V |
152 |
let ret: Options[] = []; |
|
153 |
table.getColumns({ ignoreIndex: true, ignoreAction: true }).forEach((item) => { |
|
154 |
ret.push({ |
|
155 |
label: item.title as string, |
|
156 |
value: (item.dataIndex || item.title) as string, |
|
157 |
}); |
|
158 |
}); |
54d140
|
159 |
|
V |
160 |
plainOptions.value = ret; |
8b3a4d
|
161 |
const checkList = table |
V |
162 |
.getColumns() |
|
163 |
.map((item) => item.dataIndex || item.title) as string[]; |
|
164 |
state.checkedList = checkList; |
|
165 |
state.defaultCheckList = checkList; |
|
166 |
} |
|
167 |
|
|
168 |
function handleTitleClick({ key }: { key: SizeType }) { |
|
169 |
selectedKeysRef.value = [key]; |
|
170 |
table.setProps({ |
|
171 |
size: key, |
|
172 |
}); |
|
173 |
} |
|
174 |
|
|
175 |
function handleFullScreen() { |
|
176 |
toggleFullscreen(); |
|
177 |
} |
|
178 |
|
|
179 |
function onCheckAllChange(e: ChangeEvent) { |
|
180 |
state.indeterminate = false; |
54d140
|
181 |
const checkList = plainOptions.value.map((item) => item.value); |
8b3a4d
|
182 |
if (e.target.checked) { |
V |
183 |
state.checkedList = checkList; |
|
184 |
table.setColumns(checkList); |
|
185 |
} else { |
|
186 |
state.checkedList = []; |
|
187 |
table.setColumns([]); |
|
188 |
} |
|
189 |
} |
|
190 |
|
|
191 |
function onChange(checkedList: string[]) { |
54d140
|
192 |
const len = plainOptions.value.length; |
V |
193 |
state.indeterminate = !!checkedList.length && checkedList.length < len; |
|
194 |
state.checkAll = checkedList.length === len; |
8b3a4d
|
195 |
table.setColumns(checkedList); |
V |
196 |
} |
|
197 |
|
|
198 |
function reset() { |
|
199 |
if (state.checkAll) return; |
|
200 |
state.checkedList = [...state.defaultCheckList]; |
|
201 |
state.checkAll = true; |
|
202 |
state.indeterminate = false; |
|
203 |
table.setColumns(state.defaultCheckList); |
|
204 |
} |
|
205 |
|
|
206 |
const getSetting = computed( |
|
207 |
(): TableSetting => { |
|
208 |
return { |
|
209 |
redo: true, |
|
210 |
size: true, |
|
211 |
setting: true, |
|
212 |
fullScreen: true, |
|
213 |
...props.setting, |
|
214 |
}; |
|
215 |
} |
|
216 |
); |
|
217 |
|
|
218 |
return { |
|
219 |
redo: () => table.reload(), |
|
220 |
handleTitleClick, |
|
221 |
selectedKeysRef, |
|
222 |
handleFullScreen, |
|
223 |
isFullscreenRef, |
|
224 |
onCheckAllChange, |
|
225 |
onChange, |
|
226 |
plainOptions, |
|
227 |
reset, |
|
228 |
getSetting, |
|
229 |
...toRefs(state), |
dc09de
|
230 |
t, |
8b3a4d
|
231 |
}; |
V |
232 |
}, |
|
233 |
}); |
|
234 |
</script> |
|
235 |
<style lang="less"> |
|
236 |
@import (reference) '../../../../design/index.less'; |
|
237 |
|
|
238 |
.table-settings { |
|
239 |
& > * { |
|
240 |
margin-right: 12px; |
|
241 |
} |
|
242 |
|
|
243 |
svg { |
|
244 |
width: 1.2em; |
|
245 |
height: 1.2em; |
|
246 |
} |
|
247 |
|
|
248 |
&__popover-title { |
|
249 |
display: flex; |
|
250 |
align-items: center; |
|
251 |
justify-content: space-between; |
|
252 |
} |
|
253 |
|
|
254 |
&__check-item { |
|
255 |
width: 100%; |
|
256 |
padding: 4px 16px 4px 16px; |
|
257 |
|
|
258 |
.ant-checkbox-wrapper { |
|
259 |
width: 100%; |
|
260 |
} |
|
261 |
|
|
262 |
&:hover { |
|
263 |
background: fade(@primary-color, 10%); |
|
264 |
} |
|
265 |
} |
|
266 |
|
|
267 |
&__cloumn-list { |
|
268 |
.ant-popover-inner-content { |
|
269 |
max-height: 360px; |
|
270 |
padding-right: 0; |
|
271 |
padding-left: 0; |
|
272 |
overflow: auto; |
|
273 |
} |
|
274 |
|
|
275 |
.ant-checkbox-group { |
|
276 |
width: 100%; |
|
277 |
} |
|
278 |
} |
|
279 |
} |
|
280 |
</style> |