mirror of https://github.com/nextcloud/calendar
chore(vue3): migrate appointment config store to pinia
Co-authored-by: Grigory V <scratchx@gmx.com> Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
This commit is contained in:
parent
c904b20114
commit
1c1e3ecc6b
|
@ -43,6 +43,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"md5": "^2.3.0",
|
||||
"p-limit": "^5.0.0",
|
||||
"pinia": "^2.1.7",
|
||||
"v-tooltip": "^2.1.3",
|
||||
"vue": "^2.7.16",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
|
@ -5690,6 +5691,11 @@
|
|||
"url": "https://opencollective.com/postcss/"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-api": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz",
|
||||
"integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA=="
|
||||
},
|
||||
"node_modules/@vue/eslint-config-typescript": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz",
|
||||
|
@ -15608,6 +15614,56 @@
|
|||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
|
||||
"integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.5.0",
|
||||
"vue-demi": ">=0.14.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.4.0",
|
||||
"typescript": ">=4.4.4",
|
||||
"vue": "^2.6.14 || ^3.3.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
},
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinia/node_modules/vue-demi": {
|
||||
"version": "0.14.7",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
|
||||
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pirates": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
|
||||
|
@ -18897,7 +18953,7 @@
|
|||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
|
||||
"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"md5": "^2.3.0",
|
||||
"p-limit": "^5.0.0",
|
||||
"pinia": "^2.1.7",
|
||||
"v-tooltip": "^2.1.3",
|
||||
"vue": "^2.7.16",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
|
|
|
@ -68,8 +68,9 @@ import PlusIcon from 'vue-material-design-icons/Plus.vue'
|
|||
import AppointmentConfigModal from '../AppointmentConfigModal.vue'
|
||||
import AppointmentConfig from '../../models/appointmentConfig.js'
|
||||
import logger from '../../utils/logger.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import NoEmailAddressWarning from '../AppointmentConfigModal/NoEmailAddressWarning.vue'
|
||||
import useAppointmentConfigStore from '../../store/appointmentConfigs.js'
|
||||
import { mapStores } from 'pinia'
|
||||
|
||||
export default {
|
||||
name: 'AppointmentConfigList',
|
||||
|
@ -87,9 +88,10 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
configs: 'allConfigs',
|
||||
}),
|
||||
...mapStores(useAppointmentConfigStore),
|
||||
configs() {
|
||||
return this.appointmentConfigStore.allConfigs
|
||||
},
|
||||
defaultConfig() {
|
||||
return AppointmentConfig.createDefault(
|
||||
this.calendarUrlToUri(this.$store.getters.ownSortedCalendars[0].url),
|
||||
|
@ -126,7 +128,7 @@ export default {
|
|||
logger.info('Deleting config', { config })
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('deleteConfig', config)
|
||||
await this.appointmentConfigStore.deleteConfig({ id: config.id })
|
||||
|
||||
logger.info('Config deleted', { config })
|
||||
} catch (error) {
|
||||
|
|
|
@ -157,6 +157,7 @@ import TextInput from './AppointmentConfigModal/TextInput.vue'
|
|||
import TextArea from './AppointmentConfigModal/TextArea.vue'
|
||||
import AppointmentConfig from '../models/appointmentConfig.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapStores } from 'pinia'
|
||||
import CalendarPicker from './Shared/CalendarPicker.vue'
|
||||
import DurationInput from './AppointmentConfigModal/DurationInput.vue'
|
||||
import NumberInput from './AppointmentConfigModal/NumberInput.vue'
|
||||
|
@ -165,6 +166,7 @@ import CheckedDurationSelect from './AppointmentConfigModal/CheckedDurationSelec
|
|||
import VisibilitySelect from './AppointmentConfigModal/VisibilitySelect.vue'
|
||||
import logger from '../utils/logger.js'
|
||||
import Confirmation from './AppointmentConfigModal/Confirmation.vue'
|
||||
import useAppointmentConfigStore from '../store/appointmentConfigs.js'
|
||||
|
||||
export default {
|
||||
name: 'AppointmentConfigModal',
|
||||
|
@ -209,6 +211,7 @@ export default {
|
|||
'ownSortedCalendars',
|
||||
'isTalkEnabled',
|
||||
]),
|
||||
...mapStores(useAppointmentConfigStore),
|
||||
formTitle() {
|
||||
if (this.isNew) {
|
||||
return this.$t('calendar', 'Create appointment')
|
||||
|
@ -309,10 +312,10 @@ export default {
|
|||
try {
|
||||
if (this.isNew) {
|
||||
logger.info('Creating new config', { config })
|
||||
this.editing = await this.$store.dispatch('createConfig', { config })
|
||||
this.editing = await this.appointmentConfigStore.createConfig({ config })
|
||||
} else {
|
||||
logger.info('Saving config', { config })
|
||||
this.editing = await this.$store.dispatch('updateConfig', { config })
|
||||
this.editing = await this.appointmentConfigStore.updateConfig({ config })
|
||||
}
|
||||
this.showConfirmation = true
|
||||
} catch (error) {
|
||||
|
|
14
src/main.js
14
src/main.js
|
@ -41,6 +41,11 @@ import ClickOutside from 'vue-click-outside'
|
|||
import VTooltip from 'v-tooltip'
|
||||
import VueShortKey from 'vue-shortkey'
|
||||
import windowTitleService from './services/windowTitleService.js'
|
||||
import { createPinia, PiniaVuePlugin } from 'pinia'
|
||||
import useAppointmentConfigsStore from './store/appointmentConfigs.js'
|
||||
|
||||
Vue.use(PiniaVuePlugin)
|
||||
const pinia = createPinia()
|
||||
|
||||
// register global components
|
||||
Vue.directive('ClickOutside', ClickOutside)
|
||||
|
@ -69,14 +74,13 @@ Vue.prototype.n = translatePlural
|
|||
|
||||
windowTitleService(router, store)
|
||||
|
||||
store.commit(
|
||||
'addInitialConfigs',
|
||||
loadState('calendar', 'appointmentConfigs', []).map(config => new AppointmentConfig(config))
|
||||
)
|
||||
|
||||
export default new Vue({
|
||||
el: '#content',
|
||||
router,
|
||||
store,
|
||||
render: h => h(App),
|
||||
pinia,
|
||||
})
|
||||
|
||||
const appointmentsConfigsStore = useAppointmentConfigsStore()
|
||||
appointmentsConfigsStore.addInitialConfigs(loadState('calendar', 'appointmentConfigs', []).map(config => new AppointmentConfig(config)))
|
||||
|
|
|
@ -21,74 +21,72 @@
|
|||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { createConfig, deleteConfig, updateConfig } from '../services/appointmentConfigService.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
const state = {
|
||||
configs: {},
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
addInitialConfigs(state, configs) {
|
||||
for (const config of configs) {
|
||||
Vue.set(state.configs, config.id, config)
|
||||
export default defineStore('appointmentConfig', {
|
||||
state: () => {
|
||||
return {
|
||||
configs: {},
|
||||
}
|
||||
},
|
||||
updateConfig(state, { config }) {
|
||||
if (!state.configs[config.id]) {
|
||||
return
|
||||
}
|
||||
getters: {
|
||||
allConfigs() {
|
||||
return Object.values(this.configs)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
addInitialConfigs(configs) {
|
||||
for (const config of configs) {
|
||||
Vue.set(this.configs, config.id, config)
|
||||
}
|
||||
},
|
||||
async updateConfig({ config }) {
|
||||
try {
|
||||
const updatedConfig = await updateConfig(config)
|
||||
this.updateConfigMutation(updatedConfig)
|
||||
return updatedConfig
|
||||
} catch (error) {
|
||||
logger.error('Failed to update config', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
async createConfig({ config }) {
|
||||
try {
|
||||
const fullConfig = await createConfig(config)
|
||||
this.addConfigMutation(fullConfig)
|
||||
return fullConfig
|
||||
} catch (error) {
|
||||
logger.error('Failed to create config', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
async deleteConfig({ id }) {
|
||||
try {
|
||||
await deleteConfig(id)
|
||||
this.deleteConfigMutation(id)
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete config', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
updateConfigMutation(config) {
|
||||
if (!this.configs[config.id]) {
|
||||
return
|
||||
}
|
||||
|
||||
Vue.set(state.configs, config.id, config.clone())
|
||||
},
|
||||
addConfig(state, { config }) {
|
||||
Vue.set(state.configs, config.id, config)
|
||||
},
|
||||
deleteConfig(state, { id }) {
|
||||
if (!state.configs[id]) {
|
||||
return
|
||||
}
|
||||
Vue.set(this.configs, config.id, config.clone())
|
||||
},
|
||||
addConfigMutation(config) {
|
||||
Vue.set(this.configs, config.id, config)
|
||||
},
|
||||
deleteConfigMutation(id) {
|
||||
if (!this.configs[id]) {
|
||||
return
|
||||
}
|
||||
|
||||
Vue.delete(state.configs, id)
|
||||
Vue.delete(this.configs, id)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const getters = {
|
||||
allConfigs(state) {
|
||||
return Object.values(state.configs)
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
async updateConfig({ commit }, { config }) {
|
||||
try {
|
||||
const updatedConfig = await updateConfig(config)
|
||||
commit('updateConfig', { config: updatedConfig })
|
||||
return updatedConfig
|
||||
} catch (error) {
|
||||
logger.error('Failed to update config', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
async createConfig({ commit }, { config }) {
|
||||
try {
|
||||
const fullConfig = await createConfig(config)
|
||||
commit('addConfig', { config: fullConfig })
|
||||
return fullConfig
|
||||
} catch (error) {
|
||||
logger.error('Failed to create config', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
async deleteConfig({ commit }, { id }) {
|
||||
try {
|
||||
await deleteConfig(id)
|
||||
commit('deleteConfig', { id })
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete config', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default { state, mutations, getters, actions }
|
||||
})
|
||||
|
|
|
@ -36,13 +36,11 @@ import importFiles from './importFiles.js'
|
|||
import importState from './importState.js'
|
||||
import principals from './principals.js'
|
||||
import settings from './settings.js'
|
||||
import appointmentConfigs from './appointmentConfigs.js'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
appointmentConfigs,
|
||||
calendarObjectInstance,
|
||||
calendarObjects,
|
||||
calendars,
|
||||
|
|
Loading…
Reference in New Issue