Skip to content
Snippets Groups Projects
CreateBucketModal.vue 5.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • <script setup lang="ts">
    
    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 { Modal } from "bootstrap";
    
    import { useBucketStore } from "@/stores/buckets";
    
    const router = useRouter();
    
    const bucketRepository = useBucketStore();
    
    const bucketCreateForm = ref<HTMLFormElement | undefined>(undefined);
    
    const bucketNameElement = ref<HTMLInputElement | undefined>(undefined);
    
    const bucket = reactive<BucketIn>({ name: "", description: "" });
    
    
    const formState = reactive<{
    
      validated: boolean;
      bucketNameTaken: boolean;
      loading: boolean;
    
    }>({
      validated: false,
      bucketNameTaken: false,
      loading: false,
    
    const props = defineProps<{
      modalID: string;
    
    let createBucketModal: Modal | null = null;
    
    
    onMounted(() => {
    
      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()) {
    
        formState.loading = true;
    
        bucketRepository
          .createBucket(bucket)
          .then((createdBucket) => {
    
            createBucketModal?.hide();
    
            bucket.name = "";
            bucket.description = "";
            formState.bucketNameTaken = false;
            formState.validated = false;
    
            router.push({
              name: "bucket",
              params: { bucketName: createdBucket.name, subFolders: [] },
            });
    
            if (
              error.status === 400 &&
              error.body["detail"] === "Bucket name is already taken"
            ) {
              formState.bucketNameTaken = true;
    
              bucketNameElement.value?.setCustomValidity(
                "Bucket name is already taken",
              );
    
            formState.loading = false;
    
      }
    }
    
    function modalClosed() {
      formState.validated = false;
      formState.bucketNameTaken = false;
    
      bucketNameElement.value?.setCustomValidity("");
    
    }
    </script>
    
    <template>
      <bootstrap-modal
    
        :static-backdrop="true"
    
        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 }"
    
            ref="bucketCreateForm"
    
          >
            <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])?$"
    
                  ref="bucketNameElement"
    
                />
                <div class="invalid-feedback">
    
                  <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
    
                  maxlength="65536"
    
                  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>