enhance(client): improve widgets component
This commit is contained in:
		| @@ -4,7 +4,7 @@ | |||||||
| 		<header> | 		<header> | ||||||
| 			<MkSelect v-model="widgetAdderSelected" style="margin-bottom: var(--margin)" class="mk-widget-select"> | 			<MkSelect v-model="widgetAdderSelected" style="margin-bottom: var(--margin)" class="mk-widget-select"> | ||||||
| 				<template #label>{{ $ts.selectWidget }}</template> | 				<template #label>{{ $ts.selectWidget }}</template> | ||||||
| 				<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ $t(`_widgets.${widget}`) }}</option> | 				<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ i18n.t(`_widgets.${widget}`) }}</option> | ||||||
| 			</MkSelect> | 			</MkSelect> | ||||||
| 			<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton> | 			<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton> | ||||||
| 			<MkButton inline @click="$emit('exit')">{{ $ts.close }}</MkButton> | 			<MkButton inline @click="$emit('exit')">{{ $ts.close }}</MkButton> | ||||||
| @@ -26,39 +26,41 @@ | |||||||
| 			</template> | 			</template> | ||||||
| 		</XDraggable> | 		</XDraggable> | ||||||
| 	</template> | 	</template> | ||||||
| 	<component :is="`mkw-${widget.name}`" v-for="widget in widgets" v-else :key="widget.id" class="widget" :widget="widget" @updateProps="updateWidget(widget.id, $event)"/> | 	<component :is="`mkw-${widget.name}`" v-for="widget in widgets" v-else :key="widget.id" :ref="el => widgetRefs[widget.id] = el" class="widget" :widget="widget" @updateProps="updateWidget(widget.id, $event)" @contextmenu.stop="onContextmenu(widget, $event)"/> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script lang="ts"> | <script lang="ts" setup> | ||||||
| import { defineComponent, defineAsyncComponent, reactive, ref, computed } from 'vue'; | import { defineAsyncComponent, reactive, ref, computed } from 'vue'; | ||||||
| import { v4 as uuid } from 'uuid'; | import { v4 as uuid } from 'uuid'; | ||||||
| import MkSelect from '@/components/form/select.vue'; | import MkSelect from '@/components/form/select.vue'; | ||||||
| import MkButton from '@/components/ui/button.vue'; | import MkButton from '@/components/ui/button.vue'; | ||||||
| import { widgets as widgetDefs } from '@/widgets'; | import { widgets as widgetDefs } from '@/widgets'; | ||||||
|  | import * as os from '@/os'; | ||||||
|  | import { i18n } from '@/i18n'; | ||||||
|  |  | ||||||
| export default defineComponent({ | const XDraggable = defineAsyncComponent(() => import('vuedraggable')); | ||||||
| 	components: { |  | ||||||
| 		XDraggable: defineAsyncComponent(() => import('vuedraggable')), |  | ||||||
| 		MkSelect, |  | ||||||
| 		MkButton, |  | ||||||
| 	}, |  | ||||||
|  |  | ||||||
| 	props: { | type Widget = { | ||||||
| 		widgets: { | 	name: string; | ||||||
| 			type: Array, | 	id: string; | ||||||
| 			required: true, | 	data: Record<string, any>; | ||||||
| 		}, | }; | ||||||
| 		edit: { |  | ||||||
| 			type: Boolean, |  | ||||||
| 			required: true, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
|  |  | ||||||
| 	emits: ['updateWidgets', 'addWidget', 'removeWidget', 'updateWidget', 'exit'], | const props = defineProps<{ | ||||||
|  | 	widgets: Widget[]; | ||||||
|  | 	edit: boolean; | ||||||
|  | }>(); | ||||||
|  |  | ||||||
| 	setup(props, context) { | const emit = defineEmits<{ | ||||||
| 		const widgetRefs = reactive({}); | 	(ev: 'updateWidgets', widgets: Widget[]): void; | ||||||
|  | 	(ev: 'addWidget', widget: Widget): void; | ||||||
|  | 	(ev: 'removeWidget', widget: Widget): void; | ||||||
|  | 	(ev: 'updateWidget', widget: Partial<Widget>): void; | ||||||
|  | 	(ev: 'exit'): void; | ||||||
|  | }>(); | ||||||
|  |  | ||||||
|  | const widgetRefs = {}; | ||||||
| const configWidget = (id: string) => { | const configWidget = (id: string) => { | ||||||
| 	widgetRefs[id].configure(); | 	widgetRefs[id].configure(); | ||||||
| }; | }; | ||||||
| @@ -66,7 +68,7 @@ export default defineComponent({ | |||||||
| const addWidget = () => { | const addWidget = () => { | ||||||
| 	if (widgetAdderSelected.value == null) return; | 	if (widgetAdderSelected.value == null) return; | ||||||
|  |  | ||||||
| 			context.emit('addWidget', { | 	emit('addWidget', { | ||||||
| 		name: widgetAdderSelected.value, | 		name: widgetAdderSelected.value, | ||||||
| 		id: uuid(), | 		id: uuid(), | ||||||
| 		data: {}, | 		data: {}, | ||||||
| @@ -75,30 +77,40 @@ export default defineComponent({ | |||||||
| 	widgetAdderSelected.value = null; | 	widgetAdderSelected.value = null; | ||||||
| }; | }; | ||||||
| const removeWidget = (widget) => { | const removeWidget = (widget) => { | ||||||
| 			context.emit('removeWidget', widget); | 	emit('removeWidget', widget); | ||||||
| }; | }; | ||||||
| const updateWidget = (id, data) => { | const updateWidget = (id, data) => { | ||||||
| 			context.emit('updateWidget', { id, data }); | 	emit('updateWidget', { id, data }); | ||||||
| }; | }; | ||||||
| const widgets_ = computed({ | const widgets_ = computed({ | ||||||
| 	get: () => props.widgets, | 	get: () => props.widgets, | ||||||
| 	set: (value) => { | 	set: (value) => { | ||||||
| 				context.emit('updateWidgets', value); | 		emit('updateWidgets', value); | ||||||
| 	}, | 	}, | ||||||
| }); | }); | ||||||
|  |  | ||||||
| 		return { | function onContextmenu(widget: Widget, ev: MouseEvent) { | ||||||
| 			widgetRefs, | 	const isLink = (el: HTMLElement) => { | ||||||
| 			configWidget, | 		if (el.tagName === 'A') return true; | ||||||
| 			widgetAdderSelected, | 		if (el.parentElement) { | ||||||
| 			widgetDefs, | 			return isLink(el.parentElement); | ||||||
| 			addWidget, | 		} | ||||||
| 			removeWidget, |  | ||||||
| 			updateWidget, |  | ||||||
| 			widgets_, |  | ||||||
| 	}; | 	}; | ||||||
|  | 	if (isLink(ev.target)) return; | ||||||
|  | 	if (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(ev.target.tagName) || ev.target.attributes['contenteditable']) return; | ||||||
|  | 	if (window.getSelection()?.toString() !== '') return; | ||||||
|  |  | ||||||
|  | 	os.contextMenu([{ | ||||||
|  | 		type: 'label', | ||||||
|  | 		text: i18n.t(`_widgets.${widget.name}`), | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-cog', | ||||||
|  | 		text: i18n.ts.settings, | ||||||
|  | 		action: () => { | ||||||
|  | 			configWidget(widget.id); | ||||||
| 		}, | 		}, | ||||||
| }); | 	}], ev); | ||||||
|  | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo