From 7de1908caafe44c7384f770b3131b7b67330e1f0 Mon Sep 17 00:00:00 2001 From: Grigory V Date: Thu, 11 Jan 2024 22:10:31 +0100 Subject: [PATCH] chore: migrate from Vuex to Pinia Signed-off-by: Grigory V --- package-lock.json | 19 - package.json | 4 +- .../AppNavigationHeaderDatePicker.vue | 15 +- .../AppNavigation/AppointmentConfigList.vue | 27 +- src/components/AppNavigation/CalendarList.vue | 10 +- .../CalendarList/CalendarListItem.vue | 29 +- .../CalendarList/CalendarListNew.vue | 17 +- .../CalendarList/PublicCalendarListItem.vue | 8 +- .../AppNavigation/CalendarList/Trashbin.vue | 28 +- .../AppNavigation/EditCalendarModal.vue | 27 +- .../EditCalendarModal/PublishCalendar.vue | 7 +- .../EditCalendarModal/ShareItem.vue | 12 +- .../EditCalendarModal/SharingSearch.vue | 12 +- .../EmbedHeader/EmbedHeaderViewButtons.vue | 7 +- .../AppNavigation/EmbedTopNavigation.vue | 14 +- src/components/AppNavigation/Settings.vue | 72 +- .../Settings/ImportScreenRow.vue | 22 +- .../Settings/SettingsAttachmentsFolder.vue | 11 +- .../Settings/SettingsImportSection.vue | 45 +- .../Settings/SettingsTimezoneSelect.vue | 13 +- src/components/AppointmentConfigModal.vue | 27 +- src/components/CalendarGrid.vue | 56 +- src/components/Editor/Alarm/AlarmList.vue | 14 +- src/components/Editor/Alarm/AlarmListItem.vue | 42 +- src/components/Editor/Alarm/AlarmListNew.vue | 10 +- .../Editor/Attachments/AttachmentsList.vue | 13 +- src/components/Editor/FreeBusy/FreeBusy.vue | 16 +- .../Editor/InvitationResponseButtons.vue | 7 +- .../Editor/Invitees/InviteesList.vue | 30 +- .../Editor/Invitees/InviteesListItem.vue | 10 +- .../Editor/Invitees/OrganizerListItem.vue | 1 - .../Properties/PropertyTitleTimePicker.vue | 7 +- src/components/Editor/Repeat/Repeat.vue | 60 +- .../Editor/Repeat/RepeatEndRepeat.vue | 6 +- .../Editor/Repeat/RepeatSummary.vue | 7 +- .../Editor/Resources/ResourceList.vue | 18 +- .../Editor/Resources/ResourceListSearch.vue | 5 +- src/components/Shared/CalendarPicker.vue | 5 +- .../Shared/CalendarPickerOption.vue | 5 +- src/components/Shared/DatePicker.vue | 15 +- src/components/Shared/TimePicker.vue | 7 +- .../PublicCalendarSubscriptionPicker.vue | 9 +- src/dashboard.js | 7 +- src/fullcalendar/eventSources/eventSource.js | 18 +- src/fullcalendar/interaction/eventClick.js | 28 +- src/fullcalendar/interaction/eventDrop.js | 17 +- src/fullcalendar/interaction/eventResize.js | 14 +- src/fullcalendar/interaction/select.js | 9 +- src/fullcalendar/localization/momentPlugin.js | 30 +- src/main.js | 9 +- src/mixins/EditorMixin.js | 91 +- src/reference.js | 8 +- src/services/windowTitleService.js | 18 +- src/store/appointmentConfigs.js | 13 +- src/store/calendarObjectInstance.js | 3729 ++++++++--------- src/store/calendarObjects.js | 679 ++- src/store/calendars.js | 1937 ++++----- src/store/contacts.js | 94 +- src/store/davRestrictions.js | 37 +- src/store/fetchedTimeRanges.js | 419 +- src/store/importFiles.js | 118 +- src/store/importState.js | 84 +- src/store/index.js | 36 - src/store/principals.js | 270 +- src/store/settings.js | 772 ++-- src/store/widget.js | 61 + src/views/Calendar.vue | 61 +- src/views/Dashboard.vue | 29 +- src/views/EditSidebar.vue | 32 +- src/views/EditSimple.vue | 21 +- .../eventSources/eventSource.test.js | 161 +- .../interaction/eventClick.test.js | 66 +- .../interaction/eventDrop.test.js | 226 +- .../interaction/eventResize.test.js | 158 +- .../fullcalendar/interaction/select.test.js | 60 +- .../unit/services/windowTitleService.test.js | 49 +- tests/javascript/unit/store/contacts.test.js | 45 +- .../unit/store/davRestrictions.test.js | 23 +- .../javascript/unit/store/importFiles.test.js | 43 +- .../javascript/unit/store/importState.test.js | 69 +- tests/javascript/unit/store/settings.test.js | 440 +- 81 files changed, 5131 insertions(+), 5619 deletions(-) delete mode 100644 src/store/index.js create mode 100644 src/store/widget.js diff --git a/package-lock.json b/package-lock.json index 2f8ffbe22..82f24d30d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,8 +51,6 @@ "vue-router": "^3.6.5", "vue-shortkey": "^3.1.7", "vuedraggable": "^2.24.3", - "vuex": "^3.6.2", - "vuex-router-sync": "^5.0.0", "webdav": "^5.6.0" }, "devDependencies": { @@ -19693,23 +19691,6 @@ "sortablejs": "1.10.2" } }, - "node_modules/vuex": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", - "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==", - "peerDependencies": { - "vue": "^2.0.0" - } - }, - "node_modules/vuex-router-sync": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/vuex-router-sync/-/vuex-router-sync-5.0.0.tgz", - "integrity": "sha512-Mry2sO4kiAG64714X1CFpTA/shUH1DmkZ26DFDtwoM/yyx6OtMrc+MxrU+7vvbNLO9LSpgwkiJ8W+rlmRtsM+w==", - "peerDependencies": { - "vue-router": "^3.0.0", - "vuex": "^3.0.0" - } - }, "node_modules/w3c-xmlserializer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", diff --git a/package.json b/package.json index 91820c671..e5b5f3e2d 100644 --- a/package.json +++ b/package.json @@ -78,8 +78,6 @@ "vue-router": "^3.6.5", "vue-shortkey": "^3.1.7", "vuedraggable": "^2.24.3", - "vuex": "^3.6.2", - "vuex-router-sync": "^5.0.0", "webdav": "^5.6.0" }, "browserslist": [ @@ -140,7 +138,7 @@ "clover" ], "transformIgnorePatterns": [ - "/node_modules/(?!(@fullcalendar|uuid|webdav)).+\\.js$" + "/node_modules/(?!(@fullcalendar|uuid|webdav|p-limit|yocto-queue)).+\\.js$" ], "setupFilesAfterEnv": [ "./tests/javascript/jest.setup.js", diff --git a/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue b/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue index 146b6441c..85f15017c 100644 --- a/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue +++ b/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue @@ -51,12 +51,14 @@ import { getDateFromFirstdayParam, modifyDate, } from '../../../utils/date.js' -import { mapState } from 'vuex' +import { mapState, mapStores } from 'pinia' import formatDateRange from '../../../filters/dateRangeFormat.js' import DatePicker from '../../Shared/DatePicker.vue' import ChevronLeftIcon from 'vue-material-design-icons/ChevronLeft.vue' import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue' import { NcButton } from '@nextcloud/vue' +import useSettingsStore from '../../../store/settings.js' +import useWidgetStore from '../../../store/widget.js' export default { name: 'AppNavigationHeaderDatePicker', @@ -81,12 +83,13 @@ export default { } }, computed: { - ...mapState({ - locale: (state) => state.settings.momentLocale, + ...mapStores(useWidgetStore), + ...mapState(useSettingsStore, { + locale: 'momentLocale', }), selectedDate() { if (this.isWidget) { - return getDateFromFirstdayParam(this.$store.getters.widgetDate) + return getDateFromFirstdayParam(this.widgetStore.widgetDate) } return getDateFromFirstdayParam(this.$route.params?.firstDay ?? 'now') }, @@ -136,7 +139,7 @@ export default { }, view() { if (this.isWidget) { - return this.$store.getters.widgetView + return this.widgetStore.widgetView } return this.$route.params.view }, @@ -190,7 +193,7 @@ export default { }, navigateToDate(date) { if (this.isWidget) { - this.$store.commit('setWidgetDate', { widgetDate: getYYYYMMDDFromDate(date) }) + this.widgetStore.setWidgetDate({ widgetDate: getYYYYMMDDFromDate(date) }) } else { const name = this.$route.name const params = Object.assign({}, this.$route.params, { diff --git a/src/components/AppNavigation/AppointmentConfigList.vue b/src/components/AppNavigation/AppointmentConfigList.vue index 3280ab701..062dd5c7b 100644 --- a/src/components/AppNavigation/AppointmentConfigList.vue +++ b/src/components/AppNavigation/AppointmentConfigList.vue @@ -52,8 +52,11 @@ import AppointmentConfigModal from '../AppointmentConfigModal.vue' import AppointmentConfig from '../../models/appointmentConfig.js' import logger from '../../utils/logger.js' import NoEmailAddressWarning from '../AppointmentConfigModal/NoEmailAddressWarning.vue' -import useAppointmentConfigStore from '../../store/appointmentConfigs.js' -import { mapStores } from 'pinia' +import useAppointmentConfigsStore from '../../store/appointmentConfigs.js' +import usePrincipalsStore from '../../store/principals.js' +import useCalendarsStore from '../../store/calendars.js' +import useSettingsStore from '../../store/settings.js' +import { mapStores, mapState } from 'pinia' export default { name: 'AppointmentConfigList', @@ -71,22 +74,22 @@ export default { } }, computed: { - ...mapStores(useAppointmentConfigStore), - configs() { - return this.appointmentConfigStore.allConfigs - }, + ...mapStores(useAppointmentConfigsStore, usePrincipalsStore, useCalendarsStore, useSettingsStore), + ...mapState(useAppointmentConfigsStore, { + configs: (state) => state.allConfigs, + }), defaultConfig() { return AppointmentConfig.createDefault( - this.calendarUrlToUri(this.$store.getters.ownSortedCalendars[0].url), - this.$store.getters.scheduleInbox, - this.$store.getters.getResolvedTimezone, + this.calendarUrlToUri(this.calendarsStore.ownSortedCalendars[0].url), + this.calendarsStore.scheduleInbox, + this.settingsStore.getResolvedTimezone, ) }, hasAtLeastOneCalendar() { - return !!this.$store.getters.ownSortedCalendars[0] + return !!this.calendarsStore.ownSortedCalendars[0] }, hasUserEmailAddress() { - const principal = this.$store.getters.getCurrentUserPrincipal + const principal = this.principalsStore.getCurrentUserPrincipal if (!principal) { return false } @@ -111,7 +114,7 @@ export default { logger.info('Deleting config', { config }) try { - await this.appointmentConfigStore.deleteConfig({ id: config.id }) + await this.appointmentConfigsStore.deleteConfig({ id: config.id }) logger.info('Config deleted', { config }) } catch (error) { diff --git a/src/components/AppNavigation/CalendarList.vue b/src/components/AppNavigation/CalendarList.vue index a1b3ed69d..f52fd64ae 100644 --- a/src/components/AppNavigation/CalendarList.vue +++ b/src/components/AppNavigation/CalendarList.vue @@ -33,9 +33,10 @@ import PublicCalendarListItem from './CalendarList/PublicCalendarListItem.vue' import CalendarListItemLoadingPlaceholder from './CalendarList/CalendarListItemLoadingPlaceholder.vue' import draggable from 'vuedraggable' import debounce from 'debounce' -import { mapGetters } from 'vuex' import { showError } from '@nextcloud/dialogs' import pLimit from 'p-limit' +import { mapStores, mapState } from 'pinia' +import useCalendarsStore from '../../store/calendars.js' const limit = pLimit(1) @@ -64,7 +65,8 @@ export default { } }, computed: { - ...mapGetters({ + ...mapStores(useCalendarsStore), + ...mapState(useCalendarsStore, { serverCalendars: 'sortedCalendarsSubscriptions', }), loadingKeyCalendars() { @@ -85,11 +87,11 @@ export default { }, {}) try { - await limit(() => this.$store.dispatch('updateCalendarListOrder', { newOrder })) + await limit(() => this.calendarsStore.updateCalendarListOrder({ newOrder })) } catch (err) { showError(this.$t('calendar', 'Could not update calendar order.')) // Reset calendar list order on error - this.calendars = this.serverCalendars + this.calendars = this.calendarsStore.sortedCalendarsSubscriptions } finally { this.disableDragging = false } diff --git a/src/components/AppNavigation/CalendarList/CalendarListItem.vue b/src/components/AppNavigation/CalendarList/CalendarListItem.vue index 2507284ef..af8e1a383 100644 --- a/src/components/AppNavigation/CalendarList/CalendarListItem.vue +++ b/src/components/AppNavigation/CalendarList/CalendarListItem.vue @@ -87,6 +87,9 @@ import CheckboxBlankCircleOutline from 'vue-material-design-icons/CheckboxBlankC import Pencil from 'vue-material-design-icons/Pencil.vue' import Undo from 'vue-material-design-icons/Undo.vue' import LinkVariant from 'vue-material-design-icons/LinkVariant.vue' +import usePrincipalsStore from '../../../store/principals.js' +import useCalendarsStore from '../../../store/calendars.js' +import { mapStores } from 'pinia' export default { name: 'CalendarListItem', @@ -115,6 +118,7 @@ export default { } }, computed: { + ...mapStores(usePrincipalsStore, useCalendarsStore), /** * Whether to show the sharing section * @@ -151,10 +155,10 @@ export default { * @return {boolean} */ loadedOwnerPrincipal() { - return this.$store.getters.getPrincipalByUrl(this.calendar.owner) !== undefined + return this.principalsStore.getPrincipalByUrl(this.calendar.owner) !== undefined }, ownerUserId() { - const principal = this.$store.getters.getPrincipalByUrl(this.calendar.owner) + const principal = this.principalsStore.getPrincipalByUrl(this.calendar.owner) if (principal) { return principal.userId } @@ -162,7 +166,7 @@ export default { return '' }, ownerDisplayname() { - const principal = this.$store.getters.getPrincipalByUrl(this.calendar.owner) + const principal = this.principalsStore.getPrincipalByUrl(this.calendar.owner) if (principal) { return principal.displayname } @@ -206,28 +210,27 @@ export default { /** * Toggles the enabled state of this calendar */ - toggleEnabled() { - this.$store.dispatch('toggleCalendarEnabled', { calendar: this.calendar }) - .catch((error) => { - showError(this.$t('calendar', 'An error occurred, unable to change visibility of the calendar.')) - console.error(error) - }) + async toggleEnabled() { + try { + await this.calendarsStore.toggleCalendarEnabled({ calendar: this.calendar }) + } catch (error) { + showError(this.$t('calendar', 'An error occurred, unable to change visibility of the calendar.')) + console.error(error) + } }, /** * Cancels the deletion of a calendar */ cancelDeleteCalendar() { - this.$store.dispatch('cancelCalendarDeletion', { calendar: this.calendar }) + this.calendarsStore.cancelCalendarDeletion({ calendar: this.calendar }) }, /** * Open the calendar modal for this calendar item. */ showEditModal() { - this.$store.commit('showEditCalendarModal', { - calendarId: this.calendar.id, - }) + this.calendarsStore.editCalendarModal = { calendarId: this.calendar.id } }, }, } diff --git a/src/components/AppNavigation/CalendarList/CalendarListNew.vue b/src/components/AppNavigation/CalendarList/CalendarListNew.vue index 41c7fa320..e40175afd 100644 --- a/src/components/AppNavigation/CalendarList/CalendarListNew.vue +++ b/src/components/AppNavigation/CalendarList/CalendarListNew.vue @@ -115,7 +115,9 @@ import CalendarCheck from 'vue-material-design-icons/CalendarCheck.vue' import LinkVariant from 'vue-material-design-icons/LinkVariant.vue' import Plus from 'vue-material-design-icons/Plus.vue' import Web from 'vue-material-design-icons/Web.vue' -import { mapState } from 'vuex' +import { mapStores, mapState } from 'pinia' +import useCalendarsStore from '../../../store/calendars.js' +import useSettingsStore from '../../../store/settings.js' export default { name: 'CalendarListNew', @@ -153,10 +155,11 @@ export default { } }, computed: { - ...mapState({ - canSubscribeLink: state => state.settings.canSubscribeLink, - hasPublicCalendars: state => Boolean(state.settings.publicCalendars), + ...mapState(useSettingsStore, { + canSubscribeLink: 'canSubscribeLink', + hasPublicCalendars: store => Boolean(store.publicCalendars), }), + ...mapStores(useCalendarsStore), }, watch: { isOpen() { @@ -228,7 +231,7 @@ export default { const displayName = event.target.querySelector('input[type=text]').value try { - await this.$store.dispatch('appendCalendar', { + await this.calendarsStore.appendCalendar({ displayName, color: uidToHexColor(displayName), }) @@ -254,7 +257,7 @@ export default { const displayName = event.target.querySelector('input[type=text]').value try { - await this.$store.dispatch('appendCalendar', { + await this.calendarsStore.appendCalendar({ displayName, color: uidToHexColor(displayName), components: ['VEVENT', 'VTODO'], @@ -291,7 +294,7 @@ export default { } try { - await this.$store.dispatch('appendSubscription', { + await this.calendarsStore.appendSubscription({ displayName: hostname, color: uidToHexColor(link), source: link, diff --git a/src/components/AppNavigation/CalendarList/PublicCalendarListItem.vue b/src/components/AppNavigation/CalendarList/PublicCalendarListItem.vue index 2edc1bc7e..dde60f693 100644 --- a/src/components/AppNavigation/CalendarList/PublicCalendarListItem.vue +++ b/src/components/AppNavigation/CalendarList/PublicCalendarListItem.vue @@ -77,6 +77,8 @@ import { import Download from 'vue-material-design-icons/Download.vue' import LinkVariant from 'vue-material-design-icons/LinkVariant.vue' +import useCalendarsStore from '../../../store/calendars.js' +import { mapStores } from 'pinia' export default { name: 'PublicCalendarListItem', @@ -108,6 +110,7 @@ export default { } }, computed: { + ...mapStores(useCalendarsStore), /** * Download url of the calendar * @@ -177,9 +180,10 @@ export default { }, 2000) } }, - toggleEnabled() { - this.$store.commit('toggleCalendarEnabled', { + async toggleEnabled() { + await this.calendarsStore.toggleCalendarEnabled({ calendar: this.calendar, + updateDav: false, }) }, }, diff --git a/src/components/AppNavigation/CalendarList/Trashbin.vue b/src/components/AppNavigation/CalendarList/Trashbin.vue index 14b6e81d7..827aac8ed 100644 --- a/src/components/AppNavigation/CalendarList/Trashbin.vue +++ b/src/components/AppNavigation/CalendarList/Trashbin.vue @@ -104,9 +104,11 @@ import { import moment from '@nextcloud/moment' import logger from '../../../utils/logger.js' import { showError } from '@nextcloud/dialogs' -import { mapGetters } from 'vuex' import Moment from './Moment.vue' import { uidToHexColor } from '../../../utils/color.js' +import useCalendarsStore from '../../../store/calendars.js' +import useSettingsStore from '../../../store/settings.js' +import { mapStores, mapState } from 'pinia' import Delete from 'vue-material-design-icons/Delete.vue' @@ -129,15 +131,15 @@ export default { } }, computed: { - ...mapGetters({ - trashBin: 'trashBin', + ...mapStores(useCalendarsStore), + ...mapState(useSettingsStore, { timezoneObject: 'getResolvedTimezoneObject', }), calendars() { - return this.$store.getters.sortedDeletedCalendars + return this.calendarsStore.sortedDeletedCalendars }, objects() { - return this.$store.getters.deletedCalendarObjects + return this.calendarsStore.allDeletedCalendarObjects }, items() { const formattedCalendars = this.calendars.map(calendar => ({ @@ -185,7 +187,7 @@ export default { }, retentionDuration() { return Math.ceil( - this.trashBin.retentionDuration / (60 * 60 * 24), + this.calendarsStore.trashBin.retentionDuration / (60 * 60 * 24) ) }, }, @@ -196,8 +198,8 @@ export default { this.loading = true try { await Promise.all([ - this.$store.dispatch('loadDeletedCalendars'), - this.$store.dispatch('loadDeletedCalendarObjects'), + this.calendarsStore.loadDeletedCalendars(), + this.calendarsStore.loadDeletedCalendarObjects(), ]) logger.debug('deleted calendars and objects loaded', { @@ -218,10 +220,10 @@ export default { try { switch (item.type) { case 'calendar': - await this.$store.dispatch('deleteCalendarPermanently', { calendar: item.calendar }) + await this.calendarsStore.deleteCalendarPermanently({ calendar: item.calendar }) break case 'object': - await this.$store.dispatch('deleteCalendarObjectPermanently', { vobject: item.vobject }) + await this.calendarsStore.deleteCalendarObjectPermanently({ vobject: item.vobject }) break } } catch (error) { @@ -235,11 +237,11 @@ export default { try { switch (item.type) { case 'calendar': - await this.$store.dispatch('restoreCalendar', { calendar: item.calendar }) - this.$store.dispatch('loadCollections') + await this.calendarsStore.restoreCalendar({ calendar: item.calendar }) + await this.calendarsStore.loadCollections() break case 'object': - await this.$store.dispatch('restoreCalendarObject', { vobject: item.vobject }) + await this.calendarsStore.restoreCalendarObject({ vobject: item.vobject }) break } } catch (error) { diff --git a/src/components/AppNavigation/EditCalendarModal.vue b/src/components/AppNavigation/EditCalendarModal.vue index 5229747e7..5bfb8cc6f 100644 --- a/src/components/AppNavigation/EditCalendarModal.vue +++ b/src/components/AppNavigation/EditCalendarModal.vue @@ -4,7 +4,7 @@ -->