feat: upgrade to packages for vue 3

- vue3-notification
- vue-advanced-cropper 2
- vuedraggable 4
- vue-shortkey -> moved in repo
This commit is contained in:
Dominik Pschenitschni 2021-08-20 15:46:41 +02:00
parent 7c3c2945f8
commit e779681905
Signed by: dpschen
GPG Key ID: B257AC0149F43A77
10 changed files with 405 additions and 142 deletions

View File

@ -14,6 +14,7 @@
"test:frontend": "cypress run"
},
"dependencies": {
"@kyvg/vue3-notification": "2.3.3",
"@vue/compat": "3.2.14",
"browserslist": "4.17.1",
"bulma": "0.9.3",
@ -29,14 +30,13 @@
"snake-case": "3.0.4",
"ufo": "0.7.9",
"vue": "3.2.14",
"vue-advanced-cropper": "1.8.2",
"vue-drag-resize": "1.5.4",
"vue-advanced-cropper": "^2.6.3",
"vue-drag-resize": "^2.0.3",
"vue-easymde": "1.4.0",
"vue-flatpickr-component": "9.0.4",
"vue-flatpickr-component": "9.0.5",
"vue-i18n": "9.2.0-beta.6",
"vue-router": "4.0.11",
"vue-shortkey": "3.1.7",
"vuedraggable": "2.24.3",
"vuedraggable": "4.0.1",
"vuex": "4.0.2",
"workbox-precaching": "6.3.0"
},
@ -70,7 +70,6 @@
"typescript": "4.4.3",
"vite": "2.6.1",
"vite-plugin-pwa": "0.11.2",
"vue-notification": "1.3.20",
"wait-on": "6.0.0",
"workbox-cli": "6.3.0"
},

View File

@ -91,17 +91,20 @@
@end="e => saveListPosition(e, nk)"
handle=".handle"
:disabled="n.id < 0"
:class="{'dragging-disabled': n.id < 0}"
tag="transition-group"
item-key="id"
:component-data="{
type: 'transition',
tag: 'ul',
name: !drag ? 'flip-list' : null,
class: [
'menu-list can-be-hidden',
{ 'dragging-disabled': n.id < 0 }
]
}"
>
<transition-group
type="transition"
:name="!drag ? 'flip-list' : null"
tag="ul"
class="menu-list can-be-hidden"
>
<template #item="{element: l}">
<li
v-for="l in activeLists[nk]"
:key="l.id"
class="loader-container"
:class="{'is-loading': listUpdating[l.id]}"
>
@ -140,7 +143,7 @@
<list-settings-dropdown :list="l" v-if="l.id > 0"/>
<span class="list-setting-spacer" v-else></span>
</li>
</transition-group>
</template>
</draggable>
</div>
</template>

View File

