Commit e175ee70 authored by Patricio Bruna's avatar Patricio Bruna

Merge pull request #44 from ZBoxApp/multiple_changes_from_trello

finish trello tasks, add multi form to create domain, add zone dns ta…

Wow.. eso fue grande.. vamos a tener que hacer pull más cortos.
parents fe727adf d68765d9
......@@ -101,7 +101,6 @@ http {
}
}
# HTTPS server
#
#server {
......
......@@ -70,9 +70,8 @@ export default class AddAdminModal extends React.Component {
e.preventDefault();
this.props.domain.addAdmin(
user.name,
(error, success) => {
console.log(error, success);
user.id,
(error) => {
if (error) {
return this.setState({
error: {
......
......@@ -7,6 +7,10 @@ import * as Client from '../../utils/client.jsx';
import * as Utils from '../../utils/utils.jsx';
import Promise from 'bluebird';
import DomainStore from '../../stores/domain_store.jsx';
import EventStore from '../../stores/event_store.jsx';
import Constants from '../../utils/constants.jsx';
const MessageType = Constants.MessageType;
export default class AntiSpam extends React.Component {
constructor(props) {
......@@ -15,13 +19,18 @@ export default class AntiSpam extends React.Component {
this.handleDelete = this.handleDelete.bind(this);
this.handleSave = this.handleSave.bind(this);
this.alterDomain = this.alterDomain.bind(this);
this.domain = DomainStore.getCurrent();
console.log(this.domain);
this.blackList = null;
this.whiteList = null;
if (this.domain.attrs.amavisBlacklistSender) {
this.blackList = Array.isArray(this.domain.attrs.amavisBlacklistSender) ? this.domain.attrs.amavisBlacklistSender : this.domain.attrs.amavisBlacklistSender.trim().split(' ');
}
if (this.domain.attrs.amavisWhitelistSender) {
this.whiteList = Array.isArray(this.domain.attrs.amavisWhitelistSender) ? this.domain.attrs.amavisWhitelistSender : this.domain.attrs.amavisWhitelistSender.trim().split(' ');
}
}
handleDelete(e, item, action) {
e.preventDefault();
......@@ -56,20 +65,27 @@ export default class AntiSpam extends React.Component {
const attrs = {};
const isEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const isDomain = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/;
const target = action === 'black' ? 'lista negra' : 'lista blanca';
e.preventDefault();
const input = this.refs[`${action}-item`];
const value = input.value.trim();
if (!value || value === '') {
console.log('no hay valores');
EventStore.emitMessage({
message: `No puede agregar una ${target} vacia.`,
typeError: MessageType.ERROR
});
return false;
}
const isValid = isEmail.test(value) || isDomain.test(value);
if (!isValid) {
console.log('es invalido');
EventStore.emitMessage({
message: `Solo es posible agregar dominios o email en ${target}`,
typeError: MessageType.ERROR
});
return false;
}
......@@ -84,7 +100,7 @@ export default class AntiSpam extends React.Component {
break;
}
this.alterDomain(attrs, e.target, input);
return this.alterDomain(attrs, e.target, input);
}
alterDomain(attrs, button, input) {
......@@ -99,7 +115,6 @@ export default class AntiSpam extends React.Component {
id = `#${button.getAttribute('id')}`;
}
new Promise((resolve, reject) => {
if (hasButton) {
Utils.toggleStatusButtons(id, true);
......@@ -117,7 +132,10 @@ export default class AntiSpam extends React.Component {
update: true
});
}).catch((err) => {
console.log(err);
EventStore.emitMessage({
message: err.message || err.reason,
typeError: MessageType.ERROR
});
}).finally(() => {
if (hasButton) {
Utils.toggleStatusButtons(id, false);
......@@ -134,7 +152,7 @@ export default class AntiSpam extends React.Component {
let whiteList = null;
let blackList = null;
if (this.blackList.length > 0) {
if (this.blackList && this.blackList.length > 0) {
blackList = this.blackList.map((black, i) => {
return (
<tr
......@@ -169,7 +187,7 @@ export default class AntiSpam extends React.Component {
);
}
if (this.whiteList.length > 0) {
if (this.whiteList && this.whiteList.length > 0) {
whiteList = this.whiteList.map((white, i) => {
return (
<tr
......
//import * as Utils from '../../utils/utils.jsx';
import React from 'react';
import {browserHistory} from 'react-router';
import MessageBar from '../message_bar.jsx';
import Panel from '../panel.jsx';
import CompanyStore from '../../stores/company_store.jsx';
import CreateDomainForm from './multiform/create_domain_form.jsx';
import MailCleanerForm from './multiform/mailcleaner_form.jsx';
import DNSZoneForm from './multiform/dns_form.jsx';
import DomainStore from '../../stores/domain_store.jsx';
import ZimbraStore from '../../stores/zimbra_store.jsx';
import * as Client from '../../utils/client.jsx';
import * as Utils from '../../utils/utils.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import Constants from '../../utils/constants.jsx';
import EventStore from '../../stores/event_store.jsx';
import MessageBar from '../message_bar.jsx';
export default class CreateDomain extends React.Component {
constructor(props) {
super(props);
this.planSize = this.planSize.bind(this);
this.getCompanies = this.getCompanies.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.getNextStep = this.getNextStep.bind(this);
this.showMessage = this.showMessage.bind(this);
this.state = {};
}
planSize(e) {
e.preventDefault();
let total = 0;
const plans = Object.keys(this.state.plans);
this.multiform = window.manager_config.multiFormDomain;
let total = 1;
plans.forEach((p) => {
total += parseInt(this.refs[`plan-${p}`].value, 10) || 0;
});
this.refs.mailboxLimit.value = total;
if (this.multiform) {
if (this.multiform.hasMailCleaner) {
total++;
}
getCompanies() {
const companyId = this.props.params.id;
const companies = CompanyStore.getCompanies();
if (companies) {
this.setState({
plans: Utils.getEnabledPlansByCos(ZimbraStore.getAllCos()),
companies,
companyId
});
return GlobalActions.emitEndLoading();
if (this.multiform.hasDNSZone) {
total++;
}
return Client.getAllCompanies().
then((data) => {
this.setState({
plans: Utils.getEnabledPlansByCos(ZimbraStore.getAllCos()),
companies: data,
companyId
});
}).
catch((error) => {
error.type = Constants.MessageType.ERROR;
this.setState({error});
}).
finally(() => {
GlobalActions.emitEndLoading();
});
}
handleSubmit(e) {
e.preventDefault();
GlobalActions.emitStartLoading();
this.state = {
step: 1,
total
};
}
const elementList = document.querySelectorAll('.has-error');
Array.from(elementList).forEach((el) => el.classList.remove('has-error'));
getNextStep(attrs) {
const states = {};
Utils.validateInputRequired(this.refs).
then(() => {
const plans = Object.keys(this.state.plans);
const zimbraDomainCOSMaxAccounts = [];
const name = this.refs.domainName.value.trim();
const businessCategory = this.refs.company.value.trim();
if (attrs.domain) {
states.domain = attrs.domain;
}
plans.forEach((p) => {
zimbraDomainCOSMaxAccounts.push(`${this.refs[`plan-${p}`].getAttribute('data-id')}:${this.refs[`plan-${p}`].value || 0}`);
});
states.step = attrs.step;
const domain = {
name,
attrs: {
zimbraDomainCOSMaxAccounts,
businessCategory
this.setState(states);
}
};
Client.createDomain(
domain,
(data) => {
CompanyStore.addDomain(businessCategory, data);
DomainStore.setCurrent(data);
browserHistory.push(`/domains/${data.id}`);
},
(error) => {
GlobalActions.emitEndLoading();
return this.setState({error});
}
);
}).
catch((error) => {
GlobalActions.emitEndLoading();
error.refs = true;
error.type = error.typeError;
error.node.closest('.form-group').classList.add('has-error');
return this.setState({error});
showMessage(attrs) {
this.setState({
error: attrs.message,
type: attrs.typeError
});
}
componentDidMount() {
this.getCompanies();
DomainStore.addNextStepListener(this.getNextStep);
EventStore.addMessageListener(this.showMessage);
}
render() {
const companies = this.state.companies;
const error = this.state.error;
if (companies || error) {
let backUrl = '/domains';
if (this.state.companyId) {
backUrl = `/companies/${this.state.companyId}`;
componentWillUnmount() {
DomainStore.removeNextStepListener(this.getNextStep);
EventStore.removeMessageListener(this.showMessage);
}
let errorBar;
if (error) {
errorBar = (
render() {
let form = null;
let titleForm = null;
const progress = `${this.state.step}/${this.state.total}`;
let progressForm = null;
const width = ((100 / this.state.total) * this.state.step);
const progressSize = {
width: `${width}%`
};
let error = null;
if (this.state.error) {
error = (
<MessageBar
message={error.message}
type={error.type}
message={this.state.error}
type={this.state.type}
autoclose={true}
/>
);
}
const companiesOptions = companies.map((c) => {
return (
<option
key={`company-${c.id}`}
value={c.id}
>
{c.name}
</option>
);
});
const statePlans = this.state.plans;
const enabledPlans = Object.keys(statePlans);
const plans = enabledPlans.map((p) => {
return (
<div
key={`plan-${statePlans[p]}`}
className='col-md-4 form-group required'
>
<label
htmlFor={`plan-${p}`}
clasName='label-top control-label'
>
<abbr title='Requerido'>{'*'}</abbr><br/>
{Utils.titleCase(p)}
</label>
<br/>
<div className='row'>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
defaultValue='0'
data-required='true'
data-message={`Debe asignar la cantidad de casillas del tipo ${Utils.titleCase(p)}`}
data-id={statePlans[p]}
ref={`plan-${p}`}
onKeyUp={this.planSize}
/>
</div>
</div>
</div>
);
});
const form = (
<form
className='simple_form form-horizontal mailbox-form'
onSubmit={this.handleSubmit}
>
<div className='form-group string required'>
<label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr>
{'Nombre'}
</label>
<div className='col-sm-8'>
<input
type='text'
data-required='true'
data-message='El nombre del dominio es obligatorio'
className='form-control'
ref='domainName'
placeholder='example.com'
/>
</div>
</div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr>
{'Empresa'}
</label>
<div className='col-sm-8'>
<select
className='form-control select required'
data-required='true'
data-message='Debe especificar a que empresa corresponde el dominio'
ref='company'
defaultValue={this.state.companyId}
>
{companiesOptions}
</select>
</div>
</div>
<div className='form-group row'>
<div className='col-md-8 col-md-offset-3'>
<div className='box-content'>
{plans}
</div>
</div>
</div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
{'Límite de casillas'}
</label>
let step = this.state.step;
<div className='col-sm-8'>
<input
type='text'
className='form-control'
ref='mailboxLimit'
value='0'
disabled='disabled'
/>
</div>
</div>
if (!this.multiform.hasMailCleaner && step > 1) {
++step;
}
<div className='form-group'>
<div className='col-sm-8 col-sm-offset-3'>
<input
type='submit'
name='commit'
value='Guardar'
className='btn btn-info'
switch (step) {
case 1:
form = (
<CreateDomainForm
params={this.props.params}
state={this.state}
/>
<a
href='#'
className='btn btn-default'
onClick={(e) => Utils.handleLink(e, backUrl)}
>
{'Cancelar'}
</a>
</div>
</div>
</form>
);
titleForm = 'Creación de Dominio';
break;
case 2:
form = <MailCleanerForm state={this.state}/>;
titleForm = 'Asignación del Dominio al MailCleaner';
break;
case 3:
form = <DNSZoneForm state={this.state}/>;
titleForm = 'Asignación de la Zona DNS';
break;
}
//onClick: (e) => Utils.handleLink(e, backUrl)
const actions = [
{
label: 'Cancelar',
props: {
className: 'btn btn-default btn-xs',
onClick: (e) => Utils.handleLink(e, backUrl)
className: 'btn btn-default btn-xs'
}
}
];
if (this.state.total > 1) {
progressForm = (
<div className='progress'>
<div
className={'progress-bar progress-bar-info progress-bar-striped active text-center step'}
style={progressSize}
>
<span className='progress-text'>{`${titleForm} - ${progress}`}</span>
</div>
</div>
);
}
return (
<Panel
title={'Agregar Dominio'}
btnsHeader={actions}
error={errorBar}
classHeader={'forum-box'}
btnsHeader={actions}
>
{error}
{progressForm}
{form}
</Panel>
);
}
return <div/>;
}
}
CreateDomain.propTypes = {
params: React.PropTypes.object.isRequired
};
import React from 'react';
import * as Utils from '../../utils/utils.jsx';
import Constants from '../../utils/constants.jsx';
import EventStore from '../../stores/event_store.jsx';
import DomainStore from '../../stores/domain_store.jsx';
const Labels = Constants.Labels;
const MessageType = Constants.MessageType;
export default class DNSZoneForm extends React.Component {
constructor(props) {
super(props);
this.addDNSRow = this.addDNSRow.bind(this);
this.removeRow = this.removeRow.bind(this);
this.handleChangeInput = this.handleChangeInput.bind(this);
this.addDNSRequest = this.addDNSRequest.bind(this);
this.zoneDNSChange = this.zoneDNSChange.bind(this);
this.zoneDNS = DomainStore.getZoneDNS();
this.instanceRow = {
name: '',
type: Constants.typesOfDNS[0],
content: '',
priority: 10,
ttl: 86400,
disabled: false
};
this.defaultRows = this.getRecords();
this.types = Constants.typesOfDNS;
this.state = {
fields: this.defaultRows
};
}
getRecords() {
const records = [];
const zoneRecords = this.zoneDNS;
if (zoneRecords) {
zoneRecords.records.forEach((zone) => {
const newObject = {};
Object.assign(newObject, this.instanceRow, zone);
records.push(newObject);
});
}
return records;
}
addDNSRequest() {
const records = this.defaultRows;
const zoneDNS = this.zoneDNS;
Utils.toggleStatusButtons('.savedns', true);
const button = this.refs.savedns;
const oldContent = button.innerHTML;
button.innerHTML = '<i class=\'fa fa-spinner fa-spin\'></i> Creando Zona DNS';
if (zoneDNS) {
zoneDNS.createOrModifyRecords(records, (err, data) => {
if (err) {
Utils.toggleStatusButtons('.savedns', false);
button.innerHTML = oldContent;
return EventStore.emitMessage({
message: err.reason,
typeError: MessageType.ERROR
});
}
DomainStore.setZoneDNS(data);
Utils.toggleStatusButtons('.savedns', false);
button.innerHTML = oldContent;
return EventStore.emitMessage({
message: 'Se ha registrado su nuevo DNS éxitoxamente.',
typeError: MessageType.SUCCESS
});
});
} else {
EventStore.emitMessage({
message: 'Ha ocurrido un error general al intentar agregar un registro DNS',
typeError: MessageType.ERROR
});
}
}
addDNSRow() {
const copy = Object.assign({}, this.instanceRow);
copy.enabled = true;
this.defaultRows.push(copy);
this.setState({
fields: this.defaultRows
});
}
removeRow(e, index) {
e.preventDefault();
const zoneDNS = this.zoneDNS;
const button = e.target;
const old = button.innerHTML;
button.innerHTML = '<i class=\'fa fa-spinner fa-spin\'></i>';
button.setAttribute('disabled', 'disabled');
if (this.defaultRows[index]) {
if (zoneDNS && zoneDNS.records[index]) {
return zoneDNS.deleteRecords(this.defaultRows[index], (error, success) => {
if (error) {
button.removeAttribute('disabled');
button.innerHTML = old;
return EventStore.emitMessage({
message: error.message,
typeError: MessageType.ERROR
});
}
const name = this.defaultRows[index].name;
DomainStore.setZoneDNS(success);
return EventStore.emitMessage({
message: `Se ha borrado su DNS ${name} éxitoxamente.`,
typeError: MessageType.ERROR
});
});
}
this.defaultRows.splice(index, 1);
this.setState({
fields: this.defaultRows
});
}
return false;
}
handleChangeInput(e, index, ref) {
const value = e.target.value;
if (this.defaultRows[index]) {
this.defaultRows[index][ref] = value;
return true;
}
return false;
}
zoneDNSChange() {
this.zoneDNS = DomainStore.getZoneDNS();
this.defaultRows = this.getRecords();
this.setState({
fields: this.defaultRows
});
}
componentDidMount() {
DomainStore.addZoneDNSChangeListener(this.zoneDNSChange);
}
componentWillUnmount() {
DomainStore.addZoneDNSChangeListener(this.zoneDNSChange);
}
render() {
let isVisible = false;
let fields = null;
let header = null;
const types = this.types.map((item) => {
return (
<option
key={item}
value={item}
>
{item}
</option>
);
});
fields = (
<div className='text-center'>
<h4>No existen Zonas DNS para su dominio : <strong>{this.props.domain.name}</strong></h4>
</div>
);
if (this.defaultRows.length > 0) {
isVisible = true;
header = (
<div className='row'>
<div className='col-xs-3'>
<strong>Nombre</strong>
</div>
<div className='col-xs-1'>
<strong>Tipo</strong>
</div>
<div className='col-xs-3'>
<strong>Contenido</strong>
</div>
<div className='col-xs-2'>
<strong>Prioridad</strong>
</div>
<div className='col-xs-2'>
<strong>TTL</strong>
</div>
<div className='col-xs-1'>
<strong>Acciones</strong>
</div>
</div>
);
fields = this.defaultRows.map((element, i) => {
const isDisabled = element.enabled ? null : true;
return (
<div
className='row set-margin-up'
key={`row-${new Date().getTime()}-${i}`}
id={`row-dns-${new Date().getTime()}-${i}`}
>
<div className='col-xs-3'>
<input
type='text'
defaultValue={element.name}
className='form-control'
onChange={(e) => {
this.handleChangeInput(e, i, Labels.name);
}}
disabled={isDisabled}
/>
</div>
<div className='col-xs-1'>
<select
className='form-control'
defaultValue={element.type}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.type);
}}
disabled={isDisabled}
>
{types}
</select>
</div>
<div className='col-xs-3'>
<input
type='text'
className='form-control'
defaultValue={element.content}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.content);
}}
/>
</div>
<div className='col-xs-2'>
<input
type='number'
className='form-control'
defaultValue={element.priority}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.priority);
}}
/>
</div>
<div className='col-xs-2'>
<input
type='number'
className='form-control'
defaultValue={element.ttl}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.ttl);
}}
/>
</div>
<div className='col-xs-1'>
<button
className='btn btn-danger'
onClick={(e) => {
this.removeRow(e, i);
}}
>
<i
className='fa fa-trash-o'
title='Delete'
>
</i>
</button>
</div>
</div>
);
});
}
return (
<div>
<blockquote className='clearfix'>
<p>
<button
className='btn btn-info pull-right'
onClick={this.addDNSRow}
>
<i className='fa fa-plus-circle fa-lg'></i> Agregar otro registro
</button>
</p>
</blockquote>
<form>
{header}
{fields}
<br/>
<br/>
<div className='col-xs-12 text-right'>
{(isVisible &&
<button
type='button'
className='btn btn-info savedns'
onClick={this.addDNSRequest}
ref='savedns'
>
{'Guardar'}
</button>
)}
</div>
</form>
</div>
);
}
}
DNSZoneForm.propTypes = {
domain: React.PropTypes.object
};
......@@ -8,7 +8,6 @@ import MessageBar from '../message_bar.jsx';
import PageInfo from '../page_info.jsx';
import PanelTab from '../panel_tab.jsx';
import Button from '../button.jsx';
import DomainGeneralInfo from './domain_general_info.jsx';
import DomainMailboxPlans from './domain_mailbox_plans.jsx';
import DomainAdmins from './domain_admin_list.jsx';
......@@ -16,6 +15,8 @@ import DomainDistributionList from './domain_distribution_list.jsx';
import ToggleModalButton from '../toggle_modal_button.jsx';
import MultipleTaskModal from './multiple_task_modal.jsx';
import AntiSpamComponent from './antispam.jsx';
import ZonaDNS from './domain_admin_dns.jsx';
import EventStore from '../../stores/event_store.jsx';
import DomainStore from '../../stores/domain_store.jsx';
......@@ -27,27 +28,63 @@ export default class DomainDetails extends React.Component {
super(props);
this.getDomain = this.getDomain.bind(this);
this.showMessage = this.showMessage.bind(this);
this.state = {};
}
showMessage(attrs) {
this.setState({
error: {
message: attrs.message,
type: attrs.typeError
}
});
}
getDomain() {
const domain = DomainStore.getCurrent();
if (domain && domain.id === this.props.params.id) {
GlobalActions.emitEndLoading();
Client.getZone(domain.name, (zone) => {
DomainStore.setZoneDNS(zone);
this.setState({
domain
});
GlobalActions.emitEndLoading();
}, () => {
DomainStore.setZoneDNS(null);
this.setState({
domain
});
GlobalActions.emitEndLoading();
});
} else {
Client.getDomain(
this.props.params.id,
(data) => {
DomainStore.setCurrent(data);
Client.getZone(data.name, (zone) => {
DomainStore.setZoneDNS(zone);
this.setState({
domain: data
});
GlobalActions.emitEndLoading();
}, () => {
this.setState({
domain: data
});
GlobalActions.emitEndLoading();
});
},
(error) => {
this.setState({
......@@ -60,12 +97,14 @@ export default class DomainDetails extends React.Component {
}
componentDidMount() {
EventStore.addMessageListener(this.showMessage);
$('#sidebar-domains').addClass('active');
this.getDomain();
}
componentWillUnmount() {
$('#sidebar-domains').removeClass('active');
EventStore.removeMessageListener(this.showMessage);
}
render() {
......@@ -125,14 +164,21 @@ export default class DomainDetails extends React.Component {
</div>
);
const zonaDNS = (
<ZonaDNS
domain={domain}
/>
);
const panelTabs = (
<PanelTab
tabNames={['Administradores', 'AntiSpam', 'Listas De Distribución', 'Tareas Masivas']}
tabNames={['Administradores', 'AntiSpam', 'Listas De Distribución', 'Tareas Masivas', 'Zona DNS']}
tabs={{
administradores: tabAdmin,
antispam: tabAntiSpam,
listas_de_distribución: tabDistribution,
tareas_masivas: tabTareasMasivas
tareas_masivas: tabTareasMasivas,
zona_dns: zonaDNS
}}
location={this.props.location}
/>
......
......@@ -56,13 +56,11 @@ export default class DomainGeneralInfo extends React.Component {
company: company.name
});
} else {
Client.getCompany(id).
then((data) => {
Client.getCompany(id, (data) => {
this.setState({
company: data.name
});
}).
catch((error) => {
}, (error) => {
this.setState({
error: {
message: error.message,
......
import React from 'react';
import {browserHistory} from 'react-router';
import CompanyStore from '../../../stores/company_store.jsx';
import DomainStore from '../../../stores/domain_store.jsx';
import ZimbraStore from '../../../stores/zimbra_store.jsx';
import * as Client from '../../../utils/client.jsx';
import * as Utils from '../../../utils/utils.jsx';
import * as GlobalActions from '../../../action_creators/global_actions.jsx';
import Constants from '../../../utils/constants.jsx';
const MessageType = Constants.MessageType;
export default class CreateDomainForm extends React.Component {
constructor(props) {
super(props);
this.planSize = this.planSize.bind(this);
this.getCompanies = this.getCompanies.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {};
}
planSize(e) {
e.preventDefault();
let total = 0;
const plans = Object.keys(this.state.plans);
plans.forEach((p) => {
total += parseInt(this.refs[`plan-${p}`].value, 10) || 0;
});
this.refs.mailboxLimit.value = total;
}
getCompanies() {
const companyId = this.props.params.id;
const companies = CompanyStore.getCompanies();
if (companies) {
this.setState({
plans: Utils.getEnabledPlansByCos(ZimbraStore.getAllCos()),
companies,
companyId
});
return GlobalActions.emitEndLoading();
}
return Client.getAllCompanies().
then((data) => {
this.setState({
plans: Utils.getEnabledPlansByCos(ZimbraStore.getAllCos()),
companies: data,
companyId
});
}).
catch((error) => {
GlobalActions.emitMessage({
message: error.message,
typeError: MessageType.ERROR
});
}).
finally(() => {
GlobalActions.emitEndLoading();
});
}
handleSubmit(e) {
e.preventDefault();
const button = this.refs.createdomainbtn;
const oldContent = button.innerHTML;
if (this.props.state.total === this.props.state.step) {
GlobalActions.emitStartLoading();
}
const elementList = document.querySelectorAll('.has-error');
Array.from(elementList).forEach((el) => el.classList.remove('has-error'));
Utils.validateInputRequired(this.refs).
then(() => {
const plans = Object.keys(this.state.plans);
const zimbraDomainCOSMaxAccounts = [];
const name = this.refs.domainName.value.trim();
const businessCategory = this.refs.company.value.trim();
const zimbraDomainStatus = this.refs.zimbraDomainStatus.value.trim();
plans.forEach((p) => {
zimbraDomainCOSMaxAccounts.push(`${this.refs[`plan-${p}`].getAttribute('data-id')}:${this.refs[`plan-${p}`].value || 0}`);
});
const domain = {
name,
attrs: {
zimbraDomainCOSMaxAccounts,
businessCategory,
zimbraDomainStatus
}
};
button.innerHTML = '<i class=\'fa fa-spinner fa-spin\'></i> Creando Dominio';
Utils.toggleStatusButtons('.action-create-domain', true);
Client.createDomain(
domain,
(data) => {
CompanyStore.addDomain(businessCategory, data);
DomainStore.setCurrent(data);
if (this.props.state.total === this.props.state.step) {
browserHistory.push(`/domains/${data.id}`);
} else {
DomainStore.emitNextStep({
step: ++this.props.state.step,
domain: data
});
}
button.innerHTML = oldContent;
Utils.toggleStatusButtons('.action-create-domain', false);
},
(error) => {
if (this.props.state.total === this.props.state.step) {
GlobalActions.emitEndLoading();
}
button.innerHTML = oldContent;
Utils.toggleStatusButtons('.action-create-domain', false);
return GlobalActions.emitMessage({
message: error.message,
typeError: MessageType.ERROR
});
}
);
}).
catch((error) => {
if (this.props.state.total === this.props.state.step) {
GlobalActions.emitEndLoading();
}
error.refs = true;
error.type = error.typeError;
error.node.closest('.form-group').classList.add('has-error');
return GlobalActions.emitMessage({
message: error.message,
typeError: error.type
});
});
}
componentDidMount() {
Client.initPowerDNS();
this.getCompanies();
}
render() {
const companies = this.state.companies;
const error = this.state.error;
if (companies || error) {
let backUrl = '/domains';
if (this.state.companyId) {
backUrl = `/companies/${this.state.companyId}`;
}
const companiesOptions = companies.map((c) => {
return (
<option
key={`company-${c.id}`}
value={c.id}
>
{c.name}
</option>
);
});
const statePlans = this.state.plans;
const enabledPlans = Object.keys(statePlans);
const plans = enabledPlans.map((p) => {
return (
<div
key={`plan-${statePlans[p]}`}
className='col-md-4 form-group required'
>
<label
htmlFor={`plan-${p}`}
clasName='label-top control-label'
>
<abbr title='Requerido'>{'*'}</abbr><br/>
{Utils.titleCase(p)}
</label>
<br/>
<div className='row'>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
defaultValue='0'
data-required='true'
data-message={`Debe asignar la cantidad de casillas del tipo ${Utils.titleCase(p)}`}
data-id={statePlans[p]}
ref={`plan-${p}`}
onKeyUp={this.planSize}
/>
</div>
</div>
</div>
);
});
const form = (
<form
className='simple_form form-horizontal mailbox-form'
onSubmit={this.handleSubmit}
>
<div className='form-group string required'>
<label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr>
{'Nombre'}
</label>
<div className='col-sm-8'>
<input
type='text'
data-required='true'
data-message='El nombre del dominio es obligatorio'
className='form-control'
ref='domainName'
placeholder='example.com'
/>
</div>
</div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr>
{'Empresa'}
</label>
<div className='col-sm-8'>
<select
className='form-control select required'
data-required='true'
data-message='Debe especificar a que empresa corresponde el dominio'
ref='company'
defaultValue={this.state.companyId}
>
{companiesOptions}
</select>
</div>
</div>
<div className='form-group row'>
<div className='col-md-8 col-md-offset-3'>
<div className='box-content'>
{plans}
</div>
</div>
</div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
<abbr title='requerido'>{'*'}</abbr>
{'Status'}
</label>
<div className='col-sm-8'>
<select
className='form-control select'
data-required='true'
data-message='Debe especificar el status del dominio'
ref='zimbraDomainStatus'
>
<option value='active'>Activo</option>
<option value='closed'>Cerrado</option>
<option value='locked'>Bloqueado</option>
<option value='maintenance'>En Mantención</option>
<option value='suspended'>Suspendido</option>
</select>
</div>
</div>
<div className='form-group string'>
<label className='string required col-sm-3 control-label'>
{'Límite de casillas'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
ref='mailboxLimit'
value='0'
disabled='disabled'
/>
</div>
</div>
<div className='form-group'>
<div className='col-sm-8 col-sm-offset-3'>
<button
className='btn btn-info action-create-domain'
ref='createdomainbtn'
>
{'Guardar'}
</button>
<a
href='#'
className='btn btn-default'
onClick={(e) => Utils.handleLink(e, backUrl)}
>
{'Cancelar'}
</a>
</div>
</div>
</form>
);
return (
<div>
{form}
</div>
);
}
return <div/>;
}
}
CreateDomainForm.propTypes = {
params: React.PropTypes.object.isRequired,
state: React.PropTypes.object
};
import React from 'react';
import {browserHistory} from 'react-router';
import * as Utils from '../../../utils/utils.jsx';
import Constants from '../../../utils/constants.jsx';
import * as Client from '../../../utils/client.jsx';
import EventStore from '../../../stores/event_store.jsx';
import DomainStore from '../../../stores/domain_store.jsx';
const Labels = Constants.Labels;
const MessageType = Constants.MessageType;
export default class DNSZoneForm extends React.Component {
constructor(props) {
super(props);
this.nextStep = this.nextStep.bind(this);
this.addDNSRow = this.addDNSRow.bind(this);
this.removeRow = this.removeRow.bind(this);
this.handleChangeInput = this.handleChangeInput.bind(this);
this.addDNSRequest = this.addDNSRequest.bind(this);
this.instanceRow = {
name: '',
type: Constants.typesOfDNS[0],
content: '',
priority: 10,
ttl: 86400,
disabled: false
};
this.defaultRows = [
Object.assign({}, this.instanceRow),
Object.assign({}, this.instanceRow),
Object.assign({}, this.instanceRow)
];
this.types = Constants.typesOfDNS;
this.state = {
fields: this.defaultRows,
emptyValue: ''
};
}
nextStep() {
if (this.props.state.step === this.props.state.total) {
browserHistory.push(`/domains/${this.props.state.domain.id}`);
} else {
DomainStore.emitNextStep({
step: ++this.props.state.step
});
}
}
addDNSRequest() {
const request = {
name: this.props.state.domain.name,
kind: 'Master',
nameservers: []
};
const records = this.defaultRows;
Utils.toggleStatusButtons('.savedns', true);
const button = this.refs.savedns;
const oldContent = button.innerHTML;
button.innerHTML = '<i class=\'fa fa-spinner fa-spin\'></i> Creando Zona DNS';
Client.getZone(this.props.state.domain.name, (zona) => {
zona.createOrModifyRecords(records, (err) => {
if (err) {
EventStore.emitMessage({
message: err.reason,
typeError: MessageType.ERROR
});
button.innerHTML = oldContent;
return Utils.toggleStatusButtons('.savedns', false);
}
return this.nextStep();
});
}, () => {
Client.createZoneWithRecords(request, records, () => {
this.nextStep();
}, (error) => {
EventStore.emitMessage({
message: error.reason,
typeError: MessageType.ERROR
});
Utils.toggleStatusButtons('.savedns', false);
button.innerHTML = oldContent;
});
});
}
addDNSRow() {
const copy = Object.assign({}, this.instanceRow);
this.defaultRows.push(copy);
this.setState({
fields: this.defaultRows
});
}
removeRow(e, index) {
e.preventDefault();
if (this.defaultRows[index]) {
this.defaultRows.splice(index, 1);
this.setState({
fields: this.defaultRows
});
}
return false;
}
clearInputsFromParent(parentID) {
const parent = document.getElementById(parentID);
if (parent) {
const elements = parent.querySelectorAll('input, select');
let size = elements.length;
if (size > 0) {
for (;size-- > 0;) {
if (elements[size].nodeName.toLowerCase() === 'input') {
elements[size].value = '';
} else {
elements[size].selectedIndex = 0;
}
}
}
}
}
handleChangeInput(e, index, ref) {
const value = e.target.value;
if (this.defaultRows[index]) {
this.defaultRows[index][ref] = value;
return true;
}
return false;
}
render() {
const textButton = this.props.state.step === this.props.state.total ? 'Saltar y Finalizar' : 'Saltar este paso';
let fields = null;
let header = null;
const types = this.types.map((item) => {
return (
<option
key={item}
value={item}
>
{item}
</option>
);
});
fields = (
<div className='text-center'>
<h4>No existen Zonas DNS para su dominio : <strong>{this.props.state.domain.name}</strong></h4>
</div>
);
if (Array.isArray(this.defaultRows) && this.defaultRows.length > 0) {
header = (
<div className='row'>
<div className='col-xs-3'>
<strong>Nombre</strong>
</div>
<div className='col-xs-1'>
<strong>Tipo</strong>
</div>
<div className='col-xs-3'>
<strong>Contenido</strong>
</div>
<div className='col-xs-2'>
<strong>Prioridad</strong>
</div>
<div className='col-xs-2'>
<strong>TTL</strong>
</div>
<div className='col-xs-1'>
<strong>Acciones</strong>
</div>
</div>
);
fields = this.defaultRows.map((element, i) => {
return (
<div
className='row set-margin-up'
key={`row-${new Date().getTime()}-${i}`}
id={`row-dns-${new Date().getTime()}-${i}`}
>
<div className='col-xs-3'>
<input
type='text'
defaultValue={element.name}
className='form-control'
ref={`${Labels.name}-${i}`}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.name);
}}
/>
</div>
<div className='col-xs-1'>
<select
className='form-control'
defaultValue={element.type}
ref={`${Labels.type}-${i}`}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.type);
}}
>
{types}
</select>
</div>
<div className='col-xs-3'>
<input
type='text'
className='form-control'
defaultValue={element.content}
ref={`${Labels.content}-${i}`}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.content);
}}
/>
</div>
<div className='col-xs-2'>
<input
type='number'
className='form-control'
defaultValue={element.priority}
ref={`${Labels.priority}-${i}`}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.priority);
}}
/>
</div>
<div className='col-xs-2'>
<input
type='number'
className='form-control'
defaultValue={element.ttl}
ref={`${Labels.ttl}-${i}`}
onChange={(e) => {
this.handleChangeInput(e, i, Labels.ttl);
}}
/>
</div>
<div className='col-xs-1'>
<button
className='btn btn-danger'
onClick={(e) => {
this.removeRow(e, i);
}}
>
<i
className='fa fa-trash-o'
title='Delete'
>
</i>
</button>
</div>
</div>
);
});
}
return (
<div>
<blockquote className='clearfix'>
<p>
{'Editar Zona DNS para '}<strong>{this.props.state.domain.name}</strong>
<button
className='btn btn-info pull-right'
onClick={this.addDNSRow}
>
<i className='fa fa-plus-circle fa-lg'></i> Agregar otro registro
</button>
</p>
</blockquote>
<form>
{header}
{fields}
<br/>
<br/>
<div className='col-xs-12 text-right'>
<button
type='button'
className='btn btn-info savedns'
onClick={this.addDNSRequest}
ref='savedns'
>
{'Guardar'}
</button>
<button
type='button'
className='btn btn-info'
onClick={this.nextStep}
>
{textButton}
</button>
</div>
</form>
</div>
);
}
}
DNSZoneForm.propTypes = {
state: React.PropTypes.object
};
import React from 'react';
import * as Utils from '../../../utils/utils.jsx';
import {browserHistory} from 'react-router';
import DomainStore from '../../../stores/domain_store.jsx';
export default class MailCleanerForm extends React.Component {
constructor(props) {
super(props);
this.addMailCleaner = this.addMailCleaner.bind(this);
this.nextStep = this.nextStep.bind(this);
this.handleChangeOption = this.handleChangeOption.bind(this);
this.state = {};
}
nextStep() {
if (this.props.state.step === this.props.state.total) {
browserHistory.push(`/domains/${this.props.state.domain.id}`);
} else {
DomainStore.emitNextStep({
step: ++this.props.state.step
});
}
}
handleChangeOption() {
const isEnabledMailCleaner = this.refs.enableMailcleaner.checked;
Utils.toggleStatusButtons('.saveMC', !isEnabledMailCleaner);
}
addMailCleaner() {
const isEnabledMailCleaner = this.refs.enableMailcleaner.checked;
return isEnabledMailCleaner;
}
componentDidMount() {
Utils.toggleStatusButtons('.saveMC', true);
}
render() {
const textButton = this.props.state.step === this.props.state.total ? 'Saltar y Finalizar' : 'Saltar este paso';
return (
<div>
<blockquote>
<p>{'¿ Desea agregar su dominio '}<strong>{this.props.state.domain.name}</strong>{' a MailCleaner ?'}</p>
</blockquote>
<form>
<div className='col-xs-12'>
<label
className='radio radio-info radio-inline pretty-input'
>
<div className='pretty-checkbox'>
<input
type='checkbox'
className='pretty'
name='mailbox'
ref='enableMailcleaner'
onChange={this.handleChangeOption}
/>
<span></span>
</div>
{'Desea usar MailCleaner en su dominio: '} <strong>{this.props.state.domain.name}</strong>
</label>
</div>
<br/>
<br/>
<div className='col-xs-12 text-right'>
<button
type='button'
className='btn btn-info saveMC'
onClick={this.addMailCleaner}
>
{'Guardar'}
</button>
<button
type='button'
className='btn btn-info'
onClick={this.nextStep}
>
{textButton}
</button>
</div>
</form>
</div>
);
}
}
MailCleanerForm.propTypes = {
state: React.PropTypes.object
};
......@@ -69,8 +69,7 @@ export default class MultipleTaskModal extends React.Component {
if (this.props.show) {
this.props.onHide();
}
}, (err) => {
console.log('err',err);
}, () => {
if (this.props.show) {
this.props.onHide();
}
......@@ -93,8 +92,7 @@ export default class MultipleTaskModal extends React.Component {
accounts: res
});
}).catch((error) => {
console.log('err', error);
}).finally(() => {
return error;
});
}
......
......@@ -11,7 +11,6 @@ import * as Utils from '../utils/utils.jsx';
import * as Client from '../utils/client.jsx';
import MailboxStore from '../stores/mailbox_store.jsx';
export default class ImportMassiveModal extends React.Component {
constructor(props) {
super(props);
......@@ -35,7 +34,6 @@ export default class ImportMassiveModal extends React.Component {
this.uploaded = null;
this.disabled = {};
this.plans = Utils.getEnabledPlansByCos(ZimbraStore.getAllCos());
this.state = {
......@@ -90,14 +88,17 @@ export default class ImportMassiveModal extends React.Component {
} else {
return this.setState({
alert: true,
alertMessage: 'Su archvio esta vacio, verifiquelo, por favor',
alertMessage: 'Su archvio esta vacio, verifiquelo, por favor'
});
}
return null;
};
fileReader.readAsText(file);
}
return null;
}
onChangeColumn(e, option, key) {
......@@ -149,6 +150,8 @@ export default class ImportMassiveModal extends React.Component {
if (pos === '') {
return true;
}
return null;
});
if (isEmpty) {
......@@ -204,7 +207,7 @@ export default class ImportMassiveModal extends React.Component {
if (!ul[c]) {
if (col.indexOf('@') > -1) {
if (isEmail.test(col)) {
ul[c] = {}
ul[c] = {};
ul[c][flagDefault] = [];
this.disabled[flagDefault] = {
col: c
......@@ -246,8 +249,8 @@ export default class ImportMassiveModal extends React.Component {
counter++;
}
const length = (Array.isArray(this.uploaded[current])) ? this.uploaded[current].length : this.uploaded[current]['email'].length;
const data = (Array.isArray(this.uploaded[current])) ? this.uploaded[current] : this.uploaded[current]['email'];
const length = (Array.isArray(this.uploaded[current])) ? this.uploaded[current].length : this.uploaded[current].email.length;
const data = (Array.isArray(this.uploaded[current])) ? this.uploaded[current] : this.uploaded[current].email;
for (var i = 0; i < length; i++) {
if (!padre[i]) {
......@@ -267,10 +270,11 @@ export default class ImportMassiveModal extends React.Component {
return this.createMassiveAccounts(padre);
}
return this.setState({
this.setState({
alert: true,
alertMessage: 'Faltan columnas que son obligatorias, verifique por favor.'
});
return null;
}
createMassiveAccounts(accounts) {
......@@ -324,9 +328,15 @@ export default class ImportMassiveModal extends React.Component {
//Aqui va error batchrequest
GlobalActions.emitEndTask({
id: 'casillamasiva'
id: 'casillamasiva',
toast: {
message: 'Se han importado todas las casillas.',
title: 'Mailbox - Carga Masiva'
}
});
});
return null;
}
render() {
......@@ -339,7 +349,6 @@ export default class ImportMassiveModal extends React.Component {
);
}
if (this.state.cols) {
const columns = this.state.cols;
ul = [];
......
......@@ -70,6 +70,8 @@ export default class ConfirmDeleteModal extends React.Component {
});
});
}
return null;
}
render() {
......
......@@ -182,6 +182,8 @@ export default class CreateMailBox extends React.Component {
if (currentDomainId === domain.id) {
return domain;
}
return null;
});
}
......@@ -481,5 +483,6 @@ export default class CreateMailBox extends React.Component {
}
CreateMailBox.propTypes = {
location: React.PropTypes.object
location: React.PropTypes.object,
params: React.PropTypes.object
};
......@@ -92,7 +92,7 @@ export default class EditMailBox extends React.Component {
return false;
}
this.handleRenameAccount(mail);
return this.handleRenameAccount(mail);
}
handleRenameAccount(email) {
......@@ -139,7 +139,7 @@ export default class EditMailBox extends React.Component {
});
}
GlobalActions.emitMessage({
return GlobalActions.emitMessage({
message: 'Error, no existe instancia de la casilla.',
typeError: messageType.ERROR
});
......
......@@ -132,6 +132,8 @@ export default class Mailboxes extends React.Component {
componentWillReceiveProps(newProps) {
const condition = this.props.location.query.page !== newProps.location.query.page;
let domainId = null;
if (condition) {
const page = parseInt(newProps.location.query.page, 10) || 1;
......@@ -142,13 +144,16 @@ export default class Mailboxes extends React.Component {
offset: ((page - 1) * QueryOptions.DEFAULT_LIMIT)
};
this.getAllMailboxes();
domainId = this.props.params.domain_id;
this.getAllMailboxes(domainId);
} else {
GlobalActions.emitStartLoading();
let domainId;
if (newProps.params.domain_id !== this.props.params.domain_id) {
domainId = newProps.params.domain_id;
}
this.getAllMailboxes(domainId);
}
}
......@@ -221,8 +226,8 @@ export default class Mailboxes extends React.Component {
notMatches: true,
domain: domainName
});
}).catch(() => {
console.log('error',error);
}).catch((error) => {
return error;
}).finally(() => {
GlobalActions.emitEndLoading();
});
......@@ -493,7 +498,7 @@ export default class Mailboxes extends React.Component {
className='form-control plans'
onChange={this.handleChangeFilter}
>
<option value=''>Todoas los planes</option>
<option value=''>Todos los planes</option>
<option value='basic'>Básico</option>
<option value='professional'>Profesional</option>
<option value='premium'>Premium</option>
......@@ -572,7 +577,6 @@ export default class Mailboxes extends React.Component {
onClick={this.handleTabChanged}
/>
);
}
return (
......
......@@ -97,7 +97,7 @@ export default class MailboxDetails extends React.Component {
});
}
this.setState({
return this.setState({
data: account,
alias: items,
webmail: false
......@@ -132,7 +132,7 @@ export default class MailboxDetails extends React.Component {
});
}
this.setState({
return this.setState({
data: result,
alias: items,
webmail: false
......
......@@ -39,12 +39,12 @@ export default class Pagination extends React.Component {
pageUrl = this.getPageQueryString(page);
}
browserHistory.push(`/${this.props.url}${pageUrl}`);
browserHistory.push(`${this.props.url}${pageUrl}`);
}
handleNext(e) {
e.preventDefault();
const page = this.getPageQueryString(this.props.currentPage + 1);
browserHistory.push(`/${this.props.url}${page}`);
browserHistory.push(`${this.props.url}${page}`);
}
handleLast(e) {
e.preventDefault();
......
......@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React from 'react';
import EventStore from '../stores/event_store.jsx';
import * as GlobalActions from '../action_creators/global_actions.jsx';
export default class ProgressTask extends React.Component {
constructor(props) {
......
{
"debug": false,
"debug": true,
"zimbraUrl": "http://zimbra.zboxapp.dev:8000/service/admin/soap",
"zimbraProxy": "https://zimbra.zboxapp.dev:7071",
"dnsApiUrl": "http://zimbra.zboxapp.dev:3000",
"webMailUrl": "https://zimbra.zboxapp.dev",
"dns": {
"url": "http://192.168.1.8:8081",
"token": "otto"
},
"plans": {
"basic": true,
"premium": true,
"professional": true,
"default": false
},
"multiFormDomain": {
"hasMailCleaner": false,
"hasDNSZone": true
},
"webmailLifetime": 3600,
"companiesEndPoints": {
"list": "http://zimbra.zboxapp.dev:8001/list",
......
......@@ -25,9 +25,9 @@
}
.taskboard {
height: 100%;
max-height: 0;
overflow: hidden;
height: 100%;
transition: max-height 1s;
.alert {
......@@ -48,3 +48,9 @@
width: 100%;
}
}
.flash {
+ .progress {
margin-top: 10px;
}
}
......@@ -102,3 +102,32 @@
}
}
}
.progress-text {
color: $white;
font-weight: bold;
text-align: center;
text-shadow: 0 1px 2px $black;
}
.progress-bar.step {
background-color: $bg-progresss-bar;
border-right: 0;
text-align: center;
&.first-step {
width: 33.33%;
}
&.second-step {
width: 66.66%;
}
&.third-step {
width: 100%;
}
}
.set-margin-up {
margin-top: 10px;
}
......@@ -93,3 +93,7 @@ $color-new-fields: #e4e5e7;
$bg-import-ok: rgba(78, 165, 224, .2);
$border-color-ok: #4ea5e0;
$bg-import-error: #ffe8e8;
// color ProgressBar
$bg-progresss-bar: #5bc0de;
......@@ -12,6 +12,7 @@ class DomainStoreClass extends EventEmitter {
this.current = null;
this.distributionListOwners = null;
this.distributionListMembers = null;
this.zoneDNS = null;
}
getCurrent() {
......@@ -241,6 +242,19 @@ class DomainStoreClass extends EventEmitter {
return false;
}
setZoneDNS(zone) {
this.zoneDNS = zone;
return this.emitZoneDNSChange(zone);
}
getZoneDNS() {
if (this.zoneDNS) {
return this.zoneDNS;
}
return null;
}
removeDistributionList(listId) {
if (this.current.lists) {
Reflect.deleteProperty(this.current.lists, listId);
......@@ -248,6 +262,18 @@ class DomainStoreClass extends EventEmitter {
this.emitDistributionListsChange();
}
emitZoneDNSChange(zone) {
this.emit(eventTypes.ZONE_DNS_CHANGE_EVENT, zone);
}
addZoneDNSChangeListener(zone) {
this.on(eventTypes.ZONE_DNS_CHANGE_EVENT, zone);
}
removeZoneDNSChangeListener(zone) {
this.removeListener(eventTypes.ZONE_DNS_CHANGE_EVENT, zone);
}
emitDistributionListsChange() {
this.emit(eventTypes.DOMAIN_DLS_CHANGE_EVENT);
}
......@@ -259,6 +285,18 @@ class DomainStoreClass extends EventEmitter {
removeDistributionListsChangeListener(callback) {
this.removeListener(eventTypes.DOMAIN_DLS_CHANGE_EVENT, callback);
}
emitNextStep(attrs) {
this.emit(eventTypes.NEXT_STEP_EVENT, attrs);
}
addNextStepListener(callback) {
this.on(eventTypes.NEXT_STEP_EVENT, callback);
}
removeNextStepListener(callback) {
this.removeListener(eventTypes.NEXT_STEP_EVENT, callback);
}
}
const DomainStore = new DomainStoreClass();
......
......@@ -5,6 +5,7 @@ import $ from 'jquery';
import Promise from 'bluebird';
import ZimbraAdminApi from 'zimbra-admin-api-js';
import Powerdns from 'js-powerdns';
import ZimbraStore from '../stores/zimbra_store.jsx';
import * as GlobalActions from '../action_creators/global_actions.jsx';
......@@ -160,21 +161,19 @@ export function getAllCompanies() {
});
}
export function getCompany(id) {
export function getCompany(id, success, error) {
const url = global.window.manager_config.companiesEndPoints.detail.replace('{id}', id);
return new Promise((resolve, reject) => {
return $.ajax({
url,
dataType: 'json',
success: function onSuccess(data) {
resolve(data);
success(data);
},
error: function onError(xhr, status, err) {
reject(err);
error: function onError(xhr) {
error(xhr.responseJSON);
}
});
});
}
export function getInvoices(id, success, error) {
......@@ -665,3 +664,93 @@ export function renameAccount(account, success, error) {
}
);
}
export function initPowerDNS() {
return new Promise((resolve, reject) => {
const powerAttrs = window.manager_config.dns;
const api = new Powerdns({url: powerAttrs.url, token: powerAttrs.token});
if (api) {
return resolve(api);
}
return reject({
type: Constants.MessageType.ERROR,
message: 'PowerDNS no instanciado'
});
});
}
export function createZoneWithRecords(zoneData, records, success, error) {
initPowerDNS().then(
(api) => {
api.createZoneWithRecords(zoneData, records, (er, data) => {
if (er) {
return error(er);
}
return success(data);
});
},
(err) => {
const e = handleError('createZoneWithRecords', err);
return error(e);
}
);
}
export function getZone(domain, success, error) {
initPowerDNS().then(
(api) => {
api.getZone(domain, (er, data) => {
if (er) {
return error(er);
}
return success(data);
});
},
(err) => {
const e = handleError('getZone', err);
return error(e);
}
);
}
export function modifyOrCreateRecords(record, success, error) {
initPowerDNS().then(
(api) => {
api.modifyOrCreateRecords(record, (err, data) => {
if (err) {
const e = handleError('modifyOrCreateRecords', err);
return error(e);
}
return success(data);
});
},
(err) => {
const e = handleError('modifyOrCreateRecords', err);
return error(e);
}
);
}
export function deleteRecords(zoneUrl, record, success, error) {
initPowerDNS().then(
(api) => {
api.deleteRecords(zoneUrl, record, (err, data) => {
if (err) {
const e = handleError('deleteRecords', err);
return error(e);
}
return success(data);
});
},
(err) => {
const e = handleError('deleteRecords', err);
return error(e);
}
);
}
......@@ -31,7 +31,9 @@ export default {
USER_CHANGE_EVENT: null,
NEW_MESSAGE_EVENT: null,
NEW_TOAST_EVENT: null,
MAILBOX_ADD_MASSIVE_EVENT: null
MAILBOX_ADD_MASSIVE_EVENT: null,
NEXT_STEP_EVENT: null,
ZONE_DNS_CHANGE_EVENT: null
}),
MessageType: keyMirror({
......@@ -54,5 +56,50 @@ export default {
MONTHS: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Juio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
QueryOptions: {
DEFAULT_LIMIT: 10
}
},
Labels: keyMirror({
name: null,
type: null,
content: null,
priority: null,
ttl: null
}),
typesOfDNS: [
'AAAA',
'AFSDB',
'CERT',
'CNAME',
'A',
'DLV',
'DNSKEY',
'DS',
'EUI48',
'EUI64',
'HINFO',
'IPSECKEY',
'KEY',
'KX',
'LOC',
'MINFO',
'MR',
'MX',
'NAPTR',
'NS',
'NSEC',
'NSEC3',
'NSEC3PARAM',
'OPT',
'PTR',
'RKEY',
'RP',
'RRSIG',
'SOA',
'SPF',
'SRV',
'SSHFP',
'TLSA',
'TSIG',
'TXT',
'WKS'
]
};
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