Commit 335a0fad authored by Juorder Gonzalez's avatar Juorder Gonzalez

Merge pull request #169 from ZBoxApp/issues_resolved_manager

fix search to filter domain alias, now we get only needed attrs by ap…
parents a5e09ca2 18a43af7
module.exports = {"main":{"js":"/749216bundle.js"}} module.exports = {"main":{"js":"/029325bundle.js"}}
\ No newline at end of file \ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import sweetAlert from 'sweetalert';
import DomainStore from '../../stores/domain_store.jsx'; import DomainStore from '../../stores/domain_store.jsx';
...@@ -12,7 +13,7 @@ import AddAdminModal from './add_admin_modal.jsx'; ...@@ -12,7 +13,7 @@ import AddAdminModal from './add_admin_modal.jsx';
import * as Utils from '../../utils/utils.jsx'; import * as Utils from '../../utils/utils.jsx';
import Constants from '../../utils/constants.jsx'; //import Constants from '../../utils/constants.jsx';
export default class DomainAdminList extends React.Component { export default class DomainAdminList extends React.Component {
constructor(props) { constructor(props) {
...@@ -23,12 +24,14 @@ export default class DomainAdminList extends React.Component { ...@@ -23,12 +24,14 @@ export default class DomainAdminList extends React.Component {
this.onAdminsChange = this.onAdminsChange.bind(this); this.onAdminsChange = this.onAdminsChange.bind(this);
this.state = this.getStateFromStores(); this.state = this.getStateFromStores();
} }
getStateFromStores() { getStateFromStores() {
const admins = DomainStore.getAdmins(this.props.domain); const admins = DomainStore.getAdmins(this.props.domain);
return { return {
admins admins
}; };
} }
getAdmins() { getAdmins() {
const domain = this.props.domain; const domain = this.props.domain;
domain.getAdmins((err, data) => { domain.getAdmins((err, data) => {
...@@ -37,27 +40,47 @@ export default class DomainAdminList extends React.Component { ...@@ -37,27 +40,47 @@ export default class DomainAdminList extends React.Component {
this.setState({admins}); this.setState({admins});
}); });
} }
handleRemoveAdmin(e, admin) { handleRemoveAdmin(e, admin) {
e.preventDefault(); e.preventDefault();
if (confirm(`¿Seguro quieres eliminar a ${admin.name} como administrador del dominio?`)) { //eslint-disable-line no-alert const response = {
// previo a esto hay que remover el usuario como admin del dominio title: 'Se ha borrado con éxito',
type: 'success'
};
sweetAlert({
title: 'Borrar Administrador de Dominio',
text: `¿Seguro quieres eliminar a ${admin.name} como administrador del dominio?`,
type: 'info',
showCancelButton: true,
confirmButtonColor: '#DD6B55',
confirmButtonText: 'Si, deseo borrarlo!',
closeOnConfirm: false,
showLoaderOnConfirm: true
},
(isDeleted) => {
if (isDeleted) {
this.props.domain.removeAdmin( this.props.domain.removeAdmin(
admin.name, admin.name,
(error) => { (error) => {
if (error) { if (error) {
return this.setState({ response.title = 'Ha ocurrido un error.';
error: { response.type = 'error';
message: error.extra.reason, response.confirmButtonText = 'Intentar de nuevo';
type: Constants.MessageType.ERROR response.confirmButtonColor = '#DD6B55';
}
}); return sweetAlert(response);
} }
return DomainStore.removeAdmin(admin.id); DomainStore.removeAdmin(admin.id);
return sweetAlert(response);
} }
); );
} }
} }
);
}
onAdminsChange() { onAdminsChange() {
const admins = DomainStore.getAdmins(this.props.domain); const admins = DomainStore.getAdmins(this.props.domain);
if (!admins) { if (!admins) {
...@@ -66,6 +89,7 @@ export default class DomainAdminList extends React.Component { ...@@ -66,6 +89,7 @@ export default class DomainAdminList extends React.Component {
return this.setState({admins}); return this.setState({admins});
} }
componentDidMount() { componentDidMount() {
DomainStore.addAdminsChangeListener(this.onAdminsChange); DomainStore.addAdminsChangeListener(this.onAdminsChange);
......
...@@ -46,26 +46,25 @@ export default class DomainDetails extends React.Component { ...@@ -46,26 +46,25 @@ export default class DomainDetails extends React.Component {
getDomain() { getDomain() {
const domain = DomainStore.getCurrent(); const domain = DomainStore.getCurrent();
const states = {};
if (domain && domain.id === this.props.params.id) { if (domain && domain.id === this.props.params.id) {
states.domain = domain;
GlobalActions.emitEndLoading(); GlobalActions.emitEndLoading();
this.setState({
domain this.setState(states);
});
Client.getZone(domain.name, (zone) => { Client.getZone(domain.name, (zone) => {
DomainStore.setZoneDNS(zone); DomainStore.setZoneDNS(zone);
this.setState({ this.setState(states);
domain
});
GlobalActions.emitEndLoading(); GlobalActions.emitEndLoading();
}, () => { }, () => {
DomainStore.setZoneDNS(null); DomainStore.setZoneDNS(null);
this.setState({ this.setState(states);
domain
});
GlobalActions.emitEndLoading(); GlobalActions.emitEndLoading();
}); });
...@@ -74,19 +73,16 @@ export default class DomainDetails extends React.Component { ...@@ -74,19 +73,16 @@ export default class DomainDetails extends React.Component {
this.props.params.id, this.props.params.id,
(data) => { (data) => {
DomainStore.setCurrent(data); DomainStore.setCurrent(data);
states.domain = data;
Client.getZone(data.name, (zone) => { Client.getZone(data.name, (zone) => {
DomainStore.setZoneDNS(zone); DomainStore.setZoneDNS(zone);
this.setState({ this.setState(states);
domain: data
});
GlobalActions.emitEndLoading(); GlobalActions.emitEndLoading();
}, () => { }, () => {
this.setState({ this.setState(states);
domain: data
});
GlobalActions.emitEndLoading(); GlobalActions.emitEndLoading();
}); });
...@@ -101,6 +97,15 @@ export default class DomainDetails extends React.Component { ...@@ -101,6 +97,15 @@ export default class DomainDetails extends React.Component {
} }
} }
componentWillReceiveProps(nextProps) {
const condition = nextProps.params.id !== this.props.params.id;
if (condition) {
this.props.params.id = nextProps.params.id;
this.getDomain();
}
}
componentDidMount() { componentDidMount() {
EventStore.addMessageListener(this.showMessage); EventStore.addMessageListener(this.showMessage);
$('#sidebar-domains').addClass('active'); $('#sidebar-domains').addClass('active');
...@@ -114,9 +119,19 @@ export default class DomainDetails extends React.Component { ...@@ -114,9 +119,19 @@ export default class DomainDetails extends React.Component {
render() { render() {
const domain = this.state.domain; const domain = this.state.domain;
let message = null;
let classForCol = 'col-xs-6';
let isVisible = 'show';
let hasLayout = 'layout-back';
let tabNames = [];
let tabs = {};
if (domain) { if (domain) {
let message; if (domain.isAliasDomain) {
classForCol = 'col-xs-12';
isVisible = 'hide';
}
if (this.state.error) { if (this.state.error) {
message = ( message = (
<MessageBar <MessageBar
...@@ -176,16 +191,27 @@ export default class DomainDetails extends React.Component { ...@@ -176,16 +191,27 @@ export default class DomainDetails extends React.Component {
/> />
); );
const panelTabs = ( tabNames = ['Administradores', 'AntiSpam', 'Listas De Distribución', 'Tareas Masivas', 'Zona DNS'];
<PanelTab tabs = {
tabNames={['Administradores', 'AntiSpam', 'Listas De Distribución', 'Tareas Masivas', 'Zona DNS']}
tabs={{
administradores: tabAdmin, administradores: tabAdmin,
antispam: tabAntiSpam, antispam: tabAntiSpam,
listas_de_distribución: tabDistribution, listas_de_distribución: tabDistribution,
tareas_masivas: tabTareasMasivas, tareas_masivas: tabTareasMasivas,
zona_dns: zonaDNS zona_dns: zonaDNS
}} };
if (domain.isAliasDomain) {
tabNames = ['Zona DNS'];
tabs = {
zona_dns: zonaDNS
};
hasLayout = '';
}
const panelTabs = (
<PanelTab
tabNames={tabNames}
tabs={tabs}
location={this.props.location} location={this.props.location}
/> />
); );
...@@ -200,27 +226,29 @@ export default class DomainDetails extends React.Component { ...@@ -200,27 +226,29 @@ export default class DomainDetails extends React.Component {
<div className='content animate-panel'> <div className='content animate-panel'>
{message} {message}
<div className='row'> <div className='row'>
<div className='layout-back clearfix'> <div className={`${hasLayout} clearfix`}>
<div className='back-left backstage'> <div className={`back-left backstage ${isVisible}`}>
<div className='backbg'></div> <div className='backbg'></div>
</div> </div>
<div className='back-right backstage'> <div className={`back-right backstage ${isVisible}`}>
<div className='backbg'></div> <div className='backbg'></div>
</div> </div>
<div className='col-md-6 central-content'> <div className={`${classForCol} central-content`}>
<DomainGeneralInfo <DomainGeneralInfo
domain={domain} domain={domain}
location={this.props.location} location={this.props.location}
params={this.props.params} params={this.props.params}
/> />
</div> </div>
<div className='col-md-6 central-content'> {!domain.isAliasDomain && (
<div className={`${classForCol} central-content`}>
<DomainMailboxPlans <DomainMailboxPlans
domain={domain} domain={domain}
location={this.props.location} location={this.props.location}
params={this.props.params} params={this.props.params}
/> />
</div> </div>
)}
</div> </div>
</div> </div>
<div className='row'> <div className='row'>
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import sweetAlert from 'sweetalert';
import DomainStore from '../../stores/domain_store.jsx'; import DomainStore from '../../stores/domain_store.jsx';
...@@ -47,19 +48,43 @@ export default class DomainDistributionList extends React.Component { ...@@ -47,19 +48,43 @@ export default class DomainDistributionList extends React.Component {
} }
handleRemoveAdmin(e, list) { handleRemoveAdmin(e, list) {
e.preventDefault(); e.preventDefault();
const response = {
title: 'Se ha borrado con éxito',
type: 'success'
};
if (confirm(`¿Seguro quieres eliminar la lista de distribución ${list.name} del dominio?`)) { //eslint-disable-line no-alert sweetAlert({
title: 'Borrar Lista de Distribución',
text: `¿Seguro quieres eliminar la lista de distribución ${list.name} del dominio?`,
type: 'info',
showCancelButton: true,
confirmButtonColor: '#DD6B55',
confirmButtonText: 'Si, deseo borrarlo!',
closeOnConfirm: false,
showLoaderOnConfirm: true
},
(isDeleted) => {
if (isDeleted) {
Client.removeDistributionList( Client.removeDistributionList(
list.id, list.id,
() => { () => {
DomainStore.removeDistributionList(list.id); DomainStore.removeDistributionList(list.id);
return sweetAlert(response);
}, },
(error) => { (error) => {
this.setState({error}); response.title = 'Ha ocurrido un error.';
response.text = `${error.message}`;
response.type = 'error';
response.confirmButtonText = 'Intentar de nuevo';
response.confirmButtonColor = '#DD6B55';
return sweetAlert(response);
} }
); );
} }
} }
);
}
componentDidMount() { componentDidMount() {
DomainStore.addDistributionListsChangeListener(this.onListsChange); DomainStore.addDistributionListsChangeListener(this.onListsChange);
......
...@@ -83,6 +83,12 @@ export default class DomainGeneralInfo extends React.Component { ...@@ -83,6 +83,12 @@ export default class DomainGeneralInfo extends React.Component {
render() { render() {
const domain = this.props.domain; const domain = this.props.domain;
let editDomainButton = null; let editDomainButton = null;
let masterID = null;
if (domain.attrs.zimbraDomainAliasTargetId) {
masterID = domain.attrs.zimbraDomainAliasTargetId;
}
const infoBody = ( const infoBody = (
<div className='row'> <div className='row'>
<div className='col-md-12'> <div className='col-md-12'>
...@@ -108,14 +114,31 @@ export default class DomainGeneralInfo extends React.Component { ...@@ -108,14 +114,31 @@ export default class DomainGeneralInfo extends React.Component {
<strong>{'MX Record: '}</strong> <strong>{'MX Record: '}</strong>
{this.state.mx} {this.state.mx}
</li> </li>
{domain.isAliasDomain && domain.masterDomainName && (
<li> <li>
<strong>{'Próxima renovación: '}</strong> <strong>{'Dominio Maestro: '}</strong>
{this.state.date} <a
className='account-name'
onClick={(e) => Utils.handleLink(e, `/domains/${masterID}`, this.props.location)}
>
{domain.masterDomainName}
</a>
</li> </li>
)}
<li> <li>
<strong>{'Próxima renovación: '}</strong>
{this.state.date}
</li> </li>
</ul> </ul>
<ul className='list-inline list-unstyled'> <ul className='list-inline list-unstyled'>
{domain.isAliasDomain && (
<li>
<StatusLabel
classes='btn btn-md btn-warning'
children='Dominio Alias'
/>
</li>
)}
<li> <li>
<StatusLabel <StatusLabel
classes='btn btn-md btn-info' classes='btn btn-md btn-info'
...@@ -128,7 +151,17 @@ export default class DomainGeneralInfo extends React.Component { ...@@ -128,7 +151,17 @@ export default class DomainGeneralInfo extends React.Component {
</div> </div>
); );
if (this.isGlobalAdmin) { if (domain.isAliasDomain && domain.attrs.zimbraDomainAliasTargetId) {
editDomainButton = [{
label: 'Ir a Dominio Maestro',
props: {
className: 'btn btn-info btn-xs',
onClick: (e) => Utils.handleLink(e, `/domains/${masterID}/`, this.props.location)
}
}];
}
if (this.isGlobalAdmin && !domain.isAliasDomain) {
editDomainButton = [{ editDomainButton = [{
label: 'Editar', label: 'Editar',
props: { props: {
......
...@@ -100,12 +100,12 @@ export default class CreateMailBox extends React.Component { ...@@ -100,12 +100,12 @@ export default class CreateMailBox extends React.Component {
MailboxStore.setMailbox(data); MailboxStore.setMailbox(data);
//return Utils.handleLink(event, `/mailboxes/${data.id}`, this.props.location); return Utils.handleLink(event, `/mailboxes/${data.id}`, this.props.location);
GlobalActions.emitMessage({ /*GlobalActions.emitMessage({
message: 'Se ha creado su cuenta con éxito.', message: 'Se ha creado su cuenta con éxito.',
typeError: messageType.SUCCESS typeError: messageType.SUCCESS
}); });*/
}, },
(error) => { (error) => {
GlobalActions.emitMessage({ GlobalActions.emitMessage({
......
...@@ -190,9 +190,9 @@ export default class Mailboxes extends React.Component { ...@@ -190,9 +190,9 @@ export default class Mailboxes extends React.Component {
getAccounts(domainName, maxResult) { getAccounts(domainName, maxResult) {
//const promises = []; //const promises = [];
const attrs = { const attrs = {
maxResults: maxResult maxResults: maxResult,
limit: 5000
}; };
const attrneeded = Utils.getAttrsBySectionFromConfig('mailboxes'); const attrneeded = Utils.getAttrsBySectionFromConfig('mailboxes');
......
...@@ -61,6 +61,7 @@ export default class SearchView extends React.Component { ...@@ -61,6 +61,7 @@ export default class SearchView extends React.Component {
} }
makeSearch(query) { makeSearch(query) {
const attrsNeeded = Utils.getAttrsBySectionFromConfig('search');
let advanceQuery = false; let advanceQuery = false;
try { try {
advanceQuery = JSON.parse(query).advance_query; advanceQuery = JSON.parse(query).advance_query;
...@@ -74,7 +75,7 @@ export default class SearchView extends React.Component { ...@@ -74,7 +75,7 @@ export default class SearchView extends React.Component {
maxResults: window.manager_config.maxResultOnRequestZimbra, maxResults: window.manager_config.maxResultOnRequestZimbra,
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}*))`, 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', types: 'accounts,distributionlists,domains',
attrs: 'objectClass' attrs: attrsNeeded
}; };
this.runSearch(queryObject); this.runSearch(queryObject);
} }
...@@ -101,17 +102,19 @@ export default class SearchView extends React.Component { ...@@ -101,17 +102,19 @@ export default class SearchView extends React.Component {
const id = item.id; const id = item.id;
switch (type) { switch (type) {
case 'domain': case 'domain': {
const label = item.isAliasDomain ? 'Dominio Alias' : 'Dominio';
tipo = ( tipo = (
<div> <div>
<i className='fa fa-globe fa-lg'></i> <i className='fa fa-globe fa-lg'></i>
<span className='margin-left'>{'Dominio'}</span> <span className='margin-left'>{label}</span>
</div> </div>
); );
url = `/domains/${id}`; url = `/domains/${id}`;
objectDomain[item.name] = id; objectDomain[item.name] = id;
break; break;
}
case 'account': case 'account':
tipo = ( tipo = (
<div> <div>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
"url": "http://zimbra.zboxapp.dev:9081/powerdns_proxy", "url": "http://zimbra.zboxapp.dev:9081/powerdns_proxy",
"token": "otto" "token": "otto"
}, },
"maxResultOnRequestZimbra": 20000, "maxResultOnRequestZimbra": 3000,
"autoincrementOnFailRequestZimbra": 500, "autoincrementOnFailRequestZimbra": 500,
"plans": { "plans": {
"basic": { "basic": {
...@@ -72,7 +72,18 @@ ...@@ -72,7 +72,18 @@
"domains": { "domains": {
"attrs": { "attrs": {
"zimbraDomainStatus": true, "zimbraDomainStatus": true,
"description": true "description": true,
"businessCategory": true,
"zimbraCreateTimestamp": true,
"zimbraDomainType": true,
"zimbraMailCatchAllForwardingAddress": true
}
},
"search": {
"attrs": {
"zimbraDomainType": true,
"zimbraMailCatchAllForwardingAddress": true,
"objectClass": true
} }
} }
}, },
......
// Load Awesome v1.1.0 (http://github.danielcardoso.net/load-awesome/)
//Copyright 2015 Daniel Cardoso <@DanielCardoso>
//Licensed under MIT
.la-ball-fall {
box-sizing: border-box;
color: $white;
display: block;
font-size: 0;
height: 18px;
position: relative;
width: 54px;
&.la-dark {
color: $la-dark-color;
}
> div {
animation: ball-fall 1s ease-in-out infinite;
background-color: currentColor;
border: 0 solid currentColor;
border-radius: 100%;
box-sizing: border-box;
display: inline-block;
float: none;
height: 10px;
margin: 4px;
opacity: 0;
position: relative;
width: 10px;
&:nth-child(1) {
animation-delay: -200ms;
}
&:nth-child(2) {
animation-delay: -100ms;
}
&:nth-child(3) {
animation-delay: 0ms;
}
}
&.la-sm {
height: 8px;
width: 26px;
> div {
height: 4px;
margin: 2px;
width: 4px;
}
}
&.la-2x {
height: 36px;
width: 108px;
> div {
height: 20px;
margin: 8px;
width: 20px;
}
}
&.la-3x {
height: 54px;
width: 162px;
> div {
height: 30px;
margin: 12px;
width: 30px;
}
}
}
// Animation
@keyframes ball-fall {
0% {
opacity: 0;
transform: translateY(-145%);
}
10% {
opacity: .5;
}
20% {
opacity: 1;
transform: translateY(0);
}
80% {
opacity: 1;
transform: translateY(0);
}
90% {
opacity: .5;
}
100% {
opacity: 0;
transform: translateY(145%);
}
}
...@@ -696,3 +696,5 @@ body { ...@@ -696,3 +696,5 @@ body {
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
@import 'loader_animation';
...@@ -121,3 +121,4 @@ $sweet-blue: #c9dae1; ...@@ -121,3 +121,4 @@ $sweet-blue: #c9dae1;
$sweet-green: #a5dc86; $sweet-green: #a5dc86;
$keyframe-bg-color: #f8d486; $keyframe-bg-color: #f8d486;
$keyframe-bg-color2: #f8bb86; $keyframe-bg-color2: #f8bb86;
$la-dark-color: #333;
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