feat(front/FileUpload): display errors and allow retrying or canceling the upload

This commit is contained in:
Alice Gaudon 2022-03-02 11:10:58 +01:00
parent 7ad0eac6db
commit 15441a0941
1 changed files with 37 additions and 6 deletions

View File

@ -1,5 +1,6 @@
<script lang="ts">
import {onMount} from "svelte";
import Icon from "../utils/Icon.svelte"
export let file: File;
export let form: HTMLFormElement;
@ -25,13 +26,14 @@
inProgress = true;
try {
await new Promise<void>((resolve, reject) => {
initTrackers();
reset();
prepareXhrRequest(resolve, reject);
if (!xhr) throw new Error('Failed to initialize xhr');
sendXhrRequest(xhr);
});
} catch (e) {
onError(e);
error = e;
return onError(e);
} finally {
inProgress = false;
}
@ -39,12 +41,25 @@
onEnd(file.name, finalUrl);
}
function initTrackers() {
function retry() {
run().catch(onError);
}
function cancel() {
onEnd(file.name, null);
}
function reset() {
resetResult();
initSpeedTracker();
initProgressTracker();
initErrorTracker();
}
function resetResult() {
finalUrl = undefined;
}
function initSpeedTracker() {
xferSpeed = [];
lastTransferTime = null;
@ -83,7 +98,9 @@
if (response.status === 'error') {
if (response.messages) {
// TODO: display errors // applyFormMessages(this.form, response.messages);
return reject(response.messages);
const messages = response.messages;
const formattedError = Object.keys(messages).map(field => `${field}: ${messages[field].name}, ${messages[field].message}`).join(';');
return reject(formattedError);
}
} else if (response.url) {
finalUrl = response.url;
@ -154,6 +171,11 @@
.name, .status {
text-align: center;
}
&.error {
color: var(--on-error);
background-color: var(--error);
}
}
.progress-bar {
@ -185,8 +207,17 @@
}
</style>
<div class="file-upload">
<div class="file-upload" class:error={!!error}>
<div class="name">{file?.name}</div>
<div class="progress-bar" style="--progress: {progress};"><span class="content">{progress}</span></div>
<div class="status">Uploading @ {speed}</div>
<div class="status">
{#if error}
Error: {error}
<button on:click={retry}><Icon name="repeat"/> Retry</button>
<button on:click={cancel}><Icon name="slash"/> Cancel</button>
{:else}
Uploading @ {speed}
{/if}
</div>
</div>