use sortablejs-vue3 instead of vuedraggable for more stability
This commit is contained in:
		
							parent
							
								
									fe158339da
								
							
						
					
					
						commit
						60b3d73cc9
					
				
					 8 changed files with 176 additions and 179 deletions
				
			
		|  | @ -46,6 +46,8 @@ | |||
| 		"s-age": "1.1.2", | ||||
| 		"sass": "1.57.0", | ||||
| 		"seedrandom": "3.0.5", | ||||
| 		"sortablejs": "^1.15.0", | ||||
| 		"sortablejs-vue3": "^1.2.3", | ||||
| 		"strict-event-emitter-types": "2.0.0", | ||||
| 		"stringz": "2.1.0", | ||||
| 		"syuilo-password-strength": "0.0.1", | ||||
|  | @ -61,8 +63,7 @@ | |||
| 		"vanilla-tilt": "1.8.0", | ||||
| 		"vite": "4.0.2", | ||||
| 		"vue": "3.2.45", | ||||
| 		"vue-prism-editor": "2.0.0-alpha.2", | ||||
| 		"vuedraggable": "4.0.1" | ||||
| 		"vue-prism-editor": "2.0.0-alpha.2" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@types/escape-regexp": "0.0.1", | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ | |||
| 		<input v-show="useCw" ref="cwInputEl" v-model="cw" class="cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown"> | ||||
| 		<textarea ref="textareaEl" v-model="text" class="text" :class="{ withCw: useCw }" :disabled="posting" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/> | ||||
| 		<input v-show="withHashtags" ref="hashtagsInputEl" v-model="hashtags" class="hashtags" :placeholder="i18n.ts.hashtags" list="hashtags"> | ||||
| 		<XPostFormAttaches class="attaches" :files="files" @updated="updateFiles" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/> | ||||
| 		<XPostFormAttaches v-model="files" class="attaches" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/> | ||||
| 		<XPollEditor v-if="poll" v-model="poll" @destroyed="poll = null"/> | ||||
| 		<XNotePreview v-if="showPreview" class="preview" :text="text"/> | ||||
| 		<footer> | ||||
|  | @ -370,10 +370,6 @@ function detachFile(id) { | |||
| 	files = files.filter(x => x.id !== id); | ||||
| } | ||||
| 
 | ||||
| function updateFiles(_files) { | ||||
| 	files = _files; | ||||
| } | ||||
| 
 | ||||
| function updateFileSensitive(file, sensitive) { | ||||
| 	files[files.findIndex(x => x.id === file.id)].isSensitive = sensitive; | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <div v-show="files.length != 0" class="skeikyzd"> | ||||
| 	<XDraggable v-model="_files" class="files" item-key="id" animation="150" delay="100" delay-on-touch-only="true"> | ||||
| <div v-show="props.modelValue.length != 0" class="skeikyzd"> | ||||
| 	<Sortable :list="props.modelValue" class="files" item-key="id" :options="{ animation: 150, delay: 100, delayOnTouchOnly: true }" @end="onSorted"> | ||||
| 		<template #item="{element}"> | ||||
| 			<div class="file" @click="showFileMenu(element, $event)" @contextmenu.prevent="showFileMenu(element, $event)"> | ||||
| 				<MkDriveFileThumbnail :data-id="element.id" class="thumbnail" :file="element" fit="cover"/> | ||||
|  | @ -9,71 +9,60 @@ | |||
| 				</div> | ||||
| 			</div> | ||||
| 		</template> | ||||
| 	</XDraggable> | ||||
| 	<p class="remain">{{ 16 - files.length }}/16</p> | ||||
| 	</Sortable> | ||||
| 	<p class="remain">{{ 16 - props.modelValue.length }}/16</p> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent, defineAsyncComponent } from 'vue'; | ||||
| <script lang="ts" setup> | ||||
| import { defineAsyncComponent } from 'vue'; | ||||
| import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { deepClone } from '@/scripts/clone'; | ||||
| import { i18n } from '@/i18n'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XDraggable: defineAsyncComponent(() => import('vuedraggable').then(x => x.default)), | ||||
| 		MkDriveFileThumbnail, | ||||
| 	}, | ||||
| const Sortable = defineAsyncComponent(() => import('sortablejs-vue3').then(x => x.Sortable)); | ||||
| 
 | ||||
