mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 15:31:19 +00:00
feat: added dynamic secret to overview page
This commit is contained in:
@@ -54,6 +54,7 @@ import {
|
||||
useCreateFolder,
|
||||
useCreateSecretV3,
|
||||
useDeleteSecretV3,
|
||||
useGetDynamicSecretsOfAllEnv,
|
||||
useGetFoldersByEnv,
|
||||
useGetImportedSecretsAllEnvs,
|
||||
useGetProjectSecretsAllEnv,
|
||||
@@ -66,12 +67,13 @@ import { FolderForm } from "../SecretMainPage/components/ActionBar/FolderForm";
|
||||
import { CreateSecretForm } from "./components/CreateSecretForm";
|
||||
import { FolderBreadCrumbs } from "./components/FolderBreadCrumbs";
|
||||
import { ProjectIndexSecretsSection } from "./components/ProjectIndexSecretsSection";
|
||||
import { SecretOverviewDynamicSecretRow } from "./components/SecretOverviewDynamicSecretRow";
|
||||
import { SecretOverviewFolderRow } from "./components/SecretOverviewFolderRow";
|
||||
import { SecretOverviewTableRow } from "./components/SecretOverviewTableRow";
|
||||
|
||||
export const SecretOverviewPage = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// this is to set expandable table width
|
||||
@@ -98,6 +100,7 @@ export const SecretOverviewPage = () => {
|
||||
const { currentWorkspace, isLoading: isWorkspaceLoading } = useWorkspace();
|
||||
const { currentOrg } = useOrganization();
|
||||
const workspaceId = currentWorkspace?.id as string;
|
||||
const projectSlug = currentWorkspace?.slug as string;
|
||||
const { data: latestFileKey } = useGetUserWsKey(workspaceId);
|
||||
const [searchFilter, setSearchFilter] = useState("");
|
||||
const secretPath = (router.query?.secretPath as string) || "/";
|
||||
@@ -138,6 +141,13 @@ export const SecretOverviewPage = () => {
|
||||
environments: userAvailableEnvs.map(({ slug }) => slug)
|
||||
});
|
||||
|
||||
const { dynamicSecretNames, dynamicSecrets, isDynamicSecretPresentInEnv } =
|
||||
useGetDynamicSecretsOfAllEnv({
|
||||
projectSlug,
|
||||
environmentSlugs: userAvailableEnvs.map(({ slug }) => slug),
|
||||
path: secretPath
|
||||
});
|
||||
|
||||
const { mutateAsync: createSecretV3 } = useCreateSecretV3();
|
||||
const { mutateAsync: updateSecretV3 } = useUpdateSecretV3();
|
||||
const { mutateAsync: deleteSecretV3 } = useDeleteSecretV3();
|
||||
@@ -336,12 +346,19 @@ export const SecretOverviewPage = () => {
|
||||
const filteredFolderNames = folderNames?.filter((name) =>
|
||||
name.toLowerCase().includes(searchFilter.toLowerCase())
|
||||
);
|
||||
const filteredDynamicSecrets = dynamicSecretNames?.filter((name) =>
|
||||
name.toLowerCase().includes(searchFilter.toLowerCase())
|
||||
);
|
||||
|
||||
const isTableEmpty =
|
||||
!(
|
||||
folders?.every(({ isLoading }) => isLoading) && secrets?.every(({ isLoading }) => isLoading)
|
||||
folders?.every(({ isLoading }) => isLoading) &&
|
||||
secrets?.every(({ isLoading }) => isLoading) &&
|
||||
dynamicSecrets?.every(({ isLoading }) => isLoading)
|
||||
) &&
|
||||
filteredSecretNames?.length === 0 &&
|
||||
filteredFolderNames?.length === 0;
|
||||
filteredFolderNames?.length === 0 &&
|
||||
filteredDynamicSecrets?.length === 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -651,6 +668,15 @@ export const SecretOverviewPage = () => {
|
||||
onClick={handleFolderClick}
|
||||
/>
|
||||
))}
|
||||
{!isTableLoading &&
|
||||
filteredDynamicSecrets.map((dynamicSecretName, index) => (
|
||||
<SecretOverviewDynamicSecretRow
|
||||
dynamicSecretName={dynamicSecretName}
|
||||
isDynamicSecretInEnv={isDynamicSecretPresentInEnv}
|
||||
environments={visibleEnvs}
|
||||
key={`overview-${dynamicSecretName}-${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
{!isTableLoading &&
|
||||
visibleEnvs?.length > 0 &&
|
||||
filteredSecretNames.map((key, index) => (
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import { faCheck, faFingerprint, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { Td, Tr } from "@app/components/v2";
|
||||
|
||||
type Props = {
|
||||
dynamicSecretName: string;
|
||||
environments: { name: string; slug: string }[];
|
||||
isDynamicSecretInEnv: (name: string, env: string) => boolean;
|
||||
};
|
||||
|
||||
export const SecretOverviewDynamicSecretRow = ({
|
||||
dynamicSecretName,
|
||||
environments = [],
|
||||
isDynamicSecretInEnv
|
||||
}: Props) => {
|
||||
return (
|
||||
<Tr isHoverable isSelectable className="group">
|
||||
<Td className="sticky left-0 z-10 border-0 bg-mineshaft-800 bg-clip-padding p-0 group-hover:bg-mineshaft-700">
|
||||
<div className="flex items-center space-x-5 border-r border-mineshaft-600 px-5 py-2.5">
|
||||
<div className="text-yellow-700">
|
||||
<FontAwesomeIcon icon={faFingerprint} />
|
||||
</div>
|
||||
<div>{dynamicSecretName}</div>
|
||||
</div>
|
||||
</Td>
|
||||
{environments.map(({ slug }, i) => {
|
||||
const isPresent = isDynamicSecretInEnv(dynamicSecretName, slug);
|
||||
|
||||
return (
|
||||
<Td
|
||||
key={`sec-overview-${slug}-${i + 1}-folder`}
|
||||
className={twMerge(
|
||||
"border-r border-mineshaft-600 py-3 group-hover:bg-mineshaft-700",
|
||||
isPresent ? "text-green-600" : "text-red-600"
|
||||
)}
|
||||
>
|
||||
<div className="flex justify-center">
|
||||
<FontAwesomeIcon
|
||||
// eslint-disable-next-line no-nested-ternary
|
||||
icon={isPresent ? faCheck : faXmark}
|
||||
/>
|
||||
</div>
|
||||
</Td>
|
||||
);
|
||||
})}
|
||||
</Tr>
|
||||
);
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { SecretOverviewDynamicSecretRow } from "./SecretOverviewDynamicSecretRow";
|
||||
Reference in New Issue
Block a user