feat(migration): proper wording for async migration
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
kolaente 2023-11-09 00:14:37 +01:00
parent 29e128c64c
commit 59a7360608
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
2 changed files with 44 additions and 17 deletions

View File

@ -6,6 +6,7 @@
"welcomeEvening": "Good Evening {username}!", "welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed", "lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.", "addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": { "project": {
"importText": "Import your projects and tasks from other services into Vikunja:", "importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja" "import": "Import your data into Vikunja"
@ -424,7 +425,9 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?", "alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!", "confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.", "importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file" "upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
}, },
"label": { "label": {
"title": "Labels", "title": "Labels",

View File

@ -3,7 +3,7 @@
<h1>{{ $t('migrate.titleService', {name: migrator.name}) }}</h1> <h1>{{ $t('migrate.titleService', {name: migrator.name}) }}</h1>
<p>{{ $t('migrate.descriptionDo') }}</p> <p>{{ $t('migrate.descriptionDo') }}</p>
<template v-if="message === '' && lastMigrationDate === null"> <template v-if="message === '' && lastMigrationFinishedAt === null">
<template v-if="isMigrating === false"> <template v-if="isMigrating === false">
<template v-if="migrator.isFileMigrator"> <template v-if="migrator.isFileMigrator">
<p>{{ $t('migrate.importUpload', {name: migrator.name}) }}</p> <p>{{ $t('migrate.importUpload', {name: migrator.name}) }}</p>
@ -46,21 +46,35 @@
<p>{{ $t('migrate.inProgress') }}</p> <p>{{ $t('migrate.inProgress') }}</p>
</div> </div>
</template> </template>
<div v-else-if="lastMigrationDate"> <div v-else-if="lastMigrationStartedAt && lastMigrationFinishedAt === null">
<p> <p>
{{ $t('migrate.alreadyMigrated1', {name: migrator.name, date: formatDateLong(lastMigrationDate)}) }}<br/> {{ $t('migrate.migrationInProgress') }}
</p>
<x-button :to="{name: 'home'}">{{ $t('home.goToOverview') }}</x-button>
</div>
<div v-else-if="lastMigrationFinishedAt">
<p>
{{
$t('migrate.alreadyMigrated1', {name: migrator.name, date: formatDateLong(lastMigrationFinishedAt)})
}}<br/>
{{ $t('migrate.alreadyMigrated2') }} {{ $t('migrate.alreadyMigrated2') }}
</p> </p>
<div class="buttons"> <div class="buttons">
<x-button @click="migrate">{{ $t('migrate.confirm') }}</x-button> <x-button @click="migrate">{{ $t('migrate.confirm') }}</x-button>
<x-button :to="{name: 'home'}" variant="tertiary" class="has-text-danger">{{ $t('misc.cancel') }}</x-button> <x-button :to="{name: 'home'}" variant="tertiary" class="has-text-danger">
{{ $t('misc.cancel') }}
</x-button>
</div> </div>
</div> </div>
<div v-else> <div v-else>
<Message class="mb-4"> <Message class="mb-4" v-if="migrator.isFileMigrator">
{{ message }} {{ message }}
</Message> </Message>
<x-button :to="{name: 'home'}">{{ $t('misc.refresh') }}</x-button> <Message class="mb-4" v-else>
{{ $t('migrate.migrationStartedWillReciveEmail', {service: migrator.name}) }}
</Message>
<x-button :to="{name: 'home'}">{{ $t('home.goToOverview') }}</x-button>
</div> </div>
</div> </div>
</template> </template>
@ -82,13 +96,13 @@ import {useI18n} from 'vue-i18n'
import Logo from '@/assets/logo.svg?component' import Logo from '@/assets/logo.svg?component'
import Message from '@/components/misc/message.vue' import Message from '@/components/misc/message.vue'
import AbstractMigrationService, { type MigrationConfig } from '@/services/migrator/abstractMigration' import AbstractMigrationService, {type MigrationConfig} from '@/services/migrator/abstractMigration'
import AbstractMigrationFileService from '@/services/migrator/abstractMigrationFile' import AbstractMigrationFileService from '@/services/migrator/abstractMigrationFile'
import {formatDateLong} from '@/helpers/time/formatDate' import {formatDateLong} from '@/helpers/time/formatDate'
import {parseDateOrNull} from '@/helpers/parseDateOrNull' import {parseDateOrNull} from '@/helpers/parseDateOrNull'
import {MIGRATORS} from './migrators' import {MIGRATORS, Migrator} from './migrators'
import {useTitle} from '@/composables/useTitle' import {useTitle} from '@/composables/useTitle'
import {useProjectStore} from '@/stores/projects' import {useProjectStore} from '@/stores/projects'
@ -104,11 +118,12 @@ const {t} = useI18n({useScope: 'global'})
const progressDotsCount = ref(PROGRESS_DOTS_COUNT) const progressDotsCount = ref(PROGRESS_DOTS_COUNT)
const authUrl = ref('') const authUrl = ref('')
const isMigrating = ref(false) const isMigrating = ref(false)
const lastMigrationDate = ref<Date | null>(null) const lastMigrationFinishedAt = ref<Date | null>(null)
const lastMigrationStartedAt = ref<Date | null>(null)
const message = ref('') const message = ref('')
const migratorAuthCode = ref('') const migratorAuthCode = ref('')
const migrator = computed(() => MIGRATORS[props.service]) const migrator = computed<Migrator>(() => MIGRATORS[props.service])
const migrationService = shallowReactive(new AbstractMigrationService(migrator.value.id)) const migrationService = shallowReactive(new AbstractMigrationService(migrator.value.id))
const migrationFileService = shallowReactive(new AbstractMigrationFileService(migrator.value.id)) const migrationFileService = shallowReactive(new AbstractMigrationFileService(migrator.value.id))
@ -130,23 +145,32 @@ async function initMigration() {
if (!migratorAuthCode.value) { if (!migratorAuthCode.value) {
return return
} }
const {time} = await migrationService.getStatus() const {startedAt, finishedAt} = await migrationService.getStatus()
if (time) { if (startedAt) {
lastMigrationDate.value = parseDateOrNull(time) lastMigrationStartedAt.value = parseDateOrNull(startedAt)
}
if (lastMigrationDate.value) { if (finishedAt) {
lastMigrationFinishedAt.value = parseDateOrNull(finishedAt)
if (lastMigrationFinishedAt.value) {
return return
} }
} }
if (lastMigrationStartedAt.value && lastMigrationFinishedAt.value === null) {
// Migration already in progress
return
}
await migrate() await migrate()
} }
initMigration() initMigration()
const uploadInput = ref<HTMLInputElement | null>(null) const uploadInput = ref<HTMLInputElement | null>(null)
async function migrate() { async function migrate() {
isMigrating.value = true isMigrating.value = true
lastMigrationDate.value = null lastMigrationFinishedAt.value = null
message.value = '' message.value = ''
let migrationConfig: MigrationConfig | File = {code: migratorAuthCode.value} let migrationConfig: MigrationConfig | File = {code: migratorAuthCode.value}