diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/src/components/Folders.vue | 14 | ||||
-rw-r--r-- | app/src/components/Panel.vue | 92 | ||||
-rw-r--r-- | app/src/components/Select.vue | 86 | ||||
-rw-r--r-- | app/src/index.js | 12 | ||||
-rw-r--r-- | app/src/mixins/dynamicModelObjectEmit.js | 16 | ||||
-rw-r--r-- | app/src/pages/Steps/1-From.vue | 22 | ||||
-rw-r--r-- | app/src/pages/Steps/2-To.vue | 57 | ||||
-rw-r--r-- | app/src/pages/Steps/3-Migrate.vue | 103 | ||||
-rw-r--r-- | app/src/router.js | 52 | ||||
-rw-r--r-- | app/src/store.js | 49 |
10 files changed, 212 insertions, 291 deletions
diff --git a/app/src/components/Folders.vue b/app/src/components/Folders.vue index 5c5c388..da5214d 100644 --- a/app/src/components/Folders.vue +++ b/app/src/components/Folders.vue @@ -9,15 +9,13 @@ </li> </template> -<script> -export default { - props: { - folder: { - type: Object, - required: true, - }, +<script setup> +const props = defineProps({ + folder: { + type: Object, + required: true, }, -}; +}); </script> <style lang="scss"> diff --git a/app/src/components/Panel.vue b/app/src/components/Panel.vue index eb92af7..8bd911d 100644 --- a/app/src/components/Panel.vue +++ b/app/src/components/Panel.vue @@ -7,7 +7,7 @@ <div class="grid-x"> <div class="cell"> <label> - Server <input type="text" :value="modelValue.server" required @input="emit('server', $event.target.value)"> + Server <input type="text" v-model="modelValue.server" required> </label> </div> </div> @@ -16,24 +16,23 @@ <label> Port <Select - :model-value="modelValue.port" + v-model="modelValue.port" required :options="ports" :config="{ tags: true }" - @update:modelValue="(value) => emit('port', value)" /> </label> </div> </div> <label> - Username <input type="text" :value="modelValue.username" @input="emit('username', $event.target.value)"> + Username <input type="text" v-model="modelValue.username"> </label> <label> - Passwort <input type="password" :value="modelValue.password" @input="emit('password', $event.target.value)"> + Passwort <input type="password" v-model="modelValue.password"> </label> <div class="grid-x"> <div class="cell"> - <input :id="`tls-${uid}`" type="checkbox" :checked="modelValue.tls" @input="emit('tls', $event.target.checked)"> + <input :id="`tls-${uid}`" type="checkbox" v-model="modelValue.tls"> <label :for="`tls-${uid}`">TLS enabled</label> </div> </div> @@ -43,60 +42,47 @@ </form> </template> -<script> -import Select from './Select'; -import dynamicModelObjectEmit from '~/mixins/dynamicModelObjectEmit'; +<script setup> +import { inject, onMounted, ref } from 'vue'; +import Select from '~/components/Select'; -export default { - components: { - Select, - }, +const props = defineProps(['modelValue']); +const emit = defineEmits(['update:modelValue']); - mixins: [ - dynamicModelObjectEmit, - ], +const $electron = inject('electron'); - emits: ['connect'], +const uid = crypto.getRandomValues(new Uint8Array(1)); +const apiMessage = ref({ + type: '', + msg: '', +}); - data () { - return { - uid: crypto.getRandomValues(new Uint8Array(1)), - apiMessage: { - type: '', - msg: '', - }, +const ports = ref([...new Set([ + 143, + 993, + Number(props.modelValue.port), +])].map((port) => ({ id: port, text: port }))); - ports: [...new Set([ - 143, - 993, - Number(this.modelValue.port), - ])].map((port) => ({ id: port, text: port })), - }; - }, - - mounted () { - this.$electron.ipcRenderer.on('imap:connect:reply', (event, success) => { - this.apiMessage = { - type: 'success', - msg: 'Connected!', - }; - }); +function connect() { + $electron.ipcRenderer.send('imap:connect', JSON.parse(JSON.stringify(props.modelValue))); + emit('connect'); +} - this.$electron.ipcRenderer.on('imap:connect:error', (event, error) => { - this.apiMessage = { - type: 'error', - msg: error, - }; - }); - }, +onMounted(() => { + $electron.ipcRenderer.on('imap:connect:reply', (_event, _success) => { + apiMessage.value = { + type: 'success', + msg: 'Connected!', + }; + }); - methods: { - connect () { - this.$electron.ipcRenderer.send('imap:connect', JSON.parse(JSON.stringify(this.modelValue))); - this.$emit('connect'); - }, - }, -}; + $electron.ipcRenderer.on('imap:connect:error', (_event, error) => { + apiMessage.value = { + type: 'error', + msg: error, + }; + }); +}); </script> <style lang="scss"> diff --git a/app/src/components/Select.vue b/app/src/components/Select.vue index f2d1187..0f55cca 100644 --- a/app/src/components/Select.vue +++ b/app/src/components/Select.vue @@ -1,60 +1,60 @@ <template> - <select /> + <select ref="$el" /> </template> -<script> +<script setup> +import { onMounted, onUnmounted, ref, watch } from 'vue'; import 'select2/dist/js/select2.min'; import $ from 'jquery'; -export default { - props: { - options: { - type: Array, - required: true, - }, +const props = defineProps({ + modelValue: {}, - modelValue: { - type: [Number, String], - required: true, - }, + options: { + type: Array, + required: true, + }, - config: { - type: Object, - default: () => ({}), - }, + modelValue: { + type: [Number, String], + required: true, }, - emits: ['update:modelValue'], + config: { + type: Object, + default: () => ({}), + }, +}); +const emit = defineEmits(['update:modelValue']); - watch: { - options (value) { - $(this.$el) - .empty().select2({ data: value }); - }, +const $el = ref(null); - modelValue (value) { - $(this.$el) - .val(value) - .trigger('change'); - }, - }, +onMounted(() => { + $($el.value) + .select2({ ...props.config, data: props.options }) + .val(props.modelValue) + .trigger('change') + .on('change', (event) => { + emit('update:modelValue', event.target.value); + }); +}); - mounted () { - $(this.$el) - .select2({ ...this.config, data: this.options }) - .val(this.modelValue) - .trigger('change') - .on('change', (ev) => { - this.$emit('update:modelValue', ev.target.value); - }); - }, +onUnmounted(() => { + $($el.value) + .off() + .select2('destroy'); +}); - unmounted () { - $(this.$el) - .off() - .select2('destroy'); - }, -}; +watch(() => props.options, (value) => { + $($el.value) + .empty().select2({ data: value }); +}); + +watch(() => props.modelValue, (value) => { + $($el.value) + .val(value) + .trigger('change'); +}); </script> <style lang="scss"> diff --git a/app/src/index.js b/app/src/index.js index 46dc556..6a05a8b 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -1,13 +1,13 @@ import { createApp } from 'vue'; -import router from './router'; -import store from './store'; -import App from './App'; +import { createPinia } from 'pinia'; +import { createRouter } from '~/router'; +import App from '~/App'; const app = createApp(App); -app.config.globalProperties.$electron = require('electron'); +app.provide('electron', require('electron')); -app.use(router); -app.use(store); +app.use(createRouter()); +app.use(createPinia()); app.mount('#app'); diff --git a/app/src/mixins/dynamicModelObjectEmit.js b/app/src/mixins/dynamicModelObjectEmit.js deleted file mode 100644 index 93701c8..0000000 --- a/app/src/mixins/dynamicModelObjectEmit.js +++ /dev/null @@ -1,16 +0,0 @@ -export default { - props: { - modelValue: { - type: Object, - required: true, - }, - }, - - emits: ['update:modelValue'], - - methods: { - emit (key, value) { - this.$emit('update:modelValue', { ...this.modelValue, [key]: value }); - }, - }, -}; diff --git a/app/src/pages/Steps/1-From.vue b/app/src/pages/Steps/1-From.vue index e1bd82e..c71894f 100644 --- a/app/src/pages/Steps/1-From.vue +++ b/app/src/pages/Steps/1-From.vue @@ -2,7 +2,7 @@ <div> <h1>From</h1> - <Panel v-model="from" /> + <Panel v-model="store.from" /> <router-link to="/steps/2"> next @@ -10,23 +10,9 @@ </div> </template> -<script> +<script setup> +import { useStore } from '~/store'; import Panel from '~/components/Panel'; -export default { - components: { - Panel, - }, - - computed: { - from: { - set (value) { - this.$store.commit('setFrom', value); - }, - get () { - return this.$store.state.from; - }, - }, - }, -}; +const store = useStore(); </script> diff --git a/app/src/pages/Steps/2-To.vue b/app/src/pages/Steps/2-To.vue index 1cce01d..1b0c655 100644 --- a/app/src/pages/Steps/2-To.vue +++ b/app/src/pages/Steps/2-To.vue @@ -6,7 +6,7 @@ <h1>To</h1> - <Panel v-model="to" @connect="connect" /> + <Panel v-model="store.to" @connect="connect" /> <router-link to="/steps/3"> next @@ -14,38 +14,25 @@ </div> </template> -<script>import Panel from '~/components/Panel'; - -export default { - components: { - Panel, - }, - - computed: { - to: { - set (value) { - this.$store.commit('setTo', value); - }, - get () { - return this.$store.state.to; - }, - }, - }, - - mounted () { - this.$electron.ipcRenderer.on('imap:listTree:to:reply', (event, folders) => { - this.to.folders = folders; - }); - - this.$electron.ipcRenderer.on('imap:to:error', (event, error) => { - this.to.error = error; - }); - }, - - methods: { - connect () { - this.$electron.ipcRenderer.send('imap:listTree:to', JSON.parse(JSON.stringify(this.to))); - }, - }, -}; +<script setup> +import { inject, onMounted } from 'vue'; +import { useStore } from '~/store'; +import Panel from '~/components/Panel'; + +const $electron = inject('electron'); +const store = useStore(); + +function connect() { + $electron.ipcRenderer.send('imap:listTree:to', JSON.parse(JSON.stringify(store.to))); +} + +onMounted(() => { + $electron.ipcRenderer.on('imap:listTree:to:reply', (_event, folders) => { + store.to.folders = folders; + }); + + $electron.ipcRenderer.on('imap:to:error', (_event, error) => { + store.to.error = error; + }); +}); </script> diff --git a/app/src/pages/Steps/3-Migrate.vue b/app/src/pages/Steps/3-Migrate.vue index c8d2e39..7c89f01 100644 --- a/app/src/pages/Steps/3-Migrate.vue +++ b/app/src/pages/Steps/3-Migrate.vue @@ -7,13 +7,13 @@ <div> From <div class="input-group"> - <input type="text" disabled :value="from.server"> <input type="text" disabled :value="from.port"> + <input type="text" disabled :value="store.from.server"> <input type="text" disabled :value="store.from.port"> </div> </div> <div> To <div class="input-group"> - <input type="text" disabled :value="to.server"> <input type="text" disabled :value="to.port"> + <input type="text" disabled :value="store.to.server"> <input type="text" disabled :value="store.to.port"> </div> </div> @@ -23,8 +23,13 @@ <input type="text"> </div> - <ul v-if="from.folders"> - <Folders :folder="from.folders" /> + From: + <ul v-if="store.from.folders"> + <Folders :folder="store.from.folders" /> + </ul> + To: + <ul v-if="store.to.folders"> + <Folders :folder="store.to.folders" /> </ul> <button class="button" @click="migrate"> @@ -45,67 +50,47 @@ </div> </template> -<script> +<script setup> +import { inject, onMounted, ref } from 'vue'; +import { useStore } from '~/store'; import Folders from '~/components/Folders'; -export default { - components: { - Folders, - }, +const $electron = inject('electron'); + +const store = useStore(); - data () { - return { - progress: '', - log: [], - progressMessages: '', - }; - }, +const progress = ref(''); +const log = ref([]); +const progressMessages = ref(''); - computed: { - from: { - set (value) { - this.$store.commit('setFrom', value); - }, - get () { - return this.$store.state.from; - }, - }, - to: { - set (value) { - this.$store.commit('setTo', value); - }, - get () { - return this.$store.state.to; - }, - }, - }, +async function migrate() { + progress.value = ''; + log.value = []; + progressMessages.value = ''; - mounted () { - this.$electron.ipcRenderer.on('imap:listTree:from:reply', (event, folders) => { - this.from.folders = folders; - }); - this.$electron.ipcRenderer.send('imap:listTree:from', JSON.parse(JSON.stringify(this.from))); + $electron.ipcRenderer.send('imap:migrate', JSON.parse(JSON.stringify({ + from: store.from, + to: store.to, + }))); +} - this.$electron.ipcRenderer.on('imap:migrate:progress', (event, progress) => { - this.progress = progress; - this.log.push(progress); - }); - this.$electron.ipcRenderer.on('imap:migrate:progress:messages', (event, progress) => { - this.progressMessages = progress; - }); - }, +onMounted(() => { + $electron.ipcRenderer.on('imap:listTree:from:reply', (_event, folders) => { + store.from.folders = folders; + }); + $electron.ipcRenderer.send('imap:listTree:from', JSON.parse(JSON.stringify(store.from))); - methods: { - async migrate () { - this.progress = ''; - this.log = []; - this.progressMessages = ''; + $electron.ipcRenderer.on('imap:listTree:to:reply', (_event, folders) => { + store.to.folders = folders; + }); + $electron.ipcRenderer.send('imap:listTree:to', JSON.parse(JSON.stringify(store.to))); - this.$electron.ipcRenderer.send('imap:migrate', JSON.parse(JSON.stringify({ - from: this.from, - to: this.to, - }))); - }, - }, -}; + $electron.ipcRenderer.on('imap:migrate:progress', (_event, imapProgress) => { + progress.value = imapProgress; + log.value.push(imapProgress); + }); + $electron.ipcRenderer.on('imap:migrate:progress:messages', (_event, progress) => { + progressMessages.value = progress; + }); +}); </script> diff --git a/app/src/router.js b/app/src/router.js index 93ca201..db2a284 100644 --- a/app/src/router.js +++ b/app/src/router.js @@ -1,26 +1,28 @@ -import { createRouter, createWebHashHistory } from 'vue-router'; -import Step1 from './pages/Steps/1-From'; -import Step2 from './pages/Steps/2-To'; -import Step3 from './pages/Steps/3-Migrate'; +import { createRouter as createVueRouter, createWebHashHistory } from 'vue-router'; +import Step1 from '~/pages/Steps/1-From'; +import Step2 from '~/pages/Steps/2-To'; +import Step3 from '~/pages/Steps/3-Migrate'; -export default createRouter({ - history: createWebHashHistory(), - routes: [ - { - path: '/', - redirect: '/steps/1', - }, - { - path: '/steps/1', - component: Step1, - }, - { - path: '/steps/2', - component: Step2, - }, - { - path: '/steps/3', - component: Step3, - }, - ], -}); +export function createRouter() { + return createVueRouter({ + history: createWebHashHistory(), + routes: [ + { + path: '/', + redirect: '/steps/1', + }, + { + path: '/steps/1', + component: Step1, + }, + { + path: '/steps/2', + component: Step2, + }, + { + path: '/steps/3', + component: Step3, + }, + ], + }); +}; diff --git a/app/src/store.js b/app/src/store.js index 294380c..b2fe7f1 100644 --- a/app/src/store.js +++ b/app/src/store.js @@ -1,32 +1,25 @@ -import { createStore } from 'vuex'; +import { ref } from 'vue'; +import { defineStore } from 'pinia'; -export default createStore({ - state () { - return { - from: { - server: 'localhost', - port: 3143, - username: 'from@example.org', - password: 'password', - tls: false, - }, - to: { - server: 'localhost', - port: 31432, - username: 'to@example.org', - password: 'password', - tls: false, - }, - }; - }, +export const useStore = defineStore('store', () => { + const from = ref({ + server: 'localhost', + port: 3143, + username: 'from@example.org', + password: 'password', + tls: false, + }); - mutations: { - setFrom (state, payload) { - state.from = Object.assign(state.from, payload); - }, + const to = ref({ + server: 'localhost', + port: 31432, + username: 'to@example.org', + password: 'password', + tls: false, + }); - setTo (state, payload) { - state.to = Object.assign(state.to, payload); - }, - }, + return { + from, + to, + }; }); |