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 {browserHistory} from 'react-router';
import Panel from '../panel.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 {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {};
}
this.state = {
notification: false,
notificationMsg: ''
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
};
Client.createAccount(
this.refs.mail.value,
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() {
$('#selectDomains').select2({
/*$('#selectDomains').select2({
placeholder: 'Por favor, introduzca 3 caracteres.',
allowClear: true
});
}
});*/
handleClick(e, path) {
e.preventDefault();
$('#sidebar-mailboxes').addClass('active');
GlobalActions.emitEndLoading();
}
browserHistory.push(path);
componentWillUnmount() {
$('#sidebar-mailboxes').removeClass('active');
}
render() {
let message;
if (this.state.error) {
message = (
<MessageBar
message={this.state.error}
type={this.state.typeError}
autoclose={true}
/>
);
}
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'>
<label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr>
......@@ -42,9 +107,9 @@ export default class CreateMailBox extends React.Component {
<div className='col-xs-6'>
<input
type='text'
required='required'
className='form-control'
ref='address'
ref='mail'
data-required='true'
/>
</div>
<div className='col-xs-6'>
......@@ -71,7 +136,7 @@ export default class CreateMailBox extends React.Component {
<input
type='text'
className='form-control'
ref='name'
ref='givenName'
/>
</div>
</div>
......@@ -85,7 +150,7 @@ export default class CreateMailBox extends React.Component {
<input
type='text'
className='form-control'
ref='lastname'
ref='sn'
/>
</div>
</div>
......@@ -104,25 +169,6 @@ export default class CreateMailBox extends React.Component {
</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'>
<label className='string required col-sm-3 control-label'>
{'Administrador delegado'}
......@@ -134,7 +180,7 @@ export default class CreateMailBox extends React.Component {
<input
type='checkbox'
className='pretty'
ref='isAdministrator'
ref='zimbraIsDelegatedAdminAccount'
/>
<span></span>
</div>
......@@ -200,6 +246,7 @@ export default class CreateMailBox extends React.Component {
<input
type='password'
className='form-control'
data-required='true'
ref='passwd'
/>
</div>
......@@ -218,7 +265,7 @@ export default class CreateMailBox extends React.Component {
{
className: 'btn btn-default',
onClick: (e) => {
this.handleClick(e, '/mailboxes');
Utils.handleLink(e, '/mailboxes', this.props.location);
}
}
}
......@@ -236,13 +283,18 @@ export default class CreateMailBox extends React.Component {
props: {
className: 'btn btn-default btn-xs',
onClick: (e) => {
this.handleClick(e, '/mailboxes');
Utils.handleLink(e, '/mailboxes', this.props.location);
}
}
}
];
return (
<div>
{message}
<div className='content animate-panel'>
<div className='row'>
<div className='col-md-12 central-content'>
<Panel
title={'Agregar Casilla'}
btnsHeader={actions}
......@@ -250,6 +302,14 @@ export default class CreateMailBox extends React.Component {
>
{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 {
this.handleNext = this.handleNext.bind(this);
this.handleLast = this.handleLast.bind(this);
}
getPageQueryString(number) {
const url = this.props.url;
return `${(url.indexOf('?') > -1 ? '&' : '?')}page=${number}`;
}
handleFirst(e) {
e.preventDefault();
browserHistory.push(`/${this.props.url}`);
......@@ -17,11 +21,13 @@ export default class Pagination extends React.Component {
handlePrev(e) {
e.preventDefault();
const prevPage = this.props.currentPage - 1;
const url = this.props.url;
if (prevPage > 1) {
browserHistory.push(`/${this.props.url}?page=${prevPage}`);
const page = this.getPageQueryString(prevPage);
browserHistory.push(`/${url}${page}`);
} else {
browserHistory.push(`/${this.props.url}`);
browserHistory.push(`/${url}`);
}
}
handleChange(e) {
......@@ -30,18 +36,20 @@ export default class Pagination extends React.Component {
const page = parseInt(e.currentTarget.innerText, 10);
let pageUrl = '';
if (page > 1) {
pageUrl = `?page=${page}`;
pageUrl = this.getPageQueryString(page);
}
browserHistory.push(`/${this.props.url}${pageUrl}`);
}
handleNext(e) {
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) {
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() {
const total = this.props.totalPages;
......@@ -114,7 +122,7 @@ export default class Pagination extends React.Component {
}
return (
<div className='pagination'>
<div id='pagination'>
<ul className='pagination'>
{first}
{prev}
......
......@@ -7,7 +7,7 @@ export default class Panel extends React.Component {
return (
<Button
btnAttrs={btn.props}
key={i}
key={`button-${i}`}
>
{btn.label}
</Button>
......@@ -17,7 +17,7 @@ export default class Panel extends React.Component {
let panelHeader;
if (this.props.hasHeader) {
panelHeader = (
<div className='panel-heading hbuilt'>
<div className='panel-heading hbuilt clearfix'>
<div className='pull-right'>{btns}</div>
<div className='heading-buttons'>
{this.props.title}
......
import React from 'react';
import * as Utils from '../utils/utils.jsx';
export default class Panel extends React.Component {
......@@ -8,14 +7,21 @@ export default class Panel extends React.Component {
this.changeTab = this.changeTab.bind(this);
const tab = this.props.location.query.tab || Object.keys(this.props.tabs)[0];
this.state = {
tab: Object.keys(this.props.tabs)[0]
tab
};
}
changeTab(e, tabName) {
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() {
......@@ -61,5 +67,7 @@ export default class Panel extends React.Component {
Panel.propTypes = {
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';
import DomainDetails from './components/domain/domain_details.jsx';
import CreateDomains from './components/domain/create_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 EditMailBox from './components/mailbox/edit_mailbox.jsx';
......@@ -30,6 +30,8 @@ import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, IndexRedirect, Redirect, browserHistory} from 'react-router';
import ZimbraStore from './stores/zimbra_store.jsx';
const notFoundParams = {
title: 'Página no encontrada',
message: 'La página que estás intentando acceder no existe',
......@@ -47,7 +49,7 @@ function preRenderSetup(callwhendone) {
global.window.manager_config = data;
if (data.debug) {
global.window.Zimbra = Client;
global.window.Client = Client;
global.window.Utils = Utils;
}
},
......@@ -71,6 +73,10 @@ function onPreLoggedIn(nextState, replace, callback) {
return Client.getMe(
() => {
if (global.window.manager_config.debug) {
global.window.Zimbra = ZimbraStore.getCurrent();
}
return callback();
},
(err) => {
......@@ -144,18 +150,18 @@ function renderRootComponent() {
<Route
path='mailboxes'
component={MailBox}
>
component={Mailboxes}
/>
<Route
path='new'
path='mailboxes/new'
component={CreateMailBox}
/>
<Route
path=':id/edit'
path='mailboxes/:id/edit'
component={EditMailBox}
/>
</Route>
<Route
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) {
}
);
}
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) {
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