Skip to content

Commit 2206810

Browse files
committed
Add loading spinner beside button while starting export or import
Signed-off-by: Christopher Ng <[email protected]>
1 parent e9f0af2 commit 2206810

File tree

6 files changed

+51
-28
lines changed

6 files changed

+51
-28
lines changed

js/user_migration-personal-settings.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/user_migration-personal-settings.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/ExportSection.vue

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,19 @@
4949
</div>
5050
</div>
5151

52-
<Button v-if="status.current !== 'export'"
53-
type="secondary"
54-
:aria-label="t('user_migration', 'Export your data')"
55-
:disabled="status.current === 'import'"
56-
@click.stop.prevent="startExport">
57-
<template #icon>
58-
<PackageDown title="" :size="20" />
59-
</template>
60-
{{ t('user_migration', 'Export') }}
61-
</Button>
52+
<div v-if="status.current !== 'export'"
53+
class="section__status">
54+
<Button type="secondary"
55+
:aria-label="t('user_migration', 'Export your data')"
56+
:disabled="status.current === 'import'"
57+
@click.stop.prevent="startExport">
58+
<template #icon>
59+
<PackageDown title="" :size="20" />
60+
</template>
61+
{{ t('user_migration', 'Export') }}
62+
</Button>
63+
<div v-if="startingExport" class="icon-loading" />
64+
</div>
6265
<div v-else class="section__status">
6366
<Button type="secondary"
6467
:aria-label="t('user_migration', 'Show export status')"
@@ -133,6 +136,7 @@ export default {
133136
data() {
134137
return {
135138
modalOpened: false,
139+
startingExport: false,
136140
selectedMigrators: [],
137141
}
138142
},
@@ -157,11 +161,16 @@ export default {
157161
async startExport() {
158162
try {
159163
await confirmPassword()
164+
this.startingExport = true
160165
await axios.post(generateOcsUrl('/apps/{appId}/api/v1/export', { appId: APP_ID }), {
161166
migrators: this.selectedMigrators,
162167
})
163-
this.$emit('refresh-status', () => this.openModal())
168+
this.$emit('refresh-status', () => {
169+
this.openModal()
170+
this.startingExport = false
171+
})
164172
} catch (error) {
173+
this.startingExport = false
165174
const errorMessage = error.message || 'Unknown error'
166175
this.logger.error(`Error starting user export: ${errorMessage}`, { error })
167176
showError(errorMessage)

src/components/ImportSection.vue

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,19 @@
3030

3131
<!-- TODO use server API -->
3232

33-
<Button v-if="status.current !== 'import'"
34-
type="secondary"
35-
:aria-label="t('user_migration', 'Import your data')"
36-
:disabled="status.current === 'export'"
37-
@click.stop.prevent="pickImportFile">
38-
<template #icon>
39-
<PackageUp title="" :size="20" />
40-
</template>
41-
{{ t('user_migration', 'Import') }}
42-
</Button>
33+
<div v-if="status.current !== 'import'"
34+
class="section__status">
35+
<Button type="secondary"
36+
:aria-label="t('user_migration', 'Import your data')"
37+
:disabled="status.current === 'export'"
38+
@click.stop.prevent="pickImportFile">
39+
<template #icon>
40+
<PackageUp title="" :size="20" />
41+
</template>
42+
{{ t('user_migration', 'Import') }}
43+
</Button>
44+
<div v-if="startingImport" class="icon-loading" />
45+
</div>
4346
<div v-else class="section__status">
4447
<Button type="secondary"
4548
:aria-label="t('user_migration', 'Show import status')"
@@ -76,6 +79,7 @@
7679
</template>
7780

7881
<script>
82+
import confirmPassword from '@nextcloud/password-confirmation'
7983
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
8084
8185
import Button from '@nextcloud/vue/dist/Components/Button'
@@ -114,6 +118,7 @@ export default {
114118
data() {
115119
return {
116120
modalOpened: false,
121+
startingImport: false,
117122
filePickerError: null,
118123
}
119124
},
@@ -139,10 +144,17 @@ export default {
139144
if (!filePath.startsWith('/')) {
140145
throw new Error()
141146
}
147+
142148
try {
149+
await confirmPassword()
150+
this.startingImport = true
143151
// TODO call API to start background job
144-
this.$emit('refresh-status', () => this.openModal())
152+
this.$emit('refresh-status', () => {
153+
this.openModal()
154+
this.startingImport = false
155+
})
145156
} catch (error) {
157+
this.startingImport = false
146158
const errorMessage = error.message || 'Unknown error'
147159
this.logger.error(`Error starting user import: ${errorMessage}`, { error })
148160
showError(errorMessage)

src/personal-settings.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ import '@nextcloud/dialogs/styles/toast.scss'
2727
import logger from './logger'
2828
import PersonalSettings from './views/Personal/Settings'
2929

30-
Vue.mixin({ props: { logger }, methods: { t, n } })
30+
Vue.prototype.t = t
31+
Vue.prototype.n = n
32+
Vue.prototype.logger = logger
3133

3234
export default new Vue({
3335
el: '#personal-settings',

src/views/Personal/Settings.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ export default {
8686
}
8787
},
8888
89-
async onRefreshStatus(openModalCallback) {
89+
async onRefreshStatus(callback) {
9090
await this.fetchStatus()
91-
openModalCallback()
91+
callback()
9292
},
9393
},
9494
}

0 commit comments

Comments
 (0)