WIP: code cleanup and fix typings
This commit is contained in:
parent
3eba845314
commit
ebf8d149a2
|
@ -4,7 +4,11 @@ import TableRow from '@material-ui/core/TableRow'
|
|||
import TableSortLabel from '@material-ui/core/TableSortLabel'
|
||||
import * as React from 'react'
|
||||
|
||||
export const cellWidth = (width) => {
|
||||
interface CellWidth {
|
||||
maxWidth: string
|
||||
}
|
||||
|
||||
export const cellWidth = (width: string | number): CellWidth | undefined => {
|
||||
if (!width) {
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -32,17 +32,11 @@ export const WALLET_PROVIDER = {
|
|||
}
|
||||
|
||||
export const ETHEREUM_NETWORK_IDS = {
|
||||
// $FlowFixMe
|
||||
1: ETHEREUM_NETWORK.MAINNET,
|
||||
// $FlowFixMe
|
||||
2: ETHEREUM_NETWORK.MORDEN,
|
||||
// $FlowFixMe
|
||||
3: ETHEREUM_NETWORK.ROPSTEN,
|
||||
// $FlowFixMe
|
||||
4: ETHEREUM_NETWORK.RINKEBY,
|
||||
// $FlowFixMe
|
||||
5: ETHEREUM_NETWORK.GOERLI,
|
||||
// $FlowFixMe
|
||||
42: ETHEREUM_NETWORK.KOVAN,
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,15 @@ import { handleActions } from 'redux-actions'
|
|||
|
||||
import { ADD_PROVIDER } from 'src/logic/wallets/store/actions/addProvider'
|
||||
import { REMOVE_PROVIDER } from 'src/logic/wallets/store/actions/removeProvider'
|
||||
import { makeProvider } from 'src/logic/wallets/store/model/provider'
|
||||
import { makeProvider, ProviderRecord, ProviderProps } from 'src/logic/wallets/store/model/provider'
|
||||
|
||||
export const PROVIDER_REDUCER_ID = 'providers'
|
||||
|
||||
export default handleActions(
|
||||
{
|
||||
[ADD_PROVIDER]: (state, { payload }) => makeProvider(payload),
|
||||
[REMOVE_PROVIDER]: () => makeProvider(),
|
||||
[ADD_PROVIDER]: (state: { providers: ProviderProps }, { payload }: { payload: ProviderProps }): ProviderRecord =>
|
||||
makeProvider(payload),
|
||||
[REMOVE_PROVIDER]: (): ProviderRecord => makeProvider(),
|
||||
},
|
||||
makeProvider(),
|
||||
)
|
||||
|
|
|
@ -2,28 +2,30 @@ import { createSelector } from 'reselect'
|
|||
|
||||
import { ETHEREUM_NETWORK, ETHEREUM_NETWORK_IDS } from 'src/logic/wallets/getWeb3'
|
||||
import { PROVIDER_REDUCER_ID } from 'src/logic/wallets/store/reducer/provider'
|
||||
import { GnosisState } from 'src/store'
|
||||
import { ProviderRecord } from '../model/provider'
|
||||
|
||||
export const providerSelector = (state) => state[PROVIDER_REDUCER_ID]
|
||||
export const providerSelector = (state: GnosisState): ProviderRecord => state[PROVIDER_REDUCER_ID]
|
||||
|
||||
export const userAccountSelector = createSelector(providerSelector, (provider) => {
|
||||
export const userAccountSelector = createSelector(providerSelector, (provider: ProviderRecord): string => {
|
||||
const account = provider.get('account')
|
||||
|
||||
return account || ''
|
||||
})
|
||||
|
||||
export const providerNameSelector = createSelector(providerSelector, (provider) => {
|
||||
export const providerNameSelector = createSelector(providerSelector, (provider: ProviderRecord): string | undefined => {
|
||||
const name = provider.get('name')
|
||||
|
||||
return name ? name.toLowerCase() : undefined
|
||||
})
|
||||
|
||||
export const networkSelector = createSelector(providerSelector, (provider) => {
|
||||
export const networkSelector = createSelector(providerSelector, (provider: ProviderRecord): string => {
|
||||
const networkId = provider.get('network')
|
||||
const network = ETHEREUM_NETWORK_IDS[networkId] || ETHEREUM_NETWORK.UNKNOWN
|
||||
|
||||
return network
|
||||
return ETHEREUM_NETWORK_IDS[networkId] || ETHEREUM_NETWORK.UNKNOWN
|
||||
})
|
||||
|
||||
export const loadedSelector = createSelector(providerSelector, (provider) => provider.get('loaded'))
|
||||
export const loadedSelector = createSelector(providerSelector, (provider: ProviderRecord): boolean =>
|
||||
provider.get('loaded'),
|
||||
)
|
||||
|
||||
export const availableSelector = createSelector(providerSelector, (provider) => provider.get('available'))
|
||||
export const availableSelector = createSelector(providerSelector, (provider: ProviderRecord): boolean =>
|
||||
provider.get('available'),
|
||||
)
|
||||
|
|
|
@ -10,30 +10,31 @@ export const getModuleData = (modules: Set<string>): List<{ [MODULES_TABLE_ADDRE
|
|||
}
|
||||
|
||||
interface TableColumn {
|
||||
id: string
|
||||
order: boolean
|
||||
disablePadding: boolean
|
||||
label: string
|
||||
align?: 'inherit' | 'left' | 'center' | 'right' | 'justify'
|
||||
custom: boolean
|
||||
align?: string
|
||||
disablePadding: boolean
|
||||
id: string
|
||||
label: string
|
||||
order: boolean
|
||||
width?: number
|
||||
}
|
||||
|
||||
export const generateColumns = (): List<TableColumn> => {
|
||||
const addressColumn: TableColumn = {
|
||||
id: MODULES_TABLE_ADDRESS_ID,
|
||||
order: false,
|
||||
disablePadding: false,
|
||||
label: 'Address',
|
||||
custom: false,
|
||||
align: 'left',
|
||||
custom: false,
|
||||
disablePadding: false,
|
||||
id: MODULES_TABLE_ADDRESS_ID,
|
||||
label: 'Address',
|
||||
order: false,
|
||||
}
|
||||
|
||||
const actionsColumn: TableColumn = {
|
||||
id: MODULES_TABLE_ACTIONS_ID,
|
||||
order: false,
|
||||
disablePadding: false,
|
||||
label: '',
|
||||
custom: true,
|
||||
disablePadding: false,
|
||||
id: MODULES_TABLE_ACTIONS_ID,
|
||||
label: '',
|
||||
order: false,
|
||||
}
|
||||
|
||||
return List([addressColumn, actionsColumn])
|
||||
|
|
|
@ -1,101 +1,86 @@
|
|||
import { Set } from 'immutable'
|
||||
import { GenericModal, ModalFooterConfirmation } from '@gnosis.pm/safe-react-components'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
// import { useSnackbar } from 'notistack'
|
||||
import React, { useState } from 'react'
|
||||
import { /*useDispatch, */ useSelector } from 'react-redux'
|
||||
import TableContainer from '@material-ui/core/TableContainer'
|
||||
import cn from 'classnames'
|
||||
import { Set } from 'immutable'
|
||||
import { useSnackbar } from 'notistack'
|
||||
import React from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
// import ChangeThreshold from './ChangeThreshold'
|
||||
import { generateColumns, MODULES_TABLE_ADDRESS_ID, getModuleData } from './dataFetcher'
|
||||
import { styles } from './style'
|
||||
import BinIcon from '../assets/icons/bin.svg'
|
||||
|
||||
import Modal from 'src/components/Modal'
|
||||
import DividerLine from 'src/components/DividerLine'
|
||||
import Identicon from 'src/components/Identicon'
|
||||
import Block from 'src/components/layout/Block'
|
||||
import Bold from 'src/components/layout/Bold'
|
||||
// import Button from 'src/components/layout/Button'
|
||||
import Heading from 'src/components/layout/Heading'
|
||||
import Img from 'src/components/layout/Img'
|
||||
import Paragraph from 'src/components/layout/Paragraph'
|
||||
// import Row from 'src/components/layout/Row'
|
||||
// import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
// import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
// import { grantedSelector } from 'src/routes/safe/container/selector'
|
||||
// import createTransaction from 'src/routes/safe/store/actions/createTransaction'
|
||||
import Row from 'src/components/layout/Row'
|
||||
import { TableCell, TableRow } from 'src/components/layout/Table'
|
||||
import Table from 'src/components/Table'
|
||||
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { grantedSelector } from 'src/routes/safe/container/selector'
|
||||
import createTransaction from 'src/routes/safe/store/actions/createTransaction'
|
||||
import {
|
||||
// safeOwnersSelector,
|
||||
// safeParamAddressFromStateSelector,
|
||||
// safeThresholdSelector,
|
||||
safeParamAddressFromStateSelector,
|
||||
safeNonceSelector,
|
||||
safeModulesSelector,
|
||||
} from 'src/routes/safe/store/selectors'
|
||||
import DividerLine from 'src/components/DividerLine'
|
||||
import TableContainer from '@material-ui/core/TableContainer'
|
||||
import Table from '../../../../../components/Table'
|
||||
import TableRow from '@material-ui/core/TableRow'
|
||||
import TableCell from '@material-ui/core/TableCell'
|
||||
import { cellWidth } from '../../../../../components/Table/TableHead'
|
||||
import OwnerAddressTableCell from '../ManageOwners/OwnerAddressTableCell'
|
||||
import Row from '../../../../../components/layout/Row'
|
||||
import Img from '../../../../../components/layout/Img'
|
||||
// import RenameOwnerIcon from '../ManageOwners/assets/icons/rename-owner.svg'
|
||||
// import ReplaceOwnerIcon from '../ManageOwners/assets/icons/replace-owner.svg'
|
||||
import RemoveOwnerIcon from '../assets/icons/bin.svg'
|
||||
import { generateColumns, MODULES_TABLE_ADDRESS_ID, getModuleData } from './dataFetcher'
|
||||
import { grantedSelector } from '../../../container/selector'
|
||||
// import RemoveOwnerModal from '../ManageOwners/RemoveOwnerModal'
|
||||
// import { getOwnersWithNameFromAddressBook } from '../../../../../logic/addressBook/utils'
|
||||
// import { getOwnerData } from '../ManageOwners/dataFetcher'
|
||||
|
||||
export const REMOVE_MODULE_BTN_TEST_ID = 'remove-module-btn'
|
||||
export const MODULES_ROW_TEST_ID = 'owners-row'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const useToggle = (initialOn = false) => {
|
||||
const [on, setOn] = useState(initialOn)
|
||||
const toggle = () => setOn(!on)
|
||||
|
||||
return { on, toggle }
|
||||
}
|
||||
|
||||
const Advanced: React.FC = () => {
|
||||
const classes = useStyles()
|
||||
|
||||
const columns = generateColumns()
|
||||
const autoColumns = columns.filter(({ custom }) => !custom)
|
||||
|
||||
// const { enqueueSnackbar, closeSnackbar } = useSnackbar()
|
||||
// const dispatch = useDispatch()
|
||||
|
||||
const { on, toggle } = useToggle()
|
||||
|
||||
const safeAddress = useSelector(safeParamAddressFromStateSelector)
|
||||
const nonce = useSelector(safeNonceSelector)
|
||||
const granted = useSelector(grantedSelector)
|
||||
const modules = useSelector(safeModulesSelector)
|
||||
console.log(modules)
|
||||
const moduleData = getModuleData(Set(modules))
|
||||
// const ownersAdbk = getOwnersWithNameFromAddressBook(addressBook, owners)
|
||||
// const ownerData = getOwnerData(ownersAdbk)
|
||||
|
||||
// const safeAddress = useSelector(safeParamAddressFromStateSelector)
|
||||
// const owners = useSelector(safeOwnersSelector)
|
||||
const [viewRemoveModuleModal, setViewRemoveModuleModal] = React.useState(false)
|
||||
const hideRemoveModuleModal = () => setViewRemoveModuleModal(false)
|
||||
|
||||
// const onChangeThreshold = async (newThreshold) => {
|
||||
// const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||
// const txData = safeInstance.contract.methods.changeThreshold(newThreshold).encodeABI()
|
||||
//
|
||||
// dispatch(
|
||||
// createTransaction({
|
||||
// safeAddress,
|
||||
// to: safeAddress,
|
||||
// valueInWei: 0,
|
||||
// txData,
|
||||
// notifiedTransaction: TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX,
|
||||
// enqueueSnackbar,
|
||||
// closeSnackbar,
|
||||
// } as any),
|
||||
// )
|
||||
// }
|
||||
const [selectedModule, setSelectedModule] = React.useState(null)
|
||||
const triggerRemoveSelectedModule = (moduleAddress: string): void => {
|
||||
setSelectedModule(moduleAddress)
|
||||
setViewRemoveModuleModal(true)
|
||||
}
|
||||
|
||||
const { enqueueSnackbar, closeSnackbar } = useSnackbar()
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const removeSelectedModule = async (): Promise<void> => {
|
||||
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||
const txData = safeInstance.contract.methods.disableModule(selectedModule).encodeABI()
|
||||
|
||||
dispatch(
|
||||
createTransaction({
|
||||
safeAddress,
|
||||
to: safeAddress,
|
||||
valueInWei: '0',
|
||||
txData,
|
||||
notifiedTransaction: TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX,
|
||||
enqueueSnackbar,
|
||||
closeSnackbar,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Nonce */}
|
||||
<Block className={classes.container}>
|
||||
<Heading tag="h2">Safe Nonce</Heading>
|
||||
<Paragraph>
|
||||
|
@ -107,6 +92,8 @@ const Advanced: React.FC = () => {
|
|||
</Paragraph>
|
||||
</Block>
|
||||
<DividerLine withArrow={false} />
|
||||
|
||||
{/* Modules */}
|
||||
<Block className={classes.container}>
|
||||
<Heading tag="h2">Safe Modules</Heading>
|
||||
<Paragraph>
|
||||
|
@ -145,23 +132,31 @@ const Advanced: React.FC = () => {
|
|||
key={index}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{autoColumns.map((column: any) => (
|
||||
<TableCell align={column.align} component="td" key={column.id} style={cellWidth(column.width)}>
|
||||
{column.id === MODULES_TABLE_ADDRESS_ID ? (
|
||||
<OwnerAddressTableCell address={row[column.id]} showLinks />
|
||||
{autoColumns.map((column) => {
|
||||
const columnId = column.id
|
||||
const rowElement = row[columnId]
|
||||
|
||||
return (
|
||||
<TableCell align={column.align} component="td" key={columnId}>
|
||||
{columnId === MODULES_TABLE_ADDRESS_ID ? (
|
||||
<Block justify="left">
|
||||
<Identicon address={rowElement} diameter={32} />
|
||||
<Paragraph style={{ marginLeft: 10 }}>{rowElement}</Paragraph>
|
||||
</Block>
|
||||
) : (
|
||||
row[column.id]
|
||||
rowElement
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
<TableCell component="td">
|
||||
<Row align="end" className={classes.actions}>
|
||||
{granted && (
|
||||
<Img
|
||||
alt="Remove module"
|
||||
className={classes.removeModuleIcon}
|
||||
onClick={toggle}
|
||||
src={RemoveOwnerIcon}
|
||||
onClick={triggerRemoveSelectedModule}
|
||||
src={BinIcon}
|
||||
testId={REMOVE_MODULE_BTN_TEST_ID}
|
||||
/>
|
||||
)}
|
||||
|
@ -174,21 +169,21 @@ const Advanced: React.FC = () => {
|
|||
</TableContainer>
|
||||
)}
|
||||
</Block>
|
||||
{/*<RemoveModuleModal*/}
|
||||
{/* isOpen={showRemoveModal}*/}
|
||||
{/* onClose={onHide('RemoveModal')}*/}
|
||||
{/* ownerAddress={selectedModalAddress}*/}
|
||||
{/* ownerName={selectedModalName}*/}
|
||||
{/*/>*/}
|
||||
<Modal description="Disable Module" handleClose={toggle} open={on} title="Disable Module">
|
||||
{/*<ChangeThreshold*/}
|
||||
{/* onChangeThreshold={onChangeThreshold}*/}
|
||||
{/* onClose={toggle}*/}
|
||||
{/* owners={owners}*/}
|
||||
{/* safeAddress={safeAddress}*/}
|
||||
{/* threshold={threshold}*/}
|
||||
{/*/>*/}
|
||||
</Modal>
|
||||
{viewRemoveModuleModal && (
|
||||
<GenericModal
|
||||
onClose={hideRemoveModuleModal}
|
||||
title="Disable Module"
|
||||
body={<div>This is the body</div>}
|
||||
footer={
|
||||
<ModalFooterConfirmation
|
||||
okText="Remove"
|
||||
cancelText="Cancel"
|
||||
handleCancel={hideRemoveModuleModal}
|
||||
handleOk={removeSelectedModule}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { push } from 'connected-react-router'
|
||||
import { List, Map } from 'immutable'
|
||||
import { WithSnackbarProps } from 'notistack'
|
||||
import { batch } from 'react-redux'
|
||||
import semverSatisfies from 'semver/functions/satisfies'
|
||||
|
||||
|
@ -35,6 +36,8 @@ import { makeConfirmation } from '../models/confirmation'
|
|||
import fetchTransactions from './transactions/fetchTransactions'
|
||||
import { safeTransactionsSelector } from 'src/routes/safe/store/selectors'
|
||||
import { TransactionStatus, TxArgs } from 'src/routes/safe/store/models/types/transaction'
|
||||
import { Dispatch } from 'redux'
|
||||
import { GnosisState } from 'src/store'
|
||||
|
||||
export const removeTxFromStore = (tx, safeAddress, dispatch, state) => {
|
||||
if (tx.isCancellationTx) {
|
||||
|
@ -79,6 +82,18 @@ export const storeTx = async (tx, safeAddress, dispatch, state) => {
|
|||
}
|
||||
}
|
||||
|
||||
interface CreateTransaction extends WithSnackbarProps {
|
||||
navigateToTransactionsTab?: boolean
|
||||
notifiedTransaction: string
|
||||
operation?: number
|
||||
origin?: string
|
||||
safeAddress: string
|
||||
to: string
|
||||
txData: string
|
||||
txNonce?: number | string
|
||||
valueInWei: string
|
||||
}
|
||||
|
||||
const createTransaction = ({
|
||||
safeAddress,
|
||||
to,
|
||||
|
@ -91,7 +106,7 @@ const createTransaction = ({
|
|||
operation = CALL,
|
||||
navigateToTransactionsTab = true,
|
||||
origin = null,
|
||||
}) => async (dispatch, getState) => {
|
||||
}: CreateTransaction) => async (dispatch: Dispatch, getState: () => GnosisState): Promise<void> => {
|
||||
const state = getState()
|
||||
|
||||
if (navigateToTransactionsTab) {
|
||||
|
|
|
@ -181,7 +181,7 @@ const baseSafe = makeSafe()
|
|||
|
||||
export const safeFieldSelector = (field: keyof SafeRecordProps) => (
|
||||
safe: SafeRecord,
|
||||
): SafeRecord[keyof SafeRecordProps] => safe.get(field, baseSafe.get(field))
|
||||
): SafeRecord[keyof SafeRecordProps] | null => (safe ? safe.get(field, baseSafe.get(field)) : null)
|
||||
|
||||
export const safeNameSelector = createSelector(safeSelector, safeFieldSelector('name'))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { connectRouter, routerMiddleware } from 'connected-react-router'
|
||||
import { createHashHistory } from 'history'
|
||||
import { applyMiddleware, combineReducers, compose, createStore } from 'redux'
|
||||
import { applyMiddleware, combineReducers, compose, createStore, CombinedState } from 'redux'
|
||||
import thunk from 'redux-thunk'
|
||||
|
||||
import addressBookMiddleware from 'src/logic/addressBook/store/middleware/addressBookMiddleware'
|
||||
|
@ -29,6 +29,8 @@ import incomingTransactions, {
|
|||
} from 'src/routes/safe/store/reducer/incomingTransactions'
|
||||
import safe, { SAFE_REDUCER_ID } from 'src/routes/safe/store/reducer/safe'
|
||||
import transactions, { TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/transactions'
|
||||
import { ProviderRecord } from '../logic/wallets/store/model/provider'
|
||||
import { SafeRecordProps } from '../routes/safe/store/models/safe'
|
||||
|
||||
export const history = createHashHistory({ hashType: 'slash' })
|
||||
|
||||
|
@ -63,6 +65,22 @@ const reducers = combineReducers({
|
|||
[CURRENT_SESSION_REDUCER_ID]: currentSession,
|
||||
})
|
||||
|
||||
export type GnosisState = CombinedState<{
|
||||
[PROVIDER_REDUCER_ID]: ProviderRecord
|
||||
[SAFE_REDUCER_ID]: SafeRecordProps
|
||||
// [NFT_ASSETS_REDUCER_ID]: nftAssetReducer,
|
||||
// [NFT_TOKENS_REDUCER_ID]: nftTokensReducer,
|
||||
// [TOKEN_REDUCER_ID]: tokens,
|
||||
// [TRANSACTIONS_REDUCER_ID]: transactions,
|
||||
// [CANCELLATION_TRANSACTIONS_REDUCER_ID]: cancellationTransactions,
|
||||
// [INCOMING_TRANSACTIONS_REDUCER_ID]: incomingTransactions,
|
||||
// [NOTIFICATIONS_REDUCER_ID]: notifications,
|
||||
// [CURRENCY_VALUES_KEY]: currencyValues,
|
||||
// [COOKIES_REDUCER_ID]: cookies,
|
||||
// [ADDRESS_BOOK_REDUCER_ID]: addressBook,
|
||||
// [CURRENT_SESSION_REDUCER_ID]: currentSession,
|
||||
}>
|
||||
|
||||
export const store: any = createStore(reducers, finalCreateStore)
|
||||
|
||||
export const aNewStore = (localState?: any) => createStore(reducers, localState, finalCreateStore)
|
||||
|
|
Loading…
Reference in New Issue