| 	props: { | ||||
| 		files: { | ||||
| 			type: Array, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		detachMediaFn: { | ||||
| 			type: Function, | ||||
| 			required: false, | ||||
| 		}, | ||||
| 	}, | ||||
| const props = defineProps<{ | ||||
| 	modelValue: any[]; | ||||
| 	detachMediaFn: () => void; | ||||
| }>(); | ||||
| 
 | ||||
| 	emits: ['updated', 'detach', 'changeSensitive', 'changeName'], | ||||
| const emit = defineEmits<{ | ||||
| 	(ev: 'update:modelValue', value: any[]): void; | ||||
| 	(ev: 'detach'): void; | ||||
| 	(ev: 'changeSensitive'): void; | ||||
| 	(ev: 'changeName'): void; | ||||
| }>(); | ||||
| 
 | ||||
| 	data() { | ||||
| 		return { | ||||
| 			menu: null as Promise<null> | null, | ||||
| 		}; | ||||
| 	}, | ||||
| let menuShowing = false; | ||||
| 
 | ||||
| 	computed: { | ||||
| 		_files: { | ||||
| 			get() { | ||||
| 				return this.files; | ||||
| 			}, | ||||
| 			set(value) { | ||||
| 				this.$emit('updated', value); | ||||
| 			}, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		detachMedia(id) { | ||||
| 			if (this.detachMediaFn) { | ||||
| 				this.detachMediaFn(id); | ||||
| 			} else { | ||||
| 				this.$emit('detach', id); | ||||
| function onSorted(event) { | ||||
| 	const items = deepClone(props.modelValue); | ||||
| 	const item = items.splice(event.oldIndex, 1)[0]; | ||||
| 	items.splice(event.newIndex, 0, item); | ||||
| 	emit('update:modelValue', items); | ||||
| } | ||||
| 		}, | ||||
| 		toggleSensitive(file) { | ||||
| 
 | ||||
| function detachMedia(id) { | ||||
| 	if (props.detachMediaFn) { | ||||
| 		props.detachMediaFn(id); | ||||
| 	} else { | ||||
| 		emit('detach', id); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function toggleSensitive(file) { | ||||
| 	os.api('drive/files/update', { | ||||
| 		fileId: file.id, | ||||
| 		isSensitive: !file.isSensitive, | ||||
| 	}).then(() => { | ||||
| 				this.$emit('changeSensitive', file, !file.isSensitive); | ||||
| 		emit('changeSensitive', file, !file.isSensitive); | ||||
| 	}); | ||||
| 		}, | ||||
| 		async rename(file) { | ||||
| } | ||||
| async function rename(file) { | ||||
| 	const { canceled, result } = await os.inputText({ | ||||
| 				title: this.$ts.enterFileName, | ||||
| 		title: i18n.ts.enterFileName, | ||||
| 		default: file.name, | ||||
| 		allowEmpty: false, | ||||
| 	}); | ||||
|  | @ -82,16 +71,16 @@ export default defineComponent({ | |||
| 		fileId: file.id, | ||||
| 		name: result, | ||||
| 	}).then(() => { | ||||
| 				this.$emit('changeName', file, result); | ||||
| 		emit('changeName', file, result); | ||||
| 		file.name = result; | ||||
| 	}); | ||||
| 		}, | ||||
| } | ||||
| 
 | ||||
| 		async describe(file) { | ||||
| async function describe(file) { | ||||
| 	os.popup(defineAsyncComponent(() => import('@/components/MkMediaCaption.vue')), { | ||||
| 				title: this.$ts.describeFile, | ||||
| 		title: i18n.ts.describeFile, | ||||
| 		input: { | ||||
| 					placeholder: this.$ts.inputNewDescription, | ||||
| 			placeholder: i18n.ts.inputNewDescription, | ||||
| 			default: file.comment !== null ? file.comment : '', | ||||
| 		}, | ||||
| 		image: file, | ||||
|  | @ -107,30 +96,29 @@ export default defineComponent({ | |||
| 			}); | ||||
| 		}, | ||||
| 	}, 'closed'); | ||||
| 		}, | ||||
| } | ||||
| 
 | ||||
| 		showFileMenu(file, ev: MouseEvent) { | ||||
| 			if (this.menu) return; | ||||
| 			this.menu = os.popupMenu([{ | ||||
| 				text: this.$ts.renameFile, | ||||
| function showFileMenu(file, ev: MouseEvent) { | ||||
| 	if (menuShowing) return; | ||||
| 	os.popupMenu([{ | ||||
| 		text: i18n.ts.renameFile, | ||||
| 		icon: 'ti ti-forms', | ||||
| 				action: () => { this.rename(file); }, | ||||
| 		action: () => { rename(file); }, | ||||
| 	}, { | ||||
| 				text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, | ||||
| 		text: file.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive, | ||||
| 		icon: file.isSensitive ? 'ti ti-eye-off' : 'ti ti-eye', | ||||
| 				action: () => { this.toggleSensitive(file); }, | ||||
| 		action: () => { toggleSensitive(file); }, | ||||
| 	}, { | ||||
| 				text: this.$ts.describeFile, | ||||
| 		text: i18n.ts.describeFile, | ||||
| 		icon: 'ti ti-forms', | ||||
| 				action: () => { this.describe(file); }, | ||||
| 		action: () => { describe(file); }, | ||||
| 	}, { | ||||
| 				text: this.$ts.attachCancel, | ||||
| 		text: i18n.ts.attachCancel, | ||||
| 		icon: 'ti ti-circle-x', | ||||
| 				action: () => { this.detachMedia(file.id); }, | ||||
| 			}], ev.currentTarget ?? ev.target).then(() => this.menu = null); | ||||
| 		}, | ||||
| 	}, | ||||
| }); | ||||
| 		action: () => { detachMedia(file.id); }, | ||||
| 	}], ev.currentTarget ?? ev.target).then(() => menuShowing = false); | ||||
| 	menuShowing = true; | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
|  |  | |||
|  | @ -9,11 +9,11 @@ | |||
| 			<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton> | ||||
| 			<MkButton inline @click="$emit('exit')">{{ i18n.ts.close }}</MkButton> | ||||
| 		</header> | ||||
| 		<XDraggable | ||||
| 			v-model="widgets_" | ||||
| 		<Sortable | ||||
| 			:list="props.widgets" | ||||
| 			item-key="id" | ||||
| 			handle=".handle" | ||||
| 			animation="150" | ||||
| 			:options="{ handle: '.handle', animation: 150 }" | ||||
| 			@end="onSorted" | ||||
| 		> | ||||
| 			<template #item="{element}"> | ||||
| 				<div class="customize-container"> | ||||
|  | @ -24,7 +24,7 @@ | |||
| 					</div> | ||||
| 				</div> | ||||
| 			</template> | ||||
| 		</XDraggable> | ||||
| 		</Sortable> | ||||
| 	</template> | ||||
| 	<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> | ||||
|  | @ -38,8 +38,9 @@ import MkButton from '@/components/MkButton.vue'; | |||
| import { widgets as widgetDefs } from '@/widgets'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { deepClone } from '@/scripts/clone'; | ||||
| 
 | ||||
| const XDraggable = defineAsyncComponent(() => import('vuedraggable')); | ||||
| const Sortable = defineAsyncComponent(() => import('sortablejs-vue3').then(x => x.Sortable)); | ||||
| 
 | ||||
| type Widget = { | ||||
| 	name: string; | ||||
|  | @ -82,12 +83,13 @@ const removeWidget = (widget) => { | |||
| const updateWidget = (id, data) => { | ||||
| 	emit('updateWidget', { id, data }); | ||||
| }; | ||||
| const widgets_ = computed({ | ||||
| 	get: () => props.widgets, | ||||
| 	set: (value) => { | ||||
| 		emit('updateWidgets', value); | ||||
| 	}, | ||||
| }); | ||||
| 
 | ||||
| function onSorted(event) { | ||||
| 	const items = deepClone(props.widgets); | ||||
| 	const item = items.splice(event.oldIndex, 1)[0]; | ||||
| 	items.splice(event.newIndex, 0, item); | ||||
| 	emit('updateWidgets', items); | ||||
| } | ||||
| 
 | ||||
| function onContextmenu(widget: Widget, ev: MouseEvent) { | ||||
| 	const isLink = (el: HTMLElement) => { | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| <template> | ||||
| <XDraggable v-model="blocks" tag="div" item-key="id" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150" swap-threshold="0.5"> | ||||
| <Sortable :list="blocks" tag="div" item-key="id" :options="{ handle: '.drag-handle', group: { name: 'blocks' }, animation: 150, swapThreshold: 0.5 }"> | ||||
| 	<template #item="{element}"> | ||||
| 		<component :is="'x-' + element.type" :value="element" :hpml="hpml" @update:value="updateItem" @remove="() => removeItem(element)"/> | ||||
| 	</template> | ||||
| </XDraggable> | ||||
| </Sortable> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
|  | @ -27,14 +27,14 @@ import * as os from '@/os'; | |||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XDraggable: defineAsyncComponent(() => import('vuedraggable').then(x => x.default)), | ||||
| 		XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter, XRadioButton, XCanvas, XNote | ||||
| 		Sortable: defineAsyncComponent(() => import('sortablejs-vue3').then(x => x.Sortable)), | ||||
| 		XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter, XRadioButton, XCanvas, XNote, | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		modelValue: { | ||||
| 			type: Array, | ||||
| 			required: true | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		hpml: { | ||||
| 			required: true, | ||||
|  | @ -50,8 +50,8 @@ export default defineComponent({ | |||
| 			}, | ||||
| 			set(value) { | ||||
| 				this.$emit('update:modelValue', value); | ||||
| 			} | ||||
| 		} | ||||
| 			}, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
|  | @ -60,7 +60,7 @@ export default defineComponent({ | |||
| 			const newValue = [ | ||||
| 				...this.blocks.slice(0, i), | ||||
| 				v, | ||||
| 				...this.blocks.slice(i + 1) | ||||
| 				...this.blocks.slice(i + 1), | ||||
| 			]; | ||||
| 			this.$emit('update:modelValue', newValue); | ||||
| 		}, | ||||
|  | @ -69,10 +69,10 @@ export default defineComponent({ | |||
| 			const i = this.blocks.findIndex(x => x.id === el.id); | ||||
| 			const newValue = [ | ||||
| 				...this.blocks.slice(0, i), | ||||
| 				...this.blocks.slice(i + 1) | ||||
| 				...this.blocks.slice(i + 1), | ||||
| 			]; | ||||
| 			this.$emit('update:modelValue', newValue); | ||||
| 		}, | ||||
| 	} | ||||
| 	}, | ||||
| }); | ||||
| </script> | ||||
|  |  | |||
|  | @ -54,7 +54,7 @@ | |||
| 
 | ||||
| 		<div v-else-if="tab === 'variables'"> | ||||
| 			<div class="qmuvgica"> | ||||
| 				<XDraggable v-show="variables.length > 0" v-model="variables" tag="div" class="variables" item-key="name" handle=".drag-handle" :group="{ name: 'variables' }" animation="150" swap-threshold="0.5"> | ||||
| 				<Sortable v-show="variables.length > 0" v-model="variables" tag="div" class="variables" item-key="name" handle=".drag-handle" :group="{ name: 'variables' }" animation="150" swap-threshold="0.5"> | ||||
| 					<template #item="{element}"> | ||||
| 						<XVariable | ||||
| 							:model-value="element" | ||||
|  | @ -66,7 +66,7 @@ | |||
| 							@remove="() => removeVariable(element)" | ||||
| 						/> | ||||
| 					</template> | ||||
| 				</XDraggable> | ||||
| 				</Sortable> | ||||
| 
 | ||||
| 				<MkButton v-if="!readonly" class="add" @click="addVariable()"><i class="ti ti-plus"></i></MkButton> | ||||
| 			</div> | ||||
|  | @ -107,7 +107,7 @@ import { mainRouter } from '@/router'; | |||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| import { $i } from '@/account'; | ||||
| const XDraggable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default)); | ||||
| const Sortable = defineAsyncComponent(() => import('sortablejs-vue3').then(x => x.default)); | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	initPageId?: string; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 	<FromSlot class="_formBlock"> | ||||
| 		<template #label>{{ i18n.ts.reactionSettingDescription }}</template> | ||||
| 		<div v-panel style="border-radius: 6px;"> | ||||
| 			<XDraggable v-model="reactions" class="zoaiodol" :item-key="item => item" animation="150" delay="100" delay-on-touch-only="true"> | ||||
| 			<Sortable :list="reactions" class="zoaiodol" :item-key="item => item" :options="{ animation: 150, delay: 100, delayOnTouchOnly: true }" @end="onSorted"> | ||||
| 				<template #item="{element}"> | ||||
| 					<button class="_button item" @click="remove(element, $event)"> | ||||
| 						<MkEmoji :emoji="element" :normal="true"/> | ||||
|  | @ -12,7 +12,9 @@ | |||
| 				<template #footer> | ||||
| 					<button class="_button add" @click="chooseEmoji"><i class="ti ti-plus"></i></button> | ||||
| 				</template> | ||||
| 			</XDraggable> | ||||
| 			</Sortable> | ||||
| 			<!-- TODO: https://github.com/MaxLeiter/sortablejs-vue3/issues/52 が実装されたら消す --> | ||||
| 			<button class="_button add" @click="chooseEmoji"><i class="ti ti-plus"></i></button> | ||||
| 		</div> | ||||
| 		<template #caption>{{ i18n.ts.reactionSettingDescription2 }} <button class="_textButton" @click="preview">{{ i18n.ts.preview }}</button></template> | ||||
| 	</FromSlot> | ||||
|  | @ -55,7 +57,7 @@ | |||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { defineAsyncComponent, watch } from 'vue'; | ||||
| import XDraggable from 'vuedraggable'; | ||||
| import { Sortable } from 'sortablejs-vue3'; | ||||
| import FormInput from '@/components/form/input.vue'; | ||||
| import FormRadios from '@/components/form/radios.vue'; | ||||
| import FromSlot from '@/components/form/slot.vue'; | ||||
|  | @ -75,6 +77,11 @@ const reactionPickerWidth = $computed(defaultStore.makeGetterSetter('reactionPic | |||
| const reactionPickerHeight = $computed(defaultStore.makeGetterSetter('reactionPickerHeight')); | ||||
| const reactionPickerUseDrawerForMobile = $computed(defaultStore.makeGetterSetter('reactionPickerUseDrawerForMobile')); | ||||
| 
 | ||||
| function onSorted(event) { | ||||
| 	const item = reactions.splice(event.oldIndex, 1)[0]; | ||||
| 	reactions.splice(event.newIndex, 0, item); | ||||
| } | ||||
| 
 | ||||
| function save() { | ||||
| 	defaultStore.set('reactions', reactions); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										37
									
								
								yarn.lock
									
										
									
									
									
								
							
							
						
						
									
										37
									
								
								yarn.lock
									
										
									
									
									
								
							|  | @ -5193,6 +5193,8 @@ __metadata: | |||
|     s-age: 1.1.2 | ||||
|     sass: 1.57.0 | ||||
|     seedrandom: 3.0.5 | ||||
|     sortablejs: ^1.15.0 | ||||
|     sortablejs-vue3: ^1.2.3 | ||||
|     start-server-and-test: 1.15.2 | ||||
|     strict-event-emitter-types: 2.0.0 | ||||
|     stringz: 2.1.0 | ||||
|  | @ -5212,7 +5214,6 @@ __metadata: | |||
|     vue-eslint-parser: ^9.1.0 | ||||
|     vue-prism-editor: 2.0.0-alpha.2 | ||||
|     vue-tsc: ^1.0.14 | ||||
|     vuedraggable: 4.0.1 | ||||
|   languageName: unknown | ||||
|   linkType: soft | ||||
| 
 | ||||
|  | @ -15315,10 +15316,23 @@ __metadata: | |||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "sortablejs@npm:1.10.2": | ||||
|   version: 1.10.2 | ||||
|   resolution: "sortablejs@npm:1.10.2" | ||||
|   checksum: 37f8d47a9702b93c38077c5e0af90174dcf8e95cf96fe61a722033003eb293bdf3832e4a943f281eaedc433e24cd7d5a48a408706a71a21e75bc11ced0b358da | ||||
| "sortablejs-vue3@npm:^1.2.3": | ||||
|   version: 1.2.3 | ||||
|   resolution: "sortablejs-vue3@npm:1.2.3" | ||||
|   dependencies: | ||||
|     sortablejs: ^1.15.0 | ||||
|     vue: ^3.2.37 | ||||
|   peerDependencies: | ||||
|     sortablejs: ^1.15.0 | ||||
|     vue: ^3.2.25 | ||||
|   checksum: 1cf069db4e950a9b447d98d6f4d233082f84b43ac88735e3aab07f2dcebee99026425ee5fc69b04893fe2bb9040fa8cda088a57205f7c46453043d32764b5b36 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "sortablejs@npm:^1.15.0": | ||||
|   version: 1.15.0 | ||||
|   resolution: "sortablejs@npm:1.15.0" | ||||
|   checksum: bb82223a663484640d317cad510ac987f26b7a443631040407224de1be069afcc6c39048b6d8527f10f269e33595e8128d7de2fac23517c8260470f77f932d55 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
|  | @ -17163,7 +17177,7 @@ __metadata: | |||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "vue@npm:3.2.45": | ||||
| "vue@npm:3.2.45, vue@npm:^3.2.37": | ||||
|   version: 3.2.45 | ||||
|   resolution: "vue@npm:3.2.45" | ||||
|   dependencies: | ||||
|  | @ -17176,17 +17190,6 @@ __metadata: | |||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "vuedraggable@npm:4.0.1": | ||||
|   version: 4.0.1 | ||||
|   resolution: "vuedraggable@npm:4.0.1" | ||||
|   dependencies: | ||||
|     sortablejs: 1.10.2 | ||||
|   peerDependencies: | ||||
|     vue: ^3.0.1 | ||||
|   checksum: 039e5d38560144299be3689270728639d041737b487cbb7dfec09b6c372b48804031785f9b40e6e14da0d213315b98ddc005713cc60a749cf98028e0c16fd866 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "w3c-xmlserializer@npm:^4.0.0": | ||||
|   version: 4.0.0 | ||||
|   resolution: "w3c-xmlserializer@npm:4.0.0" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue