Merge pull request #3578 from Infisical/project-template-improvements

improvement(project-templates): Project templates UI improvements
This commit is contained in:
Scott Wilson
2025-05-09 13:50:50 -07:00
committed by GitHub
4 changed files with 60 additions and 22 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -25,6 +25,7 @@ import {
import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context";
import { useGetProjectTypeFromRoute, usePopUp } from "@app/hooks";
import { TProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { DeleteProjectTemplateModal } from "./DeleteProjectTemplateModal";
@@ -40,6 +41,7 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
const { isPending, data: projectTemplates = [] } = useListProjectTemplates(projectType, {
enabled: subscription?.projectTemplates && Boolean(projectType)
});
const [search, setSearch] = useState("");
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteTemplate"] as const);
@@ -52,7 +54,9 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
[search, projectTemplates]
);
const isSecretManagerTemplates = projectType === "secret-manager";
const isSecretManagerTemplates = projectType === ProjectType.SecretManager;
const colSpan = isSecretManagerTemplates ? 4 : 3;
return (
<div>
@@ -73,10 +77,10 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
</Tr>
</THead>
<TBody>
{isPending && (
{subscription?.projectTemplates && isPending && (
<TableSkeleton
innerKey="project-templates-table"
columns={4}
columns={colSpan}
key="project-templates"
/>
)}
@@ -170,9 +174,10 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
</Tr>
);
})}
{!isPending && filteredTemplates?.length === 0 && (
{(!subscription?.projectTemplates ||
(!isPending && filteredTemplates?.length === 0)) && (
<Tr>
<Td colSpan={5}>
<Td colSpan={colSpan}>
<EmptyState
title={
search.trim()

View File

@@ -7,9 +7,10 @@ type Props = {
title: string;
children: ReactNode;
className?: string;
titleClassName?: string;
};
export const NoticeBannerV2 = ({ title, children, className }: Props) => {
export const NoticeBannerV2 = ({ title, children, className, titleClassName }: Props) => {
return (
<div
className={twMerge(
@@ -17,7 +18,7 @@ export const NoticeBannerV2 = ({ title, children, className }: Props) => {
className
)}
>
<div className="mb-1 flex items-center text-sm">
<div className={twMerge("mb-1 flex items-center text-sm", titleClassName)}>
<FontAwesomeIcon icon={faInfoCircle} size="sm" className="mr-1.5 text-primary" />
{title}
</div>

View File

@@ -1,9 +1,11 @@
import { useState } from "react";
import { useSearch } from "@tanstack/react-router";
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import { Link, useSearch } from "@tanstack/react-router";
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
import { ROUTE_PATHS } from "@app/const/routes";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { AuditLogStreamsTab } from "../AuditLogStreamTab";
import { ImportTab } from "../ImportTab";
@@ -36,22 +38,52 @@ export const OrgTabGroup = () => {
component: () => (
<div>
<NoticeBannerV2
className="mx-auto mt-10 max-w-4xl"
title="Project Templates New Location"
className="mx-auto"
titleClassName="text-base"
title="Project Templates Relocated"
>
<p className="text-sm text-bunker-200">
Project templates have been moved to the Feature Settings page, under the &#34;Project
Templates&#34; tab.
<p className="mt-1 text-mineshaft-300">
Project templates have been relocated and are now product specific:
</p>
<p className="mt-2 text-sm text-bunker-200">
Project templates are now product-specific, and can be configured for each project
type.
</p>
<img
src="/images/project-templates/project-templates-new-location.png"
className="mt-4 w-full max-w-4xl rounded"
alt="Project Templates New Location"
/>
<ul className="mb-1 flex gap-x-4 text-mineshaft-200">
{[
{
type: ProjectType.SecretManager,
label: "Secret Management",
icon: "sliding-carousel"
},
{
type: ProjectType.CertificateManager,
label: "Certificate Management",
icon: "note"
},
{
type: ProjectType.KMS,
label: "KMS",
icon: "unlock"
},
{
type: ProjectType.SSH,
label: "SSH",
icon: "verified"
}
].map(({ label, type, icon }, index) => (
<li key={`project-template-${type}`}>
<Link
to={`/organization/${type}/settings`}
className="mt-1 flex items-center gap-x-2 hover:text-mineshaft-100"
>
{index !== 0 && <span className="text-mineshaft-300">•</span>}
<DotLottieReact
src={`/lotties/${icon}.json`}
loop
className="mt-0.5 h-5 w-5"
/>{" "}
<span className="underline underline-offset-2">{label}</span>
</Link>
</li>
))}
</ul>
</NoticeBannerV2>
</div>
)