improvements: final adjustments/improvements

This commit is contained in:
Scott Wilson
2025-01-21 20:21:29 -08:00
parent 3c1fc024c2
commit 99ca9e04f8
22 changed files with 255 additions and 155 deletions
@@ -5,7 +5,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
import { Button, FormControl, Switch } from "@app/components/v2";
import { Button, Checkbox, FormControl, Switch } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
import {
@@ -43,6 +43,7 @@ export const CreateSecretSyncForm = ({ destination, onComplete, onCancel }: Prop
const { name: destinationName } = SECRET_SYNC_MAP[destination];
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
const [confirmOverwrite, setConfirmOverwrite] = useState(false);
const { syncOption } = useSecretSyncOption(destination);
@@ -93,7 +94,7 @@ export const CreateSecretSyncForm = ({ destination, onComplete, onCancel }: Prop
setSelectedTabIndex((prev) => prev - 1);
};
const { handleSubmit, trigger } = formMethods;
const { handleSubmit, trigger, watch, control } = formMethods;
const isStepValid = async (index: number) => trigger(FORM_TABS[index].fields);
@@ -122,7 +123,7 @@ export const CreateSecretSyncForm = ({ destination, onComplete, onCancel }: Prop
return isEnabled;
};
const { control } = formMethods;
const initialSyncBehavior = watch("syncOptions.initialSyncBehavior");
return (
<form className={twMerge(isFinalStep && "max-h-[70vh] overflow-y-auto")}>
@@ -195,10 +196,33 @@ export const CreateSecretSyncForm = ({ destination, onComplete, onCancel }: Prop
</Tab.Panels>
</Tab.Group>
</FormProvider>
{isFinalStep &&
initialSyncBehavior === SecretSyncInitialSyncBehavior.OverwriteDestination && (
<Checkbox
id="confirm-overwrite"
isChecked={confirmOverwrite}
containerClassName="-mt-5"
onCheckedChange={(isChecked) => setConfirmOverwrite(Boolean(isChecked))}
>
<p className={`mt-5 text-wrap ${confirmOverwrite ? "text-mineshaft-200" : "text-red"}`}>
I understand all secrets present in the configured {destinationName} destination will
be removed that are not present within Infisical.
</p>
</Checkbox>
)}
<div className="flex w-full flex-row-reverse justify-between gap-4 pt-4">
<Button onClick={handleNext} colorSchema="secondary">
<Button
isDisabled={
isFinalStep &&
initialSyncBehavior === SecretSyncInitialSyncBehavior.OverwriteDestination &&
!confirmOverwrite
}
onClick={handleNext}
colorSchema="secondary"
>
{isFinalStep ? "Create Sync" : "Next"}
</Button>
{}
{selectedTabIndex > 0 && (
<Button onClick={handlePrev} colorSchema="secondary">
Back
@@ -35,12 +35,13 @@ export const EditSecretSyncForm = ({ secretSync, fields, onComplete }: Props) =>
reValidateMode: "onChange"
});
const onSubmit = async ({ environment, ...formData }: TSecretSyncForm) => {
const onSubmit = async ({ environment, connection, ...formData }: TSecretSyncForm) => {
try {
const updatedSecretSync = await updateSecretSync.mutateAsync({
syncId: secretSync.id,
...formData,
environment: environment?.slug
environment: environment?.slug,
connectionId: connection.id
});
createNotification({
@@ -2,7 +2,7 @@ import { Controller, useFormContext } from "react-hook-form";
import { faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { FormControl, Input, Select, SelectItem } from "@app/components/v2";
import { FormControl, Select, SelectItem } from "@app/components/v2";
import { SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP, SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
import { useSecretSyncOption } from "@app/hooks/api/secretSyncs";
@@ -91,7 +91,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
)}
</>
)}
<Controller
{/* <Controller
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error)}
@@ -118,7 +118,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
)}
control={control}
name="syncOptions.appendSuffix"
/>
/> */}
</>
);
};
@@ -21,7 +21,10 @@ export const SecretSyncReviewFields = () => {
connection,
environment,
secretPath,
syncOptions: { appendSuffix, prependPrefix, initialSyncBehavior },
syncOptions: {
// appendSuffix, prependPrefix,
initialSyncBehavior
},
destination,
isEnabled
} = watch();
@@ -72,8 +75,8 @@ export const SecretSyncReviewFields = () => {
<SecretSyncLabel label="Initial Sync Behavior">
{SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP[initialSyncBehavior](destinationName).name}
</SecretSyncLabel>
<SecretSyncLabel label="Prepend Prefix">{prependPrefix}</SecretSyncLabel>
<SecretSyncLabel label="Append Suffix">{appendSuffix}</SecretSyncLabel>
{/* <SecretSyncLabel label="Prepend Prefix">{prependPrefix}</SecretSyncLabel>
<SecretSyncLabel label="Append Suffix">{appendSuffix}</SecretSyncLabel> */}
</div>
</div>
<div className="flex flex-col gap-3">
@@ -13,17 +13,18 @@ const BaseSecretSyncSchema = z.object({
environment: z.object({ slug: z.string(), id: z.string(), name: z.string() }),
secretPath: z.string().min(1, "Secret path required"),
syncOptions: z.object({
initialSyncBehavior: z.nativeEnum(SecretSyncInitialSyncBehavior),
prependPrefix: z
.string()
.trim()
.transform((str) => str.toUpperCase())
.optional(),
appendSuffix: z
.string()
.trim()
.transform((str) => str.toUpperCase())
.optional()
initialSyncBehavior: z.nativeEnum(SecretSyncInitialSyncBehavior)
// scott: removed temporarily for evaluation of template formatting
// prependPrefix: z
// .string()
// .trim()
// .transform((str) => str.toUpperCase())
// .optional(),
// appendSuffix: z
// .string()
// .trim()
// .transform((str) => str.toUpperCase())
// .optional()
}),
isEnabled: z.boolean()
});
@@ -28,7 +28,7 @@ export type TCreateSecretSyncDTO = DiscriminativePick<
> & { environment: string; secretPath: string; projectId: string };
export type TUpdateSecretSyncDTO = Partial<
Omit<TCreateSecretSyncDTO, "connectionId" | "destination" | "projectId">
Omit<TCreateSecretSyncDTO, "destination" | "projectId">
> & {
destination: SecretSync;
syncId: string;
@@ -26,8 +26,8 @@ export type TRootSecretSync = {
lastRemoveMessage: string | null;
syncOptions: {
initialSyncBehavior: SecretSyncInitialSyncBehavior;
prependPrefix?: string;
appendSuffix?: string;
// prependPrefix?: string;
// appendSuffix?: string;
};
connection: {
app: AppConnection;
@@ -19,7 +19,7 @@ export const SecretSyncsTab = () => {
const { data: secretSyncs = [], isPending: isSecretSyncsPending } = useListSecretSyncs(
currentWorkspace.id,
{
refetchInterval: 2000
refetchInterval: 4000
}
);
@@ -66,7 +66,7 @@ const PageContent = () => {
const handleEditSource = () => handlePopUpOpen("editSync", SecretSyncEditFields.Source);
const handleEditOptions = () => handlePopUpOpen("editSync", SecretSyncEditFields.Options);
// const handleEditOptions = () => handlePopUpOpen("editSync", SecretSyncEditFields.Options);
const handleEditDestination = () => handlePopUpOpen("editSync", SecretSyncEditFields.Destination);
@@ -109,7 +109,10 @@ const PageContent = () => {
<div className="mr-4 flex w-72 flex-col gap-4">
<SecretSyncDetailsSection secretSync={secretSync} onEditDetails={handleEditDetails} />
<SecretSyncSourceSection secretSync={secretSync} onEditSource={handleEditSource} />
<SecretSyncOptionsSection secretSync={secretSync} onEditOptions={handleEditOptions} />
<SecretSyncOptionsSection
secretSync={secretSync}
// onEditOptions={handleEditOptions}
/>
</div>
<div className="flex flex-1 flex-col gap-4">
<SecretSyncDestinationSection
@@ -1,24 +1,23 @@
import { faEdit } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ProjectPermissionCan } from "@app/components/permissions";
import { SecretSyncLabel } from "@app/components/secret-syncs";
import { IconButton } from "@app/components/v2";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
import { SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP } from "@app/helpers/secretSyncs";
import { TSecretSync } from "@app/hooks/api/secretSyncs";
type Props = {
secretSync: TSecretSync;
onEditOptions: VoidFunction;
// onEditOptions: VoidFunction;
};
export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) => {
export const SecretSyncOptionsSection = ({
secretSync
// onEditOptions
}: Props) => {
const {
destination,
syncOptions: { appendSuffix, prependPrefix, initialSyncBehavior },
lastSyncedAt
syncOptions: {
// appendSuffix,
// prependPrefix,
initialSyncBehavior
}
} = secretSync;
return (
@@ -26,7 +25,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) =
<div className="flex w-full flex-col gap-3 rounded-lg border border-mineshaft-600 bg-mineshaft-900 px-4 py-3">
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-2">
<h3 className="font-semibold text-mineshaft-100">Sync Options</h3>
<ProjectPermissionCan
{/* <ProjectPermissionCan
I={ProjectPermissionSecretSyncActions.Edit}
a={ProjectPermissionSub.SecretSyncs}
>
@@ -41,17 +40,15 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) =
<FontAwesomeIcon icon={faEdit} />
</IconButton>
)}
</ProjectPermissionCan>
</ProjectPermissionCan> */}
</div>
<div>
<div className="space-y-3">
{!lastSyncedAt && (
<SecretSyncLabel label="Initial Sync Behavior">
{SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP[initialSyncBehavior](destination).name}
</SecretSyncLabel>
)}
<SecretSyncLabel label="Prefix">{prependPrefix}</SecretSyncLabel>
<SecretSyncLabel label="Suffix">{appendSuffix}</SecretSyncLabel>
<SecretSyncLabel label="Initial Sync Behavior">
{SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP[initialSyncBehavior](destination).name}
</SecretSyncLabel>
{/* <SecretSyncLabel label="Prefix">{prependPrefix}</SecretSyncLabel>
<SecretSyncLabel label="Suffix">{appendSuffix}</SecretSyncLabel> */}
</div>
</div>
</div>