GUACAMOLE-742: Merge provide feedback while login is in progress.

This commit is contained in:
Virtually Nick
2019-04-27 21:53:08 -04:00
committed by GitHub
17 changed files with 93 additions and 30 deletions

View File

@@ -64,7 +64,15 @@ angular.module('form').directive('guacForm', [function form() {
*
* @type Boolean
*/
modelOnly : '='
modelOnly : '=',
/**
* Whether the contents of the form should be rendered as disabled.
* By default, form fields are enabled.
*
* @type Boolean
*/
disabled : '='
},
templateUrl: 'app/form/templates/form.html',

View File

@@ -53,7 +53,15 @@ angular.module('form').directive('guacFormField', [function formField() {
*
* @type String
*/
model : '='
model : '=',
/**
* Whether this field should be rendered as disabled. By default,
* form fields are enabled.
*
* @type Boolean
*/
disabled : '='
},
templateUrl: 'app/form/templates/formField.html',

View File

@@ -213,6 +213,10 @@ angular.module('form').provider('formService', function formServiceProvider() {
* model:
* The current String value of the field, if any.
*
* disabled:
* A boolean value which is true if the field should be disabled.
* If false or undefined, the field should be enabled.
*
* @param {Element} fieldContainer
* The DOM Element whose contents should be replaced with the
* compiled field template.

View File

@@ -1 +1 @@
<input type="checkbox" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
<input type="checkbox" ng-disabled="disabled" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>

View File

@@ -1,5 +1,6 @@
<div class="date-field">
<input type="date"
ng-disabled="disabled"
ng-model="typedValue"
ng-model-options="modelOptions"
guac-lenient-date

View File

@@ -1,5 +1,6 @@
<div class="email-field">
<input type="email"
ng-disabled="disabled"
ng-model="model"
ng-hide="readOnly"
autocorrect="off"

View File

@@ -9,6 +9,7 @@
<div class="fields">
<guac-form-field ng-repeat="field in form.fields" namespace="namespace"
ng-if="isVisible(field)"
disabled="disabled"
field="field" model="values[field.name]"></guac-form-field>
</div>

View File

@@ -1 +1 @@
<input type="number" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
<input type="number" ng-disabled="disabled" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>

View File

@@ -1,4 +1,4 @@
<div class="password-field">
<input type="{{passwordInputType}}" ng-model="model" ng-trim="false" autocorrect="off" autocapitalize="off"/>
<input type="{{passwordInputType}}" ng-disabled="disabled" ng-model="model" ng-trim="false" autocorrect="off" autocapitalize="off"/>
<div class="icon toggle-password" ng-click="togglePassword()" title="{{getTogglePasswordHelpText() | translate}}"></div>
</div>

View File

@@ -1 +1,2 @@
<select ng-model="model" ng-options="option as getFieldOption(option) | translate for option in field.options | orderBy: value"></select>
<select ng-model="model" ng-disabled="disabled"
ng-options="option as getFieldOption(option) | translate for option in field.options | orderBy: value"></select>

View File

@@ -1 +1 @@
<textarea ng-model="model" autocorrect="off" autocapitalize="off"></textarea>
<textarea ng-model="model" autocorrect="off" autocapitalize="off" ng-disabled="disabled"></textarea>

View File

@@ -1,5 +1,6 @@
<div class="text-field">
<input type="text" ng-model="model" autocorrect="off" autocapitalize="off" ng-attr-list="{{ dataListId }}"/>
<input type="text" ng-model="model" autocorrect="off" autocapitalize="off"
ng-disabled="disabled" ng-attr-list="{{ dataListId }}"/>
<datalist ng-if="dataListId" id="{{ dataListId }}">
<option ng-repeat="option in field.options | orderBy: option"
value="{{ option }}">{{ getFieldOption(option) | translate }}</option>

View File

@@ -1,5 +1,6 @@
<div class="time-field">
<input type="time"
ng-disabled="disabled"
ng-model="typedValue"
ng-model-options="modelOptions"
guac-lenient-time

View File

@@ -2,12 +2,13 @@
<!-- Available time zone regions -->
<select class="time-zone-region"
ng-disabled="disabled"
ng-model="region"
ng-options="name for name in regions | orderBy: name"></select>
<!-- Time zones within selected region -->
<select class="time-zone"
ng-disabled="!region"
ng-disabled="disabled || !region"
ng-model="model"
ng-options="timeZone.value as timeZone.key for timeZone in timeZones[region] | toArray | orderBy: key"></select>

View File

@@ -66,6 +66,7 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
var Field = $injector.get('Field');
// Required services
var $rootScope = $injector.get('$rootScope');
var $route = $injector.get('$route');
var authenticationService = $injector.get('authenticationService');
var requestService = $injector.get('requestService');
@@ -91,6 +92,16 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
*/
$scope.remainingFields = [];
/**
* Whether an authentication attempt has been submitted. This will be
* set to true once credentials have been submitted and will only be
* reset to false once the attempt has been fully processed, including
* rerouting the user to the requested page if the attempt succeeded.
*
* @type Boolean
*/
$scope.submitted = false;
/**
* Returns whether a previous login attempt is continuing.
*
@@ -141,21 +152,27 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
*/
$scope.login = function login() {
// Authentication is now in progress
$scope.submitted = true;
// Start with cleared status
$scope.loginError = null;
// Attempt login once existing session is destroyed
authenticationService.authenticate($scope.enteredValues)
// Clear and reload upon success
// Retry route upon success (entered values will be cleared only
// after route change has succeeded as this can take time)
.then(function loginSuccessful() {
$scope.enteredValues = {};
$route.reload();
})
// Reset upon failure
['catch'](requestService.createErrorCallback(function loginFailed(error) {
// Initial submission is complete and has failed
$scope.submitted = false;
// Clear out passwords if the credentials were rejected for any reason
if (error.type !== Error.Type.INSUFFICIENT_CREDENTIALS) {
@@ -183,6 +200,12 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
};
// Reset state after authentication and routing have succeeded
$rootScope.$on('$routeChangeSuccess', function routeChanged() {
$scope.enteredValues = {};
$scope.submitted = false;
});
}];
return directive;

View File

@@ -17,27 +17,20 @@
* under the License.
*/
.login-ui.error .login-dialog {
animation-name: shake-head;
animation-duration: 0.25s;
animation-timing-function: linear;
-webkit-animation-name: shake-head;
-webkit-animation-duration: 0.25s;
-webkit-animation-timing-function: linear;
.login-ui {
animation: fadein 0.125s linear;
-moz-animation: fadein 0.125s linear;
-webkit-animation: fadein 0.125s linear;
}
.login-ui div.login-dialog-middle {
.login-ui .login-dialog-middle {
width: 100%;
display: table-cell;
vertical-align: middle;
text-align: center;
}
.login-ui div.login-dialog {
animation: fadein 0.125s linear;
-moz-animation: fadein 0.125s linear;
-webkit-animation: fadein 0.125s linear;
.login-ui .login-dialog {
width: 100%;
max-width: 3in;
@@ -115,7 +108,7 @@
background-image: url("images/guac-tricolor.png");
}
.login-ui.continuation div.login-dialog {
.login-ui.continuation .login-dialog {
border-right: none;
border-left: none;
box-shadow: none;
@@ -126,3 +119,12 @@
.login-ui.continuation .login-dialog .version {
display: none;
}
.login-ui.error .login-dialog {
animation-name: shake-head;
animation-duration: 0.25s;
animation-timing-function: linear;
-webkit-animation-name: shake-head;
-webkit-animation-duration: 0.25s;
-webkit-animation-timing-function: linear;
}

View File

@@ -23,13 +23,24 @@
<!-- Login fields -->
<div class="login-fields">
<guac-form namespace="'LOGIN'" content="remainingFields" model="enteredValues"></guac-form>
<guac-form
namespace="'LOGIN'"
content="remainingFields"
model="enteredValues"
disabled="submitted"></guac-form>
</div>
<!-- Submit button -->
<!-- Login/continue button -->
<div class="buttons">
<input type="submit" name="login" class="login" value="{{'LOGIN.ACTION_LOGIN' | translate}}"/>
<input type="submit" name="login" class="continue-login" value="{{'LOGIN.ACTION_CONTINUE' | translate}}"/>
<input type="submit" name="login" class="login"
ng-disabled="submitted"
value="{{'LOGIN.ACTION_LOGIN' | translate}}"/>
<input type="submit" name="login" class="continue-login"
ng-disabled="submitted"
value="{{'LOGIN.ACTION_CONTINUE' | translate}}"/>
</div>
</form>