Merge pull request #1411 from gnosis/release/v2.12.0
Backmerge 2.12.0 to development
This commit is contained in:
commit
24f2828a7b
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "safe-react",
|
||||
"version": "2.11.1",
|
||||
"version": "2.12.0",
|
||||
"description": "Allowing crypto users manage funds in a safer way",
|
||||
"website": "https://github.com/gnosis/safe-react#readme",
|
||||
"bugs": {
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
import updateSafe from './updateSafe'
|
||||
import { Set } from 'immutable'
|
||||
import updateAssetsList from './updateAssetsList'
|
||||
import { Dispatch } from 'src/logic/safe/store/actions/types.d'
|
||||
|
||||
// the selector uses ownProps argument/router props to get the address of the safe
|
||||
// so in order to use it I had to recreate the same structure
|
||||
// const generateMatchProps = (safeAddress: string) => ({
|
||||
// match: {
|
||||
// params: {
|
||||
// [SAFE_PARAM_ADDRESS]: safeAddress,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
const updateActiveAssets = (safeAddress, activeAssets) => async (dispatch) => {
|
||||
dispatch(updateSafe({ address: safeAddress, activeAssets }))
|
||||
const updateActiveAssets = (safeAddress: string, activeAssets: Set<string>) => (dispatch: Dispatch): void => {
|
||||
dispatch(updateAssetsList({ safeAddress, activeAssets }))
|
||||
}
|
||||
|
||||
export default updateActiveAssets
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import updateSafe from './updateSafe'
|
||||
import { Set } from 'immutable'
|
||||
import { Dispatch } from 'redux'
|
||||
import updateTokensList from './updateTokensList'
|
||||
import { Dispatch } from 'src/logic/safe/store/actions/types.d'
|
||||
|
||||
// the selector uses ownProps argument/router props to get the address of the safe
|
||||
// so in order to use it I had to recreate the same structure
|
||||
|
@ -13,7 +13,7 @@ import { Dispatch } from 'redux'
|
|||
// })
|
||||
|
||||
const updateActiveTokens = (safeAddress: string, activeTokens: Set<string>) => (dispatch: Dispatch): void => {
|
||||
dispatch(updateSafe({ address: safeAddress, activeTokens }))
|
||||
dispatch(updateTokensList({ safeAddress, activeTokens }))
|
||||
}
|
||||
|
||||
export default updateActiveTokens
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import { createAction } from 'redux-actions'
|
||||
|
||||
export const UPDATE_ASSETS_LIST = 'UPDATE_ASSETS_LIST'
|
||||
|
||||
const updateAssetsList = createAction(UPDATE_ASSETS_LIST)
|
||||
|
||||
export default updateAssetsList
|
|
@ -1,7 +1,9 @@
|
|||
import updateSafe from './updateSafe'
|
||||
import { Set } from 'immutable'
|
||||
import updateAssetsList from './updateAssetsList'
|
||||
import { Dispatch } from 'src/logic/safe/store/actions/types.d'
|
||||
|
||||
const updateBlacklistedAssets = (safeAddress, blacklistedAssets) => async (dispatch) => {
|
||||
dispatch(updateSafe({ address: safeAddress, blacklistedAssets }))
|
||||
const updateBlacklistedAssets = (safeAddress: string, blacklistedAssets: Set<string>) => (dispatch: Dispatch): void => {
|
||||
dispatch(updateAssetsList({ safeAddress, blacklistedAssets }))
|
||||
}
|
||||
|
||||
export default updateBlacklistedAssets
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import updateSafe from './updateSafe'
|
||||
import { Dispatch } from 'redux'
|
||||
import { Set } from 'immutable'
|
||||
import updateTokensList from './updateTokensList'
|
||||
import { Dispatch } from 'src/logic/safe/store/actions/types.d'
|
||||
|
||||
const updateBlacklistedTokens = (safeAddress: string, blacklistedTokens: Set<string>) => (dispatch: Dispatch): void => {
|
||||
dispatch(updateSafe({ address: safeAddress, blacklistedTokens }))
|
||||
dispatch(updateTokensList({ safeAddress, blacklistedTokens }))
|
||||
}
|
||||
|
||||
export default updateBlacklistedTokens
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import { createAction } from 'redux-actions'
|
||||
|
||||
export const UPDATE_TOKENS_LIST = 'UPDATE_TOKENS_LIST'
|
||||
|
||||
const updateTokenList = createAction(UPDATE_TOKENS_LIST)
|
||||
|
||||
export default updateTokenList
|
|
@ -11,6 +11,8 @@ import { REMOVE_SAFE_OWNER } from 'src/logic/safe/store/actions/removeSafeOwner'
|
|||
import { REPLACE_SAFE_OWNER } from 'src/logic/safe/store/actions/replaceSafeOwner'
|
||||
import { SET_DEFAULT_SAFE } from 'src/logic/safe/store/actions/setDefaultSafe'
|
||||
import { UPDATE_SAFE } from 'src/logic/safe/store/actions/updateSafe'
|
||||
import { UPDATE_TOKENS_LIST } from 'src/logic/safe/store/actions/updateTokensList'
|
||||
import { UPDATE_ASSETS_LIST } from 'src/logic/safe/store/actions/updateAssetsList'
|
||||
import { getActiveTokensAddressesForAllSafes, safesMapSelector } from 'src/logic/safe/store/selectors'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
import { makeAddressBookEntry } from 'src/logic/addressBook/model/addressBook'
|
||||
|
@ -31,6 +33,8 @@ const watchedActions = [
|
|||
REPLACE_SAFE_OWNER,
|
||||
EDIT_SAFE_OWNER,
|
||||
ACTIVATE_TOKEN_FOR_ALL_SAFES,
|
||||
UPDATE_TOKENS_LIST,
|
||||
UPDATE_ASSETS_LIST,
|
||||
SET_DEFAULT_SAFE,
|
||||
]
|
||||
|
||||
|
|
|
@ -11,11 +11,14 @@ import { REPLACE_SAFE_OWNER } from 'src/logic/safe/store/actions/replaceSafeOwne
|
|||
import { SET_DEFAULT_SAFE } from 'src/logic/safe/store/actions/setDefaultSafe'
|
||||
import { SET_LATEST_MASTER_CONTRACT_VERSION } from 'src/logic/safe/store/actions/setLatestMasterContractVersion'
|
||||
import { UPDATE_SAFE } from 'src/logic/safe/store/actions/updateSafe'
|
||||
import { UPDATE_TOKENS_LIST } from 'src/logic/safe/store/actions/updateTokensList'
|
||||
import { UPDATE_ASSETS_LIST } from 'src/logic/safe/store/actions/updateAssetsList'
|
||||
import { makeOwner } from 'src/logic/safe/store/models/owner'
|
||||
import makeSafe, { SafeRecordProps } from 'src/logic/safe/store/models/safe'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
import { SafeReducerMap } from 'src/routes/safe/store/reducer/types/safe'
|
||||
import { ADD_OR_UPDATE_SAFE } from 'src/logic/safe/store/actions/addOrUpdateSafe'
|
||||
import { sameAddress } from 'src/logic/wallets/ethAddresses'
|
||||
|
||||
export const SAFE_REDUCER_ID = 'safes'
|
||||
export const DEFAULT_SAFE_INITIAL_STATE = 'NOT_ASKED'
|
||||
|
@ -51,10 +54,10 @@ const updateSafeProps = (prevSafe, safe) => {
|
|||
// We check each safe property sent in action.payload
|
||||
safeProperties.forEach((key) => {
|
||||
if (safe[key] && typeof safe[key] === 'object') {
|
||||
if (safe[key].length) {
|
||||
if (safe[key].length >= 0) {
|
||||
// If type is array we update the array
|
||||
record.update(key, () => safe[key])
|
||||
} else if (safe[key].size) {
|
||||
} else if (safe[key].size >= 0) {
|
||||
// If type is Immutable List we replace current List
|
||||
// If type is Object we do a merge
|
||||
List.isList(safe[key])
|
||||
|
@ -130,6 +133,14 @@ export default handleActions(
|
|||
[ADD_SAFE_OWNER]: (state: SafeReducerMap, action) => {
|
||||
const { ownerAddress, ownerName, safeAddress } = action.payload
|
||||
|
||||
const addressFound = state
|
||||
.getIn(['safes', safeAddress])
|
||||
.owners.find((owner) => sameAddress(owner.address, ownerAddress))
|
||||
|
||||
if (addressFound) {
|
||||
return state
|
||||
}
|
||||
|
||||
return state.updateIn(['safes', safeAddress], (prevSafe) =>
|
||||
prevSafe.merge({
|
||||
owners: prevSafe.owners.push(makeOwner({ address: ownerAddress, name: ownerName })),
|
||||
|
@ -167,6 +178,24 @@ export default handleActions(
|
|||
return prevSafe.merge({ owners: updatedOwners })
|
||||
})
|
||||
},
|
||||
[UPDATE_TOKENS_LIST]: (state: SafeReducerMap, action) => {
|
||||
// Only activeTokens or blackListedTokens is required
|
||||
const { safeAddress, activeTokens, blacklistedTokens } = action.payload
|
||||
|
||||
const key = activeTokens ? 'activeTokens' : 'blacklistedTokens'
|
||||
const list = activeTokens ?? blacklistedTokens
|
||||
|
||||
return state.updateIn(['safes', safeAddress], (prevSafe) => prevSafe.set(key, list))
|
||||
},
|
||||
[UPDATE_ASSETS_LIST]: (state: SafeReducerMap, action) => {
|
||||
// Only activeAssets or blackListedAssets is required
|
||||
const { safeAddress, activeAssets, blacklistedAssets } = action.payload
|
||||
|
||||
const key = activeAssets ? 'activeAssets' : 'blacklistedAssets'
|
||||
const list = activeAssets ?? blacklistedAssets
|
||||
|
||||
return state.updateIn(['safes', safeAddress], (prevSafe) => prevSafe.set(key, list))
|
||||
},
|
||||
[SET_DEFAULT_SAFE]: (state: SafeReducerMap, action) => state.set('defaultSafe', action.payload),
|
||||
[SET_LATEST_MASTER_CONTRACT_VERSION]: (state: SafeReducerMap, action) =>
|
||||
state.set('latestMasterContractVersion', action.payload),
|
||||
|
|
|
@ -30,15 +30,13 @@ describe('Feature > Balances', () => {
|
|||
const expectedResult = '100'
|
||||
|
||||
// when
|
||||
store.dispatch(updateActiveTokens(safeAddress, Set([token.address])))
|
||||
store.dispatch(updateSafe({ address: safeAddress, balances }))
|
||||
store.dispatch(updateActiveTokens(safeAddress, Set([token.address])))
|
||||
|
||||
const safe = safesMapSelector(store.getState()).get(safeAddress)
|
||||
//@ts-ignore
|
||||
const balanceResult = safe.get('balances').get(token.address)
|
||||
//@ts-ignore
|
||||
const activeTokens = safe.get('activeTokens')
|
||||
const tokenIsActive = activeTokens.has(token.address)
|
||||
const balanceResult = safe?.get('balances').get(token.address)
|
||||
const activeTokens = safe?.get('activeTokens')
|
||||
const tokenIsActive = activeTokens?.has(token.address)
|
||||
|
||||
// then
|
||||
expect(balanceResult).toBe(expectedResult)
|
||||
|
@ -53,8 +51,7 @@ describe('Feature > Balances', () => {
|
|||
// when
|
||||
store.dispatch(updateSafe({ address: safeAddress, ethBalance: etherAmount }))
|
||||
const safe = safesMapSelector(store.getState()).get(safeAddress)
|
||||
//@ts-ignore
|
||||
const balanceResult = safe.get('ethBalance')
|
||||
const balanceResult = safe?.get('ethBalance')
|
||||
|
||||
// then
|
||||
expect(balanceResult).toBe(expectedResult)
|
||||
|
|
|
@ -4,7 +4,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import Search from '@material-ui/icons/Search'
|
||||
import cn from 'classnames'
|
||||
import SearchBar from 'material-ui-search-bar'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { FixedSizeList } from 'react-window'
|
||||
|
||||
|
@ -55,11 +55,6 @@ const AssetsList = (props) => {
|
|||
const [blacklistedAssetsAddresses, setBlacklistedAssetsAddresses] = useState(blacklistedAssets)
|
||||
const nftAssetsList = useSelector(nftAssetsListSelector)
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updateActiveAssets(safeAddress, activeAssetsAddresses))
|
||||
dispatch(updateBlacklistedAssets(safeAddress, blacklistedAssetsAddresses))
|
||||
}, [activeAssetsAddresses, blacklistedAssetsAddresses, dispatch, safeAddress])
|
||||
|
||||
const onCancelSearch = () => {
|
||||
setFilterValue('')
|
||||
}
|
||||
|
@ -73,19 +68,22 @@ const AssetsList = (props) => {
|
|||
}
|
||||
|
||||
const onSwitch = (asset) => () => {
|
||||
const { address } = asset
|
||||
const activeAssetsAddressesResult = activeAssetsAddresses.contains(address)
|
||||
? activeAssetsAddresses.remove(address)
|
||||
: activeAssetsAddresses.add(address)
|
||||
const blacklistedAssetsAddressesResult = activeAssetsAddresses.has(address)
|
||||
? blacklistedAssetsAddresses.add(address)
|
||||
: blacklistedAssetsAddresses.remove(address)
|
||||
setActiveAssetsAddresses(activeAssetsAddressesResult)
|
||||
setBlacklistedAssetsAddresses(blacklistedAssetsAddressesResult)
|
||||
return {
|
||||
activeAssetsAddresses: activeAssetsAddressesResult,
|
||||
blacklistedAssetsAddresses: blacklistedAssetsAddressesResult,
|
||||
let newActiveAssetsAddresses
|
||||
let newBlacklistedAssetsAddresses
|
||||
if (activeAssetsAddresses.has(asset.address)) {
|
||||
newActiveAssetsAddresses = activeAssetsAddresses.delete(asset.address)
|
||||
newBlacklistedAssetsAddresses = blacklistedAssetsAddresses.add(asset.address)
|
||||
} else {
|
||||
newActiveAssetsAddresses = activeAssetsAddresses.add(asset.address)
|
||||
newBlacklistedAssetsAddresses = blacklistedAssetsAddresses.delete(asset.address)
|
||||
}
|
||||
|
||||
// Set local state
|
||||
setActiveAssetsAddresses(newActiveAssetsAddresses)
|
||||
setBlacklistedAssetsAddresses(newBlacklistedAssetsAddresses)
|
||||
// Dispatch to global state
|
||||
dispatch(updateActiveAssets(safeAddress, newActiveAssetsAddresses))
|
||||
dispatch(updateBlacklistedAssets(safeAddress, newBlacklistedAssetsAddresses))
|
||||
}
|
||||
|
||||
const createItemData = (assetsList) => {
|
||||
|
|
|
@ -5,7 +5,7 @@ import Search from '@material-ui/icons/Search'
|
|||
import cn from 'classnames'
|
||||
import { List, Set } from 'immutable'
|
||||
import SearchBar from 'material-ui-search-bar'
|
||||
import * as React from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import { FixedSizeList } from 'react-window'
|
||||
|
||||
import TokenRow from './TokenRow'
|
||||
|
@ -17,7 +17,6 @@ import Button from 'src/components/layout/Button'
|
|||
import Divider from 'src/components/layout/Divider'
|
||||
import Hairline from 'src/components/layout/Hairline'
|
||||
import Row from 'src/components/layout/Row'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Token } from 'src/logic/tokens/store/model/token'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import updateBlacklistedTokens from 'src/logic/safe/store/actions/updateBlacklistedTokens'
|
||||
|
@ -51,13 +50,6 @@ export const TokenList = (props: Props): React.ReactElement => {
|
|||
const [filter, setFilter] = useState('')
|
||||
const dispatch = useDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
dispatch(updateActiveTokens(safeAddress, activeTokensAddresses))
|
||||
dispatch(updateBlacklistedTokens(safeAddress, blacklistedTokensAddresses))
|
||||
}
|
||||
}, [dispatch, safeAddress, activeTokensAddresses, blacklistedTokensAddresses])
|
||||
|
||||
const searchClasses = {
|
||||
input: classes.searchInput,
|
||||
root: classes.searchRoot,
|
||||
|
@ -75,14 +67,22 @@ export const TokenList = (props: Props): React.ReactElement => {
|
|||
}
|
||||
|
||||
const onSwitch = (token: Token) => () => {
|
||||
let newActiveTokensAddresses
|
||||
let newBlacklistedTokensAddresses
|
||||
if (activeTokensAddresses.has(token.address)) {
|
||||
const newTokens = activeTokensAddresses.remove(token.address)
|
||||
setActiveTokensAddresses(newTokens)
|
||||
setBlacklistedTokensAddresses(blacklistedTokensAddresses.add(token.address))
|
||||
newActiveTokensAddresses = activeTokensAddresses.delete(token.address)
|
||||
newBlacklistedTokensAddresses = blacklistedTokensAddresses.add(token.address)
|
||||
} else {
|
||||
setActiveTokensAddresses(activeTokensAddresses.add(token.address))
|
||||
setBlacklistedTokensAddresses(blacklistedTokensAddresses.remove(token.address))
|
||||
newActiveTokensAddresses = activeTokensAddresses.add(token.address)
|
||||
newBlacklistedTokensAddresses = blacklistedTokensAddresses.delete(token.address)
|
||||
}
|
||||
|
||||
// Set local state
|
||||
setActiveTokensAddresses(newActiveTokensAddresses)
|
||||
setBlacklistedTokensAddresses(newBlacklistedTokensAddresses)
|
||||
// Dispatch to global state
|
||||
dispatch(updateActiveTokens(safeAddress, newActiveTokensAddresses))
|
||||
dispatch(updateBlacklistedTokens(safeAddress, newBlacklistedTokensAddresses))
|
||||
}
|
||||
|
||||
const createItemData = (
|
||||
|
|
Loading…
Reference in New Issue