<script setup lang="ts"> import BootstrapModal from "@/components/modals/BootstrapModal.vue"; import { computed, onMounted, reactive } from "vue"; import { Modal, Toast } from "bootstrap"; import { useS3ObjectStore } from "@/stores/s3objects"; import BootstrapToast from "@/components/BootstrapToast.vue"; const objectRepository = useS3ObjectStore(); const props = defineProps<{ modalID: string; bucketName: string; keyPrefix: string; }>(); const randomIDSuffix = Math.random().toString(16).substring(2, 8); let uploadModal: Modal | null = null; let successToast: Toast | null = null; let errorToast: Toast | null = null; const currentFolders = computed<string[]>(() => props.keyPrefix.split("/")); const formState = reactive<{ folderName: string; uploading: boolean; }>({ folderName: "", uploading: false, }); function uploadFolder() { const key = props.keyPrefix.length > 0 ? props.keyPrefix + "/" + formState.folderName : formState.folderName; const reversedKey = key .replace(/(\/)\1+/g, "/") .split("") .reverse(); const firstLetterIndex = reversedKey.findIndex((char) => char !== "/"); if (firstLetterIndex < 0) { return; } const realKey = reversedKey.slice(firstLetterIndex).reverse().join("") + "/"; formState.uploading = true; objectRepository .createFolder(props.bucketName, realKey) .then(() => { uploadModal?.hide(); successToast?.show(); formState.folderName = ""; }) .catch((e) => { console.error(e); errorToast?.show(); }) .finally(() => { formState.uploading = false; }); } onMounted(() => { uploadModal = new Modal("#" + props.modalID); successToast = new Toast("#successToast-" + randomIDSuffix); errorToast = new Toast("#errorToast-" + randomIDSuffix); }); </script> <template> <bootstrap-toast :toast-id="'successToast-' + randomIDSuffix"> Successfully created Folder </bootstrap-toast> <bootstrap-toast :toast-id="'errorToast-' + randomIDSuffix" color-class="danger" > There has been some Error.<br /> Try again later </bootstrap-toast> <bootstrap-modal :modalId="modalID" :static-backdrop="true" modal-label="Create Folder Modal" > <template v-slot:header> <h4>Create folder in</h4> <ol class="breadcrumb"> <li class="breadcrumb-item">{{ props.bucketName }}</li> <li class="breadcrumb-item" v-for="folder in currentFolders" :key="folder" > {{ folder }} </li> </ol> </template> <template v-slot:body> <div class="container-fluid"> <div class="row"> <form class="col-7" :id="'uploadFolderForm' + randomIDSuffix" @submit.prevent="uploadFolder" > <div class="mb-3"> <label :for="'folderName' + randomIDSuffix" class="form-label" >Folder Name</label > <input type="text" class="form-control" :id="'folderName' + randomIDSuffix" required v-model="formState.folderName" /> </div> </form> <div class="col-5"> Note: Delimiters ('/') are allowed in the folder name to place the new folder into a folder that will be created when the folder is created (to any depth of folders). </div> </div> </div> </template> <template v-slot:footer> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"> Close </button> <button :disabled="formState.uploading" type="submit" :form="'uploadFolderForm' + randomIDSuffix" class="btn btn-primary" > <span v-if="formState.uploading" class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ></span> Create </button> </template> </bootstrap-modal> </template> <style scoped></style>