Commit 77e7ab21 authored by enahum's avatar enahum

Merge pull request #23 from ZBoxApp/mailboxes

Mailboxes
parents 80a00639 4c27872c
import $ from 'jquery';
import React from 'react'; import React from 'react';
import {browserHistory} from 'react-router';
import Panel from '../panel.jsx'; import Panel from '../panel.jsx';
import Button from '../button.jsx'; import Button from '../button.jsx';
import MessageBar from '../message_bar.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import * as Client from '../../utils/client.jsx';
import * as Utils from '../../utils/utils.jsx';
export default class CreateMailBox extends React.Component { export default class CreateMailBox extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleClick = this.handleClick.bind(this); this.handleSubmit = this.handleSubmit.bind(this);
this.state = {};
}
handleSubmit(e) {
e.preventDefault();
Utils.validateInputRequired(this.refs).then(() => {
// here assign missing properties.
let attrs = {
givenName: this.refs.givenName.value,
sn: this.refs.sn.value
};
this.state = { Client.createAccount(
notification: false, this.refs.mail.value,
notificationMsg: '' this.refs.mail.passwd,
}; attrs,
(data) => {
// reset form when all is ok
document.getElementById('createAccount').reset();
this.setState(
{
error: `Su cuenta ${data.name} ha sido creada con èxito.`,
typeError: 'success'
}
);
},
(error) => {
this.setState(
{
error: error.message,
typeError: 'warning'
}
);
}
);
}).catch((err) => {
this.setState(
{
error: err.message,
typeError: err.typeError
}
);
err.node.focus();
});
} }
componentDidMount() { componentDidMount() {
$('#selectDomains').select2({ /*$('#selectDomains').select2({
placeholder: 'Por favor, introduzca 3 caracteres.', placeholder: 'Por favor, introduzca 3 caracteres.',
allowClear: true allowClear: true
}); });*/
}
handleClick(e, path) { $('#sidebar-mailboxes').addClass('active');
e.preventDefault(); GlobalActions.emitEndLoading();
}
browserHistory.push(path); componentWillUnmount() {
$('#sidebar-mailboxes').removeClass('active');
} }
render() { render() {
let message;
if (this.state.error) {
message = (
<MessageBar
message={this.state.error}
type={this.state.typeError}
autoclose={true}
/>
);
}
let form = ( let form = (
<form className='simple_form form-horizontal mailbox-form'> <form
className='simple_form form-horizontal mailbox-form'
onSubmit={(e) => {
this.handleSubmit(e);
}}
id='createAccount'
>
<div className='form-group string required'> <div className='form-group string required'>
<label className='string required col-sm-3 control-label'> <label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr> <abbr title='requerido'>{'*'}</abbr>
...@@ -42,9 +107,9 @@ export default class CreateMailBox extends React.Component { ...@@ -42,9 +107,9 @@ export default class CreateMailBox extends React.Component {
<div className='col-xs-6'> <div className='col-xs-6'>
<input <input
type='text' type='text'
required='required'
className='form-control' className='form-control'
ref='address' ref='mail'
data-required='true'
/> />
</div> </div>
<div className='col-xs-6'> <div className='col-xs-6'>
...@@ -71,7 +136,7 @@ export default class CreateMailBox extends React.Component { ...@@ -71,7 +136,7 @@ export default class CreateMailBox extends React.Component {
<input <input
type='text' type='text'
className='form-control' className='form-control'
ref='name' ref='givenName'
/> />
</div> </div>
</div> </div>
...@@ -85,7 +150,7 @@ export default class CreateMailBox extends React.Component { ...@@ -85,7 +150,7 @@ export default class CreateMailBox extends React.Component {
<input <input
type='text' type='text'
className='form-control' className='form-control'
ref='lastname' ref='sn'
/> />
</div> </div>
</div> </div>
...@@ -104,25 +169,6 @@ export default class CreateMailBox extends React.Component { ...@@ -104,25 +169,6 @@ export default class CreateMailBox extends React.Component {
</div> </div>
</div> </div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
{'Chat'}
</label>
<div className='col-sm-8'>
<label className='radio-inline pretty-input'>
<div className='pretty-checkbox'>
<input
type='checkbox'
className='pretty'
ref='hasChat'
/>
<span></span>
</div>
</label>
</div>
</div>
<div className='form-group string'> <div className='form-group string'>
<label className='string required col-sm-3 control-label'> <label className='string required col-sm-3 control-label'>
{'Administrador delegado'} {'Administrador delegado'}
...@@ -134,7 +180,7 @@ export default class CreateMailBox extends React.Component { ...@@ -134,7 +180,7 @@ export default class CreateMailBox extends React.Component {
<input <input
type='checkbox' type='checkbox'
className='pretty' className='pretty'
ref='isAdministrator' ref='zimbraIsDelegatedAdminAccount'
/> />
<span></span> <span></span>
</div> </div>
...@@ -200,6 +246,7 @@ export default class CreateMailBox extends React.Component { ...@@ -200,6 +246,7 @@ export default class CreateMailBox extends React.Component {
<input <input
type='password' type='password'
className='form-control' className='form-control'
data-required='true'
ref='passwd' ref='passwd'
/> />
</div> </div>
...@@ -218,7 +265,7 @@ export default class CreateMailBox extends React.Component { ...@@ -218,7 +265,7 @@ export default class CreateMailBox extends React.Component {
{ {
className: 'btn btn-default', className: 'btn btn-default',
onClick: (e) => { onClick: (e) => {
this.handleClick(e, '/mailboxes'); Utils.handleLink(e, '/mailboxes', this.props.location);
} }
} }
} }
...@@ -236,20 +283,33 @@ export default class CreateMailBox extends React.Component { ...@@ -236,20 +283,33 @@ export default class CreateMailBox extends React.Component {
props: { props: {
className: 'btn btn-default btn-xs', className: 'btn btn-default btn-xs',
onClick: (e) => { onClick: (e) => {
this.handleClick(e, '/mailboxes'); Utils.handleLink(e, '/mailboxes', this.props.location);
} }
} }
} }
]; ];
return ( return (
<Panel <div>
title={'Agregar Casilla'} {message}
btnsHeader={actions} <div className='content animate-panel'>
classHeader={'forum-box'} <div className='row'>
> <div className='col-md-12 central-content'>
{form} <Panel
</Panel> title={'Agregar Casilla'}
btnsHeader={actions}
classHeader={'forum-box'}
>
{form}
</Panel>
</div>
</div>
</div>
</div>
); );
} }
} }
CreateMailBox.propTypes = {
location: React.PropTypes.object
};
//import $ from 'jquery';
//import select2 from 'select2'; //import select2 from 'select2';
import $ from 'jquery';
import React from 'react'; import React from 'react';
import {browserHistory} from 'react-router';
import Panel from '../panel.jsx'; import Panel from '../panel.jsx';
import Button from '../button.jsx'; import Button from '../button.jsx';
import MessageBar from '../message_bar.jsx';
import * as Client from '../../utils/client.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import * as Utils from '../../utils/utils.jsx';
export default class EditMailBox extends React.Component { export default class EditMailBox extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleClick = this.handleClick.bind(this); this.handleEdit = this.handleEdit.bind(this);
this.handleClickDelete = this.handleClickDelete.bind(this); this.handleRadioChanged = this.handleRadioChanged.bind(this);
this.handleDelete = this.handleDelete.bind(this);
this.getMailbox = this.getMailbox.bind(this);
this.fillForm = this.fillForm.bind(this);
this.state = { this.state = {
notification: false, data: false
notificationMsg: ''
}; };
} }
handleClick(e, path) { handleRadioChanged(val) {
this.refs.plan.value = val;
}
handleEdit(e) {
e.preventDefault(); e.preventDefault();
Utils.toggleStatusButtons('.action-button', true);
Utils.validateInputRequired(this.refs).then(() => {
let isAdmin = (this.refs.zimbraIsDelegatedAdminAccount.checked === true).toString().toUpperCase();
let attrs = {
givenName: this.refs.givenName.value,
sn: this.refs.sn.value,
zimbraIsDelegatedAdminAccount: isAdmin
};
Client.modifyAccount(
this.state.data.id,
attrs,
(data) => {
Utils.toggleStatusButtons('.action-button', false);
this.setState(
{
error: `Su cuenta ${data.name} ha sido modificada con èxito.`,
typeError: 'success',
data: data
}
);
},
(error) => {
this.setState(
{
error: error.message,
typeError: 'warning'
}
);
Utils.toggleStatusButtons('.action-button', false);
}
);
}).catch((err) => {
this.setState(
{
error: err.message,
typeError: err.typeError
}
);
err.node.focus();
Utils.toggleStatusButtons('.action-button', false);
});
}
getMailbox(id) {
Client.getAccount(
id,
(data) => {
this.setState({
data
});
GlobalActions.emitEndLoading();
},
(error) => {
this.setState({
error: error.message
});
GlobalActions.emitEndLoading();
}
);
}
componentDidMount() {
$('#sidebar-mailboxes').addClass('active');
GlobalActions.emitEndLoading();
this.getMailbox(this.props.params.id);
}
browserHistory.push(path); componentWillUnmount() {
$('#sidebar-mailboxes').removeClass('active');
} }
handleClickDelete(e) { handleDelete(e) {
e.preventDefault(); e.preventDefault();
Client.removeAccount(
this.state.data.id,
(data) => {
console.log('success', data); //eslint-disable-line no-console
},
(error) => {
console.log('error', error); //eslint-disable-line no-console
}
);
}
fillForm() {
let attrs = this.state.data.attrs;
this.refs.mail.value = this.state.data.name;
this.refs.givenName.value = attrs.givenName || '';
this.refs.sn.value = attrs.sn;
this.refs.description.value = attrs.description || '';
this.refs.zimbraIsDelegatedAdminAccount.checked = attrs.zimbraIsDelegatedAdminAccount === 'true';
} }
render() { render() {
let message;
if (this.state.error) {
message = (
<MessageBar
message={this.state.error}
type={this.state.typeError}
autoclose={true}
/>
);
}
if (this.state.data) {
this.fillForm();
}
let form = ( let form = (
<form className='simple_form form-horizontal mailbox-form'> <form
className='simple_form form-horizontal mailbox-form'
id='editAccount'
onSubmit={(e) => {
this.handleEdit(e);
}}
>
<div className='form-group string required'> <div className='form-group string required'>
<label className='string required col-sm-3 control-label'> <label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr> <abbr title='requerido'>{'*'}</abbr>
...@@ -42,8 +161,10 @@ export default class EditMailBox extends React.Component { ...@@ -42,8 +161,10 @@ export default class EditMailBox extends React.Component {
<div className='col-xs-6'> <div className='col-xs-6'>
<input <input
type='text' type='text'
required='required'
className='form-control' className='form-control'
ref='mail'
data-required='true'
data-message='El campo direccion es requerido, verifique por favor.'
/> />
</div> </div>
<div className='col-xs-6'> <div className='col-xs-6'>
...@@ -52,6 +173,7 @@ export default class EditMailBox extends React.Component { ...@@ -52,6 +173,7 @@ export default class EditMailBox extends React.Component {
<select <select
className='form-control' className='form-control'
id='selectDomains' id='selectDomains'
ref='domain'
> >
</select> </select>
</div> </div>
...@@ -69,6 +191,7 @@ export default class EditMailBox extends React.Component { ...@@ -69,6 +191,7 @@ export default class EditMailBox extends React.Component {
<input <input
type='text' type='text'
className='form-control' className='form-control'
ref='givenName'
/> />
</div> </div>
</div> </div>
...@@ -82,6 +205,7 @@ export default class EditMailBox extends React.Component { ...@@ -82,6 +205,7 @@ export default class EditMailBox extends React.Component {
<input <input
type='text' type='text'
className='form-control' className='form-control'
ref='sn'
/> />
</div> </div>
</div> </div>
...@@ -95,28 +219,11 @@ export default class EditMailBox extends React.Component { ...@@ -95,28 +219,11 @@ export default class EditMailBox extends React.Component {
<input <input
type='text' type='text'
className='form-control' className='form-control'
ref='description'
/> />
</div> </div>
</div> </div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
{'Chat'}
</label>
<div className='col-sm-8'>
<label className='radio-inline pretty-input'>
<div className='pretty-checkbox'>
<input
type='checkbox'
className='pretty'
/>
<span></span>
</div>
</label>
</div>
</div>
<div className='form-group string'> <div className='form-group string'>
<label className='string required col-sm-3 control-label'> <label className='string required col-sm-3 control-label'>
{'Administrador delegado'} {'Administrador delegado'}
...@@ -128,6 +235,7 @@ export default class EditMailBox extends React.Component { ...@@ -128,6 +235,7 @@ export default class EditMailBox extends React.Component {
<input <input
type='checkbox' type='checkbox'
className='pretty' className='pretty'
ref='zimbraIsDelegatedAdminAccount'
/> />
<span></span> <span></span>
</div> </div>
...@@ -148,6 +256,9 @@ export default class EditMailBox extends React.Component { ...@@ -148,6 +256,9 @@ export default class EditMailBox extends React.Component {
type='radio' type='radio'
className='pretty' className='pretty'
name='mailbox' name='mailbox'
onChange={() => {
this.handleRadioChanged('basica');
}}
/> />
<span></span> <span></span>
</div> </div>
...@@ -157,9 +268,12 @@ export default class EditMailBox extends React.Component { ...@@ -157,9 +268,12 @@ export default class EditMailBox extends React.Component {
<label className='radio radio-info radio-inline pretty-input'> <label className='radio radio-info radio-inline pretty-input'>
<div className='pretty-radio'> <div className='pretty-radio'>
<input <input
type='radio'
className='pretty' className='pretty'
name='mailbox' name='mailbox'
type='radio'
onChange={() => {
this.handleRadioChanged('profesional');
}}
/> />
<span></span> <span></span>
</div> </div>
...@@ -172,11 +286,21 @@ export default class EditMailBox extends React.Component { ...@@ -172,11 +286,21 @@ export default class EditMailBox extends React.Component {
type='radio' type='radio'
className='pretty' className='pretty'
name='mailbox' name='mailbox'
onChange={() => {
this.handleRadioChanged('premium');
}}
/> />
<span></span> <span></span>
</div> </div>
{'Premium'} {'Premium'}
</label> </label>
<input
type='hidden'
ref='plan'
data-required='true'
data-message='El plan de su cuenta es requerido, por favor verificar.'
/>
</div> </div>
</div> </div>
...@@ -186,14 +310,15 @@ export default class EditMailBox extends React.Component { ...@@ -186,14 +310,15 @@ export default class EditMailBox extends React.Component {
type='submit' type='submit'
name='commit' name='commit'
value='Guardar' value='Guardar'
className='btn btn-primary' className='btn btn-primary action-button'
id='modifyButton'
/> />
<Button <Button
btnAttrs={ btnAttrs={
{ {
className: 'btn btn-default', className: 'btn btn-default action-button',
onClick: (e) => { onClick: (e) => {
this.handleClick(e, '/mailboxes'); Utils.handleLink(e, '/mailboxes', this.props.location);
} }
} }
} }
...@@ -209,31 +334,45 @@ export default class EditMailBox extends React.Component { ...@@ -209,31 +334,45 @@ export default class EditMailBox extends React.Component {
{ {
label: 'Cancelar', label: 'Cancelar',
props: { props: {
className: 'btn btn-default btn-xs', className: 'btn btn-default btn-xs action-button',
onClick: (e) => { onClick: (e) => {
this.handleClick(e, '/mailboxes'); Utils.handleLink(e, '/mailboxes', this.props.location);
} }
} }
}, },
{ {
label: 'Eliminar', label: 'Eliminar',
props: { props: {
className: 'btn btn-danger btn-xs', className: 'btn btn-danger btn-xs action-button',
onClick: (e) => { onClick: (e) => {
this.handleClickDelete(e, '/mailboxes/delete/1'); this.handleDelete(e);
} }
} }
} }
]; ];
return ( return (
<Panel <div>
title={'Editar Casilla'} {message}
btnsHeader={actions} <div className='content animate-panel'>
classHeader={'forum-box'} <div className='row'>
> <div className='col-md-12 central-content'>
{form} <Panel
</Panel> title={'Editar Casilla'}
btnsHeader={actions}
classHeader={'forum-box'}
>
{form}
</Panel>
</div>
</div>
</div>
</div>
); );
} }
} }
EditMailBox.propTypes = {
location: React.PropTypes.object,
params: React.PropTypes.any
};
...@@ -4,25 +4,46 @@ ...@@ -4,25 +4,46 @@
import $ from 'jquery'; import $ from 'jquery';
import React from 'react'; import React from 'react';
import {browserHistory} from 'react-router'; import {browserHistory} from 'react-router';
import Button from '../button.jsx';
import MessageBar from '../message_bar.jsx';
import PageInfo from '../page_info.jsx'; import PageInfo from '../page_info.jsx';
import Panel from '../panel.jsx'; import Panel from '../panel.jsx';
import PanelTab from '../panel_tab.jsx';
import Pagination from '../pagination.jsx';
import statusLabel from '../status_label.jsx';
import * as Client from '../../utils/client.jsx'; import * as Client from '../../utils/client.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx'; import * as GlobalActions from '../../action_creators/global_actions.jsx';
import Constants from '../../utils/constants.jsx';
import * as Utils from '../../utils/utils.jsx';
const QueryOptions = Constants.QueryOptions;
export default class Accounts extends React.Component { export default class Mailboxes extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleEdit = this.handleEdit.bind(this);
this.getMailboxes = this.getMailboxes.bind(this);
this.handleAddMailbox = this.handleAddMailbox.bind(this);
this.handleExportAsCSV = this.handleExportAsCSV.bind(this);
this.handleTabChanged = this.handleTabChanged.bind(this);
const page = parseInt(this.props.location.query.page, 10) || 1;
this.state = { this.state = {
data: null page,
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT)
}; };
this.handleLink = this.handleLink.bind(this);
this.getMailboxes = this.getMailboxes.bind(this);
} }
getMailboxes() { getMailboxes() {
Client.getAllDomains( Client.getAllAccounts(
{
limit: QueryOptions.DEFAULT_LIMIT,
offset: this.state.offset
},
(data) => { (data) => {
this.setState({ this.setState({
data data
...@@ -38,65 +59,268 @@ export default class Accounts extends React.Component { ...@@ -38,65 +59,268 @@ export default class Accounts extends React.Component {
); );
} }
handleAddMailbox(e, path) {
e.preventDefault();
if ((this.props.location.basename + this.props.location.pathname) !== path) {
browserHistory.push(path);
GlobalActions.emitStartLoading();
}
}
handleExportAsCSV(e) {
e.preventDefault();
}
handleTabChanged(tab) {
browserHistory.push(this.props.location.pathname + '?tab=' + tab);
}
componentWillReceiveProps(newProps) {
if (this.props.location.query.page !== newProps.location.query.page) {
const page = parseInt(newProps.location.query.page, 10) || 1;
GlobalActions.emitStartLoading();
this.state = {
page,
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT)
};
this.getMailboxes();
}
}
componentDidMount() { componentDidMount() {
$('#sidebar-accounts').addClass('active'); $('#sidebar-mailboxes').addClass('active');
GlobalActions.emitEndLoading(); this.getMailboxes();
} }
componentWillUnmount() { componentWillUnmount() {
$('#sidebar-accounts').removeClass('active'); $('#sidebar-mailboxes').removeClass('active');
} }
handleLink(e, path) { handleEdit(e, path) {
e.preventDefault(); e.preventDefault();
if ((this.props.location.basename + this.props.location.pathname) !== path) {
browserHistory.push(path); GlobalActions.emitStartLoading();
browserHistory.push(path);
}
} }
render() { render() {
const addMailBoxButton = [{ let message;
label: '+ Agregar Casilla', let panelTabs;
props: { if (this.state.error) {
className: 'btn btn-success', message = (
onClick: (e) => { <MessageBar
this.handleLink(e, '/mailboxes/new'); message={this.state.error}
type='success'
autoclose={true}
/>
);
}
let tableResults;
let total = 0;
let arrLocked = [];
if (this.state.data) {
total = this.state.data.account.length;
tableResults = this.state.data.account.map((mail) => {
let attrs = mail.attrs;
let statusClass = '';
let status = attrs.zimbraAccountStatus;
let id = mail.id;
switch (status) {
case 'locked':
statusClass = 'label label-warning';
status = 'Bloqueada';
arrLocked.push(mail);
break;
default:
statusClass = 'label label-success';
status = 'Activa';
break;
} }
return (
<tr
key={id}
className={'mailbox-row'}
id={id}
>
<td className={'mailbox-name'}>
<statusLabel className={statusClass}>{status}</statusLabel>
{attrs.mail}
</td>
<td className={'mailbox-displayname'}>
{mail.name}
</td>
<td className={'mailbox-cos-plan'}>
<statusLabel className={'label-plan label-unknown'}>unknown</statusLabel>
</td>
<td>
<Button
btnAttrs={
{
className: 'btn btn-xs btn-default',
onClick: (e) => {
this.handleEdit(e, '/mailboxes/' + attrs.mail + '/edit');
}
}
}
>
{'Editar'}
</Button>
</td>
</tr>
);
});
const panelBody = (
<div
key='mailboxes-body'
id='index-mailboxes-table'
className='table-responsive'
>
<table
id='index-domains'
cellPadding='1'
cellSpacing='1'
className='table table-condensed table-striped vertical-align index-mailbox-table'
>
<thead>
<tr>
<th>{'Email'}</th>
<th className='td-mbxs text-left'>{'Nombre'}</th>
<th className='text-center text-center'>{'Tipo'}</th>
<th className='text-center text-center'>{'Acciones'}</th>
</tr>
</thead>
<tbody>
{tableResults}
</tbody>
</table>
</div>
);
const todas = `Todas (${total})`;
const archiving = 'Archiving';
const noPlan = `Sin Plan (${total})`;
const locked = `Bloqueada (${arrLocked.length})`;
const arrTabNames = [
todas,
archiving,
noPlan,
locked
];
let pagination;
if (this.state.offset > 0 || (this.state.data && this.state.data.more)) {
const totalPages = this.state.data ? Math.ceil(this.state.data.total / QueryOptions.DEFAULT_LIMIT) : 0;
const tab = this.props.location.query.tab || Utils.slug(todas);
pagination = (
<Pagination
key='panelPagination'
url={`mailboxes?tab=${tab}`}
currentPage={this.state.page}
totalPages={totalPages}
/>
);
} }
}];
const panelBody = ( const icon = (
<div className='center-block text-center'> <div>
<h5>{'Sin resultados para su busqueda.'}</h5> <i className='/fa fa-download'/>
</div> <span>Exportar</span>
); </div>
);
const pageInfo = ( let tab1 = (
<PageInfo <div>
titlePage='Casillas' <Panel
descriptionPage='Las casillas ...' title=''
/> children={[panelBody, pagination]}
); btnsHeader={[
{
props: {
className: 'btn btn-default',
onClick: (e) => {
this.handleExportAsCSV(e);
}
},
label: icon
},
{
props: {
className: 'btn btn-success',
onClick: (e) => {
this.handleAddMailbox(e, '/mailboxes/new');
}
},
label: '+ Nueva Casilla'
}
]}
/>
</div>
);
const hasPageInfo = (this.props.children) ? '' : pageInfo; let tab2 = (
<Panel
title='Casillas tab2'
children={[panelBody, pagination]}
/>
);
const indexView = ( let tab3 = (
<Panel <Panel
btnsHeader={addMailBoxButton} title='Casillas tb3'
children={panelBody} children={panelBody}
/> />
); );
let tab4 = (
<Panel
title='Casillas tab4'
children={panelBody}
/>
);
let arrTabs = {};
arrTabs[Utils.slug(todas)] = tab1;
arrTabs[Utils.slug(archiving)] = tab2;
arrTabs[Utils.slug(noPlan)] = tab3;
arrTabs[Utils.slug(locked)] = tab4;
panelTabs = (
<PanelTab
tabNames={arrTabNames}
tabs={arrTabs}
location={this.props.location}
onClick={this.handleTabChanged}
/>
);
}
const views = this.props.children || indexView; const content = panelTabs || '';
return ( return (
<div> <div>
<PageInfo
titlePage='Casillas'
descriptionPage='Usuarios de correo electrónico'
/>
{hasPageInfo} {message}
<div className='content animate-panel'> <div className='content animate-panel'>
<div className='row'> <div className='row'>
<div className='col-md-12 central-content'> <div className='col-md-12 panel-with-tabs'>
{views} {content}
</div> </div>
</div> </div>
</div> </div>
...@@ -105,6 +329,6 @@ export default class Accounts extends React.Component { ...@@ -105,6 +329,6 @@ export default class Accounts extends React.Component {
} }
} }
Accounts.propTypes = { Mailboxes.propTypes = {
children: React.PropTypes.any location: React.PropTypes.object.isRequired
}; };
...@@ -10,6 +10,10 @@ export default class Pagination extends React.Component { ...@@ -10,6 +10,10 @@ export default class Pagination extends React.Component {
this.handleNext = this.handleNext.bind(this); this.handleNext = this.handleNext.bind(this);
this.handleLast = this.handleLast.bind(this); this.handleLast = this.handleLast.bind(this);
} }
getPageQueryString(number) {
const url = this.props.url;
return `${(url.indexOf('?') > -1 ? '&' : '?')}page=${number}`;
}
handleFirst(e) { handleFirst(e) {
e.preventDefault(); e.preventDefault();
browserHistory.push(`/${this.props.url}`); browserHistory.push(`/${this.props.url}`);
...@@ -17,11 +21,13 @@ export default class Pagination extends React.Component { ...@@ -17,11 +21,13 @@ export default class Pagination extends React.Component {
handlePrev(e) { handlePrev(e) {
e.preventDefault(); e.preventDefault();
const prevPage = this.props.currentPage - 1; const prevPage = this.props.currentPage - 1;
const url = this.props.url;
if (prevPage > 1) { if (prevPage > 1) {
browserHistory.push(`/${this.props.url}?page=${prevPage}`); const page = this.getPageQueryString(prevPage);
browserHistory.push(`/${url}${page}`);
} else { } else {
browserHistory.push(`/${this.props.url}`); browserHistory.push(`/${url}`);
} }
} }
handleChange(e) { handleChange(e) {
...@@ -30,18 +36,20 @@ export default class Pagination extends React.Component { ...@@ -30,18 +36,20 @@ export default class Pagination extends React.Component {
const page = parseInt(e.currentTarget.innerText, 10); const page = parseInt(e.currentTarget.innerText, 10);
let pageUrl = ''; let pageUrl = '';
if (page > 1) { if (page > 1) {
pageUrl = `?page=${page}`; pageUrl = this.getPageQueryString(page);
} }
browserHistory.push(`/${this.props.url}${pageUrl}`); browserHistory.push(`/${this.props.url}${pageUrl}`);
} }
handleNext(e) { handleNext(e) {
e.preventDefault(); e.preventDefault();
browserHistory.push(`/${this.props.url}?page=${this.props.currentPage + 1}`); const page = this.getPageQueryString(this.props.currentPage + 1);
browserHistory.push(`/${this.props.url}${page}`);
} }
handleLast(e) { handleLast(e) {
e.preventDefault(); e.preventDefault();
browserHistory.push(`/${this.props.url}?page=${this.props.totalPages}`); const page = this.getPageQueryString(this.props.totalPages);
browserHistory.push(`/${this.props.url}${page}`);
} }
render() { render() {
const total = this.props.totalPages; const total = this.props.totalPages;
...@@ -114,7 +122,7 @@ export default class Pagination extends React.Component { ...@@ -114,7 +122,7 @@ export default class Pagination extends React.Component {
} }
return ( return (
<div className='pagination'> <div id='pagination'>
<ul className='pagination'> <ul className='pagination'>
{first} {first}
{prev} {prev}
......
...@@ -7,7 +7,7 @@ export default class Panel extends React.Component { ...@@ -7,7 +7,7 @@ export default class Panel extends React.Component {
return ( return (
<Button <Button
btnAttrs={btn.props} btnAttrs={btn.props}
key={i} key={`button-${i}`}
> >
{btn.label} {btn.label}
</Button> </Button>
...@@ -17,7 +17,7 @@ export default class Panel extends React.Component { ...@@ -17,7 +17,7 @@ export default class Panel extends React.Component {
let panelHeader; let panelHeader;
if (this.props.hasHeader) { if (this.props.hasHeader) {
panelHeader = ( panelHeader = (
<div className='panel-heading hbuilt'> <div className='panel-heading hbuilt clearfix'>
<div className='pull-right'>{btns}</div> <div className='pull-right'>{btns}</div>
<div className='heading-buttons'> <div className='heading-buttons'>
{this.props.title} {this.props.title}
......
import React from 'react'; import React from 'react';
import * as Utils from '../utils/utils.jsx'; import * as Utils from '../utils/utils.jsx';
export default class Panel extends React.Component { export default class Panel extends React.Component {
...@@ -8,14 +7,21 @@ export default class Panel extends React.Component { ...@@ -8,14 +7,21 @@ export default class Panel extends React.Component {
this.changeTab = this.changeTab.bind(this); this.changeTab = this.changeTab.bind(this);
const tab = this.props.location.query.tab || Object.keys(this.props.tabs)[0];
this.state = { this.state = {
tab: Object.keys(this.props.tabs)[0] tab
}; };
} }
changeTab(e, tabName) { changeTab(e, tabName) {
e.preventDefault(); e.preventDefault();
this.setState({tab: Utils.slug(tabName)});
const tab = Utils.slug(tabName);
this.setState({tab});
if (this.props.onClick) {
this.props.onClick(tab);
}
} }
render() { render() {
...@@ -61,5 +67,7 @@ export default class Panel extends React.Component { ...@@ -61,5 +67,7 @@ export default class Panel extends React.Component {
Panel.propTypes = { Panel.propTypes = {
tabNames: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, tabNames: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
tabs: React.PropTypes.array.isRequired tabs: React.PropTypes.object.isRequired,
location: React.PropTypes.object.isRequired,
onClick: React.PropTypes.func
}; };
...@@ -17,7 +17,7 @@ import Domains from './components/domain/domains.jsx'; ...@@ -17,7 +17,7 @@ import Domains from './components/domain/domains.jsx';
import DomainDetails from './components/domain/domain_details.jsx'; import DomainDetails from './components/domain/domain_details.jsx';
import CreateDomains from './components/domain/create_domain.jsx'; import CreateDomains from './components/domain/create_domain.jsx';
import EditDomains from './components/domain/edit_domain.jsx'; import EditDomains from './components/domain/edit_domain.jsx';
import MailBox from './components/mailbox/mailbox.jsx'; import Mailboxes from './components/mailbox/mailbox.jsx';
import CreateMailBox from './components/mailbox/create_mailbox.jsx'; import CreateMailBox from './components/mailbox/create_mailbox.jsx';
import EditMailBox from './components/mailbox/edit_mailbox.jsx'; import EditMailBox from './components/mailbox/edit_mailbox.jsx';
...@@ -30,6 +30,8 @@ import React from 'react'; ...@@ -30,6 +30,8 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import {Router, Route, IndexRedirect, Redirect, browserHistory} from 'react-router'; import {Router, Route, IndexRedirect, Redirect, browserHistory} from 'react-router';
import ZimbraStore from './stores/zimbra_store.jsx';
const notFoundParams = { const notFoundParams = {
title: 'Página no encontrada', title: 'Página no encontrada',
message: 'La página que estás intentando acceder no existe', message: 'La página que estás intentando acceder no existe',
...@@ -47,7 +49,7 @@ function preRenderSetup(callwhendone) { ...@@ -47,7 +49,7 @@ function preRenderSetup(callwhendone) {
global.window.manager_config = data; global.window.manager_config = data;
if (data.debug) { if (data.debug) {
global.window.Zimbra = Client; global.window.Client = Client;
global.window.Utils = Utils; global.window.Utils = Utils;
} }
}, },
...@@ -71,6 +73,10 @@ function onPreLoggedIn(nextState, replace, callback) { ...@@ -71,6 +73,10 @@ function onPreLoggedIn(nextState, replace, callback) {
return Client.getMe( return Client.getMe(
() => { () => {
if (global.window.manager_config.debug) {
global.window.Zimbra = ZimbraStore.getCurrent();
}
return callback(); return callback();
}, },
(err) => { (err) => {
...@@ -144,18 +150,18 @@ function renderRootComponent() { ...@@ -144,18 +150,18 @@ function renderRootComponent() {
<Route <Route
path='mailboxes' path='mailboxes'
component={MailBox} component={Mailboxes}
> />
<Route
path='new'
component={CreateMailBox}
/>
<Route <Route
path=':id/edit' path='mailboxes/new'
component={EditMailBox} component={CreateMailBox}
/> />
</Route>
<Route
path='mailboxes/:id/edit'
component={EditMailBox}
/>
<Route <Route
path='logout' path='logout'
......
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
class TabStateStoreClass {
constructor() {
this.current = null;
this.states = {};
}
getCurrent() {
return this.current;
}
setCurrent(newTabState, newObject) {
this.current = newTabState;
this.states[this.current] = newObject;
}
}
const TabStateStore = new TabStateStoreClass();
export {TabStateStore as default};
...@@ -178,3 +178,98 @@ export function getDomain(id, success, error) { ...@@ -178,3 +178,98 @@ export function getDomain(id, success, error) {
} }
); );
} }
export function getAllAccounts(opts, success, error) {
initZimbra().then(
(zimbra) => {
zimbra.getAllAccounts((err, data) => {
if (err) {
let e = handleError('getAllAccounts', err);
return error(e);
}
return success(data);
}, opts);
},
(err) => {
let e = handleError('getAllAccounts', err);
return error(e);
}
);
}
export function getAccount(id, success, error) {
initZimbra().then(
(zimbra) => {
zimbra.getAccount(id, (err, data) => {
if (err) {
let e = handleError('getAccount', err);
return error(e);
}
return success(data);
});
},
(err) => {
let e = handleError('getAccount', err);
return error(e);
}
);
}
export function createAccount(mail, passwd, attrs, success, error) {
initZimbra().then(
(zimbra) => {
zimbra.createAccount(mail, passwd, attrs, (err, data) => {
if (err) {
let e = handleError('createAccount', err);
return error(e);
}
return success(data);
});
},
(err) => {
let e = handleError('createAccount', err);
return error(e);
}
);
}
export function modifyAccount(idZimbra, attrs, success, error) {
initZimbra().then(
(zimbra) => {
zimbra.modifyAccount(idZimbra, attrs, (err, data) => {
if (err) {
let e = handleError('modifyAccount', err);
return error(e);
}
return success(data);
});
},
(err) => {
let e = handleError('modifyAccount', err);
return error(e);
}
);
}
export function removeAccount(idZimbra, success, error) {
initZimbra().then(
(zimbra) => {
zimbra.removeAccount(idZimbra, (err, data) => {
if (err) {
let e = handleError('removeAccount', err);
return error(e);
}
return success(data);
});
},
(err) => {
let e = handleError('removeAccount', err);
return error(e);
}
);
}
...@@ -159,3 +159,58 @@ export function handleLink(e, path, location) { ...@@ -159,3 +159,58 @@ export function handleLink(e, path, location) {
browserHistory.push(path); browserHistory.push(path);
} }
} }
export function isObjectEmpty(value) {
for (const key in value) {
if (value.hasOwnProperty(key)) {
return false;
}
}
return true;
}
export function validateInputRequired(refs) {
return new Promise((resolve, reject) => {
if (!refs || isObjectEmpty(refs) || Array.isArray(refs)) {
reject({
message: 'No se puede validar un arreglo o un objeto vacio o indefinido',
typeError: 'warning'
});
}
for (const ref in refs) {
if (refs.hasOwnProperty(ref)) {
if (refs[ref].hasAttribute('data-required') && refs[ref].getAttribute('data-required') === 'true' && refs[ref].value === '') {
let message;
if (refs[ref].getAttribute('data-message') && refs[ref].getAttribute('data-message').length > 0) {
message = refs[ref].getAttribute('data-message');
} else {
message = 'Algunos Campos son requeridos, verificar por favor.';
}
const Error = {
message,
typeError: 'warning',
node: refs[ref]
};
return reject(Error);
}
}
}
return resolve(null);
});
}
export function toggleStatusButtons(classNames, isDisabled) {
let elements = document.querySelectorAll(classNames);
if (elements.length > 0) {
let l = elements.length;
for (; l-- > 0;) {
if (isDisabled) {
elements[l].setAttribute('disabled', 'disabled');
} else {
elements[l].removeAttribute('disabled');
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment