<script setup lang="ts"> import { onBeforeMount, onMounted } from "vue"; import { useCookies } from "vue3-cookies"; import { useRoute, useRouter } from "vue-router"; import { client } from "@/client/sdk.gen.ts"; import { environment } from "@/environment"; import AppHeader from "@/components/AppHeader.vue"; import AppFooter from "@/components/AppFooter.vue"; import { useNameStore, useUserStore, useResourceStore, useWorkflowStore, useBucketStore, useS3KeyStore, useS3ObjectStore, useOTRStore, useWorkflowExecutionStore, useNewsStore, } from "@/stores"; import { stringify as param_stringify } from "qs"; import { OwnershipTypeEnum } from "@/client/types.gen"; const { cookies } = useCookies(); const router = useRouter(); const route = useRoute(); const userRepository = useUserStore(); const nameRepository = useNameStore(); const resourceRepository = useResourceStore(); const workflowRepository = useWorkflowStore(); const bucketRepository = useBucketStore(); const s3KeyRepository = useS3KeyStore(); const objectRepository = useS3ObjectStore(); const otrRepository = useOTRStore(); const executionRepository = useWorkflowExecutionStore(); const newsStore = useNewsStore(); onBeforeMount(() => { client.setConfig({ baseURL: environment.API_BASE_URL, paramsSerializer: (params) => param_stringify(params, { arrayFormat: "repeat" }), }); userRepository.updateJWT(cookies.get("clowm-jwt")); if (userRepository.authenticated) { userRepository.getCurrentUser(); } client.instance.interceptors.response.use( (res) => res, (err) => { if ( err.response.status === 401 || (err.response.status === 400 && err.response.data.detail?.includes("JWT")) ) { userRepository.logout(); router.push({ name: "login", query: { login_error: err.response.status === 401 ? "session token invalid" : "session expired", next: route.name !== "login" ? encodeURI(route.path) : undefined, }, }); } return Promise.reject(err); }, ); router.afterEach((to, from) => { window._paq?.push(["setReferrerUrl", from.path]); window._paq?.push(["deleteCustomVariables", "page"]); window._paq?.push(["deleteCustomDimension", 1]); const mtm_query_keys = Object.keys(to.query ?? {}).filter((key) => key.startsWith("mtm_"), ); const mtm_query = mtm_query_keys.length > 0 ? mtm_query_keys .slice(1) .reduce( (prev, cur) => prev + `&${cur}=${to.query[cur]}`, `?${mtm_query_keys[0]}=${to.query[mtm_query_keys[0]]}`, ) : ""; window._paq?.push(["setCustomUrl", to.path + mtm_query]); window._paq?.push(["setDocumentTitle", to.name]); if (userRepository.currentUID.length > 0) { window._paq?.push(["setUserId", userRepository.currentUID]); } window._paq?.push(["trackPageView"]); window._paq?.push(["enableLinkTracking"]); }); router.beforeEach((to) => { // redirect path that start with '/dashboard' to ensure backwards compatibility if (/^\/dashboard\/[\w]+/.test(to.fullPath)) { return to.fullPath.slice(10); } }); router.beforeEach(async (to) => { // make sure the user is authenticated if (to.meta.public) { return; } if ( !userRepository.authenticated && // ❗️ Avoid an infinite redirect to.name !== "login" ) { // redirect the user to the login page and preserve query params for login error message return { name: "login", query: { ...to.query, next: encodeURI(to.path) }, }; } else if ( to.meta.requiresDeveloperRole && !(userRepository.workflowDev || userRepository.admin) ) { return { name: "workflows" }; } else if ( to.meta.requiresReviewerRole && !(userRepository.reviewer || userRepository.admin) ) { return "/"; } else if ( to.meta.requiresMaintainerRole && !(userRepository.resourceMaintainer || userRepository.admin) ) { return { name: "resources" }; } else if (to.meta.adminRole && !userRepository.admin) { return "/"; } else if (to.name !== "login" && to.query.next) { // return to original path after login return { path: decodeURI(to.query.next as string) }; } }); nameRepository.loadNameMapping(); }); onMounted(() => { if (userRepository.authenticated) { Promise.all([ s3KeyRepository.fetchS3Keys(), bucketRepository.fetchOwnBuckets(), ]).then(() => { Promise.all( bucketRepository.buckets .filter((bucket) => bucket.owner_id === userRepository.currentUID) .map((bucket) => objectRepository.fetchMultipartUploads(bucket.name)), ); }); resourceRepository.fetchPublicResources(); workflowRepository.fetchWorkflows(); otrRepository.fetchOwnOtrs(OwnershipTypeEnum.BUCKET); executionRepository.fetchExecutions(); newsStore.fetchCurrentNews(); if (!userRepository.foreignUser) { bucketRepository.fetchOwnPermissions(); } if (userRepository.workflowDev || userRepository.admin) { workflowRepository.fetchOwnWorkflows(); otrRepository.fetchOwnOtrs(OwnershipTypeEnum.WORKFLOW); } if (userRepository.resourceMaintainer || userRepository.admin) { resourceRepository.fetchOwnResources(); otrRepository.fetchOwnOtrs(OwnershipTypeEnum.RESOURCE); } if (userRepository.admin) { resourceRepository.fetchSyncRequests(); } } }); </script> <template> <AppHeader /> <div class="container-fluid container-xxxl mt-2 flex-grow-1 py-2"> <router-view /> </div> <AppFooter /> </template> <style scoped></style>