diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx
index 7f9ec6791..70492769f 100644
--- a/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx
+++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx
@@ -1,9 +1,28 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug"
)({
- component: RoleDetailsBySlugPage
+ component: RoleDetailsBySlugPage,
+ beforeLoad: ({ context, params }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "Access Control",
+ link: linkOptions({
+ to: "/cert-manager/$projectId/access-management",
+ params: {
+ projectId: params.projectId
+ }
+ })
+ },
+ {
+ label: "Roles"
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx
index 1677d9401..2ed018da9 100644
--- a/frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx
+++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx
@@ -1,9 +1,28 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/kms/$projectId/_kms-layout/roles/$roleSlug"
)({
- component: RoleDetailsBySlugPage
+ component: RoleDetailsBySlugPage,
+ beforeLoad: ({ context, params }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "Access Control",
+ link: linkOptions({
+ to: "/kms/$projectId/access-management",
+ params: {
+ projectId: params.projectId
+ }
+ })
+ },
+ {
+ label: "Roles"
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx
index 4a2f18750..be7d2f7ca 100644
--- a/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx
+++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx
@@ -1,9 +1,28 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/roles/$roleSlug"
)({
- component: RoleDetailsBySlugPage
+ component: RoleDetailsBySlugPage,
+ beforeLoad: ({ context, params }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "Access Control",
+ link: linkOptions({
+ to: "/secret-manager/$projectId/access-management",
+ params: {
+ projectId: params.projectId
+ }
+ })
+ },
+ {
+ label: "Roles"
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx
index 73b5826d4..f744ab313 100644
--- a/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx
+++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx
@@ -1,9 +1,28 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/roles/$roleSlug"
)({
- component: RoleDetailsBySlugPage
+ component: RoleDetailsBySlugPage,
+ beforeLoad: ({ context, params }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "Access Control",
+ link: linkOptions({
+ to: "/ssh/$projectId/access-management",
+ params: {
+ projectId: params.projectId
+ }
+ })
+ },
+ {
+ label: "Roles"
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx b/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx
index c96a37be5..b2c2e406f 100644
--- a/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx
+++ b/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx
@@ -1,7 +1,7 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
+import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { ProjectType, ProjectVersion } from "@app/hooks/api/workspace/types";
@@ -42,12 +42,9 @@ export const SettingsPage = () => {
{t("common.head-title", { title: t("settings.project.title") })}
-
-
-
-
{t("settings.project.title")}
-
+
+
{tabs
diff --git a/frontend/src/pages/secret-manager/SettingsPage/route.tsx b/frontend/src/pages/secret-manager/SettingsPage/route.tsx
index 7996396c8..f826296c5 100644
--- a/frontend/src/pages/secret-manager/SettingsPage/route.tsx
+++ b/frontend/src/pages/secret-manager/SettingsPage/route.tsx
@@ -5,5 +5,15 @@ import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/settings"
)({
- component: SettingsPage
+ component: SettingsPage,
+ beforeLoad: ({ context }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "Settings"
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/secret-manager/layout.tsx b/frontend/src/pages/secret-manager/layout.tsx
index 824c341b6..0ad0c2954 100644
--- a/frontend/src/pages/secret-manager/layout.tsx
+++ b/frontend/src/pages/secret-manager/layout.tsx
@@ -1,21 +1,16 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { workspaceKeys } from "@app/hooks/api";
import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries";
import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries";
import { ProjectLayout } from "@app/layouts/ProjectLayout";
-import { OrganizationLayout } from "@app/layouts/OrganizationLayout";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout"
)({
- component: () => (
-
-
-
- ),
+ component: ProjectLayout,
beforeLoad: async ({ params, context }) => {
- await context.queryClient.ensureQueryData({
+ const project = await context.queryClient.ensureQueryData({
queryKey: workspaceKeys.getWorkspaceById(params.projectId),
queryFn: () => fetchWorkspaceById(params.projectId)
});
@@ -26,5 +21,21 @@ export const Route = createFileRoute(
}),
queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId })
});
+
+ return {
+ breadcrumbs: [
+ {
+ label: "Secret Managers",
+ link: linkOptions({ to: "/organization/secret-manager/overview" })
+ },
+ {
+ label: project.name,
+ link: linkOptions({
+ to: "/secret-manager/$projectId/overview",
+ params: { projectId: project.id }
+ })
+ }
+ ]
+ };
}
});
diff --git a/frontend/src/pages/ssh/OverviewPage/OverviewPage.tsx b/frontend/src/pages/ssh/OverviewPage/OverviewPage.tsx
index 13c3d8ea3..9123bf675 100644
--- a/frontend/src/pages/ssh/OverviewPage/OverviewPage.tsx
+++ b/frontend/src/pages/ssh/OverviewPage/OverviewPage.tsx
@@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
import { motion } from "framer-motion";
import { ProjectPermissionCan } from "@app/components/permissions";
-import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
+import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { SshCaSection, SshCertificatesSection } from "./components";
@@ -19,12 +19,14 @@ export const OverviewPage = () => {
<>
{t("common.head-title", { title: "Certificates" })}
-
-
-
SSH
+
+
SSH Certificates
diff --git a/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx b/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx
index 674b97009..dce31f01b 100644
--- a/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx
+++ b/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx
@@ -1,7 +1,7 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
+import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectGeneralTab } from "./components/ProjectGeneralTab";
@@ -15,10 +15,8 @@ export const SettingsPage = () => {
{t("common.head-title", { title: t("settings.project.title") })}
-
-
-
{t("settings.project.title")}
-
+
+
{tabs.map((tab) => (
diff --git a/frontend/src/pages/ssh/SettingsPage/route.tsx b/frontend/src/pages/ssh/SettingsPage/route.tsx
index 5649fd26c..174064d06 100644
--- a/frontend/src/pages/ssh/SettingsPage/route.tsx
+++ b/frontend/src/pages/ssh/SettingsPage/route.tsx
@@ -5,5 +5,15 @@ import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/settings"
)({
- component: SettingsPage
+ component: SettingsPage,
+ beforeLoad: ({ context }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "Settings"
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx b/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx
index f8cf9af91..926505230 100644
--- a/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx
+++ b/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx
@@ -1,6 +1,4 @@
import { Helmet } from "react-helmet";
-import { faChevronLeft, faEllipsis } from "@fortawesome/free-solid-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNavigate, useParams } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
@@ -13,6 +11,7 @@ import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
+ PageHeader,
Tooltip
} from "@app/components/v2";
import { ROUTE_PATHS } from "@app/const/routes";
@@ -71,34 +70,17 @@ const Page = () => {
return (
{data && (
-
-
}
- onClick={() =>
- navigate({
- to: `/${ProjectType.SSH}/$projectId/overview`,
- params: {
- projectId
- }
- })
- }
- className="mb-4"
- >
- SSH Certificate Authorities
-
-
-
{data.friendlyName}
+
+
diff --git a/frontend/src/pages/ssh/SshCaByIDPage/route.tsx b/frontend/src/pages/ssh/SshCaByIDPage/route.tsx
index d8a2a4f9c..3d34bcab0 100644
--- a/frontend/src/pages/ssh/SshCaByIDPage/route.tsx
+++ b/frontend/src/pages/ssh/SshCaByIDPage/route.tsx
@@ -1,9 +1,25 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { SshCaByIDPage } from "./SshCaByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/ca/$caId"
)({
- component: SshCaByIDPage
+ component: SshCaByIDPage,
+ beforeLoad: ({ context, params }) => {
+ return {
+ breadcrumbs: [
+ ...context.breadcrumbs,
+ {
+ label: "SSH Certificate Authorities",
+ link: linkOptions({
+ to: "/ssh/$projectId/overview",
+ params: {
+ projectId: params.projectId
+ }
+ })
+ }
+ ]
+ };
+ }
});
diff --git a/frontend/src/pages/ssh/layout.tsx b/frontend/src/pages/ssh/layout.tsx
index d305bf3d2..d36c263ae 100644
--- a/frontend/src/pages/ssh/layout.tsx
+++ b/frontend/src/pages/ssh/layout.tsx
@@ -1,21 +1,16 @@
-import { createFileRoute } from "@tanstack/react-router";
+import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { workspaceKeys } from "@app/hooks/api";
import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries";
import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries";
import { ProjectLayout } from "@app/layouts/ProjectLayout";
-import { OrganizationLayout } from "@app/layouts/OrganizationLayout";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout"
)({
- component: () => (
-
-
-
- ),
+ component: ProjectLayout,
beforeLoad: async ({ params, context }) => {
- await context.queryClient.ensureQueryData({
+ const project = await context.queryClient.ensureQueryData({
queryKey: workspaceKeys.getWorkspaceById(params.projectId),
queryFn: () => fetchWorkspaceById(params.projectId)
});
@@ -26,5 +21,21 @@ export const Route = createFileRoute(
}),
queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId })
});
+
+ return {
+ breadcrumbs: [
+ {
+ label: "SSH",
+ link: linkOptions({ to: "/organization/ssh/overview" })
+ },
+ {
+ label: project.name,
+ link: linkOptions({
+ to: "/ssh/$projectId/overview",
+ params: { projectId: project.id }
+ })
+ }
+ ]
+ };
}
});