koel/resources/assets/js/components/ui/upload/UploadItem.vue

96 lines
2.3 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
<div :class="cssClass" :title="file.message" class="upload-item">
2022-12-02 16:17:37 +00:00
<span :style="{ width: `${file.progress}%` }" class="progress" />
2022-04-15 14:24:30 +00:00
<span class="details">
<span class="name">{{ file.name }}</span>
<span class="controls">
<Btn v-if="canRetry" icon-only title="Retry" transparent unrounded @click="retry">
2022-12-02 16:17:37 +00:00
<icon :icon="faRotateBack" />
2022-04-15 14:24:30 +00:00
</Btn>
<Btn v-if="canRemove" icon-only title="Remove" transparent unrounded @click="remove">
2022-12-02 16:17:37 +00:00
<icon :icon="faTrashCan" />
2022-04-15 14:24:30 +00:00
</Btn>
</span>
</span>
</div>
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
import slugify from 'slugify'
import { faRotateBack, faTrashCan } from '@fortawesome/free-solid-svg-icons'
2022-04-15 17:00:08 +00:00
import { computed, defineAsyncComponent, toRefs } from 'vue'
import { UploadFile, uploadService } from '@/services'
2022-04-15 14:24:30 +00:00
2022-04-21 18:39:18 +00:00
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
const props = defineProps<{ file: UploadFile }>()
const { file } = toRefs(props)
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
const canRetry = computed(() => file.value.status === 'Canceled' || file.value.status === 'Errored')
const canRemove = computed(() => file.value.status !== 'Uploading') // we're not supporting cancel tokens (yet).
const cssClass = computed(() => slugify(file.value.status).toLowerCase())
2022-04-15 14:24:30 +00:00
2022-04-24 08:50:45 +00:00
const remove = () => uploadService.remove(file.value)
const retry = () => uploadService.retry(file.value)
2022-04-15 14:24:30 +00:00
</script>
<style lang="scss" scoped>
.upload-item {
position: relative;
margin-bottom: 5px;
border-radius: 3px;
min-height: 32px;
overflow: hidden;
background: var(--color-bg-secondary);
.progress {
position: absolute;
height: 100%;
top: 0;
left: 0;
background: var(--color-highlight);
z-index: 0;
transition: .3s ease-out;
}
&.uploaded {
2022-04-15 14:24:30 +00:00
background: var(--color-green);
.progress {
background: transparent;
}
}
&.errored {
2022-04-15 14:24:30 +00:00
background: var(--color-red);
.progress {
background: transparent;
}
}
.details {
z-index: 1;
position: absolute;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.name {
padding: 0 12px;
}
}
.controls {
display: flex;
}
button {
padding: 8px 8px;
background: rgba(0, 0, 0, .1);
}
}
</style>