Address PR comments

This commit is contained in:
Carlos Monastyrski
2025-10-27 18:57:28 -03:00
parent 54755f2d25
commit 97a01bdcb4
8 changed files with 37 additions and 95 deletions
@@ -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 && (
@@ -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}
/> />
</> </>
); );
@@ -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 && (
@@ -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 +0,0 @@
export { BlockDuplicateSecretSyncDestinationsSection } from "./BlockDuplicateSecretSyncDestinationsSection";
@@ -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";