mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 07:26:45 +00:00
Address PR comments
This commit is contained in:
@@ -256,11 +256,7 @@ export const CreateSecretSyncForm = ({
|
|||||||
</FormProvider>
|
</FormProvider>
|
||||||
|
|
||||||
<div className="flex w-full flex-row-reverse justify-between gap-4 pt-4">
|
<div className="flex w-full flex-row-reverse justify-between gap-4 pt-4">
|
||||||
<Button
|
<Button onClick={handleNext} colorSchema="secondary" isDisabled={isCreateButtonDisabled}>
|
||||||
onClick={handleNext}
|
|
||||||
colorSchema="secondary"
|
|
||||||
isDisabled={isCreateButtonDisabled || (isFinalStep && hasDuplicate)}
|
|
||||||
>
|
|
||||||
{isFinalStep ? "Create Sync" : "Next"}
|
{isFinalStep ? "Create Sync" : "Next"}
|
||||||
</Button>
|
</Button>
|
||||||
{selectedTabIndex > 0 && (
|
{selectedTabIndex > 0 && (
|
||||||
|
|||||||
+29
-20
@@ -6,6 +6,7 @@ type Props = {
|
|||||||
onConfirm: () => void;
|
onConfirm: () => void;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
duplicateProjectId?: string;
|
duplicateProjectId?: string;
|
||||||
|
isDisabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DuplicateDestinationConfirmationModal = ({
|
export const DuplicateDestinationConfirmationModal = ({
|
||||||
@@ -13,7 +14,8 @@ export const DuplicateDestinationConfirmationModal = ({
|
|||||||
onOpenChange,
|
onOpenChange,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
isLoading,
|
isLoading,
|
||||||
duplicateProjectId
|
duplicateProjectId,
|
||||||
|
isDisabled
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||||
@@ -21,7 +23,12 @@ export const DuplicateDestinationConfirmationModal = ({
|
|||||||
<div className="mb-4 text-sm">
|
<div className="mb-4 text-sm">
|
||||||
<p>
|
<p>
|
||||||
Another secret sync in your organization is already configured with the same
|
Another secret sync in your organization is already configured with the same
|
||||||
destination. Proceeding may cause conflicts or overwrite existing data.
|
destination.{" "}
|
||||||
|
<span className={isDisabled ? "text-red-400" : ""}>
|
||||||
|
{isDisabled
|
||||||
|
? "Your organization does not allow duplicate destination configurations."
|
||||||
|
: "Proceeding may cause conflicts or overwrite existing data."}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{duplicateProjectId && (
|
{duplicateProjectId && (
|
||||||
<p className="mt-2 text-xs text-mineshaft-400">
|
<p className="mt-2 text-xs text-mineshaft-400">
|
||||||
@@ -31,26 +38,28 @@ export const DuplicateDestinationConfirmationModal = ({
|
|||||||
</code>
|
</code>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className="mt-2">Are you sure you want to continue?</p>
|
{!isDisabled && <p className="mt-2">Are you sure you want to continue?</p>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-4 pt-4">
|
{!isDisabled && (
|
||||||
<ModalClose asChild>
|
<div className="flex items-center gap-4 pt-4">
|
||||||
<Button
|
<ModalClose asChild>
|
||||||
onClick={onConfirm}
|
<Button
|
||||||
colorSchema="danger"
|
onClick={onConfirm}
|
||||||
isLoading={isLoading}
|
colorSchema="danger"
|
||||||
isDisabled={isLoading}
|
isLoading={isLoading}
|
||||||
>
|
isDisabled={isLoading}
|
||||||
Continue
|
>
|
||||||
</Button>
|
Continue
|
||||||
</ModalClose>
|
</Button>
|
||||||
<ModalClose asChild>
|
</ModalClose>
|
||||||
<Button colorSchema="secondary" variant="plain" isDisabled={isLoading}>
|
<ModalClose asChild>
|
||||||
Cancel
|
<Button colorSchema="secondary" variant="plain" isDisabled={isLoading}>
|
||||||
</Button>
|
Cancel
|
||||||
</ModalClose>
|
</Button>
|
||||||
</div>
|
</ModalClose>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { SecretSyncEditFields } from "@app/components/secret-syncs/types";
|
import { SecretSyncEditFields } from "@app/components/secret-syncs/types";
|
||||||
import { Button, ModalClose } from "@app/components/v2";
|
import { Button, ModalClose } from "@app/components/v2";
|
||||||
|
import { useOrganization } from "@app/context";
|
||||||
import { SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
|
import { SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
|
||||||
import {
|
import {
|
||||||
TSecretSync,
|
TSecretSync,
|
||||||
@@ -30,6 +31,7 @@ export const EditSecretSyncForm = ({ secretSync, fields, onComplete }: Props) =>
|
|||||||
const { name: destinationName } = SECRET_SYNC_MAP[secretSync.destination];
|
const { name: destinationName } = SECRET_SYNC_MAP[secretSync.destination];
|
||||||
const [showDuplicateConfirmation, setShowDuplicateConfirmation] = useState(false);
|
const [showDuplicateConfirmation, setShowDuplicateConfirmation] = useState(false);
|
||||||
const [pendingFormData, setPendingFormData] = useState<TSecretSyncForm | null>(null);
|
const [pendingFormData, setPendingFormData] = useState<TSecretSyncForm | null>(null);
|
||||||
|
const { currentOrg } = useOrganization();
|
||||||
|
|
||||||
const formMethods = useForm<TSecretSyncForm>({
|
const formMethods = useForm<TSecretSyncForm>({
|
||||||
resolver: zodResolver(UpdateSecretSyncFormSchema),
|
resolver: zodResolver(UpdateSecretSyncFormSchema),
|
||||||
@@ -209,6 +211,7 @@ export const EditSecretSyncForm = ({ secretSync, fields, onComplete }: Props) =>
|
|||||||
onConfirm={handleConfirmDuplicate}
|
onConfirm={handleConfirmDuplicate}
|
||||||
isLoading={updateSecretSync.isPending}
|
isLoading={updateSecretSync.isPending}
|
||||||
duplicateProjectId={storedDuplicateProjectId}
|
duplicateProjectId={storedDuplicateProjectId}
|
||||||
|
isDisabled={currentOrg?.blockDuplicateSecretSyncDestinations}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-1
@@ -219,7 +219,7 @@ export const SecretSyncReviewFields = () => {
|
|||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
{currentOrg?.blockDuplicateSecretSyncDestinations
|
{currentOrg?.blockDuplicateSecretSyncDestinations
|
||||||
? "Another secret sync in your organization is already configured with the same destination. This organization has blocking duplicate destinations enabled."
|
? "Another secret sync in your organization is already configured with the same destination. Your organization does not allow duplicate destination configurations."
|
||||||
: "Another secret sync in your organization is already configured with the same destination. This may lead to conflicts or unexpected behavior."}
|
: "Another secret sync in your organization is already configured with the same destination. This may lead to conflicts or unexpected behavior."}
|
||||||
</p>
|
</p>
|
||||||
{duplicateProjectId && (
|
{duplicateProjectId && (
|
||||||
|
|||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
|
||||||
import { Checkbox } from "@app/components/v2";
|
|
||||||
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
|
||||||
import { useUpdateOrg } from "@app/hooks/api/organization/queries";
|
|
||||||
|
|
||||||
export const BlockDuplicateSecretSyncDestinationsSection = () => {
|
|
||||||
const { currentOrg } = useOrganization();
|
|
||||||
const { mutateAsync: updateOrg } = useUpdateOrg();
|
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
|
|
||||||
const handleToggle = async (state: boolean) => {
|
|
||||||
setIsLoading(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!currentOrg?.id) {
|
|
||||||
setIsLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await updateOrg({
|
|
||||||
orgId: currentOrg.id,
|
|
||||||
blockDuplicateSecretSyncDestinations: state
|
|
||||||
});
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text: `Successfully ${state ? "enabled" : "disabled"} blocking duplicate secret sync destinations for this organization`,
|
|
||||||
type: "success"
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to update blocking duplicate secret sync destinations setting for this organization",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
|
||||||
<p className="mb-3 text-xl font-medium">Block Duplicate Secret Sync Destinations</p>
|
|
||||||
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Settings}>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<div className="w-max">
|
|
||||||
<Checkbox
|
|
||||||
id="blockDuplicateSecretSyncDestinations"
|
|
||||||
isDisabled={!isAllowed || isLoading}
|
|
||||||
isChecked={currentOrg?.blockDuplicateSecretSyncDestinations ?? false}
|
|
||||||
onCheckedChange={(state) => handleToggle(state as boolean)}
|
|
||||||
>
|
|
||||||
This feature prevents creating secret syncs with destinations that are already in use
|
|
||||||
by other syncs in your organization.
|
|
||||||
</Checkbox>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</OrgPermissionCan>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
export { BlockDuplicateSecretSyncDestinationsSection } from "./BlockDuplicateSecretSyncDestinationsSection";
|
|
||||||
+3
-3
@@ -49,11 +49,11 @@ export const OrgProductSettingsTab = () => {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-2 text-lg font-medium text-mineshaft-100">
|
<h3 className="mb-2 text-lg font-medium text-mineshaft-100">
|
||||||
Block Duplicate Secret Sync Destinations
|
Unique Secret Sync Destination Policy
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-mineshaft-400">
|
<p className="text-sm text-mineshaft-400">
|
||||||
When enabled, this setting prevents the creation of multiple sync configurations
|
When enabled, ensures each destination can only be used by one secret sync
|
||||||
pointing to the same destination.
|
configuration, preventing potential conflicts or overwrites.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Settings}>
|
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Settings}>
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
export { BlockDuplicateSecretSyncDestinationsSection } from "./BlockDuplicateSecretSyncDestinationsSection";
|
|
||||||
export { OrgProductSettingsTab } from "./OrgProductSettingsTab";
|
export { OrgProductSettingsTab } from "./OrgProductSettingsTab";
|
||||||
export { OrgTabGroup } from "./OrgTabGroup";
|
export { OrgTabGroup } from "./OrgTabGroup";
|
||||||
|
|||||||
Reference in New Issue
Block a user