1
0
mirror of http://git.whoc.org.uk/git/password-manager.git synced 2024-11-14 07:59:02 +01:00

Added basic behaviour for extra panel components

This commit is contained in:
Giulio Cesare Solaroli 2015-04-01 18:28:26 +02:00
parent 04e5b7fb02
commit b1de7de2c5
10 changed files with 463 additions and 189 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -27,6 +27,7 @@
"name": "key" "name": "key"
}, },
"setIdx": 1, "setIdx": 1,
"setId": 7,
"iconIdx": 141 "iconIdx": 141
}, },
{ {
@ -55,6 +56,7 @@
"name": "eye" "name": "eye"
}, },
"setIdx": 1, "setIdx": 1,
"setId": 7,
"iconIdx": 206 "iconIdx": 206
}, },
{ {
@ -80,6 +82,7 @@
"ligatures": "tag" "ligatures": "tag"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 0 "iconIdx": 0
}, },
{ {
@ -106,6 +109,7 @@
"ligatures": "tags" "ligatures": "tags"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 1 "iconIdx": 1
}, },
{ {
@ -132,6 +136,7 @@
"ligatures": "recent" "ligatures": "recent"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 2 "iconIdx": 2
}, },
{ {
@ -160,6 +165,7 @@
"ligatures": "loading" "ligatures": "loading"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 3 "iconIdx": 3
}, },
{ {
@ -187,6 +193,7 @@
"ligatures": "search" "ligatures": "search"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 4 "iconIdx": 4
}, },
{ {
@ -214,6 +221,7 @@
"ligatures": "locked" "ligatures": "locked"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 6 "iconIdx": 6
}, },
{ {
@ -239,6 +247,7 @@
"ligatures": "unlocked" "ligatures": "unlocked"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 7 "iconIdx": 7
}, },
{ {
@ -267,6 +276,7 @@
"ligatures": "menu" "ligatures": "menu"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 8 "iconIdx": 8
}, },
{ {
@ -292,9 +302,10 @@
"prevSize": 32, "prevSize": 32,
"code": 58882, "code": 58882,
"name": "close", "name": "close",
"ligatures": "failure, failed, delete, clear, cancel" "ligatures": "failure, failed, delete, clear, cancel, close"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 9 "iconIdx": 9
}, },
{ {
@ -323,6 +334,7 @@
"ligatures": "done, ok, save" "ligatures": "done, ok, save"
}, },
"setIdx": 2, "setIdx": 2,
"setId": 6,
"iconIdx": 10 "iconIdx": 10
}, },
{ {
@ -347,6 +359,7 @@
"ligatures": "commands" "ligatures": "commands"
}, },
"setIdx": 3, "setIdx": 3,
"setId": 4,
"iconIdx": 0 "iconIdx": 0
}, },
{ {
@ -369,6 +382,7 @@
"ligatures": "clipperz" "ligatures": "clipperz"
}, },
"setIdx": 3, "setIdx": 3,
"setId": 4,
"iconIdx": 1 "iconIdx": 1
}, },
{ {
@ -395,6 +409,7 @@
"ligatures": "email" "ligatures": "email"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 4 "iconIdx": 4
}, },
{ {
@ -418,6 +433,7 @@
"ligatures": "url, direct login" "ligatures": "url, direct login"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 35 "iconIdx": 35
}, },
{ {
@ -441,6 +457,7 @@
"ligatures": "add new field" "ligatures": "add new field"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 125 "iconIdx": 125
}, },
{ {
@ -466,6 +483,7 @@
"ligatures": "remove field, remove tag" "ligatures": "remove field, remove tag"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 126 "iconIdx": 126
}, },
{ {
@ -489,6 +507,7 @@
"ligatures": "add card" "ligatures": "add card"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 128 "iconIdx": 128
}, },
{ {
@ -512,6 +531,7 @@
"ligatures": "back" "ligatures": "back"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 205 "iconIdx": 205
}, },
{ {
@ -535,6 +555,7 @@
"ligatures": "show detail" "ligatures": "show detail"
}, },
"setIdx": 6, "setIdx": 6,
"setId": 0,
"iconIdx": 208 "iconIdx": 208
} }
], ],

View File

