vben
2020-11-28 54d14056462566521f2528480c13fb24279156ae
提交 | 用户 | 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>