mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 01:27:41 +00:00
Merge pull request #300 from kanhaiya38/feat/merge-env
feat(ui): allow user to merge secrets while uploading file
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
import { Button, Modal, ModalContent } from '../v2';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onOverwriteConfirm: (preserve: 'old' | 'new') => void;
|
||||||
|
duplicateKeys: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConfirmEnvOverwriteModal = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
duplicateKeys,
|
||||||
|
onOverwriteConfirm
|
||||||
|
}: Props): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen}>
|
||||||
|
<ModalContent
|
||||||
|
title="Duplicate Secrets"
|
||||||
|
footerContent={
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Button colorSchema="primary" onClick={() => onOverwriteConfirm('old')}>
|
||||||
|
Keep Old
|
||||||
|
</Button>
|
||||||
|
<Button colorSchema="danger" onClick={() => onOverwriteConfirm('new')}>
|
||||||
|
Overwrite
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<p className='text-gray-400'>Your file contains the following duplicate secrets:</p>
|
||||||
|
<p className="text-sm text-gray-500">{duplicateKeys.join(', ')}</p>
|
||||||
|
<p className='text-md text-gray-400'>Are you sure you want to overwrite these secrets?</p>
|
||||||
|
</div>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConfirmEnvOverwriteModal;
|
||||||
@@ -231,7 +231,8 @@ function inputPropsAreEqual(prev: DashboardInputFieldProps, next: DashboardInput
|
|||||||
prev.position === next.position &&
|
prev.position === next.position &&
|
||||||
prev.blurred === next.blurred &&
|
prev.blurred === next.blurred &&
|
||||||
prev.overrideEnabled === next.overrideEnabled &&
|
prev.overrideEnabled === next.overrideEnabled &&
|
||||||
prev.isDuplicate === next.isDuplicate
|
prev.isDuplicate === next.isDuplicate &&
|
||||||
|
prev.isSideBarOpen === next.isSideBarOpen
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|||||||
className={twMerge(
|
className={twMerge(
|
||||||
'shrink-0 cursor-pointer transition-all',
|
'shrink-0 cursor-pointer transition-all',
|
||||||
loadingToggleClass,
|
loadingToggleClass,
|
||||||
size === 'xs' ? 'ml-1' : 'ml-2'
|
size === 'xs' ? 'ml-1' : 'ml-3'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{rightIcon}
|
{rightIcon}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import Button from '@app/components/basic/buttons/Button';
|
|||||||
import ListBox from '@app/components/basic/Listbox';
|
import ListBox from '@app/components/basic/Listbox';
|
||||||
import BottonRightPopup from '@app/components/basic/popups/BottomRightPopup';
|
import BottonRightPopup from '@app/components/basic/popups/BottomRightPopup';
|
||||||
import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
|
import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
|
||||||
|
import ConfirmEnvOverwriteModal from '@app/components/dashboard/ConfirmEnvOverwriteModal';
|
||||||
import DownloadSecretMenu from '@app/components/dashboard/DownloadSecretsMenu';
|
import DownloadSecretMenu from '@app/components/dashboard/DownloadSecretsMenu';
|
||||||
import DropZone from '@app/components/dashboard/DropZone';
|
import DropZone from '@app/components/dashboard/DropZone';
|
||||||
import KeyPair from '@app/components/dashboard/KeyPair';
|
import KeyPair from '@app/components/dashboard/KeyPair';
|
||||||
@@ -131,6 +132,7 @@ export default function Dashboard() {
|
|||||||
const [snapshotData, setSnapshotData] = useState<SnapshotProps>();
|
const [snapshotData, setSnapshotData] = useState<SnapshotProps>();
|
||||||
const [numSnapshots, setNumSnapshots] = useState<number>();
|
const [numSnapshots, setNumSnapshots] = useState<number>();
|
||||||
const [saveLoading, setSaveLoading] = useState(false);
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const [dropZoneData, setDropZoneData] = useState<SecretDataProps[]>();
|
||||||
const [projectTags, setProjectTags] = useState<Tag[]>([]);
|
const [projectTags, setProjectTags] = useState<Tag[]>([]);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -546,11 +548,33 @@ export default function Dashboard() {
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const addData = (newData: SecretDataProps[]) => {
|
const addDataWithMerge = (newData: SecretDataProps[], preserve?: 'old' | 'new') => {
|
||||||
setData(data!.concat(newData));
|
setData((oldData) => {
|
||||||
|
let filteredOldData = oldData!;
|
||||||
|
let filteredNewData = newData;
|
||||||
|
if (preserve === 'new')
|
||||||
|
filteredOldData = oldData!.filter(
|
||||||
|
(oldDataPoint) => !newData.find((newDataPoint) => newDataPoint.key === oldDataPoint.key)
|
||||||
|
);
|
||||||
|
if (preserve === 'old')
|
||||||
|
filteredNewData = newData.filter(
|
||||||
|
(newDataPoint) => !oldData?.find((oldDataPoint) => oldDataPoint.key === newDataPoint.key)
|
||||||
|
);
|
||||||
|
return filteredOldData.concat(filteredNewData);
|
||||||
|
});
|
||||||
setButtonReady(true);
|
setButtonReady(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addData = (newData: SecretDataProps[]) => {
|
||||||
|
if (
|
||||||
|
newData.some((newDataPoint) => data?.find((dataPoint) => dataPoint.key === newDataPoint.key)) // if newData contains duplicates
|
||||||
|
) {
|
||||||
|
setDropZoneData(newData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addDataWithMerge(newData);
|
||||||
|
};
|
||||||
|
|
||||||
const changeBlurred = () => {
|
const changeBlurred = () => {
|
||||||
setBlurred(!blurred);
|
setBlurred(!blurred);
|
||||||
};
|
};
|
||||||
@@ -568,7 +592,22 @@ export default function Dashboard() {
|
|||||||
<meta property="og:title" content={String(t('dashboard:og-title'))} />
|
<meta property="og:title" content={String(t('dashboard:og-title'))} />
|
||||||
<meta name="og:description" content={String(t('dashboard:og-description'))} />
|
<meta name="og:description" content={String(t('dashboard:og-description'))} />
|
||||||
</Head>
|
</Head>
|
||||||
<div className="flex flex-row h-full dark:[color-scheme:dark]">
|
<div className="flex flex-row h-full">
|
||||||
|
<ConfirmEnvOverwriteModal
|
||||||
|
isOpen={!!dropZoneData}
|
||||||
|
onClose={() => setDropZoneData(undefined)}
|
||||||
|
onOverwriteConfirm={(preserve) => {
|
||||||
|
addDataWithMerge(dropZoneData!, preserve);
|
||||||
|
setDropZoneData(undefined);
|
||||||
|
}}
|
||||||
|
duplicateKeys={
|
||||||
|
dropZoneData
|
||||||
|
?.filter((newDataPoint) =>
|
||||||
|
data?.find((dataPoint) => dataPoint.key === newDataPoint.key)
|
||||||
|
)
|
||||||
|
.map((duplicate) => duplicate.key) ?? []
|
||||||
|
}
|
||||||
|
/>
|
||||||
<div className="w-full max-h-96 pb-2 dark:[color-scheme:dark]">
|
<div className="w-full max-h-96 pb-2 dark:[color-scheme:dark]">
|
||||||
<NavHeader pageName={t('dashboard:title')} isProjectRelated />
|
<NavHeader pageName={t('dashboard:title')} isProjectRelated />
|
||||||
{checkDocsPopUpVisible && (
|
{checkDocsPopUpVisible && (
|
||||||
|
|||||||
Reference in New Issue
Block a user