medialibrary-helper/assets/components/SingleFile.vue

118 lines
3.9 KiB
Vue
Raw Normal View History

2024-01-13 21:43:45 +01:00
<template>
<label class="flex flex-col" :for="id">
<span v-if="label" class="text-sm font-semibold text-gray-400">
{{ label }}
<span v-show="required" class="text-red-800">&nbsp;*</span>
</span>
<div class="h-[35px] border-2 border-solid relative rounded-lg cursor-pointer flex-none border-gray-600 text-gray-300 bg-gray-700">
2024-04-14 00:24:40 +02:00
<div v-if="inner === null" class="flex items-center justify-center h-full">
2024-01-13 21:43:45 +01:00
<div class="relative text-sm text-gray-300 leading-none">Klicken oder Datei hierhin ziehen zum hochladen</div>
2024-04-14 00:24:40 +02:00
<input :id="id" class="hidden" type="file" :name="name" :multiple="false" @change="upload($event.target.files)" />
2024-01-13 21:43:45 +01:00
<div class="absolute w-full h-full top-0 left-0 cursor-pointer" @drop="onDropping" @dragenter="onDragEnter" @dragover="onDragOver" @dragleave="onDragLeave"></div>
</div>
2024-04-14 00:24:40 +02:00
<div v-else class="flex justify-between items-center h-full space-x-2 px-2">
2024-01-13 21:43:45 +01:00
<img :src="inner.icon" class="w-6 h-6" />
2024-04-14 00:24:40 +02:00
<div class="text-sm text-gray-300 leading-none grow" v-text="inner.file_name"></div>
<a v-tooltip="`Löschen`" href="#" class="flex justify-center items-center w-6 h-6 rounded-full bg-red-200" @click.prevent="onDelete">
2024-01-13 21:43:45 +01:00
<trash-icon class="text-red-800 w-3 h-3"></trash-icon>
</a>
2024-04-14 00:24:40 +02:00
<a v-tooltip="`Öffnen`" :href="inner.original_url" class="flex justify-center items-center w-6 h-6 rounded-full bg-primary-700" target="_BLANK">
2024-01-13 21:43:45 +01:00
<external-icon class="text-primary-200 w-3 h-3"></external-icon>
</a>
</div>
</div>
</label>
</template>
<script setup>
import {watch, ref, inject} from 'vue';
import TrashIcon from './TrashIcon.vue';
import ExternalIcon from './ExternalIcon.vue';
import useReadFile from '../composables/useReadFile.js';
import {useToast} from 'vue-toastification';
const emit = defineEmits(['update:modelValue']);
const axios = inject('axios');
const toast = useToast();
const inner = ref(null);
const {dropping, onDragEnter, onDragOver, onDragLeave, processDrop, read} = useReadFile();
const props = defineProps({
required: {
type: Boolean,
default: () => false,
},
collection: {
required: true,
type: String,
},
parentName: {
required: true,
type: String,
},
parentId: {
required: true,
validator: (value) => typeof value === 'number' || value === null,
},
name: {
type: String,
required: true,
},
id: {
required: true,
type: String,
},
label: {
required: false,
default: () => null,
validator: (value) => value === null || typeof value === 'string',
},
});
function parseValue(v) {
if (v === null) {
return null;
}
if (v.fallback) {
return null;
}
return v;
}
async function reload() {
var response = await axios.get(`/mediaupload/${props.parentName}/${props.parentId}/${props.collection}`);
inner.value = parseValue(response.data);
emit('update:modelValue', inner.value.id);
}
async function onDropping(e) {
await upload(await processDrop(e, 1));
}
async function upload(files) {
await realUpload(await read(files[0]));
}
async function realUpload(file) {
inner.value = (
await axios.post('/mediaupload', {
parent: {model: props.parentName, collection_name: props.collection, id: props.parentId ? props.parentId : null},
payload: file,
})
).data;
emit('update:modelValue', inner.value);
toast.success('Datei hochgeladen');
}
async function onDelete() {
await axios.delete(`/mediaupload/${inner.value.id}`);
inner.value = null;
emit('update:modelValue', null);
toast.success('Datei entfernt');
}
if (props.parentId !== null) {
reload();
}
</script>