@ -86,9 +86,8 @@
:w="t.durationDays * dayWidth"
:x="t.offsetDays * dayWidth - 6"
:y="0"
@clicked="setTaskDragged(t)"
@dragstop="resizeTask"
@resizestop="resizeTask"
@dragstop="(e) => resizeTask(t, e)"
@resizestop="(e) => resizeTask(t, e)"
axis="x"
class="task"
>
@ -136,9 +135,8 @@
:sticks="['mr', 'ml']"
:x="dayOffsetUntilToday * dayWidth - 6"
:y="0"
@clicked="setTaskDragged(t)"
@dragstop="resizeTask"
@resizestop="resizeTask"
@dragstop="(e) => resizeTask(t, e)"
@resizestop="(e) => resizeTask(t, e)"
axis="x"
class="task nodate"
v-tooltip="$t('list.gantt.noDates')"
@ -233,7 +231,6 @@ export default {
theTasks: [], // Pretty much a copy of the prop, since we cant mutate the prop directly
tasksWithoutDates: [],
taskService: new TaskService(),
taskDragged: null, // Saves to currently dragged task to be able to update it
fullWidth: 0,
now: new Date(),
dayOffsetUntilToday: 0,
@ -361,15 +358,14 @@ export default {
t.offsetDays = Math.floor((t.startDate - this.startDate) / 1000 / 60 / 60 / 24)
return t
},
setTaskDragged(t) {
this.taskDragged = t
},
resizeTask(newRect) {
resizeTask(taskDragged, newRect) {
if (this.isTaskEdit) {
return
}
const didntHaveDates = this.taskDragged.startDate === null ? true : false
let newTask = { ...taskDragged }
const didntHaveDates = newTask.startDate === null ? true : false
let startDate = new Date(this.startDate)
startDate.setDate(
@ -379,32 +375,32 @@ export default {
startDate.setUTCMinutes(0)
startDate.setUTCSeconds(0)
startDate.setUTCMilliseconds(0)
this.taskDragged.startDate = startDate
newTask.startDate = startDate
let endDate = new Date(startDate)
endDate.setDate(
startDate.getDate() + newRect.width / this.dayWidth,
)
this.taskDragged.startDate = startDate
this.taskDragged.endDate = endDate
newTask.startDate = startDate
newTask.endDate = endDate
// We take the task from the overall tasks array because the one in it has bad data after it was updated once.
// FIXME: This is a workaround. We should use a better mechanism to get the task or, even better,
// prevent it from containing outdated Data in the first place.
for (const tt in this.theTasks) {
if (this.theTasks[tt].id === this.taskDragged.id) {
this.taskDragged = this.theTasks[tt]
if (this.theTasks[tt].id === newTask.id) {
newTask = this.theTasks[tt]
break
}
}
const ganttData = {
endDate: this.taskDragged.endDate,
durationDays: this.taskDragged.durationDays,
offsetDays: this.taskDragged.offsetDays,
endDate: newTask.endDate,
durationDays: newTask.durationDays,
offsetDays: newTask.offsetDays,
}
this.taskService
.update(this.taskDragged)
.update(newTask)
.then(r => {
r.endDate = ganttData.endDate
r.durationDays = ganttData.durationDays

View File

@ -1,4 +1,11 @@
import { createApp } from 'vue'
import { createApp, configureCompat } from 'vue'
configureCompat({
COMPONENT_V_MODEL: false,
COMPONENT_ASYNC: false,
RENDER_FUNCTION: false,
WATCH_ARRAY: false, // TODO: check this again; this might lead to some problemes
})
import App from './App.vue'
import router from './router'
@ -18,13 +25,13 @@ import {VERSION} from './version.json'
// Add CSS
import './styles/vikunja.scss'
// Notifications
import Notifications from 'vue-notification'
import Notifications from '@kyvg/vue3-notification'
// PWA
import './registerServiceWorker'
// Shortcuts
// @ts-ignore - no types available
import vueShortkey from 'vue-shortkey'
import shortkey from '@/plugins/shortkey'
// Vuex
import {store} from './store'
// i18n
@ -45,19 +52,11 @@ if (window.API_URL.substr(window.API_URL.length - 1, window.API_URL.length) ===
const app = createApp(App)
Vue.use(Notifications)
app.use(Notifications)
Vue.use(vueShortkey, {prevent: ['input', 'textarea', '.input', '[contenteditable]']})
app.config.globalProperties.$message = {
error(e, actions = []) {
return error(e, Vue.prototype, actions)
},
success(s, actions = []) {
return success(s, Vue.prototype, actions)
},
}
app.use(shortkey, {prevent: ['input', 'textarea', '.input', '[contenteditable]']})
// directives
import focus from './directives/focus'
@ -92,6 +91,15 @@ app.mixin({
},
})
app.config.errorHandler = (err, vm, info) => {
error(err)
}
app.config.globalProperties.$message = {
error,
success,
}
app.use(router)
app.use(store)
app.use(i18n)

View File

@ -1,4 +1,5 @@
import {i18n} from '@/i18n'
import { notify } from '@kyvg/vue3-notification'
export const getErrorText = (r) => {
@ -27,8 +28,8 @@ export const getErrorText = (r) => {
return [r.message]
}
export function error(e, context, actions = []) {
context.$notify({
export function error(e, actions = []) {
notify({
type: 'error',
title: i18n.global.t('error.error'),
text: getErrorText(e),
@ -37,8 +38,8 @@ export function error(e, context, actions = []) {
console.error(e, actions)
}
export function success(e, context, actions = []) {
context.$notify({
export function success(e, actions = []) {
notify({
type: 'success',
title: i18n.global.t('error.success'),
text: getErrorText(e),

View File

@ -0,0 +1,78 @@
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
const MODIFIER_KEYS = ['shift', 'ctrl', 'meta', 'alt']
const SHORT_CUT_INDEX = [
{ key: 'ArrowUp', value: 'arrowup' },
{ key: 'ArrowLeft', value: 'arrowlef' },
{ key: 'ArrowRight', value: 'arrowright' },
{ key: 'ArrowDown', value: 'arrowdown' },
{ key: 'AltGraph', value: 'altgraph' },
{ key: 'Escape', value: 'esc' },
{ key: 'Enter', value: 'enter' },
{ key: 'Tab', value: 'tab' },
{ key: ' ', value: 'space' },
{ key: 'PageUp', value: 'pagup' },
{ key: 'PageDown', value: 'pagedow' },
{ key: 'Home', value: 'home' },
{ key: 'End', value: 'end' },
{ key: 'Delete', value: 'del' },
{ key: 'Backspace', value: 'bacspace' },
{ key: 'Insert', value: 'insert' },
{ key: 'NumLock', value: 'numlock' },
{ key: 'CapsLock', value: 'capslock' },
{ key: 'Pause', value: 'pause' },
{ key: 'ContextMenu', value: 'cotextmenu' },
{ key: 'ScrollLock', value: 'scrolllock' },
{ key: 'BrowserHome', value: 'browserhome' },
{ key: 'MediaSelect', value: 'mediaselect' },
]
export function encodeKey(pKey) {
const shortKey = {}
MODIFIER_KEYS.forEach((key) => {
shortKey[`${key}Key`] = pKey.includes(key)
})
let indexedKeys = createShortcutIndex(shortKey)
const vKey = pKey.filter(
(item) => !MODIFIER_KEYS.includes(item),
)
indexedKeys += vKey.join('')
return indexedKeys
}
function createShortcutIndex(pKey) {
let k = ''
MODIFIER_KEYS.forEach((key) => {
if (pKey.key === capitalizeFirstLetter(key) || pKey[`${key}Key`]) {
k += key
}
})
SHORT_CUT_INDEX.forEach(({ key, value }) => {
if (pKey.key === key) {
k += value
}
})
if (
(pKey.key && pKey.key !== ' ' && pKey.key.length === 1) ||
/F\d{1,2}|\//g.test(pKey.key)
) {
k += pKey.key.toLowerCase()
}
return k
}
export { createShortcutIndex as decodeKey }
export function parseValue(value) {
value = typeof value === 'string' ? JSON.parse(value.replace(/'/gi, '"')) : value
return value instanceof Array ? { '': value } : value
}

View File

@ -0,0 +1,186 @@
import { parseValue, decodeKey, encodeKey } from './helpers'
let mapFunctions = {}
let objAvoided = []
let elementAvoided = []
let keyPressed = false
function dispatchShortkeyEvent(pKey) {
const e = new CustomEvent('shortkey', { bubbles: false })
if (mapFunctions[pKey].key) {
e.srcKey = mapFunctions[pKey].key
}
const elm = mapFunctions[pKey].el
if (!mapFunctions[pKey].propagte) {
elm[elm.length - 1].dispatchEvent(e)
} else {
elm.forEach((elmItem) => elmItem.dispatchEvent(e))
}
}
function keyDown(pKey) {
if (
(!mapFunctions[pKey].once && !mapFunctions[pKey].push) ||
(mapFunctions[pKey].push && !keyPressed)
) {
dispatchShortkeyEvent(pKey)
}
}
function fillMappingFunctions(
mappingFunctions,
{ b, push, once, focus, propagte, el },
) {
for (let key in b) {
const k = encodeKey(b[key])
const propagated = mappingFunctions[k] && mappingFunctions[k].propagte
const elm =
mappingFunctions[k] && mappingFunctions[k].el
? mappingFunctions[k].el
: []
elm.push(el)
mappingFunctions[k] = {
push,
once,
focus,
key,
propagte: propagated || propagte,
el: elm,
}
}
}
function bindValue(value, el, binding, vnode) {
const { modifiers } = binding
const push = !!modifiers.push
const avoid = !!modifiers.avoid
const focus = !modifiers.focus
const once = !!modifiers.once
const propagte = !!modifiers.propagte
if (avoid) {
objAvoided = objAvoided.filter((itm) => !itm === el)
objAvoided.push(el)
} else {
fillMappingFunctions(mapFunctions, {
b: value,
push,
once,
focus,
propagte,
el: vnode.el,
})
}
}
function unbindValue(value, el) {
for (let key in value) {
const k = encodeKey(value[key])
const idxElm = mapFunctions[k].el.indexOf(el)
if (mapFunctions[k].el.length > 1 && idxElm > -1) {
mapFunctions[k].el.splice(idxElm, 1)
} else {
delete mapFunctions[k]
}
}
}
function availableElement(decodedKey) {
const objectIsAvoided = !!objAvoided.find(
(r) => r === document.activeElement,
)
const filterAvoided = !!elementAvoided.find(
(selector) =>
document.activeElement && document.activeElement.matches(selector),
)
return !!mapFunctions[decodedKey] && !(objectIsAvoided || filterAvoided)
}
function keyDownListener(pKey) {
const decodedKey = decodeKey(pKey)
// Check avoidable elements
if (!availableElement(decodedKey)) {
return
}
if (!mapFunctions[decodedKey].propagte) {
pKey.preventDefault()
pKey.stopPropagation()
}
if (mapFunctions[decodedKey].focus) {
keyDown(decodedKey)
keyPressed = true
} else if (!keyPressed) {
const elm = mapFunctions[decodedKey].el
elm[elm.length - 1].focus()
keyPressed = true
}
}
function keyUpListener(pKey) {
const decodedKey = decodeKey(pKey)
if (!availableElement(decodedKey)) {
keyPressed = false
return
}
if (!mapFunctions[decodedKey].propagte) {
pKey.preventDefault()
pKey.stopPropagation()
}
if (mapFunctions[decodedKey].once || mapFunctions[decodedKey].push) {
dispatchShortkeyEvent(decodedKey)
}
keyPressed = false
}
// register key presses that happen before mounting of directive
// if (process?.env?.NODE_ENV !== 'test') {
// (() => {
document.addEventListener('keydown', keyDownListener, true)
document.addEventListener('keyup', keyUpListener, true)
// })()
// }
function install(app, options) {
elementAvoided = [...(options && options.prevent ? options.prevent : [])]
app.directive('shortkey', {
beforeMount(el, binding, vnode) {
// Mapping the commands
const value = parseValue(binding.value)
bindValue(value, el, binding, vnode)
},
updated(el, binding, vnode) {
const oldValue = parseValue(binding.oldValue)
unbindValue(oldValue, el)
const newValue = parseValue(binding.value)
bindValue(newValue, el, binding, vnode)
},
unmounted(el, binding) {
const value = parseValue(binding.value)
unbindValue(value, el)
},
})
}
export default {
install,
encodeKey,
decodeKey,
keyDown,
}

View File

@ -27,17 +27,14 @@
group="buckets"
:disabled="!canWrite"
:class="{'dragging-disabled': !canWrite}"
tag="transition-group"
:item-key="({id}) => `bucket${id}`"
:component-data="bucketDraggableComponentData"
>
<transition-group
type="transition"
:name="!dragBucket ? 'move-bucket': null"
tag="div"
class="kanban-bucket-container">
<template #item="{element: bucket, index: bucketIndex }">
<div
:key="`bucket${bucket.id}`"
class="bucket"
:class="{'is-collapsed': collapsedBuckets[bucket.id]}"
v-for="(bucket, k) in buckets"
>
<div class="bucket-header" @click="() => unCollapseBucket(bucket)">
<span
@ -136,16 +133,15 @@
:group="{name: 'tasks', put: shouldAcceptDrop(bucket) && !dragBucket}"
:disabled="!canWrite"
:class="{'dragging-disabled': !canWrite}"
:data-bucket-index="k"
:data-bucket-index="bucketIndex"
class="dropper"
tag="transition-group"
:item-key="(task) => `bucket${bucket.id}-task${task.id}`"
:component-data="taskDraggableTaskComponentData"
>
<transition-group type="transition" :name="!drag ? 'move-card': null" tag="div">
<kanban-card
:key="`bucket${bucket.id}-task${task.id}`"
v-for="task in bucket.tasks"
:task="task"
/>
</transition-group>
<template #item="{element: task}">
<kanban-card :task="task" />
</template>
</draggable>
</div>
<div class="bucket-footer" v-if="canWrite">
@ -181,7 +177,7 @@
</x-button>
</div>
</div>
</transition-group>
</template>
</draggable>
<div class="bucket new-bucket" v-if="canWrite && !loading && buckets.length > 0">
@ -251,6 +247,15 @@ import {getCollapsedBucketState, saveCollapsedBucketState} from '@/helpers/saveC
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
import KanbanCard from '../../../components/tasks/partials/kanban-card'
const DRAG_OPTIONS = {
// sortable options
animation: 150,
ghostClass: 'ghost',
dragClass: 'task-dragging',
delayOnTouchOnly: true,
delay: 150,
}
export default {
name: 'Kanban',
components: {
@ -261,6 +266,8 @@ export default {
},
data() {
return {
dragOptions: DRAG_OPTIONS,
drag: false,
dragBucket: false,
sourceBucket: 0,
@ -305,6 +312,21 @@ export default {
'$route.params.listId': 'loadBuckets',
},
computed: {
bucketDraggableComponentData() {
return {
type: 'transition',
tag: 'div',
name: !this.dragBucket ? 'move-bucket': null,
class: 'kanban-bucket-container',
}
},
taskDraggableTaskComponentData() {
return {
type: 'transition',
tag: 'div',
name: !this.drag ? 'move-card': null,
}
},
buckets: {
get() {
return this.$store.state.kanban.buckets
@ -313,17 +335,6 @@ export default {
this.$store.commit('kanban/setBuckets', value)
},
},
dragOptions() {
const options = {
animation: 150,
ghostClass: 'ghost',
dragClass: 'task-dragging',
delay: 150,
delayOnTouchOnly: true,
}
return options
},
...mapState({
loadedListId: state => state.kanban.listId,
loading: state => state[LOADING] && state[LOADING_MODULE] === 'kanban',

View File

@ -89,27 +89,28 @@
handle=".handle"
:disabled="!canWrite"
:class="{'dragging-disabled': !canWrite}"
item-key="id"
>
<single-task-in-list
:show-list-color="false"
:disabled="!canWrite"
:key="t.id"
:the-task="t"
@taskUpdated="updateTasks"
task-detail-route="task.detail"
v-for="t in tasks"
>
<span class="icon handle">
<icon icon="grip-lines"/>
</span>
<div
@click="editTask(t.id)"
class="icon settings"
v-if="!list.isArchived && canWrite"
<template #item="{element: t}">
<single-task-in-list
:show-list-color="false"
:disabled="!canWrite"
:the-task="t"
@taskUpdated="updateTasks"
task-detail-route="task.detail"
>
<icon icon="pencil-alt"/>
</div>
</single-task-in-list>
<span class="icon handle">
<icon icon="grip-lines"/>
</span>
<div
@click="editTask(t.id)"
class="icon settings"
v-if="!list.isArchived && canWrite"
>
<icon icon="pencil-alt"/>
</div>
</single-task-in-list>
</template>
</draggable>
</div>
<card

View File

@ -1293,6 +1293,11 @@
"@types/yargs" "^16.0.0"
chalk "^4.0.0"
"@kyvg/vue3-notification@2.3.3":
version "2.3.3"
resolved "https://registry.yarnpkg.com/@kyvg/vue3-notification/-/vue3-notification-2.3.3.tgz#7de890cbf000cf063da47bb49caa83bfb0350108"
integrity sha512-NxFejSs7FlaUzsPQ4jJyrB+UCFfsBUqICcQH70wHId52Hc9G9i0rBp2Wj3UsNj21H/HitP3r92rfz4ly2ImyMA==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@ -2807,11 +2812,6 @@ csstype@^2.6.8:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e"
integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==
custom-event-polyfill@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz#9bc993ddda937c1a30ccd335614c6c58c4f87aee"
integrity sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==
cypress-file-upload@5.0.8:
version "5.0.8"
resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz#d8824cbeaab798e44be8009769f9a6c9daa1b4a1"
@ -3096,11 +3096,6 @@ electron-to-chromium@^1.3.846:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.846.tgz#a55fd59613dbcaed609e965e3e88f42b08c401d3"
integrity sha512-2jtSwgyiRzybHRxrc2nKI+39wH3AwQgn+sogQ+q814gv8hIFwrcZbV07Ea9f8AmK0ufPVZUvvAG1uZJ+obV4Jw==
element-matches@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/element-matches/-/element-matches-0.1.2.tgz#7345cb71e965bd2b12f725e524591c102198361a"
integrity sha512-yWh1otcs3OKUWDvu/IxyI36ZI3WNaRZlI0uG/DK6fu0pap0VYZ0J5pEGTk1zakme+hT0OKHwhlHc0N5TJhY6yQ==
emittery@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
@ -6907,21 +6902,19 @@ vite@2.6.1:
optionalDependencies:
fsevents "~2.3.2"
vue-advanced-cropper@1.8.2:
version "1.8.2"
resolved "https://registry.yarnpkg.com/vue-advanced-cropper/-/vue-advanced-cropper-1.8.2.tgz#c163e54584cd568e9fb2b63bc0fe08a58c060421"
integrity sha512-dngjbph+QbqLpk4DWCoCajWcThyy08NorFhMcmrnGFJvdxTFiuJ+XjOtrXhNpDdl7U6E/csrkx6i6E8V+BwmoQ==
vue-advanced-cropper@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/vue-advanced-cropper/-/vue-advanced-cropper-2.6.3.tgz#3ec29584a53954f915a86e0f28069b79d7c29719"
integrity sha512-EWZ4dXnP7NpTNsCOlgGjUvBYtPtrWX+wMdW0w3PjwOk4UtQfvKz2IPYtIBzZqvxwUq0OIUq1K5y3VnCvs1DBDA==
dependencies:
classnames "^2.2.6"
debounce "^1.2.0"
easy-bem "^1.0.2"
vue-drag-resize@1.5.4, vue-drag-resize@^1.5.0-rc3:
version "1.5.4"
resolved "https://registry.yarnpkg.com/vue-drag-resize/-/vue-drag-resize-1.5.4.tgz#f583f40f356e5792aa89109b3d13ba4407c25198"
integrity sha512-SR3U7n6TAZEBgP7zw7bR9mjtAlYBjqIoaWTDPz5HXN/nYhOxKSA31aD7p71fmq1jtyt9reAnCx62valNL9ZAcg==
dependencies:
vue-drag-resize "^1.5.0-rc3"
vue-drag-resize@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/vue-drag-resize/-/vue-drag-resize-2.0.3.tgz#1faf0813f43304205bb355fbb3dacc548dd9398a"
integrity sha512-5q03tZ/LyvQsg1iHRcqs+wI2OKNbNIWl9+7V8rVL6MxJhZLCIYSSgbAUaDE38LhD6dFd5aJhdgNmES61AxjXuw==
vue-easymde@1.4.0:
version "1.4.0"
@ -6944,10 +6937,10 @@ vue-eslint-parser@^7.0.0, vue-eslint-parser@^7.10.0:
lodash "^4.17.21"
semver "^6.3.0"
vue-flatpickr-component@9.0.4:
version "9.0.4"
resolved "https://registry.yarnpkg.com/vue-flatpickr-component/-/vue-flatpickr-component-9.0.4.tgz#b064fffb11b0e351213434d2f6b2a291d753438c"
integrity sha512-E8XfzLhrPsQBtZluWYEn3m21VHn7PArYnel3QPYL3auBrVMc07WaK6b20e04OK8LUCq9V+OKNZe4MoI0znY/Hw==
vue-flatpickr-component@9.0.5:
version "9.0.5"
resolved "https://registry.yarnpkg.com/vue-flatpickr-component/-/vue-flatpickr-component-9.0.5.tgz#350ec73b7f3d7f80b050c170c088234f9c3bd14c"
integrity sha512-fKuz/D4ePQKi+jPo4xjYRgBCLTWrTsCoKbx8nam63x4kTDtSqvFOjNwLvy0QgwC0lC+aFpUWa1dNYTH0hgUcCA==
dependencies:
flatpickr "^4.6.9"
@ -6961,11 +6954,6 @@ vue-i18n@9.2.0-beta.6:
"@intlify/vue-devtools" "9.2.0-beta.6"
"@vue/devtools-api" "^6.0.0-beta.13"
vue-notification@1.3.20:
version "1.3.20"
resolved "https://registry.yarnpkg.com/vue-notification/-/vue-notification-1.3.20.tgz#d85618127763b46f3e25b8962b857947d5a97cbe"
integrity sha512-vPj67Ah72p8xvtyVE8emfadqVWguOScAjt6OJDEUdcW5hW189NsqvfkOrctxHUUO9UYl9cTbIkzAEcPnHu+zBQ==
vue-router@4.0.11:
version "4.0.11"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.11.tgz#cd649a0941c635281763a20965b599643ddc68ed"
@ -6973,14 +6961,6 @@ vue-router@4.0.11:
dependencies:
"@vue/devtools-api" "^6.0.0-beta.14"
vue-shortkey@3.1.7:
version "3.1.7"
resolved "https://registry.yarnpkg.com/vue-shortkey/-/vue-shortkey-3.1.7.tgz#31c09a99ed597331a6a49a45eeff894a78a19eef"
integrity sha512-Wm/vPXXS+4Wl/LoYpD+cZc0J0HIoVlY8Ep0JLIqqswmAya3XUBtsqKbhzEf9sXo+3rZ5p1YsUyZfXas8XD7YjQ==
dependencies:
custom-event-polyfill "^1.0.7"
element-matches "^0.1.2"
vue@3.2.14:
version "3.2.14"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.14.tgz#da577433fb74f328ed58255c728a6a1bf196d337"
@ -6992,10 +6972,10 @@ vue@3.2.14:
"@vue/server-renderer" "3.2.14"
"@vue/shared" "3.2.14"
vuedraggable@2.24.3:
version "2.24.3"
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==
vuedraggable@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-4.0.1.tgz#3bcaab0808b7944030b7d9a29f9a63d59dfa12c5"
integrity sha512-7qN5jhB1SLfx5P+HCm3JUW+pvgA1bSLgYLSVOeLWBDH9z+zbaEH0OlyZBVMLOxFR+JUHJjwDD0oy7T4r9TEgDA==
dependencies:
sortablejs "1.10.2"