mirror of
				http://git.whoc.org.uk/git/password-manager.git
				synced 2025-10-31 11:27:34 +01:00 
			
		
		
		
	Many small overall UI improvements
- proxy are now aware of their respective features; - updated account status info and added also proxy info (especially to show when using an offline copy) - conditionally enabled different features across the UI, based on user account / proxy available features
This commit is contained in:
		| @@ -936,7 +936,7 @@ div.cardContent { | ||||
|     overflow: auto; | ||||
|     z-index: 5; | ||||
|     box-shadow: 2px 0 6px 0 rgba(0, 0, 0, 0.1); } | ||||
|     div.cardContent div.cardListColumn.column div.cardList { | ||||
|     div.cardContent div.cardListColumn.column.addCard div.cardList { | ||||
|       padding-bottom: 100px; } | ||||
|     div.cardContent div.cardListColumn.column div.addCardButton { | ||||
|       font-family: 'clipperz-icons'; | ||||
| @@ -1935,32 +1935,35 @@ span.count { | ||||
|       #extraFeaturesPanel > div ul li a.button:hover { | ||||
|         color: lightgrey; } | ||||
| 
 | ||||
| .accountStatus { | ||||
| .miscInfo .proxyInfo { | ||||
|   border-bottom: 1px solid white; | ||||
|   display: none; | ||||
|   visibility: hidden; } | ||||
|   .miscInfo .proxyInfo.OFFLINE_COPY { | ||||
|     display: block; | ||||
|     visibility: visible; | ||||
|     background-color: #1863a1; | ||||
|     color: white; } | ||||
|     .miscInfo .proxyInfo.OFFLINE_COPY .referenceDate { | ||||
|       padding-left: 10px; } | ||||
| .miscInfo .accountStatus { | ||||
|   border-bottom: 1px solid white; | ||||
|   background-color: green; | ||||
|   padding: 3px; | ||||
|   font-size: 10pt; | ||||
|   border-bottom: 1px solid white; } | ||||
|   .accountStatus.FULL { | ||||
|   font-size: 10pt; } | ||||
|   .miscInfo .accountStatus.FULL { | ||||
|     display: none; | ||||
|     visibility: hidden; } | ||||
|     .accountStatus.FULL.isExpiring { | ||||
|     .miscInfo .accountStatus.FULL.isExpiring { | ||||
|       display: block; | ||||
|       visibility: visible; | ||||
|       background-color: yellow; } | ||||
|   .accountStatus.TRIAL { | ||||
|   .miscInfo .accountStatus.TRIAL { | ||||
|     background-color: orange; } | ||||
|     .accountStatus.TRIAL.isExpiring { | ||||
|     .miscInfo .accountStatus.TRIAL.isExpiring { | ||||
|       background-color: red; } | ||||
|   .accountStatus.EXPIRED { | ||||
|   .miscInfo .accountStatus.EXPIRED { | ||||
|     background-color: red; } | ||||
|   .accountStatus.OFFLINE_COPY { | ||||
|     background-color: #1863a1; | ||||
|     color: white; } | ||||
|     .accountStatus.OFFLINE_COPY .expirationDate { | ||||
|       display: none; | ||||
|       visibility: hidden; } | ||||
|     .accountStatus.OFFLINE_COPY .referenceDate { | ||||
|       padding-left: 10px; } | ||||
| 
 | ||||
| div.cardList.loadingCard li.selected { | ||||
|   background-color: gray; } | ||||
|   | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -4,28 +4,30 @@ | ||||
| 		{ | ||||
| 			"icon": { | ||||
| 				"paths": [ | ||||
| 					"M640.9 63.9c-141.4 0-256 114.6-256 256 0 19.6 2.2 38.6 6.4 56.9l-391.3 391.2v64l64 64h128l64-64v-64h64v-64h64v-64h128l70.8-70.8c18.7 4.3 38.1 6.6 58.1 6.6 141.4 0 256-114.6 256-256s-114.7-255.9-256-255.9zM384 512l-320 320v-64l320-320v64zM704 320c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64c0 35.3-28.7 64-64 64z" | ||||
| 					"M704 0c-176.73 0-320 143.268-320 320 0 20.026 1.858 39.616 5.376 58.624l-389.376 389.376v192c0 35.346 28.654 64 64 64h64v-64h128v-128h128v-128h128l83.042-83.042c34.010 12.316 70.696 19.042 108.958 19.042 176.73 0 320-143.268 320-320s-143.27-320-320-320zM799.874 320.126c-53.020 0-96-42.98-96-96s42.98-96 96-96 96 42.98 96 96-42.98 96-96 96z" | ||||
| 				], | ||||
| 				"width": 896, | ||||
| 				"attrs": [], | ||||
| 				"isMulticolor": false, | ||||
| 				"tags": [ | ||||
| 					"key" | ||||
| 					"key", | ||||
| 					"password", | ||||
| 					"login", | ||||
| 					"signin" | ||||
| 				], | ||||
| 				"defaultCode": 61513, | ||||
| 				"defaultCode": 57802, | ||||
| 				"grid": 16 | ||||
| 			}, | ||||
| 			"attrs": [], | ||||
| 			"properties": { | ||||
| 				"id": 91, | ||||
| 				"order": 23, | ||||
| 				"id": 548, | ||||
| 				"order": 26, | ||||
| 				"prevSize": 32, | ||||
| 				"code": 61513, | ||||
| 				"name": "key", | ||||
| 				"ligatures": "generate password" | ||||
| 				"code": 59789, | ||||
| 				"ligatures": "generate password", | ||||
| 				"name": "key" | ||||
| 			}, | ||||
| 			"setIdx": 0, | ||||
| 			"iconIdx": 91 | ||||
| 			"setIdx": 1, | ||||
| 			"iconIdx": 141 | ||||
| 		}, | ||||
| 		{ | ||||
| 			"icon": { | ||||
|   | ||||
| @@ -131,6 +131,20 @@ Clipperz.PM.Proxy.prototype = MochiKit.Base.update(null, { | ||||
|  | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	'type': function () { | ||||
| 		throw Clipperz.Base.exception.AbstractMethod; | ||||
| 	}, | ||||
|  | ||||
| 	'typeDescription': function () { | ||||
| 		throw Clipperz.Base.exception.AbstractMethod; | ||||
| 	}, | ||||
|  | ||||
| 	'features': function (someFeatures) { | ||||
| 		throw Clipperz.Base.exception.AbstractMethod; | ||||
| 	}, | ||||
|  | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	'processMessage': function (aFunctionName, someParameters, aRequestType) { | ||||
| 		var	deferredResult; | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,20 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.JSON, Clipperz.PM.Proxy, { | ||||
| 		return this._url; | ||||
| 	}, | ||||
|  | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	'type': function () { | ||||
| 		return 'ONLINE'; | ||||
| 	}, | ||||
|  | ||||
| 	'typeDescription': function () { | ||||
| 		return 'Online service'; | ||||
| 	}, | ||||
|  | ||||
| 	'features': function (someFeatures) { | ||||
| 		return someFeatures; | ||||
| 	}, | ||||
|  | ||||
| 	//========================================================================= | ||||
| 	 | ||||
| 	'_sendMessage': function(aFunctionName, aVersion, someParameters) { | ||||
|   | ||||
| @@ -21,6 +21,7 @@ refer to http://www.clipperz.com. | ||||
|  | ||||
| */ | ||||
|  | ||||
|  | ||||
| if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | ||||
| if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | ||||
|  | ||||
| @@ -32,6 +33,8 @@ Clipperz.PM.Proxy.Offline = function(args) { | ||||
| 	Clipperz.PM.Proxy.Offline.superclass.constructor.call(this, args); | ||||
|  | ||||
| 	this._dataStore = args.dataStore || new Clipperz.PM.Proxy.Offline.DataStore(args); | ||||
| 	this._type = args.type || 'OFFLINE'; | ||||
| 	this._typeDescription = args.typeDescription || 'Offline'; | ||||
|  | ||||
| 	return this; | ||||
| } | ||||
| @@ -64,7 +67,29 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline, Clipperz.PM.Proxy, { | ||||
| 		return this.dataStore().canRegisterNewUsers(); | ||||
| 	}, | ||||
|  | ||||
| 	//------------------------------------------------------------------------- | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	'type': function () { | ||||
| 		return this._type; | ||||
| 	}, | ||||
|  | ||||
| 	'typeDescription': function () { | ||||
| 		return this._typeDescription; | ||||
| 	}, | ||||
|  | ||||
| 	'features': function (someFeatures) { | ||||
| 		var	result; | ||||
| 		 | ||||
| 		if (this.type() == 'OFFLINE_COPY') { | ||||
| 			result = ['LIST_CARDS', 'CARD_DETAILS']; | ||||
| 		} else { | ||||
| 			result = someFeatures; | ||||
| 		} | ||||
| 		 | ||||
| 		return result; | ||||
| 	}, | ||||
|  | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	__syntaxFix__: "syntax fix" | ||||
| 	 | ||||
|   | ||||
| @@ -21,6 +21,7 @@ refer to http://www.clipperz.com. | ||||
|  | ||||
| */ | ||||
|  | ||||
| "use strict"; | ||||
| Clipperz.Base.module('Clipperz.PM.UI.Components'); | ||||
|  | ||||
| Clipperz.PM.UI.Components.AccountStatus = React.createClass({ | ||||
| @@ -28,7 +29,9 @@ Clipperz.PM.UI.Components.AccountStatus = React.createClass({ | ||||
| 	propTypes: { | ||||
| //		'currentSubscriptionType':		React.PropTypes.oneOf(['EARLY_ADOPTER', 'FRIEND', 'FAN', 'DEVOTEE', 'PATRON', 'TRIAL', 'TRIAL_EXPIRED', 'PAYMENT_FAILED_2', 'EXPIRED', 'PAYMENT_FAILED', 'VERIFYING_PAYMENT', 'VERIFYING_PAYMENT_2']).isRequired, | ||||
| 		'expirationDate':				React.PropTypes.string /* .isRequired */, | ||||
| 		'referenceDate':				React.PropTypes.string /* .isRequired */, | ||||
| 		'featureSet':					React.PropTypes.oneOf(['TRIAL', 'EXPIRED', 'FULL']) /* .isRequired */ , | ||||
| 		'proxyType':					React.PropTypes.oneOf(['ONLINE', 'OFFLINE', 'OFFLINE_COPY']), | ||||
| 		'isExpired':					React.PropTypes.bool /* .isRequired */ , | ||||
| 		'isExpiring':					React.PropTypes.bool /* .isRequired */ , | ||||
| 		'paymentVerificationPending':	React.PropTypes.bool /* .isRequired */ , | ||||
| @@ -38,18 +41,30 @@ Clipperz.PM.UI.Components.AccountStatus = React.createClass({ | ||||
|  | ||||
| 	render: function () { | ||||
| //console.log("AccountStatus props", this.props); | ||||
| 		var	classes = { | ||||
| 		var	accountInfoClasses = { | ||||
| 			'accountStatus':	true, | ||||
| 			'isExpiring':		this.props['isExpiring'], | ||||
| 			'isExpired':		this.props['isExpired'], | ||||
| 		}; | ||||
| 		accountInfoClasses[this.props['featureSet']] = true; | ||||
| 		 | ||||
| 		classes[this.props['featureSet']] = true; | ||||
| 		var proxyInfoClasses = { | ||||
| 			'proxyInfo':				true | ||||
| 		} | ||||
| 		proxyInfoClasses[this.props['proxyType']] = true; | ||||
|  | ||||
| 		return	React.DOM.div({'className':React.addons.classSet(classes)}, [ | ||||
| 			React.DOM.span({'className': 'level'}, this.props['featureSet']), | ||||
| 			React.DOM.span({'className': 'expirationDate'}, this.props['expirationDate']) | ||||
| 		return	React.DOM.div({'className':'miscInfo'}, [ | ||||
| 			React.DOM.div({'className':React.addons.classSet(proxyInfoClasses)}, [ | ||||
| 				React.DOM.span({'className':'proxyDescription'}, this.props['proxyTypeDescription']), | ||||
| 				React.DOM.span({'className':'referenceDate'}, this.props['referenceDate']) | ||||
| 			]), | ||||
| 			React.DOM.div({'className':React.addons.classSet(accountInfoClasses)}, [ | ||||
| 				React.DOM.span({'className':'level'}, Clipperz.PM.DataModel.Feature['featureSets'][this.props['featureSet']]), | ||||
| 				React.DOM.span({'className':'expirationMessage'}, "expiring on"), | ||||
| 				React.DOM.span({'className':'expirationDate'}, this.props['expirationDate']) | ||||
| 			]) | ||||
| 		]); | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	//========================================================================= | ||||
|   | ||||
| @@ -30,6 +30,7 @@ Clipperz.PM.UI.Components.CardToolbar = React.createClass({ | ||||
| 		'style':			React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired, | ||||
| 		'enableSidePanels':	React.PropTypes.bool.isRequired, | ||||
| 		'accountInfo':		React.PropTypes.object.isRequired, | ||||
| 		'proxyInfo':		React.PropTypes.object.isRequired, | ||||
| 		'messageBox':		React.PropTypes.object.isRequired, | ||||
| 		'filter':			React.PropTypes.object /*.isRequired */ | ||||
| 	}, | ||||
| @@ -99,7 +100,7 @@ Clipperz.PM.UI.Components.CardToolbar = React.createClass({ | ||||
| 		return	React.DOM.div({className:'cardToolbar ' + this.props['style']}, [ | ||||
| //			React.DOM.div({className:'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['accountInfo']), | ||||
| 			Clipperz.PM.UI.Components.AccountStatus(MochiKit.Base.update(this.props['accountInfo'], this.props['proxyInfo'])), | ||||
| 			Clipperz.PM.UI.Components.MessageBox(this.props['messageBox']), | ||||
| 		]); | ||||
| 	} | ||||
|   | ||||
| @@ -31,6 +31,15 @@ Clipperz.PM.UI.Components.Cards.CommandToolbar = React.createClass({ | ||||
| 	propTypes: { | ||||
| //		'label':	React.PropTypes.string.isRequired, | ||||
| //		'loading':	React.PropTypes.bool, | ||||
| 		'features':		React.PropTypes.array.isRequired, | ||||
| 	}, | ||||
|  | ||||
| 	features: function () { | ||||
| 		return this.props['features']; | ||||
| 	}, | ||||
| 	 | ||||
| 	isFeatureEnabled: function (aValue) { | ||||
| 		return (this.features().indexOf(aValue) > -1); | ||||
| 	}, | ||||
|  | ||||
| 	//---------------------------------------------------------------------------- | ||||
| @@ -40,29 +49,17 @@ Clipperz.PM.UI.Components.Cards.CommandToolbar = React.createClass({ | ||||
| 	}, | ||||
|  | ||||
| 	//---------------------------------------------------------------------------- | ||||
|  | ||||
| //	EDIT_CARD	-> archive, edit | ||||
| //	DELETE_CARD	-> delete | ||||
| //	ADD_CARD	-> clone | ||||
| 	commands: function () { | ||||
| 		var	archiveLabel = this.props['_isArchived'] ? "restore" : "archive"; | ||||
| 		return { | ||||
| 			'delete': { | ||||
| 				'label': "delete", | ||||
| 				'broadcastEvent': 'deleteCard' | ||||
| 			}, | ||||
| 			'archive': { | ||||
| 				'label': this.props['_isArchived'] ? "restore" : "archive", | ||||
| 				'broadcastEvent': 'toggleArchiveCard' | ||||
| 			}, | ||||
| //			'share': { | ||||
| //				'label': "share", | ||||
| //				'broadcastEvent': 'shareCard' | ||||
| //			}, | ||||
| 			'clone': { | ||||
| 				'label': "clone", | ||||
| 				'broadcastEvent': 'cloneCard' | ||||
| 			}, | ||||
| 			'edit': { | ||||
| 				'label': "edit", | ||||
| 				'broadcastEvent': 'editCard' | ||||
| 			} | ||||
| 			'delete':	{ 'label': "delete",		'broadcastEvent': 'deleteCard',			'enabled': this.isFeatureEnabled('DELETE_CARD')}, | ||||
| 			'archive':	{ 'label': archiveLabel,	'broadcastEvent': 'toggleArchiveCard',	'enabled': this.isFeatureEnabled('EDIT_CARD')}, | ||||
| //			'share':	{ 'label': "share",			'broadcastEvent': 'shareCard' }, | ||||
| 			'clone':	{ 'label': "clone",			'broadcastEvent': 'cloneCard',			'enabled': this.isFeatureEnabled('ADD_CARD')}, | ||||
| 			'edit':		{ 'label': "edit",			'broadcastEvent': 'editCard',			'enabled': this.isFeatureEnabled('EDIT_CARD')} | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| @@ -92,7 +89,12 @@ Clipperz.PM.UI.Components.Cards.CommandToolbar = React.createClass({ | ||||
| 		} | ||||
| 		 | ||||
| 		return	React.DOM.ul({}, MochiKit.Base.map(function (aCommand) { | ||||
| 					return React.DOM.li({'className':aCommand['broadcastEvent'], 'onClick':commandHandler, 'data-broadcast-event':aCommand['broadcastEvent']}, [React.DOM.span({}, aCommand['label'])]); | ||||
| 					var classes = {}; | ||||
| 					classes[aCommand['broadcastEvent']] = true; | ||||
| 					classes['enabled'] = aCommand['enabled']; | ||||
| 					classes['disabled'] = !aCommand['enabled']; | ||||
|  | ||||
| 					return React.DOM.li({'className':React.addons.classSet(classes), 'onClick':aCommand['enabled'] ? commandHandler : null, 'data-broadcast-event':aCommand['broadcastEvent']}, [React.DOM.span({}, aCommand['label'])]); | ||||
| 				}, commandValues)); | ||||
| 	}, | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,7 @@ Clipperz.PM.UI.Components.Cards.Detail = React.createClass({ | ||||
|  | ||||
| 		result = this.props['selectedCard']; | ||||
| 		if (result) { | ||||
| 			result['features'] = this.props['features']; | ||||
| 			result['style'] = this.props['style']; | ||||
| 			result['ask'] = (this.props['style'] == 'narrow') ? this.props['ask'] : null; | ||||
| 			result['showGlobalMask'] = this.props['showGlobalMask']; | ||||
|   | ||||
| @@ -30,12 +30,23 @@ Clipperz.PM.UI.Components.Cards.List = React.createClass({ | ||||
|  | ||||
| 	propTypes: { | ||||
| 		'cards':		React.PropTypes.array, | ||||
| 		'featureSet':	React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired, | ||||
| 		'featureSet':	React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired, | ||||
| 		'features':		React.PropTypes.array.isRequired, | ||||
| 		'selectedCard':	React.PropTypes.object | ||||
| 	}, | ||||
|  | ||||
| 	features: function () { | ||||
| 		return this.props['features']; | ||||
| 	}, | ||||
| 	 | ||||
| 	isFeatureEnabled: function (aValue) { | ||||
| 		return (this.features().indexOf(aValue) > -1); | ||||
| 	}, | ||||
|  | ||||
| 	handleClick: function (anEvent) { | ||||
| 		MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectCard', {'reference':anEvent.currentTarget.dataset.reference, 'label':anEvent.currentTarget.dataset.label}, true); | ||||
| 		if (this.isFeatureEnabled('CARD_DETAILS')) { | ||||
| 			MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectCard', {'reference':anEvent.currentTarget.dataset.reference, 'label':anEvent.currentTarget.dataset.label}, true); | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	renderItem: function (anItem) { | ||||
| @@ -70,7 +81,7 @@ Clipperz.PM.UI.Components.Cards.List = React.createClass({ | ||||
| 		classes[this.props['style']] = true; | ||||
|  | ||||
| 		return	React.DOM.div({'key':'cardList', 'className':React.addons.classSet(classes)}, [ | ||||
| 					React.DOM.ul({}, MochiKit.Base.map(this.renderItem, cards)) | ||||
| 					this.isFeatureEnabled('LIST_CARDS') ? React.DOM.ul({}, MochiKit.Base.map(this.renderItem, cards)) : null | ||||
| 				]); | ||||
| 	}, | ||||
| 	 | ||||
|   | ||||
| @@ -62,7 +62,6 @@ Clipperz.PM.UI.Components.Cards.View = React.createClass({ | ||||
| 		newState[aField['_reference']] = !this.state[aField['_reference']]; | ||||
| 		 | ||||
| 		return function () { | ||||
| console.log("SHOW PASSWORD", aField, self); | ||||
| 			self.setState(newState); | ||||
| 		}; | ||||
| 	}, | ||||
|   | ||||
| @@ -26,7 +26,7 @@ Clipperz.Base.module('Clipperz.PM.UI.Components'); | ||||
| Clipperz.PM.UI.Components.ExpiredPanel = React.createClass({ | ||||
|  | ||||
| 	propTypes: { | ||||
| //		featureSet:			React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired, | ||||
| //		featureSet:			React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired, | ||||
| //		'level':	React.PropTypes.oneOf(['hide', 'info', 'warning', 'error']).isRequired | ||||
| 	}, | ||||
|  | ||||
|   | ||||
| @@ -28,7 +28,8 @@ Clipperz.PM.UI.Components.Pages.MainPage = React.createClass({ | ||||
|  | ||||
| 	getDefaultProps: function () { | ||||
| 		return { | ||||
| 			featureSet: 'FULL' | ||||
| 			featureSet: 'FULL', | ||||
| 			features:	[] | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| @@ -36,7 +37,8 @@ Clipperz.PM.UI.Components.Pages.MainPage = React.createClass({ | ||||
| 		'tags':				React.PropTypes.object, | ||||
| 		'allTags':			React.PropTypes.array, | ||||
| 		'messageBox':		React.PropTypes.object.isRequired, | ||||
| 		'featureSet':		React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired, | ||||
| 		'featureSet':		React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired, | ||||
| 		'features':			React.PropTypes.array.isRequired, | ||||
| 		'accountInfo':		React.PropTypes.object.isRequired, | ||||
| //		'mediaQueryStyle':	React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired, | ||||
| 		'style':			React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired, | ||||
|   | ||||
| @@ -36,7 +36,7 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({ | ||||
| 	}, | ||||
|  | ||||
| 	propTypes: { | ||||
| 		'accountInfo':		React.PropTypes.object.isRequired, | ||||
| 		'accountInfo':	React.PropTypes.object.isRequired, | ||||
| 	}, | ||||
|  | ||||
| 	getInitialState: function() { | ||||
| @@ -90,6 +90,12 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({ | ||||
| 									React.DOM.p({}, "") | ||||
| 								]) | ||||
| 							]), | ||||
| 							React.DOM.li({}, [ | ||||
| 								React.DOM.h2({}, "Device PIN"), | ||||
| 								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.li({}, [ | ||||
| 								React.DOM.h2({}, "Preferences"), | ||||
| 								React.DOM.div({}, [ | ||||
|   | ||||
| @@ -31,7 +31,8 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({ | ||||
| 	propTypes: { | ||||
| 		'allTags':		React.PropTypes.array, | ||||
| 		'messageBox':	React.PropTypes.object.isRequired, | ||||
| 		'featureSet':	React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL', 'OFFLINE']).isRequired, | ||||
| 		'featureSet':	React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired, | ||||
| 		'features':		React.PropTypes.array.isRequired, | ||||
| 		'style':		React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired, | ||||
| 	}, | ||||
|  | ||||
| @@ -43,6 +44,14 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({ | ||||
| 		return this.props['featureSet']; | ||||
| 	}, | ||||
|  | ||||
| 	features: function () { | ||||
| 		return this.props['features']; | ||||
| 	}, | ||||
| 	 | ||||
| 	isFeatureEnabled: function (aValue) { | ||||
| 		return (this.features().indexOf(aValue) > -1); | ||||
| 	}, | ||||
|  | ||||
| 	handleMaskClick: function () { | ||||
| 		MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'maskClick'); | ||||
| 	}, | ||||
| @@ -62,15 +71,22 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({ | ||||
|  | ||||
| 	renderCardFrame: function (firstColumnComponents, secondColumnComponents) { | ||||
| 		var	addCardButton; | ||||
| 		var	cardColumnClasses; | ||||
|  | ||||
| 		if ((this.props['featureSet'] != 'EXPIRED') && (this.props['featureSet'] != 'OFFLINE')) { | ||||
| //		if ((this.props['featureSet'] != 'EXPIRED') && (this.props['featureSet'] != 'OFFLINE')) { | ||||
| 		if (this.isFeatureEnabled('ADD_CARD')) { | ||||
| 			addCardButton = React.DOM.div({'className': 'addCardButton', 'onClick':this.handleAddCardClick}, 'add card'); | ||||
| 		} else { | ||||
| 			addCardButton = null; | ||||
| 		} | ||||
|  | ||||
| 		cardColumnClasses = { | ||||
| 			'cardListColumn':	true, | ||||
| 			'column':			true, | ||||
| 			'addCard':			this.isFeatureEnabled('ADD_CARD') | ||||
| 		} | ||||
| 		return React.DOM.div({'key':'cardContent', 'className':'cardContent'}, [ | ||||
| 			React.DOM.div({'className':'cardListColumn column'}, [addCardButton, firstColumnComponents]), | ||||
| 			React.DOM.div({'className':React.addons.classSet(cardColumnClasses)}, [addCardButton, firstColumnComponents]), | ||||
| 			React.DOM.div({'className':'cardDetail column right'}, secondColumnComponents) | ||||
| 		]) | ||||
| 	}, | ||||
|   | ||||
| @@ -50,7 +50,7 @@ Clipperz.PM.UI.MainController = function() { | ||||
| 	this._selectedCardInfo = null; | ||||
|  | ||||
| 	this._closeMaskAction = null; | ||||
| 	 | ||||
|  | ||||
| 	this._pages = {}; | ||||
| 	this.renderPages([ | ||||
| 		'loginPage', | ||||
| @@ -462,6 +462,7 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
|  | ||||
| 	showCardDetailInNarrowView: function (aValue) { | ||||
| 		return Clipperz.Async.callbacks("MainController.showCardDetailInNarrowView", [ | ||||
| 			MochiKit.Base.method(this, 'setPageProperties', 'cardDetailPage', 'features', this.features()), | ||||
| 			MochiKit.Base.method(this, 'setPageProperties', 'cardDetailPage', 'selectedCard', aValue), | ||||
| 			MochiKit.Base.method(this, 'moveInPage', this.currentPage(), 'cardDetailPage'), | ||||
| 		], {trace:false}); | ||||
| @@ -581,7 +582,6 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
| 		var	fullFilterCriteria; | ||||
| 		var	selectedCardReference = this._selectedCardInfo ? this._selectedCardInfo['reference'] : null; | ||||
|  | ||||
| //console.log("updateSelectedCards - ACCOUNT INFO.featureSet", this.userAccountInfo()['featureSet']); | ||||
| 		if (aFilter['type'] == 'ALL') { | ||||
| 			filterCriteria = MochiKit.Base.operator.truth; | ||||
| 			sortCriteria = Clipperz.Base.caseInsensitiveKeyComparator('label'); | ||||
| @@ -896,25 +896,17 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
|  | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	messageBoxContent: function () { | ||||
| 		var	message; | ||||
| 		var	level; | ||||
| 		 | ||||
| 		message = ""; | ||||
| 		level = 'HIDE'; | ||||
| 		 | ||||
| //console.log("messageBox - this.user()", this.user()); | ||||
| 		if (this.userAccountInfo()['featureSet'] == 'EXPIRED') { | ||||
| 			message = "Exprired subscription"; | ||||
| 			level = 'ERROR'; | ||||
| 		} | ||||
|  | ||||
| 		return { | ||||
| 			'message': message, | ||||
| 			'level': level | ||||
| 		}; | ||||
| 	featureSet: function () { | ||||
| 		return this.userAccountInfo()['featureSet']; | ||||
| 	}, | ||||
|  | ||||
| 	features: function () { | ||||
| //		return this.userAccountInfo()['features']; | ||||
| 		return Clipperz.PM.Proxy.defaultProxy.features(this.userAccountInfo()['features']); | ||||
| 	}, | ||||
|  | ||||
| 	//......................................................................... | ||||
| 	 | ||||
| 	userAccountInfo: function () { | ||||
| 		var	result; | ||||
| 		 | ||||
| @@ -924,6 +916,7 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
| 			var	usefulFields = [ | ||||
| 				'currentSubscriptionType', | ||||
| 				'expirationDate', | ||||
| 				'referenceDate', | ||||
| 				'featureSet', | ||||
| 				'features', | ||||
| 				'isExpired', | ||||
| @@ -939,12 +932,40 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
| 		 | ||||
| 		return result; | ||||
| 	}, | ||||
| 	 | ||||
|  | ||||
| 	proxyInfo: function () { | ||||
| 		return { | ||||
| 			'proxyType':			Clipperz.PM.Proxy.defaultProxy.type(), | ||||
| 			'proxyTypeDescription':	Clipperz.PM.Proxy.defaultProxy.typeDescription() | ||||
| 		} | ||||
| 		 | ||||
| 	}, | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	messageBoxContent: function () { | ||||
| 		var	message; | ||||
| 		var	level; | ||||
| 		 | ||||
| 		message = ""; | ||||
| 		level = 'HIDE'; | ||||
| 		 | ||||
| //console.log("messageBox - this.user()", this.user()); | ||||
| 		if (this.featureSet() == 'EXPIRED') { | ||||
| 			message = "Exprired subscription"; | ||||
| 			level = 'ERROR'; | ||||
| 		} | ||||
|  | ||||
| 		return { | ||||
| 			'message': message, | ||||
| 			'level': level | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| 	genericPageProperties: function () { | ||||
| 		return { | ||||
| 			'style':			this.mediaQueryStyle(), | ||||
| 		    'isTouchDevice':	this.isTouchDevice(), | ||||
| 		    'isDesktop':		this.isDesktop(), | ||||
| 			'isTouchDevice':	this.isTouchDevice(), | ||||
| 			'isDesktop':		this.isDesktop(), | ||||
| 			'hasKeyboard':		this.hasKeyboard() | ||||
| 		}; | ||||
| 	}, | ||||
| @@ -968,7 +989,9 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
| 				'accountInfo':					this.userAccountInfo(), | ||||
| 				'selectionPanelStatus':			this.isSelectionPanelOpen()	? 'OPEN' : 'CLOSED', | ||||
| 				'settingsPanelStatus':			this.isSettingsPanelOpen()	? 'OPEN' : 'CLOSED', | ||||
| 				'featureSet':					this.userAccountInfo()['featureSet'], | ||||
| 				'featureSet':					this.featureSet(), | ||||
| 				'features':						this.features(), | ||||
| 				'proxyInfo':					this.proxyInfo(), | ||||
| //				'shouldIncludeArchivedCards':	this.shouldIncludeArchivedCards(), | ||||
| //				'cards':				…, | ||||
| //				'tags':					…, | ||||
| @@ -1156,7 +1179,7 @@ console.log("THE BROWSER IS OFFLINE"); | ||||
| 	selectCard: function (someInfo, shouldUpdateCardDetail) { | ||||
| 		var result; | ||||
|  | ||||
| 		if (this.userAccountInfo()['featureSet'] != 'EXPIRED') { | ||||
| 		if (this.featureSet() != 'EXPIRED') { | ||||
| 			this._selectedCardInfo = someInfo; | ||||
| 			this.refreshSelectedCards(); | ||||
| 			result = this.updateSelectedCard(someInfo, true, shouldUpdateCardDetail); | ||||
|   | ||||
| @@ -263,11 +263,9 @@ div.cardContent { | ||||
| 		div.cardToolbar.narrow { | ||||
| 		} | ||||
| 		 | ||||
| 		div.cardList { | ||||
| //			overflow-y: scroll; | ||||
| 			padding-bottom: 100px; | ||||
|  | ||||
| 			ul { | ||||
| 		&.addCard { | ||||
| 			div.cardList { | ||||
| 				padding-bottom: 100px; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
|   | ||||
| @@ -1,44 +1,50 @@ | ||||
| .accountStatus { | ||||
| 	background-color: green; | ||||
| 	padding: 3px; | ||||
| 	font-size: 10pt; | ||||
| 	border-bottom: 1px solid white; | ||||
| 	 | ||||
| 	&.FULL { | ||||
| .miscInfo { | ||||
| 	.proxyInfo { | ||||
| 		border-bottom: 1px solid white; | ||||
| 		display: none; | ||||
| 		visibility: hidden; | ||||
| 		 | ||||
| 		&.isExpiring { | ||||
| 			display: block; | ||||
| 		&.OFFLINE_COPY { | ||||
| 			display:block; | ||||
| 			visibility: visible; | ||||
| 			 | ||||
| 			background-color: yellow; | ||||
|  | ||||
| 			background-color: $clipperz-blue; | ||||
| 			color: white; | ||||
| 		 | ||||
| 			.referenceDate { | ||||
| 				padding-left: 10px; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	&.TRIAL { | ||||
| 		background-color: orange; | ||||
|  | ||||
| 		&.isExpiring { | ||||
| 	.accountStatus { | ||||
| 		border-bottom: 1px solid white; | ||||
| 		background-color: green; | ||||
| 		padding: 3px; | ||||
| 		font-size: 10pt; | ||||
| 	 | ||||
| 		&.FULL { | ||||
| 			display: none; | ||||
| 			visibility: hidden; | ||||
| 		 | ||||
| 			&.isExpiring { | ||||
| 				display: block; | ||||
| 				visibility: visible; | ||||
| 			 | ||||
| 				background-color: yellow; | ||||
| 			} | ||||
| 		} | ||||
| 	 | ||||
| 		&.TRIAL { | ||||
| 			background-color: orange; | ||||
|  | ||||
| 			&.isExpiring { | ||||
| 				background-color: red; | ||||
| 			} | ||||
| 		} | ||||
| 	 | ||||
| 		&.EXPIRED { | ||||
| 			background-color: red; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	&.EXPIRED { | ||||
| 		background-color: red; | ||||
| 	} | ||||
| 	 | ||||
| 	&.OFFLINE_COPY { | ||||
| 		background-color: $clipperz-blue; | ||||
| 		color: white; | ||||
| 		 | ||||
| 		.expirationDate { | ||||
| 			display: none; | ||||
| 			visibility: hidden; | ||||
| 		} | ||||
| 		 | ||||
| 		.referenceDate { | ||||
| 			padding-left: 10px; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Giulio Cesare Solaroli
					Giulio Cesare Solaroli