Commit e4c198a74bff60c220669670f8cf7edbe480c9c6
1 parent
780254b8
feat: add AuthDropDown component usage more action drowdown menu
Showing
3 changed files
with
132 additions
and
44 deletions
1 | -<script lang="ts" setup></script> | |
1 | +<script lang="ts" setup> | |
2 | + import { Dropdown, Menu, Popconfirm } from 'ant-design-vue'; | |
3 | + import { computed, useSlots } from 'vue'; | |
4 | + import Icon from '../Icon'; | |
5 | + import { usePermission } from '/@/hooks/web/usePermission'; | |
2 | 6 | |
3 | -<template> <div></div></template> | |
7 | + export interface AuthDropDownProps { | |
8 | + dropMenuList: AuthDropMenuList[]; | |
9 | + trigger?: ('contextmenu' | 'click' | 'hover')[]; | |
10 | + } | |
11 | + | |
12 | + export interface AuthDropMenuList { | |
13 | + icon?: string; | |
14 | + event: string | number; | |
15 | + text: string; | |
16 | + disabled?: boolean; | |
17 | + divider?: boolean; | |
18 | + auth?: string; | |
19 | + onClick?: Fn; | |
20 | + popconfirm?: { | |
21 | + cancelText?: string; | |
22 | + okText?: string; | |
23 | + okType?: string; | |
24 | + title?: string; | |
25 | + icon?: string; | |
26 | + disabled?: boolean; | |
27 | + onCancel?: Fn; | |
28 | + onConfirm?: Fn; | |
29 | + onVisibleChange?: Fn; | |
30 | + }; | |
31 | + } | |
32 | + | |
33 | + const props = defineProps<AuthDropDownProps>(); | |
34 | + | |
35 | + const slot = useSlots(); | |
36 | + | |
37 | + const { hasPermission } = usePermission(); | |
38 | + | |
39 | + const getMenuList = computed(() => { | |
40 | + const { dropMenuList } = props; | |
41 | + return dropMenuList.filter((menu) => (menu.auth ? hasPermission(menu.auth) : true)); | |
42 | + }); | |
43 | + | |
44 | + const hasDefaultSlot = computed(() => { | |
45 | + return !!slot.default; | |
46 | + }); | |
47 | +</script> | |
48 | + | |
49 | +<template> | |
50 | + <Dropdown :trigger="$props.trigger"> | |
51 | + <template #overlay> | |
52 | + <Menu v-if="getMenuList.length"> | |
53 | + <template v-for="item in getMenuList" :key="item.event"> | |
54 | + <Menu.Divider v-if="item.divider" /> | |
55 | + <Menu.Item v-if="!item.popconfirm" @click="item.onClick"> | |
56 | + <span class="flex justify-center items-center"> | |
57 | + <Icon :icon="item.icon" /> | |
58 | + <span class="ml-2">{{ item.text }}</span> | |
59 | + </span> | |
60 | + </Menu.Item> | |
61 | + <Menu.Item v-if="item.popconfirm"> | |
62 | + <Popconfirm v-bind="item.popconfirm"> | |
63 | + <template v-if="item.popconfirm.icon" #icon> | |
64 | + <Icon :icon="item.popconfirm.icon" /> | |
65 | + </template> | |
66 | + <span class="flex justify-center items-center"> | |
67 | + <Icon :icon="item.icon" /> | |
68 | + <span class="ml-2">{{ item.text }}</span> | |
69 | + </span> | |
70 | + </Popconfirm> | |
71 | + </Menu.Item> | |
72 | + </template> | |
73 | + </Menu> | |
74 | + </template> | |
75 | + <Icon | |
76 | + v-if="!hasDefaultSlot" | |
77 | + class="items-center justify-center" | |
78 | + icon="ant-design:ellipsis-outlined" | |
79 | + :class="!getMenuList.length ? '!text-gray-200 !cursor-not-allowed' : ''" | |
80 | + /> | |
81 | + <slot name="default"></slot> | |
82 | + </Dropdown> | |
83 | +</template> | ... | ... |
1 | 1 | <script setup lang="ts"> |
2 | 2 | import { List, Card, Button, PaginationProps, Popover, Slider, Tooltip } from 'ant-design-vue'; |
3 | - import { ReloadOutlined, AppstoreOutlined, EllipsisOutlined } from '@ant-design/icons-vue'; | |
3 | + import { ReloadOutlined, AppstoreOutlined } from '@ant-design/icons-vue'; | |
4 | 4 | import { computed, onMounted, reactive, ref, unref } from 'vue'; |
5 | 5 | import { OrganizationIdTree, useResetOrganizationTree } from '../../common/organizationIdTree'; |
6 | 6 | import { |
... | ... | @@ -9,7 +9,6 @@ |
9 | 9 | } from '/@/api/configuration/center/configurationCenter'; |
10 | 10 | import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal'; |
11 | 11 | import { PageWrapper } from '/@/components/Page'; |
12 | - import { Dropdown } from '/@/components/Dropdown'; | |
13 | 12 | import { BasicForm, useForm } from '/@/components/Form'; |
14 | 13 | import { ConfigurationPermission, searchFormSchema } from './center.data'; |
15 | 14 | import { useMessage } from '/@/hooks/web/useMessage'; |
... | ... | @@ -17,13 +16,13 @@ |
17 | 16 | import { isDevMode } from '/@/utils/env'; |
18 | 17 | import ConfigurationCenterDrawer from './ConfigurationCenterDrawer.vue'; |
19 | 18 | import { useDrawer } from '/@/components/Drawer'; |
20 | - import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm'; | |
21 | 19 | import { getBoundingClientRect } from '/@/utils/domUtils'; |
22 | 20 | import configurationSrc from '/@/assets/icons/configuration.svg'; |
23 | 21 | import { cloneDeep } from 'lodash'; |
24 | 22 | import { usePermission } from '/@/hooks/web/usePermission'; |
25 | 23 | import { useGlobSetting } from '/@/hooks/setting'; |
26 | 24 | import { AuthIcon } from '/@/components/Widget'; |
25 | + import AuthDropDown from '/@/components/Widget/AuthDropDown.vue'; | |
27 | 26 | |
28 | 27 | const listColumn = ref(5); |
29 | 28 | |
... | ... | @@ -131,10 +130,8 @@ |
131 | 130 | window.open(`${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}`); |
132 | 131 | }; |
133 | 132 | |
134 | - const { createSyncConfirm } = useSyncConfirm(); | |
135 | 133 | const handleDelete = async (record: ConfigurationCenterItemsModal) => { |
136 | 134 | try { |
137 | - await createSyncConfirm({ iconType: 'warning', content: '是否确认删除操作?' }); | |
138 | 135 | await deleteConfigurationCenter([record.id]); |
139 | 136 | createMessage.success('删除成功'); |
140 | 137 | await getListData(); |
... | ... | @@ -237,7 +234,29 @@ |
237 | 234 | @click="handleDesign(item)" |
238 | 235 | /> |
239 | 236 | </Tooltip> |
240 | - <Dropdown | |
237 | + <AuthDropDown | |
238 | + :dropMenuList="[ | |
239 | + { | |
240 | + text: '编辑', | |
241 | + auth: ConfigurationPermission.UPDATE, | |
242 | + icon: 'clarity:note-edit-line', | |
243 | + event: '', | |
244 | + onClick: handleCreateOrUpdate.bind(null, item), | |
245 | + }, | |
246 | + { | |
247 | + text: '删除', | |
248 | + auth: ConfigurationPermission.DELETE, | |
249 | + icon: 'ant-design:delete-outlined', | |
250 | + event: '', | |
251 | + popconfirm: { | |
252 | + title: '是否确认删除操作?', | |
253 | + onConfirm: handleDelete.bind(null, item), | |
254 | + }, | |
255 | + }, | |
256 | + ]" | |
257 | + :trigger="['hover']" | |
258 | + /> | |
259 | + <!-- <Dropdown | |
241 | 260 | :dropMenuList="[ |
242 | 261 | { |
243 | 262 | text: '编辑', |
... | ... | @@ -258,7 +277,7 @@ |
258 | 277 | :trigger="['hover']" |
259 | 278 | > |
260 | 279 | <EllipsisOutlined key="ellipsis" /> |
261 | - </Dropdown> | |
280 | + </Dropdown> --> | |
262 | 281 | </template> |
263 | 282 | <Card.Meta> |
264 | 283 | <template #title> | ... | ... |
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | import { PageWrapper } from '/@/components/Page'; |
3 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | 4 | import { List, Button, Tooltip, Card, PaginationProps, Image } from 'ant-design-vue'; |
5 | - import { ReloadOutlined, MoreOutlined } from '@ant-design/icons-vue'; | |
5 | + import { ReloadOutlined } from '@ant-design/icons-vue'; | |
6 | 6 | import { computed, onMounted, reactive, ref, unref } from 'vue'; |
7 | 7 | import { |
8 | 8 | AuthIcon, |
... | ... | @@ -17,7 +17,6 @@ |
17 | 17 | setDeviceProfileIsDefaultApi, |
18 | 18 | } from '/@/api/device/deviceConfigApi'; |
19 | 19 | import { ProfileRecord } from '/@/api/device/model/deviceConfigModel'; |
20 | - import { Dropdown } from '/@/components/Dropdown'; | |
21 | 20 | import { |
22 | 21 | defaultObj, |
23 | 22 | searchFormSchema, |
... | ... | @@ -25,14 +24,13 @@ |
25 | 24 | ProductPermission, |
26 | 25 | } from './device.profile.data'; |
27 | 26 | import { useMessage } from '/@/hooks/web/useMessage'; |
28 | - import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm'; | |
29 | 27 | import DeviceProfileModal from './DeviceProfileModal.vue'; |
30 | 28 | import DeviceProfileDrawer from './DeviceProfileDrawer.vue'; |
31 | 29 | import { useModal } from '/@/components/Modal'; |
32 | 30 | import { useDrawer } from '/@/components/Drawer'; |
33 | 31 | import productDefault from '/@/assets/icons/product-default.svg'; |
34 | - import { usePermission } from '/@/hooks/web/usePermission'; | |
35 | 32 | import { useRoute } from 'vue-router'; |
33 | + import AuthDropDown from '/@/components/Widget/AuthDropDown.vue'; | |
36 | 34 | |
37 | 35 | defineProps<{ |
38 | 36 | mode: EnumTableCardMode; |
... | ... | @@ -47,7 +45,6 @@ |
47 | 45 | const IMAGE_FALLBACK = productDefault; |
48 | 46 | |
49 | 47 | const { createMessage } = useMessage(); |
50 | - const { createSyncConfirm } = useSyncConfirm(); | |
51 | 48 | |
52 | 49 | const [register, { getFieldsValue, setFieldsValue }] = useForm({ |
53 | 50 | showAdvancedButton: true, |
... | ... | @@ -110,32 +107,6 @@ |
110 | 107 | } |
111 | 108 | }; |
112 | 109 | |
113 | - const { hasPermission } = usePermission(); | |
114 | - | |
115 | - const getHasDeleteFlag = computed(() => { | |
116 | - return hasPermission(ProductPermission.DELETE); | |
117 | - }); | |
118 | - | |
119 | - const getDropDownList = (record: ProfileRecord) => { | |
120 | - const list = [ | |
121 | - { | |
122 | - text: '默认', | |
123 | - event: DropMenuEvent.SET_DEFAULT, | |
124 | - icon: 'ant-design:unordered-list-outlined', | |
125 | - onClick: handleSetDefault.bind(null, record), | |
126 | - }, | |
127 | - ]; | |
128 | - if (unref(getHasDeleteFlag)) { | |
129 | - list.push({ | |
130 | - text: '删除', | |
131 | - event: DropMenuEvent.DELETE, | |
132 | - icon: 'ant-design:delete-outlined', | |
133 | - onClick: handleDelete.bind(null, [record.id]), | |
134 | - }); | |
135 | - } | |
136 | - return list; | |
137 | - }; | |
138 | - | |
139 | 110 | const handleModeChange = (mode: EnumTableCardMode) => { |
140 | 111 | emit('changeMode', mode); |
141 | 112 | }; |
... | ... | @@ -172,7 +143,6 @@ |
172 | 143 | |
173 | 144 | const handleDelete = async (id: string[]) => { |
174 | 145 | try { |
175 | - await createSyncConfirm({ iconType: 'warning', content: '是否确认删除操作?' }); | |
176 | 146 | await deviceConfigDelete(id); |
177 | 147 | createMessage.success('删除成功'); |
178 | 148 | await getDataSource(); |
... | ... | @@ -278,9 +248,28 @@ |
278 | 248 | @click.stop="handleUpdate(item)" |
279 | 249 | /> |
280 | 250 | </Tooltip> |
281 | - <Dropdown :trigger="['hover']" :drop-menu-list="getDropDownList(item)"> | |
282 | - <MoreOutlined @click.stop class="transform rotate-90" /> | |
283 | - </Dropdown> | |
251 | + <AuthDropDown | |
252 | + @click.stop | |
253 | + :trigger="['hover']" | |
254 | + :drop-menu-list="[ | |
255 | + { | |
256 | + text: '默认', | |
257 | + event: DropMenuEvent.SET_DEFAULT, | |
258 | + icon: 'ant-design:unordered-list-outlined', | |
259 | + onClick: handleSetDefault.bind(null, item), | |
260 | + }, | |
261 | + { | |
262 | + text: '删除', | |
263 | + event: DropMenuEvent.DELETE, | |
264 | + auth: ProductPermission.DELETE, | |
265 | + icon: 'ant-design:delete-outlined', | |
266 | + popconfirm: { | |
267 | + title: '是否确认删除操作?', | |
268 | + onConfirm: handleDelete.bind(null, [item.id]), | |
269 | + }, | |
270 | + }, | |
271 | + ]" | |
272 | + /> | |
284 | 273 | </template> |
285 | 274 | <Card.Meta> |
286 | 275 | <template #title> | ... | ... |