Commit ca46e66e authored by Elias Nahum's avatar Elias Nahum Committed by Juorder Antonio

add, remove alias functions, modify fields for auto response form completed.

parent e762cb49
...@@ -17,6 +17,13 @@ export function emitEndLoading() { ...@@ -17,6 +17,13 @@ export function emitEndLoading() {
}); });
} }
export function emitMessage(attrs) {
AppDispatcher.handleViewAction({
type: ActionTypes.NEW_MESSAGE,
attrs
});
}
export function saveUser(user) { export function saveUser(user) {
AppDispatcher.handleViewAction({ AppDispatcher.handleViewAction({
type: ActionTypes.USER_CHANGED, type: ActionTypes.USER_CHANGED,
......
import React from 'react'; import React from 'react';
import Datalist from 'react-datalist';
import Button from '../button.jsx'; import Button from '../button.jsx';
import * as Utils from '../../utils/utils.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import Constants from '../../utils/constants.jsx';
const typeErrors = Constants.MessageType;
export default class FormAliasMailbox extends React.Component { export default class FormAliasMailbox extends React.Component {
constructor(props) {
super(props);
this.handleDeleteAlias = this.handleDeleteAlias.bind(this);
this.sortAlias = this.sortAlias.bind(this);
this.addAlias = this.addAlias.bind(this);
this.toggleClass = 'glyphicon-sort-by-attributes';
this.asc = true;
this.state = {
alias: this.getAlias()
};
}
addAlias(e) {
e.preventDefault();
const refs = this.refs;
const newAlias = refs.alias.value + '@' + refs.domain.value;
Utils.validateInputRequired(refs).then(() => {
this.props.data.addAccountAlias(newAlias, () => {
GlobalActions.emitMessage({
message: 'Se ha agregado su nuevo Alias con éxito.',
type: typeErrors.SUCCESS
});
let alias = this.state.alias;
alias.push(newAlias);
this.setState({
alias: alias
});
}, (err) => {
GlobalActions.emitMessage({
message: err.error,
type: typeErrors.ERROR
});
});
}, (error) => {
GlobalActions.emitMessage({
message: error.message,
type: typeErrors.ERROR
});
error.node.focus();
});
}
sortAlias() {
let sort;
if (this.asc) {
sort = this.state.alias;
sort.sort().reverse();
this.setState({
alias: sort
});
this.asc = false;
this.toggleClass = 'glyphicon-sort-by-attributes';
} else {
sort = this.state.alias;
sort.sort();
this.setState({
alias: sort
});
this.asc = true;
this.toggleClass = 'glyphicon-sort-by-attributes-alt';
}
}
handleDeleteAlias(e, alias, index) {
e.preventDefault();
this.props.data.removeAccountAlias(alias, () => {
GlobalActions.emitMessage({
message: 'Se ha eliminado el alias éxitosamente.',
type: typeErrors.SUCCESS
});
const newAlias = Utils.removeIndexFromArray(this.state.alias, index);
this.setState({
alias: newAlias
});
}, (err) => {
GlobalActions.emitMessage({
message: err.error,
type: typeErrors.ERROR
});
});
}
getAlias() {
const data = this.props.data;
if (data.attrs.hasOwnProperty('zimbraMailAlias')) {
if (typeof data.attrs.zimbraMailAlias === 'string') {
return new Array(data.attrs.zimbraMailAlias);
}
return data.attrs.zimbraMailAlias.sort();
}
return [];
}
componentDidMount() {
let refs = this.refs;
refs.domain = refs.domain.refs.theInput;
refs.domain.setAttribute('data-required', 'true');
refs.domain.setAttribute('data-message', 'El dominio es necesario para crear el alias, verifiquelo por favor.');
}
render() { render() {
let tbody;
let results;
// this bellow is just for testing porpuse
let options = ['apple', 'orange', 'pear', 'pineapple', 'melon'];
if (this.state.alias) {
tbody = this.state.alias.map((alias, i) => {
return ( return (
<form <tr
className='simple_form form-horizontal mailbox-form' key={`alias-${alias}-${i}`}
onSubmit={(e) => { >
this.handleSubmit(e); <td>
<span>{alias}</span>
<Button
btnAttrs={{
className: 'pull-right',
title: `Borrar el siguiente Alias : ${alias}`,
onClick: (e) => {
this.handleDeleteAlias(e, alias, i);
}
}} }}
id='createAccount'
> >
<div className='form-group string'> <i className='fa fa-minus-circle text-danger'></i>
<label className='string required col-sm-3 control-label'> </Button>
{'Habilitado'} </td>
</label> </tr>
);
});
}
<div className='col-sm-8'> results = (
<label className='radio-inline pretty-input'> <table className='table table-striped table-bordered table-hover dataTable no-footer'>
<div className='pretty-checkbox'> <thead>
<input <tr>
type='checkbox' <th>
className='pretty' {'Nombre'}
ref='habilitado' <span className='pull-right'>
/> <i
<span></span> className={`glyphicon ${this.toggleClass} pull-right pointer`}
</div> onClick={() => {
this.sortAlias();
}}
>
</i>
</span>
</th>
</tr>
</thead>
<tbody>
{tbody}
</tbody>
</table>
);
return (
<div className='row'>
<div className='col-xs-6'>
<div className='row'>
<form className='form-inline'>
<div className='col-xs-4'>
<div className='form-group'>
<label>
{'Mostrar'}
<select
ref='shown'
className='form-control input-sm'
>
<option value='10'>10</option>
<option value='25'>25</option>
<option value='50'>50</option>
<option value='100'>100</option>
</select>
</label> </label>
</div> </div>
</div> </div>
<div className='col-xs-8 text-right'>
<div className='form-group string'> <label>
<label className='string required col-sm-3 control-label'> {'Buscar'}
{'Termina el'}
</label>
<div className='col-sm-8'>
<input <input
type='password' type='search'
className='form-control' className='form-control input-sm'
ref='endsAt' ref='search'
id='endsAt'
/> />
</label>
</div> </div>
</form>
</div> </div>
<div className='form-group string'> <div className='row'>
<label className='string required col-sm-3 control-label'> <div className='col-xs-12'>
{'Respuesta'} {results}
</label> </div>
</div>
<div className='col-sm-8'> <div className='row'>
<textarea <div className='col-xs-6'>
name='response' <div className='dataTables_info'>
className='form-control' 1 al 2 de 2 resultados
id='responseBox' </div>
rows='4' </div>
ref='respVacaciones' <div className='col-xs-6 text-right'>
<div className='btn-group'>
<Button
btnAttrs={
{
className: 'btn btn-default'
}
}
> >
</textarea> {'Anterior'}
</Button>
<Button
btnAttrs={
{
className: 'btn btn-default'
}
}
>
{'Siguiente'}
</Button>
</div> </div>
</div> </div>
</div>
<div className='form-group'> </div>
<div className='col-xs-8 col-sm-offset-2'> <div className='col-xs-6'>
<div className='input-group'>
<input
type='text'
ref='alias'
className='form-control'
placeholder='Alias'
data-required='true'
data-message='El alias es requerido, compruebelo por favor'
/>
<span className='input-group-addon'>
@
</span>
<Datalist
list='domains'
options={options}
className='form-control'
id='domain'
ref='domain'
placeholder='Dominio'
/>
<span className='input-group-btn'>
<Button <Button
btnAttrs={ btnAttrs={
{ {
className: 'btn btn-info', className: 'btn btn-default',
onClick: () => { onClick: (e) => {
this.handleSaveAutoResp(); this.addAlias(e);
} }
} }
} }
> >
{'Cancelar'} Agregar alias
</Button> </Button>
</span>
</div>
</div> </div>
</div> </div>
</form>
); );
} }
} }
FormAliasMailbox.propTypes = {
data: React.PropTypes.object
};
import React from 'react'; import React from 'react';
import Button from '../button.jsx'; import Button from '../button.jsx';
import DateTimeField from 'react-bootstrap-datetimepicker';
import * as Client from '../../utils/client.jsx';
import * as Utils from '../../utils/utils.jsx';
import Constants from '../../utils/constants.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
const messageType = Constants.MessageType;
export default class FormVacacionesMailbox extends React.Component { export default class FormVacacionesMailbox extends React.Component {
constructor(props) { constructor(props) {
...@@ -9,7 +17,43 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -9,7 +17,43 @@ export default class FormVacacionesMailbox extends React.Component {
} }
handleSaveAutoResp() { handleSaveAutoResp() {
console.log('save'); //eslint-disable-line no-console const data = this.props.data;
const refs = this.refs;
let enabled = refs.zimbraPrefOutOfOfficeReplyEnabled.checked.toString().toUpperCase();
let formated = document.getElementById('zimbraPrefOutOfOfficeUntilDate').value.split('/').reverse().join('') + '000000Z';
let attrs = {
zimbraPrefOutOfOfficeReplyEnabled: enabled,
zimbraPrefOutOfOfficeUntilDate: formated,
zimbraPrefOutOfOfficeReply: refs.zimbraPrefOutOfOfficeReply.value
};
Client.modifyAccount(data.id, attrs, () => {
GlobalActions.emitMessage({
message: 'Se ha modificado con éxito',
type: messageType.SUCCESS
});
}, (error) => {
GlobalActions.emitMessage({
message: error.message,
type: messageType.ERROR
});
});
}
componentDidMount() {
const data = this.props.data.attrs;
if (data.hasOwnProperty('zimbraPrefOutOfOfficeReplyEnabled')) {
this.refs.zimbraPrefOutOfOfficeReplyEnabled.checked = data.zimbraPrefOutOfOfficeReplyEnabled.toString().toLowerCase() === 'true';
}
if (data.hasOwnProperty('zimbraPrefOutOfOfficeUntilDate')) {
document.getElementById('zimbraPrefOutOfOfficeUntilDate').value = Utils.dateFormatted(data.zimbraPrefOutOfOfficeUntilDate, true, '/');
}
if (data.hasOwnProperty('zimbraPrefOutOfOfficeReply')) {
this.refs.zimbraPrefOutOfOfficeReply.value = data.zimbraPrefOutOfOfficeReply;
}
} }
render() { render() {
...@@ -32,7 +76,7 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -32,7 +76,7 @@ export default class FormVacacionesMailbox extends React.Component {
<input <input
type='checkbox' type='checkbox'
className='pretty' className='pretty'
ref='habilitado' ref='zimbraPrefOutOfOfficeReplyEnabled'
/> />
<span></span> <span></span>
</div> </div>
...@@ -46,11 +90,14 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -46,11 +90,14 @@ export default class FormVacacionesMailbox extends React.Component {
</label> </label>
<div className='col-sm-8'> <div className='col-sm-8'>
<input <DateTimeField
type='password' inputFormat='DD/MM/YYYY'
className='form-control' inputProps={
ref='endsAt' {
id='endsAt' id: 'zimbraPrefOutOfOfficeUntilDate',
readOnly: 'readOnly'
}
}
/> />
</div> </div>
</div> </div>
...@@ -66,7 +113,7 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -66,7 +113,7 @@ export default class FormVacacionesMailbox extends React.Component {
id='responseBox' id='responseBox'
className='form-control' className='form-control'
rows='4' rows='4'
ref='respVacaciones' ref='zimbraPrefOutOfOfficeReply'
> >
</textarea> </textarea>
</div> </div>
...@@ -84,7 +131,7 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -84,7 +131,7 @@ export default class FormVacacionesMailbox extends React.Component {
} }
} }
> >
{'Cancelar'} {'Guardar'}
</Button> </Button>
</div> </div>
</div> </div>
...@@ -92,3 +139,10 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -92,3 +139,10 @@ export default class FormVacacionesMailbox extends React.Component {
); );
} }
} }
FormVacacionesMailbox.propTypes = {
data: React.PropTypes.oneOfType([
React.PropTypes.object,
React.PropTypes.string
])
};
...@@ -204,7 +204,7 @@ export default class Mailboxes extends React.Component { ...@@ -204,7 +204,7 @@ export default class Mailboxes extends React.Component {
} }
}} }}
> >
{attrs.mail} {mail.name}
</Button> </Button>
</td> </td>
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
import $ from 'jquery'; import $ from 'jquery';
import React from 'react'; import React from 'react';
import EventStore from '../../stores/event_store.jsx';
import PageInfo from '../page_info.jsx'; import PageInfo from '../page_info.jsx';
import PanelTab from '../panel_tab.jsx'; import PanelTab from '../panel_tab.jsx';
import Panel from '../panel.jsx'; import Panel from '../panel.jsx';
...@@ -13,6 +15,7 @@ import FormVacacionesMailbox from './form_resp_vacaciones_mailbox.jsx'; ...@@ -13,6 +15,7 @@ import FormVacacionesMailbox from './form_resp_vacaciones_mailbox.jsx';
import FormAliasMailbox from './form_alias_mailbox.jsx'; import FormAliasMailbox from './form_alias_mailbox.jsx';
import ChangePasswordModal from './change_passwd_modal.jsx'; import ChangePasswordModal from './change_passwd_modal.jsx';
import ToggleModalButton from '../toggle_modal_button.jsx'; import ToggleModalButton from '../toggle_modal_button.jsx';
import MessageBar from '../message_bar.jsx';
import * as Client from '../../utils/client.jsx'; import * as Client from '../../utils/client.jsx';
import * as Utils from '../../utils/utils.jsx'; import * as Utils from '../../utils/utils.jsx';
...@@ -24,6 +27,7 @@ export default class MailboxDetails extends React.Component { ...@@ -24,6 +27,7 @@ export default class MailboxDetails extends React.Component {
this.getMailbox = this.getMailbox.bind(this); this.getMailbox = this.getMailbox.bind(this);
this.handleEdit = this.handleEdit.bind(this); this.handleEdit = this.handleEdit.bind(this);
this.showMessage = this.showMessage.bind(this);
this.state = {}; this.state = {};
} }
...@@ -32,6 +36,14 @@ export default class MailboxDetails extends React.Component { ...@@ -32,6 +36,14 @@ export default class MailboxDetails extends React.Component {
Utils.handleLink(e, path, location); Utils.handleLink(e, path, location);
} }
showMessage(attrs) {
this.setState({
error: attrs.message,
type: attrs.type.toLowerCase(),
autocloseInSecs: 10
});
}
getMailbox() { getMailbox() {
const id = this.props.params.id; const id = this.props.params.id;
Utils.toggleStatusButtons('.action-info-btns', true); Utils.toggleStatusButtons('.action-info-btns', true);
...@@ -55,11 +67,13 @@ export default class MailboxDetails extends React.Component { ...@@ -55,11 +67,13 @@ export default class MailboxDetails extends React.Component {
} }
componentDidMount() { componentDidMount() {
EventStore.addMessageListener(this.showMessage);
$('#sidebar-mailboxes').addClass('active'); $('#sidebar-mailboxes').addClass('active');
this.getMailbox(); this.getMailbox();
} }
componentWillUnmount() { componentWillUnmount() {
EventStore.removeMessageListener(this.showMessage);
$('#sidebar-mailboxes').removeClass('active'); $('#sidebar-mailboxes').removeClass('active');
} }
...@@ -68,6 +82,18 @@ export default class MailboxDetails extends React.Component { ...@@ -68,6 +82,18 @@ export default class MailboxDetails extends React.Component {
let statsData; let statsData;
let btnsGeneralInfo = []; let btnsGeneralInfo = [];
let btnsStats = []; let btnsStats = [];
let panelTabs;
let message;
if (this.state.error) {
message = (
<MessageBar
message={this.state.error}
type={this.state.type}
autoclose={true}
/>
);
}
if (this.state.data) { if (this.state.data) {
generalData = ( generalData = (
...@@ -118,32 +144,15 @@ export default class MailboxDetails extends React.Component { ...@@ -118,32 +144,15 @@ export default class MailboxDetails extends React.Component {
label: 'Ver Correos' label: 'Ver Correos'
} }
]; ];
}
const pageInfo = (
<PageInfo
titlePage='Casillas'
descriptionPage='Usuarios de correo electrónico.'
/>
);
if (this.state.notFound) {
return (
<div>
{pageInfo}
<div className='block-center text-center'>
<h3>{this.state.message}</h3>
</div>
</div>
);
}
const formAutoResp = ( const formAutoResp = (
<FormVacacionesMailbox/> <FormVacacionesMailbox data={this.state.data}/>
); );
const formAlias = ( const formAlias = (
<FormAliasMailbox/> <FormAliasMailbox
data={this.state.data}
/>
); );
const tabAdmin = ( const tabAdmin = (
...@@ -157,11 +166,12 @@ export default class MailboxDetails extends React.Component { ...@@ -157,11 +166,12 @@ export default class MailboxDetails extends React.Component {
<Panel <Panel
title='Casillas' title='Casillas'
hasHeader={false} hasHeader={false}
classHeader={'reset-panel'}
children={formAlias} children={formAlias}
/> />
); );
const panelTabs = ( panelTabs = (
<PanelTab <PanelTab
tabNames={['Resp Vacaciones', 'Alias']} tabNames={['Resp Vacaciones', 'Alias']}
tabs={{ tabs={{
...@@ -171,10 +181,30 @@ export default class MailboxDetails extends React.Component { ...@@ -171,10 +181,30 @@ export default class MailboxDetails extends React.Component {
location={this.props.location} location={this.props.location}
/> />
); );
}
const pageInfo = (
<PageInfo
titlePage='Casillas'
descriptionPage='Usuarios de correo electrónico.'
/>
);
if (this.state.notFound) {
return (
<div>
{pageInfo}
<div className='block-center text-center'>
<h3>{this.state.message}</h3>
</div>
</div>
);
}
return ( return (
<div> <div>
{pageInfo} {pageInfo}
{message}
<div className='content animate-panel'> <div className='content animate-panel'>
<div className='row'> <div className='row'>
<div className='col-md-6 central-content'> <div className='col-md-6 central-content'>
......
{ {
"debug": true, "debug": false,
"zimbraUrl": "http://zimbra.zboxapp.dev:8000/service/admin/soap", "zimbraUrl": "http://zimbra.zboxapp.dev:8000/service/admin/soap",
"zimbraProxy": "https://zimbra.zboxapp.dev:7071", "zimbraProxy": "https://zimbra.zboxapp.dev:7071",
"dnsApiUrl": "http://zimbra.zboxapp.dev:3000", "dnsApiUrl": "http://zimbra.zboxapp.dev:3000",
......
...@@ -1266,6 +1266,18 @@ label { ...@@ -1266,6 +1266,18 @@ label {
text-align: center; text-align: center;
} }
&.reset-panel {
margin: 0;
.panel-body {
padding: 0;
.btn {
margin: 0;
}
}
}
&.with-min-height { &.with-min-height {
.panel-body { .panel-body {
min-height: 200px; min-height: 200px;
...@@ -1612,3 +1624,7 @@ label { ...@@ -1612,3 +1624,7 @@ label {
} }
} }
} }
.pointer {
cursor: pointer;
}
...@@ -32,6 +32,18 @@ class EventStoreClass extends EventEmitter { ...@@ -32,6 +32,18 @@ class EventStoreClass extends EventEmitter {
removeEndLoadingListener(callback) { removeEndLoadingListener(callback) {
this.removeListener(eventTypes.END_LOADING_EVENT, callback); this.removeListener(eventTypes.END_LOADING_EVENT, callback);
} }
emitMessage(attrs) {
this.emit(eventTypes.NEW_MESSAGE_EVENT, attrs);
}
addMessageListener(callback) {
this.on(eventTypes.NEW_MESSAGE_EVENT, callback);
}
removeMessageListener(callback) {
this.removeListener(eventTypes.NEW_MESSAGE_EVENT, callback);
}
} }
var EventStore = new EventStoreClass(); var EventStore = new EventStoreClass();
...@@ -47,6 +59,9 @@ EventStore.dispatchToken = AppDispatcher.register((payload) => { ...@@ -47,6 +59,9 @@ EventStore.dispatchToken = AppDispatcher.register((payload) => {
case ActionTypes.END_LOADING: case ActionTypes.END_LOADING:
EventStore.emitEndLoading(); EventStore.emitEndLoading();
break; break;
case ActionTypes.NEW_MESSAGE:
EventStore.emitMessage(action.attrs);
break;
default: default:
} }
}); });
......
...@@ -362,3 +362,22 @@ export function getDnsInfo(domain, success, error) { ...@@ -362,3 +362,22 @@ export function getDnsInfo(domain, success, error) {
} }
}); });
} }
export function addAccountAlias(alias, success, error) {
initZimbra().then(
(zimbra) => {
zimbra.addAccountAlias(alias, (err, data) => {
if (err) {
const e = handleError('addAccountAlias', err);
return error(e);
}
return success(data);
});
},
(err) => {
const e = handleError('addAccountAlias', err);
return error(e);
}
);
}
...@@ -8,7 +8,8 @@ export default { ...@@ -8,7 +8,8 @@ export default {
START_LOADING: null, START_LOADING: null,
END_LOADING: null, END_LOADING: null,
USER_CHANGED: null, USER_CHANGED: null,
RECEIVED_ERROR: null RECEIVED_ERROR: null,
NEW_MESSAGE: null
}), }),
PayloadSources: keyMirror({ PayloadSources: keyMirror({
...@@ -21,7 +22,14 @@ export default { ...@@ -21,7 +22,14 @@ export default {
DOMAIN_DLS_CHANGE_EVENT: null, DOMAIN_DLS_CHANGE_EVENT: null,
START_LOADING_EVENT: null, START_LOADING_EVENT: null,
END_LOADING_EVENT: null, END_LOADING_EVENT: null,
USER_CHANGE_EVENT: null USER_CHANGE_EVENT: null,
NEW_MESSAGE_EVENT: null
}),
MessageType: keyMirror({
SUCCESS: null,
WARNING: null,
ERROR: null
}), }),
ZimbraCodes: { ZimbraCodes: {
......
...@@ -204,16 +204,26 @@ export function toggleStatusButtons(classNames, isDisabled) { ...@@ -204,16 +204,26 @@ export function toggleStatusButtons(classNames, isDisabled) {
} }
} }
export function dateFormatted(dateString) { export function dateFormatted(dateString, isShortDate, separator) {
if (typeof dateString === 'string') { if (typeof dateString === 'string') {
const date = dateString.substr(0, 8); const date = dateString.substr(0, 8);
const year = date.substr(0, 4); const year = date.substr(0, 4);
const month = parseInt(date.substr(4, 2), 10); const month = (isShortDate) ? date.substr(4, 2) : parseInt(date.substr(4, 2), 10);
const day = date.substr(6, 2); const day = date.substr(6, 2);
const dateFormattedString = `${day} de ${CONSTANTS.MONTHS[month - 1]} de ${year}`; let dateFormattedString = `${day} de ${CONSTANTS.MONTHS[month - 1]} de ${year}`;
if (isShortDate) {
dateFormattedString = `${day}${separator}${month}${separator}${year}`;
}
return dateFormattedString; return dateFormattedString;
} }
return false; return false;
} }
export function removeIndexFromArray(array, index, pos) {
array.splice(index, pos || 1);
return array;
}
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