mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 22:29:11 +03:00
* add dummy sinks and pipelines pages * update api types * show empty sources state * show empty replication state at /replication * create source when enable replication button is clicked * improve replication page when replication is enabled * replace sources page with publications page * publications table * show publications in table * create publication wip * show toast error instead of throwing an exception * user can now delete a publication * show empty sinks page * create and list sinks * add ui to delete a sink * show pipelines on the pipelines page * add ui to create and delete pipelines * get pipeline status wip * show pipeline status wip * show correct label on action buttons * start and stop pipelines * remove a couple of console.logs * fix error when deleting a pipeline * only consider replication enabled when a source with name = ref is present * add source and sink names * correct colspan for 'no pipelines' row * hide 'supabase_realtime' publication on ui * move filtering to fetch query * show sink name in ui * show source/sink names on pipelines page * fix start/stop status shown on ui * fix prettier formatting * update api types * extract pipeline action button as a separate component * fix a crashing page * fixed publications page crash * update to match with changes in api * add new replication page under database * hide replication page behind feature flag * update types * update api types * show destinations empty state * add destinations table * factor out components from Destinations table * show status dot * move pipeline fetch query to parent component * add ability to enable/disable a pipeline * show loader when starting or stopping a pipeline * fix a bug in which loading & empty states were shown together * fix a bug in which error & empty states were shown together * wrap in default layout * add new destination panel * add type field * fix a forwardRef error * fix layout * create destination * delete destination * add ability to create or delete destinations with pipelines * create source if missing * show only a single error * add an enable switch * new layout * add subsections * comment out unused code * show enabled switch only in the header * close panel when destination is created * disable buttons when api requests in flight * reduce panel size * remove commented out code * treat max size and max fill secs as numbers * use drop down to show publications * simpler vertical layout * add separators * add form validation * remove publications drop down padding * add new publication button * hide advanced settings behind an accordion * add some margin between icon and text * show publications panel on clicking new publication button * add header to new publication panel * fix validation not running for publication drop down * create publication in the new publication panel * add table selector in new publication panel * update api types * remove old code * update platform.d.ts * update navigation bar utils * remove a redirect from replication page to publications page * ask user for confirmation before deleting destination * edit destination panel * edit destination panel values fixed * bug fixes * fix prettier formatting * enable/disable pipeline after editing * rename snake_case params to camelCase * loading button when editing * remove merge markers * update api types * add max_staleness parameter in sinks for bigquery * add read replicas flow diagram to replication page * remove an unused import * Revert "add read replicas flow diagram to replication page" This reverts commit 8852d7847b457885603dba786141a8aaf8e99350. * add panel to warn users about additional cost before creating a destination * hide replication page contents behind a feature flag * fix merge conflicts * styling changes * revert static flag * styling updates * fixes * fix switch * copy * fix layout --------- Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
180 lines
6.1 KiB
TypeScript
180 lines
6.1 KiB
TypeScript
import { zodResolver } from '@hookform/resolvers/zod'
|
|
import { useParams } from 'common'
|
|
import { useCreatePublicationMutation } from 'data/replication/create-publication-mutation'
|
|
import { useReplicationTablesQuery } from 'data/replication/tables-query'
|
|
import { X } from 'lucide-react'
|
|
import { useForm } from 'react-hook-form'
|
|
import { toast } from 'sonner'
|
|
import {
|
|
Sheet,
|
|
SheetContent,
|
|
SheetHeader,
|
|
SheetTitle,
|
|
SheetClose,
|
|
cn,
|
|
Button,
|
|
SheetFooter,
|
|
SheetSection,
|
|
Form_Shadcn_,
|
|
FormLabel_Shadcn_,
|
|
FormField_Shadcn_,
|
|
FormItem_Shadcn_,
|
|
FormControl_Shadcn_,
|
|
Input_Shadcn_,
|
|
FormMessage_Shadcn_,
|
|
Card,
|
|
CardContent,
|
|
SheetDescription,
|
|
} from 'ui'
|
|
import { MultiSelector } from 'ui-patterns/multi-select'
|
|
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
|
import { z } from 'zod'
|
|
|
|
interface NewPublicationPanelProps {
|
|
visible: boolean
|
|
sourceId?: number
|
|
onClose: () => void
|
|
}
|
|
|
|
const NewPublicationPanel = ({ visible, sourceId, onClose }: NewPublicationPanelProps) => {
|
|
const { ref: projectRef } = useParams()
|
|
const { mutateAsync: createPublication, isLoading: creatingPublication } =
|
|
useCreatePublicationMutation()
|
|
const { data: tables } = useReplicationTablesQuery({
|
|
projectRef,
|
|
sourceId,
|
|
})
|
|
const formId = 'publication-editor'
|
|
const FormSchema = z.object({
|
|
name: z.string().min(1, 'Name is required'),
|
|
tables: z.array(z.string()).min(1, 'At least one table is required'),
|
|
})
|
|
const defaultValues = {
|
|
name: '',
|
|
tables: [],
|
|
}
|
|
const form = useForm<z.infer<typeof FormSchema>>({
|
|
mode: 'onBlur',
|
|
reValidateMode: 'onBlur',
|
|
resolver: zodResolver(FormSchema),
|
|
defaultValues,
|
|
})
|
|
|
|
const onSubmit = async (data: z.infer<typeof FormSchema>) => {
|
|
if (!projectRef) return console.error('Project ref is required')
|
|
if (!sourceId) return console.error('Source id is required')
|
|
try {
|
|
await createPublication({
|
|
projectRef,
|
|
sourceId,
|
|
name: data.name,
|
|
tables: data.tables.map((table) => {
|
|
const [schema, name] = table.split('.')
|
|
return { schema, name }
|
|
}),
|
|
})
|
|
toast.success('Successfully created publication')
|
|
onClose()
|
|
} catch (error) {
|
|
toast.error('Failed to create publication')
|
|
}
|
|
form.reset(defaultValues)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Sheet open={visible} onOpenChange={onClose}>
|
|
<SheetContent showClose={false} size="default">
|
|
<div className="flex flex-col h-full">
|
|
<SheetHeader>
|
|
<div className="flex flex-row justify-between items-center">
|
|
<div>
|
|
<SheetTitle>New Publication</SheetTitle>
|
|
<SheetDescription>
|
|
Create a new publication to share table changes for replication
|
|
</SheetDescription>
|
|
</div>
|
|
<SheetClose
|
|
className={cn(
|
|
'text-muted hover:opacity-100',
|
|
'focus:outline-none focus:ring-2',
|
|
'disabled:pointer-events-none'
|
|
)}
|
|
>
|
|
<X className="h-3 w-3" />
|
|
<span className="sr-only">Close</span>
|
|
</SheetClose>
|
|
</div>
|
|
</SheetHeader>
|
|
<SheetSection className="flex-grow overflow-auto">
|
|
<Form_Shadcn_ {...form}>
|
|
<form
|
|
id={formId}
|
|
onSubmit={form.handleSubmit(onSubmit)}
|
|
className="flex flex-col gap-y-4"
|
|
>
|
|
<FormField_Shadcn_
|
|
control={form.control}
|
|
name="name"
|
|
render={({ field }) => (
|
|
<FormItemLayout label="Name" layout="vertical">
|
|
<FormControl_Shadcn_>
|
|
<Input_Shadcn_ {...field} placeholder="Name" />
|
|
</FormControl_Shadcn_>
|
|
</FormItemLayout>
|
|
)}
|
|
/>
|
|
<FormField_Shadcn_
|
|
control={form.control}
|
|
name="tables"
|
|
render={({ field }) => (
|
|
<FormItemLayout
|
|
label="Tables"
|
|
description="Which tables to make available for replication"
|
|
>
|
|
<FormControl_Shadcn_>
|
|
<MultiSelector
|
|
values={field.value}
|
|
onValuesChange={field.onChange}
|
|
disabled={creatingPublication}
|
|
>
|
|
<MultiSelector.Trigger>
|
|
<MultiSelector.Input placeholder="Select tables" />
|
|
</MultiSelector.Trigger>
|
|
<MultiSelector.Content>
|
|
<MultiSelector.List>
|
|
{tables?.tables.map((table) => (
|
|
<MultiSelector.Item
|
|
key={`${table.schema}.${table.name}`}
|
|
value={`${table.schema}.${table.name}`}
|
|
>
|
|
{`${table.schema}.${table.name}`}
|
|
</MultiSelector.Item>
|
|
))}
|
|
</MultiSelector.List>
|
|
</MultiSelector.Content>
|
|
</MultiSelector>
|
|
</FormControl_Shadcn_>
|
|
</FormItemLayout>
|
|
)}
|
|
/>
|
|
</form>
|
|
</Form_Shadcn_>
|
|
</SheetSection>
|
|
<SheetFooter>
|
|
<Button type="default" disabled={creatingPublication} onClick={onClose}>
|
|
Cancel
|
|
</Button>
|
|
<Button type="primary" disabled={creatingPublication} form={formId} htmlType="submit">
|
|
Create publication
|
|
</Button>
|
|
</SheetFooter>
|
|
</div>
|
|
</SheetContent>
|
|
</Sheet>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default NewPublicationPanel
|