2016-10-26 06:58:14 -04:00
var React = require ( 'react' ) ;
var ReactDOM = require ( 'react-dom' ) ;
var ReactBootstrap = require ( 'react-bootstrap' ) ;
var Grid = ReactBootstrap . Grid ;
var Row = ReactBootstrap . Row ;
var Col = ReactBootstrap . Col ;
var Form = ReactBootstrap . Form ;
var FormGroup = ReactBootstrap . FormGroup ;
var FormControl = ReactBootstrap . FormControl ;
var ControlLabel = ReactBootstrap . ControlLabel ;
var Button = ReactBootstrap . Button ;
var ButtonGroup = ReactBootstrap . ButtonGroup ;
var ButtonToolbar = ReactBootstrap . ButtonToolbar ;
var Glyphicon = ReactBootstrap . Glyphicon ;
var ListGroup = ReactBootstrap . ListGroup ;
var ListGroupItem = ReactBootstrap . ListGroupItem ;
var Modal = ReactBootstrap . Modal ;
var Panel = ReactBootstrap . Panel ;
var Combobox = require ( 'react-widgets' ) . Combobox ;
var models = require ( '../models' ) ;
var Security = models . Security ;
var SecurityType = models . SecurityType ;
var SecurityTypeList = models . SecurityTypeList ;
2017-06-07 19:12:53 -04:00
class SecurityTemplatePanel extends React . Component {
constructor ( ) {
super ( ) ;
this . onSearchChange = this . handleSearchChange . bind ( this ) ;
}
handleSearchChange ( ) {
2016-10-26 06:58:14 -04:00
this . props . onSearchTemplates ( ReactDOM . findDOMNode ( this . refs . search ) . value , 0 , this . props . maxResults + 1 ) ;
2017-06-07 19:12:53 -04:00
}
renderTemplateList ( ) {
2016-10-26 06:58:14 -04:00
var templates = this . props . securityTemplates ;
if ( this . props . search != "" ) {
var items = [ ] ;
for ( var i = 0 ; i < templates . length && i < 15 ; i ++ ) {
var template = templates [ i ] ;
var self = this ;
var onClickFn = ( function ( ) {
var j = i ;
return function ( ) { self . props . onSelectTemplate ( templates [ j ] ) } ;
} ) ( ) ;
var key = template . Type . toString ( ) + template . AlternateId ;
items . push ( (
< ListGroupItem onClick = { onClickFn } key = { key } >
{ template . Name } - { template . Description }
< / L i s t G r o u p I t e m >
) ) ;
}
if ( templates . length > this . props . maxResults ) {
items . push ( (
< ListGroupItem disabled key = "too-many-templates" >
Too many templates to display , please refine your search ...
< / L i s t G r o u p I t e m >
) ) ;
} else if ( templates . length == 0 ) {
items . push ( (
< ListGroupItem disabled key = "no-templates" >
Sorry , no templates matched your search ...
< / L i s t G r o u p I t e m >
) ) ;
}
return (
< div >
< br / >
< ControlLabel > Select a template to populate your security : < / C o n t r o l L a b e l >
< ListGroup >
{ items }
< / L i s t G r o u p >
< / d i v >
) ;
}
2017-06-07 19:12:53 -04:00
}
render ( ) {
2016-10-26 06:58:14 -04:00
return (
< Panel collapsible header = "Populate Security from Template..." >
< FormControl type = "text"
placeholder = "Search..."
value = { this . props . search }
2017-06-07 19:12:53 -04:00
onChange = { this . onSearchChange }
2016-10-26 06:58:14 -04:00
ref = "search" / >
{ this . renderTemplateList ( ) }
< / P a n e l >
) ;
}
2017-06-07 19:12:53 -04:00
}
2016-10-26 06:58:14 -04:00
2017-06-07 19:12:53 -04:00
class AddEditSecurityModal extends React . Component {
getInitialState ( props ) {
2016-10-26 06:58:14 -04:00
var s = {
securityid : - 1 ,
name : "" ,
description : "" ,
symbol : "" ,
precision : 0 ,
type : 1 ,
alternateid : ""
} ;
2017-06-07 19:12:53 -04:00
if ( props && props . editSecurity != null ) {
s . securityid = props . editSecurity . SecurityId ;
s . name = props . editSecurity . Name ;
s . description = props . editSecurity . Description ;
s . symbol = props . editSecurity . Symbol ;
s . precision = props . editSecurity . Precision ;
s . type = props . editSecurity . Type ;
s . alternateid = props . editSecurity . AlternateId ;
2016-10-26 06:58:14 -04:00
}
return s ;
2017-06-07 19:12:53 -04:00
}
constructor ( ) {
super ( ) ;
this . state = this . getInitialState ( ) ;
this . onSelectTemplate = this . handleSelectTemplate . bind ( this ) ;
this . onCancel = this . handleCancel . bind ( this ) ;
this . onNameChange = this . handleNameChange . bind ( this ) ;
this . onDescriptionChange = this . handleDescriptionChange . bind ( this ) ;
this . onSymbolChange = this . handleSymbolChange . bind ( this ) ;
this . onPrecisionChange = this . handlePrecisionChange . bind ( this ) ;
this . onTypeChange = this . handleTypeChange . bind ( this ) ;
this . onAlternateIdChange = this . handleAlternateIdChange . bind ( this ) ;
this . onSubmit = this . handleSubmit . bind ( this ) ;
}
componentWillReceiveProps ( nextProps ) {
if ( nextProps . show && ! this . props . show ) {
this . setState ( this . getInitialState ( nextProps ) ) ;
}
}
handleSelectTemplate ( template ) {
2016-10-26 06:58:14 -04:00
this . setState ( {
name : template . Name ,
description : template . Description ,
symbol : template . Symbol ,
precision : template . Precision ,
type : template . Type ,
2017-06-21 21:53:01 -04:00
alternateid : template . AlternateId
2016-10-26 06:58:14 -04:00
} ) ;
2017-06-07 19:12:53 -04:00
}
handleCancel ( ) {
2016-10-26 06:58:14 -04:00
if ( this . props . onCancel != null )
this . props . onCancel ( ) ;
2017-06-07 19:12:53 -04:00
}
handleNameChange ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( {
name : ReactDOM . findDOMNode ( this . refs . name ) . value ,
} ) ;
2017-06-07 19:12:53 -04:00
}
handleDescriptionChange ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( {
description : ReactDOM . findDOMNode ( this . refs . description ) . value ,
} ) ;
2017-06-07 19:12:53 -04:00
}
handleSymbolChange ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( {
symbol : ReactDOM . findDOMNode ( this . refs . symbol ) . value ,
} ) ;
2017-06-07 19:12:53 -04:00
}
handlePrecisionChange ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( {
precision : + ReactDOM . findDOMNode ( this . refs . precision ) . value ,
} ) ;
2017-06-07 19:12:53 -04:00
}
handleTypeChange ( type ) {
2016-10-26 06:58:14 -04:00
if ( type . hasOwnProperty ( 'TypeId' ) )
this . setState ( {
type : type . TypeId
} ) ;
2017-06-07 19:12:53 -04:00
}
handleAlternateIdChange ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( {
alternateid : ReactDOM . findDOMNode ( this . refs . alternateid ) . value ,
} ) ;
2017-06-07 19:12:53 -04:00
}
handleSubmit ( ) {
2016-10-26 06:58:14 -04:00
var s = new Security ( ) ;
if ( this . props . editSecurity != null )
s . SecurityId = this . state . securityid ;
s . Name = this . state . name ;
s . Description = this . state . description ;
s . Symbol = this . state . symbol ;
s . Precision = this . state . precision ;
s . Type = this . state . type ;
s . AlternateId = this . state . alternateid ;
if ( this . props . onSubmit != null )
this . props . onSubmit ( s ) ;
2017-06-07 19:12:53 -04:00
}
render ( ) {
2016-10-26 06:58:14 -04:00
var headerText = ( this . props . editSecurity != null ) ? "Edit" : "Create New" ;
var buttonText = ( this . props . editSecurity != null ) ? "Save Changes" : "Create Security" ;
var alternateidname = ( this . state . type == SecurityType . Currency ) ? "ISO 4217 Code" : "CUSIP" ;
return (
2017-06-07 19:12:53 -04:00
< Modal show = { this . props . show } onHide = { this . onCancel } >
2016-10-26 06:58:14 -04:00
< Modal . Header closeButton >
< Modal . Title > { headerText } Security < / M o d a l . T i t l e >
< / M o d a l . H e a d e r >
< Modal . Body >
< SecurityTemplatePanel
search = { this . props . securityTemplates . search }
securityTemplates = { this . props . securityTemplates . templates }
onSearchTemplates = { this . props . onSearchTemplates }
maxResults = { 15 }
onSelectTemplate = { this . onSelectTemplate } / >
2017-06-07 19:12:53 -04:00
< Form horizontal onSubmit = { this . onSubmit } >
2016-10-26 06:58:14 -04:00
< FormGroup >
< Col componentClass = { ControlLabel } xs = { 3 } > Name < / C o l >
< Col xs = { 9 } >
< FormControl type = "text"
value = { this . state . name }
2017-06-07 19:12:53 -04:00
onChange = { this . onNameChange }
2016-10-26 06:58:14 -04:00
ref = "name" / >
< / C o l >
< / F o r m G r o u p >
< FormGroup >
< Col componentClass = { ControlLabel } xs = { 3 } > Description < / C o l >
< Col xs = { 9 } >
< FormControl type = "text"
value = { this . state . description }
2017-06-07 19:12:53 -04:00
onChange = { this . onDescriptionChange }
2016-10-26 06:58:14 -04:00
ref = "description" / >
< / C o l >
< / F o r m G r o u p >
< FormGroup >
< Col componentClass = { ControlLabel } xs = { 3 } > Symbol or Ticker < / C o l >
< Col xs = { 9 } >
< FormControl type = "text"
value = { this . state . symbol }
2017-06-07 19:12:53 -04:00
onChange = { this . onSymbolChange }
2016-10-26 06:58:14 -04:00
ref = "symbol" / >
< / C o l >
< / F o r m G r o u p >
< FormGroup >
< Col componentClass = { ControlLabel } xs = { 3 } > Smallest Fraction Traded < / C o l >
< Col xs = { 9 } >
< FormControl componentClass = "select"
placeholder = { this . state . precision }
value = { this . state . precision }
2017-06-07 19:12:53 -04:00
onChange = { this . onPrecisionChange }
2016-10-26 06:58:14 -04:00
ref = "precision" >
< option value = { 0 } > 1 < / o p t i o n >
< option value = { 1 } > 0.1 ( 1 / 10 ) < / o p t i o n >
< option value = { 2 } > 0.01 ( 1 / 100 ) < / o p t i o n >
< option value = { 3 } > 0.001 ( 1 / 1000 ) < / o p t i o n >
< option value = { 4 } > 0.0001 ( 1 / 10000 ) < / o p t i o n >
< option value = { 5 } > 0.00001 ( 1 / 100000 ) < / o p t i o n >
< / F o r m C o n t r o l >
< / C o l >
< / F o r m G r o u p >
< FormGroup >
< Col componentClass = { ControlLabel } xs = { 3 } > Security Type < / C o l >
< Col xs = { 9 } >
< Combobox
suggest
data = { SecurityTypeList }
valueField = 'TypeId'
textField = 'Name'
value = { this . state . type }
2017-06-07 19:12:53 -04:00
onChange = { this . onTypeChange }
2016-10-26 06:58:14 -04:00
ref = "type" / >
< / C o l >
< / F o r m G r o u p >
< FormGroup >
< Col componentClass = { ControlLabel } xs = { 3 } > { alternateidname } < / C o l >
< Col xs = { 9 } >
< FormControl type = "text"
value = { this . state . alternateid }
2017-06-07 19:12:53 -04:00
onChange = { this . onAlternateIdChange }
2016-10-26 06:58:14 -04:00
ref = "alternateid" / >
< / C o l >
< / F o r m G r o u p >
< / F o r m >
< / M o d a l . B o d y >
< Modal . Footer >
< ButtonGroup className = "pull-right" >
2017-06-07 19:12:53 -04:00
< Button onClick = { this . onCancel } bsStyle = "warning" > Cancel < / B u t t o n >
< Button onClick = { this . onSubmit } bsStyle = "success" > { buttonText } < / B u t t o n >
2016-10-26 06:58:14 -04:00
< / B u t t o n G r o u p >
< / M o d a l . F o o t e r >
< / M o d a l >
) ;
}
2017-06-07 19:12:53 -04:00
}
2016-10-26 06:58:14 -04:00
2017-06-07 19:12:53 -04:00
class DeletionFailedModal extends React . Component {
render ( ) {
2017-06-21 21:53:01 -04:00
var msg = "We are unable to delete your " + this . props . deletingSecurity . Name + " security because it is in use by " + this . props . securityAccounts . length + " account(s). Please change those accounts to use other securities and try again." ;
if ( this . props . user . DefaultCurrency == this . props . deletingSecurity . SecurityId ) {
msg = "We are unable to delete your default currency: " + this . props . deletingSecurity . Name + ". To delete this security, select another as your default currency under Account Settings." ;
}
2017-02-05 20:48:40 -05:00
return (
< Modal show = { this . props . show } onHide = { this . props . onClose } >
< Modal . Header closeButton >
< Modal . Title > Cannot Delete Security < / M o d a l . T i t l e >
< / M o d a l . H e a d e r >
< Modal . Body >
2017-06-21 21:53:01 -04:00
{ msg }
2017-02-05 20:48:40 -05:00
< / M o d a l . B o d y >
< Modal . Footer >
< ButtonGroup className = "pull-right" >
< Button onClick = { this . props . onClose } bsStyle = "warning" > Close < / B u t t o n >
< / B u t t o n G r o u p >
< / M o d a l . F o o t e r >
< / M o d a l >
) ;
}
2017-06-07 19:12:53 -04:00
}
2017-02-05 20:48:40 -05:00
2017-06-07 19:12:53 -04:00
class SecurityList extends React . Component {
render ( ) {
2016-10-26 06:58:14 -04:00
var children = [ ] ;
var self = this ;
for ( var securityId in this . props . securities ) {
if ( this . props . securities . hasOwnProperty ( securityId ) ) {
var buttonStyle = ( securityId == this . props . selectedSecurity ) ? "info" : "link" ;
var onClickFn = ( function ( ) {
var id = securityId ;
return function ( ) { self . props . onSelectSecurity ( id ) } ;
} ) ( ) ;
children . push ( ( < Button
bsStyle = { buttonStyle }
key = { securityId }
onClick = { onClickFn } >
{ this . props . securities [ securityId ] . Name } - { this . props . securities [ securityId ] . Description }
< / B u t t o n > ) ) ;
}
}
return (
< div >
{ children }
< / d i v >
) ;
}
2017-06-07 19:12:53 -04:00
}
2016-10-26 06:58:14 -04:00
2017-06-07 19:12:53 -04:00
class SecuritiesTab extends React . Component {
constructor ( ) {
super ( ) ;
this . state = {
2016-10-26 06:58:14 -04:00
creatingNewSecurity : false ,
2017-02-05 20:48:40 -05:00
editingSecurity : false ,
deletionFailedModal : false
2016-10-26 06:58:14 -04:00
} ;
2017-06-07 19:12:53 -04:00
this . onSelectSecurity = this . handleSelectSecurity . bind ( this ) ;
this . onNewSecurity = this . handleNewSecurity . bind ( this ) ;
this . onEditSecurity = this . handleEditSecurity . bind ( this ) ;
this . onDeleteSecurity = this . handleDeleteSecurity . bind ( this ) ;
this . onCreationCancel = this . handleCreationCancel . bind ( this ) ;
this . onCreationSubmit = this . handleCreationSubmit . bind ( this ) ;
this . onEditingCancel = this . handleEditingCancel . bind ( this ) ;
this . onEditingSubmit = this . handleEditingSubmit . bind ( this ) ;
this . onCloseDeletionFailed = this . handleCloseDeletionFailed . bind ( this ) ;
}
componentWillReceiveProps ( nextProps ) {
2017-05-28 21:19:19 -04:00
if ( nextProps . selectedSecurity == - 1 && nextProps . security _list . length > 0 ) {
nextProps . onSelectSecurity ( nextProps . security _list [ 0 ] . SecurityId ) ;
}
2017-06-07 19:12:53 -04:00
}
handleSelectSecurity ( security ) {
2017-05-28 21:19:19 -04:00
this . props . onSelectSecurity ( security . SecurityId ) ;
2017-06-07 19:12:53 -04:00
}
handleNewSecurity ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( { creatingNewSecurity : true } ) ;
2017-06-07 19:12:53 -04:00
}
handleEditSecurity ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( { editingSecurity : true } ) ;
2017-06-07 19:12:53 -04:00
}
handleDeleteSecurity ( ) {
2017-06-21 21:53:01 -04:00
// check if user has this as their default currency
var security = this . props . securities [ this . props . selectedSecurity ] ;
if ( this . props . selectedSecurityAccounts . length == 0 && security . SecurityId != this . props . user . DefaultCurrency )
this . props . onDeleteSecurity ( security ) ;
2017-02-05 20:48:40 -05:00
else
this . setState ( { deletionFailedModal : true } ) ;
2017-06-07 19:12:53 -04:00
}
handleCreationCancel ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( { creatingNewSecurity : false } ) ;
2017-06-07 19:12:53 -04:00
}
handleCreationSubmit ( security ) {
2016-10-26 06:58:14 -04:00
this . setState ( { creatingNewSecurity : false } ) ;
this . props . onCreateSecurity ( security ) ;
2017-06-07 19:12:53 -04:00
}
handleEditingCancel ( ) {
2016-10-26 06:58:14 -04:00
this . setState ( { editingSecurity : false } ) ;
2017-06-07 19:12:53 -04:00
}
handleEditingSubmit ( security ) {
2016-10-26 06:58:14 -04:00
this . setState ( { editingSecurity : false } ) ;
2017-06-21 21:53:01 -04:00
if ( security . SecurityId == this . props . user . DefaultCurrency && security . Type != SecurityType . Currency ) {
this . props . onUserError ( "Unable to modify the default currency to be a non-currency security" ) ;
} else {
this . props . onUpdateSecurity ( security ) ;
}
2017-06-07 19:12:53 -04:00
}
handleCloseDeletionFailed ( ) {
2017-02-05 20:48:40 -05:00
this . setState ( { deletionFailedModal : false } ) ;
2017-06-07 19:12:53 -04:00
}
render ( ) {
2017-02-05 20:48:40 -05:00
var noSecuritySelected = this . props . selectedSecurity == - 1 ;
2016-10-26 06:58:14 -04:00
2017-05-28 21:19:19 -04:00
var selectedSecurity = - 1 ;
2016-10-26 06:58:14 -04:00
if ( this . props . securities . hasOwnProperty ( this . props . selectedSecurity ) )
selectedSecurity = this . props . securities [ this . props . selectedSecurity ] ;
return (
2017-05-28 21:19:19 -04:00
< div >
< AddEditSecurityModal
show = { this . state . creatingNewSecurity }
2017-06-07 19:12:53 -04:00
onCancel = { this . onCreationCancel }
onSubmit = { this . onCreationSubmit }
2017-05-28 21:19:19 -04:00
onSearchTemplates = { this . props . onSearchTemplates }
securityTemplates = { this . props . securityTemplates } / >
< AddEditSecurityModal
show = { this . state . editingSecurity }
editSecurity = { selectedSecurity }
2017-06-07 19:12:53 -04:00
onCancel = { this . onEditingCancel }
onSubmit = { this . onEditingSubmit }
2017-05-28 21:19:19 -04:00
onSearchTemplates = { this . props . onSearchTemplates }
securityTemplates = { this . props . securityTemplates } / >
< DeletionFailedModal
show = { this . state . deletionFailedModal }
2017-06-21 21:53:01 -04:00
user = { this . props . user }
2017-05-28 21:19:19 -04:00
deletingSecurity = { selectedSecurity }
2017-06-07 19:12:53 -04:00
o nClose = { this . onCloseDeletionFailed }
2017-05-28 21:19:19 -04:00
securityAccounts = { this . props . selectedSecurityAccounts } / >
< ButtonToolbar >
< ButtonGroup >
2017-06-07 19:12:53 -04:00
< Button onClick = { this . onNewSecurity } bsStyle = "success" > < Glyphicon glyph = 'plus-sign' / > New Security < / B u t t o n >
2017-05-28 21:19:19 -04:00
< / B u t t o n G r o u p >
< ButtonGroup >
< Combobox
data = { this . props . security _list }
valueField = 'SecurityId'
textField = { item => typeof item === 'string' ? item : item . Name + " - " + item . Description }
value = { selectedSecurity }
2017-06-07 19:12:53 -04:00
onChange = { this . onSelectSecurity }
2017-05-28 21:19:19 -04:00
suggest
filter = 'contains'
ref = "security" / >
< / B u t t o n G r o u p >
< ButtonGroup >
2017-06-07 19:12:53 -04:00
< Button onClick = { this . onEditSecurity } bsStyle = "primary" disabled = { noSecuritySelected } > < Glyphicon glyph = 'cog' / > Edit Security < / B u t t o n >
< Button onClick = { this . onDeleteSecurity } bsStyle = "danger" disabled = { noSecuritySelected } > < Glyphicon glyph = 'trash' / > Delete Security < / B u t t o n >
2017-05-28 21:19:19 -04:00
< / B u t t o n G r o u p > < / B u t t o n T o o l b a r >
< / d i v >
2016-10-26 06:58:14 -04:00
) ;
}
2017-06-07 19:12:53 -04:00
}
module . exports = SecuritiesTab ;