import React, { useEffect, useRef, useState } from 'react'; import Modal, { RequiredModalProps } from '@/components/elements/Modal'; import { Field, Form, Formik, FormikHelpers, useFormikContext } from 'formik'; import { Actions, useStoreActions, useStoreState } from 'easy-peasy'; import { object, string } from 'yup'; import debounce from 'debounce'; import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper'; import InputSpinner from '@/components/elements/InputSpinner'; import getServers from '@/api/getServers'; import { Server } from '@definitions/user'; import { ApplicationStore } from '@/state'; import { Link } from 'react-router-dom'; import tw, { styled } from 'twin.macro'; import Input from '@/components/elements/Input'; import { formatIp } from '@/helpers'; type Props = RequiredModalProps; interface Values { term: string; } const ServerResult = styled(Link)` ${tw`flex items-center bg-neutral-900 p-4 rounded border-l-4 border-neutral-900 no-underline transition-all duration-150`}; &:hover { ${tw`shadow border-cyan-500`}; } &:not(:last-of-type) { ${tw`mb-2`}; } `; const SearchWatcher = () => { const { values, submitForm } = useFormikContext(); useEffect(() => { if (values.term.length >= 3) { submitForm(); } }, [ values.term ]); return null; }; export default ({ ...props }: Props) => { const ref = useRef(null); const isAdmin = useStoreState(state => state.user.data!.rootAdmin); const [ servers, setServers ] = useState([]); const { clearAndAddHttpError, clearFlashes } = useStoreActions((actions: Actions) => actions.flashes); const search = debounce(({ term }: Values, { setSubmitting }: FormikHelpers) => { clearFlashes('search'); // if (ref.current) ref.current.focus(); getServers({ query: term, type: isAdmin ? 'admin-all' : undefined }) .then(servers => setServers(servers.items.filter((_, index) => index < 5))) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'search', error }); }) .then(() => setSubmitting(false)) .then(() => ref.current?.focus()); }, 500); useEffect(() => { if (props.visible) { if (ref.current) ref.current.focus(); } }, [ props.visible ]); // Formik does not support an innerRef on custom components. const InputWithRef = (props: any) => ; return ( {({ isSubmitting }) => (
{servers.length > 0 &&
{ servers.map(server => ( props.onDismissed()} >

{server.name}

{ server.allocations.filter(alloc => alloc.isDefault).map(allocation => ( {allocation.alias || formatIp(allocation.ip)}:{allocation.port} )) }

{server.node}
)) }
}
)}
); };