<script setup lang="ts"> import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { useAuthStore } from "@/stores/users"; import { useRoute } from "vue-router"; import { useCookies } from "vue3-cookies"; import { watch, ref, computed } from "vue"; import BootstrapModal from "@/components/modals/BootstrapModal.vue"; import { OpenAPI as S3ProxyOpenAPI } from "@/client/s3proxy"; import { OpenAPI as AuthOpenAPI } from "@/client/auth"; import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow"; import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue"; import dayjs from "dayjs"; const store = useAuthStore(); const { cookies } = useCookies(); const route = useRoute(); function logout() { store.logout(); cookies.remove("bearer"); } const activeRoute = ref(""); const objectStorageActive = computed<boolean>( () => activeRoute.value == "buckets" || activeRoute.value == "s3_keys", ); const workflowActive = computed<boolean>( () => activeRoute.value == "workflows", ); watch( () => route.name, (to) => { if (typeof to === "string") { if (to.startsWith("bucket")) { activeRoute.value = "buckets"; } else if (to.startsWith("workflow")) { activeRoute.value = "workflows"; } else { activeRoute.value = to; } } else { activeRoute.value = ""; } }, ); </script> <template> <header class="navbar navbar-expand-lg bd-navbar sticky-top border-bottom border-secondary" > <nav class="container-xxl bd-gutter flex-wrap flex-lg-nowrap text-light"> <router-link class="navbar-brand ms-3 text-white d-flex align-items-center" to="/" > <img src="/src/assets/images/clowm.svg" alt="CloWM Icon" width="32" height="32" class="d-inline-block align-text-top me-2" /> CloWM </router-link> <div class="d-flex me-auto w-fit" v-if="store.authenticated"> <ul class="navbar-nav"> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" id="" :class="{ 'text-black': objectStorageActive }" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="true" > Files </a> <ul class="dropdown-menu shadow m-0" aria-labelledby="objectStoreDropdown" > <li> <router-link class="dropdown-item" :to="{ name: 'buckets' }" >My Data Buckets </router-link> </li> <li> <router-link class="dropdown-item" :to="{ name: 's3_keys' }" >S3 Bucket Keys </router-link> </li> </ul> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" :class="{ 'text-black': workflowActive }" id="workflowDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="true" > Workflows </a> <ul class="dropdown-menu shadow m-0" aria-labelledby="workflowDropdown" > <li> <router-link class="dropdown-item" :to="{ name: 'workflows' }" >Available Workflows </router-link> </li> <li> <router-link class="dropdown-item" :to="{ name: 'workflow-executions' }" >My Workflow Executions </router-link> </li> <li v-if=" store.workflowDev || store.workflowReviewer || store.admin " > <hr class="dropdown-divider" /> </li> <li v-if="store.workflowDev || store.admin"> <router-link class="dropdown-item" :to="{ name: 'workflows-developer' }" >My Workflows </router-link> </li> <li v-if="store.workflowReviewer || store.admin"> <router-link class="dropdown-item" :to="{ name: 'workflows-reviewer' }" >Reviews </router-link> </li> </ul> </li> </ul> </div> <div class="dropdown" v-if="store.authenticated && store.user != null"> <a href="#" class="d-flex align-items-center text-white text-decoration-none dropdown-toggle-split" id="dropdownUser1" data-bs-toggle="dropdown" aria-expanded="false" > <strong class="me-2">{{ store.user.display_name }}</strong> <font-awesome-icon icon="fa-solid fa-circle-user" class="fs-5" /> </a> <ul class="dropdown-menu text-small shadow" aria-labelledby="dropdownUser1" > <li> <a href="#" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#advancedUsageModal" >Advanced Usage</a > </li> <li> <hr class="dropdown-divider" /> </li> <li><h6 class="dropdown-header">Roles</h6></li> <li v-for="role in store.roles" :key="role" class="dropdown-item text-capitalize disabled" > {{ role }} </li> <li> <hr class="dropdown-divider" /> </li> <li> <router-link :to="{ name: 'login' }" class="dropdown-item" @click="logout" > Sign out </router-link> </li> </ul> </div> </nav> </header> <bootstrap-modal static-backdrop modal-i-d="advancedUsageModal" modal-label="Advanced Usage Modal" v-if="store.authenticated" > <template v-slot:header> <h3>Advanced Usage</h3> </template> <template v-slot:body> <table class="table table-borderless table-sm"> <tbody> <tr> <td class="text-end">Auth Service:</td> <td> <a :href="AuthOpenAPI.BASE + '/docs'" target="_blank"> <font-awesome-icon class="me-1" icon="fa-solid fa-arrow-up-right-from-square" /> {{ AuthOpenAPI.BASE }}</a > </td> </tr> <tr> <td class="text-end">S3Proxy Service:</td> <td> <a :href="S3ProxyOpenAPI.BASE + '/docs'" target="_blank"> <font-awesome-icon class="me-1" icon="fa-solid fa-arrow-up-right-from-square" /> {{ S3ProxyOpenAPI.BASE }}</a > </td> </tr> <tr> <td class="text-end">Workflow Service:</td> <td> <a :href="WorkflowOpenAPI.BASE + '/docs'" target="_blank"> <font-awesome-icon class="me-1" icon="fa-solid fa-arrow-up-right-from-square" /> {{ WorkflowOpenAPI.BASE }}</a > </td> </tr> </tbody> </table> <div class="mt-4"> <label for="clowm-jwt" class="form-label" >JWT for Services (expires at {{ dayjs.unix(store.decodedToken!.exp).format("DD.MM.YYYY HH:mm") }})</label > <div class="input-group"> <input type="text" readonly class="form-control text-truncate" id="clowm-jwt" :value="store.token" aria-describedby="clowm-jwt-copy" /> <span class="input-group-text" id="clowm-jwt-copy" ><copy-to-clipboard-icon :text="store.token ?? ''" /></span> </div> </div> </template> <template v-slot:footer> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"> Close </button> </template> </bootstrap-modal> </template> <style scoped> header { background: rgb(255, 177, 45); } </style>