mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-21 14:28:09 +00:00
Merge branch 'main' into fix/remove-duplicate-error-notifications
This commit is contained in:
@@ -2,17 +2,20 @@ import { useState } from "react";
|
||||
import { Helmet } from "react-helmet";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { ContentLoader, PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { ProjectType } from "@app/hooks/api/projects/types";
|
||||
|
||||
import { CertificateProfilesTab } from "./components/CertificateProfilesTab";
|
||||
import { CertificatesTab } from "./components/CertificatesTab";
|
||||
import { CertificateTemplatesV2Tab } from "./components/CertificateTemplatesV2Tab";
|
||||
import { PkiCollectionsTab } from "./components/PkiCollectionsTab";
|
||||
|
||||
enum TabSections {
|
||||
CertificateProfiles = "profiles",
|
||||
CertificateTemplatesV2 = "templates-v2"
|
||||
CertificateTemplatesV2 = "templates-v2",
|
||||
Certificates = "certificates",
|
||||
PkiCollections = "pki-collections"
|
||||
}
|
||||
|
||||
export const PoliciesPage = () => {
|
||||
@@ -25,59 +28,54 @@ export const PoliciesPage = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Read}
|
||||
a={ProjectPermissionSub.CertificateAuthorities}
|
||||
>
|
||||
{(isAllowed) => {
|
||||
if (!isAllowed) {
|
||||
return (
|
||||
<div className="mx-auto flex h-full flex-col justify-center bg-bunker-800 text-white">
|
||||
<div className="mx-auto mb-6 w-full max-w-8xl text-center">
|
||||
<p>You don't have permission to access certificate policies.</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
<div className="mx-auto flex h-full flex-col justify-between bg-bunker-800 text-white">
|
||||
<Helmet>
|
||||
<title>{t("common.head-title", { title: "Certificate Management" })}</title>
|
||||
</Helmet>
|
||||
<div className="mx-auto mb-6 w-full max-w-8xl">
|
||||
<PageHeader
|
||||
scope={ProjectType.CertificateManager}
|
||||
title="Certificate Management"
|
||||
description="Streamline certificate management by creating and maintaining templates, profiles, and certificates in one place"
|
||||
/>
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
||||
<Helmet>
|
||||
<title>{t("common.head-title", { title: "Certificate Policies" })}</title>
|
||||
</Helmet>
|
||||
<div className="mx-auto mb-6 w-full max-w-8xl">
|
||||
<PageHeader
|
||||
scope={ProjectType.CertificateManager}
|
||||
title="Certificate Policies"
|
||||
description="Manage certificate templates and profiles for unified certificate issuance"
|
||||
/>
|
||||
<Tabs
|
||||
orientation="vertical"
|
||||
value={activeTab}
|
||||
onValueChange={(value) => setActiveTab(value as TabSections)}
|
||||
>
|
||||
<TabList>
|
||||
<Tab variant="project" value={TabSections.CertificateProfiles}>
|
||||
Certificate Profiles
|
||||
</Tab>
|
||||
<Tab variant="project" value={TabSections.CertificateTemplatesV2}>
|
||||
Certificate Templates
|
||||
</Tab>
|
||||
<Tab variant="project" value={TabSections.Certificates}>
|
||||
Certificates
|
||||
</Tab>
|
||||
<Tab variant="project" value={TabSections.PkiCollections}>
|
||||
Certificate Collections
|
||||
</Tab>
|
||||
</TabList>
|
||||
|
||||
<Tabs
|
||||
orientation="vertical"
|
||||
value={activeTab}
|
||||
onValueChange={(value) => setActiveTab(value as TabSections)}
|
||||
>
|
||||
<TabList>
|
||||
<Tab variant="project" value={TabSections.CertificateProfiles}>
|
||||
Certificate Profiles
|
||||
</Tab>
|
||||
<Tab variant="project" value={TabSections.CertificateTemplatesV2}>
|
||||
Certificate Templates
|
||||
</Tab>
|
||||
</TabList>
|
||||
<TabPanel value={TabSections.CertificateProfiles}>
|
||||
<CertificateProfilesTab />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel value={TabSections.CertificateProfiles}>
|
||||
<CertificateProfilesTab />
|
||||
</TabPanel>
|
||||
<TabPanel value={TabSections.CertificateTemplatesV2}>
|
||||
<CertificateTemplatesV2Tab />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel value={TabSections.CertificateTemplatesV2}>
|
||||
<CertificateTemplatesV2Tab />
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</ProjectPermissionCan>
|
||||
<TabPanel value={TabSections.Certificates}>
|
||||
<CertificatesTab />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel value={TabSections.PkiCollections}>
|
||||
<PkiCollectionsTab />
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+1
-1
@@ -410,7 +410,7 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
|
||||
name="enrollmentType"
|
||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Enrollment Type"
|
||||
label="Enrollment Method"
|
||||
isRequired
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
|
||||
+3
-6
@@ -29,8 +29,7 @@ export const ProfileList = ({ onEditProfile, onDeleteProfile }: Props) => {
|
||||
projectId: currentProject?.id || "",
|
||||
limit: 100,
|
||||
offset: 0,
|
||||
includeConfigs: true,
|
||||
includeMetrics: true
|
||||
includeConfigs: true
|
||||
});
|
||||
|
||||
const profiles = data?.certificateProfiles || [];
|
||||
@@ -42,10 +41,9 @@ export const ProfileList = ({ onEditProfile, onDeleteProfile }: Props) => {
|
||||
<THead>
|
||||
<Tr>
|
||||
<Th>Name</Th>
|
||||
<Th>Enrollment Type</Th>
|
||||
<Th>Enrollment Method</Th>
|
||||
<Th>Issuing CA</Th>
|
||||
<Th>Certificate Template</Th>
|
||||
<Th>Certificates</Th>
|
||||
<Th className="w-5" />
|
||||
</Tr>
|
||||
</THead>
|
||||
@@ -67,10 +65,9 @@ export const ProfileList = ({ onEditProfile, onDeleteProfile }: Props) => {
|
||||
<THead>
|
||||
<Tr>
|
||||
<Th>Name</Th>
|
||||
<Th>Enrollment Type</Th>
|
||||
<Th>Enrollment Method</Th>
|
||||
<Th>Issuing CA</Th>
|
||||
<Th>Certificate Template</Th>
|
||||
<Th>Certificates</Th>
|
||||
<Th className="w-5" />
|
||||
</Tr>
|
||||
</THead>
|
||||
|
||||
+2
-44
@@ -33,43 +33,6 @@ import { TCertificateProfile } from "@app/hooks/api/certificateProfiles";
|
||||
import { useGetCertificateTemplateV2ById } from "@app/hooks/api/certificateTemplates/queries";
|
||||
import { CertificateIssuanceModal } from "@app/pages/cert-manager/CertificatesPage/components/CertificateIssuanceModal";
|
||||
|
||||
const MetricsBadges = ({
|
||||
metrics
|
||||
}: {
|
||||
metrics?: {
|
||||
totalCertificates: number;
|
||||
activeCertificates: number;
|
||||
expiringCertificates: number;
|
||||
expiredCertificates: number;
|
||||
revokedCertificates: number;
|
||||
};
|
||||
}) => {
|
||||
if (!metrics) {
|
||||
return <Badge variant="warning">No metrics</Badge>;
|
||||
}
|
||||
|
||||
if (metrics.totalCertificates === 0) {
|
||||
return <Badge variant="warning">No certificates</Badge>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{metrics.activeCertificates > 0 && (
|
||||
<Badge variant="success">{metrics.activeCertificates} active</Badge>
|
||||
)}
|
||||
{metrics.expiringCertificates > 0 && (
|
||||
<Badge variant="warning">{metrics.expiringCertificates} expiring</Badge>
|
||||
)}
|
||||
{metrics.expiredCertificates > 0 && (
|
||||
<Badge variant="danger">{metrics.expiredCertificates} expired</Badge>
|
||||
)}
|
||||
{metrics.revokedCertificates > 0 && (
|
||||
<Badge variant="danger">{metrics.revokedCertificates} revoked</Badge>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
interface Props {
|
||||
profile: TCertificateProfile;
|
||||
onEditProfile: (profile: TCertificateProfile) => void;
|
||||
@@ -118,8 +81,8 @@ export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) =
|
||||
|
||||
const getEnrollmentTypeBadge = (enrollmentType: string) => {
|
||||
const config = {
|
||||
api: { variant: "success" as const, label: "API" },
|
||||
est: { variant: "warning" as const, label: "EST" }
|
||||
api: { variant: "ghost" as const, label: "API" },
|
||||
est: { variant: "ghost" as const, label: "EST" }
|
||||
} as const;
|
||||
|
||||
const configKey = Object.keys(config).includes(enrollmentType)
|
||||
@@ -153,11 +116,6 @@ export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) =
|
||||
{templateData?.name || profile.certificateTemplateId}
|
||||
</span>
|
||||
</Td>
|
||||
<Td>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
<MetricsBadges metrics={profile.metrics} />
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="text-right">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild className="rounded-lg">
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import { CertificatesSection } from "../../../CertificatesPage/components/CertificatesSection";
|
||||
|
||||
export const CertificatesTab = () => {
|
||||
return <CertificatesSection />;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { CertificatesTab } from "./CertificatesTab";
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import { PkiCollectionSection } from "../../../AlertingPage/components/PkiCollectionSection";
|
||||
|
||||
export const PkiCollectionsTab = () => {
|
||||
return <PkiCollectionSection />;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { PkiCollectionsTab } from "./PkiCollectionsTab";
|
||||
@@ -1,2 +1,4 @@
|
||||
export { CertificateProfilesTab } from "./CertificateProfilesTab";
|
||||
export { CertificatesTab } from "./CertificatesTab";
|
||||
export { CertificateTemplatesV2Tab } from "./CertificateTemplatesV2Tab";
|
||||
export { PkiCollectionsTab } from "./PkiCollectionsTab";
|
||||
|
||||
Reference in New Issue
Block a user