[#2246] added drop files support for the file field

This commit is contained in:
Gani Georgiev
2023-04-13 16:46:41 +03:00
parent af5f808144
commit b347c8d80c
33 changed files with 267 additions and 213 deletions
+126 -86
View File
@@ -15,6 +15,7 @@
let fileInput;
let filesListElem;
let isDragOver = false;
// normalize uploadedFiles type
$: if (!Array.isArray(uploadedFiles)) {
@@ -68,104 +69,143 @@
})
);
}
function dropHandler(e) {
e.preventDefault();
isDragOver = false;
const files = e.dataTransfer?.files || [];
if (maxReached || !files.length) {
return;
}
for (const file of files) {
const currentTotal = valueAsArray.length + uploadedFiles.length - deletedFileIndexes.length;
if (field.options?.maxSelect <= currentTotal) {
break;
}
uploadedFiles.push(file);
}
uploadedFiles = uploadedFiles;
}
</script>
<Field
class="form-field form-field-list form-field-file {field.required ? 'required' : ''}"
name={field.name}
let:uniqueId
<div
class="block"
on:dragover|preventDefault={() => {
isDragOver = true;
}}
on:dragleave={() => {
isDragOver = false;
}}
on:drop={dropHandler}
>
<label for={uniqueId}>
<i class={CommonHelper.getFieldTypeIcon(field.type)} />
<span class="txt">{field.name}</span>
</label>
<Field
class="
form-field form-field-list form-field-file
{field.required ? 'required' : ''}
{isDragOver ? 'dragover' : ''}
"
name={field.name}
let:uniqueId
>
<label for={uniqueId}>
<i class={CommonHelper.getFieldTypeIcon(field.type)} />
<span class="txt">{field.name}</span>
</label>
<div bind:this={filesListElem} class="list">
{#each valueAsArray as filename, i (filename + record.id)}
{@const isDeleted = deletedFileIndexes.includes(i)}
<div class="list-item">
<div class:fade={deletedFileIndexes.includes(i)}>
<RecordFileThumb {record} {filename} />
<div bind:this={filesListElem} class="list">
{#each valueAsArray as filename, i (filename + record.id)}
{@const isDeleted = deletedFileIndexes.includes(i)}
<div class="list-item">
<div class:fade={deletedFileIndexes.includes(i)}>
<RecordFileThumb {record} {filename} />
</div>
<div class="content">
<a
href={ApiClient.files.getUrl(record, filename)}
class="txt-ellipsis {isDeleted ? 'txt-strikethrough txt-hint' : 'link-primary'}"
title="Download"
target="_blank"
rel="noopener noreferrer"
>
{filename}
</a>
</div>
<div class="actions">
{#if deletedFileIndexes.includes(i)}
<button
type="button"
class="btn btn-sm btn-danger btn-transparent"
on:click={() => restoreExistingFile(i)}
>
<span class="txt">Restore</span>
</button>
{:else}
<button
type="button"
class="btn btn-transparent btn-hint btn-sm btn-circle btn-remove"
use:tooltip={"Remove file"}
on:click={() => removeExistingFile(i)}
>
<i class="ri-close-line" />
</button>
{/if}
</div>
</div>
{/each}
<div class="content">
<a
href={ApiClient.files.getUrl(record, filename)}
class="txt-ellipsis {isDeleted ? 'txt-strikethrough txt-hint' : 'link-primary'}"
title="Download"
target="_blank"
rel="noopener noreferrer"
{#each uploadedFiles as file, i}
<div class="list-item">
<figure class="thumb">
<UploadedFilePreview {file} />
</figure>
<div class="filename m-r-auto" title={file.name}>
<small class="label label-success m-r-5">New</small>
<span class="txt">{file.name}</span>
</div>
<button
type="button"
class="btn btn-transparent btn-hint btn-sm btn-circle btn-remove"
use:tooltip={"Remove file"}
on:click={() => removeNewFile(i)}
>
{filename}
</a>
<i class="ri-close-line" />
</button>
</div>
{/each}
<div class="actions">
{#if deletedFileIndexes.includes(i)}
<button
type="button"
class="btn btn-sm btn-danger btn-transparent"
on:click={() => restoreExistingFile(i)}
>
<span class="txt">Restore</span>
</button>
{:else}
<button
type="button"
class="btn btn-transparent btn-hint btn-sm btn-circle btn-remove"
use:tooltip={"Remove file"}
on:click={() => removeExistingFile(i)}
>
<i class="ri-close-line" />
</button>
{/if}
</div>
</div>
{/each}
{#each uploadedFiles as file, i}
<div class="list-item">
<figure class="thumb">
<UploadedFilePreview {file} />
</figure>
<div class="filename m-r-auto" title={file.name}>
<small class="label label-success m-r-5">New</small>
<span class="txt">{file.name}</span>
</div>
<div class="list-item list-item-btn">
<input
bind:this={fileInput}
type="file"
class="hidden"
multiple={isMultiple}
on:change={() => {
for (let file of fileInput.files) {
uploadedFiles.push(file);
}
uploadedFiles = uploadedFiles;
fileInput.value = null; // reset
}}
/>
<button
type="button"
class="btn btn-transparent btn-sm btn-circle btn-remove"
use:tooltip={"Remove file"}
on:click={() => removeNewFile(i)}
class="btn btn-transparent btn-sm btn-block"
disabled={maxReached}
on:click={() => fileInput?.click()}
>
<i class="ri-close-line" />
<i class="ri-upload-cloud-line" />
<span class="txt">Upload new file</span>
</button>
</div>
{/each}
<div class="list-item list-item-btn">
<input
bind:this={fileInput}
type="file"
class="hidden"
multiple={isMultiple}
on:change={() => {
for (let file of fileInput.files) {
uploadedFiles.push(file);
}
uploadedFiles = uploadedFiles;
fileInput.value = null; // reset
}}
/>
<button
type="button"
class="btn btn-transparent btn-sm btn-block"
disabled={maxReached}
on:click={() => fileInput?.click()}
>
<i class="ri-upload-cloud-line" />
<span class="txt">Upload new file</span>
</button>
</div>
</div>
</Field>
</Field>
</div>