69 lines
1.7 KiB
Vue
69 lines
1.7 KiB
Vue
<template>
|
|
<div class="uploader">
|
|
<el-upload
|
|
:http-request="doUpload"
|
|
:show-file-list="false"
|
|
:limit="1"
|
|
:disabled="loading"
|
|
:auto-upload="true"
|
|
>
|
|
<el-button type="primary" :loading="loading">{{ TEXT.common.actions.upload }}</el-button>
|
|
</el-upload>
|
|
<el-progress v-if="progress > 0 && progress < 100" :percentage="progress" :stroke-width="6" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from "vue";
|
|
import { ElMessage } from "element-plus";
|
|
import { uploadAttachment } from "../../api/attachments";
|
|
import { TEXT } from "../../locales";
|
|
|
|
const props = defineProps<{
|
|
studyId: string;
|
|
entityType: string;
|
|
entityId: string;
|
|
maxSizeMb?: number;
|
|
}>();
|
|
const emit = defineEmits(["uploaded"]);
|
|
|
|
const progress = ref(0);
|
|
const loading = ref(false);
|
|
const maxSize = props.maxSizeMb ?? 50;
|
|
|
|
const doUpload = async (options: any) => {
|
|
const file: File = options.file;
|
|
if (!file) return;
|
|
if (file.size > maxSize * 1024 * 1024) {
|
|
ElMessage.error(`${TEXT.common.messages.fileTooLarge} ${maxSize}MB`);
|
|
return;
|
|
}
|
|
progress.value = 0;
|
|
loading.value = true;
|
|
try {
|
|
await uploadAttachment(props.studyId, props.entityType, props.entityId, file, {
|
|
onUploadProgress: (evt: ProgressEvent) => {
|
|
if (evt.total) {
|
|
progress.value = Math.round((evt.loaded / evt.total) * 100);
|
|
}
|
|
},
|
|
});
|
|
ElMessage.success(TEXT.common.messages.uploadSuccess);
|
|
emit("uploaded");
|
|
} catch (e: any) {
|
|
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.uploadFailed);
|
|
} finally {
|
|
progress.value = 0;
|
|
loading.value = false;
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.uploader {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
</style>
|