ldc-dam/resources/js/components/DepotComponent.vue
2022-07-28 12:21:02 +02:00

363 lines
10 KiB
Vue

<template>
<div class="depot_container">
<header>
<font-awesome-icon icon="images" />
<h1>Déposez vos médias</h1>
</header>
<div class="mainContent">
<div class="col">
<form class="form_depot_media" action="#" method="post">
<input
id="depot_nom"
type="text"
v-model="depotName"
placeholder="Votre nom*"
:disabled="inProgress"
required
/>
<select
id="depot_societe"
name=""
v-model="depotSocieteId"
:disabled="inProgress"
required
>
<option
v-for="(site, index) of sites"
:seleted="Number(index) === 0 ? true : false"
:value="index"
>
{{ site.libelle }}
</option>
</select>
<textarea
id="depot_description"
name="name"
v-model="depotDescription"
rows="8"
cols="80"
placeholder="Description des fichiers envoyés*"
:disabled="inProgress"
required
></textarea>
</form>
</div>
<div class="col">
<span class="fileinput-button">
<font-awesome-icon icon="plus-circle" /><span> Ajouter des fichiers</span>
<input
v-if="r"
ref="fileupload"
id="uploadDepot"
type="file"
name="files[]"
multiple
/>
</span>
<div class="content_wrapper">
<!-- The container for the uploaded errors -->
<div id="upload_errors">
<p v-for="(uploadError, index) of uploadErrors" style="color: red">
{{ uploadError }}
</p>
</div>
<!-- The container for the uploaded files -->
<div id="files" class="files">
<div v-for="(file, index) of files">
<div>
<span>
{{ String(file.fileName).trim() }}
<button v-on:click="removeFile(file)" class="cancel">
<font-awesome-icon icon="time" />
</button>
</span>
</div>
<div>
<span>{{ FileConvertSize(file.size) }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="upload_bar">
<button
id="submit"
class="btn"
href="#"
:disabled="inProgress"
v-on:click.prevent="uploadFiles"
>
<span v-if="inProgress"><font-awesome-icon icon="circle-notch" spin /></span>
<span>Transférer</span>
</button>
<!-- The global progress bar -->
<div
v-if="inProgress"
id="progress"
class="progress"
:style="inProgress ? 'display: block;' : ''"
>
<div
class="progress-bar progress-bar-success"
:style="`width: ${progress}%;`"
></div>
</div>
</div>
</div>
</template>
<script>
import Resumable from "resumablejs";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
export default {
name: "DepotComponent",
components: { FontAwesomeIcon },
mounted() {
const data = JSON.parse(this.$parent.$options.json);
this.sites = data.sites;
this.setupResumable();
},
computed: {},
data() {
return {
depotName: "",
depotSocieteId: 0,
depotDescription: "",
inProgress: false,
maxFiles: 100,
sites: [],
files: [],
uploadedFiles: [],
uploadErrors: [],
totalFiles: 0,
progress: 0,
r: null,
};
},
watch: {},
methods: {
uploadFiles() {
if (!$(".form_depot_media")[0].checkValidity()) {
$(".form_depot_media")[0].reportValidity();
$.fancyMessage({
title: "Dépôt de médias",
message: "Veuillez compléter tous les champs avant de lancer le transfert.",
type: "error",
});
return false;
}
if (this.files.length == 0) {
$.fancyMessage({
title: "Dépôt de médias",
message: "Veuillez ajouter des médias avant de lancer le transfert.",
type: "error",
});
return false;
}
this.createFolder((folder_id) => {
this.inProgress = true;
this.r.opts.query = {
dossier_id: folder_id,
};
this.totalFiles = this.files.length;
this.r.upload();
});
},
createFolder(callback) {
const currentdate = new Date(),
folderName =
this.sites[this.depotSocieteId].libelle.replace(" ", "_") +
"_" +
currentdate.getFullYear().toString() +
("0" + (currentdate.getMonth() + 1)).slice(-2) +
currentdate.getDate().toString() +
"_" +
currentdate.getHours().toString() +
currentdate.getMinutes().toString() +
currentdate.getSeconds().toString(),
description = `Nom : ${this.depotName}\nSociété : ${
this.sites[this.depotSocieteId].libelle
}\n${this.depotDescription}`;
this.uploadedFiles = [];
this.uploadErrors = [];
// création d'un dossier de dépôt
$.ajax({
url: "/ajax/add-depot-folder",
method: "POST",
dataType: "json",
data: {
libelle: folderName,
description: description,
},
success: function (result) {
callback(result.folder_id);
},
error: function (jqXHR, textStatus, errorThrown) {
$.fancyMessage({
title: "Erreur",
message: `Erreur lors de la création du dossier ${folderName}`,
type: "error",
});
},
});
},
setupResumable() {
// * Reset dom nodes
this.r = null;
this.$nextTick(() => {
// * Set resumable with new Dom nodes
this.r = new Resumable({
target: "/ajax/upload-media/depot",
simultaneousUploads: 3,
maxFiles: this.maxFiles,
testChunks: false,
fileParameterName: "file",
headers: {
"X-CSRF-TOKEN": document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content"),
},
});
this.r.on("progress", this.uploadProgress);
this.r.on("fileAdded", this.uploadFileAdded);
this.r.on("fileSuccess", this.uploadFileSuccess);
this.r.on("fileError", this.uploadFileError);
this.r.on("complete", this.uploadFilesComplete);
this.uploadErrors = [];
this.$nextTick(() => {
// * Setup resumable browse with new dom node
this.r.assignBrowse(this.$refs.fileupload);
// * If there were files from previous upload failed then use them
if (this.files.length) {
// * Reassign files
const files = this.files;
this.files = [];
for (let file of files) {
this.r.addFile(file.file);
}
}
});
});
},
uploadFileAdded(file, event) {
const acceptFileTypes = /^(gif|jpe?g|png|mp4|mp3|psd|ai|svg|pdf)$/i,
fileParts = file.fileName.split("."),
ext = String(fileParts.pop()).trim(),
fileName = String(fileParts.concat("_")).trim().substring(0, 40);
file.fileName = `${fileName}.${ext}`;
if (ext.length && !acceptFileTypes.test(ext)) {
this.uploadErrors.push(`Ce type de fichier n'est pas accepté '${ext}'`);
this.r.removeFile(file);
return false;
}
if (file.size.length && file.size > 5000000) {
this.uploadErrors.push(
`La taille du fichier ${file.fileName} est trop grande > ${this.FileConvertSize(
5000000
)}.`
);
this.r.removeFile(file);
return false;
}
if (this.files.length >= this.maxFiles) {
$.fancyMessage({
title: "Attention",
message: `Vous ne pouvez pas ajouter plus de ${this.maxFiles} fichiers`,
type: "info",
});
return false;
}
this.files.push(file);
},
uploadProgress() {
this.progress = Math.round(
((this.totalFiles - this.files.length) * 100) / this.totalFiles
);
},
uploadFileSuccess(file) {
this.uploadProgress();
this.uploadedFiles.push(file);
this.removeFile(file);
},
uploadFilesComplete() {
this.inProgress = false;
$.fancybox.close();
if (!this.files.length) {
$.fancyMessage({
title: "Tout les fichiers ont été envoyés",
type: "info",
});
this.depotName = "";
this.depotSocieteId = 0;
this.depotDescription = "";
} else {
$.fancyMessage({
title: "Des erreur sont survenus durant le transfert des fichiers",
type: "error",
});
this.uploadErrors.push(
"Des erreur sont survenus durant le transfert des fichiers"
);
}
this.$nextTick(() => {
this.setupResumable();
});
},
uploadFileError(file, httpMessage) {
let message = `Une erreur durant le transfert du fichier ${file.fileName}`;
const error = JSON.parse(httpMessage);
if (error.file) {
const errors = error.file;
if (errors instanceof String) {
message = errors;
}
if (errors instanceof Object) {
message = Object.values(errors).reduce(function (previous, current) {
return String(previous) + String(current);
});
}
}
this.uploadErrors.push(message);
},
removeFile(fileToRemove) {
this.r.removeFile(fileToRemove);
this.files = this.files.filter(
(file) =>
String(fileToRemove.file.uniqueIdentifier).trim() !==
String(file.file.uniqueIdentifier).trim()
);
},
/**
* @return {string}
*/
FileConvertSize(aSize) {
aSize = Math.abs(parseInt(aSize, 10));
let def = [
[1, "octets"],
[1024, "ko"],
[1024 * 1024, "Mo"],
[1024 * 1024 * 1024, "Go"],
[1024 * 1024 * 1024 * 1024, "To"],
];
for (let i = 0; i < def.length; i++) {
if (aSize < def[i][0])
return (aSize / def[i - 1][0]).toFixed(2) + " " + def[i - 1][1];
}
},
},
};
</script>