diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.vue | 5 | ||||
-rw-r--r-- | src/components/AppNavigation/ListItemCalendar.vue | 12 | ||||
-rw-r--r-- | src/components/AppNavigation/Trashbin.vue | 8 | ||||
-rw-r--r-- | src/components/AppSidebar/NotesItem.vue | 4 | ||||
-rw-r--r-- | src/components/AppSidebar/SliderItem.vue | 2 | ||||
-rw-r--r-- | src/components/HeaderBar.vue | 2 | ||||
-rw-r--r-- | src/components/TaskBody.vue | 4 | ||||
-rw-r--r-- | src/components/TaskDragContainer.vue | 21 | ||||
-rw-r--r-- | src/dashboard.js | 22 | ||||
-rw-r--r-- | src/helpers/selector.js | 24 | ||||
-rw-r--r-- | src/main.js | 61 | ||||
-rw-r--r-- | src/mixins/editableItem.js | 2 | ||||
-rw-r--r-- | src/router.js | 83 | ||||
-rw-r--r-- | src/store/calendars.js | 20 | ||||
-rw-r--r-- | src/store/collections.js | 7 | ||||
-rw-r--r-- | src/store/principals.js | 4 | ||||
-rw-r--r-- | src/store/settings.js | 5 | ||||
-rw-r--r-- | src/store/store.js | 7 | ||||
-rw-r--r-- | src/store/tasks.js | 96 | ||||
-rw-r--r-- | src/talk.js | 10 | ||||
-rw-r--r-- | src/views/AppNavigation.vue | 33 | ||||
-rw-r--r-- | src/views/AppSidebar.vue | 6 |
22 files changed, 192 insertions, 246 deletions
diff --git a/src/App.vue b/src/App.vue index 021e837e..65760d4b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -21,9 +21,9 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. <template> <NcContent app-name="tasks"> - <AppNavigation @click.native="closeAppSidebar($event)" /> + <AppNavigation @click="closeAppSidebar($event)" /> - <NcAppContent @click.native="closeAppSidebar($event)"> + <NcAppContent @click="closeAppSidebar($event)"> <RouterView /> </NcAppContent> @@ -49,6 +49,7 @@ export default { NcAppContent, NcContent, }, + inject: ['$OCA'], data() { return { searchString: '', diff --git a/src/components/AppNavigation/ListItemCalendar.vue b/src/components/AppNavigation/ListItemCalendar.vue index 3db18a3a..999647c7 100644 --- a/src/components/AppNavigation/ListItemCalendar.vue +++ b/src/components/AppNavigation/ListItemCalendar.vue @@ -27,10 +27,10 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. :title="calendar.displayName" :class="{'list--edit': editing, 'list--deleted': !!deleteTimeout}" class="list reactive" - @drop.native="dropTask" - @dragover.native="dragOver" - @dragenter.native="dragEnter" - @dragleave.native="dragLeave"> + @drop="dropTask" + @dragover="dragOver" + @dragenter="dragEnter" + @dragleave="dragLeave"> <template #icon> <NcAppNavigationIconBullet :color="calendar.color" /> </template> @@ -111,6 +111,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. <ShareCalendar v-if="shareOpen && !calendar.readOnly && !deleteTimeout" :calendar="calendar" /> <div v-if="!deleteTimeout" :class="{error: nameError}" class="app-navigation-entry-edit"> <NcTextField ref="editListInput" + v-model:value="newCalendarName" v-tooltip="{ content: tooltipMessage, shown: showTooltip('list_' + calendar.id), @@ -119,7 +120,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. type="text" :show-trailing-button="newCalendarName !== ''" trailing-button-icon="arrowRight" - :value.sync="newCalendarName" :error="nameError" :placeholder="t('tasks', 'Save')" @trailing-button-click="save(calendar)" @@ -157,7 +157,7 @@ import Pencil from 'vue-material-design-icons/Pencil.vue' import ShareVariant from 'vue-material-design-icons/ShareVariant.vue' import Undo from 'vue-material-design-icons/Undo.vue' -import ClickOutside from 'v-click-outside' +import ClickOutside from 'click-outside-vue3' import { mapGetters, mapActions } from 'vuex' const CD_DURATION = 7 diff --git a/src/components/AppNavigation/Trashbin.vue b/src/components/AppNavigation/Trashbin.vue index b183dff9..b74593c5 100644 --- a/src/components/AppNavigation/Trashbin.vue +++ b/src/components/AppNavigation/Trashbin.vue @@ -54,8 +54,8 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. <div class="table__header"> </div> - <template v-for="item in items"> - <div :key="`${item.url}desc`" class="table__body"> + <template v-for="item in items" :key="`${item.url}body`"> + <div class="table__body"> <div class="icon-bullet" :style="{ 'background-color': item.color }" /> <div class="item-description"> @@ -67,10 +67,10 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. </div> </div> </div> - <div :key="`${item.url}date`" class="table__body table__body--deletedAt"> + <div class="table__body table__body--deletedAt"> <Moment class="timestamp" :timestamp="item.deletedAt" /> </div> - <div :key="`${item.url}action`" class="table__body"> + <div class="table__body"> <NcButton @click="restore(item)"> <template #icon> <Undo :size="20" /> diff --git a/src/components/AppSidebar/NotesItem.vue b/src/components/AppSidebar/NotesItem.vue index 34cdd94b..73cab76f 100644 --- a/src/components/AppSidebar/NotesItem.vue +++ b/src/components/AppSidebar/NotesItem.vue @@ -34,7 +34,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. <pre><span>{{ newValue }}</span><br><br></pre> <textarea ref="note__editor" v-model="newValue" - @keyup.27="setEditing(false)" + @keyup.escape="setEditing(false)" @keydown.enter.ctrl.prevent="setValue()" @change="setValue()" /> </div> @@ -53,7 +53,7 @@ import Mila from 'markdown-it-link-attributes' import MarkdownItEmoji from 'markdown-it-emoji' import Mitl from 'markdown-it-task-lists' -import ClickOutside from 'v-click-outside' +import ClickOutside from 'click-outside-vue3' export default { name: 'NotesItem', diff --git a/src/components/AppSidebar/SliderItem.vue b/src/components/AppSidebar/SliderItem.vue index ad7eaa4f..60720eeb 100644 --- a/src/components/AppSidebar/SliderItem.vue +++ b/src/components/AppSidebar/SliderItem.vue @@ -39,7 +39,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. type="number" :min="minValue" :max="maxValue" - @keyup.27="setEditing(false)" + @keyup.escape="setEditing(false)" @keydown.enter.prevent="setValue()"> <input v-model="newValue" type="range" diff --git a/src/components/HeaderBar.vue b/src/components/HeaderBar.vue index 9ec4c4f7..dfd667db 100644 --- a/src/components/HeaderBar.vue +++ b/src/components/HeaderBar.vue @@ -29,7 +29,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. :placeholder="placeholder" autocomplete="off" class="reactive" - @keyup.27="clearNewTask($event)"> + @keyup.escape="clearNewTask($event)"> </form> </div> <SortorderDropdown /> diff --git a/src/components/TaskBody.vue b/src/components/TaskBody.vue index 6aadc996..504272a8 100644 --- a/src/components/TaskBody.vue +++ b/src/components/TaskBody.vue @@ -151,7 +151,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. v-model="newTaskName" :placeholder="subtasksCreationPlaceholder" :disabled="isAddingTask" - @keyup.27="showSubtaskInput = false"> + @keyup.escape="showSubtaskInput = false"> </form> </div> <TaskDragContainer :tasks="filteredSubtasksShown" @@ -188,7 +188,7 @@ import CalendarClock from 'vue-material-design-icons/CalendarClock.vue' import Star from 'vue-material-design-icons/Star.vue' import Undo from 'vue-material-design-icons/Undo.vue' -import ClickOutside from 'v-click-outside' +import ClickOutside from 'click-outside-vue3' import { mapGetters, mapActions, mapMutations } from 'vuex' export default { diff --git a/src/components/TaskDragContainer.vue b/src/components/TaskDragContainer.vue index e3106a09..bafa61a8 100644 --- a/src/components/TaskDragContainer.vue +++ b/src/components/TaskDragContainer.vue @@ -20,26 +20,29 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. --> <template> - <draggable tag="ol" + <!-- <draggable tag="ol" :list="['']" :set-data="setDragData" v-bind="{group: 'tasks', swapThreshold: 0.30, delay: 500, delayOnTouchOnly: true, touchStartThreshold: 3, disabled: disabled, filter: '.readOnly'}" :move="onMove" @add="onAdd" - @end="onEnd"> + @end="onEnd"> --> + <ol> <TaskBody v-for="task in sortedTasks" :key="task.key" :task="task" :collection-string="collectionString" /> - </draggable> + </ol> + <!-- </draggable> --> </template> <script> import Task from '../models/task.js' import { sort } from '../store/storeHelper.js' -import draggable from 'vuedraggable' +// import draggable from 'vuedraggable' import { mapGetters, mapActions, mapMutations } from 'vuex' +import { defineAsyncComponent } from 'vue' export default { name: 'TaskDragContainer', @@ -47,14 +50,10 @@ export default { /** * We asynchronously import here, because we have a circular dependency * between TaskDragContainer and TaskBody which otherwise cannot be resolved. - * See https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components - * - * We load it "eager", because the TaskBody will always be required. - * - * @return {object} The TaskBody component + * See https://vuejs.org/guide/components/async.html#basic-usage */ - TaskBody: () => import(/* webpackMode: "eager" */ './TaskBody.vue'), - draggable, + TaskBody: defineAsyncComponent(() => import('./TaskBody.vue')), + // draggable, }, props: { tasks: { diff --git a/src/dashboard.js b/src/dashboard.js index 54deac16..4a0e48e2 100644 --- a/src/dashboard.js +++ b/src/dashboard.js @@ -29,12 +29,8 @@ import './css/dashboard.scss' import { generateFilePath } from '@nextcloud/router' import { getRequestToken } from '@nextcloud/auth' -import { translate as t, translatePlural as n } from '@nextcloud/l10n' -import Vue from 'vue' -import Vuex from 'vuex' - -Vue.use(Vuex) +import { createApp } from 'vue' // eslint-disable-next-line __webpack_nonce__ = btoa(getRequestToken()) @@ -42,19 +38,11 @@ __webpack_nonce__ = btoa(getRequestToken()) // eslint-disable-next-line __webpack_public_path__ = generateFilePath('tasks', '', 'js/') -Vue.prototype.t = t -Vue.prototype.n = n -Vue.prototype.$OC = OC -Vue.prototype.$OCA = OCA -Vue.prototype.$appVersion = appVersion - document.addEventListener('DOMContentLoaded', () => { OCA.Dashboard.register('tasks', (el) => { - const View = Vue.extend(Dashboard) - const vm = new View({ - propsData: {}, - store, - }).$mount(el) - return vm + const item = createApp(Dashboard) + .use(store) + .mount(el) + return item }) }) diff --git a/src/helpers/selector.js b/src/helpers/selector.js index b1841f9b..007fc5ea 100644 --- a/src/helpers/selector.js +++ b/src/helpers/selector.js @@ -25,27 +25,21 @@ */ import store from '../store/store.js' -import Vue from 'vue' +import { createApp } from 'vue' const buildSelector = (selector, propsData = {}) => { return new Promise((resolve, reject) => { const container = document.createElement('div') document.getElementById('body-user').append(container) - const View = Vue.extend(selector) - const ComponentVM = new View({ - propsData, - store, - }).$mount(container) - ComponentVM.$root.$on('close', () => { - ComponentVM.$el.remove() - ComponentVM.$destroy() - reject(new Error('Selection canceled')) - }) - ComponentVM.$root.$on('select', (id) => { - ComponentVM.$el.remove() - ComponentVM.$destroy() - resolve(id) + const dialog = createApp(selector, { + ...propsData, + onClose() { + dialog.$el.remove() + reject(new Error('Selection canceled')) + }, }) + .use(store) + .mount(container) }) } diff --git a/src/main.js b/src/main.js index 9209e257..fa6dff22 100644 --- a/src/main.js +++ b/src/main.js @@ -38,12 +38,7 @@ import Pulse from 'vue-material-design-icons/Pulse.vue' import Tag from 'vue-material-design-icons/Tag.vue' import TrendingUp from 'vue-material-design-icons/TrendingUp.vue' -import Vue from 'vue' -import { sync } from 'vuex-router-sync' - -// Disable on production -Vue.config.devtools = true -Vue.config.performance = true +import { createApp } from 'vue' // CSP config for webpack dynamic chunk loading // eslint-disable-next-line @@ -56,34 +51,6 @@ __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-next-line __webpack_public_path__ = linkTo('tasks', 'js/') -sync(store, router) - -/** - * We have to globally register these material design icons - * so we can use them dynamically via `<component :is="icon" />` - * in the MultiselectOption component. - */ -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconAlertBoxOutline', AlertBoxOutline) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconCalendarRemove', CalendarRemove) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconCancel', Cancel) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconCheck', Check) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconDelete', Delete) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconEye', Eye) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconEyeOff', EyeOff) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconPulse', Pulse) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconTag', Tag) -// eslint-disable-next-line vue/match-component-file-name -Vue.component('IconTrendingUp', TrendingUp) - if (!OCA.Tasks) { /** * @namespace OCA.Tasks @@ -91,13 +58,21 @@ if (!OCA.Tasks) { OCA.Tasks = {} } -Vue.prototype.$OC = OC -Vue.prototype.$OCA = OCA -Vue.prototype.$appVersion = appVersion +const Tasks = createApp(App) + .component('IconAlertBoxOutline', AlertBoxOutline) + .component('IconCalendarRemove', CalendarRemove) + .component('IconCancel', Cancel) + .component('IconCheck', Check) + .component('IconDelete', Delete) + .component('IconEye', Eye) + .component('IconEyeOff', EyeOff) + .component('IconPulse', Pulse) + .component('IconTag', Tag) + .component('IconTrendingUp', TrendingUp) + .provide('$OCA', OCA) + .provide('$appVersion', appVersion) + .use(router) + .use(store) + .mount('.app-tasks') -OCA.Tasks.App = new Vue({ - el: '.app-tasks', - router, - store, - render: h => h(App), -}) +OCA.Tasks.App = Tasks diff --git a/src/mixins/editableItem.js b/src/mixins/editableItem.js index a7a05655..9d688e07 100644 --- a/src/mixins/editableItem.js +++ b/src/mixins/editableItem.js @@ -27,7 +27,7 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' import Check from 'vue-material-design-icons/Check.vue' import Delete from 'vue-material-design-icons/Delete.vue' -import ClickOutside from 'v-click-outside' +import ClickOutside from 'click-outside-vue3' export default { components: { diff --git a/src/router.js b/src/router.js index 3d7958f3..e5f24d2e 100644 --- a/src/router.js +++ b/src/router.js @@ -25,47 +25,64 @@ import AppSidebar from './views/AppSidebar.vue' import Calendar from './views/AppContent/Calendar.vue' import Collections from './views/AppContent/Collections.vue' -import Vue from 'vue' -import VueRouter from 'vue-router' +import { h } from 'vue' +import { createWebHashHistory, createRouter, RouterView } from 'vue-router' const routes = [ - // using - // { path: '/collections/all', component: CollectionGeneral, alias: '/' }, - // instead of { path: '/', redirect: getInitialRoute() }, - // would also be an option, but it currently does not work - // reliably with router-link due to - // https://github.com/vuejs/vue-router/issues/419 - { name: 'collections', path: '/collections/:collectionId', component: Collections, props: true }, { - name: 'collectionsTask', - path: '/collections/:collectionId/tasks/:taskId', - components: { default: Collections, AppSidebar }, - props: { default: true, AppSidebar: true }, + path: '/collections/:collectionId', + components: { + default: { render: () => h(RouterView, { name: 'default' }) }, + AppSidebar: { render: () => h(RouterView, { name: 'AppSidebar' }) }, + }, + children: [ + { + name: 'collections', + path: '/collections/:collectionId', + component: Collections, + props: true, + }, + { + name: 'collectionsTask', + path: '/collections/:collectionId/tasks/:taskId', + components: { default: Collections, AppSidebar }, + props: { default: true, AppSidebar: true }, + }, + { + name: 'collectionsParamTask', + path: '/collections/:collectionId/:collectionParam/tasks/:taskId', + components: { default: Collections, AppSidebar }, + props: { default: true, AppSidebar: true }, + }, + ], }, { - name: 'collectionsParamTask', - path: '/collections/:collectionId/:collectionParam/tasks/:taskId', - components: { default: Collections, AppSidebar }, - props: { default: true, AppSidebar: true }, - }, - { - name: 'calendars', path: '/calendars/:calendarId', - component: Calendar, - props: true, - }, - { - name: 'calendarsTask', - path: '/calendars/:calendarId/tasks/:taskId', - components: { default: Calendar, AppSidebar }, - props: { default: true, AppSidebar: true }, + components: { + default: { render: () => h(RouterView, { name: 'default' }) }, + AppSidebar: { render: () => h(RouterView, { name: 'AppSidebar' }) }, + }, + children: [ + { + name: 'calendars', + path: '/calendars/:calendarId', + component: Calendar, + props: true, + }, + { + name: 'calendarsTask', + path: '/calendars/:calendarId/tasks/:taskId', + components: { default: Calendar, AppSidebar }, + props: { default: true, AppSidebar: true }, + }, + ], }, ] -Vue.use(VueRouter) - -export default new VueRouter({ - linkActiveClass: 'active', - routes, // short for `routes: routes` +const router = createRouter({ + history: createWebHashHistory(), + routes, }) + +export default router diff --git a/src/store/calendars.js b/src/store/calendars.js index dc31666f..2a99940c 100644 --- a/src/store/calendars.js +++ b/src/store/calendars.js @@ -41,8 +41,6 @@ import router from '../router.js' import { detectColor, uidToHexColor } from '../utils/color.js' import { mapCDavObjectToCalendarObject } from '../models/calendarObject.js' -import Vue from 'vue' - const calendarModel = { id: '', color: '', @@ -322,10 +320,10 @@ const getters = { * @return {Calendar} The calendar by route */ getCalendarByRoute: (state, getters, rootState) => { - if (rootState.route.params.collectionId) { + if (router.currentRoute.value.params.collectionId) { return getters.getDefaultCalendar } - return getters.getCalendarById(rootState.route.params.calendarId) + return getters.getCalendarById(router.currentRoute.value.params.calendarId) }, /** @@ -511,7 +509,7 @@ const mutations = { if (list[task.uid]) { console.debug('Duplicate task overridden', list[task.uid], task) } - Vue.set(list, task.uid, task) + list[task.uid] = task return list }, calendar.tasks) @@ -524,7 +522,7 @@ const mutations = { * @param {Task} task The task to add */ addTaskToCalendar(state, task) { - Vue.set(task.calendar.tasks, task.uid, task) + task.calendar.tasks[task.uid] = task }, /** @@ -534,7 +532,7 @@ const mutations = { * @param {Task} task The task to delete */ deleteTaskFromCalendar(state, task) { - Vue.delete(task.calendar.tasks, task.uid) + delete task.calendar.tasks[task.uid] }, /** @@ -601,7 +599,7 @@ const mutations = { * @param {number} data.order The sort order */ setCalendarOrder(state, { calendar, order }) { - Vue.set(calendar, 'order', order) + calendar.order = order }, } @@ -850,7 +848,7 @@ const actions = { // so we need to parse one by one const tasks = response.map(item => { const task = new Task(item.data, calendar) - Vue.set(task, 'dav', item) + task.dav = item return task }) @@ -867,7 +865,7 @@ const actions = { if (list[task.uid]) { console.debug('Duplicate task overridden', list[task.uid], task) } - Vue.set(list, task.uid, task) + list[task.uid] = task return list }, parent.subTasks) @@ -892,7 +890,7 @@ const actions = { const parent = Object.values(calendar.tasks).find(search => search.uid === related) if (parent) { parent.loadedCompleted = true - tasks.map(task => Vue.set(parent.subTasks, task.uid, task)) + tasks.forEach(task => { parent.subTasks[task.uid] = task }) } } diff --git a/src/store/collections.js b/src/store/collections.js index de73ab7d..74259218 100644 --- a/src/store/collections.js +++ b/src/store/collections.js @@ -26,11 +26,6 @@ import { isTaskInList, searchSubTasks } from './storeHelper.js' import { generateUrl } from '@nextcloud/router' -import Vue from 'vue' -import Vuex from 'vuex' - -Vue.use(Vuex) - const state = { collections: [], } @@ -94,7 +89,7 @@ const mutations = { */ setVisibility(state, newCollection) { const collection = state.collections.find(search => search.id === newCollection.id) - Vue.set(collection, 'show', newCollection.show) + collection.show = newCollection.show }, } diff --git a/src/store/principals.js b/src/store/principals.js index 6eb5e317..dd7623a7 100644 --- a/src/store/principals.js +++ b/src/store/principals.js @@ -29,8 +29,6 @@ import client from '../services/cdav.js' import { getDefaultPrincipalObject, mapDavToPrincipal } from '../models/principal.js' -import Vue from 'vue' - const state = { principals: [], principalsById: {}, @@ -54,7 +52,7 @@ const mutations = { } state.principals.push(object) - Vue.set(state.principalsById, object.id, object) + state.principalsById[object.id] = object }, /** diff --git a/src/store/settings.js b/src/store/settings.js index 00da4c5a..c87f03d1 100644 --- a/src/store/settings.js +++ b/src/store/settings.js @@ -28,11 +28,6 @@ import Requests from '../services/requests.js' import { loadState } from '@nextcloud/initial-state' import { generateUrl } from '@nextcloud/router' -import Vue from 'vue' -import Vuex from 'vuex' - -Vue.use(Vuex) - const state = { settings: { sortOrder: 'default', diff --git a/src/store/store.js b/src/store/store.js index 1d236f3f..9ca18711 100644 --- a/src/store/store.js +++ b/src/store/store.js @@ -27,12 +27,9 @@ import tasks from './tasks.js' import settings from './settings.js' import principals from './principals.js' -import Vue from 'vue' -import Vuex, { Store } from 'vuex' +import { createStore } from 'vuex' -Vue.use(Vuex) - -export default new Store({ +export default createStore({ modules: { calendars, collections, diff --git a/src/store/tasks.js b/src/store/tasks.js index 1ad739e1..5019e55c 100644 --- a/src/store/tasks.js +++ b/src/store/tasks.js @@ -34,10 +34,6 @@ import { translate as t } from '@nextcloud/l10n' import moment from '@nextcloud/moment' import ICAL from 'ical.js' -import Vue from 'vue' -import Vuex from 'vuex' - -Vue.use(Vuex) const state = { tasks: {}, @@ -76,7 +72,7 @@ const getters = { * @return {Array<Task>} The tasks */ getTasksByRoute: (state, getters, rootState) => { - return getters.getTasksByCalendarId(rootState.route.params.calendarId) + return getters.getTasksByCalendarId(router.currentRoute.value.params.calendarId) }, /** @@ -124,17 +120,17 @@ const getters = { */ getTaskByRoute: (state, getters, rootState) => { // If a calendar is given, only search in that calendar. - if (rootState.route.params.calendarId) { - const calendar = getters.getCalendarById(rootState.route.params.calendarId) + if (router.currentRoute.value.params.calendarId) { + const calendar = getters.getCalendarById(router.currentRoute.value.params.calendarId) if (!calendar) { return null } return Object.values(calendar.tasks).find(task => { - return task.uri === rootState.route.params.taskId + return task.uri === router.currentRoute.value.params.taskId }) } // Else, we have to search all calendars - return getters.getTaskByUri(rootState.route.params.taskId) + return getters.getTaskByUri(router.currentRoute.value.params.taskId) }, /** @@ -307,7 +303,7 @@ const mutations = { appendTasks(state, tasks = []) { state.tasks = tasks.reduce(function(list, task) { if (task instanceof Task) { - Vue.set(list, task.key, task) + list[task.key] = task } else { console.error('Wrong task object', task) } @@ -322,7 +318,7 @@ const mutations = { * @param {Task} task The task to append */ appendTask(state, task) { - Vue.set(state.tasks, task.key, task) + state.tasks[task.key] = task }, /** @@ -333,7 +329,7 @@ const mutations = { */ deleteTask(state, task) { if (state.tasks[task.key] && task instanceof Task) { - Vue.delete(state.tasks, task.key) + delete state.tasks[task.key] } }, @@ -349,7 +345,7 @@ const mutations = { if (task instanceof Task) { // Remove task from parents subTask list if necessary if (task.related && parent) { - Vue.delete(parent.subTasks, task.uid) + delete parent.subTasks[task.uid] } } }, @@ -364,7 +360,7 @@ const mutations = { */ addTaskToParent(state, { task, parent }) { if (task.related && parent) { - Vue.set(parent.subTasks, task.uid, task) + parent.subTasks[task.uid] = task } }, @@ -377,7 +373,7 @@ const mutations = { * @param {number} data.complete The complete value */ setComplete(state, { task, complete }) { - Vue.set(task, 'complete', complete) + task.complete = complete }, /** @@ -388,9 +384,9 @@ const mutations = { */ toggleStarred(state, task) { if (+task.priority < 1 || +task.priority > 4) { - Vue.set(task, 'priority', 1) + task.priority = 1 } else { - Vue.set(task, 'priority', 0) + task.priority = 0 } }, @@ -401,7 +397,7 @@ const mutations = { * @param {Task} task The task */ togglePinned(state, task) { - Vue.set(task, 'pinned', !task.pinned) + task.pinned = !task.pinned }, /** @@ -411,7 +407,7 @@ const mutations = { * @param {Task} task The task */ toggleSubtasksVisibility(state, task) { - Vue.set(task, 'hideSubtasks', !task.hideSubtasks) + task.hideSubtasks = !task.hideSubtasks }, /** @@ -421,7 +417,7 @@ const mutations = { * @param {Task} task The task */ toggleCompletedSubtasksVisibility(state, task) { - Vue.set(task, 'hideCompletedSubtasks', !task.hideCompletedSubtasks) + task.hideCompletedSubtasks = !task.hideCompletedSubtasks }, /** @@ -433,7 +429,7 @@ const mutations = { * @param {string} data.summary The summary */ setSummary(state, { task, summary }) { - Vue.set(task, 'summary', summary) + task.summary = summary }, /** @@ -445,7 +441,7 @@ const mutations = { * @param {string} data.note The note */ setNote(state, { task, note }) { - Vue.set(task, 'note', note) + task.note = note }, /** @@ -457,7 +453,7 @@ const mutations = { * @param {Array} data.tags The array of tags */ setTags(state, { task, tags }) { - Vue.set(task, 'tags', tags) + task.tags = tags }, /** @@ -469,7 +465,7 @@ const mutations = { * @param {string} data.tag The tag to add */ addTag(state, { task, tag }) { - Vue.set(task, 'tags', task.tags.concat([tag])) + task.tags = task.tags.concat([tag]) }, /** @@ -481,7 +477,7 @@ const mutations = { * @param {string} data.priority The priority */ setPriority(state, { task, priority }) { - Vue.set(task, 'priority', priority) + task.priority = priority }, /** @@ -493,7 +489,7 @@ const mutations = { * @param {string} data.classification The classification */ setClassification(state, { task, classification }) { - Vue.set(task, 'class', classification) + task.class = classification }, /** @@ -505,7 +501,7 @@ const mutations = { * @param {string} data.status The status */ setStatus(state, { task, status }) { - Vue.set(task, 'status', status) + task.status = status }, /** @@ -517,7 +513,7 @@ const mutations = { * @param {number} data.order The sort order */ setSortOrder(state, { task, order }) { - Vue.set(task, 'sortOrder', order) + task.sortOrder = order }, /** @@ -532,7 +528,7 @@ const mutations = { setDue(state, { task, due, allDay }) { if (due === null) { // If the date is null, just set (remove) it. - Vue.set(task, 'due', due) + task.due = due } else { // Check, that the due date is after the start date. // If it is not, shift the start date to keep the difference between start and due equal. @@ -544,10 +540,10 @@ const mutations = { } else { start = due.clone() } - Vue.set(task, 'start', momentToICALTime(start, allDay)) + task.start = momentToICALTime(start, allDay) } // Set the due date, convert it to ICALTime first. - Vue.set(task, 'due', momentToICALTime(due, allDay)) + task.due = momentToICALTime(due, allDay) } }, @@ -563,7 +559,7 @@ const mutations = { setStart(state, { task, start, allDay }) { if (start === null) { // If the date is null, just set (remove) it. - Vue.set(task, 'start', start) + task.start = start } else { // Check, that the start date is before the due date. // If it is not, shift the due date to keep the difference between start and due equal. @@ -575,10 +571,10 @@ const mutations = { } else { due = start.clone() } - Vue.set(task, 'due', momentToICALTime(due, allDay)) + task.due = momentToICALTime(due, allDay) } // Set the due date, convert it to ICALTime first. - Vue.set(task, 'start', momentToICALTime(start, allDay)) + task.start = momentToICALTime(start, allDay) } }, @@ -589,7 +585,7 @@ const mutations = { * @param {Task} task The task */ toggleAllDay(state, task) { - Vue.set(task, 'allDay', !task.allDay) + task.allDay = !task.allDay }, /** @@ -601,7 +597,7 @@ const mutations = { * @param {Calendar} data.calendar The calendar to move the task to */ setTaskCalendar(state, { task, calendar }) { - Vue.set(task, 'calendar', calendar) + task.calendar = calendar }, /** @@ -613,7 +609,7 @@ const mutations = { * @param {string} data.related The uid of the related task */ setTaskParent(state, { task, related }) { - Vue.set(task, 'related', related) + task.related = related }, /** @@ -673,12 +669,12 @@ const mutations = { }, addTaskForDeletion(state, { task }) { - Vue.set(state.deletedTasks, task.key, task) + state.deletedTasks[task.key] = task }, clearTaskFromDeletion(state, { task }) { if (state.deletedTasks[task.key] && task instanceof Task) { - Vue.delete(state.deletedTasks, task.key) + delete state.deletedTasks[task.key] } }, @@ -691,7 +687,7 @@ const mutations = { * @param {number} data.countdown The countdown value */ setTaskDeleteCountdown(state, { task, countdown }) { - Vue.set(task, 'deleteCountdown', countdown) + task.deleteCountdown = countdown }, } @@ -713,7 +709,7 @@ const actions = { if (taskData.calendar.readOnly) { return } - const task = new Task('BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Nextcloud Tasks v' + this._vm.$appVersion + '\nEND:VCALENDAR', taskData.calendar) + const task = new Task('BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Nextcloud Tasks v' + appVersion + '\nEND:VCALENDAR', taskData.calendar) task.created = ICAL.Time.now() task.summary = taskData.summary @@ -751,7 +747,7 @@ const actions = { if (!task.dav) { const response = await task.calendar.dav.createVObject(vData) - Vue.set(task, 'dav', response) + task.dav = response task.syncStatus = new SyncStatus('success', t('tasks', 'Successfully created the task.')) context.commit('appendTask', task) context.commit('addTaskToCalendar', task) @@ -760,10 +756,10 @@ const actions = { // In case the task is created in Talk, we don't have a route // Only open the details view if there is enough space or if it is already open. - if (context.rootState.route !== undefined && (document.documentElement.clientWidth >= 768 || context.rootState.route?.params.taskId !== undefined)) { + if (router.currentRoute.value !== undefined && (document.documentElement.clientWidth >= 768 || router.currentRoute.value?.params.taskId !== undefined)) { // Open the details view for the new task - const calendarId = context.rootState.route.params.calendarId - const collectionId = context.rootState.route.params.collectionId + const calendarId = router.currentRoute.value.params.calendarId + const collectionId = router.currentRoute.value.params.collectionId if (calendarId) { router.push({ name: 'calendarsTask', params: { calendarId, taskId: task.uri } }) } else if (collectionId) { @@ -811,7 +807,7 @@ const actions = { context.commit('deleteTaskFromParent', { task, parent }) context.commit('deleteTaskFromCalendar', task) // If the task is open in the sidebar, close the sidebar - if (context.rootState.route.params.taskId === task.uri) { + if (router.currentRoute.value.params.taskId === task.uri) { emit('tasks:close-appsidebar') } // Stop the delete timeout if no tasks are scheduled for deletion anymore @@ -959,7 +955,7 @@ const actions = { const response = await calendar.dav.find(taskUri) if (response) { const task = new Task(response.data, calendar) - Vue.set(task, 'dav', response) + task.dav = response if (task.related) { let parent = context.getters.getTaskByUid(task.related) // If the parent is not found locally, we try to get it from the server. @@ -1000,7 +996,7 @@ const actions = { // We expect to only get zero or one task when we query by UID. if (response.length) { const task = new Task(response[0].data, calendar) - Vue.set(task, 'dav', response[0]) + task.dav = response[0] if (task.related) { let parent = context.getters.getTaskByUid(task.related) // If the parent is not found locally, we try to get it from the server. @@ -1377,10 +1373,10 @@ const actions = { const oldParent = context.getters.getTaskByUid(task.related) context.commit('deleteTaskFromParent', { task, parent: oldParent }) // Link to new parent - Vue.set(task, 'related', parentId) + task.related = parentId // Add task to new parents subtask list if (parent) { - Vue.set(parent.subTasks, task.uid, task) + parent.subTasks[task.uid] = task // If the parent is completed, we complete the task if (parent.completed) { await context.dispatch('setPercentComplete', { task, complete: 100 }) diff --git a/src/talk.js b/src/talk.js index 16b7daad..f7927dbe 100644 --- a/src/talk.js +++ b/src/talk.js @@ -32,23 +32,15 @@ import TaskCreateDialog from './components/TaskCreateDialog.vue' import { buildSelector } from './helpers/selector.js' import { getRequestToken } from '@nextcloud/auth' -import { translate as t, translatePlural as n } from '@nextcloud/l10n' +import { translate as t } from '@nextcloud/l10n' import { generateUrl, generateFilePath } from '@nextcloud/router' -import Vue from 'vue' - // eslint-disable-next-line __webpack_nonce__ = btoa(getRequestToken()) // eslint-disable-next-line __webpack_public_path__ = generateFilePath('tasks', '', 'js/') -Vue.prototype.t = t -Vue.prototype.n = n -Vue.prototype.$OC = OC -Vue.prototype.$OCA = OCA -Vue.prototype.$appVersion = appVersion - window.addEventListener('DOMContentLoaded', () => { if (!window.OCA?.Talk?.registerMessageAction) { return diff --git a/src/views/AppNavigation.vue b/src/views/AppNavigation.vue index a981da6c..da39abff 100644 --- a/src/views/AppNavigation.vue +++ b/src/views/AppNavigation.vue @@ -31,11 +31,11 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. :title="collection.displayName" class="collection reactive" draggable="false" - @dragstart.native="dragStart" - @drop.native="dropTaskOnCollection(...arguments, collection)" - @dragover.native="dragOver" - @dragenter.native="dragEnter(...arguments, collection)" - @dragleave.native="dragLeave" + @dragstart="dragStart" + @drop="dropTaskOnCollection(...arguments, collection)" + @dragover="dragOver" + @dragenter="dragEnter(...arguments, collection)" + @dragleave="dragLeave" @click="setInitialRoute(`/collections/${collection.id}`)"> <template #icon> <component :is="collection.icon" @@ -47,15 +47,15 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. </NcCounterBubble> </template> </NcAppNavigationItem> - <draggable class="draggable-container" + <!-- <draggable class="draggable-container" :set-data="setData" v-bind="{swapThreshold: 0.30, delay: 500, delayOnTouchOnly: true, touchStartThreshold: 3}" - @update="update"> - <ListItemCalendar v-for="calendar in calendars" - :key="calendar.id" - :calendar="calendar" - @click.native="setInitialRoute(`/calendars/${calendar.id}`)" /> - </draggable> + @update="update"> --> + <ListItemCalendar v-for="calendar in calendars" + :key="calendar.id" + :calendar="calendar" + @click="setInitialRoute(`/calendars/${calendar.id}`)" /> + <!-- </draggable> --> <NcAppNavigationItem v-click-outside="() => {creating = false}" :title="t('tasks', 'Add List…')" :class="{'collection--edit': creating}" @@ -67,6 +67,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. <li> <div class="app-navigation-entry-edit"> <NcTextField ref="newListInput" + v-model:value="newCalendarName" v-tooltip="{ content: tooltipMessage, shown: showTooltip('list_new'), @@ -75,7 +76,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. type="text" :show-trailing-button="newCalendarName !== ''" trailing-button-icon="arrowRight" - :value.sync="newCalendarName" :error="nameError" :placeholder="t('tasks', 'New List')" @trailing-button-click="create()" @@ -115,8 +115,8 @@ import Plus from 'vue-material-design-icons/Plus.vue' import Star from 'vue-material-design-icons/Star.vue' import TrendingUp from 'vue-material-design-icons/TrendingUp.vue' -import draggable from 'vuedraggable' -import ClickOutside from 'v-click-outside' +// import draggable from 'vuedraggable' +import ClickOutside from 'click-outside-vue3' import { mapState, mapGetters, mapActions } from 'vuex' export default { @@ -129,7 +129,7 @@ export default { NcCounterBubble, NcTextField, AppNavigationSettings, - draggable, + // draggable, CalendarToday, CalendarWeek, Check, @@ -142,6 +142,7 @@ export default { clickOutside: ClickOutside.directive, Tooltip, }, + inject: ['$OCA'], data() { return { editing: '', diff --git a/src/views/AppSidebar.vue b/src/views/AppSidebar.vue index 20e941e8..27ebf2c2 100644 --- a/src/views/AppSidebar.vue +++ b/src/views/AppSidebar.vue @@ -20,14 +20,14 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. --> <template> - <NcAppSidebar :title="title" + <NcAppSidebar v-model:active="activeTab" + :title="title" :title-editable="editingTitle" :linkify-title="true" :subtitle="subtitle" :title-tooltip="title" :subtitle-tooltip="subtitleTooltip" :empty="!task" - :active.sync="activeTab" @start-editing="newTitle = task.summary" @update:titleEditable="editTitle" @update:title="updateTitle" @@ -724,7 +724,7 @@ export default { subscribe('tasks:open-appsidebar-tab', this.openAppSidebarTab) subscribe('tasks:edit-appsidebar-title', this.editTitle) }, - beforeDestroy() { + beforeUnmount() { unsubscribe('tasks:close-appsidebar', this.closeAppSidebar) unsubscribe('tasks:open-appsidebar-tab', this.openAppSidebarTab) unsubscribe('tasks:edit-appsidebar-title', this.editTitle) |