Commit a66b9cdf authored by Patricio Bruna's avatar Patricio Bruna

Merge pull request #90 from ZBoxApp/issues_resolved_manager

solved multiple issued from mailbox, domain , search, global style, i…
parents 6ba5d677 75a752a8
module.exports = {"main":{"js":"/345013bundle.js"}}
\ No newline at end of file
module.exports = {"main":{"js":"/928473bundle.js"}}
\ No newline at end of file
......@@ -47,6 +47,9 @@ export default class DomainDetails extends React.Component {
if (domain && domain.id === this.props.params.id) {
GlobalActions.emitEndLoading();
this.setState({
domain
});
Client.getZone(domain.name, (zone) => {
DomainStore.setZoneDNS(zone);
......
......@@ -133,7 +133,7 @@ export default class Domains extends React.Component {
);
}
if (this.isGlobalAdmin) {
if (!this.isGlobalAdmin) {
addDomainButton = [{
label: 'Agregar Dominio',
props: {
......
......@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React from 'react';
import {Modal} from 'react-bootstrap';
import * as GlobalActions from '../action_creators/global_actions.jsx';
import SelectCols from './select-col.jsx';
......@@ -36,6 +35,8 @@ export default class ImportMassiveModal extends React.Component {
this.plans = Utils.getEnabledPlansByCos(ZimbraStore.getAllCos());
this.limit = 200;
this.state = {
options: this.options
};
......@@ -280,6 +281,8 @@ export default class ImportMassiveModal extends React.Component {
createMassiveAccounts(accounts) {
const allAccounts = [];
let hasError = false;
let runAgain = false;
let loop = 0;
for (const account in accounts) {
if (accounts.hasOwnProperty(account)) {
......@@ -294,6 +297,17 @@ export default class ImportMassiveModal extends React.Component {
Reflect.deleteProperty(accounts[account], 'passwd');
allAccounts.push(Client.createAccountByBatch(email, passwd, accounts[account]));
Reflect.deleteProperty(accounts, account);
loop++;
if (loop >= this.limit) {
const step = parseInt(account, 10);
if (accounts[step + 1]) {
runAgain = true;
loop = 0;
}
break;
}
}
}
......@@ -325,9 +339,20 @@ export default class ImportMassiveModal extends React.Component {
}
}
if (runAgain) {
setTimeout(() => {
this.createMassiveAccounts(accounts);
}, 250);
return null;
}
//Aqui va error batchrequest
GlobalActions.emitEndTask({
if (this.show) {
this.onHide();
}
return GlobalActions.emitEndTask({
id: 'casillamasiva',
toast: {
message: 'Se han importado todas las casillas.',
......
......@@ -51,7 +51,7 @@ export default class BlockGeneralInfoMailbox extends React.Component {
if (window.manager_config.plans[cosID.name]) {
cosName = Utils.titleCase(cosID.name);
statusCos = 'label btn-xs' + window.manager_config.plans[cosID.name].statusCos;
statusCos = 'label btn-xs ' + window.manager_config.plans[cosID.name].statusCos;
}
if (this.state.hasDomain) {
......@@ -64,6 +64,20 @@ export default class BlockGeneralInfoMailbox extends React.Component {
const description = attrs.description;
const mailhost = attrs.zimbraMailHost;
const archive = attrs.zimbraArchiveAccount;
let btnArchive = archive;
if (this.props.webmail) {
btnArchive = (
<Button
btnAttrs={{
href: this.props.webmail,
target: '_blank'
}}
>
{archive}
</Button>
);
}
blockInfo = (
<article className='account-info'>
......@@ -105,7 +119,7 @@ export default class BlockGeneralInfoMailbox extends React.Component {
<div>
<p>
<strong>{'Archive: '}</strong>
{archive}
{btnArchive}
</p>
</div>
)}
......@@ -138,5 +152,6 @@ export default class BlockGeneralInfoMailbox extends React.Component {
BlockGeneralInfoMailbox.propTypes = {
data: React.PropTypes.object.isRequired,
webmail: React.PropTypes.string,
location: React.PropTypes.object.isRequired
};
......@@ -47,7 +47,8 @@ export default class Mailboxes extends React.Component {
this.state = {
page,
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT)
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT),
loading: true
};
}
......@@ -143,7 +144,8 @@ export default class Mailboxes extends React.Component {
this.state = {
page,
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT)
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT),
loading: true
};
domainId = this.props.params.domain_id;
......@@ -229,13 +231,15 @@ export default class Mailboxes extends React.Component {
}
return this.setState({
data: tables
data: tables,
loading: false
});
}
return this.setState({
notMatches: true,
domain: domainName
domain: domainName,
loading: false
});
}).catch((error) => {
if (error.code === 'account.TOO_MANY_SEARCH_RESULTS') {
......@@ -583,6 +587,15 @@ export default class Mailboxes extends React.Component {
let message = null;
let content = null;
if (this.state.loading) {
content = (
<div className='text-center'>
<i className='fa fa-spinner fa-spin fa-4x fa-fw'></i>
<p>{'Cargando Casillas...'}</p>
</div>
);
}
if (this.state.error) {
message = (
<MessageBar
......
......@@ -303,9 +303,11 @@ export default class MailboxDetails extends React.Component {
}
if (this.state.data) {
const webmail = this.state.webmail ? this.state.webmail : null;
generalData = (
<BlockGeneralInfoMailbox
data={this.state.data}
webmail={webmail}
location={this.props.location}
/>
);
......@@ -321,7 +323,7 @@ export default class MailboxDetails extends React.Component {
props: {
className: 'btn btn-xs btn-default action-info-btns',
onClick: (e) => {
this.handleEdit(e, `mailboxes/${this.state.data.id}/edit`, this.props.location);
this.handleEdit(e, `/mailboxes/${this.state.data.id}/edit`, this.props.location);
}
},
label: 'Editar'
......@@ -330,7 +332,7 @@ export default class MailboxDetails extends React.Component {
setComponent: (
<ToggleModalButton
role='button'
className='btn btn-xs btn-default action-info-btns'
className='btn btn-xs btn-danger action-info-btns'
dialogType={ChangePasswordModal}
dialogProps={{
data: this.state.data
......@@ -440,21 +442,30 @@ export default class MailboxDetails extends React.Component {
<div className='content animate-panel'>
{message}
<div className='row'>
<div className='col-md-6 central-content'>
<Panel
title='Información General'
btnsHeader={btnsGeneralInfo}
children={generalData}
classHeader='with-min-height'
/>
</div>
<div className='col-md-6 central-content'>
<Panel
title='Estadísticas'
btnsHeader={btnsStats}
children={statsData}
classHeader='with-min-height'
/>
<div className='layout-back clearfix'>
<div className='back-left backstage'>
<div className='backbg'></div>
</div>
<div className='back-right backstage'>
<div className='backbg'></div>
</div>
<div className='col-md-6 central-content'>
<Panel
title='Información General'
btnsHeader={btnsGeneralInfo}
children={generalData}
classHeader='with-min-height'
/>
</div>
<div className='col-md-6 central-content'>
<Panel
title='Estadísticas'
btnsHeader={btnsStats}
children={statsData}
classHeader='with-min-height'
/>
</div>
</div>
</div>
<div className='row'>
......
import React from 'react';
import * as Utils from '../../utils/utils.jsx';
import ZimbraStore from '../../stores/zimbra_store.jsx';
import bytesConvertor from 'bytes';
export default class BlockGeneralInfoMailbox extends React.Component {
constructor(props) {
......@@ -9,6 +11,7 @@ export default class BlockGeneralInfoMailbox extends React.Component {
this.className = null;
this.lastConection = 'No se ha conectado';
this.getMailSize = this.getMailSize.bind(this);
this.sizeEnabled = Utils.getEnabledPlansObjectByCos(ZimbraStore.getAllCos(), this.props.data.attrs.zimbraCOSId);
this.state = {};
}
......@@ -17,7 +20,7 @@ export default class BlockGeneralInfoMailbox extends React.Component {
this.props.data.getMailboxSize((err, bytes) => {
let currentSize = '0 MB';
if (bytes) {
currentSize = Utils.bytesToMegas(bytes);
currentSize = bytesConvertor(bytes);
}
this.setState({
......@@ -58,11 +61,18 @@ export default class BlockGeneralInfoMailbox extends React.Component {
render() {
let size = null;
let sizeEnaled = null;
if (this.state.size) {
size = this.state.size;
}
if (this.sizeEnabled.hasOwnProperty('attrs') && this.sizeEnabled.attrs.zimbraMailQuota) {
const sizeOfPlan = typeof this.sizeEnabled.attrs.zimbraMailQuota === 'string' ? parseInt(this.sizeEnabled.attrs.zimbraMailQuota, 10) : this.sizeEnabled.attrs.zimbraMailQuota;
sizeEnaled = bytesConvertor(sizeOfPlan);
}
return (
<div>
<div className='row'>
......@@ -85,11 +95,23 @@ export default class BlockGeneralInfoMailbox extends React.Component {
<div className='row'>
<div className='col-xs-6'>
<div>
<p>
<span className='center-block'>Espacio Usado</span>
<strong>{size}</strong>
</p>
<div className='row'>
<div className='col-xs-6'>
{size && (
<p>
<span className='center-block'>Espacio Usado</span>
<strong>{size}</strong>
</p>
)}
</div>
<div className='col-xs-6'>
{sizeEnaled && (
<p>
<span className='center-block'>Espacio Disponible</span>
<strong>{sizeEnaled}</strong>
</p>
)}
</div>
</div>
</div>
<div className='col-xs-6'>
......
import React from 'react';
import {browserHistory} from 'react-router';
import Constants from '../utils/constants.jsx';
const limit = Constants.QueryOptions.DEFAULT_LIMIT;
export default class Pagination extends React.Component {
constructor(props) {
......@@ -48,22 +51,28 @@ export default class Pagination extends React.Component {
}
handleLast(e) {
e.preventDefault();
const page = this.getPageQueryString(this.props.totalPages);
const page = this.getPageQueryString(Math.ceil(this.props.totalPages / limit));
browserHistory.push(`/${this.props.url}${page}`);
}
render() {
//let i = 1;
const total = this.props.totalPages;
const current = this.props.currentPage;
const totalPages = Math.ceil(total / limit);
const pages = [];
let first;
let prev;
let next;
let last;
let console;
if (current > 1 && current <= total) {
const console = (
<li key='console-page'>
<span>{`${current} de ${totalPages}`}</span>
</li>
);
if (current > 1 && current <= totalPages) {
first = (
<li key='first-page'>
<a
......@@ -81,7 +90,7 @@ export default class Pagination extends React.Component {
);
}
if (current < total) {
if (current < totalPages) {
next = (
<li key='next-page'>
<a
......@@ -97,16 +106,10 @@ export default class Pagination extends React.Component {
>{'Última'}</a>
</li>
);
console = (
<li key='console-page'>
<span>{`${current} de ${this.props.totalPages}`}</span>
</li>
);
}
const rangeBack = current - this.props.range;
const rangeForward = ((current + this.props.range) + 1);
const rangeForward = ((current + this.props.range) + 1) > totalPages ? totalPages + 1 : ((current + this.props.range) + 1);
for (let p = rangeBack; p < rangeForward; p++) {
if ((p > 0) && (p <= total)) {
......
......@@ -3,22 +3,26 @@ import Button from './button.jsx';
export default class Panel extends React.Component {
render() {
const btns = this.props.btnsHeader.map((btn, i) => {
if (btn.setComponent) {
return btn.setComponent;
}
return (
<Button
btnAttrs={btn.props}
key={`button-${i}`}
>
{btn.label}
</Button>
);
});
let btns = null;
if (this.props.btnsHeader) {
btns = this.props.btnsHeader.map((btn, i) => {
if (btn.setComponent) {
return btn.setComponent;
}
return (
<Button
btnAttrs={btn.props}
key={`button-${i}`}
>
{btn.label}
</Button>
);
});
}
let panelHeader;
if (this.props.hasHeader) {
if (this.props.hasHeader && (this.props.btnsHeader || this.props.title || this.props.filter)) {
panelHeader = (
<div className='panel-heading hbuilt clearfix'>
<div className='pull-right'>{btns}</div>
......
......@@ -28,16 +28,20 @@ export default class Sidebar extends React.Component {
}
render() {
if (this.state.user) {
const userName = this.state.user.name;
return (
<aside id='menu'>
<div id='navigation'>
<div className='profile-picture'>
<div className='stats-label text-color'>
<span className='font-extra-bold font-uppercase'>
<div className='stats-label text-color format-text'>
<span
className='font-extra-bold font-uppercase'
title={userName}
>
<Link
to={`/mailboxes/${this.state.user.id}`}
>
{this.state.user.name}
{userName}
</Link>
<small className='text-muted'></small>
</span>
......
......@@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import * as GlobalActions from '../action_creators/global_actions.jsx';
import UserStore from '../stores/user_store.jsx';
import React from 'react';
import {browserHistory} from 'react-router';
......@@ -19,6 +20,8 @@ export default class SidebarMenu extends React.Component {
}
}
render() {
const companyText = UserStore.isGlobalAdmin() ? 'Empresas' : 'Mi Empresa';
return (
<ul
className='nav'
......@@ -29,7 +32,7 @@ export default class SidebarMenu extends React.Component {
href='#'
onClick={(e) => this.handleLink(e, '/companies')}
>
<span className='nav-label'>{'Empresas'}</span>
<span className='nav-label'>{companyText}</span>
</a>
</li>
<li id='sidebar-domains'>
......
......@@ -1628,3 +1628,8 @@ label {
.pointer {
cursor: pointer;
}
.format-text {
overflow: hidden;
text-overflow: ellipsis;
}
......@@ -40,15 +40,23 @@ body {
width: $menu-width;
}
#root {
height: inherit;
#wrapper {
background: $color-background;
border-left: 1px solid $border-color;
margin: 0 0 0 $menu-width;
min-height: 100%;
padding: 0;
position: relative;
transition: all .4s ease 0s;
> div {
height: inherit;
}
#wrapper {
background: $color-background;
border-left: 1px solid $border-color;
height: inherit;
margin: 0 0 0 $menu-width;
min-height: 100%;
padding: 0;
position: relative;
transition: all .4s ease 0s;
}
}
.content {
......
......@@ -10,6 +10,11 @@ class CompanyStoreClass {
this.companies = null;
}
resetThisStore() {
this.current = null;
this.companies = null;
}
getCompanies() {
const array = [];
const companies = this.companies;
......
......@@ -15,6 +15,13 @@ class DomainStoreClass extends EventEmitter {
this.zoneDNS = null;
}
resetThisStore() {
this.current = null;
this.distributionListOwners = null;
this.distributionListMembers = null;
this.zoneDNS = null;
}
getCurrent() {
return this.current;
}
......
......@@ -7,7 +7,7 @@ import Constants from '../utils/constants.jsx';
const eventTypes = Constants.EventTypes;
let mailboxesArray = null;
let mailboxexInstances = [];
let mailboxesInstances = [];
class MailboxStoreClass extends EventEmitter {
constructor() {
......@@ -16,6 +16,13 @@ class MailboxStoreClass extends EventEmitter {
this.currentPage = {};
}
resetThisStore() {
this.current = null;
this.currentPage = {};
mailboxesArray = null;
mailboxesInstances = [];
}
getMailboxById(id) {
if (mailboxesArray) {
const accounts = mailboxesArray.account;
......@@ -54,7 +61,6 @@ class MailboxStoreClass extends EventEmitter {
getMailboxByPage(page) {
if (page && this.currentPage[page]) {
console.log(this.currentPage); //eslint-disable-line no-console
return this.currentPage[page];
}
......@@ -87,21 +93,22 @@ class MailboxStoreClass extends EventEmitter {
setMailboxes(mailboxes, page) {
if (mailboxesArray) {
Array.prototype.push.apply(mailboxexInstances, mailboxes.account);
mailboxesArray.account = mailboxexInstances;
console.log('mailbox', mailboxes); //eslint-disable-line no-console
Array.prototype.push.apply(mailboxesInstances, mailboxes.account);
mailboxesArray.account = mailboxesInstances;
if (page) {
this.currentPage[page] = mailboxes;
console.log(this.currentPage[page]); //eslint-disable-line no-console
}
return true;
}
mailboxesArray = mailboxes;
mailboxexInstances = mailboxes.account;
const copy = Object.assign({}, mailboxes);
const accounts = mailboxes.account.slice();
mailboxesArray = copy;
mailboxesInstances = accounts;
if (page) {
this.currentPage[page] = mailboxes;
console.log(this.currentPage[page]); //eslint-disable-line no-console
}
return true;
}
......
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import CompanyStore from './company_store.jsx';
import DomainStore from './domain_store.jsx';
import MailboxStore from './mailbox_store.jsx';
import TabStateStore from './tab_state_store.jsx';
import UserStore from './user_store.jsx';
import ZimbraStore from './zimbra_store.jsx';
class ResetStoresClass {
constructor() {
this.zimbra = null;
this.cos = null;
}
resetAllStores() {
CompanyStore.resetThisStore();
DomainStore.resetThisStore();
MailboxStore.resetThisStore();
TabStateStore.resetThisStore();
UserStore.resetThisStore();
ZimbraStore.resetThisStore();
}
}
var ResetStores = new ResetStoresClass();
export {ResetStores as default};
......@@ -7,6 +7,11 @@ class TabStateStoreClass {
this.states = {};
}
resetThisStore() {
this.current = null;
this.states = {};
}
getCurrent() {
return this.current;
}
......
......@@ -14,6 +14,10 @@ class UserStoreClass extends EventEmitter {
this.currentUser = null;
}
resetThisStore() {
this.currentUser = null;
}
getCurrentUser() {
return this.currentUser;
}
......
......@@ -7,6 +7,11 @@ class ZimbraStoreClass {
this.cos = null;
}
resetThisStore() {
this.zimbra = null;
this.cos = null;
}
getCurrent() {
return this.zimbra;
}
......
......@@ -7,6 +7,7 @@ import Promise from 'bluebird';
import ZimbraAdminApi from 'zimbra-admin-api-js';
import Powerdns from 'js-powerdns';
import ZimbraStore from '../stores/zimbra_store.jsx';
import ResetStores from '../stores/reset_stores.jsx';
import * as GlobalActions from '../action_creators/global_actions.jsx';
import * as Utils from './utils.jsx';
......@@ -45,6 +46,7 @@ function initZimbra() {
let zimbra = ZimbraStore.getCurrent();
if (zimbra && token) {
window.manager_config.dns.token = token;
return resolve(zimbra);
} else if (token) {
zimbra = new ZimbraAdminApi({
......@@ -52,6 +54,7 @@ function initZimbra() {
});
zimbra.client.token = token;
ZimbraStore.setCurrent(zimbra);
window.manager_config.dns.token = token;
return resolve(zimbra);
}
......@@ -112,7 +115,6 @@ export function login(user, password, success, error) {
}
Utils.setCookie('token', zimbra.client.token);
window.manager_config.dns.token = Utils.getCookie('token');
return getMe(success, error);
});
}
......@@ -124,6 +126,7 @@ export function logout(callback) {
}
ZimbraStore.setCurrent(null);
GlobalActions.saveUser(null);
ResetStores.resetAllStores();
if (callback && typeof callback === 'function') {
callback();
......
......@@ -602,3 +602,13 @@ export function setInitialDate() {
return dateObject;
}
export function cloneObject(obj) {
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) {
copy[attr] = obj[attr];
}
}
return copy;
}
......@@ -90,6 +90,9 @@ var config = {
new webpack.LoaderOptionsPlugin({
minimize: !DEV,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false }
})
],
resolve: {
......
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