Added Avatar change support
This commit is contained in:
parent
269da1c75f
commit
4ffed66fa6
|
@ -0,0 +1,95 @@
|
|||
<#import "template.ftl" as layout>
|
||||
<@layout.mainLayout active='account' bodyClass='user'; section>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
<h2>${msg("editAccountHtmlTitle")}</h2>
|
||||
</div>
|
||||
<div class="col-md-2 subtitle">
|
||||
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="${url.accountUrl}" class="form-horizontal" method="post">
|
||||
|
||||
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||
|
||||
<#if !realm.registrationEmailAsUsername>
|
||||
<div class="form-group ${messagesPerField.printIfExists('username','has-error')}">
|
||||
<div class="col-sm-2 col-md-2">
|
||||
<label for="username" class="control-label">${msg("username")}</label> <#if realm.editUsernameAllowed><span class="required">*</span></#if>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-10 col-md-10">
|
||||
<input type="text" class="form-control" id="username" name="username" <#if !realm.editUsernameAllowed>disabled="disabled"</#if> value="${(account.username!'')}"/>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<div class="form-group ${messagesPerField.printIfExists('email','has-error')}">
|
||||
<div class="col-sm-2 col-md-2">
|
||||
<label for="email" class="control-label">${msg("email")}</label> <span class="required">*</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-10 col-md-10">
|
||||
<input type="text" class="form-control" id="email" name="email" autofocus value="${(account.email!'')}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group ${messagesPerField.printIfExists('firstName','has-error')}">
|
||||
<div class="col-sm-2 col-md-2">
|
||||
<label for="firstName" class="control-label">${msg("firstName")}</label> <span class="required">*</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-10 col-md-10">
|
||||
<input type="text" class="form-control" id="firstName" name="firstName" value="${(account.firstName!'')}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group ${messagesPerField.printIfExists('lastName','has-error')}">
|
||||
<div class="col-sm-2 col-md-2">
|
||||
<label for="lastName" class="control-label">${msg("lastName")}</label> <span class="required">*</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-10 col-md-10">
|
||||
<input type="text" class="form-control" id="lastName" name="lastName" value="${(account.lastName!'')}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||
<div class="">
|
||||
<#if url.referrerURI??><a href="${url.referrerURI}">${kcSanitize(msg("backToApplication")?no_esc)}</a></#if>
|
||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Save">${msg("doSave")}</button>
|
||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Cancel">${msg("doCancel")}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
<h2>${msg("changeAvatarHtmlTitle")}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<#assign avatarUrl = url.accountUrl?replace("^(.*)(/account/?)(\\?(.*))?$", "$1/avatar-provider/?account&$4", 'r') />
|
||||
<form action="${avatarUrl}" class="form-horizontal" method="post" enctype="multipart/form-data">
|
||||
|
||||
<img src="${avatarUrl}" style="max-width: 200px;"
|
||||
onerror="let div=document.createElement('div');div.innerHTML='${msg("noAvatarSet")}';this.replaceWith(div)" />
|
||||
|
||||
<input style="margin-top: 1em;" type="file" id="avatar" name="image">
|
||||
|
||||
<input type="hidden" name="stateChecker" value="${stateChecker}">
|
||||
|
||||
<div class="form-group">
|
||||
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||
<div class="">
|
||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Save">${msg("doSave")}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</@layout.mainLayout>
|
|
@ -1 +1,3 @@
|
|||
accountManagementTitle=D4Science Benutzerkontoverwaltung
|
||||
|
||||
changeAvatarHtmlTitle=Profilbild bearbeiten
|
||||
|
|
|
@ -4,3 +4,6 @@ accountManagementWelcomeMessage=Welcome to D4Science Account Management
|
|||
|
||||
authenticatorFinishSetUpMessage=Each time you sign in to your D4Science account, you will be asked to provide a two-factor authentication code.
|
||||
authenticatorSMSMessage=D4Science will send the Verification code to your phone as the two-factor authentication.
|
||||
|
||||
changeAvatarHtmlTitle=Edit Avatar
|
||||
noAvatarSet=No image set
|
|
@ -1 +1,4 @@
|
|||
accountManagementTitle=D4Science Account Management
|
||||
|
||||
changeAvatarHtmlTitle=Modifica Avatar
|
||||
noAvatarSet=Nessuna immagine impostata
|
|
@ -0,0 +1,26 @@
|
|||
module.service('UserAvatar', function(Auth) {
|
||||
this.url = function(user, realm) {
|
||||
return authUrl + '/realms/' + realm.realm + '/avatar-provider/admin/' + user.id + "?access_token=" + Auth.authz.token + "&" + + new Date().getTime();
|
||||
}
|
||||
});
|
||||
|
||||
module.controller('UserAvatarCtrl', function($scope, $http, Notifications, UserAvatar) {
|
||||
$scope.avatarUrl = UserAvatar.url($scope.user, $scope.realm);
|
||||
|
||||
$scope.uploadAvatar = function(files) {
|
||||
var fd = new FormData();
|
||||
//Take the first selected file
|
||||
fd.append("image", files[0]);
|
||||
|
||||
$http.post($scope.avatarUrl, fd, {
|
||||
headers: {'Content-Type': undefined },
|
||||
transformRequest: angular.identity
|
||||
}).then(function() {
|
||||
Notifications.success("Your changes have been saved to the user.");
|
||||
$scope.avatarUrl = UserAvatar.url($scope.user, $scope.realm);
|
||||
}, function(error) {
|
||||
console.error(error);
|
||||
Notifications.error("Could not save the avatar");
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,169 @@
|
|||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/users">{{:: 'users' | translate}}</a></li>
|
||||
<li data-ng-hide="create">{{user.username}}</li>
|
||||
<li data-ng-show="create">{{:: 'add-user' | translate}}</li>
|
||||
</ol>
|
||||
|
||||
<kc-tabs-user></kc-tabs-user>
|
||||
|
||||
<form class="form-horizontal" name="userForm" novalidate kc-read-only="!create && !user.access.manage">
|
||||
|
||||
<fieldset class="border-top">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"for="id">{{:: 'id' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" id="id" name="id" data-ng-model="user.id" autofocus data-ng-readonly="true">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"for="id">{{:: 'created-at' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
{{user.createdTimestamp|date:'shortDate'}} {{user.createdTimestamp|date:'mediumTime'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" data-ng-hide="emailAsUsername">
|
||||
<label class="col-md-2 control-label"for="username">{{:: 'username' | translate}} <span class="required" data-ng-show="create">*</span></label>
|
||||
<div class="col-md-6">
|
||||
<!-- Characters >,<,/,\ are forbidden in username -->
|
||||
<input class="form-control" type="text" id="username" name="username" data-ng-model="user.username" autofocus
|
||||
data-ng-required="!emailAsUsername" ng-pattern="/^[^\<\>\\\/]*$/" data-ng-readonly="!editUsername">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="email">{{:: 'email' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="email" name="email" id="email"
|
||||
data-ng-model="user.email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="firstName">{{:: 'first-name' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="firstName" id="firstName"
|
||||
data-ng-model="user.firstName">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="lastName">{{:: 'last-name' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="lastName" id="lastName"
|
||||
data-ng-model="user.lastName">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group clearfix block">
|
||||
<label class="col-md-2 control-label" for="userEnabled">{{:: 'user-enabled' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
<input ng-model="user.enabled" name="userEnabled" id="userEnabled" ng-disabled="!create && !user.access.manage" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'user-enabled.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix block" data-ng-show="realm.bruteForceProtected && !create">
|
||||
<label class="col-md-2 control-label" for="temporarilyDisabled">{{:: 'user-temporarily-locked' | translate}}</label>
|
||||
<div class="col-md-1">
|
||||
<input ng-model="temporarilyDisabled" name="temporarilyDisabled" id="temporarilyDisabled" data-ng-readonly="true" data-ng-disabled="true" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'user-temporarily-locked.tooltip' | translate}}</kc-tooltip>
|
||||
<div class="col-sm-2">
|
||||
<button type="submit" data-ng-click="unlockUser()" data-ng-show="temporarilyDisabled" class="btn btn-default">{{:: 'unlock-user' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group clearfix block" data-ng-show="!create && user.federationLink">
|
||||
<label class="col-md-2 control-label">{{:: 'federation-link' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
<a href="{{federationLink}}">{{federationLinkName}}</a>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'user-link.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix block" data-ng-show="!create && user.origin">
|
||||
<label class="col-md-2 control-label">{{:: 'user-origin-link' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
<a href="{{originLink}}">{{originName}}</a>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'user-origin.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix block">
|
||||
<label class="col-md-2 control-label" for="emailVerified">{{:: 'email-verified' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
<input ng-model="user.emailVerified" name="emailVerified" id="emailVerified" ng-disabled="!create && !user.access.manage" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'email-verified.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="reqActions">{{:: 'required-user-actions' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<select ui-select2 id="reqActions" ng-model="user.requiredActions" data-placeholder="{{:: 'select-an-action.placeholder' | translate}}" multiple>
|
||||
<option ng-repeat="action in userReqActionList" value="{{action.alias}}">{{action.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'required-user-actions.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="form-group clearfix" data-ng-if="realm.internationalizationEnabled">
|
||||
<label class="col-md-2 control-label" for="locale">{{:: 'locale' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
<div>
|
||||
<select class="form-control" id="locale"
|
||||
ng-model="user.attributes.locale"
|
||||
ng-options="o as o for o in realm.supportedLocales">
|
||||
<option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group clearfix" data-ng-hide="create || !access.impersonation">
|
||||
<label class="col-md-2 control-label" for="impersonate">{{:: 'impersonate-user' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<button id="impersonate" data-ng-show="access.impersonation" kc-read-only-ignore class="btn btn-default" data-ng-click="impersonate()">{{:: 'impersonate' | translate}}</button>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'impersonate-user.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageUsers">
|
||||
<button kc-save data-ng-show="changed">{{:: 'save' | translate}}</button>
|
||||
<button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="!create && user.access.manage">
|
||||
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
|
||||
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<form class="form-horizontal" ng-controller="UserAvatarCtrl" novalidate>
|
||||
<fieldset class="border-top">
|
||||
<legend><span class="text">Avatar</span></legend>
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2">
|
||||
<img style="max-width:600px;" src="{{ avatarUrl }}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="image">Upload</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="file" name="image" id="image" onchange="angular.element(this).scope().uploadAvatar(this.files)" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
|
@ -1 +1,2 @@
|
|||
parent=keycloak
|
||||
scripts=js/user-avatar.js
|
Loading…
Reference in New Issue