Files
endurain/frontend/app/src/components/Modals/ModalComponentUploadFile.vue
João Vitória Silva 393badf716 Update JSDoc and documentation standards for JS/TS
Expanded and clarified documentation standards in javatsscript.instructions.md, including detailed JSDoc rules and examples for functions, classes, interfaces, and constants. This update aims to improve code clarity and maintainability by enforcing consistent and concise documentation practices.
2025-11-03 15:41:10 +00:00

141 lines
3.4 KiB
Vue

<template>
<div
ref="modalRef"
class="modal fade"
:id="modalId"
tabindex="-1"
:aria-labelledby="`${modalId}Title`"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" :id="`${modalId}Title`">{{ title }}</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<label :for="`${modalId}FileInput`" class="form-label">
<b>* {{ fileFieldLabel }}</b>
</label>
<input
:id="`${modalId}FileInput`"
ref="fileInputRef"
class="form-control"
type="file"
:name="`${modalId}FileInput`"
:accept="filesAccepted"
:aria-label="fileFieldLabel"
@change="handleFileChange"
required
/>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
aria-label="Close modal"
>
{{ $t('generalItems.buttonClose') }}
</button>
<button
type="button"
@click="submitAction"
class="btn"
:class="{
'btn-success': actionButtonType === 'success',
'btn-danger': actionButtonType === 'danger',
'btn-warning': actionButtonType === 'warning',
'btn-primary': actionButtonType === 'primary'
}"
data-bs-dismiss="modal"
:aria-label="actionButtonText"
>
{{ actionButtonText }}
</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
// Vue composition API
import { ref, onMounted, onUnmounted, type PropType } from 'vue'
// Composables
import { useBootstrapModal } from '@/composables/useBootstrapModal'
// Types
import type { ActionButtonType } from '@/types'
const props = defineProps({
modalId: {
type: String,
required: true
},
title: {
type: String,
required: true
},
fileFieldLabel: {
type: String,
required: true
},
filesAccepted: {
type: String,
required: true
},
actionButtonType: {
type: String as PropType<ActionButtonType>,
required: true,
validator: (value: string) => ['success', 'danger', 'warning', 'primary'].includes(value)
},
actionButtonText: {
type: String,
required: true
}
})
const emit = defineEmits<{
fileToEmitAction: [file: File]
}>()
const { initializeModal, disposeModal } = useBootstrapModal()
const modalRef = ref<HTMLDivElement | null>(null)
const fileInputRef = ref<HTMLInputElement | null>(null)
const selectedFile = ref<File | null>(null)
const handleFileChange = (event: Event): void => {
const target = event.target as HTMLInputElement
const file = target.files?.[0]
if (file) {
selectedFile.value = file
}
}
const submitAction = (): void => {
if (selectedFile.value) {
emit('fileToEmitAction', selectedFile.value)
// Clear file input and selected file
if (fileInputRef.value) {
fileInputRef.value.value = ''
}
selectedFile.value = null
}
}
onMounted(async () => {
await initializeModal(modalRef)
})
onUnmounted(() => {
disposeModal()
})
</script>