additions: sub-org ui updates

This commit is contained in:
Scott Wilson
2025-10-20 11:53:20 -07:00
parent 9db8f2a87d
commit 45a7b4925b
25 changed files with 342 additions and 190 deletions
@@ -24,7 +24,7 @@ import { OrgGroupsTab, OrgIdentityTab, OrgMembersTab, OrgRoleTabSection } from "
export const AccessManagementPage = () => {
const { t } = useTranslation();
const { permission } = useOrgPermission();
const { currentOrg } = useOrganization();
const { currentOrg, isSubOrganization } = useOrganization();
const navigate = useNavigate({
from: ROUTE_PATHS.Organization.AccessControlPage.path
@@ -82,7 +82,7 @@ export const AccessManagementPage = () => {
</Helmet>
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title="Access Control"
description="Manage fine-grained access for users, groups, roles, and identities within your organization resources."
/>
@@ -116,7 +116,11 @@ export const AccessManagementPage = () => {
{tabSections
.filter((el) => !el.isHidden)
.map((el) => (
<Tab variant="org" value={el.key} key={`org-access-tab-${el.key}`}>
<Tab
variant={isSubOrganization ? "namespace" : "org"}
value={el.key}
key={`org-access-tab-${el.key}`}
>
{el.label}
</Tab>
))}
@@ -68,7 +68,7 @@ enum RolesOrderBy {
export const OrgRoleTable = () => {
const navigate = useNavigate();
const { currentOrg } = useOrganization();
const { currentOrg, isSubOrganization } = useOrganization();
const orgId = currentOrg?.id || "";
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
@@ -200,7 +200,9 @@ export const OrgRoleTable = () => {
return (
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-4 flex items-center justify-between">
<p className="text-xl font-medium text-mineshaft-100">Organization Roles</p>
<p className="text-xl font-medium text-mineshaft-100">
{isSubOrganization ? "Sub-" : ""}Organization Roles
</p>
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Role}>
{(isAllowed) => (
<Button
@@ -3,6 +3,7 @@ import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PageHeader } from "@app/components/v2";
import { useOrganization } from "@app/context";
import {
OrgPermissionAppConnectionActions,
OrgPermissionSubjects
@@ -12,6 +13,8 @@ import { AppConnectionsTable } from "@app/pages/organization/AppConnections/AppC
export const AppConnectionsPage = withPermission(
() => {
const { isSubOrganization } = useOrganization();
return (
<div className="bg-bunker-800">
<Helmet>
@@ -22,7 +25,7 @@ export const AppConnectionsPage = withPermission(
<div className="flex w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-8xl">
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
className="w-full"
title="App Connections"
description="Manage organization App Connections"
@@ -1,10 +1,13 @@
import { Helmet } from "react-helmet";
import { PageHeader } from "@app/components/v2";
import { useOrganization } from "@app/context";
import { LogsSection } from "./components";
export const AuditLogsPage = () => {
const { isSubOrganization } = useOrganization();
return (
<div className="h-full bg-bunker-800">
<Helmet>
@@ -15,7 +18,7 @@ export const AuditLogsPage = () => {
<div className="flex w-full justify-center bg-bunker-800 pb-6 text-white">
<div className="w-full max-w-8xl">
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title="Audit Logs"
description="Audit logs for security and compliance teams to monitor information access."
/>
@@ -20,7 +20,7 @@ import {
Tooltip
} from "@app/components/v2";
import { ROUTE_PATHS } from "@app/const/routes";
import { OrgPermissionGroupActions, OrgPermissionSubjects } from "@app/context";
import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { useDeleteGroup } from "@app/hooks/api";
import { useGetGroupById } from "@app/hooks/api/groups/queries";
import { usePopUp } from "@app/hooks/usePopUp";
@@ -45,6 +45,8 @@ const Page = () => {
const { data, isPending } = useGetGroupById(groupId);
const { isSubOrganization } = useOrganization();
const { mutateAsync: deleteMutateAsync } = useDeleteGroup();
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
@@ -95,7 +97,11 @@ const Page = () => {
<FontAwesomeIcon icon={faChevronLeft} />
Groups
</Link>
<PageHeader scope="org" description="Organization Group" title={data.group.name}>
<PageHeader
scope={isSubOrganization ? "namespace" : "org"}
description={`${isSubOrganization ? "Sub-" : ""}Organization Group`}
title={data.group.name}
>
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
@@ -29,7 +29,7 @@ const Page = () => {
from: ROUTE_PATHS.Organization.IdentityDetailsByIDPage.id
});
const identityId = params.identityId as string;
const { currentOrg } = useOrganization();
const { currentOrg, isSubOrganization } = useOrganization();
const orgId = currentOrg?.id || "";
const { data } = useGetIdentityById(identityId);
const { mutateAsync: deleteIdentity } = useDeleteIdentity();
@@ -88,7 +88,11 @@ const Page = () => {
<FontAwesomeIcon icon={faChevronLeft} />
Identities
</Link>
<PageHeader scope="org" description="Organization Identity" title={data.identity.name} />
<PageHeader
scope={isSubOrganization ? "namespace" : "org"}
description={`${isSubOrganization ? "Sub-" : ""}Organization Identity`}
title={data.identity.name}
/>
<div className="flex">
<div className="mr-4 w-96">
<IdentityDetailsSection
@@ -1,10 +1,13 @@
import { Helmet } from "react-helmet";
import { PageHeader } from "@app/components/v2";
import { useOrganization } from "@app/context";
import { NetworkingTabGroup } from "./components/NetworkingTabGroup/NetworkingTabGroup";
export const NetworkingPage = () => {
const { isSubOrganization } = useOrganization();
return (
<>
<Helmet>
@@ -14,7 +17,7 @@ export const NetworkingPage = () => {
<div className="flex w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-8xl">
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title="Networking"
description="Manage gateways and relays to securely access private network resources from Infisical"
/>
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useSearch } from "@tanstack/react-router";
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { useOrganization } from "@app/context";
import { GatewayTab } from "../GatewayTab/GatewayTab";
import { RelayTab } from "../RelayTab/RelayTab";
@@ -18,11 +19,13 @@ export const NetworkingTabGroup = () => {
const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key);
const { isSubOrganization } = useOrganization();
return (
<Tabs orientation="vertical" value={selectedTab} onValueChange={setSelectedTab}>
<TabList>
{tabs.map((tab) => (
<Tab variant="org" value={tab.key} key={tab.key}>
<Tab variant={isSubOrganization ? "namespace" : "org"} value={tab.key} key={tab.key}>
{tab.name}
</Tab>
))}
@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
import { NewProjectModal } from "@app/components/projects";
import { PageHeader } from "@app/components/v2";
import { useSubscription } from "@app/context";
import { useOrganization, useSubscription } from "@app/context";
import { usePopUp } from "@app/hooks/usePopUp";
import { AllProjectView } from "./components/AllProjectView";
@@ -52,7 +52,7 @@ export const ProjectsPage = () => {
] as const);
const { subscription } = useSubscription();
const { isSubOrganization } = useOrganization();
const isAddingProjectsAllowed = subscription?.workspaceLimit
? subscription.workspacesUsed < subscription.workspaceLimit
: true;
@@ -64,7 +64,7 @@ export const ProjectsPage = () => {
<link rel="icon" href="/infisical.ico" />
</Helmet>
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title="Overview"
description="Your team's complete security toolkit - organized and ready when you need them."
/>
@@ -30,7 +30,7 @@ export const Page = () => {
from: ROUTE_PATHS.Organization.RoleByIDPage.id
});
const roleId = params.roleId as string;
const { currentOrg } = useOrganization();
const { currentOrg, isSubOrganization } = useOrganization();
const orgId = currentOrg?.id || "";
const { data } = useGetOrgRole(orgId, roleId);
const { mutateAsync: deleteOrgRole } = useDeleteOrgRole();
@@ -91,7 +91,7 @@ export const Page = () => {
Roles
</Link>
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title={data.name}
description={
<>
@@ -4,12 +4,13 @@ import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PageHeader } from "@app/components/v2";
import { useOrganization } from "@app/context";
import { ShareSecretSection } from "./ShareSecretSection";
export const SecretSharingPage = () => {
const { t } = useTranslation();
const { isSubOrganization } = useOrganization();
return (
<>
<Helmet>
@@ -22,7 +23,7 @@ export const SecretSharingPage = () => {
<div className="h-full">
<div className="mx-auto h-full w-full max-w-8xl bg-bunker-800 text-white">
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title="Secret Sharing"
description="Share secrets securely using a shareable link"
>
@@ -3,6 +3,7 @@ import { useNavigate, useSearch } from "@tanstack/react-router";
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ROUTE_PATHS } from "@app/const/routes";
import { useOrganization } from "@app/context";
import { RequestSecretTab } from "./components/RequestSecret/RequestSecretTab";
import { ShareSecretTab } from "./components/ShareSecret/ShareSecretTab";
@@ -14,6 +15,7 @@ enum SecretSharingPageTabs {
export const ShareSecretSection = () => {
const navigate = useNavigate();
const { isSubOrganization } = useOrganization();
const { selectedTab } = useSearch({
from: ROUTE_PATHS.Organization.SecretSharing.id
@@ -26,6 +28,8 @@ export const ShareSecretSection = () => {
});
};
const tabVariant = isSubOrganization ? "namespace" : "org";
return (
<div>
<Helmet>
@@ -36,10 +40,10 @@ export const ShareSecretSection = () => {
<Tabs orientation="vertical" value={selectedTab} onValueChange={updateSelectedTab}>
<TabList>
<Tab variant="org" value={SecretSharingPageTabs.ShareSecret}>
<Tab variant={tabVariant} value={SecretSharingPageTabs.ShareSecret}>
Share Secrets
</Tab>
<Tab variant="org" value={SecretSharingPageTabs.RequestSecret}>
<Tab variant={tabVariant} value={SecretSharingPageTabs.RequestSecret}>
Request Secrets
</Tab>
</TabList>
@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader } from "@app/components/v2";
import { useOrganization } from "@app/context";
import {
OrgPermissionSecretShareAction,
OrgPermissionSubjects
@@ -13,6 +14,7 @@ import { SecretSharingSettingsTabGroup } from "./components";
export const SecretSharingSettingsPage = withPermission(
() => {
const { t } = useTranslation();
const { isSubOrganization } = useOrganization();
return (
<>
@@ -21,7 +23,10 @@ export const SecretSharingSettingsPage = withPermission(
</Helmet>
<div className="flex w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-8xl">
<PageHeader scope="org" title="Secret Share Settings" />
<PageHeader
scope={isSubOrganization ? "namespace" : "org"}
title="Secret Share Settings"
/>
<SecretSharingSettingsTabGroup />
</div>
</div>
@@ -2,11 +2,13 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader } from "@app/components/v2";
import { useOrganization } from "@app/context";
import { OrgTabGroup } from "./components";
export const SettingsPage = () => {
const { t } = useTranslation();
const { isSubOrganization } = useOrganization();
return (
<>
@@ -16,7 +18,7 @@ export const SettingsPage = () => {
<div className="flex w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-8xl">
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
description="Configure organization-wide settings"
title={t("settings.org.title")}
/>
@@ -74,7 +74,7 @@ export const OrgTabGroup = () => {
{tabs
.filter((el) => !el.isHidden)
.map((tab) => (
<Tab variant="org" value={tab.key} key={tab.key}>
<Tab variant={isSubOrganization ? "namespace" : "org"} value={tab.key} key={tab.key}>
{tab.name}
</Tab>
))}
@@ -46,7 +46,7 @@ const Page = withPermission(
});
const membershipId = search.membershipId as string;
const { user } = useUser();
const { currentOrg } = useOrganization();
const { currentOrg, isSubOrganization } = useOrganization();
const userId = user?.id || "";
const orgId = currentOrg?.id || "";
@@ -131,7 +131,7 @@ const Page = withPermission(
Users
</Link>
<PageHeader
scope="org"
scope={isSubOrganization ? "namespace" : "org"}
title={
membership.user.firstName || membership.user.lastName
? `${membership.user.firstName} ${membership.user.lastName ?? ""}`.trim()
@@ -140,7 +140,7 @@ const Page = withPermission(
membership.inviteEmail ??
"Unknown User")
}
description="Organization User Membership"
description={`${isSubOrganization ? "Sub-" : ""}Organization User Membership`}
>
<div>
{userId !== membership.user.id && (