mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add ActivityLog component
This commit is contained in:
parent
ce1975fbb4
commit
930dac110a
@ -17,6 +17,9 @@
|
||||
"accountSelectionRequired": {
|
||||
"message": "You need to select an account!"
|
||||
},
|
||||
"activityLog": {
|
||||
"message": "activity log"
|
||||
},
|
||||
"address": {
|
||||
"message": "Address"
|
||||
},
|
||||
|
25
ui/app/components/card/card.component.js
Normal file
25
ui/app/components/card/card.component.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
|
||||
export default class Card extends PureComponent {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
overrideClassName: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, overrideClassName, title } = this.props
|
||||
|
||||
return (
|
||||
<div className={classnames({ 'card': !overrideClassName }, className)}>
|
||||
<div className="card__title">
|
||||
{ title }
|
||||
</div>
|
||||
{ this.props.children }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
1
ui/app/components/card/index.js
Normal file
1
ui/app/components/card/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './card.component'
|
11
ui/app/components/card/index.scss
Normal file
11
ui/app/components/card/index.scss
Normal file
@ -0,0 +1,11 @@
|
||||
.card {
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08);
|
||||
padding: 16px 8px;
|
||||
|
||||
&__title {
|
||||
border-bottom: 1px solid #d8d8d8;
|
||||
padding-bottom: 4px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
@import './button-group/index';
|
||||
|
||||
@import './card/index';
|
||||
|
||||
@import './confirm-page-container/index';
|
||||
|
||||
@import './export-text-container/index';
|
||||
@ -24,6 +26,8 @@
|
||||
|
||||
@import './tabs/index';
|
||||
|
||||
@import './transaction-activity-log/index';
|
||||
|
||||
@import './transaction-view/index';
|
||||
|
||||
@import './transaction-view-balance/index';
|
||||
|
@ -80,7 +80,6 @@
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
padding: 8px;
|
||||
|
||||
.sender-to-recipient {
|
||||
&__party {
|
||||
|
1
ui/app/components/transaction-activity-log/index.js
Normal file
1
ui/app/components/transaction-activity-log/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './transaction-activity-log.component'
|
53
ui/app/components/transaction-activity-log/index.scss
Normal file
53
ui/app/components/transaction-activity-log/index.scss
Normal file
@ -0,0 +1,53 @@
|
||||
.transaction-activity-log {
|
||||
&__card {
|
||||
background: $white;
|
||||
}
|
||||
|
||||
&__activities-container {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
&__activity {
|
||||
padding: 4px 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 6px;
|
||||
border-right: 1px solid $scorpion;
|
||||
}
|
||||
|
||||
&:first-child::after {
|
||||
height: 50%;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
&:last-child::after {
|
||||
height: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&__activity-icon {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
margin-right: 6px;
|
||||
border-radius: 50%;
|
||||
background: $scorpion;
|
||||
}
|
||||
|
||||
&__activity-text {
|
||||
color: $scorpion;
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
b {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { getActivities } from './transaction-activity-log.util'
|
||||
import Card from '../card'
|
||||
|
||||
export default class TransactionActivityLog extends PureComponent {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
transaction: PropTypes.object,
|
||||
}
|
||||
|
||||
state = {
|
||||
activities: [],
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.setActivites()
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
const { transaction: { history: prevHistory = [] } = {} } = prevProps
|
||||
const { transaction: { history = [] } = {} } = this.props
|
||||
|
||||
if (prevHistory.length !== history.length) {
|
||||
this.setActivites()
|
||||
}
|
||||
}
|
||||
|
||||
setActivites () {
|
||||
const activities = getActivities(this.props.transaction)
|
||||
this.setState({ activities })
|
||||
}
|
||||
|
||||
renderActivity (activity, index) {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="transaction-activity-log__activity"
|
||||
>
|
||||
<div className="transaction-activity-log__activity-icon" />
|
||||
{ this.renderActivityText(activity) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderActivityText (activity) {
|
||||
const { eventKey, value, valueDescriptionKey } = activity
|
||||
|
||||
return (
|
||||
<div className="transaction-activity-log__activity-text">
|
||||
{ `Transaction ` }
|
||||
<b>{ `${eventKey}` }</b>
|
||||
{
|
||||
valueDescriptionKey && value
|
||||
? (
|
||||
<span>
|
||||
{ ` with a ${valueDescriptionKey} of ` }
|
||||
<b>{ value }</b>
|
||||
.
|
||||
</span>
|
||||
) : '.'
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { t } = this.context
|
||||
const { activities } = this.state
|
||||
|
||||
return (
|
||||
<div className="transaction-activity-log">
|
||||
<Card
|
||||
title={t('activityLog')}
|
||||
className="transaction-activity-log__card"
|
||||
>
|
||||
<div className="transaction-activity-log__activities-container">
|
||||
{
|
||||
activities.map((activity, index) => (
|
||||
this.renderActivity(activity, index)
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
// path constants
|
||||
const STATUS_PATH = '/status'
|
||||
const GAS_PRICE_PATH = '/txParams/gasPrice'
|
||||
|
||||
// status constants
|
||||
const STATUS_UNAPPROVED = 'unapproved'
|
||||
const STATUS_SUBMITTED = 'submitted'
|
||||
const STATUS_CONFIRMED = 'confirmed'
|
||||
const STATUS_DROPPED = 'dropped'
|
||||
|
||||
// op constants
|
||||
const REPLACE_OP = 'replace'
|
||||
|
||||
const eventPathsHash = {
|
||||
[STATUS_PATH]: true,
|
||||
[GAS_PRICE_PATH]: true,
|
||||
}
|
||||
|
||||
const statusHash = {
|
||||
[STATUS_SUBMITTED]: true,
|
||||
[STATUS_CONFIRMED]: true,
|
||||
[STATUS_DROPPED]: true,
|
||||
}
|
||||
|
||||
function eventCreator (eventKey, timestamp, value, valueDescriptionKey) {
|
||||
return {
|
||||
eventKey,
|
||||
timestamp,
|
||||
value,
|
||||
valueDescriptionKey,
|
||||
}
|
||||
}
|
||||
|
||||
export function getActivities (transaction) {
|
||||
const { history = [] } = transaction
|
||||
|
||||
return history.reduce((acc, base) => {
|
||||
// First history item should be transaction creation
|
||||
if (!Array.isArray(base) && base.status === STATUS_UNAPPROVED && base.txParams) {
|
||||
const { time, txParams: { value } = {} } = base
|
||||
return acc.concat(eventCreator('created', time, value, 'value'))
|
||||
} else if (Array.isArray(base)) {
|
||||
const events = []
|
||||
|
||||
base.forEach(entry => {
|
||||
const { op, path, value, timestamp } = entry
|
||||
|
||||
if (path in eventPathsHash && op === REPLACE_OP) {
|
||||
switch (path) {
|
||||
case STATUS_PATH: {
|
||||
if (value in statusHash) {
|
||||
events.push(eventCreator(value, timestamp))
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case GAS_PRICE_PATH: {
|
||||
events.push(eventCreator('updated', timestamp, value, 'gasPrice'))
|
||||
break
|
||||
}
|
||||
|
||||
default: {
|
||||
events.push(eventCreator(value, timestamp))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return acc.concat(events)
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [])
|
||||
}
|
Loading…
Reference in New Issue
Block a user