108 lines
2.5 KiB
Vue
108 lines
2.5 KiB
Vue
<script lang="ts" setup>
|
|
import axios from 'axios';
|
|
import { getAttachmentHead, convertFileSize } from 'stores/utils';
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
const api = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL });
|
|
const size = ref<number>(0);
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
icon?: string;
|
|
color?: string;
|
|
name?: string;
|
|
url?: string;
|
|
progress?: number;
|
|
uploading?: { loaded: number; total: number };
|
|
idle?: boolean;
|
|
|
|
clickable?: boolean;
|
|
closeable?: boolean;
|
|
}>(),
|
|
{
|
|
icon: 'mdi-file-outline',
|
|
color: 'var(--brand-1)',
|
|
name: '-',
|
|
url: '-',
|
|
progress: 0,
|
|
uploading: () => ({ loaded: 0, total: 0 }),
|
|
|
|
clickable: false,
|
|
closeable: true,
|
|
},
|
|
);
|
|
|
|
defineEmits<{
|
|
(e: 'close'): void;
|
|
(e: 'click'): void;
|
|
}>();
|
|
|
|
async function getSize() {
|
|
if (props.progress !== 1) return;
|
|
const res = await getAttachmentHead(api, props.url);
|
|
if (res && res['content-length']) size.value = Number(res['content-length']);
|
|
}
|
|
|
|
onMounted(() => {
|
|
getSize();
|
|
});
|
|
</script>
|
|
<template>
|
|
<div
|
|
class="bordered rounded row items-center q-pa-md card"
|
|
:class="{ 'cursor-pointer': clickable }"
|
|
@click="$emit('click')"
|
|
>
|
|
<q-icon :name="icon" size="lg" :style="`color: ${color}`" />
|
|
<div class="col column q-pl-md">
|
|
<div class="ellipsis full-width" style="max-width: 65vw !important">
|
|
{{ name }}
|
|
</div>
|
|
|
|
<span class="text-caption app-text-muted-2">
|
|
{{
|
|
uploading.loaded
|
|
? `${convertFileSize(uploading.loaded)} of ${convertFileSize(uploading.total)}`
|
|
: `${convertFileSize(size)} of ${convertFileSize(size)}`
|
|
}}
|
|
•
|
|
<q-spinner-ios
|
|
v-if="progress !== 1"
|
|
class="q-mx-xs"
|
|
color="primary"
|
|
size="1.5em"
|
|
/>
|
|
<q-icon
|
|
v-if="progress === 1 && !idle"
|
|
name="mdi-check-circle"
|
|
color="positive"
|
|
size="1rem"
|
|
/>
|
|
{{ idle ? `Pending` : progress !== 1 ? `Uploading...` : 'Completed' }}
|
|
</span>
|
|
</div>
|
|
<q-btn
|
|
v-if="closeable"
|
|
icon="mdi-close"
|
|
flat
|
|
rounded
|
|
size="sm"
|
|
padding="0"
|
|
class="q-ml-auto self-start"
|
|
style="color: hsl(var(--text-mute))"
|
|
@click.stop="$emit('close')"
|
|
/>
|
|
<q-linear-progress
|
|
v-if="progress !== 1"
|
|
:value="progress"
|
|
class="q-mt-sm rounded"
|
|
color="info"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<style scoped>
|
|
.card:hover {
|
|
transition: ease-in-out 0.3s;
|
|
background: hsla(var(--info-bg) / 0.05);
|
|
}
|
|
</style>
|