chore: resolve merge conflicts

This commit is contained in:
Scott Wilson
2025-01-21 21:30:18 -08:00
248 changed files with 6864 additions and 4051 deletions
@@ -2,9 +2,8 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { useNavigate, useSearch } from "@tanstack/react-router";
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectTitle } from "@app/helpers/project";
import { withProjectPermission } from "@app/hoc";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProjectAccessControlTabs } from "@app/types/project";
@@ -38,11 +37,11 @@ const Page = withProjectPermission(
return (
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-7xl px-6 py-6">
<p className="mb-4 mr-4 text-3xl font-semibold text-white">
{currentWorkspace?.type ? getProjectTitle(currentWorkspace?.type) : "Project"} Access
Control
</p>
<div className="mx-auto mb-6 w-full max-w-7xl">
<PageHeader
title="Access Control"
description="Manage fine-grained access for users, groups, roles, and identities within your project resources."
/>
<Tabs value={selectedTab} onValueChange={updateSelectedTab}>
<TabList>
<Tab value={ProjectAccessControlTabs.Member}>Users</Tab>
@@ -1,4 +1,4 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
@@ -11,8 +11,24 @@ const AccessControlPageQuerySchema = z.object({
});
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/access-management"
"/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId/_cert-manager-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema)
validateSearch: zodValidator(AccessControlPageQuerySchema),
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/cert-manager/$projectId/access-management",
params: {
projectId: params.projectId
}
})
}
]
};
}
});
@@ -1,4 +1,4 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
@@ -11,8 +11,24 @@ const AccessControlPageQuerySchema = z.object({
});
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/kms/$projectId/_kms-layout/access-management"
"/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema)
validateSearch: zodValidator(AccessControlPageQuerySchema),
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/kms/$projectId/access-management",
params: {
projectId: params.projectId
}
})
}
]
};
}
});
@@ -1,4 +1,4 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
@@ -11,8 +11,24 @@ const AccessControlPageQuerySchema = z.object({
});
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/access-management"
"/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema)
validateSearch: zodValidator(AccessControlPageQuerySchema),
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/secret-manager/$projectId/access-management",
params: {
projectId: params.projectId
}
})
}
]
};
}
});
@@ -1,4 +1,4 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
@@ -11,8 +11,24 @@ const AccessControlPageQuerySchema = z.object({
});
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/access-management"
"/_authenticate/_inject-org-details/_org-layout/ssh/$projectId/_ssh-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema)
validateSearch: zodValidator(AccessControlPageQuerySchema),
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/ssh/$projectId/access-management",
params: {
projectId: params.projectId
}
})
}
]
};
}
});
@@ -1,16 +1,13 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { subject } from "@casl/ability";
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNavigate, useParams } from "@tanstack/react-router";
import { format } from "date-fns";
import { formatRelative } from "date-fns";
import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions";
import { Button, DeleteActionModal, EmptyState, Spinner } from "@app/components/v2";
import { Button, DeleteActionModal, EmptyState, PageHeader, Spinner } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectTitle } from "@app/helpers/project";
import { usePopUp } from "@app/hooks";
import {
useDeleteIdentityFromWorkspace,
@@ -82,78 +79,37 @@ const Page = () => {
}
return (
<div className="container mx-auto flex max-w-7xl flex-col justify-between bg-bunker-800 p-6 text-white">
<div className="mb-4">
<Button
variant="link"
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
navigate({
to: `/${currentWorkspace.type}/$projectId/access-management` as const,
params: {
projectId: workspaceId
},
search: {
selectedTab: "identities"
}
});
}}
className="mb-4"
>
{currentWorkspace?.type ? getProjectTitle(currentWorkspace?.type) : "Project"} Access
Control
</Button>
</div>
<div className="container mx-auto flex max-w-7xl flex-col justify-between bg-bunker-800 text-white">
{identityMembershipDetails ? (
<>
<div className="mb-4">
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-4 flex items-center justify-between">
<h3 className="text-xl font-semibold text-mineshaft-100">
Project Identity Access
</h3>
<div>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={subject(ProjectPermissionSub.Identity, {
identityId: identityMembershipDetails?.identity?.id
})}
renderTooltip
allowedLabel="Remove from project"
<PageHeader
title={identityMembershipDetails?.identity?.name}
description={`Identity joined on ${identityMembershipDetails?.createdAt && formatRelative(new Date(identityMembershipDetails?.createdAt || ""), new Date())}`}
>
<div>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={subject(ProjectPermissionSub.Identity, {
identityId: identityMembershipDetails?.identity?.id
})}
renderTooltip
allowedLabel="Remove from project"
>
{(isAllowed) => (
<Button
colorSchema="danger"
variant="outline_bg"
size="xs"
isDisabled={!isAllowed}
isLoading={isDeletingIdentity}
onClick={() => handlePopUpOpen("deleteIdentity")}
>
{(isAllowed) => (
<Button
colorSchema="danger"
variant="outline_bg"
size="xs"
isDisabled={!isAllowed}
isLoading={isDeletingIdentity}
onClick={() => handlePopUpOpen("deleteIdentity")}
>
Remove Identity
</Button>
)}
</ProjectPermissionCan>
</div>
</div>
<div className="flex gap-12">
<div>
<span className="text-xs font-semibold text-gray-400">Name</span>
{identityMembershipDetails && (
<p className="text-lg capitalize">
{identityMembershipDetails?.identity?.name}
</p>
)}
</div>
</div>
<div className="mt-4 text-sm text-gray-400">
Joined on{" "}
{identityMembershipDetails?.createdAt &&
format(new Date(identityMembershipDetails?.createdAt || ""), "yyyy-MM-dd")}
</div>
Remove Identity
</Button>
)}
</ProjectPermissionCan>
</div>
</div>
</PageHeader>
<IdentityRoleDetailsSection
identityMembershipDetails={identityMembershipDetails}
isMembershipDetailsLoading={isMembershipDetailsLoading}
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/identities/$identityId"
"/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId/_cert-manager-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/cert-manager/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Identities"
}
]
};
}
});
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/kms/$projectId/_kms-layout/identities/$identityId"
"/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/kms/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Identities"
}
]
};
}
});
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/identities/$identityId"
"/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/secret-manager/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Identities"
}
]
};
}
});
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/identities/$identityId"
"/_authenticate/_inject-org-details/_org-layout/ssh/$projectId/_ssh-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/ssh/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Identities"
}
]
};
}
});
@@ -1,21 +1,18 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNavigate, useParams } from "@tanstack/react-router";
import { format } from "date-fns";
import { formatRelative } from "date-fns";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions";
import { Button, DeleteActionModal, EmptyState, Spinner } from "@app/components/v2";
import { Button, DeleteActionModal, EmptyState, PageHeader, Spinner } from "@app/components/v2";
import {
ProjectPermissionActions,
ProjectPermissionSub,
useOrganization,
useWorkspace
} from "@app/context";
import { getProjectTitle } from "@app/helpers/project";
import { usePopUp } from "@app/hooks";
import { useDeleteUserFromWorkspace, useGetWorkspaceUserDetails } from "@app/hooks/api";
@@ -82,77 +79,37 @@ export const Page = () => {
}
return (
<div className="container mx-auto flex max-w-7xl flex-col justify-between bg-bunker-800 p-6 text-white">
<div className="mb-4">
<Button
variant="link"
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
navigate({
to: `/${currentWorkspace.type}/$projectId/access-management` as const,
params: {
projectId: currentWorkspace.id
}
});
}}
className="mb-4"
>
{currentWorkspace?.type ? getProjectTitle(currentWorkspace?.type) : "Project"} Access
Control
</Button>
</div>
<div className="container mx-auto flex max-w-7xl flex-col justify-between bg-bunker-800 text-white">
{membershipDetails ? (
<>
<div className="mb-4">
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-4 flex items-center justify-between">
<h3 className="text-xl font-semibold text-mineshaft-100">Project User Access</h3>
<div>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={ProjectPermissionSub.Member}
renderTooltip
allowedLabel="Remove from project"
>
{(isAllowed) => (
<Button
colorSchema="danger"
variant="outline_bg"
size="xs"
isDisabled={!isAllowed}
isLoading={isRemovingUserFromWorkspace}
onClick={() => handlePopUpOpen("removeMember")}
>
Remove User
</Button>
)}
</ProjectPermissionCan>
</div>
</div>
<div className="flex gap-12">
<div>
<span className="text-xs font-semibold text-gray-400">Name</span>
{membershipDetails && (
<p className="text-lg capitalize">
{membershipDetails.user.firstName || membershipDetails.user.lastName
? `${membershipDetails.user.firstName} ${membershipDetails.user.lastName}`
: "-"}
</p>
)}
</div>
<div>
<span className="text-xs font-semibold text-gray-400">Email</span>
{membershipDetails && <p className="text-lg">{membershipDetails?.user?.email}</p>}
</div>
</div>
<div className="mt-4 text-sm text-gray-400">
Joined on{" "}
{membershipDetails?.createdAt &&
format(new Date(membershipDetails?.createdAt || ""), "yyyy-MM-dd")}
</div>
</div>
</div>
<PageHeader
title={
membershipDetails.user.firstName || membershipDetails.user.lastName
? `${membershipDetails.user.firstName} ${membershipDetails.user.lastName}`
: "-"
}
description={`User joined on ${membershipDetails?.createdAt && formatRelative(new Date(membershipDetails?.createdAt || ""), new Date())}`}
>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={ProjectPermissionSub.Member}
renderTooltip
allowedLabel="Remove from project"
>
{(isAllowed) => (
<Button
colorSchema="danger"
variant="outline_bg"
size="xs"
isDisabled={!isAllowed}
isLoading={isRemovingUserFromWorkspace}
onClick={() => handlePopUpOpen("removeMember")}
>
Remove User
</Button>
)}
</ProjectPermissionCan>
</PageHeader>
<MemberRoleDetailsSection
membershipDetails={membershipDetails}
isMembershipDetailsLoading={isMembershipDetailsLoading}
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/members/$membershipId"
"/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId/_cert-manager-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/cert-manager/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Users"
}
]
};
}
});
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/kms/$projectId/_kms-layout/members/$membershipId"
"/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/kms/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Users"
}
]
};
}
});
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/members/$membershipId"
"/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/secret-manager/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Users"
}
]
};
}
});
@@ -1,9 +1,28 @@
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/members/$membershipId"
"/_authenticate/_inject-org-details/_org-layout/ssh/$projectId/_ssh-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: "Access Control",
link: linkOptions({
to: "/ssh/$projectId/access-management",
params: {
projectId: params.projectId
}
})
},
{
label: "Users"
}
]
};
}
});
@@ -1,7 +1,5 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
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";
@@ -14,6 +12,7 @@ import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
PageHeader,
Tooltip
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
@@ -83,38 +82,18 @@ const Page = () => {
return (
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
{data && (
<div className="mx-auto mb-6 w-full max-w-7xl px-6 py-6">
<Button
variant="link"
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() =>
navigate({
to: `/${currentWorkspace?.type}/$projectId/access-management` as const,
params: {
projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Roles
}
})
}
className="mb-4"
>
Roles
</Button>
<div className="mb-4 flex items-center justify-between">
<p className="text-3xl font-semibold text-white">{data.name}</p>
<div className="mx-auto mb-6 w-full max-w-7xl">
<PageHeader title={data.name}>
{isCustomRole && (
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
<Tooltip content="More options">
<FontAwesomeIcon size="sm" icon={faEllipsis} />
<Button variant="outline_bg">More</Button>
</Tooltip>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="p-1">
<DropdownMenuContent align="end" className="p-1">
<ProjectPermissionCan
I={ProjectPermissionActions.Edit}
a={ProjectPermissionSub.Role}
@@ -156,7 +135,7 @@ const Page = () => {
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
</PageHeader>
<div className="flex">
<div className="mr-4 w-96">
<RoleDetailsSection roleSlug={roleSlug} handlePopUpOpen={handlePopUpOpen} />
@@ -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"
"/_authenticate/_inject-org-details/_org-layout/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"
}
]
};
}
});
@@ -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"
"/_authenticate/_inject-org-details/_org-layout/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"
}
]
};
}
});
@@ -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"
"/_authenticate/_inject-org-details/_org-layout/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"
}
]
};
}
});
@@ -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"
"/_authenticate/_inject-org-details/_org-layout/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"
}
]
};
}
});