Skip to content

Commit

Permalink
NEOS-14978: add check to skip setting transformer in apply default tr…
Browse files Browse the repository at this point in the history
…ansformer if… (#2766)
  • Loading branch information
evisdrenova authored Oct 2, 2024
1 parent 76f2889 commit 2c493eb
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 48 deletions.
7 changes: 6 additions & 1 deletion frontend/apps/web/components/ConfirmationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ export interface Props {
trigger?: ReactNode;
headerText?: string;
description?: string;
body?: JSX.Element;
buttonText?: string;
buttonVariant?: ButtonProps['variant'] | null | undefined;
buttonIcon?: ReactNode;
containerClassName?: string;
onConfirm(): void | Promise<void>;
}

Expand All @@ -30,9 +32,11 @@ export default function ConfirmationDialog(props: Props): ReactElement {
trigger = <Button type="button">Press to Confirm</Button>,
headerText = 'Are you sure?',
description = 'This will confirm the action that you selected.',
body,
buttonText = 'Confirm',
buttonVariant,
buttonIcon,
containerClassName,
onConfirm,
} = props;
const [open, setOpen] = useState(false);
Expand All @@ -53,13 +57,14 @@ export default function ConfirmationDialog(props: Props): ReactElement {
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogContent className={cn(containerClassName)}>
<AlertDialogHeader className="gap-2">
<AlertDialogTitle className="text-xl">{headerText}</AlertDialogTitle>
<AlertDialogDescription className="tracking-tight">
{description}
</AlertDialogDescription>
</AlertDialogHeader>
<div className="pt-6">{body}</div>
<AlertDialogFooter className="w-full flex sm:justify-between mt-4">
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
Expand Down
137 changes: 97 additions & 40 deletions frontend/apps/web/components/jobs/SchemaTable/SchemaTableToolBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ import EditTransformerOptions from '@/app/(mgmt)/[account]/transformers/EditTran
import ButtonText from '@/components/ButtonText';
import ConfirmationDialog from '@/components/ConfirmationDialog';
import FormErrorMessage from '@/components/FormErrorMessage';
import SwitchCard from '@/components/switches/SwitchCard';
import { Button } from '@/components/ui/button';
import {
Form,
FormControl,
FormField,
FormItem,
FormMessage,
} from '@/components/ui/form';
import { cn } from '@/libs/utils';
import { isSystemTransformer, Transformer } from '@/shared/transformers';
import {
Expand All @@ -17,9 +25,11 @@ import {
} from '@/util/util';
import {
convertJobMappingTransformerToForm,
DefaultTransformerFormValues,
JobMappingTransformerForm,
SchemaFormValues,
} from '@/yup-validations/jobs';
import { yupResolver } from '@hookform/resolvers/yup';
import {
GenerateDefault,
JobMappingTransformer,
Expand All @@ -31,7 +41,7 @@ import {
} from '@neosync/sdk';
import { CheckIcon, Cross2Icon } from '@radix-ui/react-icons';
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { useForm, useFormContext } from 'react-hook-form';
import { fromRowDataToColKey, getTransformerFilter } from './SchemaColumns';
import { Row as RowData } from './SchemaPageTable';
import { SchemaTableViewOptions } from './SchemaTableViewOptions';
Expand Down Expand Up @@ -82,6 +92,41 @@ export function SchemaTableToolbar<TData>({
!hasSelectedRows ||
!isTransformerAllowed(allowedTransformers, transformer);

const defaultTransformerForm = useForm<DefaultTransformerFormValues>({
resolver: yupResolver(DefaultTransformerFormValues),
defaultValues: {
overrideTransformers: false,
},
});

const handleAlertDescriptionBody = (): JSX.Element => {
return (
<div>
<Form {...form}>
<form className="space-y-8">
<FormField
control={defaultTransformerForm.control}
name="overrideTransformers"
render={({ field }) => (
<FormItem>
<FormControl>
<SwitchCard
isChecked={field.value}
onCheckedChange={field.onChange}
title="Override Mapped Transformers"
description="Do you want to overwrite the Transformers you have already mapped."
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>
</div>
);
};

return (
<div className="flex flex-col items-start w-full gap-2">
<div className="flex flex-col md:flex-row justify-between pb-2 md:items-center w-full gap-3">
Expand Down Expand Up @@ -172,49 +217,61 @@ export function SchemaTableToolbar<TData>({
</Button>
}
headerText="Apply Default Transformers?"
description="This setting will apply the 'Passthrough' Transformer to every column that is not Generated, while applying the 'Use Column Default' Transformer to all Generated (non-Identity) columns."
buttonText="Apply"
description="This setting will apply the 'Passthrough' Transformer to every column that is not Generated, while applying the 'Use Column Default' Transformer to all Generated (non-Identity)columns."
body={handleAlertDescriptionBody()}
containerClassName="max-w-xl"
onConfirm={() => {
const formMappings = form.getValues('mappings');
const defaultTransformerValues =
defaultTransformerForm.getValues();
formMappings.forEach((fm, idx) => {
const colkey = {
schema: fm.schema,
table: fm.table,
column: fm.column,
};
const isGenerated = constraintHandler.getIsGenerated(colkey);
const identityType =
constraintHandler.getIdentityType(colkey);
const newJm =
isGenerated && !identityType
? new JobMappingTransformer({
source: TransformerSource.GENERATE_DEFAULT,
config: new TransformerConfig({
config: {
case: 'generateDefaultConfig',
value: new GenerateDefault(),
},
}),
})
: new JobMappingTransformer({
source: TransformerSource.PASSTHROUGH,
config: new TransformerConfig({
config: {
case: 'passthroughConfig',
value: new Passthrough(),
},
}),
});
// skips setting the default transformer if the user has already set the transformer
if (
fm.transformer.source != 0 &&
!defaultTransformerValues.overrideTransformers
) {
return;
} else {
const colkey = {
schema: fm.schema,
table: fm.table,
column: fm.column,
};
const isGenerated =
constraintHandler.getIsGenerated(colkey);
const identityType =
constraintHandler.getIdentityType(colkey);
const newJm =
isGenerated && !identityType
? new JobMappingTransformer({
source: TransformerSource.GENERATE_DEFAULT,
config: new TransformerConfig({
config: {
case: 'generateDefaultConfig',
value: new GenerateDefault(),
},
}),
})
: new JobMappingTransformer({
source: TransformerSource.PASSTHROUGH,
config: new TransformerConfig({
config: {
case: 'passthroughConfig',
value: new Passthrough(),
},
}),
});

form.setValue(
`mappings.${idx}.transformer`,
convertJobMappingTransformerToForm(newJm),
{
shouldDirty: true,
shouldTouch: true,
shouldValidate: false,
}
);
form.setValue(
`mappings.${idx}.transformer`,
convertJobMappingTransformerToForm(newJm),
{
shouldDirty: true,
shouldTouch: true,
shouldValidate: false,
}
);
}
});
form.trigger('mappings'); // trigger validation after bulk updating the selected form options
}}
Expand Down
27 changes: 22 additions & 5 deletions frontend/apps/web/components/switches/SwitchCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { cn } from '@/libs/utils';
import { ReactElement } from 'react';

interface Props {
Expand All @@ -8,17 +9,33 @@ interface Props {
title: string;
// provide a component that will show up to the right of the title
postTitle?: ReactElement;

description?: string;
containerClassName?: string;
titleClassName?: string;
}

export default function SwitchCard(props: Props): ReactElement {
const { isChecked, onCheckedChange, title, description, postTitle } = props;
export default function SwitchCard({
isChecked,
onCheckedChange,
title,
description,
postTitle,
containerClassName,
titleClassName,
}: Props): ReactElement {
return (
<div className="flex flex-row items-center justify-between rounded-lg border p-4 dark:border dark:border-gray-700 shadow-sm">
<div
className={cn(
'flex flex-row items-center justify-between rounded-lg border p-4 shadow-sm',
'dark:border-gray-700',
containerClassName
)}
>
<div className="space-y-0.5">
<div className="flex flex-col md:flex-row gap-2 items-center">
<Label className="text-sm">{title}</Label>
<Label className={cn('text-sm font-medium', titleClassName)}>
{title}
</Label>
{postTitle}
</div>
{description && (
Expand Down
3 changes: 1 addition & 2 deletions frontend/apps/web/components/ui/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ const alertVariants = cva(
'bg-background text-foreground bg-green-100 dark:bg-green-800 border border-green-300 dark:border-green-400',
destructive:
'border-destructive/50 dark:border-destructive bg-destructive text-destructive-foreground',
warning:
'border border-yellow-300 shadow-sm bg-yellow-50 dark:bg-yellow-800 dark:border-yellow-700',
warning: 'border border-yellow-300 dark:border-orange-500 ',
info: 'border border-blue-300 shadow-sm bg-blue-50 dark:bg-gray-800 dark:border-gray-700',
},
},
Expand Down
8 changes: 8 additions & 0 deletions frontend/apps/web/yup-validations/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,11 @@ export const DataSyncSourceFormValues = SourceFormValues.concat(
export type DataSyncSourceFormValues = Yup.InferType<
typeof DataSyncSourceFormValues
>;

export const DefaultTransformerFormValues = Yup.object({
overrideTransformers: Yup.boolean().default(false),
});

export type DefaultTransformerFormValues = Yup.InferType<
typeof DefaultTransformerFormValues
>;

0 comments on commit 2c493eb

Please sign in to comment.