chore: script setup components (#7299)

This commit is contained in:
Kuchenpirat
2026-03-23 21:18:25 +01:00
committed by GitHub
parent 3ad2d9155d
commit 5ab6e98f9e
47 changed files with 1721 additions and 2453 deletions

View File

@@ -1,5 +1,5 @@
<template>
<v-form ref="files">
<v-form ref="form">
<input
ref="uploader"
class="d-none"
@@ -26,144 +26,129 @@
</v-form>
</template>
<script lang="ts">
<script setup lang="ts">
import { useUserApi } from "~/composables/api";
const UPLOAD_EVENT = "uploaded";
export default defineNuxtComponent({
props: {
small: {
type: Boolean,
default: false,
},
post: {
type: Boolean,
default: true,
},
url: {
type: String,
default: "",
},
text: {
type: String,
default: "",
},
icon: {
type: String,
default: null,
},
fileName: {
type: String,
default: "archive",
},
textBtn: {
type: Boolean,
default: true,
},
accept: {
type: String,
default: "",
},
color: {
type: String,
default: "info",
},
disabled: {
type: Boolean,
default: false,
},
multiple: {
type: Boolean,
default: false,
},
const props = defineProps({
small: {
type: Boolean,
default: false,
},
setup(props, context) {
const files = ref<File[]>([]);
const uploader = ref<HTMLInputElement | null>(null);
const isSelecting = ref(false);
const i18n = useI18n();
const { $globals } = useNuxtApp();
const effIcon = props.icon ? props.icon : $globals.icons.upload;
const defaultText = i18n.t("general.upload");
const api = useUserApi();
async function upload() {
if (files.value.length === 0) {
return;
}
isSelecting.value = true;
if (!props.post) {
// NOTE: To preserve behaviour for other parents of this component,
// we emit a single File if !props.multiple.
context.emit(UPLOAD_EVENT, props.multiple ? files.value : files.value[0]);
isSelecting.value = false;
return;
}
// WARN: My change is only for !props.post.
// I have not added support for multiple files in the API.
// Existing call-sites never passed the `multiple` prop,
// so this case will only be hit if the prop is set to true.
if (props.multiple && files.value.length > 1) {
console.warn("Multiple file uploads are not supported by the API.");
return;
}
const file = files.value[0];
const formData = new FormData();
formData.append(props.fileName, file);
try {
const response = await api.upload.file(props.url, formData);
if (response) {
context.emit(UPLOAD_EVENT, response);
}
}
catch (e) {
console.error(e);
context.emit(UPLOAD_EVENT, null);
}
isSelecting.value = false;
}
function onFileChanged(e: Event) {
const target = e.target as HTMLInputElement;
if (target.files !== null && target.files.length > 0) {
files.value = Array.from(target.files);
upload();
}
}
function onButtonClick() {
isSelecting.value = true;
window.addEventListener(
"focus",
() => {
isSelecting.value = false;
},
{ once: true },
);
uploader.value?.click();
}
return {
files,
uploader,
isSelecting,
effIcon,
defaultText,
onFileChanged,
onButtonClick,
};
post: {
type: Boolean,
default: true,
},
url: {
type: String,
default: "",
},
text: {
type: String,
default: "",
},
icon: {
type: String,
default: null,
},
fileName: {
type: String,
default: "archive",
},
textBtn: {
type: Boolean,
default: true,
},
accept: {
type: String,
default: "",
},
color: {
type: String,
default: "info",
},
disabled: {
type: Boolean,
default: false,
},
multiple: {
type: Boolean,
default: false,
},
});
const emit = defineEmits<{
(e: "uploaded", payload: File | File[] | unknown | null): void;
}>();
const selectedFiles = ref<File[]>([]);
const uploader = ref<HTMLInputElement | null>(null);
const isSelecting = ref(false);
const i18n = useI18n();
const { $globals } = useNuxtApp();
const effIcon = props.icon ? props.icon : $globals.icons.upload;
const defaultText = i18n.t("general.upload");
const api = useUserApi();
async function upload() {
if (selectedFiles.value.length === 0) {
return;
}
isSelecting.value = true;
if (!props.post) {
emit(UPLOAD_EVENT, props.multiple ? selectedFiles.value : selectedFiles.value[0]);
isSelecting.value = false;
return;
}
if (props.multiple && selectedFiles.value.length > 1) {
console.warn("Multiple file uploads are not supported by the API.");
return;
}
const file = selectedFiles.value[0];
const formData = new FormData();
formData.append(props.fileName, file);
try {
const response = await api.upload.file(props.url, formData);
if (response) {
emit(UPLOAD_EVENT, response);
}
}
catch (e) {
console.error(e);
emit(UPLOAD_EVENT, null);
}
isSelecting.value = false;
}
function onFileChanged(e: Event) {
const target = e.target as HTMLInputElement;
if (target.files !== null && target.files.length > 0) {
selectedFiles.value = Array.from(target.files);
upload();
}
}
function onButtonClick() {
isSelecting.value = true;
window.addEventListener(
"focus",
() => {
isSelecting.value = false;
},
{ once: true },
);
uploader.value?.click();
}
</script>
<style></style>