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
};
This diff is collapsed.
This diff is collapsed.
...@@ -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