import Vue from "vue";
import VueRouter from "vue-router";
import { getGalaxyInstance } from "@/app";
import { HistoryExport } from "@/components/HistoryExport/index";
import { APIKey } from "@/components/User/APIKey";
import { ExternalIdentities } from "@/components/User/ExternalIdentities";
import { hasSingleOidcProfile } from "@/components/User/ExternalIdentities/ExternalIDHelper";
import AdminRoutes from "@/entry/analysis/routes/admin-routes";
import LibraryRoutes from "@/entry/analysis/routes/library-routes";
import StorageRoutes from "@/entry/analysis/routes/storage-routes";
import { getAppRoot } from "@/onload/loadConfig";
import { requireAuth } from "@/router/guards";
import { parseBool } from "@/utils/utils";
import { patchRouterPush } from "./router-push";
import CenterFrame from "./modules/CenterFrame.vue";
import AboutGalaxy from "@/components/AboutGalaxy.vue";
import AvailableDatatypes from "@/components/AvailableDatatypes/AvailableDatatypes.vue";
import ChatGXY from "@/components/ChatGXY.vue";
import CitationsList from "@/components/Citation/CitationsList.vue";
import ClientError from "@/components/ClientError.vue";
import CollectionEditView from "@/components/Collections/common/CollectionEditView.vue";
import DisplayCollectionAsSheet from "@/components/Collections/common/DisplayCollectionAsSheet.vue";
import ListWizard from "@/components/Collections/ListWizard.vue";
import RulesStandalone from "@/components/Collections/RulesStandalone.vue";
import DatasetCopy from "@/components/Dataset/DatasetCopy.vue";
import DatasetList from "@/components/Dataset/DatasetList.vue";
import DatasetView from "@/components/Dataset/DatasetView.vue";
import DatasetDetails from "@/components/DatasetInformation/DatasetDetails.vue";
import RecentDownloads from "@/components/Downloads/RecentDownloads.vue";
import CreateFileSourceInstance from "@/components/FileSources/Instances/CreateInstance.vue";
import EditFileSourceInstance from "@/components/FileSources/Instances/EditInstance.vue";
import ManageFileSourceIndex from "@/components/FileSources/Instances/ManageIndex.vue";
import UpgradeFileSourceInstance from "@/components/FileSources/Instances/UpgradeInstance.vue";
import CreateUserFileSource from "@/components/FileSources/Templates/CreateUserFileSource.vue";
import FormGeneric from "@/components/Form/FormGeneric.vue";
import GalaxyWizard from "@/components/GalaxyWizard.vue";
import GridInvocation from "@/components/Grid/GridInvocation.vue";
import GridPage from "@/components/Grid/GridPage.vue";
import GridVisualization from "@/components/Grid/GridVisualization.vue";
import HelpTerm from "@/components/Help/HelpTerm.vue";
import HistoryArchiveWizard from "@/components/History/Archiving/HistoryArchiveWizard.vue";
import HistoryExportTasks from "@/components/History/Export/HistoryExport.vue";
import HistoryAccessibility from "@/components/History/HistoryAccessibility.vue";
import HistoryDatasetPermissions from "@/components/History/HistoryDatasetPermissions.vue";
import HistoryList from "@/components/History/HistoryList.vue";
import HistoryPublished from "@/components/History/HistoryPublished.vue";
import HistoryView from "@/components/History/HistoryView.vue";
import HistoryMultipleView from "@/components/History/Multiple/MultipleView.vue";
import HistoryImport from "@/components/HistoryImport.vue";
import ZipImportResults from "@/components/ImportData/zip/ZipImportResults.vue";
import ZipImportWizard from "@/components/ImportData/zip/ZipImportWizard.vue";
import InteractiveToolFrame from "@/components/InteractiveTools/InteractiveToolFrame.vue";
import InteractiveTools from "@/components/InteractiveTools/InteractiveTools.vue";
import JobDetails from "@/components/JobInformation/JobDetails.vue";
import CarbonEmissionsCalculations from "@/components/JobMetrics/CarbonEmissions/CarbonEmissionsCalculations.vue";
import ToolLanding from "@/components/Landing/ToolLanding.vue";
import WorkflowLanding from "@/components/Landing/WorkflowLanding.vue";
import NotificationsList from "@/components/Notifications/NotificationsList.vue";
import CreateObjectStoreInstance from "@/components/ObjectStore/Instances/CreateInstance.vue";
import EditObjectStoreInstance from "@/components/ObjectStore/Instances/EditInstance.vue";
import ManageObjectStoreIndex from "@/components/ObjectStore/Instances/ManageIndex.vue";
import UpgradeObjectStoreInstance from "@/components/ObjectStore/Instances/UpgradeInstance.vue";
import CreateUserObjectStore from "@/components/ObjectStore/Templates/CreateUserObjectStore.vue";
import PageView from "@/components/Page/PageView.vue";
import PageForm from "@/components/PageDisplay/PageForm.vue";
import PageEditor from "@/components/PageEditor/PageEditor.vue";
import UploadMethodView from "@/components/Panels/Upload/UploadMethodView.vue";
import UploadPage from "@/components/Panels/Upload/UploadPage.vue";
import UploadProgress from "@/components/Panels/Upload/UploadProgress.vue";
import Sharing from "@/components/Sharing/SharingPage.vue";
import ToolReport from "@/components/Tool/ToolReport.vue";
import ToolSuccess from "@/components/Tool/ToolSuccess.vue";
import ToolOntologies from "@/components/ToolsList/ToolOntologies.vue";
import ToolsList from "@/components/ToolsList/ToolsList.vue";
import ToolsJson from "@/components/ToolsView/ToolsSchemaJson/ToolsJson.vue";
import TourList from "@/components/Tour/TourList.vue";
import CredentialsManagement from "@/components/User/Credentials/CredentialsManagement.vue";
import CustomBuilds from "@/components/User/CustomBuilds.vue";
import HistoryStorageOverview from "@/components/User/DiskUsage/Visualizations/HistoryStorageOverview.vue";
import NotificationsPreferences from "@/components/User/Notifications/NotificationsPreferences.vue";
import UserDatasetPermissions from "@/components/User/UserDatasetPermissions.vue";
import UserOidcProfile from "@/components/User/UserOidcProfile.vue";
import UserPreferences from "@/components/User/UserPreferences.vue";
import UserPreferencesForm from "@/components/User/UserPreferencesForm.vue";
import DisplayApplication from "@/components/Visualizations/DisplayApplication.vue";
import VisualizationsList from "@/components/Visualizations/Index.vue";
import VisualizationCreate from "@/components/Visualizations/VisualizationCreate.vue";
import VisualizationDisplay from "@/components/Visualizations/VisualizationDisplay.vue";
import VisualizationPublished from "@/components/Visualizations/VisualizationPublished.vue";
import HistoryInvocations from "@/components/Workflow/HistoryInvocations.vue";
import TrsSearch from "@/components/Workflow/Import/TrsSearch.vue";
import InvocationReport from "@/components/Workflow/InvocationReport.vue";
import WorkflowList from "@/components/Workflow/List/WorkflowList.vue";
import WorkflowPublished from "@/components/Workflow/Published/WorkflowPublished.vue";
import WorkflowRerun from "@/components/Workflow/Run/WorkflowRerun.vue";
import WorkflowRun from "@/components/Workflow/Run/WorkflowRun.vue";
import StoredWorkflowInvocations from "@/components/Workflow/StoredWorkflowInvocations.vue";
import WorkflowCreate from "@/components/Workflow/WorkflowCreate.vue";
import WorkflowExport from "@/components/Workflow/WorkflowExport.vue";
import WorkflowImport from "@/components/Workflow/WorkflowImport.vue";
import WorkflowInvocationState from "@/components/WorkflowInvocationState/WorkflowInvocationState.vue";
import Analysis from "@/entry/analysis/modules/Analysis.vue";
import Home from "@/entry/analysis/modules/Home.vue";
import Login from "@/entry/analysis/modules/Login.vue";
import Register from "@/entry/analysis/modules/Register.vue";
import WorkflowEditorModule from "@/entry/analysis/modules/WorkflowEditor.vue";
Vue.use(VueRouter);
// Async component for CustomToolEditor to reduce bundle size
// NOTE: We use the full async component factory pattern instead of simple dynamic imports
// (i.e., `() => import("@/components/Tool/CustomToolEditor.vue")`) due to what I think are router limitations. Revisit with vr-4
const CustomToolEditor = () => ({
component: import("@/components/Tool/CustomToolEditor.vue"),
loading: {
template: '
Loading Tool Editor...
',
},
error: {
template: 'Failed to load Tool Editor
',
},
delay: 200,
timeout: 10000,
});
// patches $router.push() to trigger an event and hide duplication warnings
patchRouterPush(VueRouter);
// redirect anon users
function redirectAnon(redirect = "") {
const Galaxy = getGalaxyInstance();
if (!Galaxy.user || !Galaxy.user.id) {
if (redirect !== "") {
return redirect;
} else {
return "/login/start";
}
}
}
// redirect logged in users
function redirectLoggedIn() {
const Galaxy = getGalaxyInstance();
if (Galaxy.user.id) {
return "/";
}
}
function redirectIf(condition, path) {
if (condition) {
return path;
}
}
// produces the client router
export function getRouter(Galaxy) {
const router = new VueRouter({
base: getAppRoot(),
mode: "history",
routes: [
/** Login entry route */
{
path: "/login/start",
component: Login,
redirect: redirectLoggedIn(),
},
/** Registration entry route */
{
path: "/register/start",
component: Register,
redirect: redirectLoggedIn(),
},
/** Workflow editor */
{
path: "/workflows/edit",
component: WorkflowEditorModule,
redirect: redirectAnon(),
},
/** Published resources routes */
{
path: "/published/history",
component: HistoryPublished,
props: (route) => ({ id: route.query.id }),
},
{
path: "/published/page",
component: PageView,
props: (route) => ({
pageId: route.query.id,
embed: route.query.embed ? parseBool(route.query.embed) : undefined,
showHeading: route.query.heading ? parseBool(route.query.heading) : undefined,
}),
},
{
path: "/published/visualization",
component: VisualizationPublished,
props: (route) => ({ id: route.query.id }),
},
{
path: "/published/workflow",
component: WorkflowPublished,
props: (route) => ({
id: route.query.id,
version: route.query.version,
zoom: route.query.zoom ? parseFloat(route.query.zoom) : undefined,
embed: route.query.embed ? parseBool(route.query.embed) : undefined,
showButtons: route.query.buttons ? parseBool(route.query.buttons) : undefined,
showAbout: route.query.about ? parseBool(route.query.about) : undefined,
showHeading: route.query.heading ? parseBool(route.query.heading) : undefined,
showMinimap: route.query.minimap ? parseBool(route.query.minimap) : undefined,
showZoomControls: route.query.zoom_controls ? parseBool(route.query.zoom_controls) : undefined,
initialX: route.query.initialX ? parseInt(route.query.initialX) : undefined,
initialY: route.query.initialY ? parseInt(route.query.initialY) : undefined,
}),
},
{
name: "error",
path: "/client-error/",
component: ClientError,
props: true,
},
/** Analysis routes */
{
path: "/",
component: Analysis,
children: [
...AdminRoutes,
...LibraryRoutes,
...StorageRoutes,
{
path: "",
alias: "root",
component: Home,
props: (route) => ({ config: Galaxy.config, query: route.query }),
},
{
path: "about",
component: AboutGalaxy,
},
{
path: "upload",
component: UploadPage,
},
{
path: "upload/progress",
component: UploadProgress,
},
{
path: "upload/:methodId",
component: UploadMethodView,
props: true,
},
{
path: "help/terms/:term",
component: HelpTerm,
props: true,
},
{
path: "carbon_emissions_calculations",
component: CarbonEmissionsCalculations,
},
{
path: "custom_builds",
component: CustomBuilds,
redirect: redirectAnon(),
},
{
path: "collection/new_list",
component: ListWizard,
props: (route) => ({
initialAdvanced: parseBool(route.query.advanced),
}),
},
{
path: "collection/:collectionId/edit",
component: CollectionEditView,
props: true,
},
{
path: "collection/:collectionId/sheet",
component: DisplayCollectionAsSheet,
props: true,
},
{
path: "datasets/copy",
component: DatasetCopy,
},
{
path: "datasets/list",
component: DatasetList,
},
{
path: "datasets/:datasetId/report",
component: ToolReport,
props: true,
},
{
// legacy route, potentially used by 3rd parties
path: "datasets/:datasetId/show_params",
component: DatasetDetails,
props: true,
},
{
// Consolidated route for dataset view with optional tab
// Handles /datasets/{id}, /datasets/{id}/details, /datasets/{id}/visualize, etc.
path: "datasets/:datasetId/:tab?",
name: "DatasetDetails",
component: DatasetView,
props: (route) => ({
datasetId: route.params.datasetId,
tab: route.params.tab,
displayOnly: route.query.displayOnly === "true",
}),
},
{
path: "datatypes",
component: AvailableDatatypes,
},
{
path: "display_applications/:datasetId/:appName/:linkName",
component: DisplayApplication,
props: true,
redirect: redirectAnon(),
},
{
path: "histories/import",
component: HistoryImport,
},
{
path: "histories/citations",
component: CitationsList,
props: (route) => ({
id: route.query.id,
source: "histories",
}),
},
{
path: "histories/rename",
component: FormGeneric,
props: (route) => ({
url: `/history/rename?id=${route.query.id}`,
redirect: "/histories/list",
}),
},
{
path: "histories/sharing",
component: HistoryAccessibility,
props: (route) => ({
historyId: route.query.id,
}),
},
{
path: "histories/permissions",
component: HistoryDatasetPermissions,
props: (route) => ({
historyId: route.query.id,
}),
},
{
path: "histories/view",
component: HistoryView,
props: (route) => ({
id: route.query.id,
}),
},
{
path: "histories/view_multiple",
component: HistoryMultipleView,
props: true,
redirect: redirectAnon(),
},
{
path: "histories/list_published",
component: HistoryList,
props: (route) => ({
activeList: "published",
username: route.query["f-username"],
}),
},
{
path: "histories/archived",
component: HistoryList,
props: {
activeList: "archived",
},
redirect: redirectAnon(),
},
{
path: "histories/list",
component: HistoryList,
props: {
activeList: "my",
},
redirect: redirectAnon("/histories/list_published"),
},
{
path: "histories/list_shared",
component: HistoryList,
props: {
activeList: "shared",
},
redirect: redirectAnon(),
},
{
path: "histories/:historyId/export",
get component() {
return Galaxy.config.enable_celery_tasks ? HistoryExportTasks : HistoryExport;
},
props: true,
},
{
path: "histories/:historyId/archive",
component: HistoryArchiveWizard,
props: true,
},
{
path: "histories/:historyId/invocations",
component: HistoryInvocations,
props: true,
},
{
path: "interactivetool_entry_points/list",
component: InteractiveTools,
},
{
path: "interactivetool_entry_points/:entryId/display",
component: InteractiveToolFrame,
props: true,
name: "InteractiveToolDisplay",
},
{
path: "jobs/submission/success",
component: ToolSuccess,
props: true,
},
{
path: "jobs/:jobId/view",
component: JobDetails,
props: true,
},
{
path: "object_store_instances/create",
component: CreateUserObjectStore,
},
{
path: "object_store_instances/index",
component: ManageObjectStoreIndex,
props: (route) => {
return { message: route.query["message"] };
},
},
{
path: "object_store_instances/:instanceId/edit",
component: EditObjectStoreInstance,
props: true,
},
{
path: "object_store_instances/:instanceId/upgrade",
component: UpgradeObjectStoreInstance,
props: true,
},
{
path: "object_store_templates/:templateId/new",
component: CreateObjectStoreInstance,
props: true,
},
{
path: "file_source_instances/create",
component: CreateUserFileSource,
props: (route) => {
return {
error: route.params.error,
};
},
},
{
path: "file_source_instances/index",
component: ManageFileSourceIndex,
props: (route) => {
return { message: route.query["message"] };
},
},
{
path: "file_source_instances/:instanceId/edit",
component: EditFileSourceInstance,
props: true,
},
{
path: "file_source_instances/:instanceId/upgrade",
component: UpgradeFileSourceInstance,
props: true,
},
{
path: "file_source_templates/:templateId/new",
component: CreateFileSourceInstance,
props: (route) => ({
templateId: route.params.templateId,
uuid: route.query.uuid,
}),
},
{
path: "pages/create",
component: PageForm,
props: (route) => ({
invocationId: route.query.invocation_id,
mode: "create",
}),
},
{
path: "pages/edit",
component: PageForm,
props: (route) => ({
id: route.query.id,
mode: "edit",
}),
},
{
path: "/pages/editor",
component: PageEditor,
props: (route) => ({
pageId: route.query.id,
}),
},
{
path: "/tools/editor",
component: CustomToolEditor,
redirect: redirectAnon(),
},
{
path: "/tools/editor/:toolUuid",
component: CustomToolEditor,
redirect: redirectAnon(),
props: true,
},
{
path: "pages/sharing",
component: Sharing,
props: (route) => ({
id: route.query.id,
pluralName: "Pages",
modelClass: "Page",
}),
},
{
path: "pages/list",
component: GridPage,
props: {
activeList: "my",
},
redirect: redirectAnon("/pages/list_published"),
},
{
path: "pages/list_published",
component: GridPage,
props: (route) => ({
activeList: "published",
username: route.query["f-username"],
}),
},
{
path: "storage/history/:historyId",
name: "HistoryOverviewInAnalysis",
component: HistoryStorageOverview,
props: true,
},
{
path: "tours",
component: TourList,
},
{
path: "chatgxy/:exchangeId?",
component: ChatGXY,
redirect: redirectAnon(),
props: (route) => ({
exchangeId: route.params.exchangeId || undefined,
compact: route.query.compact === "true",
}),
},
{
path: "wizard",
component: GalaxyWizard,
},
{
path: "tours/:tourId",
component: CenterFrame,
props: (route) => ({
src: "/welcome",
}),
},
{
path: "rules",
component: RulesStandalone,
props: (route) => {
return {
mode: "standalone",
...route.query,
};
},
},
{
path: "tools/list",
component: ToolsList,
props: (route) => {
return {
...route.query,
};
},
},
{
path: "tools/list/ontologies",
component: ToolOntologies,
props: true,
},
{
path: "tools/json",
component: ToolsJson,
},
{
path: "tool_landings/:uuid",
component: ToolLanding,
props: (route) => ({
uuid: route.params.uuid,
public: Boolean(route.query.public),
secret: route.query.client_secret,
}),
beforeEnter: requireAuth,
},
{
path: "workflow_landings/:uuid",
component: WorkflowLanding,
props: (route) => ({
uuid: route.params.uuid,
public: (route.query.public || "").toLowerCase() === "true",
secret: route.query.client_secret,
}),
beforeEnter: requireAuth,
},
{
path: "user",
component: UserPreferences,
redirect: redirectAnon(),
},
{
path: "user/api_key",
component: APIKey,
redirect: redirectAnon(),
},
{
path: "user/credentials",
component: CredentialsManagement,
redirect: redirectAnon(),
},
{
path: "user/oidc-profile",
component: UserOidcProfile,
redirect:
redirectIf(
!Galaxy.config.enable_oidc ||
Galaxy.config.enable_account_interface ||
!hasSingleOidcProfile(Galaxy.config.oidc),
"/user",
) || redirectAnon(),
},
{
path: "user/external_ids",
component: ExternalIdentities,
redirect: redirectIf(Galaxy.config.fixed_delegated_auth, "/") || redirectAnon(),
},
{
path: "user/notifications",
component: NotificationsList,
redirect: redirectIf(!Galaxy.config.enable_notification_system, "/") || redirectAnon(),
props: (route) => ({
shouldOpenPreferences: Boolean(route.query.preferences),
}),
},
{
path: "user/notifications/preferences",
component: NotificationsPreferences,
redirect: redirectAnon(),
},
{
path: "user/permissions",
component: UserDatasetPermissions,
redirect: redirectAnon(),
props: {
userId: Galaxy.user.id,
},
},
{
path: "user/:formId",
component: UserPreferencesForm,
props: (route) => ({
formId: route.params.formId,
id: route.query.id,
}),
redirect: redirectAnon(),
},
{
path: "visualizations",
component: VisualizationsList,
props: (route) => ({
datasetId: route.query.dataset_id,
}),
},
{
path: "visualizations/create/:visualization",
component: VisualizationCreate,
name: "VisualizationsCreate",
props: true,
},
{
path: "visualizations/display",
component: VisualizationDisplay,
name: "VisualizationsDisplay",
props: (route) => ({
datasetId: route.query.dataset_id,
visualization: route.query.visualization,
visualizationId: route.query.visualization_id,
}),
},
{
path: "visualizations/edit",
component: FormGeneric,
props: (route) => ({
url: `/visualization/edit?id=${route.query.id}`,
redirect: "/visualizations/list",
active_tab: "visualization",
}),
},
{
path: "visualizations/sharing",
component: Sharing,
props: (route) => ({
id: route.query.id,
pluralName: "Visualizations",
modelClass: "Visualization",
}),
},
{
path: "visualizations/list",
component: GridVisualization,
props: {
activeList: "my",
},
redirect: redirectAnon("/visualizations/list_published"),
},
{
path: "visualizations/list_published",
component: GridVisualization,
props: (route) => ({
activeList: "published",
username: route.query["f-username"],
}),
},
{
path: "visualizations/list_shared",
component: GridVisualization,
props: {
activeList: "shared",
},
redirect: redirectAnon(),
},
{
path: "workflows/create",
component: WorkflowCreate,
redirect: redirectAnon(),
},
{
path: "workflows/export",
component: WorkflowExport,
props: (route) => ({
id: route.query.id,
}),
},
{
path: "workflows/import",
component: WorkflowImport,
redirect: redirectAnon(),
},
{
path: "workflows/trs_import",
component: WorkflowImport,
redirect: redirectAnon(),
},
{
path: "workflows/trs_search",
component: TrsSearch,
redirect: redirectAnon(),
},
{
path: "workflows/invocations",
component: GridInvocation,
redirect: redirectAnon(),
},
{
path: "workflows/invocations/import",
component: HistoryImport,
props: {
invocationImport: true,
},
},
{
path: "workflows/invocations/report",
component: InvocationReport,
props: (route) => ({
invocationId: route.query.id,
}),
},
{
// Consolidated route for workflow invocation state with optional success query param
// Handles /workflows/invocations/{id}, /workflows/invocations/{id}/steps, /workflows/invocations/{id}/inputs, etc.
path: "workflows/invocations/:invocationId/:tab?",
component: WorkflowInvocationState,
props: (route) => ({
invocationId: route.params.invocationId,
tab: route.params.tab,
isFullPage: true,
success: Boolean(route.query.success),
}),
},
{
path: "workflows/list",
component: WorkflowList,
redirect: redirectAnon("/workflows/list_published"),
},
{
path: "workflows/list_published",
component: WorkflowList,
props: (route) => ({
activeList: "published",
query: { ...route.query },
}),
},
{
path: "workflows/list_shared_with_me",
component: WorkflowList,
redirect: redirectAnon(),
props: (route) => ({
activeList: "shared_with_me",
query: { ...route.query },
}),
},
{
path: "workflows/run",
component: WorkflowRun,
redirect: redirectAnon(),
props: (route) => ({
workflowId: route.query.id,
version: route.query.version,
instance: route.query.instance,
preferSimpleForm: Galaxy.config.simplified_workflow_run_ui === "prefer",
simpleFormTargetHistory: Galaxy.config.simplified_workflow_run_ui_target_history,
simpleFormUseJobCache: Galaxy.config.simplified_workflow_run_ui_job_cache === "on",
}),
},
{
path: "workflows/rerun",
component: WorkflowRerun,
redirect: redirectAnon(),
props: (route) => ({
invocationId: route.query.invocation_id,
}),
},
{
path: "workflows/sharing",
component: Sharing,
props: (route) => ({
id: route.query.id,
pluralName: "Workflows",
modelClass: "Workflow",
}),
},
{
path: "workflows/:storedWorkflowId/invocations",
component: StoredWorkflowInvocations,
props: true,
},
{
path: "import/zip",
name: "ZipImportWizard",
component: ZipImportWizard,
props: true,
redirect: redirectAnon(),
},
{
path: "import/zip/results",
name: "ZipImportResults",
component: ZipImportResults,
props: (route) => ({
workflowFileCount: Number(route.params.workflowFileCount),
regularFileCount: Number(route.params.regularFileCount),
}),
redirect: redirectAnon(),
},
{
path: "downloads",
name: "RecentDownloads",
component: RecentDownloads,
redirect: redirectAnon(),
},
],
},
],
});
function checkAdminAccessRequired(to) {
// Check parent route hierarchy to see if we require admin access here.
// Access is required if *any* component in the hierarchy requires it.
if (to.matched.some((record) => record.meta.requiresAdmin === true)) {
const isAdmin = getGalaxyInstance()?.user?.isAdmin();
return !isAdmin;
}
return false;
}
function checkRegisteredUserAccessRequired(to) {
// Check parent route hierarchy to see if we require registered user access here.
// Access is required if *any* component in the hierarchy requires it.
if (to.matched.some((record) => record.meta.requiresRegisteredUser === true)) {
const isAnonymous = getGalaxyInstance()?.user?.isAnonymous();
return isAnonymous;
}
return false;
}
router.beforeEach(async (to, from, next) => {
// TODO: merge anon redirect functionality here for more standard handling
const isAdminAccessRequired = checkAdminAccessRequired(to);
if (isAdminAccessRequired) {
const error = new Error(`Admin access required for '${to.path}'.`);
error.name = "AdminRequired";
next(error);
}
const isRegisteredUserAccessRequired = checkRegisteredUserAccessRequired(to);
if (isRegisteredUserAccessRequired) {
const error = new Error(`Registered user access required for '${to.path}'.`);
error.name = "RegisteredUserRequired";
next(error);
}
next();
});
router.onError((error) => {
router.push({ name: "error", params: { error: error } });
});
return router;
}