toolshed/frontend/src/components/CombinedFileField.vue
2023-07-17 15:53:26 +02:00

117 lines
No EOL
3.4 KiB
Vue

<template>
<drag-drop-file-source @input="addFiles">
<h3 v-if="create">Create New</h3>
<h3 v-else>Update</h3>
<ul>
<li v-for="file in whithout_images(files)" :key="file.id">
{{ file.name }}
</li>
<li v-for="file in whithout_images(item_files)" :key="file.id">
{{ file.name }}
</li>
</ul>
<hr>
<div>
<img v-for="file in only_images(files)" :key="file.id" :src="file.name" :alt="file.name"
class="img-thumbnail" :title="file.mime_type">
<img v-for="file in whithout_images(item_files)" :key="file.id" :alt="file.name"
:src="'data:' + file.mime_type + ';base64,' + file.data" class="img-thumbnail border-info">
<fs-file-source @input="addFiles">
<div class="img-thumbnail btn btn-outline-primary">
<b-icon-upload></b-icon-upload>
</div>
</fs-file-source>
<camera-file-source @input="addFiles">
<div class="img-thumbnail btn btn-outline-primary">
<b-icon-camera></b-icon-camera>
</div>
</camera-file-source>
</div>
</drag-drop-file-source>
</template>
<style scoped>
.img-thumbnail {
width: 95px;
height: 54px;
object-fit: cover;
}
.img-thumbnail svg {
width: 100%;
height: 100%;
}
</style>
<script>
import * as BIcons from "bootstrap-icons-vue";
import {mapActions, mapState} from "vuex";
import DragDropFileSource from "@/components/DragDropFileSource.vue";
import FsFileSource from "@/components/FsFileSource.vue";
import CameraFileSource from "@/components/CameraFileSource.vue";
export default {
name: "CombinedFileField",
components: {
...BIcons,
DragDropFileSource,
CameraFileSource,
FsFileSource
},
props: {
item_files: {
type: Array,
required: true
},
item_id: {
type: Number
},
create: {
type: Boolean,
default: false
}
},
emits: ["change"],
computed: {
...mapState(["files"]),
},
methods: {
...mapActions(["fetchFiles", "pushFile"]),
async uploadFiles(files) {
const jobs = files.map(async file => {
await this.pushFile({
file: file,
item_id: this.item_id
});
});
const responses = await Promise.all(jobs);
console.log(responses);
return responses;
},
addFiles(files) {
const newfiles = files.filter(file => !this.item_files.find(f => f.hash === file.hash));
if (newfiles.length === 0) {
console.log("no new files");
return;
}
if (!this.create) {
this.uploadFiles(newfiles).then((uploaded) => {
console.log(uploaded);
})
}
this.$emit("change", [...this.item_files, ...newfiles]);
console.log(this.item_files);
},
only_images(files) {
return files.filter(file => file.mime_type.startsWith("image/"));
},
whithout_images(files) {
return files.filter(file => !file.mime_type.startsWith("image/"));
},
},
mounted() {
this.fetchFiles();
}
}
</script>