changes
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="file is-primary"
|
||||
id="ignore"
|
||||
v-if="position === 'left'"
|
||||
class="file is-primary"
|
||||
>
|
||||
<label class="file-label">
|
||||
<label
|
||||
class="file-label"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<input
|
||||
class="file-input"
|
||||
type="file"
|
||||
@@ -14,117 +16,106 @@
|
||||
name="resume"
|
||||
@change="doChange"
|
||||
/>
|
||||
<span class="file-cta px-2">
|
||||
<span class="icon-text is-clickable">
|
||||
<SvgIcon v-bind="{ name: 'attach-file.svg', type: 'white', size: 22 }"></SvgIcon>
|
||||
<!--<span class="has-text-white">File</span>-->
|
||||
<span class="file-cta px-3 py-1.5">
|
||||
<span class="icon-text is-gap-0.5 is-align-items-center">
|
||||
<slot name="icon">
|
||||
<Icon
|
||||
name="material-symbols:attach-file-rounded"
|
||||
:size="20"
|
||||
/>
|
||||
</slot>
|
||||
<slot />
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="field is-grouped is-grouped-right"
|
||||
id="ignore"
|
||||
v-else
|
||||
>
|
||||
<div class="control">
|
||||
<div class="file is-primary">
|
||||
<label class="file-label">
|
||||
<input
|
||||
class="file-input"
|
||||
type="file"
|
||||
:id="docid"
|
||||
multiple
|
||||
name="resume"
|
||||
@change="doChange"
|
||||
/>
|
||||
<span class="file-cta is-primary px-1">
|
||||
<span class="icon-text is-clickable">
|
||||
<SvgIcon v-bind="{ name: 'attach-file.svg', type: 'white', size: 22 }"></SvgIcon>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
@close="showmodal = undefined"
|
||||
v-bind="showmodal"
|
||||
v-if="showmodal"
|
||||
@close="showmodal = undefined"
|
||||
@files="getFiles"
|
||||
></Modal>
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: ["type", "position", "convert", "quality"],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
files: undefined,
|
||||
dataFiles: [],
|
||||
vtype: this.type || ["image"],
|
||||
showmodal: undefined,
|
||||
docid: this.$id(),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getFileExtension(fileName) {
|
||||
if (!fileName || typeof fileName !== "string") return "";
|
||||
const parts = fileName.split(".");
|
||||
return parts.length > 1 ? parts.pop().toLowerCase() : "";
|
||||
},
|
||||
getType(ext) {
|
||||
// copied from 01-common.js
|
||||
const imageFormat = ["png", "jpg", "jpeg", "bmp", "gif", "svg", "webp"];
|
||||
const videoFormat = ["wmv", "avi", "mp4", "flv", "mov", "mpg", "amv", "rm"];
|
||||
<script setup>
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
if (ext === "pdf") return "pdf";
|
||||
if (imageFormat.includes(ext)) return "image";
|
||||
if (videoFormat.includes(ext)) return "video";
|
||||
return "file";
|
||||
},
|
||||
doChange() {
|
||||
this.dataFiles = [];
|
||||
const fileList = document.getElementById(this.docid).files;
|
||||
this.files = Array.from(fileList);
|
||||
if (this.files.length === 0) return;
|
||||
const props = defineProps({
|
||||
type: Array,
|
||||
convert: String,
|
||||
quality: Number,
|
||||
});
|
||||
|
||||
// Xác định giá trị convert: "1" nếu convert được bật, "0" nếu không
|
||||
const convertValue = this.convert ? "1" : "0";
|
||||
const qualityValue = this.convert && this.quality ? this.quality : null;
|
||||
const emit = defineEmits(["files"]);
|
||||
const { $id, $snackbar, $upload } = useNuxtApp();
|
||||
|
||||
this.files.map((v) => {
|
||||
const ext = this.getFileExtension(v.name);
|
||||
const type = this.getType(ext);
|
||||
const vtype = props.type || ["image"];
|
||||
const files = ref();
|
||||
const dataFiles = ref();
|
||||
const showmodal = ref();
|
||||
const docid = $id();
|
||||
|
||||
if (!this.vtype.includes(type)) {
|
||||
this.$snackbar(`Định dạng file "${ext}" không hợp lệ`);
|
||||
return;
|
||||
}
|
||||
function getFileExtension(fileName) {
|
||||
if (!fileName || typeof fileName !== "string") return "";
|
||||
const parts = fileName.split(".");
|
||||
return parts.length > 1 ? parts.pop().toLowerCase() : "";
|
||||
}
|
||||
|
||||
let file = this.$upload(v, type, 1, convertValue, qualityValue);
|
||||
this.dataFiles.push(file);
|
||||
});
|
||||
function getType(ext) {
|
||||
// copied from 01-common.js
|
||||
const imageFormat = ["png", "jpg", "jpeg", "bmp", "gif", "svg", "webp"];
|
||||
const videoFormat = ["wmv", "avi", "mp4", "flv", "mov", "mpg", "amv", "rm"];
|
||||
|
||||
this.showmodal = {
|
||||
component: "media/UploadProgress",
|
||||
title: "Upload files",
|
||||
width: "700px",
|
||||
height: "200px",
|
||||
vbind: { files: this.dataFiles },
|
||||
};
|
||||
this.clearFileList();
|
||||
},
|
||||
clearFileList() {
|
||||
const fileInput = document.getElementById(this.docid);
|
||||
const dt = new DataTransfer();
|
||||
fileInput.files = dt.files;
|
||||
},
|
||||
getFiles(files) {
|
||||
this.$emit("files", files);
|
||||
setTimeout(() => (this.showmodal = undefined), 3000);
|
||||
},
|
||||
},
|
||||
};
|
||||
if (ext === "pdf") return "pdf";
|
||||
if (imageFormat.includes(ext)) return "image";
|
||||
if (videoFormat.includes(ext)) return "video";
|
||||
return "file";
|
||||
}
|
||||
|
||||
function doChange() {
|
||||
dataFiles.value = [];
|
||||
const fileList = document.getElementById(docid).files;
|
||||
files.value = Array.from(fileList);
|
||||
if (files.value.length === 0) return;
|
||||
|
||||
// Xác định giá trị convert: "1" nếu convert được bật, "0" nếu không
|
||||
const convertValue = props.convert ? "1" : "0";
|
||||
const qualityValue = props.convert && props.quality ? props.quality : null;
|
||||
|
||||
files.value.map((v) => {
|
||||
const ext = getFileExtension(v.name);
|
||||
const type = getType(ext);
|
||||
|
||||
if (!vtype.includes(type)) {
|
||||
$snackbar(`Định dạng file "${ext}" không hợp lệ`);
|
||||
return;
|
||||
}
|
||||
|
||||
const file = $upload(v, type, 1, convertValue, qualityValue);
|
||||
dataFiles.value.push(file);
|
||||
});
|
||||
|
||||
showmodal.value = {
|
||||
component: "media/UploadProgress",
|
||||
title: "Upload files",
|
||||
width: "700px",
|
||||
height: "200px",
|
||||
vbind: { files: dataFiles.value },
|
||||
};
|
||||
clearFileList();
|
||||
}
|
||||
|
||||
function clearFileList() {
|
||||
const fileInput = document.getElementById(docid);
|
||||
const dt = new DataTransfer();
|
||||
fileInput.files = dt.files;
|
||||
}
|
||||
|
||||
function getFiles(files) {
|
||||
emit("files", files);
|
||||
setTimeout(() => {
|
||||
showmodal.value = undefined;
|
||||
}, 3000);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,33 +1,43 @@
|
||||
<template>
|
||||
<div class="has-text-left">
|
||||
<div class="fs-14 has-text-left is-flex is-flex-direction-column is-gap-1">
|
||||
<p
|
||||
class="py-1 border-bottom"
|
||||
v-for="v in vfiles"
|
||||
v-for="(v, i) in vfiles"
|
||||
:key="i"
|
||||
>
|
||||
<span class="icon-text">
|
||||
<span class="mr-5">{{ v.name }}</span>
|
||||
<SvgIcon
|
||||
v-bind="{ name: 'check2.svg', type: 'primary', size: 22 }"
|
||||
v-if="v.status === 'success'"
|
||||
></SvgIcon>
|
||||
<SvgIcon
|
||||
v-bind="{ name: 'error.svg', type: 'danger', size: 22 }"
|
||||
v-else-if="v.status === 'error'"
|
||||
></SvgIcon>
|
||||
<span class="icon-text is-gap-1 is-align-items-center">
|
||||
<span class="icon">
|
||||
<Icon
|
||||
name="svg-spinners:90-ring"
|
||||
:size="22"
|
||||
class="has-text-primary"
|
||||
v-if="v.status === 'uploading'"
|
||||
/>
|
||||
<Icon
|
||||
name="material-symbols:check-circle-rounded"
|
||||
:size="22"
|
||||
class="has-text-primary"
|
||||
v-else-if="v.status === 'success'"
|
||||
/>
|
||||
<Icon
|
||||
name="material-symbols:cancel-rounded"
|
||||
:size="22"
|
||||
class="has-text-danger"
|
||||
v-else-if="v.status === 'error'"
|
||||
/>
|
||||
</span>
|
||||
<span>{{ v.name }}</span>
|
||||
</span>
|
||||
<span
|
||||
class="icon-text has-text-danger ml-6"
|
||||
class="icon-text is-gap-1 has-text-danger ml-6"
|
||||
v-if="v.error"
|
||||
>
|
||||
<SvgIcon v-bind="{ name: 'error.svg', type: 'danger', size: 22 }"></SvgIcon>
|
||||
<span class="ml-1">{{ v.text }}</span>
|
||||
<Icon
|
||||
name="material-symbols:cancel-rounded"
|
||||
:size="22"
|
||||
class="has-text-danger"
|
||||
/>
|
||||
<span>{{ v.text }}</span>
|
||||
</span>
|
||||
<button
|
||||
class="button is-small is-white is-loading px-0 ml-4"
|
||||
v-if="v.status === 'uploading'"
|
||||
>
|
||||
Loading
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user