summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/components/Folders.vue14
-rw-r--r--app/src/components/Panel.vue92
-rw-r--r--app/src/components/Select.vue86
-rw-r--r--app/src/index.js12
-rw-r--r--app/src/mixins/dynamicModelObjectEmit.js16
-rw-r--r--app/src/pages/Steps/1-From.vue22
-rw-r--r--app/src/pages/Steps/2-To.vue57
-rw-r--r--app/src/pages/Steps/3-Migrate.vue103
-rw-r--r--app/src/router.js52
-rw-r--r--app/src/store.js49
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,
+ };
});