Files
supabase/apps/studio/components/interfaces/Database/Replication/Destinations.tsx
2025-05-26 21:30:10 +05:30

139 lines
4.6 KiB
TypeScript

import { useParams } from 'common'
import Table from 'components/to-be-cleaned/Table'
import AlertError from 'components/ui/AlertError'
import { useReplicationDestinationsQuery } from 'data/replication/destinations-query'
import { Plus } from 'lucide-react'
import { Button, cn } from 'ui'
import { GenericSkeletonLoader } from 'ui-patterns'
import DestinationRow from './DestinationRow'
import { useReplicationPipelinesQuery } from 'data/replication/pipelines-query'
import { useState } from 'react'
import NewDestinationPanel from './DestinationPanel'
import { useReplicationSourcesQuery } from 'data/replication/sources-query'
import { ScaffoldSection, ScaffoldSectionTitle } from 'components/layouts/Scaffold'
const Destinations = () => {
const [showNewDestinationPanel, setShowNewDestinationPanel] = useState(false)
const { ref: projectRef } = useParams()
const {
data: sourcesData,
error: sourcesError,
isLoading: isSourcesLoading,
isError: isSourcesError,
isSuccess: isSourcesSuccess,
} = useReplicationSourcesQuery({
projectRef,
})
let sourceId = sourcesData?.sources.find((s) => s.name === projectRef)?.id
const {
data: destinationsData,
error: destinationsError,
isLoading: isDestinationsLoading,
isError: isDestinationsError,
isSuccess: isDestinationsSuccess,
} = useReplicationDestinationsQuery({
projectRef,
})
const {
data: pipelinesData,
error: pipelinesError,
isLoading: isPipelinesLoading,
isError: isPipelinesError,
isSuccess: isPipelinesSuccess,
} = useReplicationPipelinesQuery({
projectRef,
})
const anyDestinations = isDestinationsSuccess && destinationsData.destinations.length > 0
return (
<>
<ScaffoldSection isFullWidth>
<div className="flex justify-between items-center mb-4">
<ScaffoldSectionTitle>Destinations</ScaffoldSectionTitle>
<Button type="default" icon={<Plus />} onClick={() => setShowNewDestinationPanel(true)}>
Add destination
</Button>
</div>
{(isSourcesLoading || isDestinationsLoading) && <GenericSkeletonLoader />}
{(isSourcesError || isDestinationsError) && (
<AlertError
error={sourcesError || destinationsError}
subject="Failed to retrieve destinations"
/>
)}
{anyDestinations ? (
<Table
head={[
<Table.th key="name">Name</Table.th>,
<Table.th key="type">Type</Table.th>,
<Table.th key="status">Status</Table.th>,
<Table.th key="publication">Publication</Table.th>,
<Table.th key="actions"></Table.th>,
]}
body={destinationsData.destinations.map((destination) => {
const pipeline = pipelinesData?.pipelines.find(
(p) => p.destination_id === destination.id
)
return (
<DestinationRow
key={destination.id}
sourceId={sourceId}
destinationId={destination.id}
destinationName={destination.name}
type={destination.config.big_query ? 'BigQuery' : 'Other'}
pipeline={pipeline}
error={pipelinesError}
isLoading={isPipelinesLoading}
isError={isPipelinesError}
isSuccess={isPipelinesSuccess}
></DestinationRow>
)
})}
></Table>
) : (
!isSourcesLoading &&
!isDestinationsLoading &&
!isSourcesError &&
!isDestinationsError && (
<div
className={cn(
'w-full',
'border border-dashed bg-surface-100 border-overlay',
'flex flex-col px-10 rounded-lg justify-center items-center py-8 mt-4'
)}
>
<h4 className="text-lg">Send data to your first destination</h4>
<p className="prose text-sm text-center mt-2">
Use destinations to improve performance or run analysis on your data via
integrations like BigQuery
</p>
<Button
icon={<Plus />}
onClick={() => setShowNewDestinationPanel(true)}
className="mt-6"
>
Add destination
</Button>
</div>
)
)}
</ScaffoldSection>
<NewDestinationPanel
visible={showNewDestinationPanel}
sourceId={sourceId}
onClose={() => setShowNewDestinationPanel(false)}
></NewDestinationPanel>
</>
)
}
export default Destinations