Skip to content

Commit d59cf32

Browse files
feat: Better user experience when importing buckets
Instead of being redirected to an empty page the error is now shown on the same page and the buckets list reloaded
1 parent 1d3bfd1 commit d59cf32

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

src/views/Buckets.vue

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,13 @@ div
5555

5656
b-card-group.deck
5757
b-card(header="Import buckets")
58-
form(method="post", :action="$aw.baseURL + '/api/0/import'", enctype="multipart/form-data")
59-
input(type="file", name="buckets.json")
60-
input(type="submit", value="Import")
58+
b-alert(v-if="import_error" show variant="danger" dismissable)
59+
| {{ import_error }}
60+
b-form-file(v-model="import_file"
61+
placeholder="Choose a file or drop file here..."
62+
drop-placeholder="Drop file here...")
63+
// TODO: This spinner could be placed in a more suitable place
64+
div(v-if="import_file" class="spinner-border" role="status")
6165
span
6266
| A valid file to import is a JSON file from either an export of a single bucket or an export from multiple buckets.
6367
| If there are buckets with the same name the import will fail
@@ -105,6 +109,8 @@ export default {
105109
name: 'Buckets',
106110
data() {
107111
return {
112+
import_file: null,
113+
import_error: null,
108114
delete_bucket_selected: null,
109115
fields: [
110116
{ key: 'id', label: 'Bucket ID', sortable: true },
@@ -119,6 +125,26 @@ export default {
119125
return _.orderBy(this.$store.state.buckets.buckets, [b => b.id], ['asc']);
120126
},
121127
},
128+
watch: {
129+
import_file: async function(_new_value, _old_value) {
130+
if (this.import_file != null) {
131+
console.log('Importing file');
132+
try {
133+
await this.importBuckets(this.import_file);
134+
console.log('Import successful');
135+
this.import_error = null;
136+
} catch (err) {
137+
console.log('Import failed');
138+
// TODO: Make aw-server report error message so it can be shown in the web-ui
139+
this.import_error = 'Import failed, see aw-server logs for more info';
140+
}
141+
// We need to reload buckets even if we fail because imports can be partial
142+
// (first bucket succeeds, second fails for example when importing multiple)
143+
await this.$store.dispatch('buckets/loadBuckets');
144+
this.import_file = null;
145+
}
146+
},
147+
},
122148
mounted: async function() {
123149
await this.$store.dispatch('buckets/ensureBuckets');
124150
},
@@ -131,6 +157,12 @@ export default {
131157
await this.$store.dispatch('buckets/deleteBucket', { bucketId });
132158
this.$root.$emit('bv::hide::modal', 'delete-modal');
133159
},
160+
importBuckets: async function(importFile) {
161+
const formData = new FormData();
162+
formData.append('buckets.json', importFile);
163+
const headers = { 'Content-Type': 'multipart/form-data' };
164+
return this.$aw.req.post('/0/import', formData, { headers });
165+
},
134166
},
135167
};
136168
</script>

0 commit comments

Comments
 (0)