summaryrefslogtreecommitdiff
path: root/ui/app/components/addressbook
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2017-03-15 11:45:08 +0100
committerKali Kaneko (leap communications) <kali@leap.se>2017-03-15 19:09:47 +0100
commit5cbd979690212ac414bd7d399ec5183190fbf6f2 (patch)
tree2c3d8cff6451f5c4dce4198d25aaeaeee3f39e7f /ui/app/components/addressbook
parent03b874769c14a6dd8675cace24b11517848cebce (diff)
[feat] minimal addressbook ui
Diffstat (limited to 'ui/app/components/addressbook')
-rw-r--r--ui/app/components/addressbook/addressbook.less43
-rw-r--r--ui/app/components/addressbook/index.js37
-rw-r--r--ui/app/components/addressbook/key_list_item.js119
3 files changed, 185 insertions, 14 deletions
diff --git a/ui/app/components/addressbook/addressbook.less b/ui/app/components/addressbook/addressbook.less
index 53e505b6..5ca45411 100644
--- a/ui/app/components/addressbook/addressbook.less
+++ b/ui/app/components/addressbook/addressbook.less
@@ -1,6 +1,12 @@
+@left-margin: 30px;
+
.body {
- // background-color: #333;
+}
+
+.header .title {
+ line-height: 32px;
+ padding-left: 15px;
}
.darkBg {
@@ -30,5 +36,38 @@
.lightFg {
border-radius: 4px;
background-color: #fff;
- padding: 15px;
+}
+
+.key-list-item {
+ border-bottom: 1px solid #ccc;
+ .top-row {
+ &:hover {
+ background-color: #eee;
+ }
+ padding: 15px;
+ font-weight: bold;
+ font-size: 1.2em;
+ &:first-child {
+ border-radius: 4px 4px 0 0;
+ }
+ }
+ .expander {
+ width: @left-margin;
+ float: left;
+ .glyphicon {}
+ }
+ .address {
+ margin-left: @left-margin;
+ word-break: break-all;
+ }
+ .details {
+ margin-left: @left-margin;
+ padding: 15px;
+ }
+ .btn-toolbar {
+ margin-top: 15px;
+ }
+ .labels .label {
+ margin-left: 6px;
+ }
} \ No newline at end of file
diff --git a/ui/app/components/addressbook/index.js b/ui/app/components/addressbook/index.js
index 74c119d3..eeaab912 100644
--- a/ui/app/components/addressbook/index.js
+++ b/ui/app/components/addressbook/index.js
@@ -2,14 +2,15 @@
// Interface to the key manager
//
-
import React from 'react'
import App from 'app'
-import { ButtonToolbar, Button, Glyphicon, Alert } from 'react-bootstrap'
+import { Button, Glyphicon, Alert } from 'react-bootstrap'
import {VerticalLayout, Row} from 'components/layout'
-import bitmask from 'lib/bitmask'
+import Spinner from 'components/spinner'
+import KeyListItem from './key_list_item'
import './addressbook.less'
+import bitmask from 'lib/bitmask'
export default class Addressbook extends React.Component {
@@ -21,16 +22,17 @@ export default class Addressbook extends React.Component {
super(props)
this.state = {
keys: null,
+ loading: true,
errorMsg: ""
}
this.close = this.close.bind(this)
}
componentWillMount() {
- bitmask.keys.list(true).then(keys => {
- this.setState({keys: keys})
+ bitmask.keys.list(this.props.account.id, false).then(keys => {
+ this.setState({keys: keys, loading: false})
}, error => {
- this.setState({errorMsg: error})
+ this.setState({keys: null, loading: false, errorMsg: error})
})
}
@@ -41,6 +43,11 @@ export default class Addressbook extends React.Component {
render() {
let alert = null
let keyList = null
+ let spinner = null
+
+ if (this.state.loading) {
+ spinner = <Spinner />
+ }
if (this.state.errorMsg) {
alert = (
@@ -48,11 +55,15 @@ export default class Addressbook extends React.Component {
)
}
- keyList = <b>list of keys goes here</b>
+ if (this.state.keys) {
+ keyList = this.state.keys.map((theKey, i) => {
+ return <KeyListItem key={i} data={theKey} account={this.props.account} />
+ })
+ }
let buttons = (
<Button onClick={this.close} className="btn-inverse">
- <Glyphicon glyph="remove" />&nbsp;
+ <Glyphicon glyph="menu-left" />&nbsp;
Close
</Button>
)
@@ -60,17 +71,19 @@ export default class Addressbook extends React.Component {
let page = (
<VerticalLayout className="darkBg">
<Row className="header" size="shrink" gutter="8px">
- <div className="pull-right">
+ <div className="pull-left">
{buttons}
</div>
<div className="title">
- {this.props.account.address}
- <h1>Addressbook</h1>
+ {this.props.account.address} / Addressbook
</div>
</Row>
<Row className="lightFg" size="expand">
{alert}
- {keyList}
+ {spinner}
+ <div className="key-list">
+ {keyList}
+ </div>
</Row>
</VerticalLayout>
)
diff --git a/ui/app/components/addressbook/key_list_item.js b/ui/app/components/addressbook/key_list_item.js
new file mode 100644
index 00000000..b8bdad36
--- /dev/null
+++ b/ui/app/components/addressbook/key_list_item.js
@@ -0,0 +1,119 @@
+//
+// A key in the list of keys
+//
+
+import React from 'react'
+import { Glyphicon, Button, ButtonToolbar, Label } from 'react-bootstrap'
+import bitmask from 'lib/bitmask'
+
+export default class KeyListItem extends React.Component {
+
+ static get defaultProps() {return{
+ data: null, // the key as an Object
+ account: null // the account as an Account
+ }}
+
+ constructor(props) {
+ super(props)
+ this.state = {
+ expanded: false,
+ hidden: false,
+ deleting: false,
+ error: null
+ }
+ this.toggle = this.toggle.bind(this)
+ this.delete = this.delete.bind(this)
+ }
+
+ toggle() {
+ this.setState({expanded: !this.state.expanded})
+ }
+
+ delete() {
+ if (this.props.account.address == this.props.data.address) {
+ return // please do not delete your own key
+ }
+
+ bitmask.keys.del(this.props.account.id, this.props.data.address, false).then(
+ key => {
+ this.setState({hidden: true})
+ },
+ error => {
+ this.setState({error: error})
+ }
+ )
+ }
+
+ render() {
+ if (this.state.hidden) {
+ return <div></div>
+ } else if (!this.props.data) {
+ return (
+ <div className="key-list-item">
+ NO KEY
+ </div>
+ )
+ }
+
+ let details = null
+ let expander = null
+ let alert = null
+ let deleteButton = null
+ let labelArray = []
+ let labels = null
+ let glyph = this.state.expanded ? 'triangle-bottom' : 'triangle-right'
+
+ if (this.state.error) {
+ alert = (
+ <Alert bsStyle="danger">{this.state.error}</Alert>
+ )
+ }
+
+ if (this.props.account.address != this.props.data.address) {
+ deleteButton = <Button onClick={this.delete}>Delete</Button>
+ } else {
+ labelArray.push(<Label key="owner" bsStyle="primary">Mine</Label>)
+ labelArray.push(<Label key="level" bsStyle="success">Verified</Label>)
+ }
+
+ if (!this.props.data.encr_used) {
+ labelArray.push(<Label key="used" bsStyle="default">Never Used</Label>)
+ }
+
+ if (this.state.expanded) {
+ details = (
+ <div className="details">
+ {alert}
+ Security Identifier: {this.props.data.fingerprint}<br />
+ Last Updated: {this.props.data.refreshed_at}<br />
+ Expires On: {this.props.data.expiry_date}<br />
+ <ButtonToolbar>
+ <Button onClick={this.toggle}>Close</Button>
+ {deleteButton}
+ </ButtonToolbar>
+ </div>
+ )
+ }
+
+ expander = (
+ <div className="expander">
+ <Glyphicon glyph={glyph} />
+ </div>
+ )
+
+ return (
+ <div className="key-list-item">
+ <div className="top-row clickable" onClick={this.toggle} >
+ <div className="labels pull-right">
+ {labelArray}
+ </div>
+ {expander}
+ <div className="address">
+ {this.props.data.address}
+ </div>
+ </div>
+ {details}
+ </div>
+ )
+ }
+}