Merge branch 'main' of https://github.com/Infisical/infisical into chore/unify-license-key

This commit is contained in:
Piyush Gupta
2025-11-17 23:22:40 +05:30
29 changed files with 279 additions and 343 deletions
@@ -41,7 +41,6 @@
"common": { "common": {
"head-title": "{{title}} | Infisical", "head-title": "{{title}} | Infisical",
"error_project-already-exists": "A project with this name already exists.", "error_project-already-exists": "A project with this name already exists.",
"no-mobile": " To use Infisical, please log in through a device with larger dimensions. ",
"email": "Email", "email": "Email",
"password": "Password", "password": "Password",
"first-name": "First Name", "first-name": "First Name",
@@ -41,7 +41,6 @@
"common": { "common": {
"head-title": "{{title}} | Infisical", "head-title": "{{title}} | Infisical",
"error_project-already-exists": "Ya existe un proyecto con este nombre.", "error_project-already-exists": "Ya existe un proyecto con este nombre.",
"no-mobile": "Para usar Infisical, inicia sesión con un dispositivo de mayores dimesiones.",
"email": "Correo electrónico", "email": "Correo electrónico",
"password": "Contraseña", "password": "Contraseña",
"first-name": "Nombre", "first-name": "Nombre",
@@ -41,7 +41,6 @@
"common": { "common": {
"head-title": "{{title}} | Infisical", "head-title": "{{title}} | Infisical",
"error_project-already-exists": "Un projet avec ce nom existe déjà.", "error_project-already-exists": "Un projet avec ce nom existe déjà.",
"no-mobile": " Pour utiliser Infisical, veuillez vous connecter avec un appareil avec des dimensions plus grandes. ",
"email": "Email", "email": "Email",
"password": "Mot de passe", "password": "Mot de passe",
"first-name": "Prénom", "first-name": "Prénom",
@@ -30,7 +30,6 @@
"common": { "common": {
"head-title": "{{title}} | Infisical", "head-title": "{{title}} | Infisical",
"error_project-already-exists": "동일한 이름을 가진 프로젝트가 이미 존재해요.", "error_project-already-exists": "동일한 이름을 가진 프로젝트가 이미 존재해요.",
"no-mobile": " Infisical을 사용하려면, 큰 화면을 가진 디바이스로 로그인하여 주세요.",
"email": "메일", "email": "메일",
"password": "비밀번호", "password": "비밀번호",
"first-name": "이름", "first-name": "이름",
@@ -41,7 +41,6 @@
"common": { "common": {
"head-title": "{{title}} | Infisical", "head-title": "{{title}} | Infisical",
"error_project-already-exists": "Já exite um projeto com este nome.", "error_project-already-exists": "Já exite um projeto com este nome.",
"no-mobile": "Para usar o Infisical, faça o login através de um dispositivo com dimensões maiores.",
"email": "Email", "email": "Email",
"password": "Senha", "password": "Senha",
"first-name": "Primeiro Nome", "first-name": "Primeiro Nome",
@@ -41,7 +41,6 @@
"common": { "common": {
"head-title": "{{title}} | Infisical", "head-title": "{{title}} | Infisical",
"error_project-already-exists": "Bu isimle bir proje zaten mevcut.", "error_project-already-exists": "Bu isimle bir proje zaten mevcut.",
"no-mobile": " Infisical'ı kullanmak için, lütfen daha büyük boyutlara sahip bir cihaz üzerinden giriş yapın. ",
"email": "Email", "email": "Email",
"password": "Şifre", "password": "Şifre",
"first-name": "Adınız", "first-name": "Adınız",
@@ -76,8 +76,8 @@ export const ProjectOverviewChangeSection = ({ showSlugField = false }: Props) =
return ( return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4"> <div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="justify-betweens flex"> <div className="justify-betweens mb-8 flex flex-wrap gap-2">
<h2 className="mb-8 flex-1 text-xl font-medium text-mineshaft-100">Project Overview</h2> <h2 className="flex-1 text-xl font-medium text-mineshaft-100">Project Overview</h2>
<div className="space-x-2"> <div className="space-x-2">
<Button <Button
variant="outline_bg" variant="outline_bg"
@@ -1,6 +1,3 @@
import { useTranslation } from "react-i18next";
import { faMobile } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Outlet } from "@tanstack/react-router"; import { Outlet } from "@tanstack/react-router";
import { Banner } from "@app/components/page-frames/Banner"; import { Banner } from "@app/components/page-frames/Banner";
@@ -15,7 +12,6 @@ import { InsecureConnectionBanner } from "../OrganizationLayout/components/Insec
import { AdminNavBar } from "./AdminNavBar"; import { AdminNavBar } from "./AdminNavBar";
export const AdminLayout = () => { export const AdminLayout = () => {
const { t } = useTranslation();
const { config } = useServerConfig(); const { config } = useServerConfig();
const { data: serverDetails, isLoading } = useFetchServerStatus(); const { data: serverDetails, isLoading } = useFetchServerStatus();
const { subscription } = useSubscription(); const { subscription } = useSubscription();
@@ -26,7 +22,7 @@ export const AdminLayout = () => {
<> <>
<Banner /> <Banner />
<div <div
className={`dark hidden ${containerHeight} w-full flex-col overflow-x-hidden bg-bunker-800 transition-all md:flex`} className={`dark ${containerHeight} flex w-full flex-col overflow-x-hidden bg-bunker-800 transition-all`}
> >
<Navbar /> <Navbar />
{!isLoading && !serverDetails?.redisConfigured && <RedisBanner />} {!isLoading && !serverDetails?.redisConfigured && <RedisBanner />}
@@ -40,12 +36,6 @@ export const AdminLayout = () => {
</div> </div>
</div> </div>
</div> </div>
<div className="z-200 flex h-screen w-screen flex-col items-center justify-center bg-bunker-800 md:hidden">
<FontAwesomeIcon icon={faMobile} className="mb-8 text-7xl text-gray-300" />
<p className="max-w-sm px-6 text-center text-lg text-gray-200">
{` ${t("common.no-mobile")} `}
</p>
</div>
<Banner /> <Banner />
</> </>
); );
+1 -1
View File
@@ -13,7 +13,7 @@ export const KmsLayout = () => {
const location = useLocation(); const location = useLocation();
return ( return (
<div className="dark hidden h-full w-full flex-col overflow-x-hidden md:flex"> <div className="dark flex h-full w-full flex-col overflow-x-hidden">
<div className="border-b border-mineshaft-600 bg-mineshaft-900"> <div className="border-b border-mineshaft-600 bg-mineshaft-900">
<motion.div <motion.div
key="menu-project-items" key="menu-project-items"
@@ -1,6 +1,3 @@
import { useTranslation } from "react-i18next";
import { faMobile } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Outlet, useParams } from "@tanstack/react-router"; import { Outlet, useParams } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
@@ -27,8 +24,6 @@ export const OrganizationLayout = () => {
const { popUp, handlePopUpToggle } = usePopUp(["createOrg"] as const); const { popUp, handlePopUpToggle } = usePopUp(["createOrg"] as const);
const { t } = useTranslation();
const containerHeight = config.pageFrameContent ? "h-[94vh]" : "h-screen"; const containerHeight = config.pageFrameContent ? "h-[94vh]" : "h-screen";
const { data: serverDetails, isLoading } = useFetchServerStatus(); const { data: serverDetails, isLoading } = useFetchServerStatus();
@@ -38,7 +33,7 @@ export const OrganizationLayout = () => {
<> <>
<Banner /> <Banner />
<div <div
className={`dark hidden ${containerHeight} w-full flex-col overflow-x-hidden bg-bunker-800 transition-all md:flex`} className={`dark ${containerHeight} flex w-full flex-col overflow-x-hidden bg-bunker-800 transition-all`}
> >
<Navbar /> <Navbar />
<div className="flex grow flex-col overflow-y-hidden"> <div className="flex grow flex-col overflow-y-hidden">
@@ -61,12 +56,6 @@ export const OrganizationLayout = () => {
isOpen={popUp?.createOrg?.isOpen} isOpen={popUp?.createOrg?.isOpen}
onClose={() => handlePopUpToggle("createOrg", false)} onClose={() => handlePopUpToggle("createOrg", false)}
/> />
<div className="z-200 flex h-screen w-screen flex-col items-center justify-center bg-bunker-800 md:hidden">
<FontAwesomeIcon icon={faMobile} className="mb-8 text-7xl text-gray-300" />
<p className="max-w-sm px-6 text-center text-lg text-gray-200">
{` ${t("common.no-mobile")} `}
</p>
</div>
<Banner /> <Banner />
</> </>
); );
@@ -294,7 +294,7 @@ export const Navbar = () => {
</> </>
) : ( ) : (
<> <>
<div className="flex items-center overflow-hidden"> <div className="flex min-w-12 items-center overflow-hidden">
<DropdownMenu modal={false} open={isOrgSelectOpen} onOpenChange={setIsOrgSelectOpen}> <DropdownMenu modal={false} open={isOrgSelectOpen} onOpenChange={setIsOrgSelectOpen}>
<div className="group flex cursor-pointer items-center gap-2 overflow-hidden text-sm text-white transition-all duration-100 hover:text-primary"> <div className="group flex cursor-pointer items-center gap-2 overflow-hidden text-sm text-white transition-all duration-100 hover:text-primary">
<Badge <Badge
@@ -324,7 +324,7 @@ export const Navbar = () => {
<span>{currentOrg?.name}</span> <span>{currentOrg?.name}</span>
</button> </button>
</Badge> </Badge>
<div className="mr-1 rounded-sm border border-mineshaft-500 px-1 text-xs text-bunker-300 no-underline!"> <div className="mr-1 hidden rounded-sm border border-mineshaft-500 px-1 text-xs text-bunker-300 no-underline! md:inline-block">
{getPlan(subscription)} {getPlan(subscription)}
</div> </div>
{subscription.cardDeclined && ( {subscription.cardDeclined && (
@@ -468,7 +468,7 @@ export const Navbar = () => {
className={twMerge( className={twMerge(
"gap-x-1.5 text-sm", "gap-x-1.5 text-sm",
!isOrgScope && !isOrgScope &&
"bg-transparent text-mineshaft-200 hover:!bg-transparent hover:underline [&>svg]:!text-sub-org" "min-w-6 bg-transparent text-mineshaft-200 hover:!bg-transparent hover:underline [&>svg]:!text-sub-org"
)} )}
> >
<Link to="/organization/projects"> <Link to="/organization/projects">
@@ -569,11 +569,11 @@ export const Navbar = () => {
)} )}
{user.superAdmin && !location.pathname.startsWith("/admin") && ( {user.superAdmin && !location.pathname.startsWith("/admin") && (
<Link <Link
className="mr-2 flex items-center rounded-md border border-mineshaft-500 px-2.5 py-1.5 text-sm whitespace-nowrap text-mineshaft-200 hover:bg-mineshaft-600" className="mr-2 flex h-[34px] items-center rounded-md border border-mineshaft-500 px-2.5 py-1.5 text-sm whitespace-nowrap text-mineshaft-200 hover:bg-mineshaft-600"
to="/admin" to="/admin"
> >
<InstanceIcon className="mr-2 inline-block size-3.5" /> <InstanceIcon className="inline-block size-3.5" />
Server Console <span className="ml-2 hidden md:inline-block">Server Console</span>
</Link> </Link>
)} )}
<DropdownMenu modal={false}> <DropdownMenu modal={false}>
@@ -21,7 +21,7 @@ export const OrgNavBar = ({ isHidden }: Props) => {
return ( return (
<> <>
{!isHidden && ( {!isHidden && (
<div className="dark hidden w-full flex-col overflow-x-hidden border-b border-mineshaft-600 bg-mineshaft-900 px-4 md:flex"> <div className="dark flex w-full flex-col overflow-x-hidden border-b border-mineshaft-600 bg-mineshaft-900 px-4">
<motion.div <motion.div
key="menu-org-items" key="menu-org-items"
initial={{ x: -150 }} initial={{ x: -150 }}
+1 -1
View File
@@ -28,7 +28,7 @@ export const PamLayout = () => {
return ( return (
<> <>
<div className="dark hidden h-full w-full flex-col overflow-x-hidden md:flex"> <div className="dark flex h-full w-full flex-col overflow-x-hidden">
<div className="border-b border-mineshaft-600 bg-mineshaft-900"> <div className="border-b border-mineshaft-600 bg-mineshaft-900">
<motion.div <motion.div
key="menu-project-items" key="menu-project-items"
@@ -1,29 +1,16 @@
import { useTranslation } from "react-i18next";
import { faMobile } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Outlet } from "@tanstack/react-router"; import { Outlet } from "@tanstack/react-router";
import { InsecureConnectionBanner } from "../OrganizationLayout/components/InsecureConnectionBanner"; import { InsecureConnectionBanner } from "../OrganizationLayout/components/InsecureConnectionBanner";
export const PersonalSettingsLayout = () => { export const PersonalSettingsLayout = () => {
const { t } = useTranslation();
return ( return (
<> <div className="dark flex h-screen w-full flex-col overflow-x-hidden bg-bunker-800">
<div className="dark hidden h-screen w-full flex-col overflow-x-hidden bg-bunker-800 md:flex"> {!window.isSecureContext && <InsecureConnectionBanner />}
{!window.isSecureContext && <InsecureConnectionBanner />} <div className="flex grow flex-col overflow-y-hidden md:flex-row">
<div className="flex grow flex-col overflow-y-hidden md:flex-row"> <main className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4 dark:scheme-dark">
<main className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4 dark:scheme-dark"> <Outlet />
<Outlet /> </main>
</main>
</div>
</div> </div>
<div className="z-200 flex h-screen w-screen flex-col items-center justify-center bg-bunker-800 md:hidden"> </div>
<FontAwesomeIcon icon={faMobile} className="mb-8 text-7xl text-gray-300" />
<p className="max-w-sm px-6 text-center text-lg text-gray-200">
{` ${t("common.no-mobile")} `}
</p>
</div>
</>
); );
}; };
@@ -1,6 +1,3 @@
import { useTranslation } from "react-i18next";
import { faMobile } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet, useLocation } from "@tanstack/react-router"; import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
@@ -17,7 +14,6 @@ export const PkiManagerLayout = () => {
const { currentProject } = useProject(); const { currentProject } = useProject();
const { assumedPrivilegeDetails } = useProjectPermission(); const { assumedPrivilegeDetails } = useProjectPermission();
const { subscription } = useSubscription(); const { subscription } = useSubscription();
const { t } = useTranslation();
const { data: subscribers = [] } = useListWorkspacePkiSubscribers(currentProject?.id || ""); const { data: subscribers = [] } = useListWorkspacePkiSubscribers(currentProject?.id || "");
const { data: templatesData } = useListWorkspaceCertificateTemplates({ const { data: templatesData } = useListWorkspaceCertificateTemplates({
@@ -32,147 +28,137 @@ export const PkiManagerLayout = () => {
const location = useLocation(); const location = useLocation();
return ( return (
<> <div className="dark flex h-full w-full flex-col overflow-x-hidden">
<div className="dark hidden h-full w-full flex-col overflow-x-hidden md:flex"> <div className="border-b border-mineshaft-600 bg-mineshaft-900">
<div className="border-b border-mineshaft-600 bg-mineshaft-900"> <motion.div
<motion.div key="menu-project-items"
key="menu-project-items" initial={{ x: -150 }}
initial={{ x: -150 }} animate={{ x: 0 }}
animate={{ x: 0 }} exit={{ x: -150 }}
exit={{ x: -150 }} transition={{ duration: 0.2 }}
transition={{ duration: 0.2 }} className="px-4"
className="px-4" >
> <nav className="w-full">
<nav className="w-full"> <Tabs value="selected">
<Tabs value="selected"> <TabList className="border-b-0">
<TabList className="border-b-0"> <Link
<Link to="/projects/cert-management/$projectId/policies"
to="/projects/cert-management/$projectId/policies" params={{
params={{ projectId: currentProject.id
projectId: currentProject.id }}
}} >
> {({ isActive }) => <Tab value={isActive ? "selected" : ""}>Certificates</Tab>}
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Certificates</Tab>} </Link>
</Link> <Link
<Link to="/projects/cert-management/$projectId/certificate-authorities"
to="/projects/cert-management/$projectId/certificate-authorities" params={{
params={{ projectId: currentProject.id
projectId: currentProject.id }}
}} >
> {({ isActive }) => (
{({ isActive }) => ( <Tab value={isActive || location.pathname.match(/\/ca\//) ? "selected" : ""}>
<Tab value={isActive || location.pathname.match(/\/ca\//) ? "selected" : ""}> Certificate Authorities
Certificate Authorities </Tab>
</Tab>
)}
</Link>
<Link
to="/projects/cert-management/$projectId/alerting"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Alerting</Tab>}
</Link>
<Link
to="/projects/cert-management/$projectId/integrations"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Integrations</Tab>}
</Link>
<Link
to="/projects/cert-management/$projectId/app-connections"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => (
<Tab value={isActive ? "selected" : ""}>App Connections</Tab>
)}
</Link>
{showLegacySection && (
<>
{(subscription.pkiLegacyTemplates || hasExistingSubscribers) && (
<Link
to="/projects/cert-management/$projectId/subscribers"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => (
<Tab value={isActive ? "selected" : ""}>Subscribers (Legacy)</Tab>
)}
</Link>
)}
{(subscription.pkiLegacyTemplates || hasExistingTemplates) && (
<Link
to="/projects/cert-management/$projectId/certificate-templates"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => (
<Tab value={isActive ? "selected" : ""}>
Certificate Templates (Legacy)
</Tab>
)}
</Link>
)}
</>
)} )}
<Link </Link>
to="/projects/cert-management/$projectId/access-management" <Link
params={{ to="/projects/cert-management/$projectId/alerting"
projectId: currentProject.id params={{
}} projectId: currentProject.id
> }}
{({ isActive }) => ( >
<Tab {({ isActive }) => <Tab value={isActive ? "selected" : ""}>Alerting</Tab>}
value={ </Link>
isActive || <Link
location.pathname.match(/\/groups\/|\/identities\/|\/members\/|\/roles\//) to="/projects/cert-management/$projectId/integrations"
? "selected" params={{
: "" projectId: currentProject.id
} }}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Integrations</Tab>}
</Link>
<Link
to="/projects/cert-management/$projectId/app-connections"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>App Connections</Tab>}
</Link>
{showLegacySection && (
<>
{(subscription.pkiLegacyTemplates || hasExistingSubscribers) && (
<Link
to="/projects/cert-management/$projectId/subscribers"
params={{
projectId: currentProject.id
}}
> >
Access Control {({ isActive }) => (
</Tab> <Tab value={isActive ? "selected" : ""}>Subscribers (Legacy)</Tab>
)}
</Link>
)} )}
</Link> {(subscription.pkiLegacyTemplates || hasExistingTemplates) && (
<Link <Link
to="/projects/cert-management/$projectId/audit-logs" to="/projects/cert-management/$projectId/certificate-templates"
params={{ params={{
projectId: currentProject.id projectId: currentProject.id
}} }}
> >
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Audit Logs</Tab>} {({ isActive }) => (
</Link> <Tab value={isActive ? "selected" : ""}>
<Link Certificate Templates (Legacy)
to="/projects/cert-management/$projectId/settings" </Tab>
params={{ )}
projectId: currentProject.id </Link>
}} )}
> </>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Settings</Tab>} )}
</Link> <Link
</TabList> to="/projects/cert-management/$projectId/access-management"
</Tabs> params={{
</nav> projectId: currentProject.id
</motion.div> }}
</div> >
{assumedPrivilegeDetails && <AssumePrivilegeModeBanner />} {({ isActive }) => (
<div className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4"> <Tab
<Outlet /> value={
</div> isActive ||
location.pathname.match(/\/groups\/|\/identities\/|\/members\/|\/roles\//)
? "selected"
: ""
}
>
Access Control
</Tab>
)}
</Link>
<Link
to="/projects/cert-management/$projectId/audit-logs"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Audit Logs</Tab>}
</Link>
<Link
to="/projects/cert-management/$projectId/settings"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Settings</Tab>}
</Link>
</TabList>
</Tabs>
</nav>
</motion.div>
</div> </div>
<div className="z-200 flex h-screen w-screen flex-col items-center justify-center bg-bunker-800 md:hidden"> {assumedPrivilegeDetails && <AssumePrivilegeModeBanner />}
<FontAwesomeIcon icon={faMobile} className="mb-8 text-7xl text-gray-300" /> <div className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4">
<p className="max-w-sm px-6 text-center text-lg text-gray-200"> <Outlet />
{` ${t("common.no-mobile")} `}
</p>
</div> </div>
</> </div>
); );
}; };
@@ -106,7 +106,9 @@ export const ProjectSelect = () => {
</p> </p>
<Badge variant="project"> <Badge variant="project">
<ProjectIcon /> <ProjectIcon />
{currentWorkspace.type ? PROJECT_TYPE_NAME[currentWorkspace.type] : "Project"} <span className="hidden sm:inline-block">
{currentWorkspace.type ? PROJECT_TYPE_NAME[currentWorkspace.type] : "Project"}
</span>
</Badge> </Badge>
</Link> </Link>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
@@ -1,6 +1,3 @@
import { useTranslation } from "react-i18next";
import { faMobile } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet, useLocation } from "@tanstack/react-router"; import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
@@ -20,7 +17,6 @@ export const SecretManagerLayout = () => {
const { assumedPrivilegeDetails } = useProjectPermission(); const { assumedPrivilegeDetails } = useProjectPermission();
const location = useLocation(); const location = useLocation();
const { t } = useTranslation();
const projectSlug = currentProject?.slug || ""; const projectSlug = currentProject?.slug || "";
const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({ const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({
@@ -42,141 +38,131 @@ export const SecretManagerLayout = () => {
(secretApprovalReqCount?.open || 0) + (accessApprovalRequestCount?.pendingCount || 0); (secretApprovalReqCount?.open || 0) + (accessApprovalRequestCount?.pendingCount || 0);
return ( return (
<> <div className="dark flex h-full w-full flex-col overflow-x-hidden">
<div className="dark hidden h-full w-full flex-col overflow-x-hidden md:flex"> <div className="border-b border-mineshaft-600 bg-mineshaft-900">
<div className="border-b border-mineshaft-600 bg-mineshaft-900"> <motion.div
<motion.div key="menu-project-items"
key="menu-project-items" initial={{ x: -150 }}
initial={{ x: -150 }} animate={{ x: 0 }}
animate={{ x: 0 }} exit={{ x: -150 }}
exit={{ x: -150 }} transition={{ duration: 0.2 }}
transition={{ duration: 0.2 }} className="px-4"
className="px-4" >
> <nav className="w-full">
<nav className="w-full"> <Tabs value="selected">
<Tabs value="selected"> <TabList className="border-b-0">
<TabList className="border-b-0"> <Link
<Link to="/projects/secret-management/$projectId/overview"
to="/projects/secret-management/$projectId/overview" params={{
params={{ projectId: currentProject.id,
projectId: currentProject.id, ...(currentProject.environments.length
...(currentProject.environments.length ? { envSlug: currentProject.environments[0]?.slug }
? { envSlug: currentProject.environments[0]?.slug } : {})
: {}) }}
}} >
> {({ isActive }) => (
{({ isActive }) => ( <Tab
<Tab value={
value={ isActive || location.pathname.match(/\/secrets\/|\/commits\//)
isActive || location.pathname.match(/\/secrets\/|\/commits\//) ? "selected"
? "selected" : ""
: "" }
}
>
Overview
</Tab>
)}
</Link>
<Link
to="/projects/secret-management/$projectId/approval"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => (
<Tab value={isActive ? "selected" : ""}>
Approvals
{Boolean(
secretApprovalReqCount?.open || accessApprovalRequestCount?.pendingCount
) && (
<Badge variant="warning" isSquare className="ml-1.5">
{pendingRequestsCount}
</Badge>
)}
</Tab>
)}
</Link>
<Link
to="/projects/secret-management/$projectId/integrations"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Integrations</Tab>}
</Link>
{Boolean(secretRotations?.length) && (
<Link
to="/projects/secret-management/$projectId/secret-rotation"
params={{
projectId: currentProject.id
}}
> >
{({ isActive }) => ( Overview
<Tab value={isActive ? "selected" : ""}>Secret Rotations</Tab> </Tab>
)}
</Link>
)} )}
</Link>
<Link
to="/projects/secret-management/$projectId/approval"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => (
<Tab value={isActive ? "selected" : ""}>
Approvals
{Boolean(
secretApprovalReqCount?.open || accessApprovalRequestCount?.pendingCount
) && (
<Badge variant="warning" isSquare className="ml-1.5">
{pendingRequestsCount}
</Badge>
)}
</Tab>
)}
</Link>
<Link
to="/projects/secret-management/$projectId/integrations"
params={{
projectId: currentProject.id
}}
>
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Integrations</Tab>}
</Link>
{Boolean(secretRotations?.length) && (
<Link <Link
to="/projects/secret-management/$projectId/app-connections" to="/projects/secret-management/$projectId/secret-rotation"
params={{ params={{
projectId: currentProject.id projectId: currentProject.id
}} }}
> >
{({ isActive }) => ( {({ isActive }) => (
<Tab value={isActive ? "selected" : ""}>App Connections</Tab> <Tab value={isActive ? "selected" : ""}>Secret Rotations</Tab>
)} )}
</Link> </Link>
<Link )}
to="/projects/secret-management/$projectId/access-management" <Link
params={{ to="/projects/secret-management/$projectId/app-connections"
projectId: currentProject.id params={{
}} projectId: currentProject.id
> }}
{({ isActive }) => ( >
<Tab {({ isActive }) => <Tab value={isActive ? "selected" : ""}>App Connections</Tab>}
value={ </Link>
isActive || <Link
location.pathname.match(/\/groups\/|\/identities\/|\/members\/|\/roles\//) to="/projects/secret-management/$projectId/access-management"
? "selected" params={{
: "" projectId: currentProject.id
} }}
> >
Access Control {({ isActive }) => (
</Tab> <Tab
)} value={
</Link> isActive ||
<Link location.pathname.match(/\/groups\/|\/identities\/|\/members\/|\/roles\//)
to="/projects/secret-management/$projectId/audit-logs" ? "selected"
params={{ : ""
projectId: currentProject.id }
}} >
> Access Control
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Audit Logs</Tab>} </Tab>
</Link> )}
<Link </Link>
to="/projects/secret-management/$projectId/settings" <Link
params={{ to="/projects/secret-management/$projectId/audit-logs"
projectId: currentProject.id params={{
}} projectId: currentProject.id
> }}
{({ isActive }) => <Tab value={isActive ? "selected" : ""}>Settings</Tab>} >
</Link> {({ isActive }) => <Tab value={isActive ? "selected" : ""}>Audit Logs</Tab>}
</TabList> </Link>
</Tabs> <Link
</nav> to="/projects/secret-management/$projectId/settings"
</motion.div> params={{
</div> projectId: currentProject.id
{assumedPrivilegeDetails && <AssumePrivilegeModeBanner />} }}
<div className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4"> >
<Outlet /> {({ isActive }) => <Tab value={isActive ? "selected" : ""}>Settings</Tab>}
</div> </Link>
</TabList>
</Tabs>
</nav>
</motion.div>
</div> </div>
<div className="z-200 flex h-screen w-screen flex-col items-center justify-center bg-bunker-800 md:hidden"> {assumedPrivilegeDetails && <AssumePrivilegeModeBanner />}
<FontAwesomeIcon icon={faMobile} className="mb-8 text-7xl text-gray-300" /> <div className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4">
<p className="max-w-sm px-6 text-center text-lg text-gray-200"> <Outlet />
{` ${t("common.no-mobile")} `}
</p>
</div> </div>
</> </div>
); );
}; };
@@ -36,7 +36,7 @@ export const SecretScanningLayout = () => {
); );
return ( return (
<div className="dark hidden h-full w-full flex-col overflow-x-hidden md:flex"> <div className="dark flex h-full w-full flex-col overflow-x-hidden">
<div className="border-b border-mineshaft-600 bg-mineshaft-900"> <div className="border-b border-mineshaft-600 bg-mineshaft-900">
<motion.div <motion.div
key="menu-project-items" key="menu-project-items"
+1 -1
View File
@@ -18,7 +18,7 @@ export const SshLayout = () => {
const location = useLocation(); const location = useLocation();
return ( return (
<div className="dark hidden h-full w-full flex-col overflow-x-hidden md:flex"> <div className="dark flex h-full w-full flex-col overflow-x-hidden">
<div className="border-b border-mineshaft-600 bg-mineshaft-900"> <div className="border-b border-mineshaft-600 bg-mineshaft-900">
<motion.div <motion.div
key="menu-project-items" key="menu-project-items"
@@ -209,7 +209,7 @@ export const AppConnectionsTable = ({ projectId, projectType }: Props) => {
return ( return (
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4"> <div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-4 flex items-center justify-between"> <div className="mb-4 flex flex-wrap items-center justify-between gap-2">
<div> <div>
<div className="flex items-center gap-x-2"> <div className="flex items-center gap-x-2">
<p className="text-xl font-medium text-mineshaft-100">App Connections</p> <p className="text-xl font-medium text-mineshaft-100">App Connections</p>
@@ -125,7 +125,7 @@ export const AllProjectView = ({
return ( return (
<div> <div>
<div className="flex w-full flex-row"> <div className="flex w-full flex-row flex-wrap gap-2 md:flex-nowrap md:gap-0">
<ProjectListToggle value={projectListView} onChange={onProjectListViewChange} /> <ProjectListToggle value={projectListView} onChange={onProjectListViewChange} />
<Input <Input
className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80" className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
@@ -360,7 +360,7 @@ export const MyProjectView = ({
return ( return (
<div> <div>
<div className="flex w-full flex-row"> <div className="flex w-full flex-row flex-wrap gap-2 md:flex-nowrap md:gap-0">
<ProjectListToggle value={projectListView} onChange={onProjectListViewChange} /> <ProjectListToggle value={projectListView} onChange={onProjectListViewChange} />
<Input <Input
className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50/60 duration-200 focus:bg-mineshaft-700/80" className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50/60 duration-200 focus:bg-mineshaft-700/80"
@@ -90,7 +90,7 @@ export const SecretSyncsTab = () => {
return ( return (
<> <>
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-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"> <div className="mb-4 flex flex-wrap items-center justify-between gap-2">
<div> <div>
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
<p className="text-lg font-medium text-mineshaft-100">Secret Syncs</p> <p className="text-lg font-medium text-mineshaft-100">Secret Syncs</p>
@@ -959,9 +959,9 @@ export const OverviewPage = () => {
} }
/> />
</div> </div>
<div className="flex items-center justify-between"> <div className="flex flex-wrap items-center justify-between gap-2">
<FolderBreadCrumbs secretPath={secretPath} onResetSearch={handleResetSearch} /> <FolderBreadCrumbs secretPath={secretPath} onResetSearch={handleResetSearch} />
<div className="flex flex-row items-center justify-center space-x-2"> <div className="flex flex-row flex-wrap items-center gap-2">
{isTableFiltered && ( {isTableFiltered && (
<Button <Button
variant="plain" variant="plain"
@@ -294,7 +294,7 @@ export const AccessApprovalRequest = ({
return ( return (
<> <>
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-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"> <div className="mb-4 flex flex-wrap items-center justify-between gap-2">
<div> <div>
<div className="flex items-center gap-x-2"> <div className="flex items-center gap-x-2">
<p className="text-xl font-medium text-mineshaft-100">Access Requests</p> <p className="text-xl font-medium text-mineshaft-100">Access Requests</p>
@@ -240,7 +240,7 @@ export const ApprovalPolicyList = ({ projectId }: IProps) => {
return ( return (
<> <>
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-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"> <div className="mb-4 flex flex-wrap items-center justify-between gap-2">
<div> <div>
<div className="flex items-center gap-x-2"> <div className="flex items-center gap-x-2">
<p className="text-xl font-medium text-mineshaft-100">Policies</p> <p className="text-xl font-medium text-mineshaft-100">Policies</p>
@@ -690,7 +690,7 @@ export const ActionBar = ({
return ( return (
<> <>
<div className="mt-4 flex items-center space-x-2"> <div className="mt-4 flex flex-wrap items-center gap-2">
<SecretSearchInput <SecretSearchInput
isSingleEnv isSingleEnv
className="w-2/5" className="w-2/5"
@@ -40,12 +40,13 @@ export const SecretSharingSection = () => {
<p className="mb-3 text-xl font-medium">Allow Secret Sharing</p> <p className="mb-3 text-xl font-medium">Allow Secret Sharing</p>
<ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}> <ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}>
{(isAllowed) => ( {(isAllowed) => (
<div className="w-max"> <div>
<Checkbox <Checkbox
id="secretSharing" id="secretSharing"
isDisabled={!isAllowed || isLoading} isDisabled={!isAllowed || isLoading}
isChecked={currentProject?.secretSharing ?? true} isChecked={currentProject?.secretSharing ?? true}
onCheckedChange={(state) => handleToggle(state as boolean)} onCheckedChange={(state) => handleToggle(state as boolean)}
allowMultilineLabel
> >
This feature enables your project members to securely share secrets. This feature enables your project members to securely share secrets.
</Checkbox> </Checkbox>
@@ -40,12 +40,13 @@ export const SecretSnapshotsLegacySection = () => {
<p className="mb-3 text-xl font-medium">Show Secret Snapshots ( legacy )</p> <p className="mb-3 text-xl font-medium">Show Secret Snapshots ( legacy )</p>
<ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}> <ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}>
{(isAllowed) => ( {(isAllowed) => (
<div className="w-max"> <div>
<Checkbox <Checkbox
id="showSnapshotsLegacy" id="showSnapshotsLegacy"
isDisabled={!isAllowed || isLoading} isDisabled={!isAllowed || isLoading}
isChecked={currentProject?.showSnapshotsLegacy ?? false} isChecked={currentProject?.showSnapshotsLegacy ?? false}
onCheckedChange={(state) => handleToggle(state as boolean)} onCheckedChange={(state) => handleToggle(state as boolean)}
allowMultilineLabel
> >
This feature enables your project members to view secret snapshots in the legacy This feature enables your project members to view secret snapshots in the legacy
format. format.