Adding Apps info to toast notification (#621)
* Adding APP_Name for APPs TXs in toast messages * refactor: save appId instead of appName in origin field * adding fallback icon and message to TX apps table * review changes * review fixes * force build
This commit is contained in:
parent
0037522505
commit
63252566dc
|
@ -7,6 +7,7 @@ import { NOTIFICATIONS, type Notification } from './notificationTypes'
|
|||
|
||||
import closeSnackbarAction from '~/logic/notifications/store/actions/closeSnackbar'
|
||||
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
||||
import { getAppInfo } from '~/routes/safe/components/Apps/appsList'
|
||||
import { store } from '~/store'
|
||||
|
||||
export type NotificationsQueue = {
|
||||
|
@ -21,15 +22,26 @@ export type NotificationsQueue = {
|
|||
afterRejection: Notification | null,
|
||||
}
|
||||
|
||||
const standardTxNotificationsQueue: NotificationsQueue = {
|
||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||
pendingExecution: NOTIFICATIONS.TX_PENDING_MSG,
|
||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||
afterExecution: {
|
||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MSG,
|
||||
moreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MORE_CONFIRMATIONS_MSG,
|
||||
},
|
||||
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
||||
const setNotificationOrigin = (notification: Notification, origin: string): Notification => {
|
||||
if (!origin) {
|
||||
return notification
|
||||
}
|
||||
|
||||
const appInfo = getAppInfo(origin)
|
||||
return { ...notification, message: `${appInfo.name}: ${notification.message}` }
|
||||
}
|
||||
|
||||
const getStandardTxNotificationsQueue = (origin?: string): NotificationsQueue => {
|
||||
return {
|
||||
beforeExecution: setNotificationOrigin(NOTIFICATIONS.SIGN_TX_MSG, origin),
|
||||
pendingExecution: setNotificationOrigin(NOTIFICATIONS.TX_PENDING_MSG, origin),
|
||||
afterRejection: setNotificationOrigin(NOTIFICATIONS.TX_REJECTED_MSG, origin),
|
||||
afterExecution: {
|
||||
noMoreConfirmationsNeeded: setNotificationOrigin(NOTIFICATIONS.TX_EXECUTED_MSG, origin),
|
||||
moreConfirmationsNeeded: setNotificationOrigin(NOTIFICATIONS.TX_EXECUTED_MORE_CONFIRMATIONS_MSG, origin),
|
||||
},
|
||||
afterExecutionError: setNotificationOrigin(NOTIFICATIONS.TX_FAILED_MSG, origin),
|
||||
}
|
||||
}
|
||||
|
||||
const waitingTransactionNotificationsQueue: NotificationsQueue = {
|
||||
|
@ -41,26 +53,30 @@ const waitingTransactionNotificationsQueue: NotificationsQueue = {
|
|||
afterExecutionError: null,
|
||||
}
|
||||
|
||||
const confirmationTxNotificationsQueue: NotificationsQueue = {
|
||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||
pendingExecution: NOTIFICATIONS.TX_CONFIRMATION_PENDING_MSG,
|
||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||
afterExecution: {
|
||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MSG,
|
||||
moreConfirmationsNeeded: NOTIFICATIONS.TX_CONFIRMATION_EXECUTED_MSG,
|
||||
},
|
||||
afterExecutionError: NOTIFICATIONS.TX_CONFIRMATION_FAILED_MSG,
|
||||
const getConfirmationTxNotificationsQueue = (origin?: string): NotificationsQueue => {
|
||||
return {
|
||||
beforeExecution: setNotificationOrigin(NOTIFICATIONS.SIGN_TX_MSG, origin),
|
||||
pendingExecution: setNotificationOrigin(NOTIFICATIONS.TX_CONFIRMATION_PENDING_MSG, origin),
|
||||
afterRejection: setNotificationOrigin(NOTIFICATIONS.TX_REJECTED_MSG, origin),
|
||||
afterExecution: {
|
||||
noMoreConfirmationsNeeded: setNotificationOrigin(NOTIFICATIONS.TX_EXECUTED_MSG, origin),
|
||||
moreConfirmationsNeeded: setNotificationOrigin(NOTIFICATIONS.TX_CONFIRMATION_EXECUTED_MSG, origin),
|
||||
},
|
||||
afterExecutionError: setNotificationOrigin(NOTIFICATIONS.TX_CONFIRMATION_FAILED_MSG, origin),
|
||||
}
|
||||
}
|
||||
|
||||
const cancellationTxNotificationsQueue: NotificationsQueue = {
|
||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||
pendingExecution: NOTIFICATIONS.TX_PENDING_MSG,
|
||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||
afterExecution: {
|
||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MSG,
|
||||
moreConfirmationsNeeded: NOTIFICATIONS.TX_CANCELLATION_EXECUTED_MSG,
|
||||
},
|
||||
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
||||
const getCancellationTxNotificationsQueue = (origin?: string): NotificationsQueue => {
|
||||
return {
|
||||
beforeExecution: setNotificationOrigin(NOTIFICATIONS.SIGN_TX_MSG, origin),
|
||||
pendingExecution: setNotificationOrigin(NOTIFICATIONS.TX_PENDING_MSG, origin),
|
||||
afterRejection: setNotificationOrigin(NOTIFICATIONS.TX_REJECTED_MSG, origin),
|
||||
afterExecution: {
|
||||
noMoreConfirmationsNeeded: setNotificationOrigin(NOTIFICATIONS.TX_EXECUTED_MSG, origin),
|
||||
moreConfirmationsNeeded: setNotificationOrigin(NOTIFICATIONS.TX_CANCELLATION_EXECUTED_MSG, origin),
|
||||
},
|
||||
afterExecutionError: setNotificationOrigin(NOTIFICATIONS.TX_FAILED_MSG, origin),
|
||||
}
|
||||
}
|
||||
|
||||
const safeNameChangeNotificationsQueue: NotificationsQueue = {
|
||||
|
@ -143,20 +159,20 @@ const addressBookDeleteEntry: NotificationsQueue = {
|
|||
afterExecutionError: null,
|
||||
}
|
||||
|
||||
export const getNotificationsFromTxType = (txType: string) => {
|
||||
export const getNotificationsFromTxType = (txType: string, origin?: string) => {
|
||||
let notificationsQueue: NotificationsQueue
|
||||
|
||||
switch (txType) {
|
||||
case TX_NOTIFICATION_TYPES.STANDARD_TX: {
|
||||
notificationsQueue = standardTxNotificationsQueue
|
||||
notificationsQueue = getStandardTxNotificationsQueue(origin)
|
||||
break
|
||||
}
|
||||
case TX_NOTIFICATION_TYPES.CONFIRMATION_TX: {
|
||||
notificationsQueue = confirmationTxNotificationsQueue
|
||||
notificationsQueue = getConfirmationTxNotificationsQueue(origin)
|
||||
break
|
||||
}
|
||||
case TX_NOTIFICATION_TYPES.CANCELLATION_TX: {
|
||||
notificationsQueue = cancellationTxNotificationsQueue
|
||||
notificationsQueue = getCancellationTxNotificationsQueue(origin)
|
||||
break
|
||||
}
|
||||
case TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX: {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// @flow
|
||||
import appsIconSvg from '../Transactions/TxsTable/TxType/assets/appsIcon.svg'
|
||||
|
||||
const appList = [
|
||||
{
|
||||
id: 1,
|
||||
id: '1',
|
||||
name: 'Compound',
|
||||
url: process.env.REACT_APP_GNOSIS_APPS_URL || 'https://gnosis-apps.netlify.com',
|
||||
iconUrl: 'https://compound.finance/images/compound-mark.svg',
|
||||
|
@ -9,7 +11,7 @@ const appList = [
|
|||
providedBy: { name: 'Gnosis', url: '' },
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
id: '2',
|
||||
name: 'ENS Manager',
|
||||
url: '',
|
||||
iconUrl: 'https://app.ens.domains/static/media/ensIconLogo.4d995d23.svg',
|
||||
|
@ -17,7 +19,7 @@ const appList = [
|
|||
providedBy: { name: 'Gnosis', url: '' },
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
id: '3',
|
||||
name: 'Uniswap',
|
||||
url: '',
|
||||
iconUrl:
|
||||
|
@ -26,7 +28,7 @@ const appList = [
|
|||
providedBy: { name: 'Gnosis', url: '' },
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
id: '4',
|
||||
name: 'Nexus Mutual',
|
||||
url: '',
|
||||
iconUrl:
|
||||
|
@ -41,4 +43,20 @@ const appList = [
|
|||
|
||||
export default appList
|
||||
|
||||
export const getAppInfo = (appName: string) => appList.find(app => app.name === appName)
|
||||
export const getAppInfo = (appId: string) => {
|
||||
const res = appList.find(app => app.id === appId.toString())
|
||||
if (!res) {
|
||||
return {
|
||||
id: 0,
|
||||
name: 'External App',
|
||||
url: null,
|
||||
iconUrl: appsIconSvg,
|
||||
description: null,
|
||||
providedBy: {
|
||||
name: null,
|
||||
url: null,
|
||||
},
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// @flow
|
||||
import { withSnackbar } from 'notistack'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import ButtonLink from '../../../../components/layout/ButtonLink'
|
||||
|
||||
import appsList from './appsList'
|
||||
import confirmTransactions from './confirmTransactions'
|
||||
import sendTransactions from './sendTransactions'
|
||||
|
||||
import { ListContentLayout as LCL, Loader } from '~/components-v2'
|
||||
import ButtonLink from '~/components/layout/ButtonLink'
|
||||
|
||||
const StyledIframe = styled.iframe`
|
||||
width: 100%;
|
||||
|
@ -29,12 +29,25 @@ type Props = {
|
|||
ethBalance: String,
|
||||
network: String,
|
||||
createTransaction: any,
|
||||
enqueueSnackbar: Function,
|
||||
closeSnackbar: Function,
|
||||
openModal: () => {},
|
||||
closeModal: () => {},
|
||||
}
|
||||
|
||||
function Apps({ closeModal, createTransaction, ethBalance, network, openModal, safeAddress, safeName, web3 }: Props) {
|
||||
const [selectedApp, setSelectedApp] = useState(1)
|
||||
function Apps({
|
||||
closeModal,
|
||||
closeSnackbar,
|
||||
createTransaction,
|
||||
enqueueSnackbar,
|
||||
ethBalance,
|
||||
network,
|
||||
openModal,
|
||||
safeAddress,
|
||||
safeName,
|
||||
web3,
|
||||
}: Props) {
|
||||
const [selectedApp, setSelectedApp] = useState('1')
|
||||
const [appIsLoading, setAppIsLoading] = useState(true)
|
||||
const [iframeEl, setframeEl] = useState(null)
|
||||
|
||||
|
@ -55,7 +68,15 @@ function Apps({ closeModal, createTransaction, ethBalance, network, openModal, s
|
|||
const onConfirm = async () => {
|
||||
closeModal()
|
||||
|
||||
const txHash = await sendTransactions(web3, createTransaction, safeAddress, data.data, getSelectedApp().name)
|
||||
const txHash = await sendTransactions(
|
||||
web3,
|
||||
createTransaction,
|
||||
safeAddress,
|
||||
data.data,
|
||||
enqueueSnackbar,
|
||||
closeSnackbar,
|
||||
getSelectedApp().id,
|
||||
)
|
||||
|
||||
if (txHash) {
|
||||
sendMessageToIframe(operations.ON_TX_UPDATE, {
|
||||
|
@ -184,4 +205,4 @@ function Apps({ closeModal, createTransaction, ethBalance, network, openModal, s
|
|||
)
|
||||
}
|
||||
|
||||
export default Apps
|
||||
export default withSnackbar(Apps)
|
||||
|
|
|
@ -14,7 +14,15 @@ const multiSendAbi = [
|
|||
},
|
||||
]
|
||||
|
||||
const sendTransactions = (web3: any, createTransaction: any, safeAddress: String, txs: Array<any>, origin: string) => {
|
||||
const sendTransactions = (
|
||||
web3: any,
|
||||
createTransaction: any,
|
||||
safeAddress: String,
|
||||
txs: Array<any>,
|
||||
enqueueSnackbar: Function,
|
||||
closeSnackbar: Function,
|
||||
origin: string,
|
||||
) => {
|
||||
const multiSend = new web3.eth.Contract(multiSendAbi, multiSendAddress)
|
||||
|
||||
const encodeMultiSendCalldata = multiSend.methods
|
||||
|
@ -39,8 +47,8 @@ const sendTransactions = (web3: any, createTransaction: any, safeAddress: String
|
|||
valueInWei: 0,
|
||||
txData: encodeMultiSendCalldata,
|
||||
notifiedTransaction: 'STANDARD_TX',
|
||||
enqueueSnackbar: () => {},
|
||||
closeSnackbar: () => {},
|
||||
enqueueSnackbar,
|
||||
closeSnackbar,
|
||||
operation: DELEGATE_CALL,
|
||||
navigateToTransactionsTab: false,
|
||||
origin,
|
||||
|
|
|
@ -74,6 +74,7 @@ const RejectTxModal = ({
|
|||
enqueueSnackbar,
|
||||
closeSnackbar,
|
||||
txNonce: tx.nonce,
|
||||
origin: tx.origin,
|
||||
})
|
||||
onClose()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
|
||||
<path
|
||||
className="fill"
|
||||
fillRule="nonzero"
|
||||
d="M2 1h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm1 2v2h2V3H3zM10 9h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1zm1 2v2h2v-2h-2zM12 7a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-1.9a1.1 1.1 0 1 1 0-2.2 1.1 1.1 0 0 1 0 2.2z"
|
||||
/>
|
||||
<path
|
||||
className="fill"
|
||||
d="M2.641 11.999l-1.36-1.361A.96.96 0 0 1 2.637 9.28l1.36 1.36 1.362-1.36a.959.959 0 1 1 1.357 1.357l-1.36 1.36 1.36 1.362a.96.96 0 0 1-1.357 1.358L4 13.356l-1.361 1.362a.962.962 0 0 1-1.358 0 .964.964 0 0 1 0-1.358l1.361-1.361z"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 690 B |
|
@ -31,7 +31,7 @@ const typeToLabel = {
|
|||
|
||||
const TxType = ({ txType, origin }: { txType: TransactionType, origin: string | null }) => {
|
||||
const iconUrl = txType === 'third-party-app' ? getAppInfo(origin).iconUrl : typeToIcon[txType]
|
||||
const text = txType === 'third-party-app' ? origin : typeToLabel[txType]
|
||||
const text = txType === 'third-party-app' ? getAppInfo(origin).name : typeToLabel[txType]
|
||||
|
||||
return <IconText iconUrl={iconUrl} text={text} />
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ const createTransaction = ({
|
|||
'',
|
||||
)}000000000000000000000000000000000000000000000000000000000000000001`
|
||||
|
||||
const notificationsQueue: NotificationsQueue = getNotificationsFromTxType(notifiedTransaction)
|
||||
const notificationsQueue: NotificationsQueue = getNotificationsFromTxType(notifiedTransaction, origin)
|
||||
const beforeExecutionKey = showSnackbar(notificationsQueue.beforeExecution, enqueueSnackbar, closeSnackbar)
|
||||
let pendingExecutionKey
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ const processTransaction = ({
|
|||
)}000000000000000000000000000000000000000000000000000000000000000001`
|
||||
}
|
||||
|
||||
const notificationsQueue: NotificationsQueue = getNotificationsFromTxType(notifiedTransaction)
|
||||
const notificationsQueue: NotificationsQueue = getNotificationsFromTxType(notifiedTransaction, tx.origin)
|
||||
const beforeExecutionKey = showSnackbar(notificationsQueue.beforeExecution, enqueueSnackbar, closeSnackbar)
|
||||
let pendingExecutionKey
|
||||
|
||||
|
|
Loading…
Reference in New Issue