2014-07-28 18:07:48 +02:00
/ *
2015-03-09 15:45:35 +01:00
Copyright 2008 - 2015 Clipperz Srl
2014-07-28 18:07:48 +02:00
This file is part of Clipperz , the online password manager .
For further information about its features and functionalities please
refer to http : //www.clipperz.com.
* Clipperz is free software : you can redistribute it and / or modify it
under the terms of the GNU Affero General Public License as published
by the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
* Clipperz is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU Affero General Public License for more details .
* You should have received a copy of the GNU Affero General Public
License along with Clipperz . If not , see http : //www.gnu.org/licenses/.
* /
2015-01-02 10:13:04 +01:00
"use strict" ;
2014-07-28 18:07:48 +02:00
Clipperz . Base . module ( 'Clipperz.PM.UI.Components.Panels' ) ;
2015-03-23 18:10:09 +01:00
Clipperz . PM . UI . Components . Panels . ExtraFeaturesPanelClass = React . createClass ( {
2014-07-28 18:07:48 +02:00
2016-03-29 11:45:50 +02:00
displayName : 'Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel' ,
2015-06-27 19:08:20 +02:00
componentDidMount : function ( ) {
MochiKit . Signal . connect ( Clipperz . Signal . NotificationCenter , 'closeSettingsPanel' , MochiKit . Base . method ( this , 'hideExtraFeatureContent' ) ) ;
} ,
2014-07-28 18:07:48 +02:00
settingsToggleHandler : function ( anEvent ) {
2015-04-01 18:28:26 +02:00
this . hideExtraFeatureContent ( ) ;
2014-07-28 18:07:48 +02:00
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'toggleSettingsPanel' ) ;
} ,
2015-01-02 10:13:04 +01:00
handleDownloadOfflineCopyLink : function ( anEvent ) {
2015-03-11 18:18:00 +01:00
if ( this . isFeatureEnabled ( 'OFFLINE_COPY' ) ) {
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'downloadOfflineCopy' ) ;
}
2015-01-02 10:13:04 +01:00
} ,
2015-01-21 18:29:08 +01:00
propTypes : {
2015-03-10 22:59:24 +01:00
'accountInfo' : React . PropTypes . object . isRequired ,
2015-06-27 19:08:20 +02:00
'userInfo' : React . PropTypes . object . isRequired
2015-01-21 18:29:08 +01:00
} ,
getInitialState : function ( ) {
return {
2015-04-01 18:28:26 +02:00
'index' : {
'account' : false ,
'subscription' : false ,
'data' : false ,
2015-07-04 18:43:59 +02:00
'about' : false ,
2015-04-01 18:28:26 +02:00
} ,
2015-05-21 14:32:51 +02:00
'isFullyOpen' : false ,
'extraFeatureComponentName' : null ,
'extraFeatureContent' : null
2015-01-21 18:29:08 +01:00
} ;
} ,
2015-04-01 18:28:26 +02:00
toggleIndexState : function ( section ) {
2015-01-21 18:29:08 +01:00
return MochiKit . Base . bind ( function ( ) {
2015-04-03 14:44:04 +02:00
var newState = { 'index' : this . state [ 'index' ] } ;
2015-01-21 18:29:08 +01:00
2015-04-01 18:28:26 +02:00
newState [ 'index' ] [ section ] = ! this . state [ 'index' ] [ section ] ;
2015-01-21 18:29:08 +01:00
this . setState ( newState ) ;
} , this ) ;
} ,
2015-03-11 18:18:00 +01:00
isFeatureEnabled : function ( aValue ) {
return ( this . props [ 'features' ] . indexOf ( aValue ) > - 1 ) ;
} ,
2015-07-04 18:43:59 +02:00
showUrl : function ( anUrl ) {
return function ( ) {
window . open ( anUrl , 'clipperz_about' ) ;
}
} ,
2015-07-31 17:41:39 +02:00
lock : function ( ) {
2015-09-23 10:24:49 +02:00
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'lock' ) ;
2015-07-31 17:41:39 +02:00
} ,
2015-07-04 18:43:59 +02:00
logout : function ( ) {
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'logout' ) ;
} ,
2014-07-28 18:07:48 +02:00
//=========================================================================
2015-05-21 14:32:51 +02:00
toggleExtraFeatureComponent : function ( aComponentName ) {
2015-04-01 18:28:26 +02:00
return MochiKit . Base . bind ( function ( ) {
2015-05-21 14:32:51 +02:00
if ( this . state [ 'extraFeatureComponentName' ] != aComponentName ) {
this . showExtraFeatureContent ( Clipperz . PM . UI . Components . ExtraFeatures [ aComponentName ] , aComponentName ) ;
} else {
this . hideExtraFeatureContent ( ) ;
}
2015-04-01 18:28:26 +02:00
} , this ) ;
} ,
extraFeaturesProps : function ( ) {
return this . props ;
} ,
//-------------------------------------------------------------------------
hideExtraFeatureContent : function ( ) {
2015-05-21 14:32:51 +02:00
this . setState ( {
'isFullyOpen' : false ,
'extraFeatureComponentName' : null ,
2015-07-05 09:09:33 +02:00
'extraFeatureContent' : null ,
'extraFeatureContentComponent' : null
2015-05-21 14:32:51 +02:00
} ) ;
2015-04-01 18:28:26 +02:00
} ,
2015-05-21 14:32:51 +02:00
showExtraFeatureContent : function ( aComponent , aComponentName ) {
2015-06-27 19:08:20 +02:00
if ( aComponentName == 'OTP' ) {
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'updateOTPListAndDetails' ) ;
}
2016-03-29 11:45:50 +02:00
if ( aComponentName == 'Plan' ) {
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'updateUserAccountInfo' ) ;
}
2015-04-01 18:28:26 +02:00
this . setState ( {
'isFullyOpen' : true ,
2015-05-21 14:32:51 +02:00
'extraFeatureComponentName' : aComponentName ,
2015-06-27 19:08:20 +02:00
'extraFeatureContentComponent' : aComponent // Trying to instantiate the component at every render
2015-04-01 18:28:26 +02:00
} ) ;
} ,
//=========================================================================
renderIndex : function ( ) {
2015-03-11 18:18:00 +01:00
var offlineCopyButtonClasses = {
'button' : true ,
'disabled' : ! this . isFeatureEnabled ( 'OFFLINE_COPY' )
}
2015-04-01 18:28:26 +02:00
return React . DOM . div ( { 'className' : 'extraFeatureIndex' } , [
2015-03-23 18:10:09 +01:00
React . DOM . header ( { 'key' : 'header' } , [
React . DOM . div ( { 'key' : 'headerDiv' , 'className' : 'settingsToggle' } , [
Clipperz . PM . UI . Components . Button ( { 'key' : 'button' , 'eventName' : 'settingsToggleButton' , 'label' : "menu" , 'handler' : this . settingsToggleHandler } )
2014-07-28 18:07:48 +02:00
] )
] ) ,
2015-03-23 18:10:09 +01:00
React . DOM . div ( { 'key' : 'ulWrapper' } , [
React . DOM . ul ( { 'key' : 'ul' } , [
2015-04-01 18:28:26 +02:00
React . DOM . li ( { 'key' : 'account' , 'className' : this . state [ 'index' ] [ 'account' ] ? 'open' : 'closed' } , [
React . DOM . h1 ( { 'key' : 'accountH1' , 'onClick' : this . toggleIndexState ( 'account' ) } , "Account" ) ,
2015-03-23 18:10:09 +01:00
React . DOM . ul ( { 'key' : 'accountUL' } , [
2016-03-29 11:45:50 +02:00
React . DOM . li ( { 'key' : 'account_0' , 'onClick' : this . toggleExtraFeatureComponent ( 'Preferences' ) , 'className' : ( this . state [ 'extraFeatureComponentName' ] == 'Preferences' ) ? 'selected' : '' } , [
React . DOM . h2 ( { } , "Preferences" ) ,
2015-09-23 10:24:49 +02:00
] ) ,
2015-05-21 14:32:51 +02:00
React . DOM . li ( { 'key' : 'account_1' , 'onClick' : this . toggleExtraFeatureComponent ( 'Passphrase' ) , 'className' : ( this . state [ 'extraFeatureComponentName' ] == 'Passphrase' ) ? 'selected' : '' } , [
2016-03-29 11:45:50 +02:00
React . DOM . h2 ( { } , "Passphrase" ) ,
2015-06-27 19:08:20 +02:00
// React.DOM.div({'key':'account_1_div'}, [
// React.DOM.p({'key':'account_1_p'}, "Change your account passphrase.")
// ])
2015-01-21 18:29:08 +01:00
] ) ,
2016-03-29 11:45:50 +02:00
React . DOM . li ( { 'key' : 'account_2' , 'onClick' : this . toggleExtraFeatureComponent ( 'Plan' ) , 'className' : ( this . state [ 'extraFeatureComponentName' ] == 'Plan' ) ? 'selected' : '' } , [
React . DOM . h2 ( { } , "Plan" ) ,
// React.DOM.div({}, [
// React.DOM.p({}, "Current plan.")
// ])
] ) ,
React . DOM . li ( { 'key' : 'account_3' , 'onClick' : this . toggleExtraFeatureComponent ( 'OTP' ) } , [
2015-07-04 18:43:59 +02:00
React . DOM . h2 ( { } , "One-Time Passwords" ) ,
2015-06-27 19:08:20 +02:00
// React.DOM.div({}, [
// React.DOM.p({}, "Manage your OTPs.")
// ])
2015-01-21 18:29:08 +01:00
] ) ,
2015-09-30 20:09:58 +02:00
2016-03-29 11:45:50 +02:00
React . DOM . li ( { 'key' : 'account_4' , 'onClick' : this . toggleExtraFeatureComponent ( 'DevicePIN' ) } , [
2015-03-10 22:59:24 +01:00
React . DOM . h2 ( { } , "Device PIN" ) ,
2015-09-30 20:09:58 +02:00
// React.DOM.div({}, [
// React.DOM.p({}, "Configure a PIN that will allow to get access to your cards, but only on this device.")
// ])
2015-01-21 18:29:08 +01:00
] ) ,
2015-09-30 20:09:58 +02:00
2015-05-21 14:32:51 +02:00
React . DOM . li ( { 'key' : 'account_5' , 'onClick' : this . toggleExtraFeatureComponent ( 'DeleteAccount' ) , 'className' : ( this . state [ 'extraFeatureComponentName' ] == 'DeleteAccount' ) ? 'selected' : '' } , [
2015-01-21 18:29:08 +01:00
React . DOM . h2 ( { } , "Delete account" ) ,
2015-06-27 19:08:20 +02:00
// React.DOM.div({}, [
// React.DOM.p({}, "Delete your account for good.")
// ])
2015-01-21 18:29:08 +01:00
] )
] )
2015-01-02 10:13:04 +01:00
] ) ,
2015-06-27 19:08:20 +02:00
/ *
2015-04-01 18:28:26 +02:00
React . DOM . li ( { 'key' : 'subscription' , 'className' : this . state [ 'index' ] [ 'subscription' ] ? 'open' : 'closed' } , [
React . DOM . h1 ( { 'onClick' : this . toggleIndexState ( 'subscription' ) } , "Subscription" ) ,
2015-03-23 18:10:09 +01:00
React . DOM . ul ( { 'key' : 'subscription' } , [
React . DOM . li ( { 'key' : 'subscription_1' } , [
2015-01-21 18:29:08 +01:00
React . DOM . h2 ( { } , "x1" ) ,
2015-01-02 10:13:04 +01:00
React . DOM . div ( { } , [
2015-01-21 18:29:08 +01:00
React . DOM . p ( { } , "" )
2015-01-02 10:13:04 +01:00
] )
] ) ,
2015-03-23 18:10:09 +01:00
React . DOM . li ( { 'key' : 'subscription_2' } , [
2015-01-21 18:29:08 +01:00
React . DOM . h2 ( { } , "x2" ) ,
React . DOM . div ( { } , [
React . DOM . p ( { } , "" )
] )
] ) ,
2015-03-23 18:10:09 +01:00
React . DOM . li ( { 'key' : 'subscription_3' } , [
2015-01-21 18:29:08 +01:00
React . DOM . h2 ( { } , "x3" ) ,
React . DOM . div ( { } , [
React . DOM . p ( { } , "" )
] )
] ) ,
2015-03-23 18:10:09 +01:00
React . DOM . li ( { 'key' : 'subscription_4' } , [
2015-01-21 18:29:08 +01:00
React . DOM . h2 ( { } , "x4" ) ,
React . DOM . div ( { } , [
React . DOM . p ( { } , "" )
] )
] )
] )
] ) ,
2015-06-27 19:08:20 +02:00
* /
2015-04-01 18:28:26 +02:00
React . DOM . li ( { 'key' : 'data' , 'className' : this . state [ 'index' ] [ 'data' ] ? 'open' : 'closed' } , [
React . DOM . h1 ( { 'onClick' : this . toggleIndexState ( 'data' ) } , "Data" ) ,
2015-03-23 18:10:09 +01:00
React . DOM . ul ( { 'key' : 'data' } , [
2015-05-21 14:32:51 +02:00
// React.DOM.li({'key':'data_1'}, [
// React.DOM.h2({}, "Offline copy"),
// React.DOM.div({}, [
// React.DOM.p({}, "With just one click you can dump all your encrypted data from Clipperz servers to your hard disk and create a read-only offline version of Clipperz to be used when you are not connected to the Internet."),
// React.DOM.a({'className':Clipperz.PM.UI.Components.classNames(offlineCopyButtonClasses), 'onClick':this.handleDownloadOfflineCopyLink}, "Download")
// ])
// ]),
React . DOM . li ( { 'key' : 'data_2' , 'onClick' : this . toggleExtraFeatureComponent ( 'DataImport' ) , 'className' : ( this . state [ 'extraFeatureComponentName' ] == 'DataImport' ) ? 'selected' : '' } , [
2015-01-02 10:13:04 +01:00
React . DOM . h2 ( { } , "Import" ) ,
2015-06-27 19:08:20 +02:00
// React.DOM.div({}, [
// React.DOM.p({}, "CSV, JSON, …")
// ])
2015-01-02 10:13:04 +01:00
] ) ,
2015-05-21 14:32:51 +02:00
React . DOM . li ( { 'key' : 'data_3' , 'onClick' : this . toggleExtraFeatureComponent ( 'DataExport' ) , 'className' : ( this . state [ 'extraFeatureComponentName' ] == 'DataExport' ) ? 'selected' : '' } , [
2015-01-02 10:13:04 +01:00
React . DOM . h2 ( { } , "Export" ) ,
2015-06-27 19:08:20 +02:00
// React.DOM.div({}, [
// React.DOM.p({}, "Offline copy, printable version, JSON, …")
// ])
2015-01-21 18:29:08 +01:00
] ) ,
2015-06-27 19:08:20 +02:00
/ *
2015-03-23 18:10:09 +01:00
React . DOM . li ( { 'key' : 'data_4' } , [
2015-01-21 18:29:08 +01:00
React . DOM . h2 ( { } , "Sharing" ) ,
React . DOM . div ( { } , [
2015-05-21 14:32:51 +02:00
React . DOM . p ( { } , "Securely share cards with other users" )
2015-01-21 18:29:08 +01:00
] )
2015-01-02 10:13:04 +01:00
] )
2015-06-27 19:08:20 +02:00
* /
2015-01-02 10:13:04 +01:00
] )
2015-07-04 18:43:59 +02:00
] ) ,
React . DOM . li ( { 'key' : 'about' , 'className' : this . state [ 'index' ] [ 'about' ] ? 'open' : 'closed' } , [
React . DOM . h1 ( { 'key' : 'aboutH1' , 'onClick' : this . toggleIndexState ( 'about' ) } , "About" ) ,
React . DOM . div ( { 'key' : 'address' , 'className' : 'address' } , [
"Clipperz Srl" ,
"Piazza Nuova, 10" ,
"48012 Bagnacavallo" ,
"Italy"
] ) ,
React . DOM . ul ( { 'key' : 'data' } , [
React . DOM . li ( { 'key' : 'about_1' , 'className' : 'link' , 'onClick' : this . showUrl ( '/' ) } , [
React . DOM . h2 ( { } , "Website" ) ,
] ) ,
React . DOM . li ( { 'key' : 'about_2' , 'className' : 'link' , 'onClick' : this . showUrl ( '/forum/' ) } , [
React . DOM . h2 ( { } , "Forum" ) ,
] ) ,
// React.DOM.li({'key':'about_3', 'className':'link', 'onClick':this.showUrl('/blog')}, [
// React.DOM.h2({}, "Blog"),
// ]),
React . DOM . li ( { 'key' : 'about_4' , 'className' : 'link' , 'onClick' : this . showUrl ( 'https://twitter.com/clipperz' ) } , [
React . DOM . h2 ( { } , "Twitter" ) ,
] ) ,
React . DOM . li ( { 'key' : 'about_5' , 'className' : 'link' , 'onClick' : this . showUrl ( '/about/contacts/' ) } , [
React . DOM . h2 ( { } , "Contacts" ) ,
] ) ,
React . DOM . li ( { 'key' : 'about_6' , 'className' : 'link' , 'onClick' : this . showUrl ( '/terms_service/' ) } , [
React . DOM . h2 ( { } , "Terms of service" ) ,
] ) ,
React . DOM . li ( { 'key' : 'about_7' , 'className' : 'link' , 'onClick' : this . showUrl ( '/privacy_policy/' ) } , [
React . DOM . h2 ( { } , "Privacy" ) ,
] ) ,
] )
] ) ,
2015-07-31 17:41:39 +02:00
React . DOM . li ( { 'key' : 'logout' , 'className' : 'lock-logout' } , [
2015-09-23 10:24:49 +02:00
React . DOM . h2 ( { 'className' : 'lock' , 'onClick' : this . lock } , "Lock" ) ,
2015-07-31 17:41:39 +02:00
React . DOM . h2 ( { 'className' : 'logout' , 'onClick' : this . logout } , "Logout" ) ,
2015-01-02 10:13:04 +01:00
] )
] )
2015-03-22 22:43:19 +01:00
] ) ,
2015-03-23 18:10:09 +01:00
React . DOM . footer ( { 'key' : 'footer' , 'className' : 'applicationVersion' } , [
React . DOM . span ( { 'key' : 'applicationVersion' } , "application version" ) ,
React . DOM . a ( { 'key' : 'applicationVersionLink' , 'href' : 'https://github.com/clipperz/password-manager/commit/' + Clipperz _version , 'target' : 'github' } , Clipperz _version )
2015-01-02 10:13:04 +01:00
] )
] ) ;
2015-04-01 18:28:26 +02:00
} ,
renderContent : function ( ) {
return React . DOM . div ( { 'className' : 'extraFeatureContent' } , [
React . DOM . header ( { } , [
React . DOM . div ( { 'className' : 'button' , 'onClick' : this . hideExtraFeatureContent } , "close" )
] ) ,
2015-09-23 13:40:20 +02:00
this . state [ 'extraFeatureContentComponent' ] ? this . state [ 'extraFeatureContentComponent' ] ( this . props ) : null ,
// React.DOM.footer({}, "")
2015-04-01 18:28:26 +02:00
] ) ;
} ,
render : function ( ) {
//console.log("ExtraFeaturesPanel props", this.props);
2015-05-21 14:32:51 +02:00
var isOpen = ( this . props [ 'settingsPanelStatus' ] == 'OPEN' ) ;
var isFullyOpen = isOpen && this . state [ 'isFullyOpen' ] ;
2015-04-01 18:28:26 +02:00
var classes = {
'panel' : true ,
'right' : true ,
2015-05-21 14:32:51 +02:00
'open' : isOpen ,
'fullOpen' : isFullyOpen
2015-04-01 18:28:26 +02:00
}
2015-06-27 19:08:20 +02:00
2015-04-01 18:28:26 +02:00
return React . DOM . div ( { 'key' : 'extraFeaturesPanel' , 'id' : 'extraFeaturesPanel' , 'className' : Clipperz . PM . UI . Components . classNames ( classes ) } , [
this . renderIndex ( ) ,
this . renderContent ( ) ,
2015-05-21 14:32:51 +02:00
// (this.props['settingsPanelStatus'] == 'OPEN') ? this.renderContent() : null,
2015-04-01 18:28:26 +02:00
] ) ;
2014-07-28 18:07:48 +02:00
}
//=========================================================================
} ) ;
2015-03-23 18:10:09 +01:00
Clipperz . PM . UI . Components . Panels . ExtraFeaturesPanel = React . createFactory ( Clipperz . PM . UI . Components . Panels . ExtraFeaturesPanelClass ) ;