diff --git a/apps/console/src/pages/organizations/risk-assessments/routes.ts b/apps/console/src/pages/organizations/risk-assessments/routes.ts deleted file mode 100644 index aeb638569..000000000 --- a/apps/console/src/pages/organizations/risk-assessments/routes.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2026 Probo Inc . -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -import { lazy } from "@probo/react-lazy"; -import type { AppRoute } from "@probo/routes"; - -import { PageSkeleton } from "#/components/skeletons/PageSkeleton"; - -export const riskAssessmentRoutes = [ - { - path: "risk-assessments", - Fallback: PageSkeleton, - Component: lazy( - () => - import("./RiskAssessmentsPageLoader"), - ), - }, - { - path: "risk-assessments/:riskAssessmentId", - Fallback: PageSkeleton, - Component: lazy( - () => - import("./RiskAssessmentDetailPageLoader"), - ), - }, -] satisfies AppRoute[]; diff --git a/apps/console/src/pages/organizations/risks/RisksLayoutLoader.tsx b/apps/console/src/pages/organizations/risks/RisksLayoutLoader.tsx new file mode 100644 index 000000000..228a3ae60 --- /dev/null +++ b/apps/console/src/pages/organizations/risks/RisksLayoutLoader.tsx @@ -0,0 +1,43 @@ +// Copyright (c) 2026 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +import { Tabs } from "@probo/ui"; +import { Suspense, useEffect } from "react"; +import { useQueryLoader } from "react-relay"; +import { Outlet } from "react-router"; + +import type { RisksTabsQuery } from "#/__generated__/core/RisksTabsQuery.graphql"; +import { useOrganizationId } from "#/hooks/useOrganizationId"; + +import { RisksTabs, risksTabsQuery } from "./RisksTabs"; + +export default function RisksLayoutLoader() { + const organizationId = useOrganizationId(); + const [queryRef, loadQuery] + = useQueryLoader(risksTabsQuery); + + useEffect(() => { + loadQuery({ organizationId }); + }, [loadQuery, organizationId]); + + return ( +
+ }> + {queryRef && } + + + +
+ ); +} diff --git a/apps/console/src/pages/organizations/risks/RisksTabs.tsx b/apps/console/src/pages/organizations/risks/RisksTabs.tsx new file mode 100644 index 000000000..d871499b9 --- /dev/null +++ b/apps/console/src/pages/organizations/risks/RisksTabs.tsx @@ -0,0 +1,61 @@ +// Copyright (c) 2026 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +import { useTranslate } from "@probo/i18n"; +import { TabLink, Tabs } from "@probo/ui"; +import { graphql, type PreloadedQuery, usePreloadedQuery } from "react-relay"; + +import type { RisksTabsQuery } from "#/__generated__/core/RisksTabsQuery.graphql"; +import { useOrganizationId } from "#/hooks/useOrganizationId"; + +export const risksTabsQuery = graphql` + query RisksTabsQuery($organizationId: ID!) { + organization: node(id: $organizationId) { + ... on Organization { + canListRisks: permission(action: "core:risk:list") + canListRiskAssessments: permission(action: "core:risk-assessment:list") + } + } + } +`; + +interface RisksTabsProps { + queryRef: PreloadedQuery; +} + +export function RisksTabs({ queryRef }: RisksTabsProps) { + const { __ } = useTranslate(); + const organizationId = useOrganizationId(); + const data = usePreloadedQuery(risksTabsQuery, queryRef); + + const canListRisks = data.organization?.canListRisks ?? false; + const canListRiskAssessments + = data.organization?.canListRiskAssessments ?? false; + const baseUrl = `/organizations/${organizationId}`; + + return ( + + {canListRisks && ( + + {__("Risks")} + + )} + {canListRiskAssessments && ( + + {__("Risk assessments")} + + )} + + ); +} diff --git a/apps/console/src/pages/organizations/risk-assessments/RiskAssessmentDetailPage.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentDetailPage.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/RiskAssessmentDetailPage.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentDetailPage.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/RiskAssessmentDetailPageLoader.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentDetailPageLoader.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/RiskAssessmentDetailPageLoader.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentDetailPageLoader.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/RiskAssessmentsPage.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentsPage.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/RiskAssessmentsPage.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentsPage.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/RiskAssessmentsPageLoader.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentsPageLoader.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/RiskAssessmentsPageLoader.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/RiskAssessmentsPageLoader.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/BoundaryActions.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/BoundaryActions.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/BoundaryActions.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/BoundaryActions.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateBoundaryDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateBoundaryDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateBoundaryDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateBoundaryDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateNodeDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateNodeDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateNodeDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateNodeDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateProcessDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateProcessDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateProcessDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateProcessDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateRiskAssessmentDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateRiskAssessmentDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateRiskAssessmentDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateRiskAssessmentDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateScenarioInScopeDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateScenarioInScopeDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateScenarioInScopeDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateScenarioInScopeDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateScopeDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateScopeDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateScopeDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateScopeDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateThreatDialog.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateThreatDialog.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/CreateThreatDialog.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/CreateThreatDialog.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/NodeActions.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/NodeActions.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/NodeActions.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/NodeActions.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/ProcessActions.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/ProcessActions.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/ProcessActions.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/ProcessActions.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/ScenarioInScopeActions.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/ScenarioInScopeActions.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/ScenarioInScopeActions.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/ScenarioInScopeActions.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/ScopeActions.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/ScopeActions.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/ScopeActions.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/ScopeActions.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/ScopeCard.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/ScopeCard.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/ScopeCard.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/ScopeCard.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/ScopeDiagram.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/ScopeDiagram.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/ScopeDiagram.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/ScopeDiagram.tsx diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/ThreatActions.tsx b/apps/console/src/pages/organizations/risks/risk-assessments/_components/ThreatActions.tsx similarity index 100% rename from apps/console/src/pages/organizations/risk-assessments/_components/ThreatActions.tsx rename to apps/console/src/pages/organizations/risks/risk-assessments/_components/ThreatActions.tsx diff --git a/apps/console/src/pages/organizations/risks/routes.ts b/apps/console/src/pages/organizations/risks/routes.ts index 0f8d1f9fa..d28dda2e8 100644 --- a/apps/console/src/pages/organizations/risks/routes.ts +++ b/apps/console/src/pages/organizations/risks/routes.ts @@ -23,9 +23,23 @@ import { RisksPageSkeleton } from "#/components/skeletons/RisksPageSkeleton"; export const riskRoutes = [ { - path: "risks", - Fallback: RisksPageSkeleton, - Component: lazy(() => import("./RisksPageLoader")), + Fallback: PageSkeleton, + Component: lazy(() => import("./RisksLayoutLoader")), + children: [ + { + path: "risks", + Fallback: RisksPageSkeleton, + Component: lazy(() => import("./RisksPageLoader")), + }, + { + path: "risk-assessments", + Fallback: PageSkeleton, + Component: lazy( + () => + import("./risk-assessments/RiskAssessmentsPageLoader"), + ), + }, + ], }, { path: "risks/:riskId", @@ -72,4 +86,12 @@ export const riskRoutes = [ }, ], }, + { + path: "risk-assessments/:riskAssessmentId", + Fallback: PageSkeleton, + Component: lazy( + () => + import("./risk-assessments/RiskAssessmentDetailPageLoader"), + ), + }, ] satisfies AppRoute[]; diff --git a/apps/console/src/routes.tsx b/apps/console/src/routes.tsx index e0766c2dd..fb72f3b31 100644 --- a/apps/console/src/routes.tsx +++ b/apps/console/src/routes.tsx @@ -31,7 +31,6 @@ import { ViewerLayoutLoading } from "./pages/iam/memberships/ViewerLayoutLoading import { peopleRoutes } from "./pages/iam/organizations/people/routes"; import { compliancePageRoutes } from "./pages/organizations/compliance-page/routes"; import { cookieBannerRoutes } from "./pages/organizations/cookie-banners/routes"; -import { riskAssessmentRoutes } from "./pages/organizations/risk-assessments/routes"; import { riskRoutes } from "./pages/organizations/risks/routes"; import { thirdPartyRoutes } from "./pages/organizations/third-parties/routes"; import { CurrentUser } from "./providers/CurrentUser"; @@ -302,7 +301,6 @@ const routes = [ }, ...peopleRoutes, ...riskRoutes, - ...riskAssessmentRoutes, ...measureRoutes, ...documentsRoutes, ...thirdPartyRoutes,