+
diff --git a/frontend/src/layouts/AdminLayout/AdminNavBar.tsx b/frontend/src/layouts/AdminLayout/AdminNavBar.tsx
new file mode 100644
index 000000000..209486eca
--- /dev/null
+++ b/frontend/src/layouts/AdminLayout/AdminNavBar.tsx
@@ -0,0 +1,102 @@
+import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
+import {
+ faArrowLeft,
+ faBuilding,
+ faCog,
+ faDatabase,
+ faGlobe,
+ faKey,
+ faLock,
+ faPlug,
+ faUserTie
+} from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link, useMatchRoute } from "@tanstack/react-router";
+import { motion } from "framer-motion";
+
+import { Tab, TabList, Tabs } from "@app/components/v2";
+
+const generalTabs = [
+ {
+ label: "General",
+ icon: faCog,
+ link: "/admin/"
+ },
+ {
+ label: "Encryption",
+ icon: faLock,
+ link: "/admin/encryption"
+ },
+ {
+ label: "Authentication",
+ icon: faCheckCircle,
+ link: "/admin/authentication"
+ },
+ {
+ label: "Integrations",
+ icon: faPlug,
+ link: "/admin/integrations"
+ },
+ {
+ label: "Caching",
+ icon: faDatabase,
+ link: "/admin/caching"
+ },
+ {
+ label: "Environment Variables",
+ icon: faKey,
+ link: "/admin/environment"
+ }
+];
+
+const othersTabs = [
+ {
+ label: "Access Controls",
+ icon: faUserTie,
+ link: "/admin/access-management"
+ },
+ {
+ label: "Resource Overview",
+ icon: faBuilding,
+ link: "/admin/resources/overview"
+ }
+];
+
+export const AdminNavBar = () => {
+ const matchRoute = useMatchRoute();
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {[...generalTabs, ...othersTabs].map((tab) => {
+ const isActive = matchRoute({ to: tab.link, fuzzy: false });
+ return (
+
+
+ {tab.label}
+
+
+ );
+ })}
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/layouts/AdminLayout/Sidebar.tsx b/frontend/src/layouts/AdminLayout/Sidebar.tsx
deleted file mode 100644
index 185ea1dbf..000000000
--- a/frontend/src/layouts/AdminLayout/Sidebar.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
-import {
- faBuilding,
- faChevronLeft,
- faCog,
- faDatabase,
- faKey,
- faLock,
- faPlug,
- faUserTie
-} 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";
-
-const generalTabs = [
- {
- label: "General",
- icon: faCog,
- link: "/admin/"
- },
- {
- label: "Encryption",
- icon: faLock,
- link: "/admin/encryption"
- },
- {
- label: "Authentication",
- icon: faCheckCircle,
- link: "/admin/authentication"
- },
- {
- label: "Integrations",
- icon: faPlug,
- link: "/admin/integrations"
- },
- {
- label: "Caching",
- icon: faDatabase,
- link: "/admin/caching"
- },
- {
- label: "Environment Variables",
- icon: faKey,
- link: "/admin/environment"
- }
-];
-
-const othersTabs = [
- {
- label: "Access Controls",
- icon: faUserTie,
- link: "/admin/access-management"
- },
- {
- label: "Resource Overview",
- icon: faBuilding,
- link: "/admin/resources/overview"
- }
-];
-
-export const AdminSidebar = () => {
- const matchRoute = useMatchRoute();
-
- return (
-
-
-
-
-
- {generalTabs.map((tab) => {
- const isActive = matchRoute({ to: tab.link, fuzzy: false });
- return (
-
-
-
-
-
- );
- })}
-
-
- {othersTabs.map((tab) => {
- const isActive = matchRoute({ to: tab.link, fuzzy: false });
- return (
-
-
-
-
-
- );
- })}
-
-
-
-
-
-
- }
- >
- Back to Organization
-
-
-
-
-
- );
-};
diff --git a/frontend/src/layouts/KmsLayout/KmsLayout.tsx b/frontend/src/layouts/KmsLayout/KmsLayout.tsx
index 4aa1c1406..a925b7957 100644
--- a/frontend/src/layouts/KmsLayout/KmsLayout.tsx
+++ b/frontend/src/layouts/KmsLayout/KmsLayout.tsx
@@ -1,9 +1,9 @@
-import { faBook, faCog, faCube, faHome, faLock, faUsers } from "@fortawesome/free-solid-svg-icons";
+import { faArrowLeft, faGlobe } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Link, Outlet } from "@tanstack/react-router";
+import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
-import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
+import { Tab, TabList, Tabs } from "@app/components/v2";
import { useProject, useProjectPermission } from "@app/context";
import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePrivilegeModeBanner";
@@ -12,138 +12,87 @@ export const KmsLayout = () => {
const { currentProject } = useProject();
const { assumedPrivilegeDetails } = useProjectPermission();
+ const location = useLocation();
+
return (
-
+
-
-
-
- KMS
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Project Settings
-
-
- )}
-
-
-
-
-
-
+
+
+
-
-
-
- }
- >
- Organization Home
-
+
+
+
+
-
-
+
+ {({ isActive }) =>
Overview }
+
+
+ {({ isActive }) =>
KMIP }
+
+
+ {({ isActive }) =>
Audit Logs }
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) =>
Settings }
+
+
+
-
- {assumedPrivilegeDetails &&
}
-
-
+
+ {assumedPrivilegeDetails &&
}
+
+
);
diff --git a/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx b/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx
index f2866259c..c1cc10e41 100644
--- a/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx
+++ b/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx
@@ -13,7 +13,7 @@ import { useFetchServerStatus } from "@app/hooks/api";
import { AuditLogBanner } from "./components/AuditLogBanner";
import { InsecureConnectionBanner } from "./components/InsecureConnectionBanner";
import { Navbar } from "./components/NavBar";
-import { OrgSidebar } from "./components/OrgSidebar";
+import { OrgNavBar } from "./components/OrgNavBar";
import { RedisBanner } from "./components/RedisBanner";
import { SmtpBanner } from "./components/SmtpBanner";
@@ -41,16 +41,16 @@ export const OrganizationLayout = () => {
className={`dark hidden ${containerHeight} w-full flex-col overflow-x-hidden bg-bunker-800 transition-all md:flex`}
>
- {!isLoading && !serverDetails?.redisConfigured &&
}
- {!isLoading && !serverDetails?.emailConfigured &&
}
- {!isLoading && subscription.auditLogs &&
}
- {!window.isSecureContext &&
}
-
-
+
+
+ {!isLoading && !isInsideProject && !serverDetails?.redisConfigured &&
}
+ {!isLoading && !isInsideProject && !serverDetails?.emailConfigured &&
}
+ {!isLoading && !isInsideProject && subscription.auditLogs &&
}
+ {!window.isSecureContext && !isInsideProject &&
}
diff --git a/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx b/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx
index 596202bf6..4dcc31e4b 100644
--- a/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx
+++ b/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx
@@ -9,6 +9,7 @@ import {
faEnvelope,
faExclamationTriangle,
faGlobe,
+ faInfinity,
faInfo,
faInfoCircle,
faServer,
@@ -43,7 +44,7 @@ import { envConfig } from "@app/config/env";
import { useOrganization, useSubscription, useUser } from "@app/context";
import { isInfisicalCloud } from "@app/helpers/platform";
import { useToggle } from "@app/hooks";
-import { projectKeys, useGetOrganizations, useLogoutUser } from "@app/hooks/api";
+import { projectKeys, useGetOrganizations, useGetOrgTrialUrl, useLogoutUser } from "@app/hooks/api";
import { authKeys, selectOrganization } from "@app/hooks/api/auth/queries";
import { MfaMethod } from "@app/hooks/api/auth/types";
import { getAuthToken } from "@app/hooks/api/reactQuery";
@@ -162,6 +163,8 @@ export const Navbar = () => {
await navigateUserToOrg(navigate, orgId);
};
+ const { mutateAsync } = useGetOrgTrialUrl();
+
const logout = useLogoutUser();
const logOutUser = async () => {
try {
@@ -201,144 +204,191 @@ export const Navbar = () => {
const isServerAdminPanel = location.pathname.startsWith("/admin");
- const isOrgScope = breadcrumbs?.length === 1; // TODO: scott/akhil is this adequate?
+ const isOrgScope = location.pathname.startsWith("/organization"); // TODO: scott/akhil is this adequate?
return (
-
-
-
-
-
-
-
/
- {isServerAdminPanel ? (
- <>
-
-
-
-
-
Server Console
+
+
+
+
+
-
/
- {breadcrumbs ? (
- // scott: remove /admin as we show server console above
-
- ) : null}
- >
- ) : (
- <>
-
-
-
-
-
-
- {currentOrg?.name}
-
-
- {getPlan(subscription)}
-
- {subscription.cardDeclined && (
-
+ /
+ {isServerAdminPanel ? (
+ <>
+
+
+
+
+ Server Console
+
+ /
+ {breadcrumbs ? (
+ // scott: remove /admin as we show server console above
+
+ ) : null}
+ >
+ ) : (
+ <>
+
+
+
+
-
-
-
-
-
-
-
-
-
- organizations
- {orgs?.map((org) => {
- return (
-
- {
- 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;
- }
-
- if (org.googleSsoAuthEnforced) {
- await logout.mutateAsync();
- window.open(`/api/v1/sso/redirect/google?org_slug=${org.slug}`);
- window.close();
- return;
- }
-
- handleOrgChange(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 && (
-
- )
- }
+
+ {currentOrg?.name}
+
+
+ {getPlan(subscription)}
+
+ {subscription.cardDeclined && (
+
-
- {org.name}
+
+
-
-
- );
- })}
-
-
} onClick={logOutUser}>
- Log Out
-
-
-
-
- /
- {breadcrumbs ? (
-
- ) : null}
- >
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ organizations
+
+ {orgs?.map((org) => {
+ return (
+
+ {
+ 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;
+ }
+
+ if (org.googleSsoAuthEnforced) {
+ await logout.mutateAsync();
+ window.open(`/api/v1/sso/redirect/google?org_slug=${org.slug}`);
+ window.close();
+ return;
+ }
+
+ handleOrgChange(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 && (
+
+ )
+ }
+ >
+
+ {org.name}
+
+
+
+ );
+ })}
+
+ }
+ onClick={logOutUser}
+ >
+ Log Out
+
+
+
+
+ {!isOrgScope && (
+ <>
+ /
+ {breadcrumbs ? (
+
+ ) : null}
+ >
+ )}
+ >
+ )}
+
+ {subscription && subscription.slug === "starter" && !subscription.has_used_trial && (
+
+ }
+ onClick={async () => {
+ if (!subscription || !currentOrg) return;
+
+ // direct user to start pro trial
+ const url = await mutateAsync({
+ orgId: currentOrg.id,
+ success_url: window.location.href
+ });
+
+ window.location.href = url;
+ }}
+ >
+ Free Pro Trial
+
+
+ )}
+ {user.superAdmin && !location.pathname.startsWith("/admin") && (
+
+
+ Server Console
+
)}
-
diff --git a/frontend/src/layouts/OrganizationLayout/components/OrgNavBar/OrgNavBar.tsx b/frontend/src/layouts/OrganizationLayout/components/OrgNavBar/OrgNavBar.tsx
new file mode 100644
index 000000000..f9df103ff
--- /dev/null
+++ b/frontend/src/layouts/OrganizationLayout/components/OrgNavBar/OrgNavBar.tsx
@@ -0,0 +1,110 @@
+import { Link, useLocation } from "@tanstack/react-router";
+import { motion } from "framer-motion";
+
+import { CreateOrgModal } from "@app/components/organization/CreateOrgModal";
+import { Tab, TabList, Tabs } from "@app/components/v2";
+import { usePopUp } from "@app/hooks";
+
+type Props = {
+ isHidden?: boolean;
+};
+
+export const OrgNavBar = ({ isHidden }: Props) => {
+ const { popUp, handlePopUpToggle } = usePopUp(["createOrg"] as const);
+
+ const { pathname } = useLocation();
+
+ return (
+ <>
+ {!isHidden && (
+
+
+
+
+
+
+ {({ isActive }) => (
+
+ Overview
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) => (
+
+ App Connections
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Networking
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Audit Logs
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Settings
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Usage & Billing
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Secret Sharing
+
+ )}
+
+
+
+
+
+
+ )}
+
handlePopUpToggle("createOrg", false)}
+ />
+ >
+ );
+};
diff --git a/frontend/src/layouts/OrganizationLayout/components/OrgNavBar/index.tsx b/frontend/src/layouts/OrganizationLayout/components/OrgNavBar/index.tsx
new file mode 100644
index 000000000..06509e919
--- /dev/null
+++ b/frontend/src/layouts/OrganizationLayout/components/OrgNavBar/index.tsx
@@ -0,0 +1 @@
+export { OrgNavBar } from "./OrgNavBar";
diff --git a/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx b/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx
deleted file mode 100644
index 51e14721e..000000000
--- a/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx
+++ /dev/null
@@ -1,214 +0,0 @@
-import {
- faBook,
- faCog,
- faInfinity,
- faMoneyBill,
- faNetworkWired,
- faPlug,
- faShare,
- faTable,
- faUsers,
- faUserTie
-} from "@fortawesome/free-solid-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Link } from "@tanstack/react-router";
-import { AnimatePresence, motion } from "framer-motion";
-
-import { CreateOrgModal } from "@app/components/organization/CreateOrgModal";
-import { Menu, MenuGroup, MenuItem, Tooltip } from "@app/components/v2";
-import { useOrganization, useSubscription, useUser } from "@app/context";
-import { usePopUp } from "@app/hooks";
-import { useGetOrgTrialUrl } from "@app/hooks/api";
-
-type Props = {
- isHidden?: boolean;
-};
-
-export const OrgSidebar = ({ isHidden }: Props) => {
- const { subscription } = useSubscription();
-
- const { user } = useUser();
- const { mutateAsync } = useGetOrgTrialUrl();
-
- const { currentOrg } = useOrganization();
-
- const { popUp, handlePopUpToggle } = usePopUp(["createOrg"] as const);
-
- return (
- <>
-
- {!isHidden && (
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Organization Access
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Usage & Billing
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Organization Settings
-
-
- )}
-
-
-
-
- {({ isActive }) => (
-
-
-
-
-
- App Connections
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
-
-
-
- {subscription &&
- subscription.slug === "starter" &&
- !subscription.has_used_trial && (
-
-
- }
- onClick={async () => {
- if (!subscription || !currentOrg) return;
-
- // direct user to start pro trial
- const url = await mutateAsync({
- orgId: currentOrg.id,
- success_url: window.location.href
- });
-
- window.location.href = url;
- }}
- >
- Pro Trial
-
-
- )}
-
-
-
-
- }
- >
- Share Secret
-
-
- {user.superAdmin && (
-
-
-
-
- }
- >
- Server Console
-
-
- )}
-
-
-
- )}
-
-
handlePopUpToggle("createOrg", false)}
- />
- >
- );
-};
diff --git a/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/index.tsx b/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/index.tsx
deleted file mode 100644
index 315d7ffab..000000000
--- a/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/index.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export { OrgSidebar } from "./OrgSidebar";
diff --git a/frontend/src/layouts/PamLayout/PamLayout.tsx b/frontend/src/layouts/PamLayout/PamLayout.tsx
index 48f6af116..1a0564a25 100644
--- a/frontend/src/layouts/PamLayout/PamLayout.tsx
+++ b/frontend/src/layouts/PamLayout/PamLayout.tsx
@@ -1,19 +1,11 @@
import { useEffect } from "react";
-import {
- faBook,
- faBoxOpen,
- faCog,
- faDisplay,
- faHome,
- faUser,
- faUsers
-} from "@fortawesome/free-solid-svg-icons";
+import { faArrowLeft, faGlobe } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Link, Outlet } from "@tanstack/react-router";
+import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
-import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
+import { Tab, TabList, Tabs } from "@app/components/v2";
import { useProject, useProjectPermission, useSubscription } from "@app/context";
import { usePopUp } from "@app/hooks";
@@ -23,7 +15,7 @@ export const PamLayout = () => {
const { currentProject } = useProject();
const { subscription } = useSubscription();
const { assumedPrivilegeDetails } = useProjectPermission();
-
+ const location = useLocation();
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"]);
useEffect(() => {
@@ -35,152 +27,91 @@ export const PamLayout = () => {
return (
<>
-
+
-
-
-
- PAM
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Project Settings
-
-
- )}
-
-
-
-
-
-
+
+
+
-
-
-
- }
- >
- Organization Home
-
+
+
+
+
-
-
+
+ {({ isActive }) =>
Accounts }
+
+
+ {({ isActive }) =>
Resources }
+
+
+ {({ isActive }) =>
Sessions }
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) =>
Audit Logs }
+
+
+ {({ isActive }) =>
Settings }
+
+
+
-
- {assumedPrivilegeDetails &&
}
-
-
+
+ {assumedPrivilegeDetails &&
}
+
+
{
const { assumedPrivilegeDetails } = useProjectPermission();
const { t } = useTranslation();
+ const location = useLocation();
return (
<>
-
+
-
-
-
- PKI Manager
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Certificate Templates
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Certificates Authority
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- App Connections
-
-
- )}
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Project Settings
-
-
- )}
-
-
-
-
-
-
+
+
+
-
-
-
- }
- >
- Organization Home
-
+
+
+
+
-
-
+
+ {({ isActive }) =>
Subscribers }
+
+
+ {({ isActive }) => (
+
Certificate Templates
+ )}
+
+
+ {({ isActive }) => (
+
+ Certificates
+
+ )}
+
+
+ {({ isActive }) => (
+
+ Certificate Authorities
+
+ )}
+
+
+ {({ isActive }) =>
Alerting }
+
+
+ {({ isActive }) =>
Integrations }
+
+
+ {({ isActive }) => (
+
App Connections
+ )}
+
+
+ {({ isActive }) =>
Audit Logs }
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) =>
Settings }
+
+
+
-
- {assumedPrivilegeDetails &&
}
-
-
+
+ {assumedPrivilegeDetails &&
}
+
+
diff --git a/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx b/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx
index 71af774ca..45978e3d7 100644
--- a/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx
+++ b/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx
@@ -15,7 +15,7 @@ export const AssumePrivilegeModeBanner = () => {
if (!assumedPrivilegeDetails) return null;
return (
-
+
You are currently viewing the project with privileges of{" "}
@@ -24,7 +24,7 @@ export const AssumePrivilegeModeBanner = () => {
{assumedPrivilegeDetails?.actorName}
-
+
{
}, [projects, projectFavorites, currentWorkspace]);
return (
-
+
-
-
-
-
-
- {currentWorkspace?.name}
-
-
-
+
+
+
+ {currentWorkspace?.name}
+
+
diff --git a/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx b/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx
index e986d87c3..7fcd3d79c 100644
--- a/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx
+++ b/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx
@@ -1,21 +1,10 @@
import { useTranslation } from "react-i18next";
-import {
- faArrowsSpin,
- faBook,
- faCheckToSlot,
- faCog,
- faHome,
- faMobile,
- faPlug,
- faPuzzlePiece,
- faUsers,
- faVault
-} from "@fortawesome/free-solid-svg-icons";
+import { faArrowLeft, faGlobe, faMobile } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
-import { Badge, Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
+import { Badge, Tab, TabList, Tabs } from "@app/components/v2";
import { useProject, useProjectPermission } from "@app/context";
import {
useGetAccessRequestsCount,
@@ -28,10 +17,10 @@ import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePri
export const SecretManagerLayout = () => {
const { currentProject, projectId } = useProject();
const { assumedPrivilegeDetails } = useProjectPermission();
+ const location = useLocation();
const { t } = useTranslation();
const projectSlug = currentProject?.slug || "";
- const location = useLocation();
const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({
projectId
@@ -54,208 +43,137 @@ export const SecretManagerLayout = () => {
return (
<>
-
+
-
-
-
- Secrets Manager
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
- {Boolean(secretRotations?.length) && (
-
- {({ isActive }) => (
-
-
-
-
-
- Secret Rotations
-
-
- )}
-
- )}
-
- {({ isActive }) => (
-
-
-
-
-
- Approvals
- {Boolean(
- secretApprovalReqCount?.open ||
- accessApprovalRequestCount?.pendingCount
- ) && (
-
- {pendingRequestsCount}
-
- )}
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- App Connections
-
-
- )}
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Project Settings
-
-
- )}
-
-
-
-
-
-
+
+
+
-
-
-
- }
- >
- Organization Home
-
+
+
+
+
-
-
+
+ {({ isActive }) => (
+
+ Overview
+
+ )}
+
+
+ {({ isActive }) =>
Integrations }
+
+ {Boolean(secretRotations?.length) && (
+
+ {({ isActive }) => (
+
Secret Rotations
+ )}
+
+ )}
+
+ {({ isActive }) => (
+
App Connections
+ )}
+
+
+ {({ isActive }) => (
+
+ Approvals
+ {Boolean(
+ secretApprovalReqCount?.open || accessApprovalRequestCount?.pendingCount
+ ) && (
+
+ {pendingRequestsCount}
+
+ )}
+
+ )}
+
+
+ {({ isActive }) =>
Audit Logs }
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) =>
Settings }
+
+
+
-
- {assumedPrivilegeDetails &&
}
-
-
+
+ {assumedPrivilegeDetails &&
}
+
+
diff --git a/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx b/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx
index b4c79786b..b385f1bd5 100644
--- a/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx
+++ b/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx
@@ -1,17 +1,9 @@
-import {
- faBook,
- faCog,
- faDatabase,
- faHome,
- faMagnifyingGlass,
- faPlug,
- faUsers
-} from "@fortawesome/free-solid-svg-icons";
+import { faArrowLeft, faGlobe } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Link, Outlet } from "@tanstack/react-router";
+import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
-import { Badge, Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
+import { Badge, Tab, TabList, Tabs } from "@app/components/v2";
import {
ProjectPermissionSub,
useProject,
@@ -29,6 +21,7 @@ export const SecretScanningLayout = () => {
const { permission } = useProjectPermission();
const { subscription } = useSubscription();
+ const location = useLocation();
const { data: unresolvedFindings } = useGetSecretScanningUnresolvedFindingCount(
currentProject.id,
@@ -45,158 +38,101 @@ export const SecretScanningLayout = () => {
return (
-
+
-
-
-
- Secret Scanning
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
-
Findings
- {Boolean(unresolvedFindings) && (
-
- {unresolvedFindings}
-
- )}
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- App Connections
-
-
- )}
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Project Settings
-
-
- )}
-
-
-
-
-
-
+
+
+
-
-
-
- }
- >
- Organization Home
-
+
+
+
+
-
-
+
+ {({ isActive }) =>
Data Sources }
+
+
+ {({ isActive }) => (
+
+ Findings
+ {Boolean(unresolvedFindings) && (
+
+ {unresolvedFindings}
+
+ )}
+
+ )}
+
+
+ {({ isActive }) =>
App Connections }
+
+
+
+ {({ isActive }) =>
Audit Logs }
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) =>
Settings }
+
+
+
-
- {assumedPrivilegeDetails &&
}
-
-
+
+ {assumedPrivilegeDetails &&
}
+
+
);
diff --git a/frontend/src/layouts/SshLayout/SshLayout.tsx b/frontend/src/layouts/SshLayout/SshLayout.tsx
index 0d68a7548..c6e3c8b3e 100644
--- a/frontend/src/layouts/SshLayout/SshLayout.tsx
+++ b/frontend/src/layouts/SshLayout/SshLayout.tsx
@@ -1,17 +1,10 @@
-import {
- faBook,
- faCog,
- faHome,
- faServer,
- faStamp,
- faUsers
-} from "@fortawesome/free-solid-svg-icons";
+import { faArrowLeft, faGlobe } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Link, Outlet } from "@tanstack/react-router";
+import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { ProjectPermissionCan } from "@app/components/permissions";
-import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
+import { Tab, TabList, Tabs } from "@app/components/v2";
import {
ProjectPermissionActions,
ProjectPermissionSub,
@@ -24,149 +17,110 @@ import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePri
export const SshLayout = () => {
const { currentProject } = useProject();
const { assumedPrivilegeDetails } = useProjectPermission();
+ const location = useLocation();
return (
-
+
-
-
-
- SSH
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {(isAllowed) =>
- isAllowed && (
-
- {({ isActive }) => (
-
-
-
-
-
- Certificates Authority
-
-
- )}
-
- )
- }
-
-
-
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
- )}
-
-
- {({ isActive }) => (
-
-
-
-
-
- Project Settings
-
-
- )}
-
-
-
-
-
-
+
+
+
-
-
-
- }
- >
- Organization Home
-
+
+
+
+
-
-
+
+ {({ isActive }) => (
+
+ Hosts
+
+ )}
+
+
+ {(isAllowed) =>
+ isAllowed && (
+
+ {({ isActive }) => (
+
+ Certificate Authorities
+
+ )}
+
+ )
+ }
+
+
+ {({ isActive }) =>
Audit Logs }
+
+
+ {({ isActive }) => (
+
+ Access Control
+
+ )}
+
+
+ {({ isActive }) =>
Settings }
+
+
+
-
- {assumedPrivilegeDetails &&
}
-
-
+
+ {assumedPrivilegeDetails &&
}
+
+
);
diff --git a/frontend/src/pages/admin/AccessManagementPage/AccessManagementPage.tsx b/frontend/src/pages/admin/AccessManagementPage/AccessManagementPage.tsx
index 0bc494ae2..3dbfd365e 100644
--- a/frontend/src/pages/admin/AccessManagementPage/AccessManagementPage.tsx
+++ b/frontend/src/pages/admin/AccessManagementPage/AccessManagementPage.tsx
@@ -13,8 +13,8 @@ export const AccessManagementPage = () => {
{t("common.head-title", { title: "Access Control" })}
-
-
+
+
{
{t("common.head-title", { title: "Admin" })}
-
-
+
+
{
{t("common.head-title", { title: "Admin" })}
-
-
+
+
{
{t("common.head-title", { title: "Admin" })}
-
-
+
+
{
{t("common.head-title", { title: "Admin" })}
-
-
+
+
{
{t("common.head-title", { title: "Admin" })}
-
-
+
+
{
{t("common.head-title", { title: "Admin" })}
-
-
+
+
{
{t("common.head-title", { title: "Resource Overview" })}
-
-
+
+
-
+
- Organizations
- Users
- Identities
+
+ Organizations
+
+
+ Users
+
+
+ Identities
+
diff --git a/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx b/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx
index 9921ea306..9a9e45644 100644
--- a/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx
+++ b/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx
@@ -10,11 +10,11 @@ import { PkiAlertsSection } from "./components";
export const AlertingPage = () => {
const { t } = useTranslation();
return (
-
+
{t("common.head-title", { title: "Alerting" })}
-
+
{
};
return (
-
+
{data && (
-
-
+
+
+
+ Certificate Authorities
+
+
diff --git a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/CertificateAuthoritiesPage.tsx b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/CertificateAuthoritiesPage.tsx
index 7e2c9fd70..9af497262 100644
--- a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/CertificateAuthoritiesPage.tsx
+++ b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/CertificateAuthoritiesPage.tsx
@@ -11,11 +11,11 @@ import { CaSection } from "./components";
export const CertificateAuthoritiesPage = () => {
const { t } = useTranslation();
return (
-
+
{t("common.head-title", { title: "Certificate Authorities" })}
-
+
{
);
return (
-
+
{t("common.head-title", { title: "Certificates" })}
-
+
{
-
+
-
+
- Certificate Syncs
+
+ Certificate Syncs
+
{
};
return (
-
+
{data && (
-
-
+
+
+
+ Certificates
+
+
diff --git a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx
index 2a7fdf56d..5bedfd770 100644
--- a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx
+++ b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx
@@ -1,6 +1,8 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { useNavigate, useParams } from "@tanstack/react-router";
+import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link, useNavigate, useParams } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
@@ -75,10 +77,20 @@ const Page = () => {
};
return (
-
+
{data && (
-
-
+
+
+
+ Subscribers
+
+
diff --git a/frontend/src/pages/cert-manager/PkiSubscribersPage/PkiSubscribersPage.tsx b/frontend/src/pages/cert-manager/PkiSubscribersPage/PkiSubscribersPage.tsx
index bdb525b59..ad3d8428b 100644
--- a/frontend/src/pages/cert-manager/PkiSubscribersPage/PkiSubscribersPage.tsx
+++ b/frontend/src/pages/cert-manager/PkiSubscribersPage/PkiSubscribersPage.tsx
@@ -13,8 +13,8 @@ export const PkiSubscribersPage = () => {
{t("common.head-title", { title: "PKI Subscribers" })}
-
-
+
+
{
return (
<>
-
-
+
+
{
{t("common.head-title", { title: "PKI Templates" })}
-
-
+
+
-
+
Templates
@@ -267,7 +267,7 @@ export const PkiTemplateListPage = () => {
onDeleteApproved={() => onRemovePkiSubscriberSubmit()}
/>
-
+
{
{t("common.head-title", { title: t("settings.project.title") })}
-
+
-
+
{tabs.map((tab) => (
-
+
{tab.name}
))}
diff --git a/frontend/src/pages/kms/KmipPage/KmipPage.tsx b/frontend/src/pages/kms/KmipPage/KmipPage.tsx
index b2ef8a5f0..e840d1119 100644
--- a/frontend/src/pages/kms/KmipPage/KmipPage.tsx
+++ b/frontend/src/pages/kms/KmipPage/KmipPage.tsx
@@ -15,8 +15,8 @@ export const KmipPage = () => {
{t("common.head-title", { title: "KMS" })}
-
-
+
+
{
{t("common.head-title", { title: "KMS" })}
-
-
+
+
{
{t("common.head-title", { title: t("settings.project.title") })}
-
-
-
+
+
+
{tabs.map((tab) => (
-
+
{tab.name}
))}
diff --git a/frontend/src/pages/organization/AccessManagementPage/AccessManagementPage.tsx b/frontend/src/pages/organization/AccessManagementPage/AccessManagementPage.tsx
index 4ac727332..8059f71ce 100644
--- a/frontend/src/pages/organization/AccessManagementPage/AccessManagementPage.tsx
+++ b/frontend/src/pages/organization/AccessManagementPage/AccessManagementPage.tsx
@@ -76,11 +76,11 @@ export const AccessManagementPage = () => {
const hasNoAccess = tabSections.every((tab) => tab.isHidden);
return (
-
+
{t("common.head-title", { title: t("settings.org.title") })}
-
+
{
isOpen={isUpgradePrivilegeSystemModalOpen}
onOpenChange={setIsUpgradePrivilegeSystemModalOpen}
/>
-
+
{tabSections
.filter((el) => !el.isHidden)
diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/OrgGroupsTab.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/OrgGroupsTab.tsx
index 2192f78fd..d4ff577de 100644
--- a/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/OrgGroupsTab.tsx
+++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/OrgGroupsTab.tsx
@@ -1,17 +1,5 @@
-import { motion } from "framer-motion";
-
import { OrgGroupsSection } from "./components";
export const OrgGroupsTab = () => {
- return (
-
-
-
- );
+ return ;
};
diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/OrgIdentityTab.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/OrgIdentityTab.tsx
index 251b0b831..f2cc98f45 100644
--- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/OrgIdentityTab.tsx
+++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/OrgIdentityTab.tsx
@@ -1,17 +1,5 @@
-import { motion } from "framer-motion";
-
import { IdentitySection } from "./components";
export const OrgIdentityTab = () => {
- return (
-
-
-
- );
+ return ;
};
diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgMembersTab/OrgMembersTab.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgMembersTab/OrgMembersTab.tsx
index 1afb9bfbd..c95ffe816 100644
--- a/frontend/src/pages/organization/AccessManagementPage/components/OrgMembersTab/OrgMembersTab.tsx
+++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgMembersTab/OrgMembersTab.tsx
@@ -1,17 +1,5 @@
-import { motion } from "framer-motion";
-
import { OrgMembersSection } from "./components";
export const OrgMembersTab = () => {
- return (
-
-
-
- );
+ return ;
};
diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx
index 57353e8d9..3cb458d97 100644
--- a/frontend/src/pages/organization/AccessManagementPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx
+++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgRoleTabSection/OrgRoleTabSection.tsx
@@ -1,17 +1,5 @@
-import { motion } from "framer-motion";
-
import { OrgRoleTable } from "./OrgRoleTable";
export const OrgRoleTabSection = () => {
- return (
-
-
-
- );
+ return ;
};
diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/AppConnectionsPage.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/AppConnectionsPage.tsx
index b44fad6ea..3d4f244ca 100644
--- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/AppConnectionsPage.tsx
+++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/AppConnectionsPage.tsx
@@ -20,7 +20,7 @@ export const AppConnectionsPage = withPermission(
-
+
{
-
-
-
+
+
{
-
+
{
- const tabsFiltered = isInfisicalCloud()
- ? tabs
- : [{ name: "Infisical Self-Hosted", key: "tab-infisical-cloud" }];
+ if (!isInfisicalCloud()) {
+ return ;
+ }
return (
-
+
- {tabsFiltered.map((tab) => (
+ {tabs.map((tab) => (
{tab.name}
@@ -33,19 +33,15 @@ export const BillingTabGroup = withPermission(
- {isInfisicalCloud() && (
- <>
-
-
-
-
-
-
-
-
-
- >
- )}
+
+
+
+
+
+
+
+
+
);
},
diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage.tsx
index f0bd24900..d3acd618b 100644
--- a/frontend/src/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage.tsx
+++ b/frontend/src/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage.tsx
@@ -1,6 +1,8 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { useNavigate, useParams } from "@tanstack/react-router";
+import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link, useNavigate, useParams } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
@@ -80,10 +82,20 @@ const Page = () => {
if (isPending) return ;
return (
-
+
{data && (
-
-
+
+
+
+ Groups
+
+
diff --git a/frontend/src/pages/organization/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx b/frontend/src/pages/organization/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx
index adf6dfce8..d85c62727 100644
--- a/frontend/src/pages/organization/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx
+++ b/frontend/src/pages/organization/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx
@@ -1,6 +1,8 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { useNavigate, useParams } from "@tanstack/react-router";
+import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link, useNavigate, useParams } from "@tanstack/react-router";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
import { createNotification } from "@app/components/notifications";
@@ -10,6 +12,7 @@ import { ROUTE_PATHS } from "@app/const/routes";
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { useDeleteIdentity, useGetIdentityById } from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
+import { TabSections } from "@app/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage";
import { ViewIdentityAuthModal } from "@app/pages/organization/IdentityDetailsByIDPage/components/ViewIdentityAuthModal/ViewIdentityAuthModal";
import { OrgAccessControlTabSections } from "@app/types/org";
@@ -72,10 +75,20 @@ const Page = () => {
};
return (
-
+
{data && (
-
-
+
+
+
+ Identities
+
+
diff --git a/frontend/src/pages/organization/NetworkingPage/NetworkingPage.tsx b/frontend/src/pages/organization/NetworkingPage/NetworkingPage.tsx
index e7f3937d5..bc8ae44ef 100644
--- a/frontend/src/pages/organization/NetworkingPage/NetworkingPage.tsx
+++ b/frontend/src/pages/organization/NetworkingPage/NetworkingPage.tsx
@@ -12,7 +12,7 @@ export const NetworkingPage = () => {
-
+
{
const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key);
return (
-
+
{tabs.map((tab) => (
diff --git a/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx b/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx
index 92654c1e7..a528587b3 100644
--- a/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx
+++ b/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx
@@ -58,18 +58,16 @@ export const ProjectsPage = () => {
: true;
return (
-
+
{t("common.head-title", { title: t("settings.members.title") })}
-
+
{projectListView === ProjectListView.MyProjects ? (
handlePopUpOpen("addNewWs")}
diff --git a/frontend/src/pages/organization/RoleByIDPage/RoleByIDPage.tsx b/frontend/src/pages/organization/RoleByIDPage/RoleByIDPage.tsx
index 8b25247be..cce093e7a 100644
--- a/frontend/src/pages/organization/RoleByIDPage/RoleByIDPage.tsx
+++ b/frontend/src/pages/organization/RoleByIDPage/RoleByIDPage.tsx
@@ -1,8 +1,8 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { faCopy, faEllipsisV } from "@fortawesome/free-solid-svg-icons";
+import { faChevronLeft, faCopy, faEllipsisV } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { useNavigate, useParams } from "@tanstack/react-router";
+import { Link, useNavigate, useParams } from "@tanstack/react-router";
import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
@@ -19,6 +19,7 @@ import { ROUTE_PATHS } from "@app/const/routes";
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { useDeleteOrgRole, useGetOrgRole } from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
+import { TabSections } from "@app/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage";
import { DuplicateOrgRoleModal } from "@app/pages/organization/RoleByIDPage/components/DuplicateOrgRoleModal";
import { OrgAccessControlTabSections } from "@app/types/org";
@@ -77,20 +78,26 @@ export const Page = () => {
const isCustomRole = !["admin", "member", "no-access"].includes(data?.slug ?? "");
return (
-
+
{data && (
-
+
+
+
+ Roles
+
-
-
{data.name}
-
- {data.slug} {data.description && `- ${data.description}`}
-
-
-
+ title={data.name}
+ description={
+ <>
+ {data.slug} {data.description && `- ${data.description}`}
+ >
}
>
{isCustomRole && (
diff --git a/frontend/src/pages/organization/SecretSharingPage/SecretSharingPage.tsx b/frontend/src/pages/organization/SecretSharingPage/SecretSharingPage.tsx
index ec3885f5b..ace5b211e 100644
--- a/frontend/src/pages/organization/SecretSharingPage/SecretSharingPage.tsx
+++ b/frontend/src/pages/organization/SecretSharingPage/SecretSharingPage.tsx
@@ -20,7 +20,7 @@ export const SecretSharingPage = () => {
-
+
{
-
+
- Share Secrets
-
+
+ Share Secrets
+
+
Request Secrets
-
- New
-
diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx
index 6ee73a03d..8cee365e3 100644
--- a/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx
+++ b/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx
@@ -20,7 +20,7 @@ export const SecretSharingSettingsPage = withPermission(
{t("common.head-title", { title: "Secret Share Settings" })}
-
+
diff --git a/frontend/src/pages/organization/SettingsPage/SettingsPage.tsx b/frontend/src/pages/organization/SettingsPage/SettingsPage.tsx
index 52fc99f53..919a1159a 100644
--- a/frontend/src/pages/organization/SettingsPage/SettingsPage.tsx
+++ b/frontend/src/pages/organization/SettingsPage/SettingsPage.tsx
@@ -14,8 +14,12 @@ export const SettingsPage = () => {
{t("common.head-title", { title: t("settings.org.title") })}
-
diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx
index ad867238b..66af7df1b 100644
--- a/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx
+++ b/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx
@@ -55,7 +55,7 @@ export const OrgTabGroup = () => {
const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key);
return (
-
+
{tabs.map((tab) => (
diff --git a/frontend/src/pages/organization/UserDetailsByIDPage/UserDetailsByIDPage.tsx b/frontend/src/pages/organization/UserDetailsByIDPage/UserDetailsByIDPage.tsx
index 3153c5fd5..342642d50 100644
--- a/frontend/src/pages/organization/UserDetailsByIDPage/UserDetailsByIDPage.tsx
+++ b/frontend/src/pages/organization/UserDetailsByIDPage/UserDetailsByIDPage.tsx
@@ -1,6 +1,8 @@
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
-import { useNavigate, useParams } from "@tanstack/react-router";
+import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link, useNavigate, useParams } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
@@ -30,6 +32,7 @@ import {
useUpdateOrgMembership
} from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
+import { TabSections } from "@app/pages/organization/GroupDetailsByIDPage/GroupDetailsByIDPage";
import { OrgAccessControlTabSections } from "@app/types/org";
import { UserAuditLogsSection } from "./components/UserProjectsSection/UserAuditLogsSection";
@@ -115,16 +118,30 @@ const Page = withPermission(
};
return (
-
+
{membership && (
-
+
+
+
+ Users
+
{userId !== membership.user.id && (
diff --git a/frontend/src/pages/pam/PamAccountsPage/PamAccountsPage.tsx b/frontend/src/pages/pam/PamAccountsPage/PamAccountsPage.tsx
index da8132193..77f9e4798 100644
--- a/frontend/src/pages/pam/PamAccountsPage/PamAccountsPage.tsx
+++ b/frontend/src/pages/pam/PamAccountsPage/PamAccountsPage.tsx
@@ -21,8 +21,8 @@ export const PamAccountsPage = () => {
a={ProjectPermissionSub.PamAccounts}
>
-
-
+
+
{
+ const navigate = useNavigate({
+ from: "/projects/secret-management/$projectId/overview"
+ });
+
+ const onFolderCrumbClick = (index: number) => {
+ let newAccountPath = `/${path.split("/").filter(Boolean).slice(0, index).join("/")}`;
+
+ if (!newAccountPath.endsWith("/")) {
+ newAccountPath += "/";
+ }
+
+ if (path === newAccountPath) return;
+ navigate({
+ search: (prev) => ({ ...prev, accountPath: newAccountPath })
+ });
+ };
+
+ return (
+
+
onFolderCrumbClick(0)}
+ onKeyDown={() => null}
+ role="button"
+ tabIndex={0}
+ >
+
+
+ {(path || "")
+ .split("/")
+ .filter(Boolean)
+ .map((pathSegment, index, arr) => (
+
onFolderCrumbClick(index + 1)}
+ onKeyDown={() => null}
+ role="button"
+ tabIndex={0}
+ >
+ {pathSegment}
+
+ ))}
+
+ );
+};
diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx
index 7cdf93dc8..d0e86af0c 100644
--- a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx
+++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx
@@ -45,6 +45,7 @@ import { OrderByDirection } from "@app/hooks/api/generic/types";
import { PAM_RESOURCE_TYPE_MAP, TPamAccount, TPamFolder } from "@app/hooks/api/pam";
import { AccountView, AccountViewToggle } from "./AccountViewToggle";
+import { FolderBreadCrumbs } from "./FolderBreadCrumbs";
import { PamAccessAccountModal } from "./PamAccessAccountModal";
import { PamAccountRow } from "./PamAccountRow";
import { PamAddAccountModal } from "./PamAddAccountModal";
@@ -255,6 +256,7 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => {
return (
+ {accountView === AccountView.Nested &&
}
{(isAllowed) =>
diff --git a/frontend/src/pages/pam/PamResourcesPage/PamResourcesPage.tsx b/frontend/src/pages/pam/PamResourcesPage/PamResourcesPage.tsx
index 13e9028e6..8970816d7 100644
--- a/frontend/src/pages/pam/PamResourcesPage/PamResourcesPage.tsx
+++ b/frontend/src/pages/pam/PamResourcesPage/PamResourcesPage.tsx
@@ -21,8 +21,8 @@ export const PamResourcesPage = () => {
a={ProjectPermissionSub.PamResources}
>