@ -0,0 +1,46 @@
/*
Copyright 2008-2015 Clipperz Srl
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/.
*/
"use strict";
Clipperz.Base.module('Clipperz.PM.UI.Components.ExtraFeatures');
Clipperz.PM.UI.Components.ExtraFeatures.DevicePINClass = React.createClass({
propTypes: {
// featureSet: React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired,
// 'level': React.PropTypes.oneOf(['hide', 'info', 'warning', 'error']).isRequired
},
//=========================================================================
render: function () {
return React.DOM.div({className:'extraFeature devicePIN'}, [
React.DOM.h1({}, "Device PIN"),
React.DOM.h3({}, this.props['PIN'])
]);
},
//=========================================================================
});
Clipperz.PM.UI.Components.ExtraFeatures.DevicePIN = React.createFactory(Clipperz.PM.UI.Components.ExtraFeatures.DevicePINClass);

View File

@ -28,6 +28,7 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
settingsToggleHandler: function (anEvent) { settingsToggleHandler: function (anEvent) {
//console.log("settingsToggleHandler"); //console.log("settingsToggleHandler");
this.hideExtraFeatureContent();
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'toggleSettingsPanel'); MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'toggleSettingsPanel');
}, },
@ -43,17 +44,20 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {
'account': false, 'index': {
'subscription': false, 'account': false,
'data': false, 'subscription': false,
'data': false,
},
'isFullyOpen': false
}; };
}, },
toggleState: function (section) { toggleIndexState: function (section) {
return MochiKit.Base.bind(function () { return MochiKit.Base.bind(function () {
var newState = {}; var newState = { 'index': {} };
newState[section] = !this.state[section]; newState['index'][section] = !this.state['index'][section];
this.setState(newState); this.setState(newState);
}, this); }, this);
}, },
@ -64,20 +68,46 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
//========================================================================= //=========================================================================
render: function () { // showDevicePin: function () {
//console.log("ExtraFeaturesPanel props", this.props); // this.showExtraFeatureContent(Clipperz.PM.UI.Components.ExtraFeatures.DevicePIN());
var classes = { // },
'panel': true,
'right': true, showExtraFeatureComponent: function (aComponentName) {
'open': this.props['settingsPanelStatus'] == 'OPEN' return MochiKit.Base.bind(function () {
} this.showExtraFeatureContent(Clipperz.PM.UI.Components.ExtraFeatures[aComponentName]);
}, this);
},
extraFeaturesProps: function () {
return this.props;
},
//-------------------------------------------------------------------------
hideExtraFeatureContent: function () {
this.setState({'isFullyOpen':false});
},
showExtraFeatureContent: function (aComponent) {
this.setState({
'isFullyOpen':true,
'extraFeatureContent': aComponent(this.extraFeaturesProps())
});
},
toggleExtraFeatureContent: function () {
this.setState({'isFullyOpen':!this.state['isFullyOpen']});
},
//=========================================================================
renderIndex: function () {
var offlineCopyButtonClasses = { var offlineCopyButtonClasses = {
'button': true, 'button': true,
'disabled': !this.isFeatureEnabled('OFFLINE_COPY') 'disabled': !this.isFeatureEnabled('OFFLINE_COPY')
} }
return React.DOM.div({'key':'extraFeaturesPanel', 'id':'extraFeaturesPanel', 'className':Clipperz.PM.UI.Components.classNames(classes)}, [ return React.DOM.div({'className':'extraFeatureIndex'}, [
React.DOM.header({'key':'header'}, [ React.DOM.header({'key':'header'}, [
React.DOM.div({'key':'headerDiv', 'className':'settingsToggle'}, [ React.DOM.div({'key':'headerDiv', 'className':'settingsToggle'}, [
Clipperz.PM.UI.Components.Button({'key':'button', 'eventName':'settingsToggleButton', 'label':"menu", 'handler':this.settingsToggleHandler}) Clipperz.PM.UI.Components.Button({'key':'button', 'eventName':'settingsToggleButton', 'label':"menu", 'handler':this.settingsToggleHandler})
@ -86,8 +116,8 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
React.DOM.div({'key':'ulWrapper'}, [ React.DOM.div({'key':'ulWrapper'}, [
React.DOM.ul({'key':'ul'}, [ React.DOM.ul({'key':'ul'}, [
React.DOM.li({'key':'account', 'className':this.state['account'] ? 'open' : 'closed'}, [ React.DOM.li({'key':'account', 'className':this.state['index']['account'] ? 'open' : 'closed'}, [
React.DOM.h1({'key':'accountH1', 'onClick':this.toggleState('account')}, "Account"), React.DOM.h1({'key':'accountH1', 'onClick':this.toggleIndexState('account')}, "Account"),
React.DOM.ul({'key':'accountUL'}, [ React.DOM.ul({'key':'accountUL'}, [
React.DOM.li({'key':'account_1'}, [ React.DOM.li({'key':'account_1'}, [
React.DOM.h2({'key':'account_1_h2'}, "Passphrase"), React.DOM.h2({'key':'account_1_h2'}, "Passphrase"),
@ -101,7 +131,7 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
React.DOM.p({}, "") React.DOM.p({}, "")
]) ])
]), ]),
React.DOM.li({'key':'account_3'}, [ React.DOM.li({'key':'account_3', 'onClick':this.showExtraFeatureComponent('DevicePIN')}, [
React.DOM.h2({}, "Device PIN"), React.DOM.h2({}, "Device PIN"),
React.DOM.div({}, [ React.DOM.div({}, [
React.DOM.p({}, "Configure a PIN that will allow to get access to your cards, but only on this device.") React.DOM.p({}, "Configure a PIN that will allow to get access to your cards, but only on this device.")
@ -121,8 +151,8 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
]) ])
]) ])
]), ]),
React.DOM.li({'key':'subscription', 'className':this.state['subscription'] ? 'open' : 'closed'}, [ React.DOM.li({'key':'subscription', 'className':this.state['index']['subscription'] ? 'open' : 'closed'}, [
React.DOM.h1({'onClick':this.toggleState('subscription')}, "Subscription"), React.DOM.h1({'onClick':this.toggleIndexState('subscription')}, "Subscription"),
React.DOM.ul({'key':'subscription'}, [ React.DOM.ul({'key':'subscription'}, [
React.DOM.li({'key':'subscription_1'}, [ React.DOM.li({'key':'subscription_1'}, [
React.DOM.h2({}, "x1"), React.DOM.h2({}, "x1"),
@ -150,8 +180,8 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
]) ])
]) ])
]), ]),
React.DOM.li({'key':'data', 'className':this.state['data'] ? 'open' : 'closed'}, [ React.DOM.li({'key':'data', 'className':this.state['index']['data'] ? 'open' : 'closed'}, [
React.DOM.h1({'onClick':this.toggleState('data')}, "Data"), React.DOM.h1({'onClick':this.toggleIndexState('data')}, "Data"),
React.DOM.ul({'key':'data'}, [ React.DOM.ul({'key':'data'}, [
React.DOM.li({'key':'data_1'}, [ React.DOM.li({'key':'data_1'}, [
React.DOM.h2({}, "Offline copy"), React.DOM.h2({}, "Offline copy"),
@ -187,6 +217,31 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanelClass = React.createClass({
React.DOM.a({'key':'applicationVersionLink', 'href':'https://github.com/clipperz/password-manager/commit/' + Clipperz_version, 'target':'github'}, Clipperz_version) React.DOM.a({'key':'applicationVersionLink', 'href':'https://github.com/clipperz/password-manager/commit/' + Clipperz_version, 'target':'github'}, Clipperz_version)
]) ])
]); ]);
},
renderContent: function () {
return React.DOM.div({'className':'extraFeatureContent'}, [
React.DOM.header({}, [
React.DOM.div({'className':'button', 'onClick':this.hideExtraFeatureContent}, "close")
]),
this.state['extraFeatureContent']
]);
},
render: function () {
//console.log("ExtraFeaturesPanel props", this.props);
var classes = {
'panel': true,
'right': true,
'open': this.props['settingsPanelStatus'] == 'OPEN',
'fullOpen': this.state['isFullyOpen']
}
return React.DOM.div({'key':'extraFeaturesPanel', 'id':'extraFeaturesPanel', 'className':Clipperz.PM.UI.Components.classNames(classes)}, [
this.renderIndex(),
this.renderContent(),
]);
} }
//========================================================================= //=========================================================================

View File

@ -167,6 +167,8 @@
"Clipperz/PM/UI/Components/Panels/MainPanel.js", "Clipperz/PM/UI/Components/Panels/MainPanel.js",
"Clipperz/PM/UI/Components/Panels/ExtraFeaturesPanel.js", "Clipperz/PM/UI/Components/Panels/ExtraFeaturesPanel.js",
"Clipperz/PM/UI/Components/ExtraFeatures/DevicePIN.js",
"Clipperz/PM/UI/Components/Cards/FavIcon.js", "Clipperz/PM/UI/Components/Cards/FavIcon.js",
"Clipperz/PM/UI/Components/Cards/List.js", "Clipperz/PM/UI/Components/Cards/List.js",
"Clipperz/PM/UI/Components/Cards/Detail.js", "Clipperz/PM/UI/Components/Cards/Detail.js",

View File

@ -64,6 +64,7 @@ $transition-duration: 0.5s;
top: 0; top: 0;
left: -$size; left: -$size;
// transition: left 0.3s ease-in-out;
} }
@mixin sliding-panel-right ($size) { @mixin sliding-panel-right ($size) {
@ -74,6 +75,7 @@ $transition-duration: 0.5s;
top: 0; top: 0;
right: -$size; right: -$size;
transition: right 0.3s ease-in-out;
} }
@mixin sliding-panel ($side, $size) { @mixin sliding-panel ($side, $size) {
@ -107,11 +109,13 @@ $transition-duration: 0.5s;
@mixin sliding-panel-wrapper-open-left ($size) { @mixin sliding-panel-wrapper-open-left ($size) {
top: 0; top: 0;
left: $size; left: $size;
// transition: left 0.3s ease-in-out;
} }
@mixin sliding-panel-wrapper-open-right ($size) { @mixin sliding-panel-wrapper-open-right ($size) {
top: 0; top: 0;
right: $size; right: $size;
// transition: right 0.3s ease-in-out;
} }
@mixin sliding-panel-wrapper-open ($side, $size) { @mixin sliding-panel-wrapper-open ($side, $size) {

File diff suppressed because one or more lines are too long

View File

@ -40,7 +40,7 @@ html {
.mainPage > #selectionPanel { .mainPage > #selectionPanel {
@include sliding-panel(left, $selectionPanelWidth); @include sliding-panel(left, $selectionPanelWidth);
&.open { &.open {
@include sliding-panel-open(left, $selectionPanelWidth); @include sliding-panel-open(left, $selectionPanelWidth);
} }
@ -123,12 +123,14 @@ html {
} }
&.wide { &.wide {
// transition: left 0.3s ease-in-out;
.container { .container {
@include sliding-panel-container(); @include sliding-panel-container();
} }
} }
&.narrow { &.narrow {
// transition: left 0.3s ease-in-out;
.container { .container {
@include sliding-panel-container(); @include sliding-panel-container();
} }
@ -143,6 +145,7 @@ html {
} }
&.open.left { &.open.left {
// transition: left 0.3s ease-in-out;
@include sliding-panel-wrapper-open (left, $selectionPanelWidth); @include sliding-panel-wrapper-open (left, $selectionPanelWidth);
@include mask(); @include mask();
} }
@ -154,30 +157,72 @@ html {
} }
.mainPage.narrow {
#extraFeaturesPanel {
&.fullOpen {
.extraFeatureIndex {
width: 0px;
}
}
}
}
#extraFeaturesPanel { #extraFeaturesPanel {
@include sliding-panel(right, $settingsPanelWidth); @include sliding-panel(right, $settingsPanelWidth);
@include flexbox();
@include flex-direction(column); // transition: right 0.3s ease-in-out;
min-height: 100%;
&.open { &.open {
@include sliding-panel-open(right, $settingsPanelWidth); @include sliding-panel-open(right, $settingsPanelWidth);
} }
header { .extraFeatureContent {
@include flex(none); display: none;
}
& > div {
@include flex(auto);
overflow: auto;
} }
footer { &.fullOpen {
// right: 0px;
width: 100%;
.extraFeatureContent {
display: block;
}
}
@include flexbox();
@include flex-direction(row-reverse);
.extraFeatureIndex {
@include flex(none); @include flex(none);
width: $settingsPanelWidth;
height: 100%;
@include flexbox();
@include flex-direction(column);
header {
@include flex(none);
}
& > div {
@include flex(auto);
overflow: auto;
}
footer {
@include flex(none);
}
}
.extraFeatureContent {
// display: none;
@include flex(auto);
width: 100%;
height: 100%;
// background-color: rgba( 0, 0, 0, 0.95);
background-color: black;
} }
} }

View File

@ -22,129 +22,163 @@ refer to http://www.clipperz.com.
*/ */
#extraFeaturesPanel { #extraFeaturesPanel {
background-color: $main-alternate-color; .extraFeatureIndex {
color: $main-alternate-text-color; background-color: $main-alternate-color;
color: $main-alternate-text-color;
header {
text-align: right;
height: 48px;
font-size: 24pt;
.button { header {
@include icon-font(); text-align: right;
height: 48px;
font-size: 24pt;
.label { .button {
padding-top: 8px; @include icon-font();
padding-right: 8px;
.label {
padding-top: 8px;
padding-right: 8px;
}
} }
} }
}
& > div { & > div {
border-top: 1px solid white; border-top: 1px solid white;
& > ul > li { & > ul > li {
// padding: 10px; // padding: 10px;
// padding-right: 0px; // padding-right: 0px;
border-bottom: 1px solid white; border-bottom: 1px solid white;
& > ul { & > ul {
padding-left: 10px; padding-left: 10px;
}
// &:last-child {
// border-bottom: 1px solid white;
// }
&.closed > ul {
display: none;
visibility: hidden;
}
} }
// &:last-child { ul {
// border-bottom: 1px solid white;
// } li {
& > ul > li {
&.closed > ul { padding: 10px;
display: none; padding-right: 0px;
visibility: hidden;
& > div {
padding: 4px;
}
}
&.open {
}
&.close {
}
h1 {
cursor: pointer;
font-size: 16pt;
padding: 10px;
}
h2 {
font-weight: 300;
font-size: 14pt;
}
h3 {
font-size: 12pt;
}
p {
font-size: 10pt;
font-weight: 100;
padding-bottom: 5px;
line-height: 1.2em;
}
a.button {
@include border-radius(2);
display: inline-block;
padding: 10px 16px;
background-color: green;
color: white;
&:hover {
color: lightgrey;
};
&.disabled {
background-color: #999;
&:hover {
color: white;
};
}
}
}
} }
} }
footer {
$applicationVersionColor: #999;
font-size: 8pt;
padding: 5px 5px 5px 5px;
border-top: 1px solid $applicationVersionColor;
ul { span {
color: $applicationVersionColor;
li { &:after {
& > ul > li { content: ":";
padding: 10px; };
padding-right: 0px; }
a {
& > div { color: $applicationVersionColor;
padding: 4px; text-decoration: none;
} padding-left: 5px;
} font-weight: bold;
&.open {
}
&.close {
}
h1 {
cursor: pointer;
font-size: 16pt;
padding: 10px;
}
h2 {
font-weight: 300;
font-size: 14pt;
}
h3 {
font-size: 12pt;
}
p {
font-size: 10pt;
font-weight: 100;
padding-bottom: 5px;
line-height: 1.2em;
}
a.button {
@include border-radius(2);
display: inline-block;
padding: 10px 16px;
background-color: green;
color: white;
&:hover {
color: lightgrey;
};
&.disabled {
background-color: #999;
&:hover {
color: white;
};
}
}
} }
} }
} }
footer {
$applicationVersionColor: #999;
font-size: 8pt;
padding: 5px 5px 5px 5px;
border-top: 1px solid $applicationVersionColor;
span { .extraFeatureContent {
color: $applicationVersionColor; border-right: 1px solid #222;
&:after { color: white;
content: ":";
}; header {
} display: none;
a {
color: $applicationVersionColor;
text-decoration: none;
padding-left: 5px;
font-weight: bold;
} }
} }
} }
.mainPage.narrow {
#extraFeaturesPanel {
.extraFeatureContent {
header {
display: block;
height: 48px;
border-bottom : 1px solid white;
.button {
@include icon-font();
cursor: pointer;
color: white;
font-size: 16pt;
padding-top: 15px;
padding-left: 10px;
}
}
}
}
}