Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
index.ts 3.51 KiB
import Vue from "vue";
import VueRouter, { RawLocation, Route, RouteConfig } from "vue-router";

import { AdminRoutes } from "@/modules/admin/routes";
import { LoginRoutes } from "@/modules/login/routes";
import { PidRoutes } from "@/modules/pid/routes";
import { ProjectRoutes } from "@/modules/project/routes";
import { UserRoutes } from "@/modules/user/routes";
import { SearchRoutes } from "@/modules/search/routes";
import { ErrorRoutes } from "@/modules/error/routes";

Vue.use(VueRouter);

export const routes: RouteConfig[] = [
  // Module Routes
  ...AdminRoutes,
  ...LoginRoutes,
  ...PidRoutes,
  ...ProjectRoutes,
  ...UserRoutes,
  ...SearchRoutes,

  ...ErrorRoutes,
];

const router = new VueRouter({
  base: import.meta.env.BASE_URL,
  mode: "history",
  routes,
});

export default router;

// Additional method to silence "NavigationDuplicated" errors when source and target routes are equal
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = async function (location: RawLocation) {
  let route: Route;
  try {
    route = await originalPush.call<VueRouter, [RawLocation], Promise<Route>>(
      this,
      location
    );
  } catch (err) {
    if (err instanceof Error) {
      if (err.name !== "NavigationDuplicated") {
        throw err;
      }
    }
  }
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  return route!;
};

// Import the relevant stores
import useMainStore from "@/store/index";
import useUserStore from "@/modules/user/store";
import type { ProjectObject } from "@coscine/api-client/dist/types/Coscine.Api.Project";
import i18n, { def } from "@/plugins/vue-i18n";
import type VueI18n from "vue-i18n";

router.beforeEach((to, _, next) => {
  // Replace the available locale messages
  const localeMessages: VueI18n.LocaleMessages | undefined = to.matched
    .map((e) => e.meta.i18n)
    .filter((i) => i)
    .pop();
  if (localeMessages) {
    i18n.availableLocales.forEach((locale) => {
      i18n.setLocaleMessage(locale, def[locale]); // default locale messages
      i18n.mergeLocaleMessage(locale, localeMessages[locale]); // append the locale messages for the component
    });
  }
  // Define the relevant stores
  const mainStore = useMainStore();
  const userStore = useUserStore();

  // Handle access token from URL
  mainStore.setAccessTokenFromRoute(router, to);
  // Handle contact change token from URL
  userStore.resolveContactChangeToken(router, to);
  // Collect ongoing Maintenance information
  mainStore.getMaintenance();
  if (to.meta?.requiresAuth && !mainStore.loggedIn) {
    // Route requires auth, check if logged in
    // if not, redirect to login page.
    next({
      path: "/login",
      // Save the location we were at to come back later
      query: { redirect: to.fullPath },
    });
  } else {
    // Continue navigation
    next();
  }
});

export const removeQueryParameterFromUrl = function (
  route: Route,
  param: string
) {
  // Remove /?<param>=... from the URL
  const newQuery = route.query;
  if (newQuery[param] !== null && newQuery[param] !== undefined) {
    delete newQuery[param];
    const routeNew = {
      ...route,
      query: newQuery,
    } as RawLocation;
    router.replace(routeNew);
  }
};

export const navigateToProject = function (project: ProjectObject | null) {
  if (project && project.slug) {
    // Navigate to that project-page
    router.push({
      name: "project-page",
      params: {
        slug: project.slug,
      },
    });
  } else {
    // Navigate to list-projects
    router.push({ name: "list-projects" });
  }
};