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
f553a80e
Commit
f553a80e
authored
Apr 19, 2016
by
Elias Nahum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Domain deatils patialy done, modal example and a few utils
parent
b1ad0f75
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
522 additions
and
24 deletions
+522
-24
add_admin_modal.jsx
src/components/add_admin_modal.jsx
+197
-0
domain_details.jsx
src/components/domain/domain_details.jsx
+106
-16
status_label.jsx
src/components/status_label.jsx
+1
-0
toggle_modal_button.jsx
src/components/toggle_modal_button.jsx
+79
-0
_buttons.scss
src/sass/components/_buttons.scss
+3
-3
_modal.scss
src/sass/components/_modal.scss
+1
-5
_domain.scss
src/sass/routes/_domain.scss
+4
-0
utils.jsx
src/utils/utils.jsx
+131
-0
No files found.
src/components/add_admin_modal.jsx
0 → 100644
View file @
f553a80e
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
*
as
GlobalActions
from
'../action_creators/global_actions.jsx'
;
import
*
as
Utils
from
'../utils/utils.jsx'
;
import
StatusLabel
from
'../components/status_label.jsx'
;
import
{
Modal
}
from
'react-bootstrap'
;
import
React
from
'react'
;
export
default
class
AddAdminModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
handleSearch
=
this
.
handleSearch
.
bind
(
this
);
this
.
handleAddAdmin
=
this
.
handleAddAdmin
.
bind
(
this
);
this
.
state
=
{
users
:
null
};
}
handleSearch
(
e
)
{
e
.
preventDefault
();
const
query
=
this
.
refs
.
searchUser
.
value
.
trim
();
GlobalActions
.
emitStartLoading
();
if
(
query
)
{
this
.
setState
({
users
:
[]});
}
else
{
this
.
setState
({
users
:
null
});
}
}
handleAddAdmin
(
e
,
user
)
{
e
.
preventDefault
();
console
.
log
(
user
);
//eslint-disable-line no-console
}
shouldComponentUpdate
(
nextProps
,
nextState
)
{
if
(
!
this
.
props
.
show
&&
!
nextProps
.
show
)
{
return
false
;
}
if
(
!
Utils
.
areObjectsEqual
(
this
.
props
,
nextProps
))
{
return
true
;
}
return
!
Utils
.
areObjectsEqual
(
this
.
state
,
nextState
);
}
componentWillReceiveProps
(
nextProps
)
{
if
(
!
this
.
props
.
show
&&
nextProps
.
show
)
{
this
.
setState
({
users
:
null
});
}
else
{
GlobalActions
.
emitEndLoading
();
}
}
render
()
{
const
users
=
this
.
state
.
users
;
let
results
;
if
(
users
)
{
if
(
users
.
length
===
0
)
{
results
=
(
<
div
style=
{
{
margin
:
'20px 0'
}
}
>
<
div
className=
'empty-search'
>
{
'Sin resultados para tu búsqueda'
}
</
div
>
</
div
>
);
}
else
{
const
rows
=
users
.
map
((
u
)
=>
{
const
statusClass
=
'mailbox-active'
;
//esto debe ser dependiendo del status que tenga el usuario
return
(
<
tr
key=
{
`user-${u.id}`
}
className=
'mailbox-row'
>
<
td
className=
'mailbox-status'
>
<
StatusLabel
classes=
{
`label-mailbox ${statusClass}`
}
children=
{
u
.
status
}
/>
</
td
>
<
td
className=
'mailbox-name'
>
<
a
href=
'#'
onClick=
{
(
e
)
=>
{
Utils
.
handleLink
(
e
,
`/mailboxes/${u.id}`
);
}
}
>
{
u
.
email
}
</
a
>
</
td
>
<
td
className=
'mailbox-displayname'
>
{
u
.
givenName
}
</
td
>
<
td
className=
'text-center'
>
<
a
className=
'btn btn-warning btn-xs'
onClick=
{
(
e
)
=>
this
.
handleAddAdmin
(
e
,
u
)
}
>
{
'Activar Admin'
}
</
a
>
</
td
>
</
tr
>
);
});
results
=
(
<
table
cellPadding=
'1'
cellSpacing=
'1'
className=
'table table-condensed table-striped vertical-align index-mailbox-table'
>
<
thead
>
<
tr
>
<
th
></
th
>
<
th
>
{
'Email'
}
</
th
>
<
th
className=
'text-left'
>
{
'Nombre'
}
</
th
>
<
th
className=
'text-center'
>
{
' Administrador '
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
rows
}
</
tbody
>
</
table
>
);
}
}
return
(
<
Modal
show=
{
this
.
props
.
show
}
onHide=
{
this
.
props
.
onHide
}
>
<
div
className=
'color-line'
></
div
>
<
Modal
.
Header
closeButton=
{
true
}
>
<
Modal
.
Title
>
{
'Nuevo administador de dominio'
}
</
Modal
.
Title
>
</
Modal
.
Header
>
<
Modal
.
Body
>
<
p
>
{
'El administrador debe tener una casilla de correo creada en la plataforma.'
}
<
br
/>
{
'Si no está creada, '
}
<
a
href=
'#'
onClick=
{
(
e
)
=>
Utils
.
handleLink
(
e
,
`/domains/${this.props.domain.id}/mailboxes/new`
)
}
>
{
'la puedes crear ahora.'
}
</
a
>
</
p
>
<
div
className=
'panel-header-search'
>
<
form
onSubmit=
{
this
.
handleSearch
}
>
<
div
className=
'input-group'
>
<
input
type=
'text'
ref=
'searchUser'
className=
'form-control'
placeholder=
'Buscar Por Nombre'
/>
<
span
className=
'input-group-btn'
>
<
button
className=
'btn btn-default'
type=
'submit'
>
<
span
className=
'fa fa-search'
></
span
>
</
button
>
</
span
>
</
div
>
</
form
>
</
div
>
{
results
}
</
Modal
.
Body
>
<
Modal
.
Footer
>
<
button
type=
'button'
className=
'btn btn-default'
onClick=
{
this
.
props
.
onHide
}
>
{
'Cancelar'
}
</
button
>
</
Modal
.
Footer
>
</
Modal
>
);
}
}
AddAdminModal
.
propTypes
=
{
show
:
React
.
PropTypes
.
bool
.
isRequired
,
onHide
:
React
.
PropTypes
.
func
.
isRequired
,
domain
:
React
.
PropTypes
.
object
.
isRequired
};
src/components/domain/domain_details.jsx
View file @
f553a80e
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
import
$
from
'jquery'
;
import
$
from
'jquery'
;
import
React
from
'react'
;
import
React
from
'react'
;
import
{
browserHistory
}
from
'react-router'
;
import
MessageBar
from
'../message_bar.jsx'
;
import
MessageBar
from
'../message_bar.jsx'
;
import
PageInfo
from
'../page_info.jsx'
;
import
PageInfo
from
'../page_info.jsx'
;
...
@@ -11,26 +10,29 @@ import PanelTab from '../panel_tab.jsx';
...
@@ -11,26 +10,29 @@ import PanelTab from '../panel_tab.jsx';
import
Panel
from
'../panel.jsx'
;
import
Panel
from
'../panel.jsx'
;
import
StatusLabel
from
'../status_label.jsx'
;
import
StatusLabel
from
'../status_label.jsx'
;
import
ToggleModalButton
from
'../toggle_modal_button.jsx'
;
import
AddAdminModal
from
'../add_admin_modal.jsx'
;
import
DomainStore
from
'../../stores/domain_store.jsx'
;
import
DomainStore
from
'../../stores/domain_store.jsx'
;
import
*
as
Client
from
'../../utils/client.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
*
as
GlobalActions
from
'../../action_creators/global_actions.jsx'
;
export
default
class
DomainDetails
extends
React
.
Component
{
export
default
class
DomainDetails
extends
React
.
Component
{
constructor
(
props
)
{
constructor
(
props
)
{
super
(
props
);
super
(
props
);
this
.
handleLink
=
this
.
handleLink
.
bind
(
this
);
this
.
getDomain
=
this
.
getDomain
.
bind
(
this
);
this
.
getDomain
=
this
.
getDomain
.
bind
(
this
);
this
.
handleDeleteAdmin
=
this
.
handleDeleteAdmin
.
bind
(
this
);
this
.
state
=
{};
this
.
state
=
{};
}
}
handle
Link
(
e
,
path
)
{
handle
DeleteAdmin
(
e
,
admin
)
{
e
.
preventDefault
();
e
.
preventDefault
();
if
(
`/
${
this
.
props
.
location
.
pathname
}
`
!==
path
)
{
console
.
log
(
admin
);
//eslint-disable-line no-console
GlobalActions
.
emitStartLoading
();
browserHistory
.
push
(
path
);
//here we need to delete the admin and show a message of success or error
}
}
}
getDomain
()
{
getDomain
()
{
const
domain
=
DomainStore
.
getCurrent
();
const
domain
=
DomainStore
.
getCurrent
();
...
@@ -96,7 +98,7 @@ export default class DomainDetails extends React.Component {
...
@@ -96,7 +98,7 @@ export default class DomainDetails extends React.Component {
label
:
'Editar'
,
label
:
'Editar'
,
props
:
{
props
:
{
className
:
'btn btn-default btn-xs'
,
className
:
'btn btn-default btn-xs'
,
onClick
:
(
e
)
=>
this
.
handleLink
(
e
,
`/domains/
${
this
.
props
.
params
.
id
}
/edit`
)
onClick
:
(
e
)
=>
Utils
.
handleLink
(
e
,
`/domains/
${
this
.
props
.
params
.
id
}
/edit`
,
this
.
props
.
location
)
}
}
}];
}];
...
@@ -115,7 +117,7 @@ export default class DomainDetails extends React.Component {
...
@@ -115,7 +117,7 @@ export default class DomainDetails extends React.Component {
<
p
>
<
p
>
<
a
<
a
className=
'account-name'
className=
'account-name'
onClick=
{
(
e
)
=>
this
.
handleLink
(
e
,
`/accounts/${domain.id_empresa}`
)
}
onClick=
{
(
e
)
=>
Utils
.
handleLink
(
e
,
`/accounts/${domain.id_empresa}`
,
this
.
props
.
location
)
}
>
>
{
'Nombre de la Empresa'
}
{
'Nombre de la Empresa'
}
</
a
>
</
a
>
...
@@ -154,14 +156,14 @@ export default class DomainDetails extends React.Component {
...
@@ -154,14 +156,14 @@ export default class DomainDetails extends React.Component {
label
:
'Ver casillas'
,
label
:
'Ver casillas'
,
props
:
{
props
:
{
className
:
'btn btn-default btn-xs'
,
className
:
'btn btn-default btn-xs'
,
onClick
:
(
e
)
=>
this
.
handleLink
(
e
,
`/domains/
${
this
.
props
.
params
.
id
}
/mailboxes`
)
onClick
:
(
e
)
=>
Utils
.
handleLink
(
e
,
`/domains/
${
this
.
props
.
params
.
id
}
/mailboxes`
,
this
.
props
.
location
)
}
}
},
},
{
{
label
:
'Nueva Casilla'
,
label
:
'Nueva Casilla'
,
props
:
{
props
:
{
className
:
'btn btn-info add-button btn-xs'
,
className
:
'btn btn-info add-button btn-xs'
,
onClick
:
(
e
)
=>
this
.
handleLink
(
e
,
`/domains/
${
this
.
props
.
params
.
id
}
/mailboxes/new`
)
onClick
:
(
e
)
=>
Utils
.
handleLink
(
e
,
`/domains/
${
this
.
props
.
params
.
id
}
/mailboxes/new`
,
this
.
props
.
location
)
}
}
}
}
];
];
...
@@ -204,11 +206,99 @@ export default class DomainDetails extends React.Component {
...
@@ -204,11 +206,99 @@ export default class DomainDetails extends React.Component {
</
table
>
</
table
>
);
);
const
tab1
=
(
const
admins
=
[];
// this should be the actual admins
const
adminRows
=
admins
.
map
((
a
)
=>
{
return
(
<
tr
key=
{
`admin-${a.id}`
}
className=
'user-row'
>
<
td
className=
'user-email'
>
{
a
.
email
}
</
td
>
<
td
className=
'user-name text-center'
>
{
a
.
username
}
</
td
>
<
td
className=
'user-type text-center'
>
{
a
.
type
}
</
td
>
<
td
className=
'user-actions text-center'
>
<
ul
className=
'list-inline list-unstyled'
>
<
li
>
<
a
className=
'btn btn-default btn-xs'
onClick=
{
(
e
)
=>
Utils
.
handleLink
(
e
,
`/mailboxes/${a.id}/edit`
,
this
.
props
.
location
)
}
>
{
'Editar'
}
</
a
>
</
li
>
<
li
>
<
a
className=
'btn btn-danger btn-xs'
onClick=
{
(
e
)
=>
this
.
handleDeleteAdmin
(
e
,
a
)
}
>
{
'Eliminar'
}
</
a
>
</
li
>
</
ul
>
</
td
>
</
tr
>
);
});
let
adminContent
;
if
(
adminRows
.
length
>
0
)
{
adminContent
=
(
<
div
className=
'table-responsive'
>
<
table
id=
'index-users'
cellPadding=
'1'
cellSpacing=
'1'
className=
'table table-condensed table-striped vertical-align'
>
<
thead
>
<
tr
>
<
th
>
{
'email'
}
</
th
>
<
th
className=
'text-center'
>
{
'Nombre'
}
</
th
>
<
th
></
th
>
<
th
className=
'text-center'
>
{
'Acciones'
}
</
th
>
</
tr
>
</
thead
>
<
tbody
>
{
adminRows
}
</
tbody
>
</
table
>
<
ToggleModalButton
role=
'button'
className=
'btn btn-default'
dialogType=
{
AddAdminModal
}
dialogProps=
{
{
domain
}
}
>
{
'Agregar administrador'
}
</
ToggleModalButton
>
</
div
>
);
}
else
{
adminContent
=
(
<
div
className=
'empty-message'
>
<
h4
>
{
'No existen Administradores. '
}
<
ToggleModalButton
role=
'button'
dialogType=
{
AddAdminModal
}
dialogProps=
{
{
domain
}
}
>
{
'Agregar administrador'
}
</
ToggleModalButton
>
</
h4
>
</
div
>
);
}
const
tabAdmin
=
(
<
Panel
<
Panel
title=
'Información General'
hasHeader=
{
false
}
btnsHeader=
{
editDomainButton
}
children=
{
adminContent
}
children=
{
infoBody
}
/>
/>
);
);
...
@@ -224,7 +314,7 @@ export default class DomainDetails extends React.Component {
...
@@ -224,7 +314,7 @@ export default class DomainDetails extends React.Component {
<
PanelTab
<
PanelTab
tabNames=
{
[
'Administradores'
,
'Listas De Distribución'
]
}
tabNames=
{
[
'Administradores'
,
'Listas De Distribución'
]
}
tabs=
{
{
tabs=
{
{
administradores
:
tab
1
,
administradores
:
tab
Admin
,
listas_de_distribuci
ó
n
:
tab2
listas_de_distribuci
ó
n
:
tab2
}
}
}
}
/>
/>
...
...
src/components/status_label.jsx
View file @
f553a80e
import
React
from
'react'
;
import
React
from
'react'
;
// Cambiar por algo que reciba el status y el tamaño y se cree el componente de una vez
export
default
class
StatusLabel
extends
React
.
Component
{
export
default
class
StatusLabel
extends
React
.
Component
{
render
()
{
render
()
{
return
(
return
(
...
...
src/components/toggle_modal_button.jsx
0 → 100644
View file @
f553a80e
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
import
React
from
'react'
;
export
default
class
ModalToggleButton
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
show
=
this
.
show
.
bind
(
this
);
this
.
hide
=
this
.
hide
.
bind
(
this
);
this
.
state
=
{
show
:
false
};
}
show
(
e
)
{
if
(
e
)
{
e
.
preventDefault
();
}
this
.
setState
({
show
:
true
});
}
hide
()
{
this
.
setState
({
show
:
false
});
}
render
()
{
const
{
children
,
dialogType
,
dialogProps
,
onClick
,
...
props
}
=
this
.
props
;
// eslint-disable-line no-use-before-define
// allow callers to provide an onClick which will be called before the modal is shown
let
clickHandler
=
this
.
show
;
if
(
onClick
)
{
clickHandler
=
()
=>
{
onClick
();
this
.
show
();
};
}
// this assumes that all modals will have a show property and an onHide event
const
dialog
=
React
.
createElement
(
dialogType
,
Object
.
assign
({},
dialogProps
,
{
show
:
this
.
state
.
show
,
onHide
:
()
=>
{
this
.
hide
();
if
(
dialogProps
.
onHide
)
{
dialogProps
.
onHide
();
}
}
}));
// nesting the dialog in the anchor tag looks like it shouldn't work, but it does due to how react-bootstrap
// renders modals at the top level of the DOM instead of where you specify in the virtual DOM
return
(
<
a
{
...
props
}
href=
'#'
onClick=
{
clickHandler
}
>
{
children
}
{
dialog
}
</
a
>
);
}
}
ModalToggleButton
.
propTypes
=
{
children
:
React
.
PropTypes
.
node
.
isRequired
,
dialogType
:
React
.
PropTypes
.
func
.
isRequired
,
dialogProps
:
React
.
PropTypes
.
object
,
onClick
:
React
.
PropTypes
.
func
};
ModalToggleButton
.
defaultProps
=
{
dialogProps
:
{}
};
src/sass/components/_buttons.scss
View file @
f553a80e
...
@@ -1257,8 +1257,8 @@ fieldset {
...
@@ -1257,8 +1257,8 @@ fieldset {
}
}
}
}
.
panel-heading
{
.
hpanel
{
.btn
{
.btn
:not
(
:last-child
)
{
margin-
lef
t
:
5px
;
margin-
righ
t
:
5px
;
}
}
}
}
src/sass/components/_modal.scss
View file @
f553a80e
...
@@ -32,17 +32,13 @@
...
@@ -32,17 +32,13 @@
.modal-header
{
.modal-header
{
background
:
$color-bright
;
background
:
$color-bright
;
padding
:
40px
30
px
;
padding
:
15
px
;
small
{
small
{
color
:
lighten
(
$color-text
,
20%
);
color
:
lighten
(
$color-text
,
20%
);
}
}
}
}
.modal-body
{
padding
:
20px
30px
;
}
.modal-footer
{
.modal-footer
{
background
:
$color-bright
;
background
:
$color-bright
;
}
}
...
...
src/sass/routes/_domain.scss
View file @
f553a80e
...
@@ -19,3 +19,7 @@
...
@@ -19,3 +19,7 @@
font-weight
:
bold
;
font-weight
:
bold
;
margin-right
:
5px
;
margin-right
:
5px
;
}
}
.empty-search
{
margin-top
:
10px
;
}
src/utils/utils.jsx
View file @
f553a80e
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// Copyright (c) 2016 ZBox, Spa. All Rights Reserved.
// See LICENSE.txt for license information.
// See LICENSE.txt for license information.
import
{
browserHistory
}
from
'react-router'
;
import
*
as
GlobalActions
from
'../action_creators/global_actions.jsx'
;
const
COOKIE_TIMEOUT
=
24
*
60
*
60
*
1000
;
const
COOKIE_TIMEOUT
=
24
*
60
*
60
*
1000
;
export
function
setCookie
(
cname
,
cvalue
,
exdays
)
{
export
function
setCookie
(
cname
,
cvalue
,
exdays
)
{
...
@@ -28,3 +31,131 @@ export function getCookie(cname) {
...
@@ -28,3 +31,131 @@ export function getCookie(cname) {
export
function
slug
(
str
)
{
export
function
slug
(
str
)
{
return
str
.
toLowerCase
().
replace
(
/ /g
,
'_'
);
return
str
.
toLowerCase
().
replace
(
/ /g
,
'_'
);
}
}
export
function
areObjectsEqual
(
x
,
y
)
{
let
p
;
const
leftChain
=
[];
const
rightChain
=
[];
// Remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if
(
isNaN
(
x
)
&&
isNaN
(
y
)
&&
typeof
x
===
'number'
&&
typeof
y
===
'number'
)
{
return
true
;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on step when comparing prototypes
if
(
x
===
y
)
{
return
true
;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if
((
typeof
x
===
'function'
&&
typeof
y
===
'function'
)
||
(
x
instanceof
Date
&&
y
instanceof
Date
)
||
(
x
instanceof
RegExp
&&
y
instanceof
RegExp
)
||
(
x
instanceof
String
&&
y
instanceof
String
)
||
(
x
instanceof
Number
&&
y
instanceof
Number
))
{
return
x
.
toString
()
===
y
.
toString
();
}
if
(
x
instanceof
Map
&&
y
instanceof
Map
)
{
return
areMapsEqual
(
x
,
y
);
}
// At last checking prototypes as good a we can
if
(
!
(
x
instanceof
Object
&&
y
instanceof
Object
))
{
return
false
;
}
if
(
x
.
isPrototypeOf
(
y
)
||
y
.
isPrototypeOf
(
x
))
{
return
false
;
}
if
(
x
.
constructor
!==
y
.
constructor
)
{
return
false
;
}
if
(
x
.
prototype
!==
y
.
prototype
)
{
return
false
;
}
// Check for infinitive linking loops
if
(
leftChain
.
indexOf
(
x
)
>
-
1
||
rightChain
.
indexOf
(
y
)
>
-
1
)
{
return
false
;
}
// Quick checking of one object beeing a subset of another.
for
(
p
in
y
)
{
if
(
y
.
hasOwnProperty
(
p
)
!==
x
.
hasOwnProperty
(
p
))
{
return
false
;
}
else
if
(
typeof
y
[
p
]
!==
typeof
x
[
p
])
{
return
false
;
}
}
for
(
p
in
x
)
{
if
(
y
.
hasOwnProperty
(
p
)
!==
x
.
hasOwnProperty
(
p
))
{
return
false
;
}
else
if
(
typeof
y
[
p
]
!==
typeof
x
[
p
])
{
return
false
;
}
switch
(
typeof
(
x
[
p
]))
{
case
'object'
:
case
'function'
:
leftChain
.
push
(
x
);
rightChain
.
push
(
y
);
if
(
!
areObjectsEqual
(
x
[
p
],
y
[
p
]))
{
return
false
;
}
leftChain
.
pop
();
rightChain
.
pop
();
break
;
default
:
if
(
x
[
p
]
!==
y
[
p
])
{
return
false
;
}
break
;
}
}
return
true
;
}
export
function
areMapsEqual
(
a
,
b
)
{
if
(
a
.
size
!==
b
.
size
)
{
return
false
;
}
for
(
let
[
key
,
value
]
of
a
)
{
if
(
!
b
.
has
(
key
))
{
return
false
;
}
if
(
!
areObjectsEqual
(
value
,
b
.
get
(
key
)))
{
return
false
;
}
}
return
true
;
}
export
function
handleLink
(
e
,
path
,
location
)
{
e
.
preventDefault
();
if
(
location
)
{
if
(
`/
${
location
.
pathname
}
`
!==
path
)
{
GlobalActions
.
emitStartLoading
();
browserHistory
.
push
(
path
);
}
}
else
{
GlobalActions
.
emitStartLoading
();
browserHistory
.
push
(
path
);
}
}
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