mirror of
https://github.com/bitwarden/desktop.git
synced 2024-09-16 02:17:24 +02:00
login form styling. server validation errors displayed as sweet alerts
This commit is contained in:
parent
2fefdf8f6c
commit
47b500d7c0
@ -2,7 +2,10 @@
|
|||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller('accountsLoginController', function ($scope, $state, loginService, userService) {
|
.controller('accountsLoginController', function ($scope, $state, loginService, userService) {
|
||||||
$scope.login = function (model) {
|
popupUtils.initListSectionItemListeners();
|
||||||
|
|
||||||
|
$scope.loginPromise = null;
|
||||||
|
$scope.login = function (model, form) {
|
||||||
$scope.loginPromise = loginService.logIn(model.email, model.masterPassword);
|
$scope.loginPromise = loginService.logIn(model.email, model.masterPassword);
|
||||||
|
|
||||||
$scope.loginPromise.then(function () {
|
$scope.loginPromise.then(function () {
|
||||||
|
@ -1,22 +1,33 @@
|
|||||||
<ion-view view-title="bitwarden">
|
<form name="theForm" ng-submit="theForm.$valid && login(model, theForm)" bit-form="loginPromise">
|
||||||
<ion-content>
|
<div class="header">
|
||||||
<div class="list">
|
<div class="left">
|
||||||
<label class="item item-input">
|
<a ng-click="close()" href="">Cancel</a>
|
||||||
<i class="icon ion-android-mail placeholder-icon"></i>
|
</div>
|
||||||
<input type="text" placeholder="Email address" ng-model="model.email">
|
<div class="right">
|
||||||
</label>
|
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Log In</button>
|
||||||
<label class="item item-input">
|
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
|
||||||
<i class="icon ion-locked placeholder-icon"></i>
|
</div>
|
||||||
<input type="password" placeholder="Master password" ng-model="model.masterPassword">
|
<div class="title">bitwarden</div>
|
||||||
</label>
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="list">
|
||||||
|
<div class="list-section">
|
||||||
|
<div class="list-section-items">
|
||||||
|
<div class="list-section-item list-section-item-icon-input">
|
||||||
|
<i class="fa fa-envelope fa-lg fa-fw"></i>
|
||||||
|
<label for="email" class="sr-only">Email Address</label>
|
||||||
|
<input id="email" type="email" name="Email" placeholder="Email Address" ng-model="model.email">
|
||||||
|
</div>
|
||||||
|
<div class="list-section-item list-section-item-icon-input">
|
||||||
|
<i class="fa fa-lock fa-lg fa-fw"></i>
|
||||||
|
<label for="master-password" class="sr-only">Master Password</label>
|
||||||
|
<input id="master-password" type="password" name="MasterPassword" placeholder="Master Password" ng-model="model.masterPassword">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="padding">
|
|
||||||
<button class="button button-block button-positive" ng-click="login(model)">
|
|
||||||
Log In
|
|
||||||
</button>
|
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
<a href="#/hint">Get master password hint</a>
|
<a href="#/hint">Get master password hint</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</ion-content>
|
</form>
|
||||||
</ion-view>
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="right">
|
<div class="right">
|
||||||
<a href="" ng-click="addSite()"><i class="fa fa-plus fa-lg"></i></a>
|
<a href="" ng-click="addSite()"><i class="fa fa-plus fa-lg"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">Current Tab Sites</div>
|
<div class="title">Current Tab</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content content-tabs">
|
<div class="content content-tabs">
|
||||||
<div ng-if="sites.length">
|
<div ng-if="sites.length">
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
angular
|
|
||||||
.module('bit.directives')
|
|
||||||
|
|
||||||
.directive('bitField', function () {
|
|
||||||
var linkFn = function (scope, element, attrs, ngModel) {
|
|
||||||
ngModel.$registerError = registerError;
|
|
||||||
ngModel.$validators.validate = validator;
|
|
||||||
|
|
||||||
function validator() {
|
|
||||||
ngModel.$setValidity('bit', true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerError() {
|
|
||||||
ngModel.$setValidity('bit', false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
require: 'ngModel',
|
|
||||||
restrict: 'A',
|
|
||||||
compile: function (elem, attrs) {
|
|
||||||
if (!attrs.name || attrs.name === '') {
|
|
||||||
throw 'bit-field element does not have a valid name attribute';
|
|
||||||
}
|
|
||||||
|
|
||||||
return linkFn;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
@ -18,9 +18,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset errors
|
|
||||||
form.$errors = null;
|
|
||||||
|
|
||||||
// start loading
|
// start loading
|
||||||
form.$loading = true;
|
form.$loading = true;
|
||||||
|
|
||||||
@ -28,8 +25,7 @@
|
|||||||
form.$loading = false;
|
form.$loading = false;
|
||||||
}, function failure(reason) {
|
}, function failure(reason) {
|
||||||
form.$loading = false;
|
form.$loading = false;
|
||||||
validationService.addErrors(form, reason);
|
validationService.showError(reason);
|
||||||
scope.$broadcast('show-errors-check-validity');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
angular
|
angular
|
||||||
.module('bit.services', ['angular-jwt']);
|
.module('bit.services', ['angular-jwt', 'oitozero.ngSweetAlert']);
|
||||||
|
@ -1,61 +1,47 @@
|
|||||||
angular
|
angular
|
||||||
.module('bit.services')
|
.module('bit.services')
|
||||||
|
|
||||||
.factory('validationService', function () {
|
.factory('validationService', function (SweetAlert) {
|
||||||
var _service = {};
|
var _service = {};
|
||||||
|
|
||||||
_service.addErrors = function (form, reason) {
|
_service.showError = function (data) {
|
||||||
var data = reason.data;
|
|
||||||
var defaultErrorMessage = 'An unexpected error has occured.';
|
var defaultErrorMessage = 'An unexpected error has occured.';
|
||||||
form.$errors = [];
|
var errors = [];
|
||||||
|
|
||||||
if (!data || !angular.isObject(data)) {
|
if (!data || !angular.isObject(data)) {
|
||||||
form.$errors.push(defaultErrorMessage);
|
errors.push(defaultErrorMessage);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (!data.validationErrors) {
|
||||||
if (!data.validationErrors) {
|
|
||||||
if (data.message) {
|
if (data.message) {
|
||||||
form.$errors.push(data.message);
|
errors.push(data.message);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
form.$errors.push(defaultErrorMessage);
|
errors.push(defaultErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
for (var key in data.validationErrors) {
|
for (var key in data.validationErrors) {
|
||||||
if (!data.validationErrors.hasOwnProperty(key)) {
|
if (!data.validationErrors.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < data.validationErrors[key].length; i++) {
|
for (var i = 0; i < data.validationErrors[key].length; i++) {
|
||||||
_service.addError(form, key, data.validationErrors[key][i]);
|
errors.push(data.validationErrors[key][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
_service.addError = function (form, key, errorMessage, clearExistingErrors) {
|
|
||||||
if (clearExistingErrors || !form.$errors) {
|
|
||||||
form.$errors = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var pushError = true;
|
|
||||||
for (var i = 0; i < form.$errors.length; i++) {
|
|
||||||
if (form.$errors[i] === errorMessage) {
|
|
||||||
pushError = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushError) {
|
if (errors.length) {
|
||||||
form.$errors.push(errorMessage);
|
SweetAlert.swal({
|
||||||
|
title: 'Error',
|
||||||
|
text: errors[0],
|
||||||
|
type: 'error',
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonText: 'Ok'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key && key !== '' && form[key] && form[key].$registerError) {
|
return errors;
|
||||||
form[key].$registerError();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return _service;
|
return _service;
|
||||||
|
@ -18,19 +18,19 @@
|
|||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="name" class="item-label">Name</label>
|
<label for="name" class="item-label">Name</label>
|
||||||
<input id="name" type="text" name="Name" ng-model="site.name" bit-field>
|
<input id="name" type="text" name="Name" ng-model="site.name">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="uri" class="item-label">URI</label>
|
<label for="uri" class="item-label">URI</label>
|
||||||
<input id="uri" type="text" name="Uri" ng-model="site.uri" bit-field>
|
<input id="uri" type="text" name="Uri" ng-model="site.uri">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="username" class="item-label">Username</label>
|
<label for="username" class="item-label">Username</label>
|
||||||
<input id="username" type="text" name="Username" ng-model="site.username" bit-field>
|
<input id="username" type="text" name="Username" ng-model="site.username">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="password" class="item-label">Password</label>
|
<label for="password" class="item-label">Password</label>
|
||||||
<input id="password" type="password" name="Password" ng-model="site.password" bit-field>
|
<input id="password" type="password" name="Password" ng-model="site.password">
|
||||||
</div>
|
</div>
|
||||||
<a class="list-section-item" href="" ng-click="generatePassword()">
|
<a class="list-section-item" href="" ng-click="generatePassword()">
|
||||||
Generate Password
|
Generate Password
|
||||||
@ -42,13 +42,13 @@
|
|||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="folder" class="item-label">Folder</label>
|
<label for="folder" class="item-label">Folder</label>
|
||||||
<select id="folder" name="FolderId" ng-model="site.folderId" bit-field>
|
<select id="folder" name="FolderId" ng-model="site.folderId">
|
||||||
<option ng-repeat="folder in folders | orderBy: ['name']" value="{{folder.id}}">{{folder.name}}</option>
|
<option ng-repeat="folder in folders | orderBy: ['name']" value="{{folder.id}}">{{folder.name}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="favorite">Favorite</label>
|
<label for="favorite">Favorite</label>
|
||||||
<input id="favorite" name="Favorite" type="checkbox" ng-model="site.favorite" bit-field>
|
<input id="favorite" name="Favorite" type="checkbox" ng-model="site.favorite">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<textarea id="notes" name="Notes" rows="5" ng-model="site.notes" bit-field></textarea>
|
<textarea id="notes" name="Notes" rows="5" ng-model="site.notes"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,19 +18,19 @@
|
|||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="name" class="item-label">Name</label>
|
<label for="name" class="item-label">Name</label>
|
||||||
<input id="name" type="text" name="Name" ng-model="site.name" bit-field>
|
<input id="name" type="text" name="Name" ng-model="site.name">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="uri" class="item-label">URI</label>
|
<label for="uri" class="item-label">URI</label>
|
||||||
<input id="uri" type="text" name="Uri" ng-model="site.uri" bit-field>
|
<input id="uri" type="text" name="Uri" ng-model="site.uri">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="username" class="item-label">Username</label>
|
<label for="username" class="item-label">Username</label>
|
||||||
<input id="username" type="text" name="Username" ng-model="site.username" bit-field>
|
<input id="username" type="text" name="Username" ng-model="site.username">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="password" class="item-label">Password</label>
|
<label for="password" class="item-label">Password</label>
|
||||||
<input id="password" type="password" name="Password" ng-model="site.password" bit-field>
|
<input id="password" type="password" name="Password" ng-model="site.password">
|
||||||
</div>
|
</div>
|
||||||
<a class="list-section-item" href="" ng-click="generatePassword()">
|
<a class="list-section-item" href="" ng-click="generatePassword()">
|
||||||
Generate Password
|
Generate Password
|
||||||
@ -42,13 +42,13 @@
|
|||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="folder" class="item-label">Folder</label>
|
<label for="folder" class="item-label">Folder</label>
|
||||||
<select id="folder" name="FolderId" ng-model="site.folderId" bit-field>
|
<select id="folder" name="FolderId" ng-model="site.folderId">
|
||||||
<option ng-repeat="folder in folders | orderBy: ['name']" value="{{folder.id}}">{{folder.name}}</option>
|
<option ng-repeat="folder in folders | orderBy: ['name']" value="{{folder.id}}">{{folder.name}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="favorite">Favorite</label>
|
<label for="favorite">Favorite</label>
|
||||||
<input id="favorite" name="Favorite" type="checkbox" ng-model="site.favorite" bit-field>
|
<input id="favorite" name="Favorite" type="checkbox" ng-model="site.favorite">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<textarea id="notes" name="Notes" rows="5" ng-model="site.notes" bit-field></textarea>
|
<textarea id="notes" name="Notes" rows="5" ng-model="site.notes"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
<script src="app/directives/directivesModule.js"></script>
|
<script src="app/directives/directivesModule.js"></script>
|
||||||
<script src="app/directives/formDirective.js"></script>
|
<script src="app/directives/formDirective.js"></script>
|
||||||
<script src="app/directives/fieldDirective.js"></script>
|
|
||||||
|
|
||||||
<script src="app/services/servicesModule.js"></script>
|
<script src="app/services/servicesModule.js"></script>
|
||||||
<script src="app/services/backgroundService.js"></script>
|
<script src="app/services/backgroundService.js"></script>
|
||||||
|
@ -348,6 +348,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.list-section-item-icon-input {
|
||||||
|
padding: 15px 15px;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
float: left;
|
||||||
|
color: @list-icon-color;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.list-no-selection {
|
&.list-no-selection {
|
||||||
|
Loading…
Reference in New Issue
Block a user