From 4f6a3e93eb9181fce3b40fdb10d6fb5aec4cc3b5 Mon Sep 17 00:00:00 2001 From: nicolas Date: Fri, 14 May 2021 06:32:49 -0300 Subject: [PATCH] Bug: Add custom app feature works weird or doesn't work (#2279) * prevent trigger for "" value * remove autocomplete for input * Add loading indicator * Ivan feedback * fix jumping * Rename prop Co-authored-by: katspaugh --- .../Apps/components/AddAppForm/AppUrl.tsx | 30 +++++++++++++--- .../Apps/components/AddAppForm/index.tsx | 34 ++++++++++++++++--- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx b/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx index 52d2e673..325a633a 100644 --- a/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx +++ b/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx @@ -28,22 +28,34 @@ export const appUrlResolver = createDecorator({ }, }) -export const AppInfoUpdater = ({ onAppInfo }: { onAppInfo: (appInfo: SafeApp) => void }): null => { +type AppInfoUpdaterProps = { + onAppInfo: (appInfo: SafeApp) => void + onLoading: (isLoading: boolean) => void +} + +export const AppInfoUpdater = ({ onAppInfo, onLoading }: AppInfoUpdaterProps): null => { const { input: { value: appUrl }, } = useField('appUrl', { subscription: { value: true } }) + const debouncedValue = useDebounce(appUrl, 500) React.useEffect(() => { const updateAppInfo = async () => { - const appInfo = await getAppInfoFromUrl(debouncedValue) - onAppInfo({ ...appInfo }) + try { + onLoading(true) + const appInfo = await getAppInfoFromUrl(debouncedValue) + onAppInfo({ ...appInfo }) + onLoading(false) + } catch (error) { + onLoading(false) + } } if (isValidURL(debouncedValue)) { updateAppInfo() } - }, [debouncedValue, onAppInfo]) + }, [debouncedValue, onAppInfo, onLoading]) return null } @@ -55,7 +67,15 @@ const AppUrl = ({ appList }: { appList: SafeApp[] }): React.ReactElement => { const validate = !visited?.appUrl ? undefined : composeValidators(required, validateUrl, uniqueApp(appList)) return ( - + ) } diff --git a/src/routes/safe/components/Apps/components/AddAppForm/index.tsx b/src/routes/safe/components/Apps/components/AddAppForm/index.tsx index 76827a62..5a728bb6 100644 --- a/src/routes/safe/components/Apps/components/AddAppForm/index.tsx +++ b/src/routes/safe/components/Apps/components/AddAppForm/index.tsx @@ -1,4 +1,4 @@ -import { TextField } from '@gnosis.pm/safe-react-components' +import { TextField, Loader } from '@gnosis.pm/safe-react-components' import React, { useState, ReactElement } from 'react' import styled from 'styled-components' @@ -24,6 +24,7 @@ const StyledTextFileAppName = styled(TextField)` ` const AppInfo = styled.div` + display: flex; margin: 36px 0 24px 0; img { @@ -41,6 +42,18 @@ const AppDocsInfo = styled.div` } ` +const WrapperLoader = styled.div` + height: 55px; + width: 65px; + display: flex; + align-items: center; + justify-content: center; +` + +const StyledLoader = styled(Loader)` + margin-right: 15px; +` + interface AddAppFormValues { appUrl: string agreementAccepted: boolean @@ -62,6 +75,7 @@ const AddApp = ({ appList, closeModal }: AddAppProps): ReactElement => { const [appInfo, setAppInfo] = useState(APP_INFO) const history = useHistory() const matchSafeWithAddress = useRouteMatch<{ safeAddress: string }>({ path: `${SAFELIST_ADDRESS}/:safeAddress` }) + const [isLoading, setIsLoading] = useState(false) const handleSubmit = () => { const newAppList = [ @@ -93,14 +107,26 @@ const AddApp = ({ appList, closeModal }: AddAppProps): ReactElement => { + {/* Fetch app from url and return a SafeApp */} - + - Token image - {}} /> + {isLoading ? ( + + + + ) : ( + Token image + )} + {}} + />