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

View File

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