Skip to content
Snippets Groups Projects
S3KeysView.vue 5.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Daniel Göbel's avatar
    Daniel Göbel committed
    <script setup lang="ts">
    
    import S3KeyView from "@/views/object-storage/S3KeyView.vue";
    
    import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
    
    Daniel Göbel's avatar
    Daniel Göbel committed
    import { reactive, onMounted, computed } from "vue";
    
    import type { S3Key } from "@/client/s3proxy";
    import { S3KeyService } from "@/client/s3proxy";
    
    Daniel Göbel's avatar
    Daniel Göbel committed
    import { useAuthStore } from "@/stores/auth";
    import { Toast } from "bootstrap";
    
    const authStore = useAuthStore();
    
    authStore.$onAction(({ name, args }) => {
      if (name === "updateUser") {
        refreshKeys(args[0].uid);
      }
    });
    
    let successToast: Toast | null = null;
    
    
    const keyState = reactive<{
    
    Daniel Göbel's avatar
    Daniel Göbel committed
      keys: S3Key[];
      activeKey: number;
      initialLoading: boolean;
      deletedKey: string;
    
    }>({
      keys: [],
      activeKey: 0,
      initialLoading: true,
      deletedKey: "",
    
    Daniel Göbel's avatar
    Daniel Göbel committed
    });
    
    
    const allowKeyDeletion = computed<boolean>(() => keyState.keys.length > 1);
    
    Daniel Göbel's avatar
    Daniel Göbel committed
    
    function refreshKeys(uid: string) {
    
      S3KeyService.s3KeyGetUserKeys(uid)
    
    Daniel Göbel's avatar
    Daniel Göbel committed
        .then((keys) => {
          if (keyState.activeKey >= keys.length) {
            keyState.activeKey = keys.length - 1;
          }
          keyState.keys = keys;
        })
        .catch((err) => console.error(err))
        .finally(() => (keyState.initialLoading = false));
    }
    
    function deleteKey(accessKey: string) {
    
      if (allowKeyDeletion.value && authStore.authenticated) {
        S3KeyService.s3KeyDeleteUserKey(accessKey, authStore.currentUID)
    
    Daniel Göbel's avatar
    Daniel Göbel committed
          .then(() => {
            keyState.deletedKey = accessKey;
            keyState.activeKey = 0;
            keyState.keys = keyState.keys.filter(
    
              (s3key) => s3key.access_key !== accessKey,
    
    Daniel Göbel's avatar
    Daniel Göbel committed
            );
            authStore.setS3Key(keyState.keys[0]);
            successToast?.show();
          })
          .catch((err) => console.error(err));
      }
    }
    
    function createKey() {
    
      if (authStore.authenticated) {
        S3KeyService.s3KeyCreateUserKey(authStore.currentUID)
    
    Daniel Göbel's avatar
    Daniel Göbel committed
          .then((s3key) => {
            keyState.keys.push(s3key);
            keyState.keys = [...keyState.keys].sort((keyA, keyB) =>
    
              keyA.access_key > keyB.access_key ? 1 : -1,
    
    Daniel Göbel's avatar
    Daniel Göbel committed
            );
          })
          .catch((err) => console.error(err));
      }
    }
    
    onMounted(() => {
      successToast = new Toast("#successKeyToast");
    
      if (authStore.authenticated) {
        refreshKeys(authStore.currentUID);
    
    Daniel Göbel's avatar
    Daniel Göbel committed
      }
    });
    </script>
    
    
    Daniel Göbel's avatar
    Daniel Göbel committed
    <template>
    
    Daniel Göbel's avatar
    Daniel Göbel committed
      <div class="toast-container position-fixed top-toast end-0 p-3">
        <div
          role="alert"
          aria-live="assertive"
          aria-atomic="true"
          class="toast text-bg-success align-items-center border-0"
          data-bs-autohide="true"
          :id="'successKeyToast'"
        >
          <div class="d-flex">
            <div class="toast-body">
    
              Successfully deleted S3 Key {{ keyState.deletedKey.slice(0, 5) }}...
    
    Daniel Göbel's avatar
    Daniel Göbel committed
            </div>
            <button
              type="button"
              class="btn-close btn-close-white me-2 m-auto"
              data-bs-dismiss="toast"
              aria-label="Close"
            ></button>
          </div>
        </div>
      </div>
    
      <div class="row m-2 border-bottom mt-4">
    
    Daniel Göbel's avatar
    Daniel Göbel committed
        <div class="col-12"></div>
    
    Daniel Göbel's avatar
    Daniel Göbel committed
      </div>
      <div class="row m-2 mt-4">
        <div class="col-4">
          <div class="d-flex justify-content-between mb-4">
            <button
              type="button"
    
              class="btn btn-light border shadow-sm"
    
              @click="refreshKeys(authStore.currentUID)"
    
    Daniel Göbel's avatar
    Daniel Göbel committed
            >
    
              <font-awesome-icon
                icon="fa-solid fa-arrow-rotate-right"
                class="fs-5"
              />
    
    Daniel Göbel's avatar
    Daniel Göbel committed
              <span class="visually-hidden">Refresh S3 Keys</span>
            </button>
    
            <button
              type="button"
              class="btn btn-light border shadow-sm"
              @click="createKey"
            >
    
              <font-awesome-icon icon="fa-solid fa-plus" class="fs-5" />
    
    Daniel Göbel's avatar
    Daniel Göbel committed
              <span class="visually-hidden">Create S3 Key</span>
            </button>
          </div>
          <div v-if="keyState.initialLoading" class="placeholder-glow">
            <a
              v-for="n in 3"
              :key="n"
              type="button"
              aria-hidden="true"
              class="btn w-100 fs-5 mb-3 btn-secondary disabled placeholder"
            />
          </div>
    
          <div v-else class="d-grid gap-3">
    
    Daniel Göbel's avatar
    Daniel Göbel committed
            <button
              v-for="(s3key, index) in keyState.keys"
              :key="s3key.access_key"
    
              class="btn fs-5 text-truncate border hover-shadow"
    
    Daniel Göbel's avatar
    Daniel Göbel committed
              type="button"
              @click="keyState.activeKey = index"
              :class="{
                'btn-light': keyState.activeKey !== index,
                'btn-primary': keyState.activeKey === index,
    
                shadow: keyState.activeKey === index,
    
    Daniel Göbel's avatar
    Daniel Göbel committed
              }"
            >
    
              {{ s3key.access_key.slice(0, 5) }}...
    
    Daniel Göbel's avatar
    Daniel Göbel committed
            </button>
          </div>
        </div>
        <div class="col-7 offset-md-1">
          <s3-key-view
            v-if="keyState.keys.length > 0 || keyState.initialLoading"
            :s3key="
              keyState.initialLoading
                ? { user: '', access_key: '', secret_key: '' }
                : keyState.keys[keyState.activeKey]
            "
            :deletable="allowKeyDeletion"
            :loading="keyState.initialLoading"
            @delete-key="deleteKey"
          />
          <div v-else>
            No keys here. <br />
            Create a new Key to interact with your Buckets again.
          </div>
        </div>
    
    Daniel Göbel's avatar
    Daniel Göbel committed
      </div>
    </template>
    
    
    Daniel Göbel's avatar
    Daniel Göbel committed
    <style scoped></style>