mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 15:27:46 +00:00
add new modal to compare secrets across environments
This commit is contained in:
@@ -0,0 +1,75 @@
|
|||||||
|
import { SetStateAction, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { WorkspaceEnv } from '~/pages/dashboard/[id]';
|
||||||
|
|
||||||
|
import getSecretsForProject from '../utilities/secrets/getSecretsForProject';
|
||||||
|
import { Modal, ModalContent } from '../v2';
|
||||||
|
|
||||||
|
interface Secrets {
|
||||||
|
label: string;
|
||||||
|
secret: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CompareSecretsModalProps {
|
||||||
|
compareModal: boolean;
|
||||||
|
setCompareModal: React.Dispatch<SetStateAction<boolean>>;
|
||||||
|
selectedEnv: WorkspaceEnv;
|
||||||
|
workspaceEnvs: WorkspaceEnv[];
|
||||||
|
workspaceId: string;
|
||||||
|
currentSecret: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const CompareSecretsModal = ({
|
||||||
|
compareModal,
|
||||||
|
setCompareModal,
|
||||||
|
selectedEnv,
|
||||||
|
workspaceEnvs,
|
||||||
|
workspaceId,
|
||||||
|
currentSecret
|
||||||
|
}: CompareSecretsModalProps) => {
|
||||||
|
const [secrets, setSecrets] = useState<Secrets[]>([]);
|
||||||
|
|
||||||
|
const getEnvSecrets = async () => {
|
||||||
|
const workspaceEnvironments = workspaceEnvs.filter((env) => env !== selectedEnv);
|
||||||
|
const newSecrets = await Promise.all(
|
||||||
|
workspaceEnvironments.map(async (env) => {
|
||||||
|
const allSecrets = await getSecretsForProject({ env: env.slug, workspaceId });
|
||||||
|
const secret =
|
||||||
|
allSecrets.find((item) => item.key === currentSecret.key)?.value ?? 'Not found';
|
||||||
|
return { label: env.name, secret };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
setSecrets([{ label: selectedEnv.name, secret: currentSecret.value }, ...newSecrets]);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (compareModal) {
|
||||||
|
(async () => {
|
||||||
|
await getEnvSecrets();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}, [compareModal]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={compareModal} onOpenChange={setCompareModal}>
|
||||||
|
<ModalContent title={currentSecret?.key} onOpenAutoFocus={(e) => e.preventDefault()}>
|
||||||
|
<div className="space-y-4">
|
||||||
|
{secrets.map((item) => (
|
||||||
|
<div key={`${currentSecret.key}${item.label}`} className="space-y-1">
|
||||||
|
<p className="text-sm text-bunker-300">{item.label}</p>
|
||||||
|
<input
|
||||||
|
defaultValue={item.secret}
|
||||||
|
className="h-no-capture text-md min-w-16 no-scrollbar::-webkit-scrollbar peer z-10 w-full rounded-md bg-bunker-800 px-2 py-1.5 font-mono text-gray-400 caret-white outline-none duration-200 no-scrollbar focus:ring-2 focus:ring-primary/50 "
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CompareSecretsModal;
|
||||||
@@ -7,9 +7,12 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|||||||
|
|
||||||
import SecretVersionList from '@app/ee/components/SecretVersionList';
|
import SecretVersionList from '@app/ee/components/SecretVersionList';
|
||||||
|
|
||||||
|
import { WorkspaceEnv } from '~/pages/dashboard/[id]';
|
||||||
|
|
||||||
import Button from '../basic/buttons/Button';
|
import Button from '../basic/buttons/Button';
|
||||||
import Toggle from '../basic/Toggle';
|
import Toggle from '../basic/Toggle';
|
||||||
import CommentField from './CommentField';
|
import CommentField from './CommentField';
|
||||||
|
import CompareSecretsModal from './CompareSecretsModal';
|
||||||
import DashboardInputField from './DashboardInputField';
|
import DashboardInputField from './DashboardInputField';
|
||||||
import { DeleteActionButton } from './DeleteActionButton';
|
import { DeleteActionButton } from './DeleteActionButton';
|
||||||
import GenerateSecretMenu from './GenerateSecretMenu';
|
import GenerateSecretMenu from './GenerateSecretMenu';
|
||||||
@@ -40,6 +43,9 @@ interface SideBarProps {
|
|||||||
sharedToHide: string[];
|
sharedToHide: string[];
|
||||||
setSharedToHide: (values: string[]) => void;
|
setSharedToHide: (values: string[]) => void;
|
||||||
deleteRow: (props: DeleteRowFunctionProps) => void;
|
deleteRow: (props: DeleteRowFunctionProps) => void;
|
||||||
|
workspaceEnvs: WorkspaceEnv[];
|
||||||
|
selectedEnv: WorkspaceEnv;
|
||||||
|
workspaceId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,11 +69,15 @@ const SideBar = ({
|
|||||||
modifyComment,
|
modifyComment,
|
||||||
buttonReady,
|
buttonReady,
|
||||||
savePush,
|
savePush,
|
||||||
deleteRow
|
deleteRow,
|
||||||
|
workspaceEnvs,
|
||||||
|
selectedEnv,
|
||||||
|
workspaceId
|
||||||
}: SideBarProps) => {
|
}: SideBarProps) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [overrideEnabled, setOverrideEnabled] = useState(data[0].valueOverride !== undefined);
|
const [overrideEnabled, setOverrideEnabled] = useState(data[0]?.valueOverride !== undefined);
|
||||||
|
const [compareModal, setCompareModal] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -171,20 +181,38 @@ const SideBar = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex justify-start max-w-sm mt-4 px-4 mt-full mb-[4.7rem]">
|
<div className="mt-full mt-4 mb-[4.7rem] flex max-w-sm flex-col justify-start space-y-2 px-4">
|
||||||
<Button
|
<div>
|
||||||
text={String(t('common:save-changes'))}
|
<Button
|
||||||
onButtonPressed={savePush}
|
text="Compare secret across environments"
|
||||||
color="primary"
|
color="mineshaft"
|
||||||
size="md"
|
size="md"
|
||||||
active={buttonReady}
|
onButtonPressed={() => setCompareModal(true)}
|
||||||
textDisabled="Saved"
|
/>
|
||||||
/>
|
<CompareSecretsModal
|
||||||
<DeleteActionButton
|
compareModal={compareModal}
|
||||||
onSubmit={() =>
|
setCompareModal={setCompareModal}
|
||||||
deleteRow({ ids: data.map((secret) => secret.id), secretName: data[0]?.key })
|
currentSecret={{ key: data[0]?.key, value: data[0]?.value }}
|
||||||
}
|
workspaceEnvs={workspaceEnvs}
|
||||||
/>
|
selectedEnv={selectedEnv}
|
||||||
|
workspaceId={workspaceId}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex">
|
||||||
|
<Button
|
||||||
|
text={String(t('common:save-changes'))}
|
||||||
|
onButtonPressed={savePush}
|
||||||
|
color="primary"
|
||||||
|
size="md"
|
||||||
|
active={buttonReady}
|
||||||
|
textDisabled="Saved"
|
||||||
|
/>
|
||||||
|
<DeleteActionButton
|
||||||
|
onSubmit={() =>
|
||||||
|
deleteRow({ ids: data.map((secret) => secret.id), secretName: data[0]?.key })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user