mirror of
https://github.com/status-im/safe-react.git
synced 2025-02-10 08:36:35 +00:00
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 <katspaugh@users.noreply.github.com>
This commit is contained in:
parent
f9f7b3dad2
commit
4f6a3e93eb
@ -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 {
|
const {
|
||||||
input: { value: appUrl },
|
input: { value: appUrl },
|
||||||
} = useField('appUrl', { subscription: { value: true } })
|
} = useField('appUrl', { subscription: { value: true } })
|
||||||
|
|
||||||
const debouncedValue = useDebounce(appUrl, 500)
|
const debouncedValue = useDebounce(appUrl, 500)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const updateAppInfo = async () => {
|
const updateAppInfo = async () => {
|
||||||
const appInfo = await getAppInfoFromUrl(debouncedValue)
|
try {
|
||||||
onAppInfo({ ...appInfo })
|
onLoading(true)
|
||||||
|
const appInfo = await getAppInfoFromUrl(debouncedValue)
|
||||||
|
onAppInfo({ ...appInfo })
|
||||||
|
onLoading(false)
|
||||||
|
} catch (error) {
|
||||||
|
onLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValidURL(debouncedValue)) {
|
if (isValidURL(debouncedValue)) {
|
||||||
updateAppInfo()
|
updateAppInfo()
|
||||||
}
|
}
|
||||||
}, [debouncedValue, onAppInfo])
|
}, [debouncedValue, onAppInfo, onLoading])
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -55,7 +67,15 @@ const AppUrl = ({ appList }: { appList: SafeApp[] }): React.ReactElement => {
|
|||||||
const validate = !visited?.appUrl ? undefined : composeValidators(required, validateUrl, uniqueApp(appList))
|
const validate = !visited?.appUrl ? undefined : composeValidators(required, validateUrl, uniqueApp(appList))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Field label="App URL" name="appUrl" placeholder="App URL" type="text" component={TextField} validate={validate} />
|
<Field
|
||||||
|
label="App URL"
|
||||||
|
name="appUrl"
|
||||||
|
placeholder="App URL"
|
||||||
|
type="text"
|
||||||
|
component={TextField}
|
||||||
|
validate={validate}
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 React, { useState, ReactElement } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ const StyledTextFileAppName = styled(TextField)`
|
|||||||
`
|
`
|
||||||
|
|
||||||
const AppInfo = styled.div`
|
const AppInfo = styled.div`
|
||||||
|
display: flex;
|
||||||
margin: 36px 0 24px 0;
|
margin: 36px 0 24px 0;
|
||||||
|
|
||||||
img {
|
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 {
|
interface AddAppFormValues {
|
||||||
appUrl: string
|
appUrl: string
|
||||||
agreementAccepted: boolean
|
agreementAccepted: boolean
|
||||||
@ -62,6 +75,7 @@ const AddApp = ({ appList, closeModal }: AddAppProps): ReactElement => {
|
|||||||
const [appInfo, setAppInfo] = useState<SafeApp>(APP_INFO)
|
const [appInfo, setAppInfo] = useState<SafeApp>(APP_INFO)
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const matchSafeWithAddress = useRouteMatch<{ safeAddress: string }>({ path: `${SAFELIST_ADDRESS}/:safeAddress` })
|
const matchSafeWithAddress = useRouteMatch<{ safeAddress: string }>({ path: `${SAFELIST_ADDRESS}/:safeAddress` })
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
const newAppList = [
|
const newAppList = [
|
||||||
@ -93,14 +107,26 @@ const AddApp = ({ appList, closeModal }: AddAppProps): ReactElement => {
|
|||||||
<Icon size="sm" type="externalLink" color="primary" />
|
<Icon size="sm" type="externalLink" color="primary" />
|
||||||
</Link>
|
</Link>
|
||||||
</AppDocsInfo>
|
</AppDocsInfo>
|
||||||
|
|
||||||
<AppUrl appList={appList} />
|
<AppUrl appList={appList} />
|
||||||
|
|
||||||
{/* Fetch app from url and return a SafeApp */}
|
{/* Fetch app from url and return a SafeApp */}
|
||||||
<AppInfoUpdater onAppInfo={setAppInfo} />
|
<AppInfoUpdater onAppInfo={setAppInfo} onLoading={setIsLoading} />
|
||||||
|
|
||||||
<AppInfo>
|
<AppInfo>
|
||||||
<Img alt="Token image" height={55} src={appInfo.iconUrl} />
|
{isLoading ? (
|
||||||
<StyledTextFileAppName label="App name" readOnly value={appInfo.name} onChange={() => {}} />
|
<WrapperLoader>
|
||||||
|
<StyledLoader size="sm" />
|
||||||
|
</WrapperLoader>
|
||||||
|
) : (
|
||||||
|
<Img alt="Token image" width={55} src={appInfo.iconUrl} />
|
||||||
|
)}
|
||||||
|
<StyledTextFileAppName
|
||||||
|
label="App name"
|
||||||
|
readOnly
|
||||||
|
value={isLoading ? 'Loading...' : appInfo.name}
|
||||||
|
onChange={() => {}}
|
||||||
|
/>
|
||||||
</AppInfo>
|
</AppInfo>
|
||||||
|
|
||||||
<AppAgreement />
|
<AppAgreement />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user