Newer
Older
import type { BucketIn } from "@/client/s3proxy";
import { reactive, onMounted, ref } from "vue";
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import { useRouter } from "vue-router";
import { useBucketStore } from "@/stores/buckets";
const bucketRepository = useBucketStore();
const bucketCreateForm = ref<HTMLFormElement | undefined>(undefined);
const bucketNameElement = ref<HTMLInputElement | undefined>(undefined);
const bucket = reactive<BucketIn>({ name: "", description: "" });
validated: boolean;
bucketNameTaken: boolean;
loading: boolean;
}>({
validated: false,
bucketNameTaken: false,
loading: false,
const props = defineProps<{
modalID: string;
let createBucketModal: Modal | null = null;
createBucketModal = new Modal("#" + props.modalID);
});
function createBucket() {
formState.validated = true;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
formState.bucketNameTaken = false;
bucket.description = bucket.description.trim();
bucket.name = bucket.name.trim();
bucketNameElement.value?.setCustomValidity("");
if (bucketCreateForm.value?.checkValidity()) {
bucketRepository
.createBucket(bucket)
.then((createdBucket) => {
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;
bucketNameElement.value?.setCustomValidity(
"Bucket name is already taken",
);
})
.finally(() => {
}
}
function modalClosed() {
formState.validated = false;
formState.bucketNameTaken = false;
bucketNameElement.value?.setCustomValidity("");
}
</script>
<template>
<bootstrap-modal
modal-label="Create Bucket Modal"
v-on="{ 'hidden.bs.modal': modalClosed }"
>
<template v-slot:header> Create new S3 Bucket</template>
<template v-slot:body>
<form
id="bucketCreateForm"
:class="{ 'was-validated': formState.validated }"
>
<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="(?!(^(\d+\.){3}\d+$))^([a-z0-9](?:[a-z0-9\-]*[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?$"
v-model="bucket.name"
<div v-if="formState.bucketNameTaken">
Bucket name already taken.
</div>
<div>
Requirements
<ul>
<li>At least 3 Characters long</li>
<li>Unique in CloWM</li>
<li>
Only lowercase letters, numbers, single periods (.) and
hyphen (-)
</li>
<li>Start and end with letter or number</li>
<li>
A letter or number must be before and after a period (.)
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="mb-3">
<label for="bucketDescriptionInput" class="form-label">
</label>
<div class="input-group">
<textarea
class="form-control"
id="bucketDescriptionInput"
required
v-model="bucket.description"
placeholder="Describe the purpose of the bucket"
></textarea>
<div class="invalid-feedback">
Requirements
<ul>
<li>At least 32 Characters long</li>
</ul>
</div>
</div>
</div>
</form>
</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>