diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel.tsx index 36b0407e88..10c152d69e 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel.tsx @@ -21,6 +21,7 @@ import { AccordionItem_Shadcn_, AccordionTrigger_Shadcn_, Button, + DialogSectionSeparator, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_, @@ -30,7 +31,6 @@ import { SelectGroup_Shadcn_, SelectItem_Shadcn_, SelectTrigger_Shadcn_, - Separator, Sheet, SheetContent, SheetDescription, @@ -40,6 +40,7 @@ import { SheetTitle, TextArea_Shadcn_, } from 'ui' +import { Admonition } from 'ui-patterns' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import NewPublicationPanel from './NewPublicationPanel' import PublicationsComboBox from './PublicationsComboBox' @@ -96,10 +97,12 @@ export const DestinationPanel = ({ const { mutateAsync: startPipeline, isLoading: startingPipeline } = useStartPipelineMutation() - const { data: publications, isLoading: loadingPublications } = useReplicationPublicationsQuery({ - projectRef, - sourceId, - }) + const { + data: publications = [], + isLoading: isLoadingPublications, + isSuccess: isSuccessPublications, + refetch: refetchPublications, + } = useReplicationPublicationsQuery({ projectRef, sourceId }) const { data: destinationData } = useReplicationDestinationByIdQuery({ projectRef, @@ -132,11 +135,21 @@ export const DestinationPanel = ({ resolver: zodResolver(FormSchema), defaultValues, }) + const publicationName = form.watch('publicationName') const isSaving = creatingDestinationPipeline || updatingDestinationPipeline || startingPipeline + const publicationNames = useMemo(() => publications?.map((pub) => pub.name) ?? [], [publications]) + const isSelectedPublicationMissing = + isSuccessPublications && !!publicationName && !publicationNames.includes(publicationName) + + const isSubmitDisabled = isSaving || isSelectedPublicationMissing + const onSubmit = async (data: z.infer) => { if (!projectRef) return console.error('Project ref is required') if (!sourceId) return console.error('Source id is required') + if (isSelectedPublicationMissing) { + return toast.error('Please select another publication before continuing') + } try { if (editMode && existingDestination) { @@ -236,6 +249,12 @@ export const DestinationPanel = ({ } }, [visible, defaultValues, form]) + useEffect(() => { + if (visible && projectRef && sourceId) { + refetchPublications() + } + }, [visible, projectRef, sourceId, refetchPublications]) + return ( <> @@ -247,59 +266,72 @@ export const DestinationPanel = ({ {editMode ? null : 'Send data to a new destination'} - + +
-
- ( - - - - - - )} - /> + ( + + + + + + )} + /> -

What data to send

+ +
+

What data to send

( pub.name) || []} - loading={loadingPublications} + publications={publicationNames} + loading={isLoadingPublications} field={field} onNewPublicationClick={() => setPublicationPanelVisible(true)} /> + {isSelectedPublicationMissing && ( + +

+ The publication{' '} + {publicationName} was + not found, it may have been renamed or deleted, please select + another one. +

+
+ )}
)} /> +
-

Where to send that data

+ +
+

Where to send that data

( ( ( - + @@ -373,7 +400,7 @@ export const DestinationPanel = ({ />
- +
@@ -443,7 +470,12 @@ export const DestinationPanel = ({ -