Add File migrator

This commit is contained in:
kolaente 2021-09-03 21:34:17 +02:00
parent af4a99dd24
commit 3fe6d1298d
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
5 changed files with 105 additions and 12 deletions

View File

@ -1,16 +1,34 @@
<template>
<div class="content">
<h1>{{ $t('migrate.titleService', { name: name }) }}</h1>
<h1>{{ $t('migrate.titleService', {name: name}) }}</h1>
<p>{{ $t('migrate.descriptionDo') }}</p>
<template v-if="isMigrating === false && message === '' && lastMigrationDate === null">
<p>{{ $t('migrate.authorize', {name: name}) }}</p>
<x-button
:loading="migrationService.loading"
:disabled="migrationService.loading"
:href="authUrl"
>
{{ $t('migrate.getStarted') }}
</x-button>
<template v-if="isFileMigrator">
<p>{{ $t('migrate.importUpload', {name: name}) }}</p>
<input
@change="migrate"
class="is-hidden"
ref="uploadInput"
type="file"
/>
<x-button
:loading="migrationService.loading"
:disabled="migrationService.loading"
@click="$refs.uploadInput.click()"
>
{{ $t('migrate.upload') }}
</x-button>
</template>
<template v-else>
<p>{{ $t('migrate.authorize', {name: name}) }}</p>
<x-button
:loading="migrationService.loading"
:disabled="migrationService.loading"
:href="authUrl"
>
{{ $t('migrate.getStarted') }}
</x-button>
</template>
</template>
<div
class="migration-in-progress-container"
@ -33,7 +51,7 @@
</div>
<div v-else-if="lastMigrationDate">
<p>
{{ $t('migrate.alreadyMigrated1', { name: name, date: formatDate(lastMigrationDate) }) }}<br/>
{{ $t('migrate.alreadyMigrated1', {name: name, date: formatDate(lastMigrationDate)}) }}<br/>
{{ $t('migrate.alreadyMigrated2') }}
</p>
<div class="buttons">
@ -54,6 +72,7 @@
<script>
import AbstractMigrationService from '../../services/migrator/abstractMigration'
import AbstractMigrationFileService from '../../services/migrator/abstractMigrationFile'
export default {
name: 'migration',
@ -75,11 +94,21 @@ export default {
type: String,
required: true,
},
isFileMigrator: {
type: Boolean,
default: false,
},
},
created() {
this.message = ''
if (this.isFileMigrator) {
this.migrationService = new AbstractMigrationFileService(this.identifier)
return
}
this.migrationService = new AbstractMigrationService(this.identifier)
this.getAuthUrl()
this.message = ''
if (typeof this.$route.query.code !== 'undefined' || location.hash.startsWith('#token=')) {
if (location.hash.startsWith('#token=')) {
@ -122,6 +151,11 @@ export default {
this.isMigrating = true
this.lastMigrationDate = null
this.message = ''
if (this.isFileMigrator) {
return this.migrateFile()
}
this.migrationService.migrate({code: this.migratorAuthCode})
.then(r => {
this.message = r.message
@ -134,6 +168,23 @@ export default {
this.isMigrating = false
})
},
migrateFile() {
if (this.$refs.uploadInput.files.length === 0) {
return
}
this.migrationService.migrate(this.$refs.uploadInput.files[0])
.then(r => {
this.message = r.message
this.$store.dispatch('namespaces/loadNamespaces')
})
.catch(e => {
this.error(e)
})
.finally(() => {
this.isMigrating = false
})
},
},
}
</script>

View File

@ -371,7 +371,9 @@
"inProgress": "Importing in progress…",
"alreadyMigrated1": "It looks like you've already imported your stuff from {name} at {date}.",
"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.",
"upload": "Upload file"
},
"label": {
"title": "Labels",

View File

@ -487,6 +487,8 @@ export default class AbstractService {
* @returns {Q.Promise<unknown>}
*/
uploadFormData(url, formData) {
console.log(formData, formData._boundary)
const cancel = this.setLoading()
return this.http.put(
url,

View File

@ -0,0 +1,31 @@
import AbstractService from '../abstractService'
// This service builds on top of the abstract service and basically just hides away method names.
// It enables migration services to be created with minimal overhead and even better method names.
export default class AbstractMigrationFileService extends AbstractService {
serviceUrlKey = ''
constructor(serviceUrlKey) {
super({
create: '/migration/' + serviceUrlKey + '/migrate',
})
this.serviceUrlKey = serviceUrlKey
}
getStatus() {
return this.getM('/migration/' + this.serviceUrlKey + '/status')
}
useCreateInterceptor() {
return false
}
migrate(file) {
console.log(file)
return this.uploadFile(
this.paths.create,
file,
'import',
)
}
}

View File

@ -2,6 +2,7 @@
<migration
:identifier="identifier"
:name="name"
:is-file-migrator="isFileMigrator"
/>
</template>
@ -18,6 +19,7 @@ export default {
return {
name: '',
identifier: '',
isFileMigrator: false,
}
},
mounted() {
@ -41,6 +43,11 @@ export default {
this.name = 'Microsoft Todo'
this.identifier = 'microsoft-todo'
break
case 'vikunja-file':
this.name = 'Vikunja Export'
this.identifier = 'vikunja-file'
this.isFileMigrator = true
break
default:
router.push({name: '404'})
}