Commit 58b41f50 authored by Elias Nahum's avatar Elias Nahum Committed by Juorder Antonio

many issues resolved, list, and modify task massive from domain, in parts,...

many issues resolved, list, and modify task massive from domain, in parts, solved modal change password, etc
parent c82ac91a
module.exports = {"main":{"js":"/244695bundle.js"}} module.exports = {"main":{"js":"/887398bundle.js"}}
\ No newline at end of file \ No newline at end of file
...@@ -20,8 +20,8 @@ export default class AntiSpam extends React.Component { ...@@ -20,8 +20,8 @@ export default class AntiSpam extends React.Component {
this.handleSave = this.handleSave.bind(this); this.handleSave = this.handleSave.bind(this);
this.alterDomain = this.alterDomain.bind(this); this.alterDomain = this.alterDomain.bind(this);
this.domain = DomainStore.getCurrent(); this.domain = DomainStore.getCurrent();
this.blackList = null; this.blackList = [];
this.whiteList = null; this.whiteList = [];
if (this.domain.attrs.amavisBlacklistSender) { if (this.domain.attrs.amavisBlacklistSender) {
this.blackList = Array.isArray(this.domain.attrs.amavisBlacklistSender) ? this.domain.attrs.amavisBlacklistSender : this.domain.attrs.amavisBlacklistSender.trim().split(' '); this.blackList = Array.isArray(this.domain.attrs.amavisBlacklistSender) ? this.domain.attrs.amavisBlacklistSender : this.domain.attrs.amavisBlacklistSender.trim().split(' ');
...@@ -39,11 +39,11 @@ export default class AntiSpam extends React.Component { ...@@ -39,11 +39,11 @@ export default class AntiSpam extends React.Component {
switch (action) { switch (action) {
case 'black': case 'black':
this.searchItemToRemove(this.blackList, item); this.searchItemToRemove(this.blackList, item);
attrs.amavisBlacklistSender = this.blackList; attrs.amavisBlacklistSender = this.blackList.length > 0 ? this.blackList : null;
break; break;
case 'white': case 'white':
this.searchItemToRemove(this.whiteList, item); this.searchItemToRemove(this.whiteList, item);
attrs.amavisWhitelistSender = this.whiteList; attrs.amavisWhitelistSender = this.whiteList.length > 0 ? this.whiteList : null;
break; break;
} }
......
...@@ -111,6 +111,7 @@ export default class DomainMailboxPlans extends React.Component { ...@@ -111,6 +111,7 @@ export default class DomainMailboxPlans extends React.Component {
); );
} }
} else { } else {
console.log(totalLimit);
totalLimit += plan.limit; totalLimit += plan.limit;
} }
......
...@@ -17,6 +17,7 @@ import * as Client from '../../utils/client.jsx'; ...@@ -17,6 +17,7 @@ import * as Client from '../../utils/client.jsx';
import * as Utils from '../../utils/utils.jsx'; import * as Utils from '../../utils/utils.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 Constants from '../../utils/constants.jsx';
import UserStore from '../../stores/user_store.jsx';
const QueryOptions = Constants.QueryOptions; const QueryOptions = Constants.QueryOptions;
const messageType = Constants.MessageType; const messageType = Constants.MessageType;
...@@ -28,12 +29,14 @@ export default class Domains extends React.Component { ...@@ -28,12 +29,14 @@ export default class Domains extends React.Component {
this.getDomains = this.getDomains.bind(this); this.getDomains = this.getDomains.bind(this);
const page = parseInt(this.props.location.query.page, 10) || 1; const page = parseInt(this.props.location.query.page, 10) || 1;
this.isGlobalAdmin = UserStore.isGlobalAdmin();
this.state = { this.state = {
page, page,
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT) offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT)
}; };
} }
getDomains() { getDomains() {
const self = this; const self = this;
Client.getAllDomains( Client.getAllDomains(
...@@ -72,6 +75,7 @@ export default class Domains extends React.Component { ...@@ -72,6 +75,7 @@ export default class Domains extends React.Component {
} }
); );
} }
getPlans(domains) { getPlans(domains) {
const names = domains.map((d) => { const names = domains.map((d) => {
return d.name; return d.name;
...@@ -110,6 +114,7 @@ export default class Domains extends React.Component { ...@@ -110,6 +114,7 @@ export default class Domains extends React.Component {
$('#sidebar-domains').addClass('active'); $('#sidebar-domains').addClass('active');
this.getDomains(); this.getDomains();
} }
componentWillUnmount() { componentWillUnmount() {
$('#sidebar-domains').removeClass('active'); $('#sidebar-domains').removeClass('active');
} }
...@@ -117,6 +122,7 @@ export default class Domains extends React.Component { ...@@ -117,6 +122,7 @@ export default class Domains extends React.Component {
render() { render() {
const error = this.state.error; const error = this.state.error;
let message; let message;
let addDomainButton = null;
if (error) { if (error) {
message = ( message = (
<MessageBar <MessageBar
...@@ -127,7 +133,8 @@ export default class Domains extends React.Component { ...@@ -127,7 +133,8 @@ export default class Domains extends React.Component {
); );
} }
const addDomainButton = [{ if (this.isGlobalAdmin) {
addDomainButton = [{
label: 'Agregar Dominio', label: 'Agregar Dominio',
props: { props: {
className: 'btn btn-success', className: 'btn btn-success',
...@@ -136,6 +143,7 @@ export default class Domains extends React.Component { ...@@ -136,6 +143,7 @@ export default class Domains extends React.Component {
} }
} }
}]; }];
}
let tableResults; let tableResults;
if (this.state.data) { if (this.state.data) {
...@@ -233,7 +241,7 @@ export default class Domains extends React.Component { ...@@ -233,7 +241,7 @@ export default class Domains extends React.Component {
<thead> <thead>
<tr> <tr>
<th>{'Nombre'}</th> <th>{'Nombre'}</th>
<th className='text-center'>{'Casillas Usadas'}</th> <th className='text-center'>{'Casillas Compradas'}</th>
<th className='text-center'>{'Descripción'}</th> <th className='text-center'>{'Descripción'}</th>
<th className='text-center'>{'Estado'}</th> <th className='text-center'>{'Estado'}</th>
</tr> </tr>
......
...@@ -7,6 +7,7 @@ import ReactDOM from 'react-dom'; ...@@ -7,6 +7,7 @@ import ReactDOM from 'react-dom';
import * as GlobalActions from '../action_creators/global_actions.jsx'; import * as GlobalActions from '../action_creators/global_actions.jsx';
import {browserHistory, Link} from 'react-router'; import {browserHistory, Link} from 'react-router';
import * as Utils from '../utils/utils.jsx';
import logo from '../images/logo.png'; import logo from '../images/logo.png';
export default class Header extends React.Component { export default class Header extends React.Component {
...@@ -15,6 +16,7 @@ export default class Header extends React.Component { ...@@ -15,6 +16,7 @@ export default class Header extends React.Component {
this.handleSearch = this.handleSearch.bind(this); this.handleSearch = this.handleSearch.bind(this);
this.toggleSidebar = this.toggleSidebar.bind(this); this.toggleSidebar = this.toggleSidebar.bind(this);
} }
handleSearch(e) { handleSearch(e) {
e.preventDefault(); e.preventDefault();
const search = ReactDOM.findDOMNode(this.refs.query); const search = ReactDOM.findDOMNode(this.refs.query);
...@@ -22,11 +24,14 @@ export default class Header extends React.Component { ...@@ -22,11 +24,14 @@ export default class Header extends React.Component {
const utf8 = ReactDOM.findDOMNode(this.refs.utf8).value.trim(); const utf8 = ReactDOM.findDOMNode(this.refs.utf8).value.trim();
search.value = ''; search.value = '';
GlobalActions.emitStartLoading(); GlobalActions.emitStartLoading();
browserHistory.push(`search/global?utf8=${utf8}&query=${encodeURIComponent(term)}`); Utils.handleLink(e, `/search/${encodeURIComponent(term)}`);
//browserHistory.push(`search/?utf8=${utf8}&query=${encodeURIComponent(term)}`);
} }
toggleSidebar() { toggleSidebar() {
$('body').toggleClass('hide-sidebar').toggleClass('show-sidebar'); $('body').toggleClass('hide-sidebar').toggleClass('show-sidebar');
} }
render() { render() {
return ( return (
<div id='header'> <div id='header'>
......
...@@ -34,7 +34,7 @@ export default class Login extends React.Component { ...@@ -34,7 +34,7 @@ export default class Login extends React.Component {
componentDidMount() { componentDidMount() {
Client.isLoggedIn((data) => { Client.isLoggedIn((data) => {
if (data && data.logged_in) { if (data && data.logged_in) {
browserHistory.push('/companies'); browserHistory.push('/mailboxes');
} else { } else {
$('body').addClass('blank'); $('body').addClass('blank');
} }
...@@ -46,7 +46,7 @@ export default class Login extends React.Component { ...@@ -46,7 +46,7 @@ export default class Login extends React.Component {
this.setState({user}); this.setState({user});
if (user) { if (user) {
browserHistory.push('/companies'); browserHistory.push('/mailboxes');
} }
} }
submit(email, password) { submit(email, password) {
...@@ -71,7 +71,7 @@ export default class Login extends React.Component { ...@@ -71,7 +71,7 @@ export default class Login extends React.Component {
return Client.getAllCos( return Client.getAllCos(
(cosData) => { (cosData) => {
ZimbraStore.setAllCos(cosData); ZimbraStore.setAllCos(cosData);
browserHistory.push('/companies'); browserHistory.push('/mailboxes');
} }
); );
}, },
......
...@@ -2,17 +2,19 @@ ...@@ -2,17 +2,19 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import {browserHistory} from 'react-router';
import {Modal} from 'react-bootstrap'; import {Modal} from 'react-bootstrap';
import UserStore from '../../stores/user_store.jsx'; import UserStore from '../../stores/user_store.jsx';
import PasswordStrengthMeter from 'react-password-strength-meter'; import PasswordStrengthMeter from 'react-password-strength-meter';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import Constants from '../../utils/constants.jsx';
const MessageTypes = Constants.MessageType;
export default class ConfirmDeleteModal extends React.Component { export default class ConfirmDeleteModal extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleChangePasswd = this.handleChangePasswd.bind(this); this.handleChangePasswd = this.handleChangePasswd.bind(this);
this.forceLogout = this.forceLogout.bind(this);
this.handlePasswd = this.handlePasswd.bind(this); this.handlePasswd = this.handlePasswd.bind(this);
this.restart = this.restart.bind(this); this.restart = this.restart.bind(this);
...@@ -36,12 +38,6 @@ export default class ConfirmDeleteModal extends React.Component { ...@@ -36,12 +38,6 @@ export default class ConfirmDeleteModal extends React.Component {
return {currentUser}; return {currentUser};
} }
forceLogout(path) {
setTimeout(() => {
browserHistory.push(path);
}, 3000);
}
handleChangePasswd() { handleChangePasswd() {
if (this.refs.passwdfield.value && this.refs.passwdfield.value.length > 0) { if (this.refs.passwdfield.value && this.refs.passwdfield.value.length > 0) {
if (this.refs.passwdfield.value.length < 9) { if (this.refs.passwdfield.value.length < 9) {
...@@ -53,15 +49,22 @@ export default class ConfirmDeleteModal extends React.Component { ...@@ -53,15 +49,22 @@ export default class ConfirmDeleteModal extends React.Component {
} }
this.props.data.setPassword(this.refs.passwdfield.value, () => { this.props.data.setPassword(this.refs.passwdfield.value, () => {
this.setState({ const message = {
alert: true, error: 'Su contraseña se ha sido cambiada éxitosamente.',
message: 'Su contraseña se ha sido cambiada éxitosamente.', typeError: MessageTypes.SUCCESS
typeError: 'text-success' };
});
if (this.props.show) {
this.props.onHide();
}
if (this.props.data.name === this.state.currentUser.name) { if (this.props.data.name === this.state.currentUser.name) {
this.forceLogout('/logout'); const alterMessage = `${message.error} Deberá iniciar sesión de nuevo.`;
message.error = alterMessage;
message.logout = true;
} }
GlobalActions.emitMessage(message);
}, (error) => { }, (error) => {
this.setState({ this.setState({
alert: true, alert: true,
......
...@@ -14,46 +14,103 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -14,46 +14,103 @@ export default class FormVacacionesMailbox extends React.Component {
super(props); super(props);
this.handleSaveAutoResp = this.handleSaveAutoResp.bind(this); this.handleSaveAutoResp = this.handleSaveAutoResp.bind(this);
this.dateStart = null;
this.dateEnd = null;
this.initialDate = Utils.setInitialDate();
}
handleChangeDate(x, from) {
const ref = this.refs[from];
const timestamp = Utils.getInitialDateFromTimestamp(x);
ref.value = timestamp;
} }
handleSaveAutoResp() { handleSaveAutoResp() {
const data = this.props.data; const data = this.props.data;
const refs = this.refs; const refs = this.refs;
let enabled = refs.zimbraPrefOutOfOfficeReplyEnabled.checked.toString().toUpperCase(); const attrs = {};
let formated = document.getElementById('zimbraPrefOutOfOfficeUntilDate').value.split('/').reverse().join('') + '000000Z'; const isEnabled = refs.zimbraPrefOutOfOfficeReplyEnabled.checked;
const start = refs.zimbraPrefOutOfOfficeFromDate.value;
const end = refs.zimbraPrefOutOfOfficeUntilDate.value;
let formatedStart = document.getElementById('zimbraPrefOutOfOfficeFromDate').value.split('/').reverse().join('') + '000000Z';
let formatedEnd = document.getElementById('zimbraPrefOutOfOfficeUntilDate').value.split('/').reverse().join('') + '000000Z';
if ((start > end) && isEnabled) {
GlobalActions.emitMessage({
error: 'La fecha en la que termina su respuesta automática, debe ser mayor que en la que comienza.',
typeError: messageType.ERROR
});
let attrs = { return false;
zimbraPrefOutOfOfficeReplyEnabled: enabled, } else if ((start === end) && isEnabled) {
zimbraPrefOutOfOfficeUntilDate: formated, GlobalActions.emitMessage({
zimbraPrefOutOfOfficeReply: refs.zimbraPrefOutOfOfficeReply.value error: 'La fecha en la que comienza su respuesta automática no puede ser la misma fecha en la que termina.',
}; typeError: messageType.ERROR
});
return false;
}
if (isEnabled) {
attrs.zimbraPrefOutOfOfficeReplyEnabled = isEnabled.toString().toUpperCase();
attrs.zimbraPrefOutOfOfficeReply = refs.zimbraPrefOutOfOfficeReply.value;
attrs.zimbraPrefOutOfOfficeUntilDate = formatedEnd;
attrs.zimbraPrefOutOfOfficeFromDate = formatedStart;
} else {
attrs.zimbraPrefOutOfOfficeReplyEnabled = isEnabled.toString().toUpperCase();
}
Client.modifyAccount(data.id, attrs, () => { Client.modifyAccount(data.id, attrs, () => {
GlobalActions.emitMessage({ GlobalActions.emitMessage({
error: 'Se ha modificado su respuesta de vacaciones con éxito.', error: 'Se ha modificado su respuesta de vacaciones con éxito.',
type: messageType.SUCCESS typeError: messageType.SUCCESS
}); });
}, (error) => { }, (error) => {
GlobalActions.emitMessage({ GlobalActions.emitMessage({
error: error.message, error: error.message,
type: messageType.ERROR typeError: messageType.ERROR
}); });
}); });
return null;
} }
componentDidMount() { componentDidMount() {
const data = this.props.data.attrs; const data = this.props.data.attrs;
if (data.hasOwnProperty('zimbraPrefOutOfOfficeReplyEnabled')) { if (data.hasOwnProperty('zimbraPrefOutOfOfficeReplyEnabled')) {
this.refs.zimbraPrefOutOfOfficeReplyEnabled.checked = data.zimbraPrefOutOfOfficeReplyEnabled.toString().toLowerCase() === 'true'; 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')) { if (data.hasOwnProperty('zimbraPrefOutOfOfficeReply')) {
this.refs.zimbraPrefOutOfOfficeReply.value = data.zimbraPrefOutOfOfficeReply; this.refs.zimbraPrefOutOfOfficeReply.value = data.zimbraPrefOutOfOfficeReply;
} }
if (this.dateStart) {
this.refs.zimbraPrefOutOfOfficeFromDate.value = Utils.forceTimestampFromHumanDate(this.dateStart);
}
if (this.dateEnd) {
this.refs.zimbraPrefOutOfOfficeUntilDate.value = Utils.forceTimestampFromHumanDate(this.dateEnd);
}
}
componentWillMount() {
const data = this.props.data.attrs;
if (data.hasOwnProperty('zimbraPrefOutOfOfficeFromDate')) {
this.dateStart = Utils.dateFormatted(data.zimbraPrefOutOfOfficeFromDate, true, '/');
} else {
this.dateStart = this.initialDate.formatted;
}
if (data.hasOwnProperty('zimbraPrefOutOfOfficeUntilDate')) {
this.dateEnd = Utils.dateFormatted(data.zimbraPrefOutOfOfficeUntilDate, true, '/');
} else {
this.dateEnd = this.initialDate.formatted;
}
} }
render() { render() {
...@@ -84,6 +141,33 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -84,6 +141,33 @@ export default class FormVacacionesMailbox extends React.Component {
</div> </div>
</div> </div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
{'Empieza el'}
</label>
<div className='col-sm-8'>
<DateTimeField
inputFormat='DD/MM/YYYY'
inputProps={
{
id: 'zimbraPrefOutOfOfficeFromDate',
readOnly: 'readOnly'
}
}
onChange={(x) => {
this.handleChangeDate(x, 'zimbraPrefOutOfOfficeFromDate');
}}
defaultText={this.dateStart}
mode={'date'}
/>
<input
type='hidden'
ref='zimbraPrefOutOfOfficeFromDate'
/>
</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'>
{'Termina el'} {'Termina el'}
...@@ -98,6 +182,16 @@ export default class FormVacacionesMailbox extends React.Component { ...@@ -98,6 +182,16 @@ export default class FormVacacionesMailbox extends React.Component {
readOnly: 'readOnly' readOnly: 'readOnly'
} }
} }
onChange={(x) => {
this.handleChangeDate(x, 'zimbraPrefOutOfOfficeUntilDate');
}}
defaultText={this.dateEnd}
mode={'date'}
/>
<input
type='hidden'
ref='zimbraPrefOutOfOfficeUntilDate'
/> />
</div> </div>
</div> </div>
......
...@@ -46,6 +46,8 @@ export default class BlockGeneralInfoMailbox extends React.Component { ...@@ -46,6 +46,8 @@ export default class BlockGeneralInfoMailbox extends React.Component {
render() { render() {
let blockInfo = null; let blockInfo = null;
let statusCos = null; let statusCos = null;
console.log(ZimbraStore.getAllCos());
console.log(this.data);
const cosID = Utils.getEnabledPlansObjectByCos(ZimbraStore.getAllCos(), this.props.data.attrs.zimbraCOSId); const cosID = Utils.getEnabledPlansObjectByCos(ZimbraStore.getAllCos(), this.props.data.attrs.zimbraCOSId);
let cosName = null; let cosName = null;
......
...@@ -41,7 +41,9 @@ export default class Mailboxes extends React.Component { ...@@ -41,7 +41,9 @@ export default class Mailboxes extends React.Component {
const page = parseInt(this.props.location.query.page, 10) || 1; const page = parseInt(this.props.location.query.page, 10) || 1;
this.mailboxes = null; this.mailboxes = null;
this.status = ''; this.status = '';
this.cos = null; this.cos = Utils.getEnabledPlansByCos(ZimbraStore.getAllCos());
this.cosById = Utils.getEnabledPlansByCosId(ZimbraStore.getAllCos());
this.isRefreshing = true;
this.state = { this.state = {
page, page,
...@@ -146,7 +148,7 @@ export default class Mailboxes extends React.Component { ...@@ -146,7 +148,7 @@ export default class Mailboxes extends React.Component {
domainId = this.props.params.domain_id; domainId = this.props.params.domain_id;
this.getAllMailboxes(domainId); this.getAllMailboxes(domainId, window.manager_config.maxResultOnRequestZimbra);
} else { } else {
GlobalActions.emitStartLoading(); GlobalActions.emitStartLoading();
...@@ -154,7 +156,7 @@ export default class Mailboxes extends React.Component { ...@@ -154,7 +156,7 @@ export default class Mailboxes extends React.Component {
domainId = newProps.params.domain_id; domainId = newProps.params.domain_id;
} }
this.getAllMailboxes(domainId); this.getAllMailboxes(domainId, window.manager_config.maxResultOnRequestZimbra);
} }
} }
...@@ -180,8 +182,13 @@ export default class Mailboxes extends React.Component { ...@@ -180,8 +182,13 @@ export default class Mailboxes extends React.Component {
); );
} }
getAccounts(domainName) { getAccounts(domainName, maxResult) {
const attrs = {}; const attrs = {
limit: QueryOptions.DEFAULT_LIMIT,
maxResults: maxResult,
offset: this.state.offset
};
if (domainName) { if (domainName) {
attrs.domain = domainName; attrs.domain = domainName;
} }
...@@ -195,19 +202,23 @@ export default class Mailboxes extends React.Component { ...@@ -195,19 +202,23 @@ export default class Mailboxes extends React.Component {
}); });
} }
if (MailboxStore.hasMailboxes()) { if (MailboxStore.hasMailboxes() && MailboxStore.hasThisPage(this.state.page)) {
resolve(MailboxStore.getMailboxes()); console.log('has page with data');
return resolve(MailboxStore.getMailboxByPage(this.state.page));
} }
return Client.getAllAccounts(attrs, (success) => { return Client.getAllAccounts(attrs, (success) => {
MailboxStore.setMailboxes(success); MailboxStore.setMailboxes(success, this.state.page);
this.mailboxes = this.mailboxes = MailboxStore.getMailboxes(); this.mailboxes = MailboxStore.getMailboxes();
return resolve(success); return resolve(success);
}, (error) => { }, (error) => {
return reject(error); return reject(error);
}); });
}).then((data) => { }).then((data) => {
if (data.account) { if (data.account) {
this.isRefreshing = false;
const tables = this.buildTableFromData(data, ['Todas', 'Bloqueadas']); const tables = this.buildTableFromData(data, ['Todas', 'Bloqueadas']);
if (tables.lockedAlert) { if (tables.lockedAlert) {
...@@ -227,9 +238,18 @@ export default class Mailboxes extends React.Component { ...@@ -227,9 +238,18 @@ export default class Mailboxes extends React.Component {
domain: domainName domain: domainName
}); });
}).catch((error) => { }).catch((error) => {
return error; if (error.code === 'account.TOO_MANY_SEARCH_RESULTS') {
this.isRefreshing = true;
const newMaxResult = (parseInt(maxResult, 10) + window.manager_config.autoincrementOnFailRequestZimbra);
window.manager_config.maxResultOnRequestZimbra = newMaxResult;
setTimeout(() => {
this.getAccounts(domainName, newMaxResult);
}, 250);
}
}).finally(() => { }).finally(() => {
if (!this.isRefreshing) {
GlobalActions.emitEndLoading(); GlobalActions.emitEndLoading();
}
}); });
} }
...@@ -237,11 +257,11 @@ export default class Mailboxes extends React.Component { ...@@ -237,11 +257,11 @@ export default class Mailboxes extends React.Component {
if (domainId) { if (domainId) {
return this.domainInfo(domainId).then(() => { return this.domainInfo(domainId).then(() => {
const domain = DomainStore.getCurrent(); const domain = DomainStore.getCurrent();
this.getAccounts(domain.name); this.getAccounts(domain.name, window.manager_config.maxResultOnRequestZimbra);
}); });
} }
return this.getAccounts(); return this.getAccounts(null, window.manager_config.maxResultOnRequestZimbra);
} }
refreshAllAccounts() { refreshAllAccounts() {
...@@ -276,6 +296,29 @@ export default class Mailboxes extends React.Component { ...@@ -276,6 +296,29 @@ export default class Mailboxes extends React.Component {
buildRow(row, classes, status) { buildRow(row, classes, status) {
const id = row.id; const id = row.id;
const attrs = row.attrs;
let displayName = 'No definido';
let tipo = attrs.zimbraCOSId || null;
if (tipo) {
tipo = this.cosById[tipo] || null;
if (tipo) {
tipo = Utils.titleCase(tipo);
}
}
if (!tipo) {
tipo = 'Desconocido';
}
if (attrs.displayName) {
displayName = attrs.displayName.trim();
} else if (attrs.cn || attrs.sn) {
const cn = attrs.cn || '';
const sn = attrs.sn || '';
displayName = `${cn.trim()} ${sn.trim()}`;
}
return ( return (
<tr <tr
key={id} key={id}
...@@ -297,14 +340,14 @@ export default class Mailboxes extends React.Component { ...@@ -297,14 +340,14 @@ export default class Mailboxes extends React.Component {
</td> </td>
<td className={'mailbox-displayname'}> <td className={'mailbox-displayname'}>
{row.name} {displayName}
</td> </td>
<td className={'mailbox-cos-plan'}> <td className={'mailbox-cos-plan'}>
<statusLabel className={'label-plan label-unknown'}>{'unknown'}</statusLabel> <statusLabel className={'label-plan label-unknown'}>{tipo}</statusLabel>
</td> </td>
<td> <td className='text-center'>
<Button <Button
btnAttrs={ btnAttrs={
{ {
...@@ -360,8 +403,8 @@ export default class Mailboxes extends React.Component { ...@@ -360,8 +403,8 @@ export default class Mailboxes extends React.Component {
<tr> <tr>
<th>{'Email'}</th> <th>{'Email'}</th>
<th className='td-mbxs text-left'>{'Nombre'}</th> <th className='td-mbxs text-left'>{'Nombre'}</th>
<th className='text-center text-center'>{'Tipo'}</th> <th className='text-left'>{'Tipo'}</th>
<th className='text-center text-center'>{'Acciones'}</th> <th className='text-center'>{'Acciones'}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -416,7 +459,7 @@ export default class Mailboxes extends React.Component { ...@@ -416,7 +459,7 @@ export default class Mailboxes extends React.Component {
} }
const response = {}; const response = {};
const all = `${arrayTabNames.shift()} (${activeAccounts.length})`; const all = `${arrayTabNames.shift()} (${totalAccounts})`;
const locked = `${arrayTabNames.shift()} (${lockedAccounts.length})`; const locked = `${arrayTabNames.shift()} (${lockedAccounts.length})`;
// create structure html for all accountsç // create structure html for all accountsç
...@@ -461,7 +504,9 @@ export default class Mailboxes extends React.Component { ...@@ -461,7 +504,9 @@ export default class Mailboxes extends React.Component {
} }
]; ];
let activePagination = null; let activePagination = {
total: totalAccounts
};
const totalPage = Math.ceil(totalAccounts / QueryOptions.DEFAULT_LIMIT); const totalPage = Math.ceil(totalAccounts / QueryOptions.DEFAULT_LIMIT);
if (activeAccounts.length > QueryOptions.DEFAULT_LIMIT) { if (activeAccounts.length > QueryOptions.DEFAULT_LIMIT) {
activeAccounts = activeAccounts.slice(this.state.offset, (this.state.page * QueryOptions.DEFAULT_LIMIT)); activeAccounts = activeAccounts.slice(this.state.offset, (this.state.page * QueryOptions.DEFAULT_LIMIT));
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import $ from 'jquery'; import $ from 'jquery';
import React from 'react'; import React from 'react';
import {browserHistory} from 'react-router';
import EventStore from '../../stores/event_store.jsx'; import EventStore from '../../stores/event_store.jsx';
...@@ -52,6 +53,12 @@ export default class MailboxDetails extends React.Component { ...@@ -52,6 +53,12 @@ export default class MailboxDetails extends React.Component {
error: attrs.error, error: attrs.error,
type: attrs.typeError type: attrs.typeError
}); });
if (attrs.logout) {
setTimeout(() => {
browserHistory.push('/logout');
}, 3000);
}
} }
onRemoveAlias(alias) { onRemoveAlias(alias) {
......
...@@ -19,7 +19,7 @@ export default class PageInfo extends React.Component { ...@@ -19,7 +19,7 @@ export default class PageInfo extends React.Component {
PageInfo.propTypes = { PageInfo.propTypes = {
titlePage: React.PropTypes.any.isRequired, titlePage: React.PropTypes.any.isRequired,
descriptionPage: React.PropTypes.string descriptionPage: React.PropTypes.any
}; };
PageInfo.defaultProps = { PageInfo.defaultProps = {
......
...@@ -60,7 +60,8 @@ export default class Pagination extends React.Component { ...@@ -60,7 +60,8 @@ export default class Pagination extends React.Component {
let prev; let prev;
let next; let next;
let last; let last;
let i = 1; let console;
//let i = 1;
if (current > 1 && current <= total) { if (current > 1 && current <= total) {
first = ( first = (
...@@ -96,9 +97,43 @@ export default class Pagination extends React.Component { ...@@ -96,9 +97,43 @@ export default class Pagination extends React.Component {
>{'Última'}</a> >{'Última'}</a>
</li> </li>
); );
console = (
<li key='console-page'>
<span>{`${current} de ${this.props.totalPages}`}</span>
</li>
);
} }
for (; i <= total; i++) { const rangeBack = current - this.props.range;
const rangeForward = ((current + this.props.range) + 1);
for (let p = rangeBack; p < rangeForward; p++) {
if ((p > 0) && (p <= total)) {
if (p === current) {
pages.push(
<li
key={`page-${p}`}
className='active'
>
<a remote='false'>{p.toString()}</a>
</li>
);
} else {
pages.push(
<li key={`page-${p}`}>
<a
onClick={this.handleChange}
>
{p.toString()}
</a>
</li>
);
}
}
}
/*for (; i <= total; i++) {
if (current === i) { if (current === i) {
pages.push( pages.push(
<li <li
...@@ -119,7 +154,7 @@ export default class Pagination extends React.Component { ...@@ -119,7 +154,7 @@ export default class Pagination extends React.Component {
</li> </li>
); );
} }
} }*/
return ( return (
<div id='pagination'> <div id='pagination'>
...@@ -129,6 +164,7 @@ export default class Pagination extends React.Component { ...@@ -129,6 +164,7 @@ export default class Pagination extends React.Component {
{pages} {pages}
{next} {next}
{last} {last}
{console}
</ul> </ul>
</div> </div>
); );
...@@ -138,5 +174,10 @@ export default class Pagination extends React.Component { ...@@ -138,5 +174,10 @@ export default class Pagination extends React.Component {
Pagination.propTypes = { Pagination.propTypes = {
url: React.PropTypes.string.isRequired, url: React.PropTypes.string.isRequired,
currentPage: React.PropTypes.number.isRequired, currentPage: React.PropTypes.number.isRequired,
totalPages: React.PropTypes.number.isRequired totalPages: React.PropTypes.number.isRequired,
range: React.PropTypes.number
}; };
Pagination.defaultProps = {
range: 2
}
...@@ -58,10 +58,26 @@ export default class ProgressTask extends React.Component { ...@@ -58,10 +58,26 @@ export default class ProgressTask extends React.Component {
}); });
} }
isTaskDuplicated(params) {
const id = params.id;
for (let i = 0; i < this.tasks.length; i++) {
const currentTask = this.tasks[i];
if (id === currentTask.id) {
return true;
}
}
return false;
}
showTasks(params) { showTasks(params) {
if (this.isTaskDuplicated(params)) {
return null;
}
this.tasks.push(params); this.tasks.push(params);
this.setState({ return this.setState({
show: true, show: true,
tasks: this.tasks, tasks: this.tasks,
total: this.tasks.length total: this.tasks.length
......
import React from 'react';
import PageInfo from '../page_info.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import * as Client from '../../utils/client.jsx';
import Button from '../button.jsx';
import * as Utils from '../../utils/utils.jsx';
import Panel from '../panel.jsx';
export default class SearchView extends React.Component {
constructor(props) {
super(props);
this.makeSearch = this.makeSearch.bind(this);
this.state = {};
}
componentDidMount() {
GlobalActions.emitEndLoading();
const query = this.props.params.query;
this.makeSearch(query);
}
componentWillReceiveProps(newProps) {
//const condition = (newProps.params.query !== this.props.params.query);
GlobalActions.emitEndLoading();
const query = newProps.params.query;
this.makeSearch(query);
};
makeSearch(query) {
Client.search({
query: `(|(mail=*${query}*)(cn=*${query}*)(sn=*${query}*)(gn=*${query}*)(displayName=*${query}*)(zimbraMailDeliveryAddress=*${query}*)(zimbraDomainName=*${query}*)(uid=*${query}*)(zimbraMailAlias=*${query}*)(uid=*${query}*)(zimbraDomainName=*${query}*)(cn=*${query}*))`,
types: 'accounts,distributionlists,domains'
}, (success) => {
const result = [];
for (const key in success) {
if (success.hasOwnProperty(key)) {
if (key === 'dl' || key === 'domain' || key === 'account') {
Array.prototype.push.apply(result, success[key]);
}
}
}
if (success.total <= 0) {
return this.setState({
notfound: true
});
}
return this.setState({
result
});
}, (error) => {
console.log(error);
});
}
render() {
const query = this.props.params.query;
let content = null;
const pagelInfo = (
<PageInfo
titlePage='Búsqueda'
descriptionPage={`Resultados para su búsqueda: ${query}`}
/>
);
if (this.state.result) {
const data = this.state.result;
const objectDomain = {};
const rows = data.map((item) => {
const type = item.constructor.name.toString().toLowerCase();
let tipo = 'Desconocido';
let url = null;
const id = item.id;
switch(type) {
case 'domain':
tipo = (
<div>
<i className='fa fa-globe fa-lg'></i>
<span className='marginLeft'>{'Dominio'}</span>
</div>
);
url = `/domains/${id}`;
objectDomain[item.name] = id;
break;
case 'account':
tipo = (
<div>
<i className='fa fa-user fa-lg'></i>
<span className='marginLeft'>{'Casilla'}</span>
</div>
);
url = `/mailboxes/${id}`;
break;
case 'distributionlist':
tipo = (
<div>
<i className='fa fa-users fa-lg'></i>
<span className='marginLeft'>{'Lista de Distribución'}</span>
</div>
);
const dlName = item.name.indexOf('@') > -1 ? item.name.split('@').pop() : item.name;
let domainId = null;
if (objectDomain[dlName]) {
domainId = objectDomain[dlName];
} else {
domainId = Utils.getDomainIdFromDL(item.name, data);
}
url = `/domains/${domainId}/distribution_lists/${id}`;
break;
}
return (
<tr
key={id}
className={'mailbox-row'}
>
<td className={'mailbox-name'}>
{tipo}
</td>
<td className={'mailbox-displayname'}>
{item.name}
</td>
<td className={'text-right'}>
<Button
btnAttrs={
{
className: 'btn btn-xs btn-info',
onClick: (e) => Utils.handleLink(e, url)
}
}
>
{'Ver'}
</Button>
</td>
</tr>
);
});
const table = (
<div
key='mailbox'
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 className='text-left'>{'Tipo'}</th>
<th className='td-mbxs text-left'>{'Nombre'}</th>
<th className='text-right'>{'Acciones'}</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
</div>
);
content = (
<Panel
children={table}
hasHeader={false}
/>
);
}
if (this.state.notfound) {
content = (
<div className='text-center'>
<h4>
No existen resultados para su búsqueda
</h4>
</div>
);
}
return (
<div>
{pagelInfo}
<div className='content animate-panel'>
<div className='row'>
<div className='col-md-12 panel-with-tabs'>
{content}
</div>
</div>
</div>
</div>
);
}
}
SearchView.propTypes = {
params: React.PropTypes.object
};
...@@ -24,14 +24,6 @@ export default class SidebarMenu extends React.Component { ...@@ -24,14 +24,6 @@ export default class SidebarMenu extends React.Component {
className='nav' className='nav'
id='side-menu' id='side-menu'
> >
<li id='sidebar-dashboards'>
<a
href='#'
onClick={(e) => this.handleLink(e, '/dashboards')}
>
<span className='nav-label'>{'dashboards'}</span>
</a>
</li>
<li id='sidebar-companies'> <li id='sidebar-companies'>
<a <a
href='#' href='#'
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
"url": "http://192.168.1.8:8081", "url": "http://192.168.1.8:8081",
"token": "otto" "token": "otto"
}, },
"maxResultOnRequestZimbra": 4000,
"autoincrementOnFailRequestZimbra": 500,
"plans": { "plans": {
"basic": true, "basic": true,
"premium": true, "premium": true,
......
...@@ -22,6 +22,7 @@ import CreateMailBox from './components/mailbox/create_mailbox.jsx'; ...@@ -22,6 +22,7 @@ import CreateMailBox from './components/mailbox/create_mailbox.jsx';
import EditMailBox from './components/mailbox/edit_mailbox.jsx'; import EditMailBox from './components/mailbox/edit_mailbox.jsx';
import DistributionLists from './components/distribution/distribution_lists.jsx'; import DistributionLists from './components/distribution/distribution_lists.jsx';
import EditDistributionList from './components/distribution/edit_distribution_lists.jsx'; import EditDistributionList from './components/distribution/edit_distribution_lists.jsx';
import SearchView from './components/search/search.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';
...@@ -193,6 +194,11 @@ function renderRootComponent() { ...@@ -193,6 +194,11 @@ function renderRootComponent() {
path='logout' path='logout'
onEnter={onLoggedOut} onEnter={onLoggedOut}
/> />
<Route
path='search/:query'
component={SearchView}
/>
</Route> </Route>
<Route component={NotLoggedIn}> <Route component={NotLoggedIn}>
<IndexRedirect to='login'/> <IndexRedirect to='login'/>
......
...@@ -3,3 +3,4 @@ ...@@ -3,3 +3,4 @@
@import 'domain'; @import 'domain';
@import 'companies'; @import 'companies';
@import 'mailbox'; @import 'mailbox';
@import 'search';
.marginLeft {
margin-left: 5px;
}
...@@ -7,11 +7,13 @@ import Constants from '../utils/constants.jsx'; ...@@ -7,11 +7,13 @@ import Constants from '../utils/constants.jsx';
const eventTypes = Constants.EventTypes; const eventTypes = Constants.EventTypes;
let mailboxesArray = null; let mailboxesArray = null;
let mailboxexInstances = [];
class MailboxStoreClass extends EventEmitter { class MailboxStoreClass extends EventEmitter {
constructor() { constructor() {
super(); super();
this.current = null; this.current = null;
this.currentPage = {};
} }
getMailboxById(id) { getMailboxById(id) {
...@@ -38,6 +40,27 @@ class MailboxStoreClass extends EventEmitter { ...@@ -38,6 +40,27 @@ class MailboxStoreClass extends EventEmitter {
} }
} }
hasThisPage(page) {
if (page && this.currentPage[page]) {
return this.currentPage[page];
}
return false;
}
setCurrentPage(page) {
this.currentPage[page] = true;
}
getMailboxByPage(page) {
if (page && this.currentPage[page]) {
console.log(this.currentPage);
return this.currentPage[page];
}
return false;
}
setCurrent(account) { setCurrent(account) {
this.current = account; this.current = account;
} }
...@@ -54,12 +77,33 @@ class MailboxStoreClass extends EventEmitter { ...@@ -54,12 +77,33 @@ class MailboxStoreClass extends EventEmitter {
return false; return false;
} }
getPages() {
return this.currentPage;
}
getMailboxes() { getMailboxes() {
return mailboxesArray; return mailboxesArray;
} }
setMailboxes(mailboxes) { setMailboxes(mailboxes, page) {
if (mailboxesArray) {
Array.prototype.push.apply(mailboxexInstances, mailboxes.account);
mailboxesArray.account = mailboxexInstances;
console.log('mailbox', mailboxes);
if (page) {
this.currentPage[page] = mailboxes;
console.log(this.currentPage[page]);
}
return true;
}
mailboxesArray = mailboxes; mailboxesArray = mailboxes;
mailboxexInstances = mailboxes.account;
if (page) {
this.currentPage[page] = mailboxes;
console.log(this.currentPage[page]);
}
return true;
} }
changeAccount(newAccount) { changeAccount(newAccount) {
......
...@@ -29,6 +29,7 @@ function handleError(methodName, err) { ...@@ -29,6 +29,7 @@ function handleError(methodName, err) {
if (err) { if (err) {
error.message = err.extra.reason; error.message = err.extra.reason;
error.code = err.extra.code || null;
} else { } else {
error.message = 'Ocurrio un error general'; error.message = 'Ocurrio un error general';
} }
...@@ -111,7 +112,7 @@ export function login(user, password, success, error) { ...@@ -111,7 +112,7 @@ export function login(user, password, success, error) {
} }
Utils.setCookie('token', zimbra.client.token); Utils.setCookie('token', zimbra.client.token);
ZimbraStore.setCurrent(zimbra); window.manager_config.dns.token = Utils.getCookie('token');
return getMe(success, error); return getMe(success, error);
}); });
} }
...@@ -524,9 +525,7 @@ export function search(query, success, error) { ...@@ -524,9 +525,7 @@ export function search(query, success, error) {
initZimbra().then( initZimbra().then(
(zimbra) => { (zimbra) => {
zimbra.directorySearch( zimbra.directorySearch(
{ query,
query
},
(err, data) => { (err, data) => {
if (err) { if (err) {
const e = handleError('search', err); const e = handleError('search', err);
......
...@@ -544,3 +544,59 @@ export function getOwners(owners) { ...@@ -544,3 +544,59 @@ export function getOwners(owners) {
throw Error('Owners array no es un arreglo :' + typeof owners); throw Error('Owners array no es un arreglo :' + typeof owners);
} }
export function getDomainIdFromDL(dlName, arr) {
const domainName = dlName.indexOf('@') > -1 ? dlName.split('@').pop() : dlName;
for (const domain in arr) {
if (arr.hasOwnProperty(domain)) {
if (domain.constructor.name.toString().toLowerCase() === 'domain') {
if (arr[domain].name === domainName) {
return arr[domain];
}
}
}
}
}
export function getInitialDateFromTimestamp(timestamp) {
const time = parseInt(timestamp, 10);
const date = new Date(time).toLocaleString();
let dateParts = date.split('/');
const lastPosition = dateParts.pop();
const formattedLastPosition = lastPosition.substring(0, 4);
dateParts.push(formattedLastPosition);
const timestampReseted = new Date(dateParts[2], (parseInt(dateParts[1], 10) - 1).toString(), dateParts[0], '00', '00', '00').getTime();
return timestampReseted;
}
export function forceTimestampFromHumanDate(date) {
const arrDate = date.split('/').reverse();
const newDateArr = arrDate.map((pos, i) => {
let item = parseInt(pos, 10);
if (i === 1) {
const tmp = item - 1;
item = tmp;
}
return item;
});
const formattedTimeStamp = new Date(newDateArr[0], newDateArr[1], newDateArr[2], '00', '00', '00').getTime();
return formattedTimeStamp;
}
export function setInitialDate(){
const dateInstance = new Date();
const day = dateInstance.getDate().toString().length < 2 ? '0' + dateInstance.getDate().toString() : dateInstance.getDate();
const month = (dateInstance.getMonth() + 1).toString().length < 2 ? '0' + (dateInstance.getMonth() + 1).toString() : (dateInstance.getMonth() + 1);
const formatted = `${day}/${month}/${dateInstance.getFullYear()}`;
const date = new Date(dateInstance.getFullYear(), dateInstance.getMonth(), dateInstance.getDate(), '00','00','00').getTime();
const dateObject = {
timestamp: date,
formatted
};
return dateObject;
}
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