import * as React from 'react'; import { useQuery, useLazyQuery } from '@apollo/client'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; import Collapse from '@mui/material/Collapse'; import ListItem from '@mui/material/ListItem'; import Autocomplete from '@mui/material/Autocomplete'; import { EditorContext } from 'contexts/Editor'; import FlowSubstepTitle from 'components/FlowSubstepTitle'; import type { IApp, IConnection, IStep, ISubstep } from '@automatisch/types'; import { GET_APP_CONNECTIONS } from 'graphql/queries/get-app-connections'; import { TEST_CONNECTION } from 'graphql/queries/test-connection'; type ChooseConnectionSubstepProps = { substep: ISubstep, expanded?: boolean; onExpand: () => void; onCollapse: () => void; onChange: ({ step }: { step: IStep }) => void; onSubmit: () => void; step: IStep; }; const optionGenerator = (connection: IConnection): { label: string; value: string; } => ({ label: connection?.formattedData?.screenName as string ?? 'Unnamed', value: connection?.id as string, }); const getOption = (options: Record[], connectionId?: string) => options.find(connection => connection.value === connectionId) || null; function ChooseConnectionSubstep(props: ChooseConnectionSubstepProps): React.ReactElement { const { substep, expanded = false, onExpand, onCollapse, step, onSubmit, onChange, } = props; const { connection, appKey, } = step; const editorContext = React.useContext(EditorContext); const { data, loading } = useQuery(GET_APP_CONNECTIONS, { variables: { key: appKey }}); // TODO: show detailed error when connection test/verification fails const [ testConnection, { loading: testResultLoading, refetch: retestConnection } ] = useLazyQuery( TEST_CONNECTION, { variables: { id: connection?.id, } } ); React.useEffect(() => { if (connection?.id) { testConnection({ variables: { id: connection.id, } }); } // intentionally no dependencies for initial test }, []); const connectionOptions = React.useMemo(() => (data?.getApp as IApp)?.connections?.map((connection) => optionGenerator(connection)) || [], [data]); const { name } = substep; const handleChange = React.useCallback((event: React.SyntheticEvent, selectedOption: unknown) => { if (typeof selectedOption === 'object') { // TODO: try to simplify type casting below. const typedSelectedOption = selectedOption as { value: string }; const option: { value: string } = typedSelectedOption; const connectionId = option?.value as string; if (connectionId !== step.connection?.id) { onChange({ step: { ...step, connection: { id: connectionId, }, }, }); } } }, [step, onChange]); React.useEffect(() => { if (step.connection?.id) { retestConnection({ id: step.connection.id, }); } }, [step.connection?.id, retestConnection]) const onToggle = expanded ? onCollapse : onExpand; return ( } value={getOption(connectionOptions, connection?.id)} onChange={handleChange} loading={loading} data-test="choose-connection-autocomplete" /> ); } export default ChooseConnectionSubstep;