diff --git a/airbyte-webapp/src/components/ConnectorBlocks/TableItemTitle.tsx b/airbyte-webapp/src/components/ConnectorBlocks/TableItemTitle.tsx index 01526606df24..82084d3cb0d9 100644 --- a/airbyte-webapp/src/components/ConnectorBlocks/TableItemTitle.tsx +++ b/airbyte-webapp/src/components/ConnectorBlocks/TableItemTitle.tsx @@ -7,6 +7,7 @@ import { Heading } from "components/ui/Heading"; import { Text } from "components/ui/Text"; import { ReleaseStage } from "core/request/AirbyteClient"; +import { getIcon } from "utils/imageUtils"; import { Button } from "../ui/Button"; import styles from "./TableItemTitle.module.scss"; @@ -17,7 +18,7 @@ interface TableItemTitleProps { onSelect: (data: DropdownMenuOptionType) => void; entity: string; entityName: string; - entityIcon?: React.ReactNode; + entityIcon?: string; releaseStage?: ReleaseStage; } @@ -35,7 +36,7 @@ const TableItemTitle: React.FC = ({ return ( <>
- {entityIcon &&
{entityIcon}
} + {entityIcon &&
{getIcon(entityIcon)}
}
{entityName} diff --git a/airbyte-webapp/src/core/domain/connection/WebBackendConnectionService.ts b/airbyte-webapp/src/core/domain/connection/WebBackendConnectionService.ts index bfd3f6c9b050..4aa576a11606 100644 --- a/airbyte-webapp/src/core/domain/connection/WebBackendConnectionService.ts +++ b/airbyte-webapp/src/core/domain/connection/WebBackendConnectionService.ts @@ -1,5 +1,6 @@ import { WebBackendConnectionCreate, + WebBackendConnectionListRequestBody, WebBackendConnectionUpdate, webBackendCreateConnection, webBackendGetConnection, @@ -13,8 +14,8 @@ export class WebBackendConnectionService extends AirbyteRequestService { return webBackendGetConnection({ connectionId, withRefreshedCatalog }, this.requestOptions); } - public list(workspaceId: string) { - return webBackendListConnectionsForWorkspace({ workspaceId }, this.requestOptions); + public list(payload: WebBackendConnectionListRequestBody) { + return webBackendListConnectionsForWorkspace(payload, this.requestOptions); } public update(payload: WebBackendConnectionUpdate) { diff --git a/airbyte-webapp/src/hooks/services/useConnectionHook.tsx b/airbyte-webapp/src/hooks/services/useConnectionHook.tsx index 838da75b5f31..c5d38b3f61fc 100644 --- a/airbyte-webapp/src/hooks/services/useConnectionHook.tsx +++ b/airbyte-webapp/src/hooks/services/useConnectionHook.tsx @@ -19,6 +19,7 @@ import { SourceDefinitionRead, SourceRead, WebBackendConnectionListItem, + WebBackendConnectionListRequestBody, WebBackendConnectionRead, WebBackendConnectionReadList, WebBackendConnectionUpdate, @@ -31,8 +32,7 @@ import { useCurrentWorkspace } from "./useWorkspace"; export const connectionsKeys = { all: [SCOPE_WORKSPACE, "connections"] as const, - lists: () => [...connectionsKeys.all, "list"] as const, - list: (filters: string) => [...connectionsKeys.lists(), { filters }] as const, + lists: (sourceOrDestinationIds: string[] = []) => [...connectionsKeys.all, "list", ...sourceOrDestinationIds], detail: (connectionId: string) => [...connectionsKeys.all, "details", connectionId] as const, getState: (connectionId: string) => [...connectionsKeys.all, "getState", connectionId] as const, }; @@ -236,11 +236,13 @@ export const useRemoveConnectionsFromList = (): ((connectionIds: string[]) => vo ); }; -const useConnectionList = () => { +const useConnectionList = (payload: Pick = {}) => { const workspace = useCurrentWorkspace(); const service = useWebConnectionService(); - return useSuspenseQuery(connectionsKeys.lists(), () => service.list(workspace.workspaceId)); + return useSuspenseQuery(connectionsKeys.lists(payload.destinationId ?? payload.sourceId), () => + service.list({ ...payload, workspaceId: workspace.workspaceId }) + ); }; const useGetConnectionState = (connectionId: string) => { diff --git a/airbyte-webapp/src/pages/SourcesPage/pages/SourceItemPage/SourceItemPage.tsx b/airbyte-webapp/src/pages/SourcesPage/pages/SourceItemPage/SourceItemPage.tsx index ef0ccd18a6a6..43cb982bcb2b 100644 --- a/airbyte-webapp/src/pages/SourcesPage/pages/SourceItemPage/SourceItemPage.tsx +++ b/airbyte-webapp/src/pages/SourcesPage/pages/SourceItemPage/SourceItemPage.tsx @@ -13,14 +13,12 @@ import { PageHeader } from "components/ui/PageHeader"; import { useTrackPage, PageTrackingCodes } from "hooks/services/Analytics"; import { useConnectionList } from "hooks/services/useConnectionHook"; +import { useDestinationList } from "hooks/services/useDestinationHook"; import { useGetSource } from "hooks/services/useSourceHook"; -import { useDestinationDefinitionList } from "services/connector/DestinationDefinitionService"; import { useSourceDefinition } from "services/connector/SourceDefinitionService"; -import { getIcon } from "utils/imageUtils"; import { ConnectorDocumentationWrapper } from "views/Connector/ConnectorDocumentationLayout"; import { DropdownMenuOptionType } from "../../../../components/ui/DropdownMenu"; -import { useDestinationList } from "../../../../hooks/services/useDestinationHook"; import { RoutePaths } from "../../../routePaths"; import SourceConnectionTable from "./components/SourceConnectionTable"; import SourceSettings from "./components/SourceSettings"; @@ -35,14 +33,11 @@ const SourceItemPage: React.FC = () => { [params] ); - const { destinations } = useDestinationList(); - - const { destinationDefinitions } = useDestinationDefinitionList(); - const source = useGetSource(params.id || ""); - const sourceDefinition = useSourceDefinition(source?.sourceDefinitionId); + const sourceDefinition = useSourceDefinition(source.sourceDefinitionId); - const { connections } = useConnectionList(); + // We load only connections attached to this source to be shown in the connections grid + const { connections } = useConnectionList({ sourceId: [source.sourceId] }); const breadcrumbsData = [ { @@ -52,23 +47,20 @@ const SourceItemPage: React.FC = () => { { label: source.name }, ]; - const connectionsWithSource = connections.filter(({ source: { sourceId } }) => sourceId === source.sourceId); - + // We load all destinations so the add destination button has a pre-filled list of options. + const { destinations } = useDestinationList(); const destinationDropdownOptions: DropdownMenuOptionType[] = useMemo( () => - destinations.map((item) => { - const destinationDef = destinationDefinitions.find( - (dd) => dd.destinationDefinitionId === item.destinationDefinitionId - ); + destinations.map((destination) => { return { as: "button", - icon: , + icon: , iconPosition: "right", - displayName: item.name, - value: item.destinationId, + displayName: destination.name, + value: destination.destinationId, }; }), - [destinations, destinationDefinitions] + [destinations] ); const onSelectStep = (id: string) => { @@ -102,7 +94,7 @@ const SourceItemPage: React.FC = () => { } + element={} /> { onSelect={onSelect} entity={source.sourceName} entityName={source.name} - entityIcon={sourceDefinition ? getIcon(sourceDefinition.icon) : null} + entityIcon={source.icon} releaseStage={sourceDefinition.releaseStage} /> - {connectionsWithSource.length ? ( - + {connections.length ? ( + ) : ( )} diff --git a/airbyte-webapp/src/pages/destination/DestinationOverviewPage.tsx b/airbyte-webapp/src/pages/destination/DestinationOverviewPage.tsx index 31cedd071c00..1996af562bb6 100644 --- a/airbyte-webapp/src/pages/destination/DestinationOverviewPage.tsx +++ b/airbyte-webapp/src/pages/destination/DestinationOverviewPage.tsx @@ -12,35 +12,30 @@ import { useGetDestination } from "hooks/services/useDestinationHook"; import { useSourceList } from "hooks/services/useSourceHook"; import { DestinationPaths } from "pages/routePaths"; import { useDestinationDefinition } from "services/connector/DestinationDefinitionService"; -import { useSourceDefinitionList } from "services/connector/SourceDefinitionService"; -import { getIcon } from "utils/imageUtils"; export const DestinationOverviewPage = () => { const params = useParams() as { "*": StepsTypes | ""; id: string }; - const { sources } = useSourceList(); const navigate = useNavigate(); + const destination = useGetDestination(params.id); const destinationDefinition = useDestinationDefinition(destination.destinationDefinitionId); - const { connections } = useConnectionList(); - const { sourceDefinitions } = useSourceDefinitionList(); + // We load only connections attached to this destination to be shown in the connections grid + const { connections } = useConnectionList({ destinationId: [destination.destinationId] }); - const connectionsWithDestination = connections.filter( - ({ destination: { destinationId } }) => destinationId === destination.destinationId - ); - - const sourceDropdownOptions: DropdownMenuOptionType[] = useMemo( + // We load all sources so the add source button has a pre-filled list of options. + const { sources } = useSourceList(); + const sourceDropdownOptions = useMemo( () => - sources.map((item) => { - const sourceDef = sourceDefinitions.find((sd) => sd.sourceDefinitionId === item.sourceDefinitionId); + sources.map((source) => { return { as: "button", - icon: , + icon: , iconPosition: "right", - displayName: item.name, - value: item.sourceId, + displayName: source.name, + value: source.sourceId, }; }), - [sources, sourceDefinitions] + [sources] ); const onSelect = (data: DropdownMenuOptionType) => { @@ -64,11 +59,11 @@ export const DestinationOverviewPage = () => { onSelect={onSelect} entityName={destination.name} entity={destination.destinationName} - entityIcon={destinationDefinition.icon ? getIcon(destinationDefinition.icon) : null} + entityIcon={destination.icon} releaseStage={destinationDefinition.releaseStage} /> - {connectionsWithDestination.length ? ( - + {connections.length ? ( + ) : ( )}