-
Daniel Göbel authored
#6
Daniel Göbel authored#6
CreateBucketComponent.vue 4.57 KiB
<script setup lang="ts">
import { BucketService } from "@/client";
import type { BucketIn } from "@/client";
import { reactive, onMounted } from "vue";
import BootstrapModal from "@/components/BootstrapModal.vue";
import { useRouter } from "vue-router";
import { Modal } from "bootstrap";
const router = useRouter();
const emit = defineEmits(["bucketCreated"]);
const bucket = reactive({ name: "", description: "" } as BucketIn);
const formState = reactive({
validated: false,
bucketNameTaken: false,
loading: false,
} as {
validated: boolean;
bucketNameTaken: boolean;
loading: boolean;
});
const props = defineProps<{
modalID: string;
modalLabel: string;
}>();
let createBucketModal: Modal | null = null;
onMounted(() => {
createBucketModal = new Modal("#" + props.modalID);
console.log("Modal ID", props.modalID);
});
function createBucket() {
formState.validated = true;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const form = document.getElementById("bucketCreateForm")! as HTMLFormElement;
formState.bucketNameTaken = false;
if (form.checkValidity()) {
formState.loading = true;
BucketService.bucketCreateBucket(bucket)
.then((createdBucket) => {
emit("bucketCreated", createdBucket);
createBucketModal?.hide();
bucket.name = "";
bucket.description = "";
formState.bucketNameTaken = false;
formState.validated = false;
router.push({
name: "bucket",
params: { bucketName: createdBucket.name, subFolders: [] },
});
})
.catch((error) => {
if (
error.status === 400 &&
error.body["detail"] === "Bucket name is already taken"
) {
formState.bucketNameTaken = true;
}
})
.finally(() => {
formState.loading = false;
});
}
}
function modalClosed() {
formState.validated = false;
formState.bucketNameTaken = false;
}
</script>
<template>
<bootstrap-modal
:modal-id="modalID"
:static-backdrop="true"
:modal-label="modalLabel"
v-on="{ 'hidden.bs.modal': modalClosed }"
>
<template v-slot:header> Create new Bucket </template>
<template v-slot:body>
<form
id="bucketCreateForm"
:class="{ 'was-validated': formState.validated }"
novalidate
>
<div class="mb-3">
<label for="bucketNameInput" class="form-label">Bucket Name</label>
<div class="input-group">
<input
type="text"
class="form-control"
id="bucketNameInput"
required
minlength="3"
maxlength="63"
pattern="(?!(^((2(5[0-5]|[0-4]\d)|[01]?\d{1,2})\.){3}(2(5[0-5]|[0-4]\d)|[01]?\d{1,2})$))^[a-z\d][a-z\d.-]{1,61}[a-z\d]$"
v-model.trim="bucket.name"
/>
<div class="invalid-feedback">
Requirements
<ul>
<li>At least 3 Characters long</li>
<li>Lowercase</li>
<li>Only [a-z][0-9].-</li>
<li>No IP address</li>
</ul>
</div>
</div>
</div>
<div class="mb-3">
<label for="bucketDescriptionInput" class="form-label">
Description
</label>
<div class="input-group">
<textarea
class="form-control"
id="bucketDescriptionInput"
required
rows="5"
minlength="126"
maxlength="65536"
v-model.trim="bucket.description"
placeholder="Describe the purpose of the bucket"
></textarea>
<div class="invalid-feedback">
Requirements
<ul>
<li>At least 126 Characters long</li>
</ul>
</div>
</div>
</div>
</form>
<div v-if="formState.bucketNameTaken" class="text-danger">
Bucket name already taken.
</div>
</template>
<template v-slot:footer>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button
type="submit"
form="bucketCreateForm"
class="btn btn-primary"
:disabled="formState.loading"
@click.prevent="createBucket"
>
<span
v-if="formState.loading"
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
Save
</button>
</template>
</bootstrap-modal>
</template>
<style scoped></style>