Sort safes alphabetically in the sidebar
This commit is contained in:
parent
fbb89bb32d
commit
6d1c44bc39
|
@ -13,8 +13,9 @@ import Spacer from '~/components/Spacer'
|
||||||
import Hairline from '~/components/layout/Hairline'
|
import Hairline from '~/components/layout/Hairline'
|
||||||
import Row from '~/components/layout/Row'
|
import Row from '~/components/layout/Row'
|
||||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||||
import { safesListSelector, defaultSafeSelector } from '~/routes/safe/store/selectors'
|
import { defaultSafeSelector } from '~/routes/safe/store/selectors'
|
||||||
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
|
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
|
||||||
|
import { sortedSafeListSelector } from './selectors'
|
||||||
import useSidebarStyles from './style'
|
import useSidebarStyles from './style'
|
||||||
import SafeList from './SafeList'
|
import SafeList from './SafeList'
|
||||||
import { WELCOME_ADDRESS } from '~/routes/routes'
|
import { WELCOME_ADDRESS } from '~/routes/routes'
|
||||||
|
@ -136,6 +137,6 @@ const Sidebar = ({
|
||||||
|
|
||||||
export default connect<Object, Object, ?Function, ?Object>(
|
export default connect<Object, Object, ?Function, ?Object>(
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
(state) => ({ safes: safesListSelector(state), defaultSafe: defaultSafeSelector(state) }),
|
(state) => ({ safes: sortedSafeListSelector(state), defaultSafe: defaultSafeSelector(state) }),
|
||||||
{ setDefaultSafeAction: setDefaultSafe },
|
{ setDefaultSafeAction: setDefaultSafe },
|
||||||
)(Sidebar)
|
)(Sidebar)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// @flow
|
||||||
|
import { List } from 'immutable'
|
||||||
|
import { createSelector, type Selector } from 'reselect'
|
||||||
|
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||||
|
import { safesListSelector } from '~/routes/safe/store/selectors'
|
||||||
|
import { type GlobalState } from '~/store/index'
|
||||||
|
|
||||||
|
export const sortedSafeListSelector: Selector<GlobalState, {}, List<Safe>> = createSelector(
|
||||||
|
safesListSelector,
|
||||||
|
(safes: List<Safe>): List<Safe> => safes.sort((a: Safe, b: Safe) => (a.name > b.name ? 1 : -1)),
|
||||||
|
)
|
|
@ -14,7 +14,7 @@ const useSidebarStyles = makeStyles({
|
||||||
width: sidebarWidth,
|
width: sidebarWidth,
|
||||||
},
|
},
|
||||||
headerPlaceholder: {
|
headerPlaceholder: {
|
||||||
height: headerHeight, // for some reason it didn't want to work with an imported variable 🤔
|
minHeight: headerHeight,
|
||||||
},
|
},
|
||||||
addSafeBtn: {
|
addSafeBtn: {
|
||||||
fontSize: mediumFontSize,
|
fontSize: mediumFontSize,
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
// @flow
|
|
||||||
/*
|
|
||||||
import { aNewStore } from '~/store'
|
|
||||||
import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
|
||||||
import { sleep } from '~/utils/timer'
|
|
||||||
import { type Match } from 'react-router-dom'
|
|
||||||
import { promisify } from '~/utils/promisify'
|
|
||||||
import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions'
|
|
||||||
import {
|
|
||||||
confirmationsTransactionSelector,
|
|
||||||
safeSelector,
|
|
||||||
safeTransactionsSelector
|
|
||||||
} from '~/routes/safe/store/selectors'
|
|
||||||
import { getTransactionFromReduxStore } from '~/routes/safe/test/testMultisig'
|
|
||||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
|
||||||
import { createTransaction } from '~/wallets/createTransactions'
|
|
||||||
import { getGnosisSafeInstanceAt } from '~/wallets/safeContracts'
|
|
||||||
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
|
|
||||||
*/
|
|
||||||
describe('React DOM TESTS > Change threshold', () => {
|
|
||||||
it('should update the threshold directly if safe has 1 threshold', async () => {})
|
|
||||||
})
|
|
||||||
|
|
||||||
/*
|
|
||||||
// GIVEN
|
|
||||||
const numOwners = 2
|
|
||||||
const threshold = 1
|
|
||||||
const store = aNewStore()
|
|
||||||
const address = await aDeployedSafe(store, 10, threshold, numOwners)
|
|
||||||
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
|
|
||||||
const match: Match = buildMathPropsFrom(address)
|
|
||||||
const safe = safeSelector(store.getState(), { match })
|
|
||||||
if (!safe) throw new Error()
|
|
||||||
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
const nonce = Date.now()
|
|
||||||
const data = gnosisSafe.contract.changeThreshold.getData(2)
|
|
||||||
await createTransaction(safe, "Change Safe's threshold", address, 0, nonce, accounts[0], data)
|
|
||||||
await sleep(1500)
|
|
||||||
await store.dispatch(fetchTransactions())
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
const transactions = safeTransactionsSelector(store.getState(), { safeAddress: address })
|
|
||||||
expect(transactions.count()).toBe(1)
|
|
||||||
|
|
||||||
const thresholdTx = transactions.get(0)
|
|
||||||
if (!thresholdTx) throw new Error()
|
|
||||||
expect(thresholdTx.get('tx')).not.toBe(null)
|
|
||||||
expect(thresholdTx.get('tx')).not.toBe(undefined)
|
|
||||||
expect(thresholdTx.get('tx')).not.toBe('')
|
|
||||||
|
|
||||||
const safeThreshold = await gnosisSafe.getThreshold()
|
|
||||||
expect(Number(safeThreshold)).toEqual(2)
|
|
||||||
})
|
|
||||||
|
|
||||||
const changeThreshold = async (store, safeAddress, executor) => {
|
|
||||||
const tx = getTransactionFromReduxStore(store, safeAddress)
|
|
||||||
if (!tx) throw new Error()
|
|
||||||
const confirmed = confirmationsTransactionSelector(store.getState(), { transaction: tx })
|
|
||||||
const data = tx.get('data')
|
|
||||||
expect(data).not.toBe(null)
|
|
||||||
expect(data).not.toBe(undefined)
|
|
||||||
expect(data).not.toBe('')
|
|
||||||
await processTransaction(safeAddress, tx, confirmed, executor)
|
|
||||||
await sleep(1800)
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should wait for confirmation to update threshold when safe has 1+ threshold', async () => {
|
|
||||||
// GIVEN
|
|
||||||
const numOwners = 3
|
|
||||||
const threshold = 2
|
|
||||||
const store = aNewStore()
|
|
||||||
const address = await aDeployedSafe(store, 10, threshold, numOwners)
|
|
||||||
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
|
|
||||||
const match: Match = buildMathPropsFrom(address)
|
|
||||||
const safe = safeSelector(store.getState(), { match })
|
|
||||||
if (!safe) throw new Error()
|
|
||||||
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
const nonce = Date.now()
|
|
||||||
const data = gnosisSafe.contract.changeThreshold.getData(3)
|
|
||||||
await createTransaction(safe, "Change Safe's threshold", address, 0, nonce, accounts[0], data)
|
|
||||||
await sleep(1500)
|
|
||||||
await store.dispatch(fetchTransactions())
|
|
||||||
|
|
||||||
let transactions = safeTransactionsSelector(store.getState(), { safeAddress: address })
|
|
||||||
if (!transactions) throw new Error()
|
|
||||||
expect(transactions.count()).toBe(1)
|
|
||||||
|
|
||||||
let thresholdTx = transactions.get(0)
|
|
||||||
if (!thresholdTx) throw new Error()
|
|
||||||
expect(thresholdTx.get('tx')).toBe('')
|
|
||||||
let firstOwnerConfirmation = thresholdTx.get('confirmations').get(0)
|
|
||||||
if (!firstOwnerConfirmation) throw new Error()
|
|
||||||
expect(firstOwnerConfirmation.get('status')).toBe(true)
|
|
||||||
let secondOwnerConfirmation = thresholdTx.get('confirmations').get(1)
|
|
||||||
if (!secondOwnerConfirmation) throw new Error()
|
|
||||||
expect(secondOwnerConfirmation.get('status')).toBe(false)
|
|
||||||
|
|
||||||
let safeThreshold = await gnosisSafe.getThreshold()
|
|
||||||
expect(Number(safeThreshold)).toEqual(2)
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
await changeThreshold(store, address, accounts[1])
|
|
||||||
safeThreshold = await gnosisSafe.getThreshold()
|
|
||||||
expect(Number(safeThreshold)).toEqual(3)
|
|
||||||
|
|
||||||
await store.dispatch(fetchTransactions())
|
|
||||||
sleep(1200)
|
|
||||||
transactions = safeTransactionsSelector(store.getState(), { safeAddress: address })
|
|
||||||
expect(transactions.count()).toBe(1)
|
|
||||||
|
|
||||||
thresholdTx = transactions.get(0)
|
|
||||||
if (!thresholdTx) throw new Error()
|
|
||||||
expect(thresholdTx.get('tx')).not.toBe(undefined)
|
|
||||||
expect(thresholdTx.get('tx')).not.toBe(null)
|
|
||||||
expect(thresholdTx.get('tx')).not.toBe('')
|
|
||||||
|
|
||||||
firstOwnerConfirmation = thresholdTx.get('confirmations').get(0)
|
|
||||||
if (!firstOwnerConfirmation) throw new Error()
|
|
||||||
expect(firstOwnerConfirmation.get('status')).toBe(true)
|
|
||||||
secondOwnerConfirmation = thresholdTx.get('confirmations').get(1)
|
|
||||||
if (!secondOwnerConfirmation) throw new Error()
|
|
||||||
expect(secondOwnerConfirmation.get('status')).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
*/
|
|
|
@ -1,9 +0,0 @@
|
||||||
// @flow
|
|
||||||
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
|
|
||||||
import { type GlobalState } from '~/store/index'
|
|
||||||
|
|
||||||
export const getTransactionFromReduxStore = (store: Store<GlobalState>, address: string, index: number = 0) => {
|
|
||||||
const transactions = safeTransactionsSelector(store.getState(), { safeAddress: address })
|
|
||||||
|
|
||||||
return transactions.get(index)
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
// @flow
|
Loading…
Reference in New Issue