Update Umbraco to 7.12.2

This commit is contained in:
2018-09-16 15:08:47 -04:00
parent 7ed7776432
commit 616ab81bad
764 changed files with 142787 additions and 66790 deletions
+253
View File
@@ -0,0 +1,253 @@
<div ng-controller="Umbraco.Editors.Users.GroupController as vm" class="clearfix">
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
<form name="editUserForm" novalidate val-form-manager>
<umb-editor-view ng-if="!vm.loading">
<umb-editor-header
name="vm.userGroup.name"
alias="vm.userGroup.alias"
icon="vm.userGroup.icon"
hide-description="true">
</umb-editor-header>
<umb-editor-container>
<div class="umb-packages-view-wrapper" style="padding: 0;">
<div class="umb-package-details">
<div class="umb-package-details__main-content">
<umb-box>
<umb-box-header title-key="user_assignAccess"></umb-box-header>
<umb-box-content class="block-form">
<umb-control-group style="margin-bottom: 20px;" label="@main_sections" description="@user_sectionsHelp">
<umb-node-preview
style="max-width: 100%;"
ng-repeat="section in vm.userGroup.sections"
icon="section.icon"
name="section.name"
allow-remove="true"
on-remove="vm.removeSelectedItem($index, vm.userGroup.sections)">
</umb-node-preview>
<a href=""
style="max-width: 100%;"
class="umb-node-preview-add"
ng-click="vm.openSectionPicker()"
prevent-default>
<localize key="general_add">Add</localize>
</a>
</umb-control-group>
<umb-control-group style="margin-bottom: 20px;" label="@user_startnode" description="@user_startnodehelp">
<umb-node-preview
ng-if="vm.userGroup.contentStartNode.id"
style="max-width: 100%;"
icon="vm.userGroup.contentStartNode.icon"
name="vm.userGroup.contentStartNode.name"
allow-edit="true"
allow-remove="true"
on-edit="vm.openContentPicker()"
on-remove="vm.clearStartNode('content')">
</umb-node-preview>
<a href=""
ng-if="!vm.userGroup.contentStartNode"
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_mediastartnode" description="@user_mediastartnodehelp">
<umb-node-preview
ng-if="vm.userGroup.mediaStartNode.id"
style="max-width: 100%;"
icon="vm.userGroup.mediaStartNode.icon"
name="vm.userGroup.mediaStartNode.name"
allow-edit="true"
allow-remove="true"
on-edit="vm.openMediaPicker()"
on-remove="vm.clearStartNode('media')">
</umb-node-preview>
<a href=""
ng-if="!vm.userGroup.mediaStartNode"
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_permissionsDefault"></umb-box-header>
<umb-box-content class="block-form">
<umb-control-group
ng-repeat="(category, permissions) in vm.userGroup.defaultPermissions"
label="{{ category }}">
<umb-permission
ng-repeat="permission in permissions"
name="permission.name"
description="permission.description"
selected="permission.checked">
</umb-permission>
</umb-control-group>
</umb-box-content>
</umb-box>
<umb-box>
<umb-box-header title-key="user_permissionsGranular"></umb-box-header>
<umb-box-content class="block-form">
<umb-control-group label="Nodes" description="@user_permissionsGranularHelp">
<umb-node-preview
ng-repeat="node in vm.userGroup.assignedPermissions"
style="max-width: 100%;"
icon="node.icon"
name="node.name"
permissions="node.allowedPermissions"
allow-remove="true"
on-remove="vm.removeSelectedItem($index, vm.userGroup.assignedPermissions)"
allow-edit="true"
on-edit="vm.setPermissionsForNode(node)">
</umb-node-preview>
<a href=""
style="max-width: 100%;"
class="umb-node-preview-add"
ng-click="vm.openGranularPermissionsPicker()"
prevent-default>
<localize key="general_add">Add</localize>
</a>
</umb-control-group>
</umb-box-content>
</umb-box>
</div>
<div class="umb-package-details__sidebar">
<div class="umb-package-details__section">
<div class="umb-package-details__section-title"><localize key="sections_users">Users</localize></div>
<umb-user-preview
ng-repeat="user in vm.userGroup.users"
name="user.name"
avatars="user.avatars"
allow-remove="true"
on-remove="vm.removeSelectedItem($index, vm.userGroup.users)">
</umb-user-preview>
<a href=""
style="max-width: 100%;"
class="umb-node-preview-add"
ng-click="vm.openUserPicker()"
prevent-default>
<localize key="general_add">Add</localize>
</a>
</div>
</div>
</div>
</div>
</umb-editor-container>
<umb-editor-footer>
<umb-editor-footer-content-left>
<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">
</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">
</umb-button>
</umb-editor-footer-content-right>
</umb-editor-footer>
</umb-editor-view>
</form>
<umb-overlay
ng-if="vm.sectionPicker.show"
model="vm.sectionPicker"
view="vm.sectionPicker.view"
position="right">
</umb-overlay>
<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>
<umb-overlay
ng-if="vm.userPicker.show"
model="vm.userPicker"
view="vm.userPicker.view"
position="right">
</umb-overlay>
<umb-overlay
ng-if="vm.nodePermissions.show"
model="vm.nodePermissions"
view="vm.nodePermissions.view"
position="right">
</umb-overlay>
</div>
+24
View File
@@ -0,0 +1,24 @@
<div data-element="editor-users" ng-controller="Umbraco.Editors.Users.OverviewController as vm" class="clearfix">
<umb-editor-view footer="false">
<umb-editor-header
name="vm.page.name"
name-locked="true"
hide-icon="true"
hide-description="true"
navigation="vm.page.navigation"
hide-alias="true">
</umb-editor-header>
<umb-editor-container>
<umb-editor-sub-views
sub-views="vm.page.navigation">
</umb-editor-sub-views>
</umb-editor-container>
</umb-editor-view>
</div>
+86
View File
@@ -0,0 +1,86 @@
<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"
navigation="vm.user.navigation">
</umb-editor-header>
<umb-editor-container>
<div ng-if="!vm.loading" class="umb-packages-view-wrapper" style="padding: 0;">
<umb-editor-sub-views
ng-if="!vm.loading"
sub-views="vm.user.navigation"
model="vm">
</umb-editor-sub-views>
</div>
</umb-editor-container>
<umb-editor-footer>
<umb-editor-footer-content-left>
<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>
<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>
</umb-editor-footer>
</umb-editor-view>
</form>
<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>
<umb-overlay ng-if="vm.mediaPicker.show"
model="vm.mediaPicker"
view="vm.mediaPicker.view"
position="right">
</umb-overlay>
</div>
@@ -0,0 +1,106 @@
<div ng-controller="Umbraco.Editors.Users.GroupsController as vm" class="clearfix">
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
<umb-editor-sub-header>
<!-- No selection -->
<umb-editor-sub-header-content-left ng-if="vm.selection.length === 0">
<umb-button
type="button"
button-style="success"
action="vm.createUserGroup()"
label="Create Group"
label-key="actions_createGroup">
</umb-button>
</umb-editor-sub-header-content-left>
<umb-editor-sub-header-content-right ng-if="vm.selection.length === 0">
<umb-editor-sub-header-section>
<div class="form-search -no-margin-bottom pull-right">
<div class="inner-addon left-addon">
<i class="icon icon-search"></i>
<input class="form-control search-input"
type="text"
localize="placeholder"
placeholder="@placeholders_filter"
ng-model="vm.filter"
prevent-enter-submit
no-dirty-check>
</div>
</div>
</umb-editor-sub-header-section>
</umb-editor-sub-header-content-right>
<!-- With selection -->
<umb-editor-sub-header-content-left ng-if="vm.selection.length > 0">
<umb-editor-sub-header-section>
<umb-button
type="button"
label-key="buttons_clearSelection"
action="vm.clearSelection()"
size="xs">
</umb-button>
</umb-editor-sub-header-section>
<umb-editor-sub-header-section>
<strong>{{ vm.selection.length }} <localize key="general_of">of</localize> {{ vm.userGroups.length }} <localize key="general_selected">selected</localize></strong>
</umb-editor-sub-header-section>
</umb-editor-sub-header-content-left>
<umb-editor-sub-header-content-right ng-if="vm.selection.length > 0">
<umb-button
type="button"
label="Delete"
label-key="general_delete"
icon="icon-trash"
action="vm.deleteUserGroups()"
size="xs">
</umb-button>
</umb-editor-sub-header-content-right>
</umb-editor-sub-header>
<div style="margin-bottom: 20px;" class="flex items-center">
<div style="font-size: 16px;">
<span class="bold"><localize key="general_groups">Groups</localize> </span> <span>({{vm.userGroups.length}})</span>
</div>
</div>
<div class="umb-list" ng-if="!vm.loading" ng-switch="">
<div ng-repeat="group in vm.userGroups | filter:vm.filter" ng-switch="group.hasAccess">
<div class="umb-list-item umb-list-item--disabled" ng-switch-when="false">
<div style="margin-right: 25px;">
<div class="umb-list-checkbox"></div>
</div>
<umb-user-group-preview style="border-bottom: none; margin-bottom: 0; padding: 0;"
icon="group.group.icon"
name="group.group.name"
sections="group.group.sections"
content-start-node="group.group.contentStartNode"
media-start-node="group.group.mediaStartNode">
</umb-user-group-preview>
</div>
<a class="umb-list-item" ng-click="vm.clickUserGroup(group)" ng-class="{'umb-list-item--selected': group.selected}" href="" ng-switch-when="true">
<div style="margin-right: 25px;">
<div class="umb-list-checkbox"
ng-hide="group.group.alias === 'admin' || group.group.alias === 'translator'"
ng-class="{'umb-list-checkbox--visible': vm.selection.length > 0}"
ng-click="vm.selectUserGroup(group, vm.selection, $event)" >
<umb-checkmark checked="group.selected"></umb-checkmark>
</div>
</div>
<umb-user-group-preview
style="border-bottom: none; margin-bottom: 0; padding: 0;"
icon="group.group.icon"
name="group.group.name"
sections="group.group.sections"
content-start-node="group.group.contentStartNode"
media-start-node="group.group.mediaStartNode">
</umb-user-group-preview>
</a>
</div>
</div>
</div>
@@ -0,0 +1,391 @@
<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" alias="email">
<input type="email"
localize="placeholder"
placeholder="@placeholders_enteremail"
class="input-block-level"
ng-model="model.user.email"
umb-auto-focus
name="email"
id="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="model.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.userDisplayState.key !== 'Invited' && !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" ng-if="model.user.userDisplayState.key !== 'Invited'"
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>
<umb-button type="button" ng-if="!model.user.lastLoginDate"
button-style="[danger,block]"
action="model.deleteNonLoggedInUser()"
label="Delete"
label-key="user_deleteUser"
state="deleteNotLoggedInUserButtonState"
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 style="margin-bottom: 10px;" ng-if="model.user.userDisplayState.key === 'Invited' && !model.user.isCurrentUser">
<textarea name="resendInviteMessage"
type="text"
class="input-block-level"
localize="placeholder"
placeholder="@placeholders_enterMessage"
ng-model="model.resendInviteMessage"
rows="4">
</textarea>
<umb-button type="button"
button-style="[info,block]"
action="model.resendInvite()"
state="model.resendInviteButtonState"
label="Resend Invite"
label-key="actions_resendInvite"
size="s">
</umb-button>
</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>
@@ -0,0 +1,537 @@
<div ng-controller="Umbraco.Editors.Users.UsersController as vm" class="clearfix">
<!-- Users Overview -->
<div ng-if="vm.usersViewState === 'overview'">
<umb-load-indicator ng-show="vm.loading"></umb-load-indicator>
<umb-editor-sub-header>
<!-- No selection -->
<umb-editor-sub-header-content-left ng-if="vm.selection.length === 0">
<umb-button-group
ng-if="vm.defaultButton"
default-button="vm.defaultButton"
sub-buttons="vm.subButtons">
</umb-button-group>
</umb-editor-sub-header-content-left>
<umb-editor-sub-header-content-right ng-if="vm.selection.length === 0">
<umb-editor-sub-header-section>
<umb-layout-selector
ng-if="vm.layouts"
layouts="vm.layouts"
active-layout="vm.activeLayout"
on-layout-select="vm.selectLayout">
</umb-layout-selector>
</umb-editor-sub-header-section>
<umb-editor-sub-header-section>
<div class="form-search -no-margin-bottom pull-right">
<div class="inner-addon left-addon">
<i class="icon icon-search"></i>
<input
class="form-control search-input"
type="text" localize="placeholder"
placeholder="@general_typeToSearch"
ng-model="vm.usersOptions.filter"
ng-change="vm.searchUsers()"
prevent-enter-submit
no-dirty-check>
</div>
</div>
</umb-editor-sub-header-section>
</umb-editor-sub-header-content-right>
<!-- With selection -->
<umb-editor-sub-header-content-left ng-if="vm.selection.length > 0">
<umb-editor-sub-header-section>
<umb-button
type="button"
label="Clear selection"
size="xs"
label-key="buttons_clearSelection"
action="vm.clearSelection()"
disabled="actionInProgress">
</umb-button>
</umb-editor-sub-header-section>
<umb-editor-sub-header-section>
<strong>{{ vm.selection.length }} <localize key="general_of">of</localize> {{ vm.users.length }} <localize key="general_selected">selected</localize></strong>
</umb-editor-sub-header-section>
</umb-editor-sub-header-content-left>
<umb-editor-sub-header-content-right ng-if="vm.selection.length > 0">
<div style="margin-right: 5px;">
<umb-button
ng-if="vm.allowSetUserGroup"
type="button" size="xs"
label-key="actions_setGroup"
icon="icon-users"
action="vm.openBulkUserGroupPicker()">
</umb-button>
</div>
<div style="margin-right: 5px;">
<umb-button
ng-if="vm.allowEnableUser"
type="button"
size="xs"
state="vm.enableUserButtonState"
label-key="actions_enable"
icon="icon-check"
action="vm.enableUsers()">
</umb-button>
</div>
<div style="margin-right: 5px;">
<umb-button
ng-if="vm.allowUnlockUser"
type="button"
size="xs"
state="vm.unlockUserButtonState"
label-key="actions_unlock"
icon="icon-unlocked"
action="vm.unlockUsers()">
</umb-button>
</div>
<div>
<umb-button
ng-if="vm.allowDisableUser"
type="button"
size="xs"
state="vm.disableUserButtonState"
label-key="actions_disable"
icon="icon-block"
action="vm.disableUsers()">
</umb-button>
</div>
</umb-editor-sub-header-content-right>
</umb-editor-sub-header>
<!-- Filters -->
<div style="margin-bottom: 20px;" class="flex items-center">
<div style="font-size: 16px;">
<span class="bold"><localize key="sections_users">Users</localize></span> <span ng-if="vm.usersOptions.totalItems">({{vm.usersOptions.totalItems}})</span>
</div>
<div class="flex" style="margin-left: auto;">
<!-- State filter -->
<div style="position: relative;" ng-if="vm.userStatesFilter.length > 0">
<a class="btn btn-link dropdown-toggle flex" href="" ng-click="vm.toggleFilter('state')">
<span><localize key="general_status">Status</localize>:</span>
<span class="bold truncate dib" style="margin-left: 5px; margin-right: 3px; max-width: 150px;">{{ vm.getFilterName(vm.userStatesFilter) }}</span>
<span class="caret"></span>
</a>
<umb-dropdown class="pull-right" ng-if="vm.page.showStatusFilter" on-close="vm.page.showStatusFilter = false;">
<umb-dropdown-item ng-repeat="userState in vm.userStatesFilter | filter:{ count: '!0', key: '!All'}" style="padding: 8px 20px 8px 16px;">
<div class="flex items-center">
<input
id="state-{{$index}}"
type="checkbox"
ng-model="userState.selected"
ng-change="vm.setUserStatesFilter(userState)"
style="margin-right: 10px; margin-top: -3px;" />
<label for="state-{{$index}}">{{ userState.name }} ({{userState.count}})</label>
</div>
</umb-dropdown-item>
</umb-dropdown>
</div>
<!-- Groups filter -->
<div style="position: relative;">
<a class="btn btn-link dropdown-toggle flex" href="" ng-click="vm.toggleFilter('group')">
<span><localize key="general_groups"></localize>:</span>
<span class="bold truncate dib" style="margin-left: 5px; margin-right: 3px; max-width: 150px;">{{ vm.getFilterName(vm.userGroups) }}</span>
<span class="caret"></span>
</a>
<umb-dropdown class="pull-right" ng-if="vm.page.showGroupFilter" on-close="vm.page.showGroupFilter = false;">
<umb-dropdown-item ng-repeat="userGroup in vm.userGroups" style="padding: 8px 20px 8px 16px;">
<div class="flex items-center">
<input
id="group-{{$index}}"
type="checkbox"
ng-model="userGroup.selected"
ng-change="vm.setUserGroupFilter(userGroup)"
style="margin-right: 10px; margin-top: -3px;" />
<label for="group-{{$index}}">{{ userGroup.name }}</label>
</div>
</umb-dropdown-item>
</umb-dropdown>
</div>
<!-- Order By -->
<div style="position: relative;">
<a class="btn btn-link dropdown-toggle flex" href="" ng-click="vm.toggleFilter('orderBy')">
<span><localize key="general_orderBy">Order by</localize>:</span>
<span class="bold" style="margin-left: 2px;">{{ vm.getSortLabel(vm.usersOptions.orderBy, vm.usersOptions.orderDirection) }} </span>
<span class="caret"></span>
</a>
<umb-dropdown class="pull-right" ng-if="vm.page.showOrderByFilter" on-close="vm.page.showOrderByFilter = false;" umb-keyboard-list>
<umb-dropdown-item ng-repeat="sortData in vm.userSortData">
<a href="#" ng-click="vm.setOrderByFilter(sortData.key, sortData.direction)" prevent-default>{{sortData.label}}</a>
</umb-dropdown-item>
</umb-dropdown>
</div>
</div>
</div>
<!-- Empty states -->
<umb-empty-state
ng-if="!vm.users && vm.usersOptions.filter.length > 0"
position="center">
<localize key="general_searchNoResult"></localize>
</umb-empty-state>
<!-- Layout: Cards -->
<div class="umb-user-cards" ng-if="vm.activeLayout.path === '1' && vm.loading === false">
<a href="" class="umb-user-card" ng-repeat="user in vm.users" ng-click="vm.clickUser(user)">
<div class="umb-user-card__content" ng-class="{'umb-user-card__content--selected': user.selected}">
<umb-badge class="umb-user-card__badge" size="xs" ng-if="user.userDisplayState.key !== 'Active'" color="{{user.userDisplayState.color}}">
{{ user.userDisplayState.name }}
</umb-badge>
<div class="umb-user-card__avatar">
<umb-avatar size="l" color="secondary" name="{{user.name}}" img-src="{{user.avatars[2]}}" img-srcset="{{user.avatars[3]}} 2x, {{user.avatars[4]}} 3x">
</umb-avatar>
</div>
<div class="umb-user-card__checkmark" ng-class="{'umb-user-card__checkmark--visible': user.selected || vm.selection.length > 0 }"
ng-click="vm.selectUser(user, vm.selection, $event)">
<umb-checkmark ng-if="!user.isCurrentUser" checked="user.selected" size="s"></umb-checkmark>
</div>
<div class="umb-user-card__name" href="">{{user.name}}</div>
<div class="umb-user-card__group">
<span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span>
</div>
<div class="umb-user-card__last-login">
<div ng-if="user.formattedLastLogin">
<div>
<localize key="user_lastLogin">Last login</localize>
</div>
{{ user.formattedLastLogin }}
</div>
<div ng-if="!user.formattedLastLogin">
<div>{{ user.name | umbWordLimit:1 }}
<localize key="user_noLogin">has not logged in yet</localize>
</div>
</div>
</div>
</div>
</a>
</div>
<!-- Layout: Table -->
<div ng-if="vm.activeLayout.path === '2'">
<table class="table table-hover">
<thead>
<tr>
<th style="padding-left: 10px; width: 10px;">
<a href="" style="text-decoration: none;" ng-click="vm.selectAll()">
<umb-checkmark checked="vm.areAllSelected()" size="xs"></umb-checkmark>
</a>
</th>
<th style="width: 70px;"></th>
<th><localize key="general_name">Name</localize></th>
<th><localize key="user_usergroup">User group</localize></th>
<th><localize key="user_lastLogin">Last login</localize></th>
<th><localize key="general_status">Status</localize></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in vm.users" ng-click="vm.clickUser(user)" style="cursor: pointer;" ng-mouseenter="user.hover = true" ng-mouseleave="user.hover = false">
<td style="padding-left: 10px;">
<div ng-if="!user.isCurrentUser" ng-click="vm.selectUser(user, vm.selection, $event)">
<umb-checkmark
ng-if="vm.selection.length > 0 || user.hover"
checked="user.selected"
size="xs">
</umb-checkmark>
</div>
</td>
<td scope="row">
<umb-avatar
size="xs"
color="secondary"
name="{{user.name}}"
img-src="{{user.avatars[0]}}"
img-srcset="{{user.avatars[1]}} 2x, {{user.avatars[2]}} 3x">
</umb-avatar>
</td>
<td class="bold">{{user.name}}</td>
<td><span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span></td>
<td>{{ user.formattedLastLogin }}</td>
<td style="text-transform: capitalize;">
<umb-badge
size="xs"
ng-if="user.userDisplayState.key !== 'Active'"
color="{{user.userDisplayState.color}}">
{{ user.userDisplayState.name }}
</umb-badge>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Pagination -->
<div ng-if="!vm.loading" class="flex justify-center">
<umb-pagination
ng-if="vm.usersOptions.totalPages"
page-number="vm.usersOptions.pageNumber"
total-pages="vm.usersOptions.totalPages"
on-change="vm.changePageNumber(pageNumber)">
</umb-pagination>
</div>
</div>
<!-- Add user -->
<div ng-if="vm.usersViewState === 'inviteUser' || vm.usersViewState === 'createUser'">
<umb-editor-sub-header>
<umb-editor-sub-header-content-left>
<a class="umb-package-details__back-link" href="" ng-click="vm.setUsersViewState('overview');">&larr; <localize key="user_backToUsers">Back to users</localize></a>
</umb-editor-sub-header-content-left>
</umb-editor-sub-header>
<div class="flex justify-center">
<form name="addUserForm" no-validate val-form-manager style="max-width: 500px;" class="block-form">
<div>
<div ng-if="vm.usersViewState === 'inviteUser'">
<h3 class="bold" style="margin-bottom: 0;">
<localize key="user_inviteUser">Invite User</localize>
</h3>
<p style="line-height: 1.6em; margin-bottom: 15px;">
<localize key="user_inviteUserHelp"></localize>
</p>
</div>
<div ng-if="vm.usersViewState === 'createUser'">
<h3 class="bold" style="margin-bottom: 0;">
<localize key="user_createUser">Create user</localize>
</h3>
<p style="line-height: 1.6em; margin-bottom: 15px;">
<localize key="user_createUserHelp"></localize>
</p>
</div>
</div>
<umb-control-group label="@general_name" label-for="name" required="true">
<input type="text" name="name" localize="placeholder" placeholder="@placeholders_entername" class="input-block-level" ng-model="vm.newUser.name"
umb-auto-focus required val-server-field="Name" />
<span class="help-inline" val-msg-for="name" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
<span class="help-inline" val-msg-for="name" val-toggle-msg="valServerField"></span>
</umb-control-group>
<umb-control-group label="@general_username" label-for="username" required="true" ng-if="!vm.usernameIsEmail">
<input type="text" name="username" localize="placeholder" placeholder="@placeholders_enterusername" class="input-block-level"
ng-model="vm.newUser.username" val-server-field="Username" ng-required="vm.usernameIsEmail" />
<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="@general_email" label-for="email" required="true">
<input type="email" name="email" localize="placeholder" placeholder="@placeholders_enteremail" class="input-block-level"
ng-model="vm.newUser.email" required val-email 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="@user_usergroup" description="@user_groupsHelp" required="true">
<umb-user-group-preview
ng-repeat="group in vm.newUser.userGroups"
icon="group.icon"
name="group.name"
sections="group.sections"
content-start-node="group.contentStartNode"
media-start-node="group.mediaStartNode"
allow-remove="true"
on-remove="vm.removeSelectedUserGroup($index, vm.newUser.userGroups)">
</umb-user-group-preview>
<a href="" style="max-width: 100%;" class="umb-node-preview-add" ng-click="vm.openUserGroupPicker($event)" prevent-default>
<localize key="general_add">Add</localize>
</a>
</umb-control-group>
<umb-control-group label="@general_message" ng-if="vm.usersViewState === 'inviteUser'" label-for="message" required="true">
<textarea
name="message"
type="text"
class="input-block-level"
localize="placeholder"
placeholder="@placeholders_enterMessage"
ng-model="vm.newUser.message"
rows="4"
required val-server-field="Message">
</textarea>
<span class="help-inline" val-msg-for="message" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
<span class="help-inline" val-msg-for="message" val-toggle-msg="valServerField"></span>
</umb-control-group>
<umb-button
ng-if="vm.usersViewState === 'inviteUser'"
button-style="success"
state="vm.page.createButtonState"
type="button"
action="vm.inviteUser(addUserForm)"
label-key="user_sendInvite"
size="m">
</umb-button>
<umb-button
ng-if="vm.usersViewState === 'createUser'"
button-style="success"
state="vm.page.createButtonState"
type="button"
action="vm.createUser(addUserForm)"
label-key="user_createUser"
size="m">
</umb-button>
</form>
</div>
</div>
<!-- Create user success -->
<div ng-if="vm.usersViewState === 'createUserSuccess'">
<umb-editor-sub-header>
<umb-editor-sub-header-content-left>
<a class="umb-package-details__back-link" href="" ng-click="vm.setUsersViewState('overview');">&larr; <localize key="user_backToUsers">Back to users</localize></a>
</umb-editor-sub-header-content-left>
</umb-editor-sub-header>
<div class="flex justify-center">
<div style="max-width: 500px;">
<!-- Success text -->
<div class="flex items-center" style="margin-bottom: 15px;">
<umb-checkmark
checked="vm.usersViewState === 'createUserSuccess'"
size="m">
</umb-checkmark>
<h3 class="bold" style="margin: 0 0 0 10px;">
{{vm.newUser.name | umbWordLimit:1}}
<localize key="user_userCreated">has been created</localize>
</h3>
</div>
<p style="line-height: 1.6em; margin-bottom: 20px;"><localize key="user_userCreatedSuccessHelp"></localize></p>
<!-- New password -->
<div>
<label class="bold"><localize key="user_password">Password</localize></label>
<div class="flex items-center justify-between" style="background-color: #f3f3f5; padding: 10px 20px; border-radius: 3px; margin-bottom: 30px;">
<div ng-show="vm.newUser.showPassword">{{vm.newUser.resetPasswordValue}}</div>
<div ng-show="!vm.newUser.showPassword">&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;</div>
<div>
<umb-button
ng-if="!vm.newUser.showPassword"
type="button"
action="vm.toggleNewUserPassword()"
label-key="general_show"
size="xs">
</umb-button>
<umb-button
ng-if="vm.newUser.showPassword"
type="button"
action="vm.toggleNewUserPassword()"
label-key="general_hide"
size="xs">
</umb-button>
<umb-button
ng-if="vm.newUser.resetPasswordValue"
umb-clipboard
umb-clipboard-success="vm.copySuccess()"
umb-clipboard-error="vm.copyError()"
umb-clipboard-text="vm.newUser.resetPasswordValue"
state="vm.page.copyPasswordButtonState"
type="button"
label-key="general_copy" size="xs">
</umb-button>
</div>
</div>
</div>
<!-- actions -->
<div>
<umb-button
type="button" button-style="info"
label-key="user_createAnotherUser"
action="vm.setUsersViewState('createUser');"
size="m">
</umb-button>
<umb-button
type="button"
button-style="success"
label-key="user_goToProfile"
action="vm.goToUser(vm.newUser.id);"
size="m">
</umb-button>
</div>
</div>
</div>
</div>
<!-- Invite user success -->
<div ng-if="vm.usersViewState === 'inviteUserSuccess'">
<umb-editor-sub-header>
<umb-editor-sub-header-content-left>
<a class="umb-package-details__back-link" href="" ng-click="vm.setUsersViewState('overview');">&larr; <localize key="user_backToUsers">Back to users</localize></a>
</umb-editor-sub-header-content-left>
</umb-editor-sub-header>
<div class="flex justify-center">
<div style="max-width: 500px;">
<!-- Success text -->
<div class="flex items-center" style="margin-bottom: 15px;">
<umb-checkmark
checked="vm.usersViewState === 'inviteUserSuccess'"
size="m">
</umb-checkmark>
<h3 class="bold" style="margin: 0 0 0 10px;">
{{vm.newUser.name | umbWordLimit:1}}
<localize key="user_userInvited">has been created</localize>
</h3>
</div>
<p style="line-height: 1.6em; margin-bottom: 20px;"><localize key="user_userInvitedSuccessHelp"></localize></p>
<!-- actions -->
<div>
<umb-button
type="button" button-style="info"
label-key="user_inviteAnotherUser"
action="vm.setUsersViewState('inviteUser');"
size="m">
</umb-button>
<umb-button
type="button"
button-style="success"
label-key="user_goToProfile"
action="vm.goToUser(vm.newUser.id);"
size="m">
</umb-button>
</div>
</div>
</div>
</div>
<umb-overlay
ng-if="vm.userGroupPicker.show"
model="vm.userGroupPicker"
view="vm.userGroupPicker.view"
position="right">
</umb-overlay>
</div>