mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 00:27:35 +00:00
Merge pull request #3578 from Infisical/project-template-improvements
improvement(project-templates): Project templates UI improvements
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB |
+10
-5
@@ -25,6 +25,7 @@ import {
|
|||||||
import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context";
|
import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context";
|
||||||
import { useGetProjectTypeFromRoute, usePopUp } from "@app/hooks";
|
import { useGetProjectTypeFromRoute, usePopUp } from "@app/hooks";
|
||||||
import { TProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
|
import { TProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
|
|
||||||
import { DeleteProjectTemplateModal } from "./DeleteProjectTemplateModal";
|
import { DeleteProjectTemplateModal } from "./DeleteProjectTemplateModal";
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
const { isPending, data: projectTemplates = [] } = useListProjectTemplates(projectType, {
|
const { isPending, data: projectTemplates = [] } = useListProjectTemplates(projectType, {
|
||||||
enabled: subscription?.projectTemplates && Boolean(projectType)
|
enabled: subscription?.projectTemplates && Boolean(projectType)
|
||||||
});
|
});
|
||||||
|
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteTemplate"] as const);
|
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteTemplate"] as const);
|
||||||
@@ -52,7 +54,9 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
[search, projectTemplates]
|
[search, projectTemplates]
|
||||||
);
|
);
|
||||||
|
|
||||||
const isSecretManagerTemplates = projectType === "secret-manager";
|
const isSecretManagerTemplates = projectType === ProjectType.SecretManager;
|
||||||
|
|
||||||
|
const colSpan = isSecretManagerTemplates ? 4 : 3;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -73,10 +77,10 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
</Tr>
|
</Tr>
|
||||||
</THead>
|
</THead>
|
||||||
<TBody>
|
<TBody>
|
||||||
{isPending && (
|
{subscription?.projectTemplates && isPending && (
|
||||||
<TableSkeleton
|
<TableSkeleton
|
||||||
innerKey="project-templates-table"
|
innerKey="project-templates-table"
|
||||||
columns={4}
|
columns={colSpan}
|
||||||
key="project-templates"
|
key="project-templates"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -170,9 +174,10 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
</Tr>
|
</Tr>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{!isPending && filteredTemplates?.length === 0 && (
|
{(!subscription?.projectTemplates ||
|
||||||
|
(!isPending && filteredTemplates?.length === 0)) && (
|
||||||
<Tr>
|
<Tr>
|
||||||
<Td colSpan={5}>
|
<Td colSpan={colSpan}>
|
||||||
<EmptyState
|
<EmptyState
|
||||||
title={
|
title={
|
||||||
search.trim()
|
search.trim()
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ type Props = {
|
|||||||
title: string;
|
title: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
titleClassName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NoticeBannerV2 = ({ title, children, className }: Props) => {
|
export const NoticeBannerV2 = ({ title, children, className, titleClassName }: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
@@ -17,7 +18,7 @@ export const NoticeBannerV2 = ({ title, children, className }: Props) => {
|
|||||||
className
|
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" />
|
<FontAwesomeIcon icon={faInfoCircle} size="sm" className="mr-1.5 text-primary" />
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+47
-15
@@ -1,9 +1,11 @@
|
|||||||
import { useState } from "react";
|
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 { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||||
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
|
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
|
||||||
import { ROUTE_PATHS } from "@app/const/routes";
|
import { ROUTE_PATHS } from "@app/const/routes";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
|
|
||||||
import { AuditLogStreamsTab } from "../AuditLogStreamTab";
|
import { AuditLogStreamsTab } from "../AuditLogStreamTab";
|
||||||
import { ImportTab } from "../ImportTab";
|
import { ImportTab } from "../ImportTab";
|
||||||
@@ -36,22 +38,52 @@ export const OrgTabGroup = () => {
|
|||||||
component: () => (
|
component: () => (
|
||||||
<div>
|
<div>
|
||||||
<NoticeBannerV2
|
<NoticeBannerV2
|
||||||
className="mx-auto mt-10 max-w-4xl"
|
className="mx-auto"
|
||||||
title="Project Templates New Location"
|
titleClassName="text-base"
|
||||||
|
title="Project Templates Relocated"
|
||||||
>
|
>
|
||||||
<p className="text-sm text-bunker-200">
|
<p className="mt-1 text-mineshaft-300">
|
||||||
Project templates have been moved to the Feature Settings page, under the "Project
|
Project templates have been relocated and are now product specific:
|
||||||
Templates" tab.
|
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-2 text-sm text-bunker-200">
|
<ul className="mb-1 flex gap-x-4 text-mineshaft-200">
|
||||||
Project templates are now product-specific, and can be configured for each project
|
{[
|
||||||
type.
|
{
|
||||||
</p>
|
type: ProjectType.SecretManager,
|
||||||
<img
|
label: "Secret Management",
|
||||||
src="/images/project-templates/project-templates-new-location.png"
|
icon: "sliding-carousel"
|
||||||
className="mt-4 w-full max-w-4xl rounded"
|
},
|
||||||
alt="Project Templates New Location"
|
{
|
||||||
/>
|
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>
|
</NoticeBannerV2>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user