mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2024-11-14 07:59:02 +01:00
Added a few feature based on actual subscription options
This commit is contained in:
parent
334affd36d
commit
43b0239ab8
@ -33,6 +33,41 @@ Clipperz.PM.DataModel.User.AccountInfo = function(args) {
|
|||||||
|
|
||||||
Clipperz.Base.extend(Clipperz.PM.DataModel.User.AccountInfo, Object, {
|
Clipperz.Base.extend(Clipperz.PM.DataModel.User.AccountInfo, Object, {
|
||||||
|
|
||||||
|
'status': function () {
|
||||||
|
return this._attributes['currentSubscriptionType'];
|
||||||
|
},
|
||||||
|
|
||||||
|
'level': function () {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
// -1.00 -> EARLY_ADOPTER
|
||||||
|
// 2.00 -> FRIEND
|
||||||
|
// 5.00 -> FAN
|
||||||
|
// 10.00 -> DEVOTEE
|
||||||
|
// 15.00 -> PATRON
|
||||||
|
|
||||||
|
if (this.status() == 'FRIEND') {
|
||||||
|
result = 1;
|
||||||
|
} else if (this.status() == 'FAN') {
|
||||||
|
result = 2;
|
||||||
|
} else if (this.status() == 'DEVOTEE') {
|
||||||
|
result = 3;
|
||||||
|
} else if (this.status() == 'PATRON') {
|
||||||
|
result = 4;
|
||||||
|
} else {
|
||||||
|
result = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
// return this._attributes['latestActiveThreshold'];
|
||||||
|
},
|
||||||
|
|
||||||
|
'isExpiring': function () {
|
||||||
|
return this._attributes['isExpiring'];
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
'features': function () {
|
'features': function () {
|
||||||
return this._attributes['features'];
|
return this._attributes['features'];
|
||||||
},
|
},
|
||||||
@ -48,6 +83,12 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.AccountInfo, Object, {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'isExpired': function () {
|
||||||
|
return this._attributes['isExpired'];
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
__syntaxFix__: "syntax fix"
|
__syntaxFix__: "syntax fix"
|
||||||
});
|
});
|
||||||
|
@ -29,7 +29,7 @@ Clipperz.PM.UI.Components.CardToolbar = React.createClass({
|
|||||||
// 'style': React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired,
|
// 'style': React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired,
|
||||||
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
||||||
'enableSidePanels': React.PropTypes.bool.isRequired,
|
'enableSidePanels': React.PropTypes.bool.isRequired,
|
||||||
'accountStatus': React.PropTypes.object.isRequired,
|
'accountInfo': React.PropTypes.object.isRequired,
|
||||||
'messageBox': React.PropTypes.object.isRequired,
|
'messageBox': React.PropTypes.object.isRequired,
|
||||||
'filter': React.PropTypes.object /*.isRequired */
|
'filter': React.PropTypes.object /*.isRequired */
|
||||||
},
|
},
|
||||||
@ -99,7 +99,7 @@ Clipperz.PM.UI.Components.CardToolbar = React.createClass({
|
|||||||
return React.DOM.div({className:'cardToolbar ' + this.props['style']}, [
|
return React.DOM.div({className:'cardToolbar ' + this.props['style']}, [
|
||||||
// React.DOM.div({className:'header'}, this.props['enableSidePanels'] ? this.renderWithSidePanels() : this.renderWithoutSidePanels()),
|
// React.DOM.div({className:'header'}, this.props['enableSidePanels'] ? this.renderWithSidePanels() : this.renderWithoutSidePanels()),
|
||||||
React.DOM.header({}, this.props['enableSidePanels'] ? this.renderWithSidePanels() : this.renderWithoutSidePanels()),
|
React.DOM.header({}, this.props['enableSidePanels'] ? this.renderWithSidePanels() : this.renderWithoutSidePanels()),
|
||||||
Clipperz.PM.UI.Components.AccountStatus(this.props['accountStatus']),
|
Clipperz.PM.UI.Components.AccountStatus(this.props['accountInfo']),
|
||||||
Clipperz.PM.UI.Components.MessageBox(this.props['messageBox']),
|
Clipperz.PM.UI.Components.MessageBox(this.props['messageBox']),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ Clipperz.PM.UI.Components.Cards.List = React.createClass({
|
|||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
'cards': React.PropTypes.array,
|
'cards': React.PropTypes.array,
|
||||||
|
'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired,
|
||||||
'selectedCard': React.PropTypes.object
|
'selectedCard': React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ Clipperz.PM.UI.Components.Cards.List = React.createClass({
|
|||||||
var cards = this.props['cards'] ? this.props['cards'] : [];
|
var cards = this.props['cards'] ? this.props['cards'] : [];
|
||||||
var classes = {
|
var classes = {
|
||||||
'cardList': true,
|
'cardList': true,
|
||||||
'loadingCard': this.props['selectedCard'] && this.props['selectedCard']['_reference'] && this.props['selectedCard']['loading']
|
'loadingCard': this.props['selectedCard'] && this.props['selectedCard']['_reference'] && this.props['selectedCard']['loading'],
|
||||||
|
'EXPIRED': this.props['featureSet'] == 'EXPIRED',
|
||||||
};
|
};
|
||||||
classes[this.props['style']] = true;
|
classes[this.props['style']] = true;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ Clipperz.Base.module('Clipperz.PM.UI.Components');
|
|||||||
Clipperz.PM.UI.Components.ExpiredPanel = React.createClass({
|
Clipperz.PM.UI.Components.ExpiredPanel = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// featureSet: React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired,
|
// featureSet: React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired,
|
||||||
// 'level': React.PropTypes.oneOf(['hide', 'info', 'warning', 'error']).isRequired
|
// 'level': React.PropTypes.oneOf(['hide', 'info', 'warning', 'error']).isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -28,13 +28,14 @@ Clipperz.PM.UI.Components.Pages.MainPage = React.createClass({
|
|||||||
|
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
return {
|
return {
|
||||||
}
|
featureSet: 'FULL'
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
'messageBox': React.PropTypes.object.isRequired,
|
'messageBox': React.PropTypes.object.isRequired,
|
||||||
// 'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']),
|
'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired,
|
||||||
'accountStatus': React.PropTypes.object.isRequired,
|
'accountInfo': React.PropTypes.object.isRequired,
|
||||||
// 'mediaQueryStyle': React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired,
|
// 'mediaQueryStyle': React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired,
|
||||||
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
||||||
// 'cards': React.PropTypes.deferred.isRequired
|
// 'cards': React.PropTypes.deferred.isRequired
|
||||||
|
@ -35,9 +35,31 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({
|
|||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy');
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'accountInfo': React.PropTypes.object.isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
'account': false,
|
||||||
|
'subscription': false,
|
||||||
|
'data': false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleState: function (section) {
|
||||||
|
return MochiKit.Base.bind(function () {
|
||||||
|
var newState = {};
|
||||||
|
|
||||||
|
newState[section] = !this.state[section];
|
||||||
|
this.setState(newState);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
|
//console.log("ExtraFeaturesPanel props", this.props);
|
||||||
var classes = {
|
var classes = {
|
||||||
'panel': true,
|
'panel': true,
|
||||||
'right': true,
|
'right': true,
|
||||||
@ -52,33 +74,94 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({
|
|||||||
]),
|
]),
|
||||||
|
|
||||||
React.DOM.div({}, [
|
React.DOM.div({}, [
|
||||||
|
React.DOM.ul({}, [
|
||||||
|
React.DOM.li({'className':this.state['account'] ? 'open' : 'closed'}, [
|
||||||
|
React.DOM.h1({'onClick':this.toggleState('account')}, "Account"),
|
||||||
React.DOM.ul({}, [
|
React.DOM.ul({}, [
|
||||||
React.DOM.li({}, [
|
React.DOM.li({}, [
|
||||||
React.DOM.h1({}, "Account"),
|
React.DOM.h2({}, "Passphrase"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
]),
|
]),
|
||||||
React.DOM.li({}, [
|
React.DOM.li({}, [
|
||||||
React.DOM.h1({}, "Data"),
|
React.DOM.h2({}, "One Time Passwords"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "Preferences"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "Delete account"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({'className':this.state['subscription'] ? 'open' : 'closed'}, [
|
||||||
|
React.DOM.h1({'onClick':this.toggleState('subscription')}, "Subscription"),
|
||||||
|
React.DOM.ul({}, [
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "x1"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "x2"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "x3"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "x4"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({'className':this.state['data'] ? 'open' : 'closed'}, [
|
||||||
|
React.DOM.h1({'onClick':this.toggleState('data')}, "Data"),
|
||||||
React.DOM.ul({}, [
|
React.DOM.ul({}, [
|
||||||
React.DOM.li({}, [
|
React.DOM.li({}, [
|
||||||
React.DOM.h2({}, "Offline copy"),
|
React.DOM.h2({}, "Offline copy"),
|
||||||
React.DOM.div({}, [
|
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.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({'onClick':this.handleDownloadOfflineCopyLink}, "Download")
|
React.DOM.a({'className':'button', 'onClick':this.handleDownloadOfflineCopyLink}, "Download")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "Import"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.li({}, [
|
||||||
|
React.DOM.h2({}, "Export"),
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.p({}, "")
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
React.DOM.li({}, [
|
React.DOM.li({}, [
|
||||||
React.DOM.h2({}, "Sharing"),
|
React.DOM.h2({}, "Sharing"),
|
||||||
]),
|
React.DOM.div({}, [
|
||||||
React.DOM.li({}, [
|
React.DOM.p({}, "")
|
||||||
React.DOM.h2({}, "Import"),
|
])
|
||||||
]),
|
|
||||||
React.DOM.li({}, [
|
|
||||||
React.DOM.h2({}, "Export"),
|
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
]),
|
|
||||||
React.DOM.li({}, [
|
|
||||||
React.DOM.h1({}, "Tools"),
|
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
@ -30,16 +30,10 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({
|
|||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
'messageBox': React.PropTypes.object.isRequired,
|
'messageBox': React.PropTypes.object.isRequired,
|
||||||
'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired,
|
'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired,
|
||||||
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function () {
|
|
||||||
return {
|
|
||||||
featureSet: 'FULL'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
style: function () {
|
style: function () {
|
||||||
return this.props['style'];
|
return this.props['style'];
|
||||||
},
|
},
|
||||||
@ -66,7 +60,13 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderCardFrame: function (firstColumnComponents, secondColumnComponents) {
|
renderCardFrame: function (firstColumnComponents, secondColumnComponents) {
|
||||||
var addCardButton = React.DOM.div({'className': 'addCardButton', 'onClick':this.handleAddCardClick}, 'add card');
|
var addCardButton;
|
||||||
|
|
||||||
|
if ((this.props['featureSet'] != 'EXPIRED') && (this.props['featureSet'] != 'OFFLINE')) {
|
||||||
|
addCardButton = React.DOM.div({'className': 'addCardButton', 'onClick':this.handleAddCardClick}, 'add card');
|
||||||
|
} else {
|
||||||
|
addCardButton = null;
|
||||||
|
}
|
||||||
|
|
||||||
return React.DOM.div({'key':'cardContent', 'className':'cardContent'}, [
|
return React.DOM.div({'key':'cardContent', 'className':'cardContent'}, [
|
||||||
React.DOM.div({'className':'cardListColumn column'}, [addCardButton, firstColumnComponents]),
|
React.DOM.div({'className':'cardListColumn column'}, [addCardButton, firstColumnComponents]),
|
||||||
@ -82,7 +82,8 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({
|
|||||||
cardToolbarProps = MochiKit.Base.merge(this.props, {
|
cardToolbarProps = MochiKit.Base.merge(this.props, {
|
||||||
'key': 'toolbar',
|
'key': 'toolbar',
|
||||||
'style': this.style(),
|
'style': this.style(),
|
||||||
'enableSidePanels': (this.props['featureSet'] != 'EXPIRED')
|
// 'enableSidePanels': (this.props['featureSet'] != 'EXPIRED')
|
||||||
|
'enableSidePanels': true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return Clipperz.PM.UI.Components.CardToolbar(cardToolbarProps);
|
return Clipperz.PM.UI.Components.CardToolbar(cardToolbarProps);
|
||||||
|
@ -581,6 +581,7 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
var fullFilterCriteria;
|
var fullFilterCriteria;
|
||||||
var selectedCardReference = this._selectedCardInfo ? this._selectedCardInfo['reference'] : null;
|
var selectedCardReference = this._selectedCardInfo ? this._selectedCardInfo['reference'] : null;
|
||||||
|
|
||||||
|
//console.log("updateSelectedCards - ACCOUNT INFO.featureSet", this.userAccountInfo()['featureSet']);
|
||||||
if (aFilter['type'] == 'ALL') {
|
if (aFilter['type'] == 'ALL') {
|
||||||
filterCriteria = MochiKit.Base.operator.truth;
|
filterCriteria = MochiKit.Base.operator.truth;
|
||||||
sortCriteria = Clipperz.Base.caseInsensitiveKeyComparator('label');
|
sortCriteria = Clipperz.Base.caseInsensitiveKeyComparator('label');
|
||||||
@ -884,7 +885,7 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
level = 'HIDE';
|
level = 'HIDE';
|
||||||
|
|
||||||
//console.log("messageBox - this.user()", this.user());
|
//console.log("messageBox - this.user()", this.user());
|
||||||
if (this.user() != null && this.user().accountInfo() != null && this.user().accountInfo().featureSet() == 'EXPIRED') {
|
if (this.userAccountInfo()['featureSet'] == 'EXPIRED') {
|
||||||
message = "Exprired subscription";
|
message = "Exprired subscription";
|
||||||
level = 'ERROR';
|
level = 'ERROR';
|
||||||
}
|
}
|
||||||
@ -905,6 +906,7 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
'currentSubscriptionType',
|
'currentSubscriptionType',
|
||||||
'expirationDate',
|
'expirationDate',
|
||||||
'featureSet',
|
'featureSet',
|
||||||
|
'features',
|
||||||
'isExpired',
|
'isExpired',
|
||||||
'isExpiring',
|
'isExpiring',
|
||||||
'paymentVerificationPending'
|
'paymentVerificationPending'
|
||||||
@ -944,9 +946,10 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
} else if (aPageName == 'mainPage') {
|
} else if (aPageName == 'mainPage') {
|
||||||
extraProperties = {
|
extraProperties = {
|
||||||
'messageBox': this.messageBoxContent(),
|
'messageBox': this.messageBoxContent(),
|
||||||
'accountStatus': this.userAccountInfo(),
|
'accountInfo': this.userAccountInfo(),
|
||||||
'selectionPanelStatus': this.isSelectionPanelOpen() ? 'OPEN' : 'CLOSED',
|
'selectionPanelStatus': this.isSelectionPanelOpen() ? 'OPEN' : 'CLOSED',
|
||||||
'settingsPanelStatus': this.isSettingsPanelOpen() ? 'OPEN' : 'CLOSED',
|
'settingsPanelStatus': this.isSettingsPanelOpen() ? 'OPEN' : 'CLOSED',
|
||||||
|
'featureSet': this.userAccountInfo()['featureSet'],
|
||||||
// 'shouldIncludeArchivedCards': this.shouldIncludeArchivedCards(),
|
// 'shouldIncludeArchivedCards': this.shouldIncludeArchivedCards(),
|
||||||
// 'cards': …,
|
// 'cards': …,
|
||||||
// 'tags': …,
|
// 'tags': …,
|
||||||
@ -1135,9 +1138,15 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
},
|
},
|
||||||
|
|
||||||
selectCard_handler: function (someInfo, shouldUpdateCardDetail) {
|
selectCard_handler: function (someInfo, shouldUpdateCardDetail) {
|
||||||
|
if (this.userAccountInfo()['featureSet'] != 'EXPIRED') {
|
||||||
this._selectedCardInfo = someInfo;
|
this._selectedCardInfo = someInfo;
|
||||||
this.refreshSelectedCards();
|
this.refreshSelectedCards();
|
||||||
this.updateSelectedCard(someInfo, true, shouldUpdateCardDetail);
|
this.updateSelectedCard(someInfo, true, shouldUpdateCardDetail);
|
||||||
|
|
||||||
|
// # TODO: make the selected element visible;
|
||||||
|
// this may not always be the case, as selection can also be changed using keys.
|
||||||
|
// MochiKit.Visual.ScrollTo(MochiKit.DOM.getElement("xxx"));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
refreshCardEditDetail_handler: function (aRecordReference) {
|
refreshCardEditDetail_handler: function (aRecordReference) {
|
||||||
|
Loading…
Reference in New Issue
Block a user