diff options
| -rw-r--r-- | ui/app/app.js | 4 | ||||
| -rw-r--r-- | ui/app/components/confirmation.js | 43 | ||||
| -rw-r--r-- | ui/app/components/login.js | 2 | ||||
| -rw-r--r-- | ui/app/components/main_panel/account_list.js | 30 | ||||
| -rw-r--r-- | ui/app/components/main_panel/index.js | 25 | ||||
| -rw-r--r-- | ui/app/models/account.js | 32 | 
6 files changed, 119 insertions, 17 deletions
| diff --git a/ui/app/app.js b/ui/app/app.js index 75c7cb8..a27cba6 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -21,12 +21,12 @@ class Application {    start() {      Provider.list(false).then(domains => { -      Account.initialize_list(domains) +      Account.initializeList(domains)        Account.active().then(account => {          if (account == null) {            this.show('greeter')          } else { -          Account.add_primary(account) +          Account.addPrimary(account)            this.show('main', {initialAccount: account})          }        }, error => { diff --git a/ui/app/components/confirmation.js b/ui/app/components/confirmation.js new file mode 100644 index 0000000..6918616 --- /dev/null +++ b/ui/app/components/confirmation.js @@ -0,0 +1,43 @@ +// +// A simple diagon that asks if you are sure. +// + +import React from 'react' +import {Button, ButtonGroup, ButtonToolbar, Glyphicon, Modal} +  from 'react-bootstrap' + +export default class Confirmation extends React.Component { + +  static get defaultProps() {return{ +    title: "Are you sure?", +    onCancel: null, +    onAccept: null, +    acceptStr: 'Accept', +    cancelStr: 'Cancel' +  }} + +  constructor(props) { +    super(props) +  } + +  render() { +    return ( +      <Modal show={true} onHide={this.props.onCancel}> +        <Modal.Header closeButton> +          <Modal.Title>{this.props.title}</Modal.Title> +        </Modal.Header> +        <Modal.Body> +          <ButtonToolbar> +            <Button onClick={this.props.onAccept} bsStyle="success"> +              {this.props.acceptStr} +            </Button> +            <Button onClick={this.props.onCancel}> +              {this.props.cancelStr} +            </Button> +          </ButtonToolbar> +        </Modal.Body> +      </Modal> +    ) +  } +} + diff --git a/ui/app/components/login.js b/ui/app/components/login.js index af3dfe8..9ff6541 100644 --- a/ui/app/components/login.js +++ b/ui/app/components/login.js @@ -390,7 +390,7 @@ class Login extends React.Component {    }    doLogin() { -    let account = Account.find_or_add(this.state.username) +    let account = Account.findOrAdd(this.state.username)      account.login(this.state.password).then(        account => {          this.setState({loading: false}) diff --git a/ui/app/components/main_panel/account_list.js b/ui/app/components/main_panel/account_list.js index d0ef092..36b6c18 100644 --- a/ui/app/components/main_panel/account_list.js +++ b/ui/app/components/main_panel/account_list.js @@ -3,6 +3,7 @@ import {Button, ButtonGroup, ButtonToolbar, Glyphicon} from 'react-bootstrap'  import App from 'app'  import Account from 'models/account' +import Confirmation from 'components/confirmation'  export default class AccountList extends React.Component { @@ -18,13 +19,16 @@ export default class AccountList extends React.Component {      super(props)      this.state = { -      mode: 'expanded' +      mode: 'expanded', +      showRemoveConfirmation: false      }      // prebind:      this.select = this.select.bind(this)      this.add    = this.add.bind(this)      this.remove = this.remove.bind(this) +    this.askRemove = this.askRemove.bind(this) +    this.cancelRemove = this.cancelRemove.bind(this)      this.expand = this.expand.bind(this)      this.collapse = this.collapse.bind(this)    } @@ -43,6 +47,17 @@ export default class AccountList extends React.Component {    }    remove() { +    this.setState({showRemoveConfirmation: false}) +    if (this.props.onRemove) { +      this.props.onRemove(this.props.account) +    } +  } + +  askRemove() { +    this.setState({showRemoveConfirmation: true}) +  } +  cancelRemove() { +    this.setState({showRemoveConfirmation: false})    }    expand() { @@ -57,6 +72,7 @@ export default class AccountList extends React.Component {      let style = {}      let expandButton = null      let plusminusButtons = null +    let removeModal = null      if (this.state.mode == 'expanded') {        expandButton = ( @@ -69,7 +85,7 @@ export default class AccountList extends React.Component {            <Button onClick={this.add} className="btn-inverse">              <Glyphicon glyph="plus" />            </Button> -          <Button disabled={this.props.account == null} onClick={this.remove} className="btn-inverse"> +          <Button disabled={this.props.account == null} onClick={this.askRemove} className="btn-inverse">              <Glyphicon glyph="minus" />            </Button>          </ButtonGroup> @@ -83,6 +99,14 @@ export default class AccountList extends React.Component {        )      } +    if (this.state.showRemoveConfirmation) { +      let domain = this.props.account.domain +      let title = `Are you sure you wish to remove ${domain}?` +      removeModal = ( +        <Confirmation title={title} onAccept={this.remove} onCancel={this.cancelRemove} /> +      ) +    } +      let items = this.props.accounts.map((account, i) => {        let className = account == this.props.account ? 'active' : 'inactive'        return ( @@ -95,6 +119,7 @@ export default class AccountList extends React.Component {        )      }) +    expandButton = null // for now, disable expand  button      return (        <div className="accounts" style={style}> @@ -105,6 +130,7 @@ export default class AccountList extends React.Component {            {plusminusButtons}            {expandButton}          </ButtonToolbar> +        {removeModal}        </div>      )    } diff --git a/ui/app/components/main_panel/index.js b/ui/app/components/main_panel/index.js index 775dff6..1948535 100644 --- a/ui/app/components/main_panel/index.js +++ b/ui/app/components/main_panel/index.js @@ -28,6 +28,7 @@ export default class MainPanel extends React.Component {        accounts: []      }      this.activateAccount = this.activateAccount.bind(this) +    this.removeAccount = this.removeAccount.bind(this)    }    componentWillMount() { @@ -46,11 +47,20 @@ export default class MainPanel extends React.Component {      })    } -  //setAccounts(accounts) { -  //  this.setState({ -  //    accounts: accounts -  //  }) -  //} +  removeAccount(account) { +    Account.remove(account).then( +      newActiveAccount => { +        console.log(newActiveAccount) +        this.setState({ +          account: newActiveAccount, +          accounts: Account.list +        }) +      }, +      error => { +        console.log(error) +      } +    ) +  }    render() {      let emailSection = null @@ -64,7 +74,10 @@ export default class MainPanel extends React.Component {      return (        <div className="main-panel"> -        <AccountList account={this.state.account} accounts={this.state.accounts} onSelect={this.activateAccount} /> +        <AccountList account={this.state.account} +          accounts={this.state.accounts} +          onSelect={this.activateAccount} +          onRemove={this.removeAccount}/>          <div className="body">            <UserSection account={this.state.account} onLogin={this.activateAccount} onLogout={this.activateAccount}/>            {vpnSection} diff --git a/ui/app/models/account.js b/ui/app/models/account.js index 412ee56..cb008cc 100644 --- a/ui/app/models/account.js +++ b/ui/app/models/account.js @@ -99,7 +99,7 @@ export default class Account {      return account    } -  static find_or_add(address) { +  static findOrAdd(address) {      let account = Account.find(address)      if (!account) {        account = new Account(address) @@ -129,10 +129,30 @@ export default class Account {      }    } +  // +  // For now, accounts are really just providers. Eventually, +  // there will be a separate account and provider list. +  // +  // Returns the account in the list that is closest to the one +  // We removed. +  //    static remove(account) { -    Account.list = Account.list.filter(i => { -      return i.id != account.id -    }) +    return bitmask.bonafide.provider.delete(account.domain).then( +      response => { +        let index = Account.list.findIndex(i => { +          return i.id == account.id +        }) +        Account.list = Account.list.filter(i => { +          return i.id != account.id +        }) +        if (index >= Account.list.length) { +          index = index - 1 +        } else if (index == -1) { +          index = 0 +        } +        return Account.list[index] +      } +    )    }    static create(address, password, invite=null) { @@ -143,7 +163,7 @@ export default class Account {      )    } -  static initialize_list(domains) { +  static initializeList(domains) {      for (let domain of domains) {        Account.add(new Account(domain))      } @@ -156,7 +176,7 @@ export default class Account {    // this is a temporary hack to support the old behavior    // util the backend has a proper concept of an account list.    // -  static add_primary(account) { +  static addPrimary(account) {      Account.list = Account.list.filter(i => {        return i.domain != account.domain      }) | 
