Mailspring/internal_packages/preferences/lib/tabs/preferences-account-details.jsx
Juan Tejada 281e458d39 feat(account-prefs): Adds new page for Account in preferences
Summary:
Adds the new Account preferences page. This consists of two major React components,
PreferencesAccountList and PreferencesAccountDetails, both of which use EditableList.

I added a bunch of fixes and updated the API for EditableList, plus a bit of
refactoring for PreferencesAccount component, and a bunch of CSS so its a big diff.

The detailed changelog:

Updates to EditableList:
  - Fix bug updating selection state when arrows pressed to move selection
  - Add new props:
    - allowEmptySelection to allow the list to have no selection
    - createInputProps to pass aditional props to the createInput
  - Add scroll region for list items
  - Update styles and refactor render methods

Other Updates:
- Updates Account model to hold aliases and a label
  - Adds getter for label to default to email
- Update accountswitcher to display label, update styles and spec

- Refactor PreferencesAccounts component:
  - Splits it into smaller components,
  - Removes unused code
- Splits preferences styelsheets into smaller separate stylesheet for
  account page. Adds some updates and fixes (scroll-region padding)
- Update AccountStore to be able to perform updates on an account.
- Adds new Action to update account, and an action to remove account to
  be consistent with Action usage
- Adds components for Account list and Aliases list using EditableList

Test Plan: - All specs pass, but need to write new tests!

Reviewers: bengotow, evan

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2332
2015-12-10 15:27:29 -08:00

111 lines
2.7 KiB
JavaScript

import _ from 'underscore';
import React, {Component, PropTypes} from 'react';
import {EditableList} from 'nylas-component-kit';
import {RegExpUtils} from 'nylas-exports';
class PreferencesAccountDetails extends Component {
static propTypes = {
account: PropTypes.object,
onAccountUpdated: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
this.state = _.clone(props.account);
}
componentWillReceiveProps(nextProps) {
this.setState(_.clone(nextProps.account));
}
componentWillUnmount() {
this._saveChanges();
}
// Helpers
_makeAlias(str, account = this.props.account) {
const emailRegex = RegExpUtils.emailRegex();
const match = emailRegex.exec(str);
if (!match) {
return `${str} <${account.emailAddress}>`;
}
const email = match[0];
let name = str.slice(0, Math.max(0, match.index - 1));
if (!name) {
name = account.name || 'No name provided';
}
// TODO Sanitize the name string
return `${name} <${email}>`;
}
_saveChanges = ()=> {
this.props.onAccountUpdated(this.props.account, this.state);
}
// Handlers
_onAccountLabelUpdated = (event)=> {
this.setState({label: event.target.value});
}
_onAccountAliasCreated = (newAlias)=> {
const coercedAlias = this._makeAlias(newAlias);
const aliases = this.state.aliases.concat([coercedAlias]);
this.setState({aliases}, ()=> {
this._saveChanges();
});
}
_onAccountAliasUpdated = (newAlias, alias, idx)=> {
const coercedAlias = this._makeAlias(newAlias);
const aliases = this.state.aliases.slice();
aliases[idx] = coercedAlias;
this.setState({aliases}, ()=> {
this._saveChanges();
});
}
_onAccountAliasRemoved = (alias, idx)=> {
const aliases = this.state.aliases.slice();
aliases.splice(idx, 1);
this.setState({aliases}, ()=> {
this._saveChanges();
});
}
render() {
const account = this.state;
const aliasPlaceholder = this._makeAlias(
`alias@${account.emailAddress.split('@')[1]}`
);
return (
<div className="account-details">
<h3>Account Label</h3>
<input
type="text"
value={account.label}
onBlur={this._saveChanges}
onChange={this._onAccountLabelUpdated} />
<h3>Aliases</h3>
<EditableList
showEditIcon
createInputProps={{placeholder: aliasPlaceholder}}
onItemCreated={this._onAccountAliasCreated}
onItemEdited={this._onAccountAliasUpdated}
onDeleteItem={this._onAccountAliasRemoved} >
{account.aliases}
</EditableList>
</div>
);
}
}
export default PreferencesAccountDetails;