Skip to content

Commit

Permalink
Token Manager + Finance: edit label from a table’s context menu (arag…
Browse files Browse the repository at this point in the history
  • Loading branch information
delfipolito authored and bpierre committed May 16, 2019
1 parent 0ecaf2d commit 8593cfa
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 64 deletions.
72 changes: 42 additions & 30 deletions app/src/components/HolderRow.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useCallback } from 'react'
import styled from 'styled-components'
import {
ContextMenu,
Expand All @@ -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 (
<TableRow>
<FirstTableCell css="padding-right: 0">
Expand All @@ -65,14 +63,14 @@ class HolderRow extends React.Component {
<TableCell align="right" css="padding-left: 0">
<ContextMenu>
{canAssign && (
<ContextMenuItem onClick={this.handleAssignTokens}>
<ContextMenuItem onClick={handleAssignTokens}>
<IconWrapper>
<IconAdd />
</IconWrapper>
<ActionLabel>Add tokens</ActionLabel>
</ContextMenuItem>
)}
<ContextMenuItem onClick={this.handleRemoveTokens}>
<ContextMenuItem onClick={handleRemoveTokens}>
<IconWrapper>
<IconRemove />
</IconWrapper>
Expand All @@ -81,11 +79,25 @@ class HolderRow extends React.Component {
{singleToken ? '' : 's'}
</ActionLabel>
</ContextMenuItem>
<ContextMenuItem onClick={handleEditLabel}>
<IconWrapper>
<IconLabel />
</IconWrapper>
<ActionLabel>{label ? 'Edit' : 'Add'} custom label</ActionLabel>
</ContextMenuItem>
</ContextMenu>
</TableCell>
</TableRow>
)
}
)

HolderRow.defaultProps = {
address: '',
balance: 0,
groupMode: false,
onAssignTokens: () => {},
onRemoveTokens: () => {},
}

const FirstTableCell = styled(TableCell)`
Expand Down
14 changes: 14 additions & 0 deletions app/src/components/IconLabel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react'

const Label = props => (
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" {...props}>
<path
d="M11.5404 19.0354L11.5758 19.0707L11.6111 19.0354C14.0854 16.5604 16.5604 14.0854 19.0354 11.6111L19.0708 11.5757L19.0353 11.5403L8.42655 0.96459L8.41191 0.95H8.39125H1H0.95V1V8.42125V8.44196L0.96464 8.4566L11.5404 19.0354ZM6.84037 4.11766L6.84036 4.11764C6.08883 3.36612 4.86917 3.36612 4.11764 4.11764C3.36612 4.86917 3.36612 6.08883 4.11764 6.84036L4.11766 6.84037C4.86918 7.59113 6.08882 7.59113 6.84034 6.84037L6.84037 6.84034C7.59113 6.08882 7.59113 4.86918 6.84037 4.11766ZM6.23868 6.23861L6.23861 6.23868C5.81941 6.65859 5.1386 6.65864 4.71861 6.23864C4.29941 5.81945 4.29935 5.13861 4.71861 4.71861C5.13861 4.29935 5.81945 4.29941 6.23864 4.71861C6.65864 5.1386 6.65859 5.81941 6.23868 6.23861ZM8.06084 1.8C11.3299 5.05861 14.5989 8.31721 17.868 11.5766L11.5758 17.8688L1.8 8.09004V1.8H8.06084Z"
fill="#99A0A2"
stroke="#8B9396"
strokeWidth="0.1"
/>
</svg>
)

export default Label
39 changes: 37 additions & 2 deletions app/src/components/IdentityManager/IdentityManager.js
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -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,
Expand All @@ -33,4 +68,4 @@ IdentityProvider.propTypes = {

const IdentityConsumer = IdentityContext.Consumer

export { IdentityProvider, IdentityConsumer, IdentityContext }
export { IdentityConsumer, IdentityContext, IdentityProvider, useIdentity }
33 changes: 1 addition & 32 deletions app/src/components/LocalIdentityBadge/LocalIdentityBadge.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 8593cfa

Please sign in to comment.