Commit 4c27872c authored by Elias Nahum's avatar Elias Nahum Committed by Juorder Antonio

list, add, edit, delete account functionalities, use promise insteid callback...

list, add, edit, delete account functionalities, use promise insteid callback in validateInputs function
parent 80a00639
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 = {};
}
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 = {
notification: false,
notificationMsg: ''
};
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,20 +283,33 @@ 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 (
<Panel
title={'Agregar Casilla'}
btnsHeader={actions}
classHeader={'forum-box'}
>
{form}
</Panel>
<div>
{message}
<div className='content animate-panel'>
<div className='row'>
<div className='col-md-12 central-content'>
<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 {
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}
>
<Route
path='new'
component={CreateMailBox}
/>
component={Mailboxes}
/>
<Route
path=':id/edit'
component={EditMailBox}
/>
</Route>
<Route
path='mailboxes/new'
component={CreateMailBox}
/>
<Route
path='mailboxes/:id/edit'
component={EditMailBox}
/>
<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