Merge remote-tracking branch 'origin/dev-v7.8' into temp-U4-10803
# Conflicts: # src/Umbraco.Web.UI.Client/bower.json
This commit is contained in:
@@ -33,56 +33,44 @@
|
||||
"clipboard": "1.7.1",
|
||||
"font-awesome": "~4.2"
|
||||
},
|
||||
|
||||
"install": {
|
||||
|
||||
"path": "lib-bower",
|
||||
|
||||
"ignore": [
|
||||
"font-awesome",
|
||||
"angular",
|
||||
"bootstrap",
|
||||
"codemirror"
|
||||
],
|
||||
|
||||
"sources": {
|
||||
"moment": "bower_components/moment/min/moment-with-locales.js",
|
||||
|
||||
"underscore": [
|
||||
"bower_components/underscore/underscore-min.js",
|
||||
"bower_components/underscore/underscore-min.map"
|
||||
],
|
||||
|
||||
"jquery": [
|
||||
"bower_components/jquery/dist/jquery.min.js",
|
||||
"bower_components/jquery/dist/jquery.min.map"
|
||||
],
|
||||
|
||||
"angular-dynamic-locale": [
|
||||
"bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js",
|
||||
"bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js.map"
|
||||
],
|
||||
|
||||
"angular-local-storage": [
|
||||
"bower_components/angular-local-storage/dist/angular-local-storage.min.js",
|
||||
"bower_components/angular-local-storage/dist/angular-local-storage.min.js.map"
|
||||
],
|
||||
|
||||
"tinymce": [
|
||||
"bower_components/tinymce/tinymce.min.js"
|
||||
],
|
||||
|
||||
"typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js",
|
||||
|
||||
"rgrove-lazyload":"bower_components/rgrove-lazyload/lazyload.js",
|
||||
|
||||
"ng-file-upload":"bower_components/ng-file-upload/ng-file-upload.min.js",
|
||||
|
||||
"jquery-ui":"bower_components/jquery-ui/jquery-ui.min.js",
|
||||
|
||||
"jquery-migrate":"bower_components/jquery-migrate/jquery-migrate.min.js",
|
||||
|
||||
"rgrove-lazyload": "bower_components/rgrove-lazyload/lazyload.js",
|
||||
"ng-file-upload": "bower_components/ng-file-upload/ng-file-upload.min.js",
|
||||
"jquery-ui": "bower_components/jquery-ui/jquery-ui.min.js",
|
||||
"jquery-migrate": "bower_components/jquery-migrate/jquery-migrate.min.js",
|
||||
"clipboard": "bower_components/clipboard/dist/clipboard.min.js"
|
||||
}
|
||||
},
|
||||
"resolutions": {
|
||||
"moment": ">=2.19.3 <3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,52 +16,16 @@ function eventsService($q, $rootScope) {
|
||||
|
||||
return {
|
||||
|
||||
/** raise an event with a given name, returns an array of promises for each listener */
|
||||
emit: function (name, args) {
|
||||
/** raise an event with a given name */
|
||||
emit: function (name, args) {
|
||||
|
||||
//there are no listeners
|
||||
if (!$rootScope.$$listeners[name]) {
|
||||
return;
|
||||
//return [];
|
||||
}
|
||||
|
||||
//send the event
|
||||
$rootScope.$emit(name, args);
|
||||
|
||||
|
||||
//PP: I've commented out the below, since we currently dont
|
||||
// expose the eventsService as a documented api
|
||||
// and think we need to figure out our usecases for this
|
||||
// since the below modifies the return value of the then on() method
|
||||
/*
|
||||
//setup a deferred promise for each listener
|
||||
var deferred = [];
|
||||
for (var i = 0; i < $rootScope.$$listeners[name].length; i++) {
|
||||
deferred.push($q.defer());
|
||||
}*/
|
||||
|
||||
//create a new event args object to pass to the
|
||||
// $emit containing methods that will allow listeners
|
||||
// to return data in an async if required
|
||||
/*
|
||||
var eventArgs = {
|
||||
args: args,
|
||||
reject: function (a) {
|
||||
deferred.pop().reject(a);
|
||||
},
|
||||
resolve: function (a) {
|
||||
deferred.pop().resolve(a);
|
||||
}
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//return an array of promises
|
||||
var promises = _.map(deferred, function(p) {
|
||||
return p.promise;
|
||||
});
|
||||
return promises;*/
|
||||
},
|
||||
|
||||
/** subscribe to a method, or use scope.$on = same thing */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* Registers all tours from the server and returns a promise
|
||||
*/
|
||||
function registerAllTours() {
|
||||
tours = [];
|
||||
return tourResource.getTours().then(function(tourFiles) {
|
||||
angular.forEach(tourFiles, function (tourFile) {
|
||||
angular.forEach(tourFile.tours, function(newTour) {
|
||||
@@ -218,7 +219,38 @@
|
||||
var deferred = $q.defer();
|
||||
var tours = getTours();
|
||||
setTourStatuses(tours).then(function() {
|
||||
var groupedTours = _.groupBy(tours, "group");
|
||||
var groupedTours = [];
|
||||
tours.forEach(function (item) {
|
||||
|
||||
var groupExists = false;
|
||||
var newGroup = {
|
||||
"group": "",
|
||||
"tours": []
|
||||
};
|
||||
|
||||
groupedTours.forEach(function(group){
|
||||
// extend existing group if it is already added
|
||||
if(group.group === item.group) {
|
||||
if(item.groupOrder) {
|
||||
group.groupOrder = item.groupOrder
|
||||
}
|
||||
groupExists = true;
|
||||
group.tours.push(item)
|
||||
}
|
||||
});
|
||||
|
||||
// push new group to array if it doesn't exist
|
||||
if(!groupExists) {
|
||||
newGroup.group = item.group;
|
||||
if(item.groupOrder) {
|
||||
newGroup.groupOrder = item.groupOrder
|
||||
}
|
||||
newGroup.tours.push(item);
|
||||
groupedTours.push(newGroup);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
deferred.resolve(groupedTours);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
|
||||
function showTourButton(index, tourGroup) {
|
||||
if(index !== 0) {
|
||||
var prevTour = tourGroup[index - 1];
|
||||
var prevTour = tourGroup.tours[index - 1];
|
||||
if(prevTour.completed) {
|
||||
return true;
|
||||
}
|
||||
@@ -147,12 +147,12 @@
|
||||
// Finding out, how many tours are completed for the progress circle
|
||||
angular.forEach(vm.tours, function(group){
|
||||
var completedTours = 0;
|
||||
angular.forEach(group, function(tour){
|
||||
angular.forEach(group.tours, function(tour){
|
||||
if(tour.completed) {
|
||||
completedTours++;
|
||||
}
|
||||
});
|
||||
group.completedPercentage = Math.round((completedTours/group.length)*100);
|
||||
group.completedPercentage = Math.round((completedTours/group.tours.length)*100);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
|
||||
<h5 style="margin-bottom: 10px; margin-top: 0;">Tours</h5>
|
||||
|
||||
<div ng-repeat="(key,value) in vm.tours" style="margin-bottom: 5px;">
|
||||
<div ng-repeat="tourGroup in vm.tours | orderBy:'groupOrder'" style="margin-bottom: 5px;">
|
||||
|
||||
<div class="umb-help-list">
|
||||
|
||||
<a href="" class="umb-help-list-item umb-help-list-item__content flex items-center justify-between" style="text-decoration: none;" ng-click="value.open = !value.open">
|
||||
<h5 class="umb-help-list-item__group-title"><i style="margin-right: 2px;text-decoration: none;" ng-class="{'icon-navigation-right': !value.open, 'icon-navigation-down': value.open}"></i>
|
||||
<span ng-if="key !== 'undefined'">{{key}}</span>
|
||||
<span ng-if="key === 'undefined'">Other</span>
|
||||
<a href="" class="umb-help-list-item umb-help-list-item__content flex items-center justify-between" style="text-decoration: none;" ng-click="tourGroup.open = !tourGroup.open">
|
||||
<h5 class="umb-help-list-item__group-title"><i style="margin-right: 2px;text-decoration: none;" ng-class="{'icon-navigation-right': !tourGroup.open, 'icon-navigation-down': tourGroup.open}"></i>
|
||||
<span ng-if="tourGroup.group !== 'undefined'">{{tourGroup.group}}</span>
|
||||
<span ng-if="tourGroup.group === 'undefined'">Other</span>
|
||||
</h5>
|
||||
<umb-progress-circle
|
||||
percentage="{{value.completedPercentage}}"
|
||||
percentage="{{tourGroup.completedPercentage}}"
|
||||
size="40">
|
||||
</umb-progress-circle>
|
||||
</a>
|
||||
|
||||
<div ng-if="value.open">
|
||||
<div data-element="tour-{{tour.alias}}" class="umb-help-list-item" ng-repeat="tour in value">
|
||||
<div ng-if="tourGroup.open">
|
||||
<div data-element="tour-{{tour.alias}}" class="umb-help-list-item" ng-repeat="tour in tourGroup.tours">
|
||||
<div class="umb-help-list-item__content justify-between">
|
||||
<div class="flex items-center">
|
||||
<div ng-if="!tour.completed" class="umb-number-badge umb-number-badge--xs umb-help-list-item__icon">{{ $index + 1 }}</div>
|
||||
@@ -36,7 +36,7 @@
|
||||
<span ng-class="{'strike': tour.completed}" class="umb-help-list-item__title">{{ tour.name }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<umb-button ng-if="!tour.completed && vm.showTourButton($index, value)" button-style="primary" size="xxs" type="button" label="Start" action="vm.startTour(tour)"></umb-button>
|
||||
<umb-button ng-if="!tour.completed && vm.showTourButton($index, tourGroup)" button-style="primary" size="xxs" type="button" label="Start" action="vm.startTour(tour)"></umb-button>
|
||||
<umb-button ng-if="tour.completed" size="xxs" type="button" label="Rerun" action="vm.startTour(tour)"></umb-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function UserEditController($scope, $timeout, $location, $routeParams, formHelper, usersResource, userService, contentEditingHelper, localizationService, notificationsService, mediaHelper, Upload, umbRequestHelper, usersHelper, authResource, dateHelper) {
|
||||
function UserEditController($scope, eventsService, $q, $timeout, $location, $routeParams, formHelper, usersResource, userService, contentEditingHelper, localizationService, notificationsService, mediaHelper, Upload, umbRequestHelper, usersHelper, authResource, dateHelper) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
|
||||
vm.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes);
|
||||
vm.usernameIsEmail = Umbraco.Sys.ServerVariables.umbracoSettings.usernameIsEmail;
|
||||
|
||||
|
||||
//create the initial model for change password
|
||||
vm.changePasswordModel = {
|
||||
config: {},
|
||||
@@ -33,6 +33,7 @@
|
||||
vm.unlockUser = unlockUser;
|
||||
vm.clearAvatar = clearAvatar;
|
||||
vm.save = save;
|
||||
|
||||
vm.toggleChangePassword = toggleChangePassword;
|
||||
|
||||
function init() {
|
||||
@@ -117,38 +118,83 @@
|
||||
|
||||
function save() {
|
||||
|
||||
vm.page.saveButtonState = "busy";
|
||||
vm.user.resetPasswordValue = null;
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: vm.labels.saving })) {
|
||||
|
||||
//anytime a user is changing another user's password, we are in effect resetting it so we need to set that flag here
|
||||
if(vm.user.changePassword) {
|
||||
vm.user.changePassword.reset = !vm.user.changePassword.oldPassword && !vm.user.isCurrentUser;
|
||||
//anytime a user is changing another user's password, we are in effect resetting it so we need to set that flag here
|
||||
if (vm.user.changePassword) {
|
||||
vm.user.changePassword.reset = !vm.user.changePassword.oldPassword && !vm.user.isCurrentUser;
|
||||
}
|
||||
|
||||
vm.page.saveButtonState = "busy";
|
||||
vm.user.resetPasswordValue = null;
|
||||
|
||||
//save current nav to be restored later so that the tabs dont change
|
||||
var currentNav = vm.user.navigation;
|
||||
|
||||
usersResource.saveUser(vm.user)
|
||||
.then(function (saved) {
|
||||
|
||||
//if the user saved, then try to execute all extended save options
|
||||
extendedSave(saved).then(function(result) {
|
||||
//if all is good, then reset the form
|
||||
formHelper.resetForm({ scope: $scope, notifications: saved.notifications });
|
||||
}, function(err) {
|
||||
//otherwise show the notifications for the user being saved
|
||||
formHelper.showNotifications(saved);
|
||||
});
|
||||
|
||||
vm.user = _.omit(saved, "navigation");
|
||||
//restore
|
||||
vm.user.navigation = currentNav;
|
||||
setUserDisplayState();
|
||||
formatDatesToLocal(vm.user);
|
||||
|
||||
vm.changePasswordModel.isChanging = false;
|
||||
//the user has a password if they are not states: Invited, NoCredentials
|
||||
vm.changePasswordModel.config.hasPassword = vm.user.userState !== 3 && vm.user.userState !== 4;
|
||||
|
||||
vm.page.saveButtonState = "success";
|
||||
|
||||
}, function (err) {
|
||||
|
||||
contentEditingHelper.handleSaveError({
|
||||
redirectOnFailure: false,
|
||||
err: err
|
||||
});
|
||||
//show any notifications
|
||||
if (err.data) {
|
||||
formHelper.showNotifications(err.data);
|
||||
}
|
||||
vm.page.saveButtonState = "error";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
contentEditingHelper.contentEditorPerformSave({
|
||||
statusMessage: vm.labels.saving,
|
||||
saveMethod: usersResource.saveUser,
|
||||
scope: $scope,
|
||||
content: vm.user,
|
||||
// We do not redirect on failure for users - this is because it is not possible to actually save a user
|
||||
// when server side validation fails - as opposed to content where we are capable of saving the content
|
||||
// item if server side validation fails
|
||||
redirectOnFailure: false,
|
||||
rebindCallback: function (orignal, saved) { }
|
||||
}).then(function (saved) {
|
||||
/**
|
||||
* Used to emit the save event and await any async operations being performed by editor extensions
|
||||
* @param {any} savedUser
|
||||
*/
|
||||
function extendedSave(savedUser) {
|
||||
|
||||
vm.user = saved;
|
||||
setUserDisplayState();
|
||||
formatDatesToLocal(vm.user);
|
||||
//used to track any promises added by the event handlers to be awaited
|
||||
var promises = [];
|
||||
|
||||
var args = {
|
||||
//getPromise: getPromise,
|
||||
user: savedUser,
|
||||
//a promise can be added by the event handler if the handler needs an async operation to be awaited
|
||||
addPromise: function (p) {
|
||||
promises.push(p);
|
||||
}
|
||||
};
|
||||
|
||||
vm.changePasswordModel.isChanging = false;
|
||||
vm.page.saveButtonState = "success";
|
||||
|
||||
//the user has a password if they are not states: Invited, NoCredentials
|
||||
vm.changePasswordModel.config.hasPassword = vm.user.userState !== 3 && vm.user.userState !== 4;
|
||||
}, function (err) {
|
||||
vm.page.saveButtonState = "error";
|
||||
});
|
||||
//emit the event
|
||||
eventsService.emit("editors.user.editController.save", args);
|
||||
|
||||
//await all promises to complete
|
||||
var resultPromise = $q.all(promises);
|
||||
|
||||
return resultPromise;
|
||||
}
|
||||
|
||||
function goToPage(ancestor) {
|
||||
|
||||
@@ -1,406 +1,27 @@
|
||||
<div ng-controller="Umbraco.Editors.Users.UserController as vm" class="clearfix">
|
||||
|
||||
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
|
||||
|
||||
<form name="editUserForm" novalidate val-form-manager>
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<umb-editor-header
|
||||
name="vm.user.name"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true">
|
||||
<umb-editor-header name="vm.user.name"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true"
|
||||
navigation="vm.user.navigation">
|
||||
</umb-editor-header>
|
||||
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
<umb-load-indicator
|
||||
ng-if="vm.loading">
|
||||
</umb-load-indicator>
|
||||
|
||||
<div ng-if="!vm.loading" class="umb-packages-view-wrapper" style="padding: 0;">
|
||||
|
||||
<div class="umb-package-details">
|
||||
<div ng-if="!vm.loading" class="umb-packages-view-wrapper" style="padding: 0;">
|
||||
|
||||
<div class="umb-package-details__main-content">
|
||||
|
||||
<umb-box>
|
||||
|
||||
<umb-box-header title-key="user_profile"></umb-box-header>
|
||||
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<umb-control-group label="@general_email" required="true">
|
||||
|
||||
<input
|
||||
type="email"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enteremail"
|
||||
class="input-block-level"
|
||||
ng-model="vm.user.email"
|
||||
umb-auto-focus name="email"
|
||||
val-email
|
||||
required
|
||||
val-server-field="Email" />
|
||||
<span class="help-inline" val-msg-for="email" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="email" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_username" ng-if="!vm.usernameIsEmail" required="true">
|
||||
<input
|
||||
type="text"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enterusername"
|
||||
class="input-block-level"
|
||||
ng-model="vm.user.username"
|
||||
umb-auto-focus name="username"
|
||||
required
|
||||
val-server-field="Username" />
|
||||
<span class="help-inline" val-msg-for="username" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="username" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@user_language" description="@user_languageHelp">
|
||||
<select
|
||||
class="input-block-level"
|
||||
ng-model="vm.user.culture"
|
||||
ng-options="key as value for (key, value) in vm.user.availableCultures"
|
||||
name="culture"
|
||||
required
|
||||
val-server-field="Culture">
|
||||
</select>
|
||||
<span class="help-inline" val-msg-for="culture" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="culture" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<umb-box>
|
||||
<umb-box-header title-key="user_assignAccess"></umb-box-header>
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<umb-control-group style="margin-bottom: 25px;" label="@general_groups" description="@user_groupsHelp" required="true">
|
||||
|
||||
<umb-user-group-preview
|
||||
ng-repeat="userGroup in vm.user.userGroups"
|
||||
icon="userGroup.icon"
|
||||
name="userGroup.name"
|
||||
sections="userGroup.sections"
|
||||
content-start-node="userGroup.contentStartNode"
|
||||
media-start-node="userGroup.mediaStartNode"
|
||||
allow-remove="!vm.user.isCurrentUser"
|
||||
on-remove="vm.removeSelectedItem($index, vm.user.userGroups)">
|
||||
</umb-user-group-preview>
|
||||
|
||||
<a href=""
|
||||
ng-if="!vm.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="vm.openUserGroupPicker()"
|
||||
prevent-default>
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group style="margin-bottom: 25px;" label="@user_startnodes" description="@user_startnodeshelp">
|
||||
|
||||
<umb-node-preview
|
||||
style="max-width: 100%;"
|
||||
ng-repeat="node in vm.user.startContentIds"
|
||||
icon="node.icon"
|
||||
name="node.name"
|
||||
allow-remove="!vm.user.isCurrentUser"
|
||||
on-remove="vm.removeSelectedItem($index, vm.user.startContentIds)">
|
||||
</umb-node-preview>
|
||||
|
||||
<umb-node-preview
|
||||
ng-if="vm.user.startContentIds.length === 0 && vm.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
name="vm.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
|
||||
<a href=""
|
||||
ng-if="!vm.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="vm.openContentPicker()"
|
||||
prevent-default>
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@user_mediastartnodes" description="@user_mediastartnodeshelp">
|
||||
|
||||
<umb-node-preview
|
||||
style="max-width: 100%;"
|
||||
ng-repeat="node in vm.user.startMediaIds"
|
||||
icon="node.icon"
|
||||
name="node.name"
|
||||
allow-remove="!vm.user.isCurrentUser"
|
||||
on-remove="vm.removeSelectedItem($index, vm.user.startMediaIds)">
|
||||
</umb-node-preview>
|
||||
|
||||
<umb-node-preview
|
||||
ng-if="vm.user.startMediaIds.length === 0 && vm.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
name="vm.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
|
||||
<a href=""
|
||||
ng-if="!vm.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="vm.openMediaPicker()"
|
||||
prevent-default>
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<umb-box>
|
||||
<umb-box-header title-key="user_access" description-key="user_accessHelp"></umb-box-header>
|
||||
<umb-box-content class="block-form" style="padding-bottom: 0;">
|
||||
|
||||
<umb-control-group label="@sections_content">
|
||||
<umb-node-preview
|
||||
style="max-width: 100%;"
|
||||
ng-repeat="node in vm.user.calculatedStartContentIds"
|
||||
icon="node.icon"
|
||||
name="node.name">
|
||||
</umb-node-preview>
|
||||
<umb-node-preview
|
||||
ng-if="vm.user.calculatedStartContentIds.length === 0"
|
||||
style="max-width: 100%;"
|
||||
name="vm.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@sections_media">
|
||||
<umb-node-preview
|
||||
style="max-width: 100%;"
|
||||
ng-repeat="node in vm.user.calculatedStartMediaIds"
|
||||
icon="node.icon"
|
||||
name="node.name">
|
||||
</umb-node-preview>
|
||||
<umb-node-preview
|
||||
ng-if="vm.user.calculatedStartMediaIds.length === 0"
|
||||
style="max-width: 100%;"
|
||||
name="vm.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
</umb-control-group>
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__sidebar">
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
|
||||
<!-- Avatar -->
|
||||
<div style="margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #d8d7d9;">
|
||||
<ng-form name="avatarForm" class="flex flex-column justify-center items-center">
|
||||
|
||||
<umb-avatar
|
||||
style="margin-bottom: 15px;"
|
||||
color="secondary"
|
||||
size="xxl"
|
||||
name="{{vm.user.name}}"
|
||||
img-src="{{vm.user.avatars[3]}}"
|
||||
img-srcset="{{vm.user.avatars[4]}} 2x, {{vm.user.avatars[4]}} 3x">
|
||||
</umb-avatar>
|
||||
|
||||
<umb-progress-bar
|
||||
style="max-width: 120px;"
|
||||
ng-if="vm.avatarFile.uploadStatus === 'uploading'"
|
||||
progress="{{ vm.avatarFile.uploadProgress }}"
|
||||
size="s">
|
||||
</umb-progress-bar>
|
||||
|
||||
<div class="flex items-center" ng-if="vm.avatarFile.uploadStatus !== 'uploading'">
|
||||
|
||||
<a href=""
|
||||
class="umb-user-group-preview__action"
|
||||
ngf-select ng-model="filesHolder"
|
||||
ngf-change="changeAvatar($files, $event)"
|
||||
ngf-multiple="false"
|
||||
ngf-pattern="{{vm.acceptedFileTypes}}"
|
||||
ngf-max-size="{{ vm.maxFileSize }}">
|
||||
<localize key="user_changePhoto">Change photo</localize>
|
||||
</a>
|
||||
|
||||
<a href=""
|
||||
ng-if="vm.user.avatars"
|
||||
class="umb-user-group-preview__action umb-user-group-preview__action--red"
|
||||
ng-click="vm.clearAvatar()"
|
||||
prevent-default>
|
||||
<localize key="user_removePhoto">Remove photo</localize>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-form>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button
|
||||
ng-if="vm.user.userDisplayState.key === 'Disabled' && !vm.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[success,block]"
|
||||
state="vm.enableUserButtonState"
|
||||
action="vm.enableUser()"
|
||||
label="Enable"
|
||||
label-key="actions_enable"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button
|
||||
ng-if="vm.user.userDisplayState.key === 'LockedOut' && !vm.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[success,block]"
|
||||
state="vm.unlockUserButtonState"
|
||||
action="vm.unlockUser()"
|
||||
label="Unlock"
|
||||
label-key="actions_unlock"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button
|
||||
ng-if="vm.user.userDisplayState.key !== 'Disabled' && !vm.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[info,block]"
|
||||
action="vm.disableUser()"
|
||||
state="vm.disableUserButtonState"
|
||||
label="Disable"
|
||||
label-key="actions_disable"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="[info,block]"
|
||||
action="vm.toggleChangePassword()"
|
||||
label="Change password"
|
||||
label-key="general_changePassword"
|
||||
state="changePasswordButtonState"
|
||||
ng-if="vm.changePasswordModel.isChanging === false"
|
||||
size="s">
|
||||
</umb-button>
|
||||
|
||||
<ng-form ng-if="vm.changePasswordModel.isChanging" name="passwordForm" class="block-form" val-form-manager>
|
||||
|
||||
<change-password
|
||||
password-values="vm.user.changePassword"
|
||||
config="vm.changePasswordModel.config">
|
||||
</change-password>
|
||||
|
||||
<umb-button
|
||||
type="button"
|
||||
action="vm.toggleChangePassword()"
|
||||
label="Cancel"
|
||||
label-key="general_cancel"
|
||||
button-style="cancel">
|
||||
</umb-button>
|
||||
|
||||
</ng-form>
|
||||
|
||||
<div ng-if="vm.user.resetPasswordValue">
|
||||
<p><br />Password reset to value: <strong>{{vm.user.resetPasswordValue}}</strong></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- User stats -->
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="general_status">Status</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<umb-badge style="margin-top: 4px;" size="s" color="{{vm.user.userDisplayState.color}}">
|
||||
{{vm.user.userDisplayState.name}}
|
||||
</umb-badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastLogin">Last login</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<span ng-if="vm.user.lastLoginDate">{{ vm.user.formattedLastLogin }}</span>
|
||||
<span ng-if="!vm.user.lastLoginDate">{{ vm.user.name | umbWordLimit:1 }} <localize key="user_noLogin">has not logged in yet</localize></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_failedPasswordAttempts">Failed login attempts</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
{{ vm.user.failedPasswordAttempts }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastLockoutDate">Last lockout date</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<span ng-if="vm.user.lastLockoutDate === '0001-01-01T00:00:00'">
|
||||
{{ vm.user.name | umbWordLimit:1 }} <localize key="user_noLockouts">hasn't been locked out</localize>
|
||||
</span>
|
||||
<span ng-if="vm.user.lastLockoutDate !== '0001-01-01T00:00:00'">{{ vm.user.formattedLastLockoutDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastPasswordChangeDate">Password is last changed</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<span ng-if="vm.user.lastPasswordChangeDate === '0001-01-01T00:00:00'">
|
||||
<localize key="user_noPasswordChange">The password hasn't been changed</localize>
|
||||
</span>
|
||||
<span ng-if="vm.user.lastPasswordChangeDate !== '0001-01-01T00:00:00'">{{ vm.user.formattedLastPasswordChangeDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_createDate">User is created</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
{{ vm.user.formattedCreateDate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_updateDate">User is last updated</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
{{ vm.user.formattedUpdateDate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<umb-editor-sub-views
|
||||
ng-if="!vm.loading"
|
||||
sub-views="vm.user.navigation"
|
||||
model="vm">
|
||||
</umb-editor-sub-views>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -410,33 +31,30 @@
|
||||
|
||||
<umb-editor-footer-content-left>
|
||||
|
||||
<umb-breadcrumbs
|
||||
ancestors="vm.breadcrumbs"
|
||||
allow-on-open="true"
|
||||
on-open="vm.goToPage(ancestor)">
|
||||
<umb-breadcrumbs ancestors="vm.breadcrumbs"
|
||||
allow-on-open="true"
|
||||
on-open="vm.goToPage(ancestor)">
|
||||
</umb-breadcrumbs>
|
||||
|
||||
</umb-editor-footer-content-left>
|
||||
|
||||
<umb-editor-footer-content-right>
|
||||
|
||||
<umb-button
|
||||
type="button"
|
||||
action="vm.goToPage(vm.breadcrumbs[0])"
|
||||
label="Return to list"
|
||||
label-key="buttons_returnToList"
|
||||
disabled="vm.loading">
|
||||
<umb-button type="button"
|
||||
action="vm.goToPage(vm.breadcrumbs[0])"
|
||||
label="Return to list"
|
||||
label-key="buttons_returnToList"
|
||||
disabled="vm.loading">
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
type="button"
|
||||
action="vm.save()"
|
||||
state="vm.page.saveButtonState"
|
||||
button-style="success"
|
||||
shortcut="ctrl+s"
|
||||
label="Save"
|
||||
label-key="buttons_save"
|
||||
disabled="vm.loading">
|
||||
<umb-button type="button"
|
||||
action="vm.save()"
|
||||
state="vm.page.saveButtonState"
|
||||
button-style="success"
|
||||
shortcut="ctrl+s"
|
||||
label="Save"
|
||||
label-key="buttons_save"
|
||||
disabled="vm.loading">
|
||||
</umb-button>
|
||||
|
||||
</umb-editor-footer-content-right>
|
||||
@@ -447,25 +65,22 @@
|
||||
|
||||
</form>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="vm.userGroupPicker.show"
|
||||
model="vm.userGroupPicker"
|
||||
view="vm.userGroupPicker.view"
|
||||
position="right">
|
||||
<umb-overlay ng-if="vm.userGroupPicker.show"
|
||||
model="vm.userGroupPicker"
|
||||
view="vm.userGroupPicker.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="vm.contentPicker.show"
|
||||
model="vm.contentPicker"
|
||||
view="vm.contentPicker.view"
|
||||
position="right">
|
||||
<umb-overlay ng-if="vm.contentPicker.show"
|
||||
model="vm.contentPicker"
|
||||
view="vm.contentPicker.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="vm.mediaPicker.show"
|
||||
model="vm.mediaPicker"
|
||||
view="vm.mediaPicker.view"
|
||||
position="right">
|
||||
<umb-overlay ng-if="vm.mediaPicker.show"
|
||||
model="vm.mediaPicker"
|
||||
view="vm.mediaPicker.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,361 @@
|
||||
<div class="umb-package-details">
|
||||
|
||||
<div class="umb-package-details__main-content">
|
||||
|
||||
<umb-box>
|
||||
|
||||
<umb-box-header title-key="user_profile"></umb-box-header>
|
||||
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<umb-control-group label="@general_email" required="true">
|
||||
|
||||
<input type="email"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enteremail"
|
||||
class="input-block-level"
|
||||
ng-model="model.user.email"
|
||||
umb-auto-focus name="email"
|
||||
val-email
|
||||
required
|
||||
val-server-field="Email" />
|
||||
<span class="help-inline" val-msg-for="email" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="email" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_username" ng-if="!model.usernameIsEmail" required="true">
|
||||
<input type="text"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enterusername"
|
||||
class="input-block-level"
|
||||
ng-model="model.user.username"
|
||||
umb-auto-focus name="username"
|
||||
required
|
||||
val-server-field="Username" />
|
||||
<span class="help-inline" val-msg-for="username" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="username" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@user_language" description="@user_languageHelp">
|
||||
<select class="input-block-level"
|
||||
ng-model="model.user.culture"
|
||||
ng-options="key as value for (key, value) in model.user.availableCultures"
|
||||
name="culture"
|
||||
required
|
||||
val-server-field="Culture"></select>
|
||||
<span class="help-inline" val-msg-for="culture" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="culture" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<umb-box>
|
||||
<umb-box-header title-key="user_assignAccess"></umb-box-header>
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<umb-control-group style="margin-bottom: 25px;" label="@general_groups" description="@user_groupsHelp" required="true">
|
||||
|
||||
<umb-user-group-preview ng-repeat="userGroup in model.user.userGroups"
|
||||
icon="userGroup.icon"
|
||||
name="userGroup.name"
|
||||
sections="userGroup.sections"
|
||||
content-start-node="userGroup.contentStartNode"
|
||||
media-start-node="userGroup.mediaStartNode"
|
||||
allow-remove="!model.user.isCurrentUser"
|
||||
on-remove="model.removeSelectedItem($index, model.user.userGroups)">
|
||||
</umb-user-group-preview>
|
||||
|
||||
<a href=""
|
||||
ng-if="!model.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="model.openUserGroupPicker()"
|
||||
prevent-default>
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group style="margin-bottom: 25px;" label="@user_startnodes" description="@user_startnodeshelp">
|
||||
|
||||
<umb-node-preview style="max-width: 100%;"
|
||||
ng-repeat="node in model.user.startContentIds"
|
||||
icon="node.icon"
|
||||
name="node.name"
|
||||
allow-remove="!model.user.isCurrentUser"
|
||||
on-remove="model.removeSelectedItem($index, model.user.startContentIds)">
|
||||
</umb-node-preview>
|
||||
|
||||
<umb-node-preview ng-if="model.user.startContentIds.length === 0 && model.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
name="model.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
|
||||
<a href=""
|
||||
ng-if="!model.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="model.openContentPicker()"
|
||||
prevent-default>
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@user_mediastartnodes" description="@user_mediastartnodeshelp">
|
||||
|
||||
<umb-node-preview style="max-width: 100%;"
|
||||
ng-repeat="node in model.user.startMediaIds"
|
||||
icon="node.icon"
|
||||
name="node.name"
|
||||
allow-remove="!model.user.isCurrentUser"
|
||||
on-remove="model.removeSelectedItem($index, model.user.startMediaIds)">
|
||||
</umb-node-preview>
|
||||
|
||||
<umb-node-preview ng-if="model.user.startMediaIds.length === 0 && model.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
name="model.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
|
||||
<a href=""
|
||||
ng-if="!model.user.isCurrentUser"
|
||||
style="max-width: 100%;"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="model.openMediaPicker()"
|
||||
prevent-default>
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<umb-box>
|
||||
<umb-box-header title-key="user_access" description-key="user_accessHelp"></umb-box-header>
|
||||
<umb-box-content class="block-form" style="padding-bottom: 0;">
|
||||
|
||||
<umb-control-group label="@sections_content">
|
||||
<umb-node-preview style="max-width: 100%;"
|
||||
ng-repeat="node in model.user.calculatedStartContentIds"
|
||||
icon="node.icon"
|
||||
name="node.name">
|
||||
</umb-node-preview>
|
||||
<umb-node-preview ng-if="model.user.calculatedStartContentIds.length === 0"
|
||||
style="max-width: 100%;"
|
||||
name="model.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@sections_media">
|
||||
<umb-node-preview style="max-width: 100%;"
|
||||
ng-repeat="node in model.user.calculatedStartMediaIds"
|
||||
icon="node.icon"
|
||||
name="node.name">
|
||||
</umb-node-preview>
|
||||
<umb-node-preview ng-if="model.user.calculatedStartMediaIds.length === 0"
|
||||
style="max-width: 100%;"
|
||||
name="model.labels.noStartNodes">
|
||||
</umb-node-preview>
|
||||
</umb-control-group>
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__sidebar">
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
|
||||
<!-- Avatar -->
|
||||
<div style="margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #d8d7d9;">
|
||||
<ng-form name="avatarForm" class="flex flex-column justify-center items-center">
|
||||
|
||||
<umb-avatar style="margin-bottom: 15px;"
|
||||
color="secondary"
|
||||
size="xxl"
|
||||
name="{{model.user.name}}"
|
||||
img-src="{{model.user.avatars[3]}}"
|
||||
img-srcset="{{model.user.avatars[4]}} 2x, {{model.user.avatars[4]}} 3x">
|
||||
</umb-avatar>
|
||||
|
||||
<umb-progress-bar style="max-width: 120px;"
|
||||
ng-if="model.avatarFile.uploadStatus === 'uploading'"
|
||||
progress="{{ model.avatarFile.uploadProgress }}"
|
||||
size="s">
|
||||
</umb-progress-bar>
|
||||
|
||||
<div class="flex items-center" ng-if="model.avatarFile.uploadStatus !== 'uploading'">
|
||||
|
||||
<a href=""
|
||||
class="umb-user-group-preview__action"
|
||||
ngf-select ng-model="filesHolder"
|
||||
ngf-change="changeAvatar($files, $event)"
|
||||
ngf-multiple="false"
|
||||
ngf-pattern="{{model.acceptedFileTypes}}"
|
||||
ngf-max-size="{{ model.maxFileSize }}">
|
||||
<localize key="user_changePhoto">Change photo</localize>
|
||||
</a>
|
||||
|
||||
<a href=""
|
||||
ng-if="model.user.avatars"
|
||||
class="umb-user-group-preview__action umb-user-group-preview__action--red"
|
||||
ng-click="model.clearAvatar()"
|
||||
prevent-default>
|
||||
<localize key="user_removePhoto">Remove photo</localize>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-form>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button ng-if="model.user.userDisplayState.key === 'Disabled' && !model.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[success,block]"
|
||||
state="model.enableUserButtonState"
|
||||
action="model.enableUser()"
|
||||
label="Enable"
|
||||
label-key="actions_enable"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button ng-if="model.user.userDisplayState.key === 'LockedOut' && !model.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[success,block]"
|
||||
state="model.unlockUserButtonState"
|
||||
action="model.unlockUser()"
|
||||
label="Unlock"
|
||||
label-key="actions_unlock"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button ng-if="model.user.userDisplayState.key !== 'Disabled' && !model.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[info,block]"
|
||||
action="model.disableUser()"
|
||||
state="model.disableUserButtonState"
|
||||
label="Disable"
|
||||
label-key="actions_disable"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<umb-button type="button"
|
||||
button-style="[info,block]"
|
||||
action="model.toggleChangePassword()"
|
||||
label="Change password"
|
||||
label-key="general_changePassword"
|
||||
state="changePasswordButtonState"
|
||||
ng-if="model.changePasswordModel.isChanging === false"
|
||||
size="s">
|
||||
</umb-button>
|
||||
|
||||
<ng-form ng-if="model.changePasswordModel.isChanging" name="passwordForm" class="block-form" val-form-manager>
|
||||
|
||||
<change-password password-values="model.user.changePassword"
|
||||
config="model.changePasswordModel.config">
|
||||
</change-password>
|
||||
|
||||
<umb-button type="button"
|
||||
action="model.toggleChangePassword()"
|
||||
label="Cancel"
|
||||
label-key="general_cancel"
|
||||
button-style="cancel">
|
||||
</umb-button>
|
||||
|
||||
</ng-form>
|
||||
|
||||
<div ng-if="model.user.resetPasswordValue">
|
||||
<p><br />Password reset to value: <strong>{{model.user.resetPasswordValue}}</strong></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- User stats -->
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="general_status">Status</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<umb-badge style="margin-top: 4px;" size="s" color="{{model.user.userDisplayState.color}}">
|
||||
{{model.user.userDisplayState.name}}
|
||||
</umb-badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastLogin">Last login</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<span ng-if="model.user.lastLoginDate">{{ model.user.formattedLastLogin }}</span>
|
||||
<span ng-if="!model.user.lastLoginDate">{{ model.user.name | umbWordLimit:1 }} <localize key="user_noLogin">has not logged in yet</localize></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_failedPasswordAttempts">Failed login attempts</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
{{ model.user.failedPasswordAttempts }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastLockoutDate">Last lockout date</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<span ng-if="model.user.lastLockoutDate === '0001-01-01T00:00:00'">
|
||||
{{ model.user.name | umbWordLimit:1 }} <localize key="user_noLockouts">hasn't been locked out</localize>
|
||||
</span>
|
||||
<span ng-if="model.user.lastLockoutDate !== '0001-01-01T00:00:00'">{{ model.user.formattedLastLockoutDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastPasswordChangeDate">Password is last changed</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
<span ng-if="model.user.lastPasswordChangeDate === '0001-01-01T00:00:00'">
|
||||
<localize key="user_noPasswordChange">The password hasn't been changed</localize>
|
||||
</span>
|
||||
<span ng-if="model.user.lastPasswordChangeDate !== '0001-01-01T00:00:00'">{{ model.user.formattedLastPasswordChangeDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_createDate">User is created</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
{{ model.user.formattedCreateDate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_updateDate">User is last updated</localize>:
|
||||
</div>
|
||||
<div class="umb-package-details__information-item-content">
|
||||
{{ model.user.formattedUpdateDate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user