improvement: address feedback

This commit is contained in:
Scott Wilson
2025-10-16 10:48:31 -07:00
parent 713d10bb96
commit f4b8177496
55 changed files with 138 additions and 116 deletions

View File

@@ -5,29 +5,48 @@ import { ReactNode } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
import { Badge } from "@app/components/v2";
import { BadgeProps } from "@app/components/v2/Badge/Badge";
import { ProjectType } from "@app/hooks/api/projects/types";
type Props = {
title: ReactNode;
description?: ReactNode;
children?: ReactNode;
className?: string;
scope: "org" | "project" | "namespace" | "instance";
scope: "org" | "namespace" | "instance" | ProjectType;
};
const SCOPE_NAME: Record<NonNullable<Props["scope"]>, { label: string; icon: IconDefinition }> = {
org: { label: "Organization", icon: faGlobe },
project: { label: "Project", icon: faCube },
[ProjectType.SecretManager]: { label: "Secrets Management", icon: faCube },
[ProjectType.CertificateManager]: { label: "PKI", icon: faCube },
[ProjectType.SSH]: { label: "SSH", icon: faCube },
[ProjectType.KMS]: { label: "KMS", icon: faCube },
[ProjectType.PAM]: { label: "PAM", icon: faCube },
[ProjectType.SecretScanning]: { label: "Secret Scanning", icon: faCube },
namespace: { label: "Namespace", icon: faCubes },
instance: { label: "Server", icon: faServer }
};
const SCOPE_VARIANT: Record<NonNullable<Props["scope"]>, BadgeProps["variant"]> = {
org: "org",
[ProjectType.SecretManager]: "project",
[ProjectType.CertificateManager]: "project",
[ProjectType.SSH]: "project",
[ProjectType.KMS]: "project",
[ProjectType.PAM]: "project",
[ProjectType.SecretScanning]: "project",
namespace: "namespace",
instance: "instance"
};
export const PageHeader = ({ title, description, children, className, scope }: Props) => (
<div className={twMerge("mb-10 w-full border-b border-mineshaft-500 pb-10", className)}>
<div className={twMerge("mb-10 w-full", className)}>
<div className="flex w-full justify-between">
<div className="mr-4 flex w-full items-center">
<h1 className="text-3xl font-medium text-white capitalize">{title}</h1>
{scope && (
<Badge variant={scope} className="mt-1 ml-2.5">
<Badge variant={SCOPE_VARIANT[scope]} className="mt-1 ml-2.5">
<FontAwesomeIcon icon={SCOPE_NAME[scope].icon} />
{SCOPE_NAME[scope].label}
</Badge>

View File

@@ -4,7 +4,6 @@ import {
faBuilding,
faCog,
faDatabase,
faGlobe,
faKey,
faLock,
faPlug,
@@ -14,7 +13,7 @@ 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";
import { Tab, TabList, Tabs, Tooltip } from "@app/components/v2";
const generalTabs = [
{
@@ -74,12 +73,13 @@ export const AdminNavBar = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Tooltip position="bottom" content="Back to organization">
<Link to="/organization/projects">
<Tab value="back">
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
</Tooltip>
{generalTabs.map((tab) => {
const isActive = matchRoute({ to: tab.link, fuzzy: false });
return (

View File

@@ -1,5 +1,3 @@
import { faArrowLeft, faGlobe } 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";
@@ -28,12 +26,6 @@ export const KmsLayout = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Link
to="/projects/kms/$projectId/overview"
params={{

View File

@@ -241,7 +241,7 @@ export const Navbar = () => {
<Badge
variant="org"
className={twMerge(
"max-w-full min-w-0 text-sm",
"max-w-full min-w-0 cursor-pointer text-sm",
!isOrgScope && "bg-transparent opacity-75"
)}
>

View File

@@ -19,10 +19,10 @@ export const OrgNavBar = ({ isHidden }: Props) => {
{!isHidden && (
<div className="dark hidden w-full flex-col overflow-x-hidden border-b border-mineshaft-600 bg-mineshaft-900 px-4 md:flex">
<motion.div
key="menu-project-items"
initial={{ x: 150 }}
key="menu-org-items"
initial={{ x: -150 }}
animate={{ x: 0 }}
exit={{ x: 150 }}
exit={{ x: -150 }}
transition={{ duration: 0.2 }}
className=""
>

View File

@@ -1,6 +1,4 @@
import { useEffect } from "react";
import { faArrowLeft, faGlobe } 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";
@@ -39,12 +37,6 @@ export const PamLayout = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Link
to="/projects/pam/$projectId/accounts"
params={{

View File

@@ -1,5 +1,5 @@
import { useTranslation } from "react-i18next";
import { faArrowLeft, faGlobe, faMobile } from "@fortawesome/free-solid-svg-icons";
import { 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";
@@ -30,12 +30,6 @@ export const PkiManagerLayout = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Link
to="/projects/cert-management/$projectId/subscribers"
params={{

View File

@@ -108,12 +108,10 @@ export const ProjectSelect = () => {
}}
className="overflow-hidden"
>
<Tooltip content={currentWorkspace.name} className="max-w-96 break-words">
<Badge variant="project" className="max-w-full min-w-0 text-sm">
<FontAwesomeIcon icon={faCube} />
<p className="truncate">{currentWorkspace?.name}</p>
</Badge>
</Tooltip>
<Badge variant="project" className="max-w-full min-w-0 cursor-pointer text-sm">
<FontAwesomeIcon icon={faCube} />
<p className="truncate">{currentWorkspace?.name}</p>
</Badge>
</Link>
<DropdownMenuTrigger asChild>
<div>

View File

@@ -1,5 +1,5 @@
import { useTranslation } from "react-i18next";
import { faArrowLeft, faGlobe, faMobile } from "@fortawesome/free-solid-svg-icons";
import { 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";
@@ -55,12 +55,6 @@ export const SecretManagerLayout = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Link
to="/projects/secret-management/$projectId/overview"
params={{

View File

@@ -1,5 +1,3 @@
import { faArrowLeft, faGlobe } 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";
@@ -50,12 +48,6 @@ export const SecretScanningLayout = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Link
to="/projects/secret-scanning/$projectId/data-sources"
params={{

View File

@@ -1,5 +1,3 @@
import { faArrowLeft, faGlobe } 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";
@@ -33,12 +31,6 @@ export const SshLayout = () => {
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
<Link
to="/projects/ssh/$projectId/overview"
params={{

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PkiAlertsSection } from "./components";
@@ -16,7 +17,7 @@ export const AlertingPage = () => {
</Helmet>
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.CertificateManager}
title="Alerting"
description="Configure alerts for expiring certificates and CAs to maintain security and compliance."
/>

View File

@@ -20,6 +20,7 @@ import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
import { CaType, useDeleteCa, useGetCa } from "@app/hooks/api";
import { TInternalCertificateAuthority } from "@app/hooks/api/ca/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { CaInstallCertModal } from "../CertificateAuthoritiesPage/components/CaInstallCertModal";
@@ -99,7 +100,11 @@ const Page = () => {
<FontAwesomeIcon icon={faChevronLeft} />
Certificate Authorities
</Link>
<PageHeader scope="project" description="Manage certificate authority" title={data.name}>
<PageHeader
scope={ProjectType.CertificateManager}
description="Manage certificate authority"
title={data.name}
>
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { ProjectType } from "@app/hooks/api/projects/types";
import { ExternalCaSection } from "./components/ExternalCaSection";
import { CaSection } from "./components";
@@ -17,7 +18,7 @@ export const CertificateAuthoritiesPage = () => {
</Helmet>
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.CertificateManager}
title="Certificate Authorities"
description="Manage certificate authorities for issuing and signing certificates"
/>

View File

@@ -9,6 +9,7 @@ import {
ProjectPermissionSub,
useProjectPermission
} from "@app/context";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PkiCollectionSection } from "../AlertingPage/components";
import { CertificatesSection } from "./components";
@@ -33,7 +34,7 @@ export const CertificatesPage = () => {
</Helmet>
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.CertificateManager}
title="Certificates"
description="View and track issued certificates, monitor expiration dates, and manage certificate lifecycles."
/>

View File

@@ -7,6 +7,7 @@ import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionSub, useProject } from "@app/context";
import { ProjectPermissionPkiSyncActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { IntegrationsListPageTabs } from "@app/types/integrations";
import { PkiSyncsTab } from "./components";
@@ -45,7 +46,7 @@ export const IntegrationsListPage = () => {
<div className="relative mx-auto max-w-8xl pb-12 text-white">
<div className="mb-8">
<PageHeader
scope="project"
scope={ProjectType.CertificateManager}
title="Integrations"
description="Manage integrations with third-party certificate services."
/>

View File

@@ -21,6 +21,7 @@ import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
import { useDeletePkiCollection, useGetPkiCollectionById } from "@app/hooks/api";
import { PkiItemType } from "@app/hooks/api/pkiCollections/constants";
import { ProjectType } from "@app/hooks/api/projects/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { PkiCollectionModal } from "../AlertingPage/components/PkiCollectionModal";
@@ -85,7 +86,11 @@ export const PkiCollectionPage = () => {
<FontAwesomeIcon icon={faChevronLeft} />
Certificates
</Link>
<PageHeader scope="project" title={data.name} description="Manage certificate collection">
<PageHeader
scope={ProjectType.CertificateManager}
title={data.name}
description="Manage certificate collection"
>
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">

View File

@@ -24,6 +24,7 @@ import {
useProject
} from "@app/context";
import { useDeletePkiSubscriber, useGetPkiSubscriber } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/projects/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { PkiSubscriberModal } from "../PkiSubscribersPage/components/PkiSubscriberModal";
@@ -90,7 +91,11 @@ const Page = () => {
<FontAwesomeIcon icon={faChevronLeft} />
Subscribers
</Link>
<PageHeader scope="project" title={data.name} description="Manage PKI subscriber">
<PageHeader
scope={ProjectType.CertificateManager}
title={data.name}
description="Manage PKI subscriber"
>
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PkiSubscriberSection } from "./components";
@@ -16,7 +17,7 @@ export const PkiSubscribersPage = () => {
<div className="mx-auto flex flex-col justify-between text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.CertificateManager}
title="Subscribers"
description="Manage subscribers that request and receive certificates, including user devices, servers, and services."
/>

View File

@@ -48,6 +48,7 @@ import {
import { usePopUp } from "@app/hooks";
import { useDeleteCertTemplateV2 } from "@app/hooks/api";
import { useListCertificateTemplates } from "@app/hooks/api/certificateTemplates/queries";
import { ProjectType } from "@app/hooks/api/projects/types";
import { CertificateTemplateEnrollmentModal } from "../CertificatesPage/components/CertificateTemplateEnrollmentModal";
import { PkiTemplateForm } from "./components/PkiTemplateForm";
@@ -106,7 +107,7 @@ export const PkiTemplateListPage = () => {
<div className="mx-auto flex flex-col justify-between text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.CertificateManager}
title="Certificate Templates"
description="Manage certificate template to request and issue dynamic certificates following a strict format."
/>

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
const tabs = [
@@ -21,7 +22,7 @@ export const SettingsPage = () => {
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
</Helmet>
<div className="w-full max-w-8xl">
<PageHeader scope="project" title={t("settings.project.title")} />
<PageHeader scope={ProjectType.CertificateManager} title={t("settings.project.title")} />
<Tabs orientation="vertical" defaultValue={tabs[0].key}>
<TabList>
{tabs.map((tab) => (

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionKmipActions, ProjectPermissionSub } from "@app/context";
import { ProjectType } from "@app/hooks/api/projects/types";
import { KmipClientTable } from "./components/KmipClientTable";
@@ -18,7 +19,7 @@ export const KmipPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.KMS}
title="KMIP"
description="Integrate with Infisical KMS via Key Management Interoperability Protocol."
/>

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { ProjectType } from "@app/hooks/api/projects/types";
import { CmekTable } from "./components";
@@ -18,7 +19,7 @@ export const OverviewPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.KMS}
title="Overview"
description="Manage keys and perform cryptographic operations."
/>

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
const tabs = [
@@ -22,7 +23,7 @@ export const SettingsPage = () => {
</Helmet>
<div className="w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.KMS}
title="Settings"
description="Configure general project settings"
/>

View File

@@ -5,6 +5,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionPamAccountActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PamAccountsSection } from "./components/PamAccountsSection";
@@ -24,7 +25,7 @@ export const PamAccountsPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.PAM}
title="Accounts"
description="View, access, and manage accounts."
/>

View File

@@ -5,6 +5,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionPamAccountActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PamResourcesSection } from "./components/PamResourcesSection";
@@ -24,7 +25,7 @@ export const PamResourcesPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.PAM}
title="Resources"
description="Manage resources such as servers, databases, and more."
/>

View File

@@ -9,6 +9,7 @@ import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionSub, useProject } from "@app/context";
import { ProjectPermissionPamSessionActions } from "@app/context/ProjectPermissionContext/types";
import { useGetPamSessionById } from "@app/hooks/api/pam";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PamSessionDetailsSection } from "./components/PamSessionDetailsSection";
import { PamSessionLogsSection } from "./components/PamSessionLogsSection";
@@ -35,7 +36,7 @@ const Page = () => {
Sessions
</Link>
<PageHeader
scope="project"
scope={ProjectType.PAM}
title={`${session.accountName} Session`}
description={`View details for this ${session.accountName} session.`}
/>

View File

@@ -5,6 +5,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionPamSessionActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { PamSessionSection } from "./components/PamSessionSection";
@@ -24,7 +25,7 @@ export const PamSessionPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.PAM}
title="Sessions"
description="Filter and search through account sessions."
/>

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
export const SettingsPage = () => {
@@ -13,7 +14,11 @@ export const SettingsPage = () => {
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
</Helmet>
<div className="w-full max-w-8xl">
<PageHeader scope="project" title="Settings" description="Configure your PAM project." />
<PageHeader
scope={ProjectType.PAM}
title="Settings"
description="Configure your PAM project."
/>
<Tabs orientation="vertical" defaultValue="tab-project-general">
<TabList>
<Tab variant="project" value="tab-project-general">

View File

@@ -40,7 +40,7 @@ const Page = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={currentProject.type}
title="Access Control"
description="Manage fine-grained access for users, groups, roles, and identities within your project resources."
/>

View File

@@ -23,7 +23,7 @@ export const AppConnectionsPage = withProjectPermission(
<div className="flex w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-8xl">
<PageHeader
scope="project"
scope={currentProject.type}
className="w-full"
title="App Connections"
description="Manage project App Connections"

View File

@@ -16,7 +16,7 @@ export const AuditLogsPage = () => {
<div className="flex h-full w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-8xl">
<PageHeader
scope="project"
scope={currentProject.type}
title="Audit logs"
description="Audit logs for security and compliance teams to monitor information access."
/>

View File

@@ -53,7 +53,7 @@ const Page = () => {
Groups
</Link>
<PageHeader
scope="project"
scope={currentProject.type}
title={groupMembership.group.name}
description={`Group joined on ${groupMembership?.createdAt && formatRelative(new Date(groupMembership?.createdAt || ""), new Date())}`}
/>

View File

@@ -133,7 +133,7 @@ const Page = () => {
Identities
</Link>
<PageHeader
scope="project"
scope={currentProject.type}
title={identityMembershipDetails?.identity?.name}
description={`Identity joined on ${identityMembershipDetails?.createdAt && formatRelative(new Date(identityMembershipDetails?.createdAt || ""), new Date())}`}
>

View File

@@ -135,7 +135,7 @@ export const Page = () => {
Users
</Link>
<PageHeader
scope="project"
scope={currentProject.type}
title={
membershipDetails.user.firstName || membershipDetails.user.lastName
? `${membershipDetails.user.firstName} ${membershipDetails.user.lastName}`

View File

@@ -109,7 +109,7 @@ const Page = () => {
Roles
</Link>
<PageHeader
scope="project"
scope={currentProject.type}
title={data.name}
description={
<>

View File

@@ -29,6 +29,7 @@ import {
import { usePopUp } from "@app/hooks";
import { CommitWithChanges } from "@app/hooks/api/folderCommits";
import { useCommitRevert, useGetCommitDetails } from "@app/hooks/api/folderCommits/queries";
import { ProjectType } from "@app/hooks/api/projects/types";
import { CommitType } from "@app/hooks/api/types";
import { SecretVersionDiffView } from "../SecretVersionDiffView";
@@ -260,7 +261,7 @@ export const CommitDetailsTab = ({
Commit History
</Button>
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title={`${parsedCommitDetails.changes?.message}` || "No message"}
description={
<>

View File

@@ -24,6 +24,7 @@ import {
} from "@app/context/ProjectPermissionContext/types";
import { usePopUp } from "@app/hooks";
import { useCommitRollback, useGetRollbackPreview } from "@app/hooks/api/folderCommits/queries";
import { ProjectType } from "@app/hooks/api/projects/types";
import { SecretVersionDiffView } from "../SecretVersionDiffView";
@@ -307,7 +308,7 @@ export const RollbackPreviewTab = (): JSX.Element => {
<div className="h-full w-full">
<div>
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title={`Restore folder at commit ${selectedCommitId.substring(0, 8)}`}
description={`Will return all changes in this folder to how they appeared at the point of commit ${selectedCommitId.substring(0, 8)}. Any modifications made after this commit will be undone.`}
/>

View File

@@ -11,6 +11,7 @@ import {
ProjectPermissionCommitsActions,
ProjectPermissionSub
} from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { CommitHistoryTab } from "./components/CommitHistoryTab";
@@ -62,7 +63,7 @@ export const CommitsPage = () => {
Secrets
</Link>
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title="Commits"
description="Track, inspect, and restore your secrets and folders with confidence. View the complete history of changes made to your environment, examine specific modifications at each commit point, and preview the exact impact before rolling back to previous states."
/>

View File

@@ -94,7 +94,7 @@ export const IntegrationDetailsByIDPage = () => {
{integration ? (
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title={`${integrationSlugNameMapping[integration.integration]} Integration`}
>
<DropdownMenu>

View File

@@ -7,6 +7,7 @@ import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { IntegrationsListPageTabs } from "@app/types/integrations";
import {
@@ -48,7 +49,7 @@ export const IntegrationsListPage = () => {
<div className="relative mx-auto max-w-8xl pb-12 text-white">
<div className="mb-8">
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title="Integrations"
description="Manage integrations with third-party services."
/>

View File

@@ -92,7 +92,7 @@ import {
import { useGetProjectSecretsOverview } from "@app/hooks/api/dashboard/queries";
import { DashboardSecretsOrderBy, ProjectSecretsImportedBy } from "@app/hooks/api/dashboard/types";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { ProjectVersion } from "@app/hooks/api/projects/types";
import { ProjectType, ProjectVersion } from "@app/hooks/api/projects/types";
import { useUpdateFolderBatch } from "@app/hooks/api/secretFolders/queries";
import { TUpdateFolderBatchDTO } from "@app/hooks/api/secretFolders/types";
import { TSecretRotationV2 } from "@app/hooks/api/secretRotationsV2";
@@ -914,8 +914,8 @@ export const OverviewPage = () => {
<div className="relative mx-auto max-w-8xl text-mineshaft-50 dark:scheme-dark">
<div className="flex w-full items-baseline justify-between">
<PageHeader
scope="project"
title="Secrets Overview"
scope={ProjectType.SecretManager}
title="Overview"
description={
<p className="text-md text-bunker-300">
Inject your secrets using

View File

@@ -5,6 +5,7 @@ import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { Badge } from "@app/components/v2/Badge";
import { useProject } from "@app/context";
import { useGetAccessRequestsCount, useGetSecretApprovalRequestCount } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/projects/types";
import { AccessApprovalRequest } from "./components/AccessApprovalRequest";
import { ApprovalPolicyList } from "./components/ApprovalPolicyList";
@@ -40,7 +41,7 @@ export const SecretApprovalsPage = () => {
</Helmet>
<div className="mx-auto h-full w-full max-w-8xl bg-bunker-800 text-white">
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title="Approval Workflows"
description="Create approval policies for any modifications to secrets in sensitive environments and folders."
/>

View File

@@ -56,7 +56,7 @@ import { dashboardKeys } from "@app/hooks/api/dashboard/queries";
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
import { useGetFolderCommitsCount } from "@app/hooks/api/folderCommits";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { ProjectVersion } from "@app/hooks/api/projects/types";
import { ProjectType, ProjectVersion } from "@app/hooks/api/projects/types";
import { queryClient } from "@app/hooks/api/reactQuery";
import { PendingAction } from "@app/hooks/api/secretFolders/types";
import { useCreateCommit } from "@app/hooks/api/secrets/mutations";
@@ -777,7 +777,7 @@ const Page = () => {
Secrets Overview
</Link>
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title="Secrets Management"
description={
<p className="text-md text-bunker-300">

View File

@@ -52,6 +52,7 @@ import {
useGetSecretRotations,
useRestartSecretRotation
} from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/projects/types";
import { TSecretRotationProviderTemplate } from "@app/hooks/api/secretRotation/types";
import { CreateRotationForm } from "@app/pages/secret-manager/SecretRotationPage/components/CreateRotationForm";
@@ -147,7 +148,7 @@ const Page = () => {
return (
<div className="container mx-auto w-full max-w-8xl bg-bunker-800 text-white">
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title="Secret Rotation"
description="Stop manually rotating secrets and automate credential rotation."
>

View File

@@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { useProject } from "@app/context";
import { ProjectVersion } from "@app/hooks/api/projects/types";
import { ProjectType, ProjectVersion } from "@app/hooks/api/projects/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
import { EncryptionTab } from "./components/EncryptionTab";
@@ -42,7 +42,7 @@ export const SettingsPage = () => {
</Helmet>
<div className="w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SecretManager}
title="Settings"
description="Configure your secret manager's encryption, environments, webhooks and other configurations."
/>

View File

@@ -7,6 +7,7 @@ import {
ProjectPermissionSecretScanningDataSourceActions,
ProjectPermissionSub
} from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { SecretScanningDataSourcesSection } from "./components";
@@ -26,7 +27,7 @@ export const SecretScanningDataSourcesPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SecretScanning}
title="Data Sources"
description="Manage your Secret Scanning data sources."
/>

View File

@@ -5,6 +5,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader } from "@app/components/v2";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionSecretScanningFindingActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { SecretScanningFindingsSection } from "./components";
@@ -24,7 +25,7 @@ export const SecretScanningFindingsPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SecretScanning}
title="Findings"
description="View Secret Leaks across your project."
/>

View File

@@ -5,6 +5,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionSecretScanningConfigActions } from "@app/context/ProjectPermissionContext/types";
import { ProjectType } from "@app/hooks/api/projects/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
import { ProjectScanningConfigTab } from "./components/ProjectScanningConfigTab";
@@ -19,7 +20,7 @@ export const SettingsPage = () => {
</Helmet>
<div className="w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SecretScanning}
title="Settings"
description="Configure your Secret Scanning product's configurations."
/>

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { ProjectType } from "@app/hooks/api/projects/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
import { ProjectSshTab } from "./components/ProjectSshTab";
@@ -18,7 +19,7 @@ export const SettingsPage = () => {
</Helmet>
<div className="w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SSH}
title="Settings"
description="Configure your SSH product's configurations."
/>

View File

@@ -19,6 +19,7 @@ import {
import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
import { useDeleteSshCa, useGetSshCaById } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/projects/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { SshCaModal } from "../SshCasPage/components/SshCaModal";
@@ -83,7 +84,7 @@ const Page = () => {
Certificate Authorities
</Link>
<PageHeader
scope="project"
scope={ProjectType.SSH}
description="Configure Certificate Authority"
title={data.friendlyName}
>

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { SshCaSection } from "./components";
@@ -16,7 +17,7 @@ export const SshCasPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SSH}
title="SSH Certificate Authorities"
description="Manage the SSH certificate authorities used to sign user and host certificates, including custom and default CAs."
/>

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { SshCertificatesSection } from "./components";
@@ -16,7 +17,7 @@ export const SshCertsPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SSH}
title="SSH Certificates"
description="View and audit all issued SSH certificates, including validity and associated access metadata."
/>

View File

@@ -20,6 +20,7 @@ import {
import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
import { useDeleteSshHostGroup, useGetSshHostGroupById } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/projects/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { SshHostGroupModal } from "../SshHostsPage/components/SshHostGroupModal";
@@ -83,7 +84,7 @@ const Page = () => {
<FontAwesomeIcon icon={faChevronLeft} />
Hosts
</Link>
<PageHeader scope="project" title={data.name} description="Configure SSH Group">
<PageHeader scope={ProjectType.SSH} title={data.name} description="Configure SSH Group">
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">

View File

@@ -2,6 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/projects/types";
import { SshHostGroupsSection, SshHostsSection } from "./components";
@@ -16,7 +17,7 @@ export const SshHostsPage = () => {
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-8xl">
<PageHeader
scope="project"
scope={ProjectType.SSH}
title="Hosts"
description="Manage your SSH hosts, configure access policies, and define login behavior for secure connections."
/>