Commit 18a43af7 authored by Juorder Antonio's avatar Juorder Antonio

fix search to filter domain alias, now we get only needed attrs by api in...

fix search to filter domain alias, now we get only needed attrs by api in mailbox, domain, search, fix issues from github issues
parent a5e09ca2
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