From eaea640dfe683dd75cff4e8c043d34ca866646c8 Mon Sep 17 00:00:00 2001 From: delfipolito Date: Thu, 16 May 2019 06:08:40 -0300 Subject: [PATCH] =?UTF-8?q?Token=20Manager=20+=20Finance:=20edit=20label?= =?UTF-8?q?=20from=20a=20table=E2=80=99s=20context=20menu=20(#849)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IdentityManager/IdentityManager.js | 39 +++++++++- .../LocalIdentityBadge/LocalIdentityBadge.js | 34 +-------- .../finance/app/src/components/TransferRow.js | 62 ++++++++-------- .../app/src/components/icons/IconLabel.js | 14 ++++ .../app/src/components/HolderRow.js | 72 +++++++++++-------- .../app/src/components/IconLabel.js | 14 ++++ .../IdentityManager/IdentityManager.js | 39 +++++++++- .../LocalIdentityBadge/LocalIdentityBadge.js | 33 +-------- 8 files changed, 179 insertions(+), 128 deletions(-) create mode 100644 apps/finance/app/src/components/icons/IconLabel.js create mode 100644 apps/token-manager/app/src/components/IconLabel.js diff --git a/apps/finance/app/src/components/IdentityManager/IdentityManager.js b/apps/finance/app/src/components/IdentityManager/IdentityManager.js index 4b0b6014b6..7f757d7767 100644 --- a/apps/finance/app/src/components/IdentityManager/IdentityManager.js +++ b/apps/finance/app/src/components/IdentityManager/IdentityManager.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useCallback, useContext, useEffect, useState } from 'react' import PropTypes from 'prop-types' import { Subject } from 'rxjs' @@ -9,6 +9,41 @@ const IdentityContext = React.createContext({ Promise.reject(Error('Please set resolve using IdentityProvider')), }) +function useIdentity(address) { + const [name, setName] = useState(null) + const { resolve, updates$, showLocalIdentityModal } = useContext( + IdentityContext + ) + + const handleNameChange = useCallback(metadata => { + setName(metadata ? metadata.name : null) + }, []) + + const handleShowLocalIdentityModal = useCallback( + address => { + // Emit an event whenever the modal is closed (when the promise resolves) + return showLocalIdentityModal(address) + .then(() => updates$.next(address)) + .catch(e => null) + }, + [showLocalIdentityModal, updates$] + ) + + useEffect(() => { + resolve(address).then(handleNameChange) + + const subscription = updates$.subscribe(updatedAddress => { + if (updatedAddress.toLowerCase() === address.toLowerCase()) { + // Resolve and update state when the identity have been updated + resolve(address).then(handleNameChange) + } + }) + return () => subscription.unsubscribe() + }, [address, handleNameChange, updates$]) + + return [name, handleShowLocalIdentityModal] +} + const IdentityProvider = ({ onResolve, onShowLocalIdentityModal, @@ -33,4 +68,4 @@ IdentityProvider.propTypes = { const IdentityConsumer = IdentityContext.Consumer -export { IdentityProvider, IdentityConsumer, IdentityContext } +export { IdentityConsumer, IdentityContext, IdentityProvider, useIdentity } diff --git a/apps/finance/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js b/apps/finance/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js index bdda1a3df8..4fbf4ff1b1 100644 --- a/apps/finance/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js +++ b/apps/finance/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js @@ -2,39 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import styled from 'styled-components' import { Badge, IdentityBadge, font } from '@aragon/ui' -import { IdentityContext } from '../IdentityManager/IdentityManager' - -function useIdentity(address) { - const [name, setName] = React.useState(null) - const { resolve, updates$, showLocalIdentityModal } = React.useContext( - IdentityContext - ) - - const handleNameChange = metadata => { - setName(metadata ? metadata.name : null) - } - - const handleShowLocalIdentityModal = address => { - // Emit an event whenever the modal is closed (when the promise resolves) - return showLocalIdentityModal(address) - .then(() => updates$.next(address)) - .catch(e => null) - } - - React.useEffect(() => { - resolve(address).then(handleNameChange) - - const subscription = updates$.subscribe(updatedAddress => { - if (updatedAddress.toLowerCase() === address.toLowerCase()) { - // Resolve and update state when the identity have been updated - resolve(address).then(handleNameChange) - } - }) - return () => subscription.unsubscribe() - }, [address]) - - return [name, handleShowLocalIdentityModal] -} +import { useIdentity } from '../IdentityManager/IdentityManager' const LocalIdentityBadge = ({ entity, ...props }) => { const [label, showLocalIdentityModal] = useIdentity(entity) diff --git a/apps/finance/app/src/components/TransferRow.js b/apps/finance/app/src/components/TransferRow.js index 533a413f32..200efc4aa8 100644 --- a/apps/finance/app/src/components/TransferRow.js +++ b/apps/finance/app/src/components/TransferRow.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useCallback } from 'react' import styled from 'styled-components' import { format } from 'date-fns' import { useNetwork } from '@aragon/api-react' @@ -12,40 +12,37 @@ import { } from '@aragon/ui' import { formatTokenAmount } from '../lib/utils' import IconTokens from './icons/IconTokens' +import IconLabel from './icons/IconLabel' import LocalIdentityBadge from './LocalIdentityBadge/LocalIdentityBadge' +import { useIdentity } from './IdentityManager/IdentityManager' -class TransferRow extends React.PureComponent { - handleViewTransaction = () => { +const TransferRow = React.memo( + ({ network, transaction, token, smallViewMode }) => { const { - network, - transaction: { transactionHash }, - } = this.props - window.open( - blockExplorerUrl('transaction', transactionHash, { - networkType: network.type, - }), - '_blank' - ) - } + date, + entity, + isIncoming, + numData: { amount }, + reference, + transactionHash, + } = transaction - render() { - const { - network, - token, - smallViewMode, - transaction: { - date, - entity, - isIncoming, - numData: { amount }, - reference, - transactionHash, - }, - } = this.props + const handleViewTransaction = useCallback(() => { + window.open( + blockExplorerUrl('transaction', transactionHash, { + networkType: network.type, + }), + '_blank' + ) + }, [transactionHash, network]) + + const [label, showLocalIdentityModal] = useIdentity(entity) + const handleEditLabel = useCallback(() => showLocalIdentityModal(entity)) const txUrl = blockExplorerUrl('transaction', transactionHash, { networkType: network.type, }) + const formattedAmount = formatTokenAmount( amount, isIncoming, @@ -53,6 +50,7 @@ class TransferRow extends React.PureComponent { true, { rounding: 5 } ) + const formattedDate = format(date, "yyyy-MM-dd'T'HH:mm:ss.SSSxxx") if (smallViewMode) { @@ -115,10 +113,16 @@ class TransferRow extends React.PureComponent {
{txUrl && ( - +
View Transaction
+ + +
+ {label ? 'Edit' : 'Add'} custom label +
+
)}
@@ -126,7 +130,7 @@ class TransferRow extends React.PureComponent { ) } -} +) const StyledTableCell = styled(TableCell)` max-width: 0; diff --git a/apps/finance/app/src/components/icons/IconLabel.js b/apps/finance/app/src/components/icons/IconLabel.js new file mode 100644 index 0000000000..733ed5552c --- /dev/null +++ b/apps/finance/app/src/components/icons/IconLabel.js @@ -0,0 +1,14 @@ +import React from 'react' + +const Label = props => ( + + + +) + +export default Label diff --git a/apps/token-manager/app/src/components/HolderRow.js b/apps/token-manager/app/src/components/HolderRow.js index 9b43c5f260..47b77688b3 100644 --- a/apps/token-manager/app/src/components/HolderRow.js +++ b/apps/token-manager/app/src/components/HolderRow.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useCallback } from 'react' import styled from 'styled-components' import { ContextMenu, @@ -9,42 +9,40 @@ import { TableRow, theme, } from '@aragon/ui' +import IconLabel from './IconLabel' import { useNetwork } from '@aragon/api-react' import LocalIdentityBadge from './LocalIdentityBadge/LocalIdentityBadge' import { formatBalance } from '../utils' import You from './You' +import { useIdentity } from './IdentityManager/IdentityManager' -class HolderRow extends React.Component { - static defaultProps = { - address: '', - balance: 0, - groupMode: false, - onAssignTokens: () => {}, - onRemoveTokens: () => {}, - } - handleAssignTokens = () => { - const { address, onAssignTokens } = this.props - onAssignTokens(address) - } - handleRemoveTokens = () => { - const { address, onRemoveTokens } = this.props - onRemoveTokens(address) - } - render() { - const { - address, - balance, - groupMode, - isCurrentUser, - maxAccountTokens, - network, - tokenDecimalsBase, - compact, - } = this.props +const HolderRow = React.memo( + ({ + address, + balance, + groupMode, + isCurrentUser, + maxAccountTokens, + network, + tokenDecimalsBase, + compact, + onAssignTokens, + onRemoveTokens, + }) => { + const handleAssignTokens = useCallback(() => { + onAssignTokens(address) + }, [address, onAssignTokens]) + + const handleRemoveTokens = useCallback(() => { + onRemoveTokens(address) + }, [address, onRemoveTokens]) const singleToken = balance.eq(tokenDecimalsBase) const canAssign = balance.lt(maxAccountTokens) + const [label, showLocalIdentityModal] = useIdentity(address) + const handleEditLabel = useCallback(() => showLocalIdentityModal(address)) + return ( @@ -65,14 +63,14 @@ class HolderRow extends React.Component { {canAssign && ( - + Add tokens )} - + @@ -81,11 +79,25 @@ class HolderRow extends React.Component { {singleToken ? '' : 's'} + + + + + {label ? 'Edit' : 'Add'} custom label + ) } +) + +HolderRow.defaultProps = { + address: '', + balance: 0, + groupMode: false, + onAssignTokens: () => {}, + onRemoveTokens: () => {}, } const FirstTableCell = styled(TableCell)` diff --git a/apps/token-manager/app/src/components/IconLabel.js b/apps/token-manager/app/src/components/IconLabel.js new file mode 100644 index 0000000000..026fd6cc38 --- /dev/null +++ b/apps/token-manager/app/src/components/IconLabel.js @@ -0,0 +1,14 @@ +import React from 'react' + +const Label = props => ( + + + +) + +export default Label diff --git a/apps/token-manager/app/src/components/IdentityManager/IdentityManager.js b/apps/token-manager/app/src/components/IdentityManager/IdentityManager.js index 4b0b6014b6..7f757d7767 100644 --- a/apps/token-manager/app/src/components/IdentityManager/IdentityManager.js +++ b/apps/token-manager/app/src/components/IdentityManager/IdentityManager.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useCallback, useContext, useEffect, useState } from 'react' import PropTypes from 'prop-types' import { Subject } from 'rxjs' @@ -9,6 +9,41 @@ const IdentityContext = React.createContext({ Promise.reject(Error('Please set resolve using IdentityProvider')), }) +function useIdentity(address) { + const [name, setName] = useState(null) + const { resolve, updates$, showLocalIdentityModal } = useContext( + IdentityContext + ) + + const handleNameChange = useCallback(metadata => { + setName(metadata ? metadata.name : null) + }, []) + + const handleShowLocalIdentityModal = useCallback( + address => { + // Emit an event whenever the modal is closed (when the promise resolves) + return showLocalIdentityModal(address) + .then(() => updates$.next(address)) + .catch(e => null) + }, + [showLocalIdentityModal, updates$] + ) + + useEffect(() => { + resolve(address).then(handleNameChange) + + const subscription = updates$.subscribe(updatedAddress => { + if (updatedAddress.toLowerCase() === address.toLowerCase()) { + // Resolve and update state when the identity have been updated + resolve(address).then(handleNameChange) + } + }) + return () => subscription.unsubscribe() + }, [address, handleNameChange, updates$]) + + return [name, handleShowLocalIdentityModal] +} + const IdentityProvider = ({ onResolve, onShowLocalIdentityModal, @@ -33,4 +68,4 @@ IdentityProvider.propTypes = { const IdentityConsumer = IdentityContext.Consumer -export { IdentityProvider, IdentityConsumer, IdentityContext } +export { IdentityConsumer, IdentityContext, IdentityProvider, useIdentity } diff --git a/apps/token-manager/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js b/apps/token-manager/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js index bdda1a3df8..657ea3f67e 100644 --- a/apps/token-manager/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js +++ b/apps/token-manager/app/src/components/LocalIdentityBadge/LocalIdentityBadge.js @@ -3,38 +3,7 @@ import PropTypes from 'prop-types' import styled from 'styled-components' import { Badge, IdentityBadge, font } from '@aragon/ui' import { IdentityContext } from '../IdentityManager/IdentityManager' - -function useIdentity(address) { - const [name, setName] = React.useState(null) - const { resolve, updates$, showLocalIdentityModal } = React.useContext( - IdentityContext - ) - - const handleNameChange = metadata => { - setName(metadata ? metadata.name : null) - } - - const handleShowLocalIdentityModal = address => { - // Emit an event whenever the modal is closed (when the promise resolves) - return showLocalIdentityModal(address) - .then(() => updates$.next(address)) - .catch(e => null) - } - - React.useEffect(() => { - resolve(address).then(handleNameChange) - - const subscription = updates$.subscribe(updatedAddress => { - if (updatedAddress.toLowerCase() === address.toLowerCase()) { - // Resolve and update state when the identity have been updated - resolve(address).then(handleNameChange) - } - }) - return () => subscription.unsubscribe() - }, [address]) - - return [name, handleShowLocalIdentityModal] -} +import { useIdentity } from '../IdentityManager/IdentityManager' const LocalIdentityBadge = ({ entity, ...props }) => { const [label, showLocalIdentityModal] = useIdentity(entity)