mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-18 13:15:39 +00:00
feat: brought back assume privilege banner
This commit is contained in:
+2
-6
@@ -3,10 +3,9 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { Button } from "@app/components/v2";
|
||||
import { useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { getCurrentProductFromUrl, getProjectHomePage } from "@app/helpers/project";
|
||||
import { getProjectHomePage } from "@app/helpers/project";
|
||||
import { useRemoveAssumeProjectPrivilege } from "@app/hooks/api";
|
||||
import { ActorType } from "@app/hooks/api/auditLogs/enums";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
|
||||
export const AssumePrivilegeModeBanner = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
@@ -37,10 +36,7 @@ export const AssumePrivilegeModeBanner = () => {
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
const url = getProjectHomePage(
|
||||
getCurrentProductFromUrl(window.location.href) || ProjectType.SecretManager
|
||||
);
|
||||
|
||||
const url = getProjectHomePage(currentWorkspace.type);
|
||||
window.location.href = url.replace("$projectId", currentWorkspace.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
import { ComponentPropsWithRef, ElementType, useRef } from "react";
|
||||
import { DotLottie, DotLottieReact } from "@lottiefiles/dotlottie-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { MenuItemProps } from "@app/components/v2";
|
||||
|
||||
export const MenuIconButton = <T extends ElementType = "button">({
|
||||
children,
|
||||
icon,
|
||||
className,
|
||||
isDisabled,
|
||||
isSelected,
|
||||
as: Item = "div",
|
||||
description,
|
||||
// wrapping in forward ref with generic component causes the loss of ts definitions on props
|
||||
inputRef,
|
||||
lottieIconMode = "forward",
|
||||
...props
|
||||
}: MenuItemProps<T> &
|
||||
ComponentPropsWithRef<T> & { lottieIconMode?: "reverse" | "forward" }): JSX.Element => {
|
||||
const iconRef = useRef<DotLottie | null>(null);
|
||||
return (
|
||||
<div className="px-1">
|
||||
<Item
|
||||
type="button"
|
||||
role="menuitem"
|
||||
className={twMerge(
|
||||
"group relative my-1 flex w-full cursor-pointer flex-col items-center justify-center rounded p-2 font-inter text-sm text-bunker-100 transition-all duration-150 hover:bg-mineshaft-700",
|
||||
isSelected && "bg-bunker-8g0 hover:bg-mineshaft-500",
|
||||
isDisabled && "cursor-not-allowed hover:bg-transparent",
|
||||
className
|
||||
)}
|
||||
onMouseEnter={() => iconRef.current?.play()}
|
||||
onMouseLeave={() => iconRef.current?.stop()}
|
||||
ref={inputRef}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
className={`${isSelected ? "opacity-100" : "opacity-0"} absolute left-0 h-full w-0.5 rounded-bl rounded-tl bg-primary transition-all duration-150`}
|
||||
/>
|
||||
{icon && (
|
||||
<div className="my-auto mb-2 h-6 w-6">
|
||||
<DotLottieReact
|
||||
dotLottieRefCallback={(el) => {
|
||||
iconRef.current = el;
|
||||
}}
|
||||
src={`/lotties/${icon}.json`}
|
||||
loop
|
||||
className="h-full w-full"
|
||||
mode={lottieIconMode}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="flex-grow justify-center break-words text-center"
|
||||
style={{ fontSize: "10px" }}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</Item>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// export const MenuIconButton = <T extends ElementType = "button">({
|
||||
// children,
|
||||
// icon,
|
||||
// className,
|
||||
// isDisabled,
|
||||
// isSelected,
|
||||
// as: Item = "div",
|
||||
// description,
|
||||
// // wrapping in forward ref with generic component causes the loss of ts definitions on props
|
||||
// inputRef,
|
||||
// lottieIconMode = "forward",
|
||||
// ...props
|
||||
// }: MenuItemProps<T> &
|
||||
// ComponentPropsWithRef<T> & { lottieIconMode?: "reverse" | "forward" }): JSX.Element => {
|
||||
// const iconRef = useRef<DotLottie | null>(null);
|
||||
// return (
|
||||
// <div className="px-1">
|
||||
// <Item
|
||||
// type="button"
|
||||
// role="menuitem"
|
||||
// className={twMerge(
|
||||
// "group relative my-1 flex w-full cursor-pointer flex-col items-center justify-center rounded p-2 font-inter text-sm text-bunker-100 transition-all duration-150 hover:bg-mineshaft-700",
|
||||
// isSelected && "bg-mineshaft-600 hover:bg-mineshaft-700",
|
||||
// isDisabled && "cursor-not-allowed hover:bg-transparent",
|
||||
// className
|
||||
// )}
|
||||
// onMouseEnter={() => iconRef.current?.play()}
|
||||
// onMouseLeave={() => iconRef.current?.stop()}
|
||||
// ref={inputRef}
|
||||
// {...props}
|
||||
// >
|
||||
// <div
|
||||
// className={`${"opacity-0"} absolute left-0 h-full w-1 bg-primary transition-all duration-150`}
|
||||
// />
|
||||
// {icon && (
|
||||
// <div className="my-auto mb-2 h-6 w-6">
|
||||
// <DotLottieReact
|
||||
// dotLottieRefCallback={(el) => {
|
||||
// iconRef.current = el;
|
||||
// }}
|
||||
// src={`/lotties/${icon}.json`}
|
||||
// loop
|
||||
// className="h-full w-full"
|
||||
// mode={lottieIconMode}
|
||||
// />
|
||||
// </div>
|
||||
// )}
|
||||
// <div
|
||||
// className="flex-grow justify-center break-words text-center"
|
||||
// style={{ fontSize: "10px" }}
|
||||
// >
|
||||
// {children}
|
||||
// </div>
|
||||
// </Item>
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
@@ -1,65 +0,0 @@
|
||||
import { ComponentPropsWithRef, ElementType, useRef } from "react";
|
||||
import { DotLottie, DotLottieReact } from "@lottiefiles/dotlottie-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { MenuItemProps } from "@app/components/v2";
|
||||
|
||||
export const MenuIconButton = <T extends ElementType = "button">({
|
||||
children,
|
||||
icon,
|
||||
className,
|
||||
isDisabled,
|
||||
isSelected,
|
||||
as: Item = "div",
|
||||
description,
|
||||
// wrapping in forward ref with generic component causes the loss of ts definitions on props
|
||||
inputRef,
|
||||
lottieIconMode = "forward",
|
||||
...props
|
||||
}: MenuItemProps<T> &
|
||||
ComponentPropsWithRef<T> & { lottieIconMode?: "reverse" | "forward" }): JSX.Element => {
|
||||
const iconRef = useRef<DotLottie | null>(null);
|
||||
return (
|
||||
<div>
|
||||
<Item
|
||||
type="button"
|
||||
role="menuitem"
|
||||
className={twMerge(
|
||||
"group relative flex w-full cursor-pointer flex-col items-center justify-center p-2 font-inter text-sm text-bunker-100 transition-all duration-150 hover:bg-mineshaft-700",
|
||||
isSelected && "rounded-none bg-bunker-800 hover:bg-mineshaft-600",
|
||||
isDisabled && "cursor-not-allowed hover:bg-transparent",
|
||||
className
|
||||
)}
|
||||
onMouseEnter={() => iconRef.current?.play()}
|
||||
onMouseLeave={() => iconRef.current?.stop()}
|
||||
ref={inputRef}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
className={`${
|
||||
isSelected ? "opacity-100" : "opacity-0"
|
||||
} absolute left-0 h-full w-0.5 bg-primary transition-all duration-150`}
|
||||
/>
|
||||
{icon && (
|
||||
<div className="my-auto mb-2 h-6 w-6">
|
||||
<DotLottieReact
|
||||
dotLottieRefCallback={(el) => {
|
||||
iconRef.current = el;
|
||||
}}
|
||||
src={`/lotties/${icon}.json`}
|
||||
loop
|
||||
className="h-full w-full"
|
||||
mode={lottieIconMode}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="flex-grow justify-center break-words text-center"
|
||||
style={{ fontSize: "10px" }}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</Item>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export { MenuIconButton } from "./MenuIconButton";
|
||||
@@ -1,179 +0,0 @@
|
||||
import {
|
||||
faAngleDown,
|
||||
faArrowLeft,
|
||||
faArrowUpRightFromSquare,
|
||||
faCheck
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Link, useNavigate } from "@tanstack/react-router";
|
||||
|
||||
import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger
|
||||
} from "@app/components/v2";
|
||||
import { useOrganization, useUser } from "@app/context";
|
||||
import { useGetOrganizations, useLogoutUser } from "@app/hooks/api";
|
||||
import { AuthMethod } from "@app/hooks/api/users/types";
|
||||
|
||||
type Prop = {
|
||||
onChangeOrg: (orgId: string) => void;
|
||||
};
|
||||
|
||||
export const SidebarHeader = ({ onChangeOrg }: Prop) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { user } = useUser();
|
||||
const navigate = useNavigate();
|
||||
const { data: orgs } = useGetOrganizations();
|
||||
|
||||
const logout = useLogoutUser();
|
||||
const logOutUser = async () => {
|
||||
try {
|
||||
console.log("Logging out...");
|
||||
await logout.mutateAsync();
|
||||
navigate({ to: "/login" });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-12 cursor-default items-center px-3 pt-6">
|
||||
<Link to="/organization/projects">
|
||||
<div className="pl-1 pr-2 text-mineshaft-400 duration-200 hover:text-mineshaft-100">
|
||||
<FontAwesomeIcon icon={faArrowLeft} />
|
||||
</div>
|
||||
</Link>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild className="max-w-[160px] data-[state=open]:bg-mineshaft-600">
|
||||
<div className="mr-auto flex items-center rounded-md py-1.5 pl-1.5 pr-2 hover:bg-mineshaft-600">
|
||||
<div className="flex h-5 w-5 min-w-[20px] items-center justify-center rounded-md bg-primary text-sm">
|
||||
{currentOrg?.name.charAt(0)}
|
||||
</div>
|
||||
<div
|
||||
className="overflow-hidden truncate text-ellipsis pl-2 text-sm text-mineshaft-100"
|
||||
style={{ maxWidth: "140px" }}
|
||||
>
|
||||
{currentOrg?.name}
|
||||
</div>
|
||||
<FontAwesomeIcon icon={faAngleDown} className="pl-1 pt-1 text-xs text-mineshaft-300" />
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
<div className="px-2 py-1 text-xs text-mineshaft-400">{user?.username}</div>
|
||||
{orgs?.map((org) => {
|
||||
return (
|
||||
<DropdownMenuItem key={org.id}>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
if (currentOrg?.id === org.id) return;
|
||||
|
||||
if (org.authEnforced) {
|
||||
// org has an org-level auth method enabled (e.g. SAML)
|
||||
// -> logout + redirect to SAML SSO
|
||||
|
||||
await logout.mutateAsync();
|
||||
if (org.orgAuthMethod === AuthMethod.OIDC) {
|
||||
window.open(`/api/v1/sso/oidc/login?orgSlug=${org.slug}`);
|
||||
} else {
|
||||
window.open(`/api/v1/sso/redirect/saml2/organizations/${org.slug}`);
|
||||
}
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
onChangeOrg(org?.id);
|
||||
}}
|
||||
variant="plain"
|
||||
colorSchema="secondary"
|
||||
size="xs"
|
||||
className="flex w-full items-center justify-start p-0 font-normal"
|
||||
leftIcon={
|
||||
currentOrg?.id === org.id && (
|
||||
<FontAwesomeIcon icon={faCheck} className="mr-3 text-primary" />
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex w-full max-w-[150px] items-center justify-between truncate">
|
||||
{org.name}
|
||||
</div>
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
})}
|
||||
|
||||
<div className="mt-1 h-1 border-t border-mineshaft-600" />
|
||||
<button type="button" onClick={logOutUser} className="w-full">
|
||||
<DropdownMenuItem>Log Out</DropdownMenuItem>
|
||||
</button>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
asChild
|
||||
className="p-1 hover:bg-primary-400 hover:text-black data-[state=open]:bg-primary-400 data-[state=open]:text-black"
|
||||
>
|
||||
<div
|
||||
className="child flex items-center justify-center rounded-full bg-mineshaft pr-1 text-mineshaft-300 hover:bg-mineshaft-500"
|
||||
style={{ fontSize: "11px", width: "26px", height: "26px" }}
|
||||
>
|
||||
{user?.firstName?.charAt(0)}
|
||||
{user?.lastName && user?.lastName?.charAt(0)}
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
<div className="px-2 py-1 text-xs text-mineshaft-400">{user?.username}</div>
|
||||
<Link to="/personal-settings">
|
||||
<DropdownMenuItem>Personal Settings</DropdownMenuItem>
|
||||
</Link>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/getting-started/introduction"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-3 w-full text-sm font-normal leading-[1.2rem] text-mineshaft-300 hover:text-mineshaft-100"
|
||||
>
|
||||
<DropdownMenuItem>
|
||||
Documentation
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.06rem] pl-1.5 text-xxs"
|
||||
/>
|
||||
</DropdownMenuItem>
|
||||
</a>
|
||||
<a
|
||||
href="https://infisical.com/slack"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-3 w-full text-sm font-normal leading-[1.2rem] text-mineshaft-300 hover:text-mineshaft-100"
|
||||
>
|
||||
<DropdownMenuItem>
|
||||
Join Slack Community
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.06rem] pl-1.5 text-xxs"
|
||||
/>
|
||||
</DropdownMenuItem>
|
||||
</a>
|
||||
{user?.superAdmin && (
|
||||
<Link to="/admin">
|
||||
<DropdownMenuItem className="mt-1 border-t border-mineshaft-600">
|
||||
Server Admin Console
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
)}
|
||||
<Link to="/organization/admin">
|
||||
<DropdownMenuItem className="mt-1 border-t border-mineshaft-600">
|
||||
Organization Admin Console
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<div className="mt-1 h-1 border-t border-mineshaft-600" />
|
||||
<button type="button" onClick={logOutUser} className="w-full">
|
||||
<DropdownMenuItem>Log Out</DropdownMenuItem>
|
||||
</button>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export { SidebarHeader } from "./SidebarHeader";
|
||||
Reference in New Issue
Block a user