mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 05:27:48 +00:00
added ability to hide environments in the overview screen
This commit is contained in:
@@ -291,7 +291,7 @@ export const SecretDetailSidebar = ({
|
|||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
<DropdownMenuContent align="end" className="z-[100]">
|
<DropdownMenuContent align="end" className="z-[100]">
|
||||||
<DropdownMenuLabel>Apply tags to this secrets</DropdownMenuLabel>
|
<DropdownMenuLabel>Add tags to this secret</DropdownMenuLabel>
|
||||||
{tags.map((tag) => {
|
{tags.map((tag) => {
|
||||||
const { id: tagId, name, color } = tag;
|
const { id: tagId, name, color } = tag;
|
||||||
|
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ export const SecretItem = memo(
|
|||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
<DropdownMenuLabel>Apply tags to this secrets</DropdownMenuLabel>
|
<DropdownMenuLabel>Add tags to this secret</DropdownMenuLabel>
|
||||||
{tags.map((tag) => {
|
{tags.map((tag) => {
|
||||||
const { id: tagId, name, color } = tag;
|
const { id: tagId, name, color } = tag;
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import { useEffect, useRef, useState } from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
|
||||||
import {
|
import {
|
||||||
faArrowDown,
|
faArrowDown,
|
||||||
faArrowUp,
|
faArrowUp,
|
||||||
faFolderBlank,
|
faFolderBlank,
|
||||||
|
faList,
|
||||||
faMagnifyingGlass
|
faMagnifyingGlass
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
@@ -15,6 +17,11 @@ import NavHeader from "@app/components/navigation/NavHeader";
|
|||||||
import { PermissionDeniedBanner } from "@app/components/permissions";
|
import { PermissionDeniedBanner } from "@app/components/permissions";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuTrigger,
|
||||||
EmptyState,
|
EmptyState,
|
||||||
IconButton,
|
IconButton,
|
||||||
Input,
|
Input,
|
||||||
@@ -86,6 +93,7 @@ export const SecretOverviewPage = () => {
|
|||||||
}, [isWorkspaceLoading, workspaceId, router.isReady]);
|
}, [isWorkspaceLoading, workspaceId, router.isReady]);
|
||||||
|
|
||||||
const userAvailableEnvs = currentWorkspace?.environments || [];
|
const userAvailableEnvs = currentWorkspace?.environments || [];
|
||||||
|
const [visibleEnvs, setVisisbleEnvs] = useState(userAvailableEnvs);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: secrets,
|
data: secrets,
|
||||||
@@ -149,6 +157,14 @@ export const SecretOverviewPage = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEnvSelect = (envId: string) => {
|
||||||
|
if (visibleEnvs.map(env => env.id).includes(envId)) {
|
||||||
|
setVisisbleEnvs(visibleEnvs.filter(env => env.id !== envId))
|
||||||
|
} else {
|
||||||
|
setVisisbleEnvs(visibleEnvs.concat(userAvailableEnvs.filter(env => env.id === envId)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSecretUpdate = async (env: string, key: string, value: string, secretId?: string) => {
|
const handleSecretUpdate = async (env: string, key: string, value: string, secretId?: string) => {
|
||||||
try {
|
try {
|
||||||
await updateSecretV3({
|
await updateSecretV3({
|
||||||
@@ -225,7 +241,7 @@ export const SecretOverviewPage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const query: Record<string, string> = { ...router.query, env: slug };
|
const query: Record<string, string> = { ...router.query, env: slug };
|
||||||
const envIndex = userAvailableEnvs.findIndex((el) => slug === el.slug);
|
const envIndex = visibleEnvs.findIndex((el) => slug === el.slug);
|
||||||
if (envIndex !== -1) {
|
if (envIndex !== -1) {
|
||||||
router.push({
|
router.push({
|
||||||
pathname: "/project/[id]/secrets/[env]",
|
pathname: "/project/[id]/secrets/[env]",
|
||||||
@@ -317,7 +333,53 @@ export const SecretOverviewPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex items-center justify-between">
|
<div className="mt-8 flex items-center justify-between">
|
||||||
<FolderBreadCrumbs secretPath={secretPath} onResetSearch={handleResetSearch} />
|
<FolderBreadCrumbs secretPath={secretPath} onResetSearch={handleResetSearch} />
|
||||||
<div className="w-80">
|
<div className="w-96 flex flex-row">
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="Environments"
|
||||||
|
variant="plain"
|
||||||
|
size="sm"
|
||||||
|
className="flex justify-center items-center overflow-hidden p-0 w-11 bg-mineshaft-800 hover:bg-primary/10 hover:border-primary/60 border border-mineshaft-600 mr-2"
|
||||||
|
>
|
||||||
|
<Tooltip content="Choose visible environments" className="mb-2">
|
||||||
|
<FontAwesomeIcon icon={faList} />
|
||||||
|
</Tooltip>
|
||||||
|
</IconButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuLabel>Choose visible environments</DropdownMenuLabel>
|
||||||
|
{userAvailableEnvs.map((avaiableEnv) => {
|
||||||
|
const { id: envId, name } = avaiableEnv;
|
||||||
|
|
||||||
|
const isEnvSelected = visibleEnvs.map(env => env.id).includes(envId);
|
||||||
|
return (
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => handleEnvSelect(envId)}
|
||||||
|
key={envId}
|
||||||
|
icon={isEnvSelected && <FontAwesomeIcon className="text-primary" icon={faCheckCircle} />}
|
||||||
|
iconPos="left"
|
||||||
|
>
|
||||||
|
<div className="flex items-center">
|
||||||
|
{name}
|
||||||
|
</div>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{/* <DropdownMenuItem className="px-1.5" asChild>
|
||||||
|
<Button
|
||||||
|
size="xs"
|
||||||
|
className="w-full"
|
||||||
|
colorSchema="primary"
|
||||||
|
variant="outline_bg"
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faHockeyPuck} />}
|
||||||
|
// onClick={onCreateTag}
|
||||||
|
>
|
||||||
|
Create an environment
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuItem> */}
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
<Input
|
<Input
|
||||||
className="h-[2.3rem] bg-mineshaft-800 placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
className="h-[2.3rem] bg-mineshaft-800 placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
||||||
placeholder="Search by secret/folder name..."
|
placeholder="Search by secret/folder name..."
|
||||||
@@ -345,7 +407,7 @@ export const SecretOverviewPage = () => {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
</Th>
|
</Th>
|
||||||
{userAvailableEnvs?.map(({ name, slug }, index) => {
|
{visibleEnvs?.map(({ name, slug }, index) => {
|
||||||
const envSecKeyCount = getEnvSecretKeyCount(slug);
|
const envSecKeyCount = getEnvSecretKeyCount(slug);
|
||||||
const missingKeyCount = secKeys.length - envSecKeyCount;
|
const missingKeyCount = secKeys.length - envSecKeyCount;
|
||||||
return (
|
return (
|
||||||
@@ -388,12 +450,12 @@ export const SecretOverviewPage = () => {
|
|||||||
)}
|
)}
|
||||||
{isTableEmpty && !isTableLoading && (
|
{isTableEmpty && !isTableLoading && (
|
||||||
<Tr>
|
<Tr>
|
||||||
<Td colSpan={userAvailableEnvs.length + 1}>
|
<Td colSpan={visibleEnvs.length + 1}>
|
||||||
<EmptyState title="Let's add some secrets" icon={faFolderBlank} iconSize="3x">
|
<EmptyState title="Let's add some secrets" icon={faFolderBlank} iconSize="3x">
|
||||||
<Link
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: "/project/[id]/secrets/[env]",
|
pathname: "/project/[id]/secrets/[env]",
|
||||||
query: { id: workspaceId, env: userAvailableEnvs?.[0]?.slug }
|
query: { id: workspaceId, env: visibleEnvs?.[0]?.slug }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@@ -402,7 +464,7 @@ export const SecretOverviewPage = () => {
|
|||||||
colorSchema="primary"
|
colorSchema="primary"
|
||||||
size="md"
|
size="md"
|
||||||
>
|
>
|
||||||
Go to {userAvailableEnvs?.[0]?.name}
|
Go to {visibleEnvs?.[0]?.name}
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</EmptyState>
|
</EmptyState>
|
||||||
@@ -414,13 +476,13 @@ export const SecretOverviewPage = () => {
|
|||||||
<SecretOverviewFolderRow
|
<SecretOverviewFolderRow
|
||||||
folderName={folderName}
|
folderName={folderName}
|
||||||
isFolderPresentInEnv={isFolderPresentInEnv}
|
isFolderPresentInEnv={isFolderPresentInEnv}
|
||||||
environments={userAvailableEnvs}
|
environments={visibleEnvs}
|
||||||
key={`overview-${folderName}-${index + 1}`}
|
key={`overview-${folderName}-${index + 1}`}
|
||||||
onClick={handleFolderClick}
|
onClick={handleFolderClick}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{!isTableLoading &&
|
{!isTableLoading &&
|
||||||
(userAvailableEnvs?.length > 0 ? (
|
(visibleEnvs?.length > 0 ? (
|
||||||
filteredSecretNames.map((key, index) => (
|
filteredSecretNames.map((key, index) => (
|
||||||
<SecretOverviewTableRow
|
<SecretOverviewTableRow
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
@@ -428,7 +490,7 @@ export const SecretOverviewPage = () => {
|
|||||||
onSecretDelete={handleSecretDelete}
|
onSecretDelete={handleSecretDelete}
|
||||||
onSecretUpdate={handleSecretUpdate}
|
onSecretUpdate={handleSecretUpdate}
|
||||||
key={`overview-${key}-${index + 1}`}
|
key={`overview-${key}-${index + 1}`}
|
||||||
environments={userAvailableEnvs}
|
environments={visibleEnvs}
|
||||||
secretKey={key}
|
secretKey={key}
|
||||||
getSecretByKey={getSecretByKey}
|
getSecretByKey={getSecretByKey}
|
||||||
expandableColWidth={expandableTableWidth}
|
expandableColWidth={expandableTableWidth}
|
||||||
@@ -446,7 +508,7 @@ export const SecretOverviewPage = () => {
|
|||||||
style={{ height: "45px" }}
|
style={{ height: "45px" }}
|
||||||
/>
|
/>
|
||||||
</Td>
|
</Td>
|
||||||
{userAvailableEnvs.map(({ name, slug }) => (
|
{visibleEnvs.map(({ name, slug }) => (
|
||||||
<Td key={`explore-${name}-btn`} className="border-0 border-mineshaft-600 p-0">
|
<Td key={`explore-${name}-btn`} className="border-0 border-mineshaft-600 p-0">
|
||||||
<div className="flex w-full items-center justify-center border-r border-t border-mineshaft-600 px-5 py-2">
|
<div className="flex w-full items-center justify-center border-r border-t border-mineshaft-600 px-5 py-2">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
Reference in New Issue
Block a user