Files
mealie/frontend/components/global/AppButtonUpload.vue

155 lines
2.9 KiB
Vue
Raw Normal View History

<template>
2026-03-23 21:18:25 +01:00
<v-form ref="form">
<input
ref="uploader"
class="d-none"
type="file"
:accept="accept"
:multiple="multiple"
@change="onFileChanged"
>
<slot v-bind="{ isSelecting, onButtonClick }">
<v-btn
:loading="isSelecting"
:small="small"
:color="color"
:variant="textBtn ? 'text' : 'elevated'"
:disabled="disabled"
@click="onButtonClick"
>
<v-icon start>
{{ effIcon }}
</v-icon>
{{ text ? text : defaultText }}
</v-btn>
</slot>
</v-form>
</template>
2026-03-23 21:18:25 +01:00
<script setup lang="ts">
import { useUserApi } from "~/composables/api";
Use composition API for more components, enable more type checking (#914) * Activate more linting rules from eslint and typescript * Properly add VForm as type information * Fix usage of native types * Fix more linting issues * Rename vuetify types file, add VTooltip * Fix some more typing problems * Use composition API for more components * Convert RecipeRating * Convert RecipeNutrition * Convert more components to composition API * Fix globals plugin for type checking * Add missing icon types * Fix vuetify types in Nuxt context * Use composition API for RecipeActionMenu * Convert error.vue to composition API * Convert RecipeContextMenu to composition API * Use more composition API and type checking in recipe/create * Convert AppButtonUpload to composition API * Fix some type checking in RecipeContextMenu * Remove unused components BaseAutoForm and BaseColorPicker * Convert RecipeCategoryTagDialog to composition API * Convert RecipeCardSection to composition API * Convert RecipeCategoryTagSelector to composition API * Properly import vuetify type definitions * Convert BaseButton to composition API * Convert AutoForm to composition API * Remove unused requests API file * Remove static routes from recipe API * Fix more type errors * Convert AppHeader to composition API, fixing some search bar focus problems * Convert RecipeDialogSearch to composition API * Update API types from pydantic models, handle undefined values * Improve more typing problems * Add types to other plugins * Properly type the CRUD API access * Fix typing of static image routes * Fix more typing stuff * Fix some more typing problems * Turn off more rules
2022-01-09 07:15:23 +01:00
const UPLOAD_EVENT = "uploaded";
Use composition API for more components, enable more type checking (#914) * Activate more linting rules from eslint and typescript * Properly add VForm as type information * Fix usage of native types * Fix more linting issues * Rename vuetify types file, add VTooltip * Fix some more typing problems * Use composition API for more components * Convert RecipeRating * Convert RecipeNutrition * Convert more components to composition API * Fix globals plugin for type checking * Add missing icon types * Fix vuetify types in Nuxt context * Use composition API for RecipeActionMenu * Convert error.vue to composition API * Convert RecipeContextMenu to composition API * Use more composition API and type checking in recipe/create * Convert AppButtonUpload to composition API * Fix some type checking in RecipeContextMenu * Remove unused components BaseAutoForm and BaseColorPicker * Convert RecipeCategoryTagDialog to composition API * Convert RecipeCardSection to composition API * Convert RecipeCategoryTagSelector to composition API * Properly import vuetify type definitions * Convert BaseButton to composition API * Convert AutoForm to composition API * Remove unused requests API file * Remove static routes from recipe API * Fix more type errors * Convert AppHeader to composition API, fixing some search bar focus problems * Convert RecipeDialogSearch to composition API * Update API types from pydantic models, handle undefined values * Improve more typing problems * Add types to other plugins * Properly type the CRUD API access * Fix typing of static image routes * Fix more typing stuff * Fix some more typing problems * Turn off more rules
2022-01-09 07:15:23 +01:00
2026-03-23 21:18:25 +01:00
const props = defineProps({
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: "",
},
2026-03-23 21:18:25 +01:00
color: {
type: String,
default: "info",
},
disabled: {
type: Boolean,
default: false,
},
multiple: {
type: Boolean,
default: false,
},
});
2026-03-23 21:18:25 +01:00
const emit = defineEmits<{
(e: "uploaded", payload: File | File[] | unknown | null): void;
}>();
Use composition API for more components, enable more type checking (#914) * Activate more linting rules from eslint and typescript * Properly add VForm as type information * Fix usage of native types * Fix more linting issues * Rename vuetify types file, add VTooltip * Fix some more typing problems * Use composition API for more components * Convert RecipeRating * Convert RecipeNutrition * Convert more components to composition API * Fix globals plugin for type checking * Add missing icon types * Fix vuetify types in Nuxt context * Use composition API for RecipeActionMenu * Convert error.vue to composition API * Convert RecipeContextMenu to composition API * Use more composition API and type checking in recipe/create * Convert AppButtonUpload to composition API * Fix some type checking in RecipeContextMenu * Remove unused components BaseAutoForm and BaseColorPicker * Convert RecipeCategoryTagDialog to composition API * Convert RecipeCardSection to composition API * Convert RecipeCategoryTagSelector to composition API * Properly import vuetify type definitions * Convert BaseButton to composition API * Convert AutoForm to composition API * Remove unused requests API file * Remove static routes from recipe API * Fix more type errors * Convert AppHeader to composition API, fixing some search bar focus problems * Convert RecipeDialogSearch to composition API * Update API types from pydantic models, handle undefined values * Improve more typing problems * Add types to other plugins * Properly type the CRUD API access * Fix typing of static image routes * Fix more typing stuff * Fix some more typing problems * Turn off more rules
2022-01-09 07:15:23 +01:00
2026-03-23 21:18:25 +01:00
const selectedFiles = ref<File[]>([]);
const uploader = ref<HTMLInputElement | null>(null);
const isSelecting = ref(false);
2026-03-23 21:18:25 +01:00
const i18n = useI18n();
const { $globals } = useNuxtApp();
const effIcon = props.icon ? props.icon : $globals.icons.upload;
Use composition API for more components, enable more type checking (#914) * Activate more linting rules from eslint and typescript * Properly add VForm as type information * Fix usage of native types * Fix more linting issues * Rename vuetify types file, add VTooltip * Fix some more typing problems * Use composition API for more components * Convert RecipeRating * Convert RecipeNutrition * Convert more components to composition API * Fix globals plugin for type checking * Add missing icon types * Fix vuetify types in Nuxt context * Use composition API for RecipeActionMenu * Convert error.vue to composition API * Convert RecipeContextMenu to composition API * Use more composition API and type checking in recipe/create * Convert AppButtonUpload to composition API * Fix some type checking in RecipeContextMenu * Remove unused components BaseAutoForm and BaseColorPicker * Convert RecipeCategoryTagDialog to composition API * Convert RecipeCardSection to composition API * Convert RecipeCategoryTagSelector to composition API * Properly import vuetify type definitions * Convert BaseButton to composition API * Convert AutoForm to composition API * Remove unused requests API file * Remove static routes from recipe API * Fix more type errors * Convert AppHeader to composition API, fixing some search bar focus problems * Convert RecipeDialogSearch to composition API * Update API types from pydantic models, handle undefined values * Improve more typing problems * Add types to other plugins * Properly type the CRUD API access * Fix typing of static image routes * Fix more typing stuff * Fix some more typing problems * Turn off more rules
2022-01-09 07:15:23 +01:00
2026-03-23 21:18:25 +01:00
const defaultText = i18n.t("general.upload");
2026-03-23 21:18:25 +01:00
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>