diff --git a/public/images/migration/wunderlist.png b/public/images/migration/wunderlist.png new file mode 100644 index 000000000..907ed0ca1 Binary files /dev/null and b/public/images/migration/wunderlist.png differ diff --git a/src/components/Home.vue b/src/components/Home.vue index 4c4152eef..378b21420 100644 --- a/src/components/Home.vue +++ b/src/components/Home.vue @@ -2,6 +2,7 @@

Hi {{user.infos.username}}!

Click on a list or namespace on the left to get started.

+ Import your data into Vikunja
diff --git a/src/components/migrator/migrate.vue b/src/components/migrator/migrate.vue new file mode 100644 index 000000000..f3b10288f --- /dev/null +++ b/src/components/migrator/migrate.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/migrator/wunderlist.vue b/src/components/migrator/wunderlist.vue new file mode 100644 index 000000000..3014e1d41 --- /dev/null +++ b/src/components/migrator/wunderlist.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/router/index.js b/src/router/index.js index c6c73f8b3..cc1374e49 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -23,6 +23,9 @@ import EditTeamComponent from '@/components/teams/EditTeam' import NewTeamComponent from '@/components/teams/NewTeam' // Label Handling import ListLabelsComponent from '@/components/labels/ListLabels' +// Migration +import MigrationComponent from '../components/migrator/migrate' +import WunderlistMigrationComponent from '../components/migrator/wunderlist' Vue.use(Router) @@ -135,5 +138,15 @@ export default new Router({ name: 'linkShareAuth', component: LinkShareAuthComponent }, + { + path: '/migrate', + name: 'migrateStart', + component: MigrationComponent, + }, + { + path: '/migrate/wunderlist', + name: 'migrateWunderlist', + component: WunderlistMigrationComponent, + }, ] }) \ No newline at end of file diff --git a/src/services/migrator/abstractMigrationService.js b/src/services/migrator/abstractMigrationService.js new file mode 100644 index 000000000..0e17d1b61 --- /dev/null +++ b/src/services/migrator/abstractMigrationService.js @@ -0,0 +1,20 @@ +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 AbstractMigrationService extends AbstractService { + constructor(serviceUrlKey) { + super({ + update: '/migration/'+serviceUrlKey+'/migrate', + get: '/migration/'+serviceUrlKey+'/auth', + }) + } + + getAuthUrl() { + return this.get({}) + } + + migrate(data) { + return this.update(data) + } +} \ No newline at end of file diff --git a/src/services/migrator/wunderlist.js b/src/services/migrator/wunderlist.js new file mode 100644 index 000000000..341989ecd --- /dev/null +++ b/src/services/migrator/wunderlist.js @@ -0,0 +1,7 @@ +import AbstractMigrationService from './abstractMigrationService' + +export default class WunderlistMigrationService extends AbstractMigrationService { + constructor() { + super('wunderlist') + } +} diff --git a/src/styles/components/_all.scss b/src/styles/components/_all.scss index 007f6fb65..bf427a129 100644 --- a/src/styles/components/_all.scss +++ b/src/styles/components/_all.scss @@ -11,3 +11,4 @@ @import 'taskRelations'; @import 'tasks'; @import 'teams'; +@import 'migrator'; diff --git a/src/styles/components/migrator.scss b/src/styles/components/migrator.scss new file mode 100644 index 000000000..605dc3d65 --- /dev/null +++ b/src/styles/components/migrator.scss @@ -0,0 +1,69 @@ +.migration-services-overview { + text-align: center; + + a { + display: inline-block; + width: 100px; + + img { + display: block; + } + } +} + +.migration-in-progress-container { + max-width: 400px; + margin: 4em auto 0; + text-align: center; +} + +.migration-in-progress { + text-align: center; + display: flex; + max-width: 400px; + justify-content: space-between; + align-items: center; + margin-bottom: 2em; + + img { + display: block; + max-height: 100px; + } + + .progress-dots { + height: 40px; + width: 140px; + overflow: visible; + + span { + transition: all 500ms ease; + background: $grey; + height: 10px; + width: 10px; + display: inline-block; + border-radius: 10px; + animation: wave 2s ease infinite; + margin-right: 5px; + + &:nth-child(1){ animation-delay: 0; } + &:nth-child(2){ animation-delay: 100ms; } + &:nth-child(3){ animation-delay: 200ms; } + &:nth-child(4){ animation-delay: 300ms; } + &:nth-child(5){ animation-delay: 400ms; } + &:nth-child(6){ animation-delay: 500ms; } + &:nth-child(7){ animation-delay: 600ms; } + &:nth-child(8){ animation-delay: 700ms; } + } + } + + @keyframes wave{ + 0%, 40%, 100% { + transform: translate(0, 0); + background-color: $primary; + } + 10% { + transform: translate(0, -15px); + background-color: $primary-dark; + } + } +}