Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Z
zimbra-admin-api-js
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Public
zimbra-admin-api-js
Commits
03047062
Commit
03047062
authored
Apr 28, 2016
by
Elias Nahum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Companies with details for each company
- Update dependencies
parent
07deed30
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
1577 additions
and
462 deletions
+1577
-462
companies-service.js
companies-service.js
+30
-1
list.json
companies/list.json
+12
-0
package.json
package.json
+17
-15
global_actions.jsx
src/action_creators/global_actions.jsx
+8
-0
accounts.jsx
src/components/accounts/accounts.jsx
+0
-90
create_account.jsx
src/components/accounts/create_account.jsx
+0
-129
edit_account.jsx
src/components/accounts/edit_account.jsx
+0
-129
companies.jsx
src/components/companies/companies.jsx
+251
-0
company_admins.jsx
src/components/companies/company_admins.jsx
+122
-0
company_details.jsx
src/components/companies/company_details.jsx
+228
-0
company_domains.jsx
src/components/companies/company_domains.jsx
+139
-0
company_info.jsx
src/components/companies/company_info.jsx
+39
-0
company_invoices.jsx
src/components/companies/company_invoices.jsx
+189
-0
company_mailbox_plans.jsx
src/components/companies/company_mailbox_plans.jsx
+123
-0
domain_admin_list.jsx
src/components/domain/domain_admin_list.jsx
+0
-1
domain_general_info.jsx
src/components/domain/domain_general_info.jsx
+40
-8
domain_mailbox_plans.jsx
src/components/domain/domain_mailbox_plans.jsx
+2
-2
domains.jsx
src/components/domain/domains.jsx
+3
-2
logged_in.jsx
src/components/logged_in.jsx
+2
-0
login.jsx
src/components/login/login.jsx
+8
-6
create_mailbox.jsx
src/components/mailbox/create_mailbox.jsx
+6
-2
edit_mailbox.jsx
src/components/mailbox/edit_mailbox.jsx
+6
-2
mailbox.jsx
src/components/mailbox/mailbox.jsx
+2
-1
message_bar.jsx
src/components/message_bar.jsx
+12
-6
root.jsx
src/components/root.jsx
+1
-1
sidebar_menu.jsx
src/components/sidebar_menu.jsx
+3
-3
toast_alert.jsx
src/components/toast_alert.jsx
+41
-0
config.json
src/config/config.json
+6
-1
index.jsx
src/index.jsx
+9
-16
_companies.scss
src/sass/routes/_companies.scss
+37
-0
_module.scss
src/sass/routes/_module.scss
+1
-0
styles.scss
src/sass/styles.scss
+2
-0
company_store.jsx
src/stores/company_store.jsx
+58
-0
event_store.jsx
src/stores/event_store.jsx
+15
-0
user_store.jsx
src/stores/user_store.jsx
+11
-1
client.jsx
src/utils/client.jsx
+94
-1
constants.jsx
src/utils/constants.jsx
+6
-3
utils.jsx
src/utils/utils.jsx
+54
-0
domain.jsx
src/zimbra/domain.jsx
+0
-42
No files found.
companies-service.js
View file @
03047062
...
...
@@ -11,6 +11,7 @@ const cookieParser = require('cookie-parser');
const
bodyParser
=
require
(
'body-parser'
);
const
Promise
=
require
(
'bluebird'
);
const
_
=
require
(
'lodash'
);
const
moment
=
require
(
'moment'
);
const
port
=
normalizePort
(
process
.
env
.
PORT
||
'8001'
);
//eslint-disable-line no-process-env
...
...
@@ -53,7 +54,35 @@ app.get('/company/:id', (req, res) => {
});
app
.
get
(
'/company/:id/invoices'
,
(
req
,
res
)
=>
{
return
res
.
json
([]);
return
res
.
json
([
{
number
:
355
,
link
:
'http://google.com'
,
date
:
moment
(
'2016-01-01'
).
toJSON
(),
total
:
'$ 54.490'
,
status
:
1
},
{
number
:
356
,
link
:
'http://google.com'
,
date
:
moment
(
'2016-02-01'
).
toJSON
(),
total
:
'$ 54.490'
,
status
:
2
},
{
number
:
357
,
date
:
moment
(
'2016-02-01'
).
toJSON
(),
total
:
'$ 54.490'
,
status
:
3
},
{
number
:
358
,
link
:
'http://google.com'
,
date
:
moment
(
'2016-03-01'
).
toJSON
(),
total
:
'$ 54.490'
,
status
:
0
}
]);
});
// catch 404 and forward to error handler
...
...
companies/list.json
View file @
03047062
...
...
@@ -2,5 +2,17 @@
{
"id"
:
"24346664-4"
,
"name"
:
"ZBox"
},
{
"id"
:
"13834853-9"
,
"name"
:
"Patricio Bruna"
},
{
"id"
:
"76530890-9"
,
"name"
:
"IT Linux"
},
{
"id"
:
"76424135-5"
,
"name"
:
"Test Company"
}
]
package.json
View file @
03047062
...
...
@@ -3,45 +3,48 @@
"version"
:
"0.0.1"
,
"private"
:
true
,
"dependencies"
:
{
"
animate.css
"
:
"
^3.5.1
"
,
"
bluebird
"
:
"
^3.3.5
"
,
"
bootstrap
"
:
"
3.3.6
"
,
"
compass-mixins
"
:
"
0.12.7
"
,
"
flux
"
:
"
2.1.1
"
,
"
font-awesome
"
:
"
4.
5.0
"
,
"
font-awesome
"
:
"
4.
6.1
"
,
"
jasny-bootstrap
"
:
"
3.1.3
"
,
"
jquery
"
:
"
2.2.3
"
,
"
keymirror
"
:
"
0.1.1
"
,
"
lodash
"
:
"
^4.11.1
"
,
"
moment
"
:
"
^2.13.0
"
,
"
nprogress
"
:
"
^0.2.0
"
,
"
object-assign
"
:
"
4.0.1
"
,
"
perfect-scrollbar
"
:
"
0.6.10
"
,
"
react
"
:
"
15.0.0
"
,
"
react-bootstrap
"
:
"
0.28.5
"
,
"
react
"
:
"
15.0.1
"
,
"
react-bootstrap
"
:
"
0.29.2
"
,
"
react-bootstrap-datetimepicker
"
:
"
0.0.22
"
,
"
react-datalist
"
:
"
^3.0.0
"
,
"
react-dom
"
:
"
15.0.0
"
,
"
react-router
"
:
"
2.0.1
"
,
"
react-textarea-autosize
"
:
"
3.3.1
"
,
"
zimbra-admin-api-js
"
:
"
ZBoxApp/zimbra-admin-api-js#umd
"
"
react-dom
"
:
"
15.0.1
"
,
"
react-router
"
:
"
2.3.0
"
,
"
react-textarea-autosize
"
:
"
4.0.0
"
,
"
react-toastr
"
:
"
^2.6.0
"
,
"
toastr
"
:
"
^2.1.2
"
,
"
zimbra-admin-api-js
"
:
"
ZBoxApp/zimbra-admin-api-js#master
"
},
"devDependencies"
:
{
"
babel-cli
"
:
"
^6.7.5
"
,
"
babel-eslint
"
:
"
6.0.
2
"
,
"
babel-eslint
"
:
"
6.0.
4
"
,
"
babel-loader
"
:
"
6.2.4
"
,
"
babel-plugin-transform-runtime
"
:
"
6.7.5
"
,
"
babel-polyfill
"
:
"
6.7.4
"
,
"
babel-preset-es2015-webpack
"
:
"
6.4.
0
"
,
"
babel-preset-es2015-webpack
"
:
"
6.4.
1
"
,
"
babel-preset-react
"
:
"
6.5.0
"
,
"
babel-preset-stage-0
"
:
"
6.5.0
"
,
"
babel-runtime
"
:
"
^6.6.1
"
,
"
body-parser
"
:
"
^1.15.0
"
,
"
cookie-parser
"
:
"
^1.4.1
"
,
"
copy-webpack-plugin
"
:
"
1.1.1
"
,
"
copy-webpack-plugin
"
:
"
2.1.3
"
,
"
cors
"
:
"
^2.7.1
"
,
"
css-loader
"
:
"
0.23.1
"
,
"
debug
"
:
"
^2.2.0
"
,
"
eslint
"
:
"
2.
7
.0
"
,
"
eslint-plugin-react
"
:
"
4.3.0
"
,
"
eslint
"
:
"
2.
8
.0
"
,
"
eslint-plugin-react
"
:
"
5.0.1
"
,
"
exports-loader
"
:
"
0.6.3
"
,
"
express
"
:
"
^4.13.4
"
,
"
extract-text-webpack-plugin
"
:
"
1.0.1
"
,
...
...
@@ -50,9 +53,8 @@
"
http-proxy
"
:
"
^1.13.2
"
,
"
imports-loader
"
:
"
0.6.5
"
,
"
json-loader
"
:
"
0.5.4
"
,
"
lodash
"
:
"
^4.11.1
"
,
"
morgan
"
:
"
^1.7.0
"
,
"
node-sass
"
:
"
3.
4.2
"
,
"
node-sass
"
:
"
3.
6.0
"
,
"
raw-loader
"
:
"
0.5.1
"
,
"
sass-loader
"
:
"
3.2.0
"
,
"
style-loader
"
:
"
0.13.1
"
,
...
...
src/action_creators/global_actions.jsx
View file @
03047062
...
...
@@ -30,3 +30,11 @@ export function saveUser(user) {
user
});
}
export
function
showAlert
(
message
)
{
AppDispatcher
.
handleViewAction
({
type
:
ActionTypes
.
NEW_TOAST
,
message
});
}
src/components/accounts/accounts.jsx
deleted
100644 → 0
View file @
07deed30
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
$
from
'jquery'
;
import
React
from
'react'
;
import
{
browserHistory
}
from
'react-router'
;
import
PageInfo
from
'../page_info.jsx'
;
import
Panel
from
'../panel.jsx'
;
import
*
as
GlobalActions
from
'../../action_creators/global_actions.jsx'
;
export
default
class
Accounts
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{};
this
.
handleLink
=
this
.
handleLink
.
bind
(
this
);
}
componentDidMount
()
{
$
(
'#sidebar-accounts'
).
addClass
(
'active'
);
GlobalActions
.
emitEndLoading
();
}
componentWillUnmount
()
{
$
(
'#sidebar-accounts'
).
removeClass
(
'active'
);
}
handleLink
(
e
,
path
)
{
e
.
preventDefault
();
browserHistory
.
push
(
path
);
}
render
()
{
const
addAccountButton
=
[{
label
:
'Agregar Cuenta'
,
props
:
{
className
:
'btn btn-success'
,
onClick
:
(
e
)
=>
{
this
.
handleLink
(
e
,
'/accounts/new'
);
}
}
}];
const
panelBody
=
(
<
div
className=
'center-block text-center'
>
<
h5
>
{
'Sin resultados para su busqueda.'
}
</
h5
>
</
div
>
);
const
pageInfo
=
(
<
PageInfo
titlePage=
'Cuentas'
descriptionPage=
'Las cuentas son los que pagan el servicio'
/>
);
const
hasPageInfo
=
(
this
.
props
.
children
)
?
''
:
pageInfo
;
const
indexView
=
(
<
Panel
btnsHeader=
{
addAccountButton
}
children=
{
panelBody
}
/>
);
const
views
=
this
.
props
.
children
||
indexView
;
return
(
<
div
>
{
hasPageInfo
}
<
div
className=
'content animate-panel'
>
<
div
className=
'row'
>
<
div
className=
'col-md-12 central-content'
>
{
views
}
</
div
>
</
div
>
</
div
>
</
div
>
);
}
}
Accounts
.
propTypes
=
{
children
:
React
.
PropTypes
.
any
};
src/components/accounts/create_account.jsx
deleted
100644 → 0
View file @
07deed30
import
React
from
'react'
;
import
{
browserHistory
}
from
'react-router'
;
import
Panel
from
'../panel.jsx'
;
import
Button
from
'../button.jsx'
;
export
default
class
CreateAccount
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
handleClick
=
this
.
handleClick
.
bind
(
this
);
this
.
state
=
{
notification
:
false
,
notificationMsg
:
''
};
}
handleClick
(
e
,
path
)
{
e
.
preventDefault
();
browserHistory
.
push
(
path
);
}
render
()
{
let
form
=
(
<
form
className=
'simple_form form-horizontal mailbox-form'
>
<
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'
required=
'required'
className=
'form-control'
ref=
'companyName'
placeholder=
'Razón social de la empresa'
/>
</
div
>
</
div
>
<
div
className=
'form-group string'
>
<
label
className=
'string required col-sm-3 control-label'
>
<
abbr
title=
'requerido'
>
{
'*'
}
</
abbr
>
{
'ID Cliente'
}
</
label
>
<
div
className=
'col-sm-8'
>
<
input
type=
'text'
className=
'form-control select required'
required=
'required'
ref=
'idclient'
placeholder=
'Ingresa el RUT de la empresa (xxxxxxxx-y)'
>
</
input
>
</
div
>
</
div
>
<
div
className=
'form-group string'
>
<
label
className=
'string required col-sm-3 control-label'
>
{
'Reseller'
}
</
label
>
<
div
className=
'col-sm-8'
>
<
label
className=
'radio-inline pretty-input'
>
<
div
className=
'pretty-checkbox'
>
<
input
type=
'checkbox'
className=
'pretty'
ref=
'reseller'
/>
<
span
></
span
>
</
div
>
</
label
>
</
div
>
</
div
>
<
div
className=
'form-group'
>
<
div
className=
'col-sm-8 col-sm-offset-3'
>
<
input
type=
'submit'
name=
'commit'
defaulValue=
'Guardar'
className=
'btn btn-info'
/>
<
Button
btnAttrs=
{
{
className
:
'btn btn-default'
,
onClick
:
(
e
)
=>
{
this
.
handleClick
(
e
,
'/accounts'
);
}
}
}
>
{
'Cancelar'
}
</
Button
>
</
div
>
</
div
>
</
form
>
);
const
actions
=
[
{
label
:
'Cancelar'
,
props
:
{
className
:
'btn btn-default btn-xs'
,
onClick
:
(
e
)
=>
{
this
.
handleClick
(
e
,
'/accounts'
);
}
}
}
];
return
(
<
Panel
title=
{
'Agregar Cuenta'
}
btnsHeader=
{
actions
}
classHeader=
{
'forum-box'
}
>
{
form
}
</
Panel
>
);
}
}
src/components/accounts/edit_account.jsx
deleted
100644 → 0
View file @
07deed30
import
React
from
'react'
;
import
{
browserHistory
}
from
'react-router'
;
import
Panel
from
'../panel.jsx'
;
import
Button
from
'../button.jsx'
;
export
default
class
EditAccount
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
handleClick
=
this
.
handleClick
.
bind
(
this
);
this
.
state
=
{
notification
:
false
,
notificacionMsg
:
''
};
}
handleClick
(
e
,
path
)
{
e
.
preventDefault
();
browserHistory
.
push
(
path
);
}
render
()
{
let
form
=
(
<
form
className=
'simple_form form-horizontal mailbox-form'
>
<
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'
required=
'required'
className=
'form-control'
ref=
'companyName'
placeholder=
'Razón social de la empresa'
/>
</
div
>
</
div
>
<
div
className=
'form-group string'
>
<
label
className=
'string required col-sm-3 control-label'
>
<
abbr
title=
'requerido'
>
{
'*'
}
</
abbr
>
{
'ID Cliente'
}
</
label
>
<
div
className=
'col-sm-8'
>
<
input
type=
'text'
className=
'form-control select required'
required=
'required'
ref=
'idclient'
placeholder=
'Ingresa el RUT de la empresa (xxxxxxxx-y)'
>
</
input
>
</
div
>
</
div
>
<
div
className=
'form-group string'
>
<
label
className=
'string required col-sm-3 control-label'
>
{
'Reseller'
}
</
label
>
<
div
className=
'col-sm-8'
>
<
label
className=
'radio-inline pretty-input'
>
<
div
className=
'pretty-checkbox'
>
<
input
type=
'checkbox'
className=
'pretty'
ref=
'reseller'
/>
<
span
></
span
>
</
div
>
</
label
>
</
div
>
</
div
>
<
div
className=
'form-group'
>
<
div
className=
'col-sm-8 col-sm-offset-3'
>
<
input
type=
'submit'
name=
'commit'
defaulValue=
'Guardar'
className=
'btn btn-info'
/>
<
Button
btnAttrs=
{
{
className
:
'btn btn-default'
,
onClick
:
(
e
)
=>
{
this
.
handleClick
(
e
,
'/accounts'
);
}
}
}
>
{
'Cancelar'
}
</
Button
>
</
div
>
</
div
>
</
form
>
);
const
actions
=
[
{
label
:
'Cancelar'
,
props
:
{
className
:
'btn btn-default btn-xs'
,
onClick
:
(
e
)
=>
{
this
.
handleClick
(
e
,
'/accounts'
);
}
}
}
];
return
(
<
Panel
title=
{
'Editar Cuenta'
}
btnsHeader=
{
actions
}
classHeader=
{
'forum-box'
}
>
{
form
}
</
Panel
>
);
}
}
src/components/companies/companies.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
$
from
'jquery'
;
import
React
from
'react'
;
import
Promise
from
'bluebird'
;
import
PageInfo
from
'../page_info.jsx'
;
import
Panel
from
'../panel.jsx'
;
import
CompaniesStore
from
'../../stores/company_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
messageTypes
=
Constants
.
MessageType
;
export
default
class
Companies
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{};
this
.
getCompanies
=
this
.
getCompanies
.
bind
(
this
);
this
.
getDomains
=
this
.
getDomains
.
bind
(
this
);
this
.
getPlans
=
this
.
getPlans
.
bind
(
this
);
this
.
getAdmins
=
this
.
getAdmins
.
bind
(
this
);
this
.
gotoCompany
=
this
.
gotoCompany
.
bind
(
this
);
}
gotoCompany
(
e
,
company
)
{
CompaniesStore
.
setCurrent
(
company
);
Utils
.
handleLink
(
e
,
`/companies/
${
company
.
id
}
`
,
this
.
props
.
location
);
}
getCompanies
()
{
const
self
=
this
;
const
companies
=
CompaniesStore
.
getCompanies
();
if
(
companies
)
{
self
.
setState
({
companies
});
return
GlobalActions
.
emitEndLoading
();
}
return
Client
.
getAllCompanies
().
then
((
data
)
=>
{
const
domains
=
data
.
map
((
d
)
=>
{
return
self
.
getDomains
(
d
);
});
return
Promise
.
all
(
domains
).
then
((
comps
)
=>
{
CompaniesStore
.
setCompanies
(
comps
);
self
.
setState
({
companies
:
comps
});
}).
catch
((
error
)
=>
{
self
.
setState
({
error
:
{
message
:
error
,
type
:
messageTypes
.
ERROR
}});
});
}).
catch
((
error
)
=>
{
self
.
setState
({
error
});
}).
finally
(()
=>
{
GlobalActions
.
emitEndLoading
();
});
}
getDomains
(
company
)
{
const
self
=
this
;
return
new
Promise
((
resolve
,
reject
)
=>
{
return
Client
.
getAllDomains
(
{
query
:
`businessCategory=
${
company
.
id
}
`
},
(
data
)
=>
{
const
domains
=
data
.
domain
;
Promise
.
all
([
self
.
getPlans
(
domains
),
self
.
getAdmins
(
domains
)]).
then
(()
=>
{
company
.
domains
=
domains
;
resolve
(
company
);
}).
catch
((
error
)
=>
{
reject
(
error
);
});
},
(
error
)
=>
{
reject
(
error
);
});
});
}
getAdmins
(
domains
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
promises
=
domains
.
map
((
d
)
=>
{
return
new
Promise
((
solve
,
rej
)
=>
{
return
d
.
getAdmins
((
err
,
admins
)
=>
{
if
(
err
)
{
return
rej
(
err
);
}
d
.
admins
=
admins
;
return
solve
(
d
);
});
});
});
Promise
.
all
(
promises
).
then
((
doms
)
=>
{
resolve
(
doms
);
}).
catch
((
error
)
=>
{
reject
(
error
);
});
});
}
getPlans
(
domains
)
{
const
names
=
domains
.
map
((
d
)
=>
{
return
d
.
name
;
});
return
new
Promise
((
resolve
,
reject
)
=>
{
return
Client
.
batchCountAccount
(
names
,
(
data
)
=>
{
domains
.
forEach
((
d
,
i
)
=>
{
d
.
plans
=
data
[
i
];
});
resolve
(
domains
);
},
(
error
)
=>
{
reject
(
error
);
}
);
});
}
componentDidMount
()
{
$
(
'#sidebar-companies'
).
addClass
(
'active'
);
this
.
getCompanies
();
}
componentWillUnmount
()
{
$
(
'#sidebar-companies'
).
removeClass
(
'active'
);
}
render
()
{
if
(
!
this
.
state
.
companies
)
{
return
<
div
/>;
}
let
panelBody
;
if
(
this
.
state
.
companies
.
length
===
0
)
{
panelBody
=
(
<
div
className=
'center-block text-center'
>
<
h5
>
{
'Actualmente no hay ninguna empresa registrada '
}
<
label
style=
{
{
transform
:
'rotate(90deg)'
}
}
>
{
':=('
}
</
label
>
</
h5
>
</
div
>
);
}
else
{
const
rows
=
this
.
state
.
companies
.
map
((
c
)
=>
{
const
plans
=
Utils
.
getPlansFromDomains
(
c
.
domains
);
const
plansString
=
[];
const
totalBought
=
Object
.
keys
(
plans
).
reduce
((
prev
,
current
)
=>
{
const
limit
=
plans
[
current
].
limit
;
plansString
.
push
(
`
${
limit
}
${
Utils
.
titleCase
(
current
.
slice
(
0
,
3
))}
`
);
//eslint-disable-line no-undefined
if
(
plans
[
prev
])
{
return
plans
[
prev
].
limit
+
limit
;
}
return
limit
;
});
return
(
<
tr
key=
{
c
.
id
}
>
<
td
className=
'company-name'
>
<
a
href=
'#'
onClick=
{
(
e
)
=>
this
.
gotoCompany
(
e
,
c
)
}
>
{
c
.
name
}
</
a
>
<
br
/>
<
small
>
{
c
.
id
}
</
small
>
</
td
>
<
td
className=
'company-mbxs'
>
<
span
className=
'total-mbxs'
>
{
totalBought
}
</
span
>
<
br
/>
<
small
>
{
plansString
.
join
(
' | '
)
}
</
small
>
</
td
>
</
tr
>
);
});
panelBody
=
(
<
div
className=
'table-responsive'
>
<
div
className=
'table-responsive'
>
<
table
cellPadding=
'1'
cellSpacing=
'1'
className=
'table table-condensed table-striped vertical-align'
>
<
thead
>
<
tr
>
<
th
>
{
'Nombre'
}
</
th
>
<
th
className=
'text-center'
>
{
'Casillas compradas'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
rows
}
</
tbody
>
</
table
>
</
div
>
</
div
>
);
}
return
(
<
div
>
<
PageInfo
titlePage=
'Empresas'
descriptionPage=
'Las empresas son los que pagan el servicio'
/>
<
div
className=
'content animate-panel'
>
<
div
className=
'row'
>
<
div
className=
'col-md-12 central-content'
>
<
Panel
hasHeader=
{
false
}
children=
{
panelBody
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
);
}
}
Companies
.
propTypes
=
{
location
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/companies/company_admins.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
import
_
from
'lodash'
;
import
Panel
from
'../panel.jsx'
;
import
StatusLabel
from
'../status_label.jsx'
;
import
*
as
Utils
from
'../../utils/utils.jsx'
;
export
default
class
CompanyAdmins
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
getCompanyAdmins
=
this
.
getCompanyAdmins
.
bind
(
this
);
this
.
state
=
this
.
getCompanyAdmins
();
}
getCompanyAdmins
()
{
const
domains
=
this
.
props
.
company
.
domains
;
const
admins
=
[];
if
(
domains
)
{
domains
.
forEach
((
d
)
=>
{
Reflect
.
apply
(
Array
.
prototype
.
push
,
admins
,
d
.
admins
);
});
}
return
{
admins
:
_
.
uniqBy
(
admins
,
'id'
)
};
}
render
()
{
const
admins
=
this
.
state
.
admins
;
let
panelBody
;
if
(
admins
.
length
>
0
)
{
const
rows
=
admins
.
map
((
a
)
=>
{
let
globalAdmin
=
a
.
attrs
.
zimbraIsAdminAccount
===
'TRUE'
;
let
adminClass
=
''
;
if
(
globalAdmin
)
{
adminClass
=
'btn btn-xs btn-danger'
;
globalAdmin
=
'global admin'
;
}
else
{
adminClass
=
'btn btn-xs btn-info'
;
globalAdmin
=
'domain admin'
;
}
return
(
<
tr
key=
{
`admin-${a.id}`
}
className=
'user-row'
>
<
td
className=
'user-email'
>
{
a
.
name
}
</
td
>
<
td
className=
'user-name text-center'
>
{
a
.
attrs
.
cn
}
{
a
.
attrs
.
sn
}
</
td
>
<
td
className=
'user-type text-center'
>
<
StatusLabel
classes=
{
adminClass
}
children=
{
globalAdmin
}
/>
</
td
>
<
td
className=
'user-actions text-center'
>
<
a
className=
'btn btn-default btn-xs'
href=
'#'
onClick=
{
(
e
)
=>
Utils
.
handleLink
(
e
,
`/mailboxes/${a.id}/edit`
,
this
.
props
.
location
)
}
>
{
'Editar'
}
</
a
>
</
td
>
</
tr
>
);
});
panelBody
=
(
<
div
className=
'table-responsive'
>
<
table
cellPadding=
'1'
cellSpacing=
'1'
className=
'table table-condensed table-striped vertical-align'
>
<
thead
>
<
tr
>
<
th
>
{
'email'
}
</
th
>
<
th
className=
'td-mbxs text-center'
>
{
'Nombre'
}
</
th
>
<
th
className=
'text-center'
>
{
'Perfil'
}
</
th
>
<
th
className=
'text-center'
>
{
'Acciones'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
rows
}
</
tbody
>
</
table
>
</
div
>
);
}
else
{
panelBody
=
(
<
div
className=
'empty-message text-danger'
>
<
h4
>
{
'Esta empresa no tiene administradores de dominio registrados.'
}
</
h4
>
</
div
>
);
}
return
(
<
Panel
hasHeader=
{
false
}
children=
{
panelBody
}
/>
);
}
}
CompanyAdmins
.
propTypes
=
{
company
:
React
.
PropTypes
.
object
.
isRequired
,
location
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/companies/company_details.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
$
from
'jquery'
;
import
React
from
'react'
;
import
Promise
from
'bluebird'
;
import
CompanyInfo
from
'./company_info.jsx'
;
import
CompanyMailboxPlans
from
'./company_mailbox_plans.jsx'
;
import
CompanyDomains
from
'./company_domains.jsx'
;
import
CompanyAdmins
from
'./company_admins.jsx'
;
import
CompanyInvoices
from
'./company_invoices.jsx'
;
import
MessageBar
from
'../message_bar.jsx'
;
import
PageInfo
from
'../page_info.jsx'
;
import
PanelTab
from
'../panel_tab.jsx'
;
import
CompaniesStore
from
'../../stores/company_store.jsx'
;
import
*
as
Client
from
'../../utils/client.jsx'
;
import
*
as
GlobalActions
from
'../../action_creators/global_actions.jsx'
;
import
Constants
from
'../../utils/constants.jsx'
;
const
messageTypes
=
Constants
.
MessageType
;
export
default
class
CompaniesDetails
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{};
this
.
getCompany
=
this
.
getCompany
.
bind
(
this
);
this
.
getDomains
=
this
.
getDomains
.
bind
(
this
);
this
.
getAdmins
=
this
.
getAdmins
.
bind
(
this
);
this
.
getPlans
=
this
.
getPlans
.
bind
(
this
);
}
getCompany
()
{
const
self
=
this
;
const
companyId
=
this
.
props
.
params
.
id
;
const
company
=
CompaniesStore
.
getCurrent
();
if
(
company
)
{
self
.
setState
({
company
});
return
GlobalActions
.
emitEndLoading
();
}
return
Client
.
getCompany
(
companyId
).
then
((
data
)
=>
{
return
self
.
getDomains
(
data
).
then
((
comp
)
=>
{
CompaniesStore
.
setCurrent
(
comp
);
self
.
setState
({
company
:
comp
});
}).
catch
((
error
)
=>
{
self
.
setState
({
error
:
{
message
:
error
.
message
,
type
:
messageTypes
.
ERROR
}});
});
}).
catch
((
error
)
=>
{
self
.
setState
({
error
});
}).
finally
(()
=>
{
GlobalActions
.
emitEndLoading
();
});
}
getDomains
(
company
)
{
const
self
=
this
;
return
new
Promise
((
resolve
,
reject
)
=>
{
return
Client
.
getAllDomains
(
{
query
:
`businessCategory=
${
company
.
id
}
`
},
(
data
)
=>
{
const
domains
=
data
.
domain
;
Promise
.
all
([
self
.
getPlans
(
domains
),
self
.
getAdmins
(
domains
)]).
then
(()
=>
{
company
.
domains
=
domains
;
resolve
(
company
);
}).
catch
((
error
)
=>
{
reject
(
error
);
});
},
(
error
)
=>
{
reject
(
error
);
});
});
}
getAdmins
(
domains
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
promises
=
domains
.
map
((
d
)
=>
{
return
new
Promise
((
solve
,
rej
)
=>
{
return
d
.
getAdmins
((
err
,
admins
)
=>
{
if
(
err
)
{
return
rej
(
err
);
}
d
.
admins
=
admins
;
return
solve
(
d
);
});
});
});
Promise
.
all
(
promises
).
then
((
doms
)
=>
{
resolve
(
doms
);
}).
catch
((
error
)
=>
{
reject
(
error
);
});
});
}
getPlans
(
domains
)
{
const
names
=
domains
.
map
((
d
)
=>
{
return
d
.
name
;
});
return
new
Promise
((
resolve
,
reject
)
=>
{
return
Client
.
batchCountAccount
(
names
,
(
data
)
=>
{
domains
.
forEach
((
d
,
i
)
=>
{
d
.
plans
=
data
[
i
];
});
resolve
(
domains
);
},
(
error
)
=>
{
reject
(
error
);
}
);
});
}
componentDidMount
()
{
$
(
'#sidebar-companies'
).
addClass
(
'active'
);
this
.
getCompany
();
}
componentWillUnmount
()
{
$
(
'#sidebar-companies'
).
removeClass
(
'active'
);
}
render
()
{
const
company
=
this
.
state
.
company
;
if
(
!
company
)
{
return
<
div
/>;
}
let
message
;
if
(
this
.
state
.
error
)
{
message
=
(
<
MessageBar
message=
{
this
.
state
.
error
.
message
}
type=
{
this
.
state
.
error
.
type
||
messageTypes
.
ERROR
}
autoclose=
{
true
}
/>
);
}
const
tabAdmins
=
(
<
CompanyAdmins
company=
{
company
}
location=
{
this
.
props
.
location
}
/>
);
const
tabDomains
=
(
<
CompanyDomains
company=
{
company
}
location=
{
this
.
props
.
location
}
/>
);
const
panelTabs
=
(
<
PanelTab
tabNames=
{
[
'Administradores de dominio'
,
'Dominios'
]
}
tabs=
{
{
administradores_de_dominio
:
tabAdmins
,
dominios
:
tabDomains
}
}
location=
{
this
.
props
.
location
}
/>
);
return
(
<
div
>
<
PageInfo
titlePage=
{
`Empresa: ${company.name}`
}
descriptionPage=
'Las empresas son los que pagan el servicio'
/>
{
message
}
<
div
className=
'content animate-panel'
>
<
div
className=
'row'
>
<
div
className=
'col-md-6 central-content'
>
<
CompanyInfo
company=
{
company
}
/>
</
div
>
<
div
className=
'col-md-6 central-content'
>
<
CompanyMailboxPlans
company=
{
company
}
/>
</
div
>
</
div
>
<
div
className=
'row'
>
<
div
className=
'col-md-12 central-content'
>
{
panelTabs
}
</
div
>
</
div
>
<
div
className=
'row'
>
<
div
className=
'col-md-12 central-content'
>
<
CompanyInvoices
company=
{
company
}
location=
{
this
.
props
.
location
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
);
}
}
CompaniesDetails
.
propTypes
=
{
location
:
React
.
PropTypes
.
object
.
isRequired
,
params
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/companies/company_domains.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
import
UserStore
from
'../../stores/user_store.jsx'
;
import
Panel
from
'../panel.jsx'
;
import
StatusLabel
from
'../status_label.jsx'
;
import
*
as
Utils
from
'../../utils/utils.jsx'
;
export
default
class
CompanyDomains
extends
React
.
Component
{
render
()
{
const
domains
=
this
.
props
.
company
.
domains
;
const
isAdmin
=
UserStore
.
isGlobalAdmin
();
let
buttons
;
if
(
isAdmin
)
{
buttons
=
[{
label
:
'Agregar Dominio'
,
props
:
{
className
:
'btn btn-default btn-xs'
,
onClick
:
(
e
)
=>
Utils
.
handleLink
(
e
,
'/domains/new'
,
this
.
props
.
location
)
}
}];
}
let
panelBody
;
if
(
domains
.
length
>
0
)
{
const
rows
=
domains
.
map
((
d
)
=>
{
let
status
=
d
.
attrs
.
zimbraDomainStatus
;
let
statusClass
=
''
;
switch
(
status
)
{
case
'locked'
:
statusClass
=
'btn btn-xs btn-warning'
;
status
=
'Bloqueado'
;
break
;
case
'closed'
:
statusClass
=
'btn btn-xs btn-danger'
;
status
=
'Cerrado'
;
break
;
default
:
statusClass
=
'btn btn-xs btn-info'
;
status
=
'Activo'
;
break
;
}
let
totalAccounts
=
0
;
const
plans
=
Utils
.
getPlansFromDomain
(
d
);
const
plansArray
=
Object
.
keys
(
plans
).
map
((
p
)
=>
{
const
limit
=
plans
[
p
].
limit
;
totalAccounts
+=
limit
;
return
(
<
li
key=
{
`domain-${d.id}-${p}`
}
>
{
limit
}
{
Utils
.
titleCase
(
p
.
slice
(
0
,
3
))
}
</
li
>
);
});
return
(
<
tr
className=
'company-domain-row'
key=
{
`domain-${d.id}`
}
>
<
td
className=
'domain-name'
>
<
h4
>
<
a
href=
'#'
onClick=
{
(
e
)
=>
Utils
.
handleLink
(
e
,
`/domains/${d.id}`
,
this
.
props
.
location
)
}
>
{
`@${d.name}`
}
</
a
>
</
h4
>
</
td
>
<
td
className=
'company-domain-cell'
>
<
span
className=
'total-mbxs-per-domain'
>
{
totalAccounts
}
</
span
>
<
ul
className=
'list-inline'
>
{
plansArray
}
</
ul
>
</
td
>
<
td
className=
'company-domain-cell'
>
{
d
.
attrs
.
description
}
</
td
>
<
td
className=
'company-domain-cell'
>
<
StatusLabel
classes=
{
statusClass
}
children=
{
status
}
/>
</
td
>
</
tr
>
);
});
panelBody
=
(
<
div
className=
'table-responsive'
>
<
table
cellPadding=
'1'
cellSpacing=
'1'
className=
'table table-condensed table-striped vertical-align'
>
<
thead
>
<
tr
>
<
th
>
{
'Nombre'
}
</
th
>
<
th
className=
'td-mbxs text-center'
>
{
'Casillas'
}
</
th
>
<
th
className=
'text-center'
>
{
'Descripción'
}
</
th
>
<
th
className=
'text-center'
>
{
'Estado'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
rows
}
</
tbody
>
</
table
>
</
div
>
);
}
else
{
panelBody
=
(
<
div
className=
'empty-message text-danger'
>
<
h4
>
{
'Esta empresa no tiene dominios registrados.'
}
</
h4
>
</
div
>
);
}
return
(
<
Panel
btnsHeader=
{
buttons
}
children=
{
panelBody
}
/>
);
}
}
CompanyDomains
.
propTypes
=
{
company
:
React
.
PropTypes
.
object
.
isRequired
,
location
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/companies/company_info.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
import
Panel
from
'../panel.jsx'
;
export
default
class
CompanyInfo
extends
React
.
Component
{
render
()
{
const
company
=
this
.
props
.
company
;
const
infoBody
=
(
<
div
className=
'account-info'
>
<
h4
>
{
company
.
name
}
<
br
/>
<
small
>
{
company
.
id
}
</
small
>
</
h4
>
<
p
>
<
br
/><
br
/><
br
/><
br
/>
</
p
>
</
div
>
);
return
(
<
Panel
title=
'Información General'
children=
{
infoBody
}
/>
);
}
}
CompanyInfo
.
propTypes
=
{
company
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/companies/company_invoices.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
import
moment
from
'moment'
;
import
_
from
'lodash'
;
import
MessageBar
from
'../message_bar.jsx'
;
import
Panel
from
'../panel.jsx'
;
import
StatusLabel
from
'../status_label.jsx'
;
import
*
as
Client
from
'../../utils/client.jsx'
;
import
*
as
GlobalActions
from
'../../action_creators/global_actions.jsx'
;
import
Constants
from
'../../utils/constants.jsx'
;
const
messageType
=
Constants
.
MessageType
;
export
default
class
CompanyInvoices
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
getInvoices
=
this
.
getInvoices
.
bind
(
this
);
this
.
state
=
{};
}
componentDidMount
()
{
this
.
getInvoices
();
}
getInvoices
()
{
if
(
global
.
window
.
manager_config
.
companiesEndPoints
.
invoices
)
{
return
Client
.
getInvoices
(
this
.
props
.
company
.
id
,
(
invoices
)
=>
{
const
hasDebt
=
_
.
find
(
invoices
,
{
status
:
2
});
if
(
hasDebt
)
{
GlobalActions
.
showAlert
({
type
:
'error'
,
title
:
'Cuenta con deuda'
,
body
:
'Tiene una o más facturas impagas. Por favor corrija esta situación para prevenir un bloqueo de los servicios'
,
options
:
{
timeOut
:
10000
,
extendedTimeOut
:
5000
,
closeButton
:
true
}
});
}
this
.
setState
({
invoices
});
},
(
error
)
=>
{
this
.
setState
({
error
:
{
message
:
error
.
message
,
type
:
messageType
.
ERROR
}
});
}
);
}
return
this
.
setState
({
error
:
{
message
:
'No se ha configurado la integración con el sistema de facturación.'
,
type
:
messageType
.
WARNING
}
});
}
render
()
{
const
invoices
=
this
.
state
.
invoices
;
const
error
=
this
.
state
.
error
;
let
errorMessage
;
if
(
error
)
{
errorMessage
=
(
<
MessageBar
message=
{
error
.
message
}
type=
{
error
.
type
||
messageType
.
ERROR
}
canClose=
{
false
}
/>
);
}
let
panelBody
;
if
(
invoices
)
{
if
(
invoices
.
length
>
0
)
{
const
rows
=
invoices
.
map
((
i
)
=>
{
let
status
;
let
statusClass
=
''
;
let
number
=
i
.
number
;
if
(
i
.
link
)
{
number
=
(
<
a
href=
{
i
.
link
}
target=
'_blank'
>
{
i
.
number
}
</
a
>
);
}
switch
(
i
.
status
)
{
case
0
:
status
=
'Pendiente'
;
statusClass
=
'btn btn-xs btn-info'
;
break
;
case
1
:
status
=
'Pagada'
;
statusClass
=
'btn btn-xs btn-success'
;
break
;
case
2
:
status
=
'Vencida'
;
statusClass
=
'btn btn-xs btn-danger'
;
break
;
default
:
status
=
'Anulada'
;
statusClass
=
'btn btn-xs btn-default'
;
break
;
}
return
(
<
tr
key=
{
`invoice-${i.number}`
}
>
<
td
>
{
number
}
</
td
>
<
td
className=
'text-center'
>
{
i
.
total
}
</
td
>
<
td
className=
'text-center'
>
{
moment
(
i
.
date
).
locale
(
'es'
).
format
(
'DD [de] MMMM [de] YYYY'
)
}
</
td
>
<
td
className=
'text-center'
>
<
StatusLabel
classes=
{
statusClass
}
children=
{
status
}
/>
</
td
>
</
tr
>
);
});
panelBody
=
(
<
div
className=
'table-responsive'
>
<
table
cellPadding=
'1'
cellSpacing=
'1'
className=
'table table-condensed table-striped vertical-align'
>
<
thead
>
<
tr
>
<
th
>
{
'Número'
}
</
th
>
<
th
className=
'text-center'
>
{
'Total'
}
</
th
>
<
th
className=
'text-center'
>
{
'Fecha'
}
</
th
>
<
th
className=
'text-center'
>
{
'Estado'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
rows
}
</
tbody
>
</
table
>
</
div
>
);
}
else
{
errorMessage
=
(
<
MessageBar
message=
'Esta empresa todavía no tiene facturas emitidas.'
type=
{
messageType
.
INFO
}
canClose=
{
false
}
/>
);
}
}
if
(
error
||
invoices
)
{
return
(
<
Panel
title=
'Facturas'
error=
{
errorMessage
}
children=
{
panelBody
}
/>
);
}
return
<
div
/>;
}
}
CompanyInvoices
.
propTypes
=
{
company
:
React
.
PropTypes
.
object
.
isRequired
,
location
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/companies/company_mailbox_plans.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
import
Panel
from
'../panel.jsx'
;
import
*
as
Utils
from
'../../utils/utils.jsx'
;
export
default
class
CompanyMailboxPlans
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
handleBuy
=
this
.
handleBuy
.
bind
(
this
);
}
handleBuy
(
e
)
{
e
.
preventDefault
();
alert
(
'llevar al usuario a la página que permita comprar más casillas'
);
//eslint-disable-line no-alert
}
render
()
{
const
company
=
this
.
props
.
company
;
const
headerButtons
=
[
{
label
:
'Comprar'
,
props
:
{
className
:
'btn btn-info btn-xs'
,
onClick
:
this
.
handleBuy
}
}
];
const
mailboxPlans
=
[];
const
domains
=
company
.
domains
;
const
plans
=
Utils
.
getPlansFromDomains
(
domains
);
for
(
const
key
in
plans
)
{
if
(
plans
.
hasOwnProperty
(
key
))
{
let
freeClass
=
'text-center'
;
let
percent
=
0
;
let
limit
=
0
;
let
used
=
0
;
let
free
=
0
;
const
plan
=
plans
[
key
];
limit
=
plan
.
limit
;
used
=
plan
.
used
;
if
(
limit
)
{
free
=
limit
-
used
;
percent
=
Math
.
round
((
used
*
100
)
/
limit
);
}
else
{
limit
=
free
=
'
\
u221e'
;
percent
=
100
;
}
if
(
percent
<=
10
)
{
freeClass
+=
' alert-free-mbxs'
;
}
else
if
(
percent
<=
20
)
{
freeClass
+=
' warning-free-mbxs'
;
}
mailboxPlans
.
push
(
<
tr
key=
{
`plan-${key}`
}
>
<
td
className=
'mbx-plan'
style=
{
{
borderTop
:
0
}
}
>
{
key
}
</
td
>
<
td
className=
'text-center'
style=
{
{
borderTop
:
0
}
}
>
{
limit
}
</
td
>
<
td
className=
'text-center'
style=
{
{
borderTop
:
0
}
}
>
{
used
}
</
td
>
<
td
className=
{
freeClass
}
style=
{
{
borderTop
:
0
}
}
>
{
free
}
</
td
>
</
tr
>
);
}
}
const
panelBody
=
(
<
table
id=
'company-mbxs'
cellPadding=
'1'
cellSpacing=
'1'
className=
'table'
style=
{
{
marginBottom
:
'0px'
}
}
>
<
thead
>
<
tr
>
<
th
style=
{
{
width
:
'50%'
}
}
></
th
>
<
th
className=
'text-center'
>
{
'Límite'
}
</
th
>
<
th
className=
'text-center'
>
{
'Usadas'
}
</
th
>
<
th
className=
'text-center'
>
{
'Libres'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
mailboxPlans
}
</
tbody
>
</
table
>
);
return
(
<
Panel
title=
'Casillas'
btnsHeader=
{
headerButtons
}
children=
{
panelBody
}
/>
);
}
}
CompanyMailboxPlans
.
propTypes
=
{
company
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/domain/domain_admin_list.jsx
View file @
03047062
...
...
@@ -9,7 +9,6 @@ import Panel from '../panel.jsx';
import
ToggleModalButton
from
'../toggle_modal_button.jsx'
;
import
AddAdminModal
from
'./add_admin_modal.jsx'
;
// import * as Client from '../../utils/client.jsx';
import
*
as
Utils
from
'../../utils/utils.jsx'
;
export
default
class
DomainAdminList
extends
React
.
Component
{
...
...
src/components/domain/domain_general_info.jsx
View file @
03047062
...
...
@@ -7,15 +7,20 @@ import moment from 'moment';
import
Panel
from
'../panel.jsx'
;
import
StatusLabel
from
'../status_label.jsx'
;
import
{
getDnsInfo
}
from
'../../utils/client.jsx'
;
import
CompanyStore
from
'../../stores/company_store.jsx'
;
import
*
as
Client
from
'../../utils/client.jsx'
;
import
*
as
Utils
from
'../../utils/utils.jsx'
;
import
Constant
from
'../../utils/constants.jsx'
;
export
default
class
DomainGeneralInfo
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
getMXRecord
=
this
.
getMXRecord
.
bind
(
this
);
this
.
renovationDate
=
this
.
renovationDate
.
bind
(
this
);
this
.
getCompany
=
this
.
getCompany
.
bind
(
this
);
this
.
state
=
{
mx
:
null
,
...
...
@@ -23,23 +28,50 @@ export default class DomainGeneralInfo extends React.Component {
};
}
componentWillMount
()
{
this
.
getMXRecord
();
const
domain
=
this
.
props
.
domain
;
this
.
getMXRecord
(
domain
.
name
);
this
.
getCompany
(
domain
.
attrs
.
businessCategory
);
}
getMXRecord
()
{
getDnsInfo
(
this
.
props
.
domain
.
name
,
getMXRecord
(
name
)
{
const
self
=
this
;
Client
.
getDnsInfo
(
name
,
(
data
)
=>
{
this
.
setState
({
self
.
setState
({
mx
:
data
.
mx
});
},
(
err
)
=>
{
this
.
setState
({
self
.
setState
({
mx
:
err
});
}
);
}
getCompany
(
id
)
{
const
company
=
CompanyStore
.
getCompanyById
(
id
);
if
(
company
)
{
this
.
setState
({
company
:
company
.
name
});
}
else
{
Client
.
getCompany
(
id
).
then
((
data
)
=>
{
this
.
setState
({
company
:
data
.
name
});
}).
catch
((
error
)
=>
{
this
.
setState
({
error
:
{
message
:
error
.
message
,
type
:
Constant
.
MessageType
.
ERROR
}
});
});
}
}
renovationDate
()
{
const
timestamp
=
moment
(
this
.
props
.
domain
.
attrs
.
zimbraCreateTimestamp
);
const
now
=
moment
();
...
...
@@ -69,7 +101,7 @@ export default class DomainGeneralInfo extends React.Component {
className=
'account-name'
onClick=
{
(
e
)
=>
Utils
.
handleLink
(
e
,
`/accounts/${domain.id_empresa}`
,
this
.
props
.
location
)
}
>
{
'Nombre de la Empresa'
}
{
this
.
state
.
company
}
</
a
>
</
p
>
<
ul
className=
'list-unstyled'
>
...
...
src/components/domain/domain_mailbox_plans.jsx
View file @
03047062
...
...
@@ -127,8 +127,8 @@ export default class DomainMailboxPlans extends React.Component {
<
thead
>
<
tr
>
<
th
style=
{
{
width
:
'50%'
}
}
></
th
>
<
th
className=
'text-center'
>
Límite
</
th
>
<
th
className=
'text-center'
>
Usadas
</
th
>
<
th
className=
'text-center'
>
{
'Límite'
}
</
th
>
<
th
className=
'text-center'
>
{
'Usadas'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
...
...
src/components/domain/domains.jsx
View file @
03047062
...
...
@@ -18,6 +18,7 @@ import * as GlobalActions from '../../action_creators/global_actions.jsx';
import
Constants
from
'../../utils/constants.jsx'
;
const
QueryOptions
=
Constants
.
QueryOptions
;
const
messageType
=
Constants
.
MessageType
;
export
default
class
Domains
extends
React
.
Component
{
constructor
(
props
)
{
...
...
@@ -36,7 +37,7 @@ export default class Domains extends React.Component {
const
self
=
this
;
Client
.
getAllDomains
(
{
limit
:
QueryOptions
.
DEFAULT_LIMIT
,
limit
:
200
,
offset
:
this
.
state
.
offset
},
(
data
)
=>
{
...
...
@@ -109,7 +110,7 @@ export default class Domains extends React.Component {
message
=
(
<
MessageBar
message=
{
this
.
state
.
error
}
type=
'success'
type=
{
messageType
.
WARNING
}
autoclose=
{
true
}
/>
);
...
...
src/components/logged_in.jsx
View file @
03047062
...
...
@@ -4,6 +4,7 @@
import
LoadingScreen
from
'./loading_screen.jsx'
;
import
Header
from
'./header.jsx'
;
import
Sidebar
from
'./sidebar.jsx'
;
import
ToastAlert
from
'./toast_alert.jsx'
;
import
React
from
'react'
;
...
...
@@ -11,6 +12,7 @@ export default class LoggedIn extends React.Component {
render
()
{
return
(
<
div
>
<
ToastAlert
/>
<
LoadingScreen
/>
<
Header
/>
<
Sidebar
location=
{
this
.
props
.
location
}
/>
...
...
src/components/login/login.jsx
View file @
03047062
...
...
@@ -13,6 +13,8 @@ import Panel from '../panel.jsx';
import
LoginEmail
from
'./login_email.jsx'
;
import
MessageBar
from
'../message_bar.jsx'
;
const
messageTypes
=
Constants
.
MessageType
;
export
default
class
Login
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
...
...
@@ -30,7 +32,7 @@ export default class Login extends React.Component {
componentDidMount
()
{
Client
.
isLoggedIn
((
data
)
=>
{
if
(
data
&&
data
.
logged_in
)
{
browserHistory
.
push
(
'/
account
s'
);
browserHistory
.
push
(
'/
companie
s'
);
}
else
{
$
(
'body'
).
addClass
(
'blank'
);
}
...
...
@@ -42,7 +44,7 @@ export default class Login extends React.Component {
this
.
setState
({
user
});
if
(
user
)
{
browserHistory
.
push
(
'/
account
s'
);
browserHistory
.
push
(
'/
companie
s'
);
}
}
submit
(
email
,
password
)
{
...
...
@@ -64,7 +66,7 @@ export default class Login extends React.Component {
Client
.
login
(
email
,
password
,
()
=>
{
browserHistory
.
push
(
'/
account
s'
);
browserHistory
.
push
(
'/
companie
s'
);
},
(
err
)
=>
{
this
.
setState
({
loginError
:
err
.
message
});
...
...
@@ -81,7 +83,7 @@ export default class Login extends React.Component {
loginError
=
(
<
MessageBar
message=
{
this
.
state
.
loginError
}
type=
'error'
type=
{
messageTypes
.
ERROR
}
position=
'relative'
canClose=
{
false
}
/>
...
...
@@ -90,7 +92,7 @@ export default class Login extends React.Component {
loginError
=
(
<
MessageBar
message=
'Tu sesión a expirado. Por favor ingresa nuevamente.'
type=
'info'
type=
{
messageTypes
.
INFO
}
position=
'relative'
canClose=
{
false
}
/>
...
...
@@ -99,7 +101,7 @@ export default class Login extends React.Component {
loginError
=
(
<
MessageBar
message=
'Necesitas iniciar sesión o registrarte para continuar.'
type=
'error'
type=
{
messageTypes
.
ERROR
}
position=
'relative'
canClose=
{
false
}
/>
...
...
src/components/mailbox/create_mailbox.jsx
View file @
03047062
...
...
@@ -8,6 +8,10 @@ import * as GlobalActions from '../../action_creators/global_actions.jsx';
import
*
as
Client
from
'../../utils/client.jsx'
;
import
*
as
Utils
from
'../../utils/utils.jsx'
;
import
Constants
from
'../../utils/constants.jsx'
;
const
messageType
=
Constants
.
MessageType
;
export
default
class
CreateMailBox
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
...
...
@@ -37,7 +41,7 @@ export default class CreateMailBox extends React.Component {
this
.
setState
(
{
error
:
`Su cuenta
${
data
.
name
}
ha sido creada con èxito.`
,
typeError
:
'success'
typeError
:
messageType
.
SUCCESS
}
);
},
...
...
@@ -45,7 +49,7 @@ export default class CreateMailBox extends React.Component {
this
.
setState
(
{
error
:
error
.
message
,
typeError
:
'warning'
typeError
:
messageType
.
WARNING
}
);
}
...
...
src/components/mailbox/edit_mailbox.jsx
View file @
03047062
...
...
@@ -11,6 +11,10 @@ import * as Client from '../../utils/client.jsx';
import
*
as
GlobalActions
from
'../../action_creators/global_actions.jsx'
;
import
*
as
Utils
from
'../../utils/utils.jsx'
;
import
Constants
from
'../../utils/constants.jsx'
;
const
messageType
=
Constants
.
MessageType
;
export
default
class
EditMailBox
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
...
...
@@ -45,7 +49,7 @@ export default class EditMailBox extends React.Component {
this
.
setState
(
{
error
:
`Su cuenta
${
data
.
name
}
ha sido modificada con èxito.`
,
typeError
:
'success'
,
typeError
:
messageType
.
SUCCESS
,
data
:
data
}
);
...
...
@@ -54,7 +58,7 @@ export default class EditMailBox extends React.Component {
this
.
setState
(
{
error
:
error
.
message
,
typeError
:
'warning'
typeError
:
messageType
.
WARNING
}
);
Utils
.
toggleStatusButtons
(
'.action-button'
,
false
);
...
...
src/components/mailbox/mailbox.jsx
View file @
03047062
...
...
@@ -21,6 +21,7 @@ import Constants from '../../utils/constants.jsx';
import
DomainStore
from
'../../stores/domain_store.jsx'
;
const
QueryOptions
=
Constants
.
QueryOptions
;
const
messageType
=
Constants
.
MessageType
;
export
default
class
Mailboxes
extends
React
.
Component
{
constructor
(
props
)
{
...
...
@@ -159,7 +160,7 @@ export default class Mailboxes extends React.Component {
message
=
(
<
MessageBar
message=
{
this
.
state
.
error
}
type=
'success'
type=
{
messageType
.
SUCCESS
}
autoclose=
{
true
}
/>
);
...
...
src/components/message_bar.jsx
View file @
03047062
...
...
@@ -4,6 +4,10 @@
import
$
from
'jquery'
;
import
React
from
'react'
;
import
Constants
from
'../utils/constants.jsx'
;
const
messageType
=
Constants
.
MessageType
;
export
default
class
MessageBar
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
...
...
@@ -60,18 +64,20 @@ export default class MessageBar extends React.Component {
);
}
const
alertClass
=
`alert flash-
${
this
.
props
.
type
}
${
dismissible
}
`
;
const
alertClass
=
`alert flash-
${
this
.
props
.
type
.
toLowerCase
()
}
${
dismissible
}
`
;
let
icon
;
switch
(
this
.
props
.
type
)
{
case
'error'
:
case
messageType
.
ERROR
:
icon
=
(<
i
className=
'fa fa-exclamation-circle'
></
i
>);
break
;
case
'info'
:
case
messageType
.
INFO
:
icon
=
(<
i
className=
'fa fa-info-circle'
></
i
>);
break
;
case
'success'
:
case
messageType
.
SUCCESS
:
icon
=
(<
i
className=
'fa fa-check-circle'
></
i
>);
break
;
case
'warning'
:
case
messageType
.
WARNING
:
icon
=
(<
i
className=
'fa fa-exclamation-triangle'
></
i
>);
break
;
}
...
...
@@ -106,7 +112,7 @@ MessageBar.defaultProps = {
MessageBar
.
propTypes
=
{
message
:
React
.
PropTypes
.
string
.
isRequired
,
type
:
React
.
PropTypes
.
oneOf
([
'
success'
,
'error'
,
'warning'
,
'info
'
]),
type
:
React
.
PropTypes
.
oneOf
([
'
SUCCESS'
,
'ERROR'
,
'WARNING'
,
'INFO
'
]),
position
:
React
.
PropTypes
.
oneOf
([
'absolute'
,
'fixed'
,
'relative'
,
'static'
,
'inherit'
]),
canClose
:
React
.
PropTypes
.
bool
,
autoclose
:
React
.
PropTypes
.
bool
,
...
...
src/components/root.jsx
View file @
03047062
...
...
@@ -21,7 +21,7 @@ export default class Root extends React.Component {
if
(
!
data
||
!
data
.
logged_in
)
{
browserHistory
.
push
(
'/login'
);
}
else
{
browserHistory
.
push
(
'/
account
s'
);
browserHistory
.
push
(
'/
companie
s'
);
}
});
}
...
...
src/components/sidebar_menu.jsx
View file @
03047062
...
...
@@ -32,12 +32,12 @@ export default class SidebarMenu extends React.Component {
<
span
className=
'nav-label'
>
{
'dashboards'
}
</
span
>
</
a
>
</
li
>
<
li
id=
'sidebar-
account
s'
>
<
li
id=
'sidebar-
companie
s'
>
<
a
href=
'#'
onClick=
{
(
e
)
=>
this
.
handleLink
(
e
,
'/
account
s'
)
}
onClick=
{
(
e
)
=>
this
.
handleLink
(
e
,
'/
companie
s'
)
}
>
<
span
className=
'nav-label'
>
{
'
cuent
as'
}
</
span
>
<
span
className=
'nav-label'
>
{
'
Empres
as'
}
</
span
>
</
a
>
</
li
>
<
li
id=
'sidebar-domains'
>
...
...
src/components/toast_alert.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
import
{
ToastContainer
,
ToastMessage
}
from
'react-toastr'
;
import
EventStore
from
'../stores/event_store.jsx'
;
const
ToastMessageFactory
=
React
.
createFactory
(
ToastMessage
.
animation
);
export
default
class
ToastAlert
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
addAlert
=
this
.
addAlert
.
bind
(
this
);
}
componentDidMount
()
{
EventStore
.
addToastListener
(
this
.
addAlert
);
}
componentWillUnmount
()
{
EventStore
.
removeToastListener
(
this
.
addAlert
);
}
addAlert
(
message
)
{
this
.
refs
.
alertContainer
[
message
.
type
](
message
.
body
,
message
.
title
,
message
.
options
);
}
render
()
{
return
(
<
div
>
<
ToastContainer
ref=
'alertContainer'
toastMessageFactory=
{
ToastMessageFactory
}
className=
'toast-top-center'
/>
</
div
>
);
}
}
src/config/config.json
View file @
03047062
{
"debug"
:
fals
e
,
"debug"
:
tru
e
,
"zimbraUrl"
:
"http://zimbra.zboxapp.dev:8000/service/admin/soap"
,
"zimbraProxy"
:
"https://zimbra.zboxapp.dev:7071"
,
"dnsApiUrl"
:
"http://zimbra.zboxapp.dev:3000"
,
...
...
@@ -8,5 +8,10 @@
"premium"
:
true
,
"professional"
:
true
,
"default"
:
false
},
"companiesEndPoints"
:
{
"list"
:
"http://zimbra.zboxapp.dev:8001/list"
,
"detail"
:
"http://zimbra.zboxapp.dev:8001/company/{id}"
,
"invoices"
:
"http://zimbra.zboxapp.dev:8001/company/{id}/invoices"
}
}
src/index.jsx
View file @
03047062
...
...
@@ -10,9 +10,8 @@ import ErrorPage from './components/error_page.jsx';
import
LoggedIn
from
'./components/logged_in.jsx'
;
import
NotLoggedIn
from
'./components/not_logged_in.jsx'
;
import
Login
from
'./components/login/login.jsx'
;
import
Accounts
from
'./components/accounts/accounts.jsx'
;
import
CreateAccount
from
'./components/accounts/create_account.jsx'
;
import
EditAccount
from
'./components/accounts/edit_account.jsx'
;
import
Companies
from
'./components/companies/companies.jsx'
;
import
Company
from
'./components/companies/company_details.jsx'
;
import
Domains
from
'./components/domain/domains.jsx'
;
import
DomainDetails
from
'./components/domain/domain_details.jsx'
;
import
CreateDomains
from
'./components/domain/create_domain.jsx'
;
...
...
@@ -139,19 +138,13 @@ function renderRootComponent() {
/>
<
Route
path=
'accounts'
component=
{
Accounts
}
>
<
Route
path=
'new'
component=
{
CreateAccount
}
/>
<
Route
path=
':id/edit'
component=
{
EditAccount
}
/>
</
Route
>
path=
'companies'
component=
{
Companies
}
/>
<
Route
path=
'companies/:id'
component=
{
Company
}
/>
<
Route
path=
'mailboxes'
...
...
src/sass/routes/_companies.scss
0 → 100644
View file @
03047062
.company-name
{
a
{
color
:
$color-green
;
font-size
:
16px
;
font-weight
:
bold
;
}
}
.company-mbxs
{
text-align
:
center
;
.total-mbxs
{
font-size
:
16px
;
font-weight
:
bold
;
}
}
table
{
.alert-free-mbxs
{
background
:
$color-red-deep
;
color
:
$white
;
}
.warning-free-mbxs
{
background
:
$color-orange
;
color
:
$white
;
}
.company-domain-row
{
.company-domain-cell
{
padding
:
0
20px
;
text-align
:
center
;
vertical-align
:
middle
;
}
}
}
src/sass/routes/_module.scss
View file @
03047062
@import
'landing'
;
@import
'login'
;
@import
'domain'
;
@import
'companies'
;
src/sass/styles.scss
View file @
03047062
...
...
@@ -8,6 +8,8 @@
@import
'~perfect-scrollbar/dist/css/perfect-scrollbar.css'
;
@import
'~font-awesome/css/font-awesome.css'
;
@import
'~nprogress/nprogress.css'
;
@import
'~toastr/build/toastr.css'
;
@import
'~animate.css'
;
// styles.scss
@import
'utils/module'
;
@import
'layout/module'
;
...
...
src/stores/company_store.jsx
0 → 100644
View file @
03047062
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
class
CompanyStoreClass
{
constructor
()
{
this
.
current
=
null
;
this
.
companies
=
null
;
}
getCompanies
()
{
const
array
=
[];
const
companies
=
this
.
companies
;
if
(
!
companies
)
{
return
null
;
}
for
(
const
id
in
companies
)
{
if
(
companies
.
hasOwnProperty
(
id
))
{
array
.
push
(
companies
[
id
]);
}
}
return
array
;
}
getCompanyById
(
id
)
{
if
(
!
this
.
companies
)
{
return
null
;
}
return
this
.
companies
[
id
];
}
getCurrent
()
{
return
this
.
current
;
}
setCompanies
(
companiesArray
)
{
const
companies
=
{};
companiesArray
.
forEach
((
c
)
=>
{
companies
[
c
.
id
]
=
c
;
});
this
.
companies
=
companies
;
}
setCurrent
(
company
)
{
this
.
current
=
company
;
}
}
const
CompanyStore
=
new
CompanyStoreClass
();
export
{
CompanyStore
as
default
};
src/stores/event_store.jsx
View file @
03047062
...
...
@@ -44,6 +44,18 @@ class EventStoreClass extends EventEmitter {
removeMessageListener
(
callback
)
{
this
.
removeListener
(
eventTypes
.
NEW_MESSAGE_EVENT
,
callback
);
}
emitToast
(
message
)
{
this
.
emit
(
eventTypes
.
NEW_TOAST_EVENT
,
message
);
}
addToastListener
(
callback
)
{
this
.
on
(
eventTypes
.
NEW_TOAST_EVENT
,
callback
);
}
removeToastListener
(
callback
)
{
this
.
removeListener
(
eventTypes
.
NEW_TOAST_EVENT
,
callback
);
}
}
var
EventStore
=
new
EventStoreClass
();
...
...
@@ -62,6 +74,9 @@ EventStore.dispatchToken = AppDispatcher.register((payload) => {
case
ActionTypes
.
NEW_MESSAGE
:
EventStore
.
emitMessage
(
action
.
attrs
);
break
;
case
ActionTypes
.
NEW_TOAST
:
EventStore
.
emitToast
(
action
.
message
);
break
;
default
:
}
});
...
...
src/stores/user_store.jsx
View file @
03047062
...
...
@@ -23,7 +23,7 @@ class UserStoreClass extends EventEmitter {
}
getCurrentId
()
{
var
user
=
this
.
getCurrentUser
();
const
user
=
this
.
getCurrentUser
();
if
(
user
)
{
return
user
.
id
;
...
...
@@ -32,6 +32,16 @@ class UserStoreClass extends EventEmitter {
return
null
;
}
isGlobalAdmin
()
{
const
user
=
this
.
getCurrentUser
();
if
(
user
)
{
return
user
.
attrs
.
_attrs
.
zimbraIsAdminAccount
===
'TRUE'
;
//eslint-disable-line no-underscore-dangle
}
return
false
;
}
emitChange
()
{
this
.
emit
(
eventTypes
.
USER_CHANGE_EVENT
);
}
...
...
src/utils/client.jsx
View file @
03047062
...
...
@@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import
$
from
'jquery'
;
import
Promise
from
'bluebird'
;
import
ZimbraAdminApi
from
'zimbra-admin-api-js'
;
import
ZimbraStore
from
'../stores/zimbra_store.jsx'
;
...
...
@@ -23,7 +24,10 @@ function handleError(methodName, err) {
console
.
error
(
methodName
,
err
);
//eslint-disable-line no-console
const
error
=
{};
const
error
=
{
type
:
Constants
.
MessageType
.
ERROR
};
if
(
err
)
{
error
.
message
=
err
.
extra
.
reason
;
}
else
{
...
...
@@ -141,6 +145,53 @@ export function isLoggedIn(callback) {
return
callback
(
data
);
}
export
function
getAllCompanies
()
{
const
url
=
global
.
window
.
manager_config
.
companiesEndPoints
.
list
;
return
new
Promise
((
resolve
,
reject
)
=>
{
return
$
.
ajax
({
url
,
dataType
:
'json'
,
success
:
function
onSuccess
(
data
)
{
resolve
(
data
);
},
error
:
function
onError
(
xhr
,
status
,
err
)
{
reject
(
err
);
}
});
});
}
export
function
getCompany
(
id
)
{
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
);
},
error
:
function
onError
(
xhr
,
status
,
err
)
{
reject
(
err
);
}
});
});
}
export
function
getInvoices
(
id
,
success
,
error
)
{
const
url
=
global
.
window
.
manager_config
.
companiesEndPoints
.
invoices
.
replace
(
'{id}'
,
id
);
return
$
.
ajax
({
url
,
dataType
:
'json'
,
success
,
error
:
function
onError
(
xhr
,
status
,
err
)
{
error
(
err
);
}
});
}
export
function
getAllDomains
(
opts
,
success
,
error
)
{
initZimbra
().
then
(
(
zimbra
)
=>
{
...
...
@@ -331,6 +382,25 @@ export function countAccounts(domain, success, error) {
);
}
export
function
batchCountAccount
(
domains
,
success
,
error
)
{
initZimbra
().
then
(
(
zimbra
)
=>
{
zimbra
.
batchCountAccounts
(
domains
,
(
err
,
data
)
=>
{
if
(
err
)
{
const
e
=
handleError
(
'batchCountAccount'
,
err
);
return
error
(
e
);
}
return
success
(
data
);
});
},
(
err
)
=>
{
const
e
=
handleError
(
'batchCountAccount'
,
err
);
return
error
(
e
);
}
);
}
export
function
getDnsInfo
(
domain
,
success
,
error
)
{
$
.
ajax
({
url
:
`
${
global
.
window
.
manager_config
.
dnsApiUrl
}
/dns`
,
...
...
@@ -381,3 +451,26 @@ export function addAccountAlias(alias, success, error) {
}
);
}
export
function
search
(
query
,
success
,
error
)
{
initZimbra
().
then
(
(
zimbra
)
=>
{
zimbra
.
directorySearch
(
{
query
},
(
err
,
data
)
=>
{
if
(
err
)
{
const
e
=
handleError
(
'search'
,
err
);
return
error
(
e
);
}
return
success
(
data
);
});
},
(
err
)
=>
{
const
e
=
handleError
(
'search'
,
err
);
return
error
(
e
);
}
);
}
src/utils/constants.jsx
View file @
03047062
...
...
@@ -9,7 +9,8 @@ export default {
END_LOADING
:
null
,
USER_CHANGED
:
null
,
RECEIVED_ERROR
:
null
,
NEW_MESSAGE
:
null
NEW_MESSAGE
:
null
,
NEW_TOAST
:
null
}),
PayloadSources
:
keyMirror
({
...
...
@@ -23,13 +24,15 @@ export default {
START_LOADING_EVENT
:
null
,
END_LOADING_EVENT
:
null
,
USER_CHANGE_EVENT
:
null
,
NEW_MESSAGE_EVENT
:
null
NEW_MESSAGE_EVENT
:
null
,
NEW_TOAST_EVENT
:
null
}),
MessageType
:
keyMirror
({
SUCCESS
:
null
,
WARNING
:
null
,
ERROR
:
null
ERROR
:
null
,
INFO
:
null
}),
ZimbraCodes
:
{
...
...
src/utils/utils.jsx
View file @
03047062
...
...
@@ -227,3 +227,57 @@ export function removeIndexFromArray(array, index, pos) {
return
array
;
}
export
function
getPlansFromDomains
(
domains
)
{
const
configPlans
=
global
.
window
.
manager_config
.
plans
;
const
plans
=
{};
for
(
const
key
in
configPlans
)
{
if
(
configPlans
.
hasOwnProperty
(
key
)
&&
configPlans
[
key
])
{
plans
[
key
]
=
{
used
:
0
,
limit
:
0
};
}
}
domains
.
forEach
((
d
)
=>
{
const
pls
=
d
.
plans
;
for
(
const
key
in
pls
)
{
if
(
pls
.
hasOwnProperty
(
key
)
&&
plans
.
hasOwnProperty
(
key
))
{
plans
[
key
].
used
+=
pls
[
key
].
used
;
plans
[
key
].
limit
+=
(
pls
[
key
].
limit
||
0
);
}
}
});
return
plans
;
}
export
function
getPlansFromDomain
(
domain
)
{
const
configPlans
=
global
.
window
.
manager_config
.
plans
;
const
plans
=
{};
for
(
const
key
in
configPlans
)
{
if
(
configPlans
.
hasOwnProperty
(
key
)
&&
configPlans
[
key
])
{
plans
[
key
]
=
{
used
:
0
,
limit
:
0
};
}
}
const
pls
=
domain
.
plans
;
for
(
const
key
in
pls
)
{
if
(
pls
.
hasOwnProperty
(
key
)
&&
plans
.
hasOwnProperty
(
key
))
{
plans
[
key
].
used
+=
pls
[
key
].
used
;
plans
[
key
].
limit
+=
(
pls
[
key
].
limit
||
0
);
}
}
return
plans
;
}
export
function
titleCase
(
string
)
{
return
string
.
charAt
(
0
).
toUpperCase
()
+
string
.
slice
(
1
);
}
src/zimbra/domain.jsx
deleted
100644 → 0
View file @
07deed30
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
export
default
class
Domain
{
constructor
(
connection
)
{
this
.
zimbra
=
connection
;
}
get
(
name
,
by
,
attrs
,
success
,
error
)
{
if
(
this
.
zimbra
)
{
this
.
zimbra
.
getRequest
({},
(
err
,
req
)
=>
{
if
(
err
)
{
return
error
(
err
);
}
return
req
.
addRequest
({
name
:
'GetDomainRequest'
,
namespace
:
'zimbraAdmin'
,
params
:
{
domain
:
{
attrs
,
by
,
_content
:
name
}
}
},
(
er
)
=>
{
if
(
er
)
{
return
error
(
er
);
}
return
this
.
zimbra
.
send
(
req
,
(
err2
,
response
)
=>
{
if
(
err2
)
{
return
error
(
err2
);
}
return
success
(
response
.
get
().
GetAccountInfoResponse
);
});
});
});
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment