mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-18 21:29:36 +00:00
improvements: refactor project templates, filter policies by project type, project type specific roles
This commit is contained in:
@@ -11,11 +11,12 @@ import { BreadcrumbContainer, TBreadcrumbFormat } from "@app/components/v2";
|
||||
import { OrgPermissionSubjects, useOrgPermission, useServerConfig } from "@app/context";
|
||||
import { OrgPermissionSecretShareAction } from "@app/context/OrgPermissionContext/types";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
|
||||
import { InsecureConnectionBanner } from "./components/InsecureConnectionBanner";
|
||||
import { MinimizedOrgSidebar } from "./components/MinimizedOrgSidebar";
|
||||
import { SidebarHeader } from "./components/SidebarHeader";
|
||||
import { DefaultSideBar, SecretSharingSideBar } from "./ProductsSideBar";
|
||||
import { DefaultSideBar, ProjectOverviewSideBar, SecretSharingSideBar } from "./ProductsSideBar";
|
||||
|
||||
export const OrganizationLayout = () => {
|
||||
const matches = useRouterState({ select: (s) => s.matches.at(-1)?.context });
|
||||
@@ -45,21 +46,38 @@ export const OrganizationLayout = () => {
|
||||
] as string[]
|
||||
).includes(location.pathname);
|
||||
|
||||
const isProjectOverviewOrSettingsPage = (
|
||||
[
|
||||
linkOptions({ to: "/organization/secret-manager/overview" }).to,
|
||||
linkOptions({ to: "/organization/secret-manager/settings" }).to,
|
||||
linkOptions({ to: "/organization/cert-manager/overview" }).to,
|
||||
linkOptions({ to: "/organization/cert-manager/settings" }).to,
|
||||
linkOptions({ to: "/organization/kms/overview" }).to,
|
||||
linkOptions({ to: "/organization/kms/settings" }).to,
|
||||
linkOptions({ to: "/organization/ssh/overview" }).to,
|
||||
linkOptions({ to: "/organization/ssh/settings" }).to
|
||||
] as string[]
|
||||
).includes(location.pathname);
|
||||
|
||||
const shouldShowOrgSidebar =
|
||||
location.pathname.startsWith("/organization") &&
|
||||
(!isSecretSharingPage || shouldShowProductsSidebar) &&
|
||||
!(
|
||||
[
|
||||
linkOptions({ to: "/organization/secret-manager/overview" }).to,
|
||||
linkOptions({ to: "/organization/cert-manager/overview" }).to,
|
||||
linkOptions({ to: "/organization/ssh/overview" }).to,
|
||||
linkOptions({ to: "/organization/kms/overview" }).to,
|
||||
linkOptions({ to: "/organization/secret-scanning" }).to
|
||||
] as string[]
|
||||
).includes(location.pathname);
|
||||
!([linkOptions({ to: "/organization/secret-scanning" }).to] as string[]).includes(
|
||||
location.pathname
|
||||
);
|
||||
|
||||
const containerHeight = config.pageFrameContent ? "h-[94vh]" : "h-screen";
|
||||
|
||||
let SideBarComponent = <DefaultSideBar />;
|
||||
|
||||
if (isSecretSharingPage) {
|
||||
SideBarComponent = <SecretSharingSideBar />;
|
||||
} else if (isProjectOverviewOrSettingsPage) {
|
||||
SideBarComponent = (
|
||||
<ProjectOverviewSideBar type={location.pathname.split("/")[2] as ProjectType} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Banner />
|
||||
@@ -80,10 +98,12 @@ export const OrganizationLayout = () => {
|
||||
className="dark w-60 overflow-hidden border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900"
|
||||
>
|
||||
<nav className="items-between flex h-full flex-col overflow-y-auto dark:[color-scheme:dark]">
|
||||
<div className="p-2 pt-3">
|
||||
<SidebarHeader />
|
||||
</div>
|
||||
{isSecretSharingPage ? <SecretSharingSideBar /> : <DefaultSideBar />}
|
||||
{!isProjectOverviewOrSettingsPage && (
|
||||
<div className="p-2 pt-3">
|
||||
<SidebarHeader />
|
||||
</div>
|
||||
)}
|
||||
{SideBarComponent}
|
||||
</nav>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Link, useMatchRoute } from "@tanstack/react-router";
|
||||
|
||||
import { Menu, MenuGroup, MenuItem } from "@app/components/v2";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
|
||||
type TProjectOverviewSideBarProps = {
|
||||
type: ProjectType;
|
||||
};
|
||||
|
||||
export const ProjectOverviewSideBar = ({ type }: TProjectOverviewSideBarProps) => {
|
||||
const matchRoute = useMatchRoute();
|
||||
|
||||
const isOverviewActive = !!matchRoute({
|
||||
to: `/organization/${type}/overview`,
|
||||
fuzzy: false
|
||||
});
|
||||
|
||||
let label: string;
|
||||
let icon: string;
|
||||
let link: string;
|
||||
|
||||
switch (type) {
|
||||
case ProjectType.CertificateManager:
|
||||
label = "Cert Management";
|
||||
icon = "note";
|
||||
link = "https://infisical.com/docs/documentation/platform/pki/overview";
|
||||
break;
|
||||
case ProjectType.SecretManager:
|
||||
label = "Secret Management";
|
||||
icon = "sliding-carousel";
|
||||
link = "https://infisical.com/docs/documentation/getting-started/introduction";
|
||||
break;
|
||||
case ProjectType.KMS:
|
||||
label = "KMS";
|
||||
icon = "unlock";
|
||||
link = "https://infisical.com/docs/documentation/platform/kms/overview";
|
||||
break;
|
||||
case ProjectType.SSH:
|
||||
label = "SSH";
|
||||
icon = "verified";
|
||||
link = "https://infisical.com/docs/documentation/platform/ssh/overview";
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown project type");
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="p-2 pt-3">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={link}
|
||||
className="flex w-full items-center rounded-md border border-mineshaft-600 p-2 pl-3 transition-all duration-150 hover:bg-mineshaft-700"
|
||||
>
|
||||
<div className="mr-2 flex h-6 w-6 items-center justify-center rounded-md bg-mineshaft-500 p-4">
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="h-3.5 w-3.5 text-mineshaft-300"
|
||||
/>
|
||||
</div>
|
||||
<div className="-mt-1 flex flex-grow flex-col text-white">
|
||||
<div className="max-w-36 truncate text-ellipsis text-sm font-medium capitalize">
|
||||
Infisical Docs
|
||||
</div>
|
||||
<div className="text-xs leading-[10px] text-mineshaft-400">
|
||||
{type === ProjectType.SecretManager ? "Get Started" : `${label} Overview`}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<Menu>
|
||||
<MenuGroup title="Overview">
|
||||
<Link to={`/organization/${type}/overview`}>
|
||||
<MenuItem isSelected={isOverviewActive} icon={icon}>
|
||||
{label}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
</MenuGroup>
|
||||
<MenuGroup title="Other">
|
||||
<Link to={`/organization/${type}/settings`}>
|
||||
{({ isActive }) => (
|
||||
<MenuItem isSelected={isActive} icon="toggle-settings">
|
||||
Settings
|
||||
</MenuItem>
|
||||
)}
|
||||
</Link>
|
||||
</MenuGroup>
|
||||
</Menu>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./DefaultSideBar";
|
||||
export * from "./ProjectOverviewSideBar";
|
||||
export * from "./SecretSharingSideBar";
|
||||
|
||||
+10
-4
@@ -269,7 +269,9 @@ export const MinimizedOrgSidebar = () => {
|
||||
<MenuIconButton
|
||||
isSelected={
|
||||
isActive ||
|
||||
window.location.pathname.startsWith(`/${ProjectType.SecretManager}`)
|
||||
window.location.pathname.startsWith(
|
||||
`/organization/${ProjectType.SecretManager}`
|
||||
)
|
||||
}
|
||||
icon="sliding-carousel"
|
||||
>
|
||||
@@ -282,7 +284,9 @@ export const MinimizedOrgSidebar = () => {
|
||||
<MenuIconButton
|
||||
isSelected={
|
||||
isActive ||
|
||||
window.location.pathname.startsWith(`/${ProjectType.CertificateManager}`)
|
||||
window.location.pathname.startsWith(
|
||||
`/organization/${ProjectType.CertificateManager}`
|
||||
)
|
||||
}
|
||||
icon="note"
|
||||
>
|
||||
@@ -294,7 +298,8 @@ export const MinimizedOrgSidebar = () => {
|
||||
{({ isActive }) => (
|
||||
<MenuIconButton
|
||||
isSelected={
|
||||
isActive || window.location.pathname.startsWith(`/${ProjectType.KMS}`)
|
||||
isActive ||
|
||||
window.location.pathname.startsWith(`/organization/${ProjectType.KMS}`)
|
||||
}
|
||||
icon="unlock"
|
||||
>
|
||||
@@ -306,7 +311,8 @@ export const MinimizedOrgSidebar = () => {
|
||||
{({ isActive }) => (
|
||||
<MenuIconButton
|
||||
isSelected={
|
||||
isActive || window.location.pathname.startsWith(`/${ProjectType.SSH}`)
|
||||
isActive ||
|
||||
window.location.pathname.startsWith(`/organization/${ProjectType.SSH}`)
|
||||
}
|
||||
icon="verified"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user