2018-01-22 13:01:38 -08:00
<!-- Modal add user -->
< div class = "modal fade" id = "userAddModal" tabindex = "-1" role = "dialog" >
2020-11-13 16:44:39 +01:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > {{ 'users.addUserDialog.title' | tr }}< / h4 >
< / div >
< div class = "modal-body" >
2024-01-19 23:35:02 +01:00
< form name = "useraddForm" role = "form" ng-submit = "userAdd.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (useraddForm.displayName.$dirty && useraddForm.displayName.$invalid) || (!useraddForm.displayName.$dirty && userAdd.error.displayName) }" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.user.fullName' | tr }}< / label >
2024-01-19 23:35:02 +01:00
< input type = "text" class = "form-control" ng-model = "userAdd.displayName" name = "displayName" id = "inputUserAddDisplayName" autofocus autocomplete = "off" placeholder = "{{ 'users.user.displayNamePlaceholder' | tr }}" >
< div class = "control-label" ng-show = "(!useraddForm.displayName.$dirty && userAdd.error.displayName) || (useraddForm.displayName.$dirty && useraddForm.displayName.$invalid) || (!useraddForm.displayName.$dirty && userAdd.error.displayName)" >
2022-03-30 09:18:20 -07:00
< small ng-show = "useraddForm.displayName.$error.displayName" > {{ 'users.user.errorNotValidFullName' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useraddForm.displayName.$dirty && userAdd.error.displayName" > {{ userAdd.error.displayName }}< / small >
2020-11-13 16:44:39 +01:00
< / div >
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-class = "{ 'has-error': (useraddForm.email.$dirty && useraddForm.email.$invalid) || (!useraddForm.email.$dirty && userAdd.error.email) }" >
2022-05-26 14:42:52 -07:00
< label class = "control-label" > {{ 'users.user.primaryEmail' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/profile/#primary-email" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / label >
2024-01-19 23:35:02 +01:00
< input type = "email" class = "form-control" ng-model = "userAdd.email" name = "email" id = "inputUserAddEmail" required >
< div class = "control-label" ng-show = "(!useraddForm.email.$dirty && userAdd.error.email) || (useraddForm.email.$dirty && useraddForm.email.$invalid) || (!useraddForm.email.$dirty && userAdd.error.email)" >
2022-03-30 09:18:20 -07:00
< small ng-show = "useraddForm.email.$error.required" > {{ 'users.user.errorEmailRequired' | tr }}< / small >
< small ng-show = "useraddForm.email.$error.email" > {{ 'users.user.errorInvalidEmail' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useraddForm.email.$dirty && userAdd.error.email" > {{ userAdd.error.email }}< / small >
2018-01-22 13:01:38 -08:00
< / div >
2020-11-13 16:44:39 +01:00
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-class = "{ 'has-error': (useraddForm.fallbackEmail.$dirty && useraddForm.fallbackEmail.$invalid) || (!useraddForm.fallbackEmail.$dirty && userAdd.error.fallbackEmail) }" >
2022-05-26 14:42:52 -07:00
< label class = "control-label" > {{ 'users.user.recoveryEmail' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/profile/#password-recovery-email" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / label >
2024-01-19 23:35:02 +01:00
< input type = "email" class = "form-control" ng-model = "userAdd.fallbackEmail" name = "fallbackEmail" id = "inputUserAddFallbackEmail" placeholder = "{{ 'users.user.fallbackEmailPlaceholder' | tr }}" >
< div class = "control-label" ng-show = "(!useraddForm.fallbackEmail.$dirty && userAdd.error.fallbackEmail) || (useraddForm.fallbackEmail.$dirty && useraddForm.fallbackEmail.$invalid) || (!useraddForm.fallbackEmail.$dirty && userAdd.error.fallbackEmail)" >
2022-03-30 09:18:20 -07:00
< small ng-show = "useraddForm.fallbackEmail.$error.required" > {{ 'users.user.errorEmailRequired' | tr }}< / small >
< small ng-show = "useraddForm.fallbackEmail.$error.fallbackEmail" > {{ 'users.user.errorInvalidEmail' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useraddForm.fallbackEmail.$dirty && userAdd.error.fallbackEmail" > {{ userAdd.error.fallbackEmail }}< / small >
2021-10-26 23:39:15 +02:00
< / div >
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-class = "{ 'has-error': (useraddForm.username.$dirty && useraddForm.username.$invalid) || (!useraddForm.username.$dirty && userAdd.error.username) }" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.user.username' | tr }}< / label >
2024-01-19 23:35:02 +01:00
< input type = "text" class = "form-control" ng-model = "userAdd.username" name = "username" id = "inputUserAddUsername" ng-required = "config.profileLocked" placeholder = "{{ config.profileLocked ? '' : ('users.user.usernamePlaceholder' | tr) }}" >
< div class = "control-label" ng-show = "(!useraddForm.username.$dirty && userAdd.error.username) || (useraddForm.username.$dirty && useraddForm.username.$invalid) || (!useraddForm.username.$dirty && userAdd.error.username)" >
2022-07-27 18:02:39 +02:00
< small ng-show = "useraddForm.username.$error.username" > {{ 'users.user.errorInvalidUsername' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useraddForm.username.$dirty && userAdd.error.username" > {{ userAdd.error.username }}< / small >
2018-01-22 13:01:38 -08:00
< / div >
2020-11-13 16:44:39 +01:00
< / div >
< div class = "form-group" ng-show = "userInfo.isAtLeastAdmin" >
< label class = "control-label" > {{ 'users.user.role' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/user-management/#roles" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / sup > < / label >
< div class = "control-label" >
2024-01-19 23:35:02 +01:00
< select class = "form-control" ng-model = "userAdd.role" ng-options = "role.id as role.name disable when role.disabled for role in roles" > < / select >
2018-01-22 13:01:38 -08:00
< / div >
2020-11-13 16:44:39 +01:00
< / div >
< div class = "form-group" >
< label class = "control-label" > {{ 'users.user.groups' | tr }}< / label >
< div class = "control-label" >
< div ng-show = "groups.length === 0" > {{ 'users.user.noGroups' | tr }}< / div >
2024-03-01 18:37:34 +01:00
<!-- local groups. they can have local and external users . angular cannot filter empty strings - https://github.com/angular/angular.js/issues/7890 -->
< multiselect ng-show = "groups.length !== 0" ng-model = "userAdd.selectedLocalGroups" options = "group.name for group in groups | filter:{ source: '!ldap' }" data-compare-by = "name" data-multiple = "true" filter-after-rows = "5" scroll-after-rows = "10" > < / multiselect >
2020-11-13 16:44:39 +01:00
< / div >
< / div >
2021-09-16 20:17:37 +02:00
< div class = "checkbox" >
< label >
2024-01-19 23:35:02 +01:00
< input type = "checkbox" ng-model = "userAdd.sendInvite" id = "inputUserAddSendInvite" > {{ 'users.addUserDialog.sendInviteCheckbox' | tr }}
2021-09-16 20:17:37 +02:00
< / label >
< / div >
2024-01-19 23:35:02 +01:00
< input class = "ng-hide" type = "submit" ng-disabled = "useraddForm.$invalid || userAdd.busy" / >
2020-11-13 16:44:39 +01:00
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
2024-01-19 23:35:02 +01:00
< button type = "button" class = "btn btn-success" ng-click = "userAdd.submit()" ng-disabled = "useraddForm.$invalid || userAdd.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "userAdd.busy" > < / i > {{ 'users.addUserDialog.addUserAction' | tr }}< / button >
2020-11-13 16:44:39 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2020-11-13 16:44:39 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
<!-- Modal remove user -->
< div class = "modal fade" id = "userRemoveModal" tabindex = "-1" role = "dialog" >
2019-05-13 23:55:54 +02:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2024-01-19 23:35:02 +01:00
< h4 class = "modal-title" > {{ 'users.deleteUserDialog.title' | tr:{ username: (userRemove.userInfo.username || userRemove.userInfo.email) } }}< / h4 >
2019-05-13 23:55:54 +02:00
< / div >
< div class = "modal-body" >
2024-01-19 23:35:02 +01:00
< p class = "text-bold text-danger" ng-show = "userRemove.error" > {{ userRemove.error }}< / p >
< p ng-hide = "userRemove.error" > {{ 'users.deleteUserDialog.description' | tr }}< / p >
2019-05-13 23:55:54 +02:00
< / div >
< div class = "modal-footer" >
2020-11-13 16:44:39 +01:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
2024-01-19 23:35:02 +01:00
< button type = "button" class = "btn btn-danger" ng-click = "userRemove.submit()" ng-hide = "userRemove.error" ng-disabled = "userRemove.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "userRemove.busy" > < / i > {{ 'users.deleteUserDialog.deleteAction' | tr }}< / button >
2019-05-13 23:55:54 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2019-05-13 23:55:54 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
<!-- Modal edit user -->
< div class = "modal fade" id = "userEditModal" tabindex = "-1" role = "dialog" >
2019-08-30 13:32:20 +02:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2024-01-19 23:35:02 +01:00
< h4 class = "modal-title" > {{ 'users.editUserDialog.title' | tr:{ username: (userEdit.userInfo.username || userEdit.userInfo.email) } }}< / h4 >
2019-08-30 13:32:20 +02:00
< / div >
< div class = "modal-body" >
2024-01-19 23:35:02 +01:00
< div ng-show = "userEdit.source" >
2020-11-13 16:44:39 +01:00
< p class = "text-warning" > {{ 'users.editUserDialog.externalLdapWarning' | tr }}< / p >
2024-01-19 23:35:02 +01:00
< p > < label > {{ 'users.user.displayName' | tr }}< / label > < br / > < input type = "text" class = "form-control" ng-disabled = "true" ng-model = "userEdit.displayName" >
< p > < label > {{ 'users.user.email' | tr }}< / label > < br / > < input type = "text" class = "form-control" ng-disabled = "true" ng-model = "userEdit.email" > < / p >
2019-08-30 13:32:20 +02:00
< / div >
2024-01-19 23:35:02 +01:00
< form name = "useredit_form" role = "form" ng-submit = "userEdit.submit()" autocomplete = "off" >
< p class = "has-error text-center" ng-show = "userEdit.error.generic" > {{ userEdit.error.generic }}< / p >
2020-10-23 11:47:37 -07:00
2022-01-12 16:20:50 -08:00
<!-- when user profiles are locked, this provides a way for the admin to set the username -->
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-hide = "userEdit.source || userEdit.userInfo.username" ng-class = "{ 'has-error': (useredit_form.username.$dirty && useredit_form.username.$invalid) || (!useredit_form.username.$dirty && userEdit.error.username) }" >
2022-01-12 16:20:50 -08:00
< label class = "control-label" > {{ 'users.user.username' | tr }}< / label >
2024-01-19 23:35:02 +01:00
< div class = "control-label" ng-show = "(!useredit_form.username.$dirty && userEdit.error.username) || (useredit_form.username.$dirty && useredit_form.username.$invalid) || (!useredit_form.username.$dirty && userEdit.error.username)" >
< small ng-show = "!useredit_form.username.$dirty && userEdit.error.username" > {{ userEdit.error.username }}< / small >
2022-01-12 16:20:50 -08:00
< / div >
2024-01-19 23:35:02 +01:00
< input type = "text" class = "form-control" ng-model = "userEdit.username" name = "username" autocomplete = "off" >
2022-01-12 16:20:50 -08:00
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-hide = "userEdit.source" ng-class = "{ 'has-error': (useredit_form.displayName.$dirty && useredit_form.displayName.$invalid) || (!useredit_form.displayName.$dirty && userEdit.error.displayName) }" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.user.displayName' | tr }}< / label >
2024-01-19 23:35:02 +01:00
< div class = "control-label" ng-show = "(!useredit_form.displayName.$dirty && userEdit.error.displayName) || (useredit_form.displayName.$dirty && useredit_form.displayName.$invalid) || (!useredit_form.displayName.$dirty && userEdit.error.displayName)" >
2020-11-13 16:44:39 +01:00
< small ng-show = "useredit_form.displayName.$error.required" > {{ 'users.user.errorDisplayNameRequired' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useredit_form.displayName.$dirty && userEdit.error.displayName" > {{ userEdit.error.displayName }}< / small >
2018-01-22 13:01:38 -08:00
< / div >
2024-01-19 23:35:02 +01:00
< input type = "text" class = "form-control" ng-model = "userEdit.displayName" name = "displayName" required autofocus autocomplete = "off" >
2019-08-30 13:32:20 +02:00
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-hide = "userEdit.source" ng-class = "{ 'has-error': (useredit_form.email.$dirty && useredit_form.email.$invalid) || (!useredit_form.email.$dirty && userEdit.error.email) }" >
2022-05-26 14:42:52 -07:00
< label class = "control-label" > {{ 'users.user.primaryEmail' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/profile/#primary-email" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / label >
2024-01-19 23:35:02 +01:00
< div class = "control-label" ng-show = "(!useredit_form.email.$dirty && userEdit.error.email) || (useredit_form.email.$dirty && useredit_form.email.$invalid) || (!useredit_form.email.$dirty && userEdit.error.email)" >
2020-11-13 16:44:39 +01:00
< small ng-show = "useredit_form.email.$error.required" > {{ 'users.user.errorEmailRequired' | tr }}< / small >
< small ng-show = "useredit_form.email.$error.email" > {{ 'users.user.errorInvalidEmail' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useredit_form.email.$dirty && userEdit.error.email" > {{ userEdit.error.email }}< / small >
2018-01-22 13:01:38 -08:00
< / div >
2024-01-19 23:35:02 +01:00
< input type = "email" class = "form-control" ng-model = "userEdit.email" name = "email" required >
2019-08-30 13:32:20 +02:00
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-hide = "userEdit.source" ng-class = "{ 'has-error': (useredit_form.fallbackEmail.$dirty && useredit_form.fallbackEmail.$invalid) || (!useredit_form.fallbackEmail.$dirty && userEdit.error.fallbackEmail) }" >
2022-05-26 14:42:52 -07:00
< label class = "control-label" > {{ 'users.user.recoveryEmail' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/profile/#password-recovery-email" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / label >
2024-01-19 23:35:02 +01:00
< div class = "control-label" ng-show = "(!useredit_form.fallbackEmail.$dirty && userEdit.error.fallbackEmail) || (useredit_form.fallbackEmail.$dirty && useredit_form.fallbackEmail.$invalid) || (!useredit_form.fallbackEmail.$dirty && userEdit.error.fallbackEmail)" >
2020-11-13 16:44:39 +01:00
< small ng-show = "useredit_form.fallbackEmail.$error.fallbackEmail" > {{ 'users.user.errorInvalidEmail' | tr }}< / small >
2024-01-19 23:35:02 +01:00
< small ng-show = "!useredit_form.fallbackEmail.$dirty && userEdit.error.fallbackEmail" > {{ userEdit.error.fallbackEmail }}< / small >
2018-01-22 13:01:38 -08:00
< / div >
2024-01-19 23:35:02 +01:00
< input type = "fallbackEmail" class = "form-control" ng-model = "userEdit.fallbackEmail" name = "fallbackEmail" >
2019-08-30 13:32:20 +02:00
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-show = "!isMe(userEdit.userInfo) && userInfo.isAtLeastAdmin" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.user.role' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/user-management/#roles" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / sup > < / label >
2020-02-21 21:12:25 +01:00
< div class = "control-label" >
2024-01-19 23:35:02 +01:00
< select class = "form-control" ng-model = "userEdit.role" ng-options = "role.id as role.name disable when role.disabled for role in roles" > < / select >
2020-02-17 14:05:26 +01:00
< / div >
2019-08-30 13:32:20 +02:00
< / div >
2020-02-22 17:51:30 +01:00
< div class = "form-group" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.user.groups' | tr }}< / label >
2020-02-22 17:51:30 +01:00
< div class = "control-label" >
2024-01-20 00:11:10 +01:00
< div ng-switch on = "groups.length" >
< div ng-switch-when = "0" > {{ 'users.user.noGroups' | tr }}< / div >
< div ng-switch-default >
2024-03-01 18:37:34 +01:00
<!-- local groups. they can have local and external users . angular cannot filter empty strings - https://github.com/angular/angular.js/issues/7890 -->
< multiselect ng-show = "hasLocalGroups" ng-model = "userEdit.selectedLocalGroups" options = "group.name for group in groups | filter:{ source: '!ldap' }" data-compare-by = "id" data-multiple = "true" filter-after-rows = "5" scroll-after-rows = "10" > < / multiselect >
2024-01-20 00:11:10 +01:00
< / div >
< / div >
2020-02-22 17:51:30 +01:00
< / div >
< / div >
2024-03-01 18:37:34 +01:00
< div class = "form-group" ng-show = "userEdit.externalGroups.length" >
<!-- remote groups. cannot be edited -->
< label class = "control-label" > {{ 'users.user.ldapGroups' | tr }}< / label >
< div > < span ng-repeat = "group in userEdit.externalGroups" > {{ group.name }}< / span > < / div >
< / div >
2024-01-19 23:35:02 +01:00
< div class = "form-group" ng-hide = "isMe(userEdit.userInfo)" >
2019-08-30 13:32:20 +02:00
< div class = "checkbox" >
< label >
2024-01-19 23:35:02 +01:00
< input type = "checkbox" ng-model = "userEdit.active" > {{ 'users.user.activeCheckbox' | tr }} < sup > < a ng-href = "https://docs.cloudron.io/user-management/#disable-user" class = "help" target = "_blank" > < i class = "fa fa-question-circle" > < / i > < / a > < / sup >
2019-08-30 13:32:20 +02:00
< / label >
< / div >
< / div >
2024-01-19 23:35:02 +01:00
< input class = "hide" type = "submit" ng-disabled = "useredit_form.$invalid || userEdit.busy" / >
2019-08-30 13:32:20 +02:00
< / form >
2021-09-20 17:25:58 +02:00
< hr / >
2024-01-20 11:35:27 +01:00
< div ng-hide = "userEdit.source && config.external2FA" >
2024-01-19 23:35:02 +01:00
< p ng-hide = "userEdit.userInfo.twoFactorAuthenticationEnabled" > {{ 'users.passwordResetDialog.no2FASetup' | tr }}< / p >
< p ng-show = "userEdit.userInfo.twoFactorAuthenticationEnabled" > {{ 'users.passwordResetDialog.2FAIsSetup' | tr }}< / p >
< button type = "button" class = "btn btn-danger" ng-click = "userEdit.reset2FA()" ng-disabled = "!userEdit.userInfo.twoFactorAuthenticationEnabled || userEdit.reset2FABusy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "userEdit.reset2FABusy" > < / i > {{ 'users.passwordResetDialog.reset2FAAction' | tr }}< / button >
2021-09-20 17:25:58 +02:00
< / div >
2024-01-20 11:35:27 +01:00
< div ng-show = "userEdit.source && config.external2FA" > {{ 'users.user.external2FA' | tr }}< / div >
2019-08-30 13:32:20 +02:00
< / div >
< div class = "modal-footer" >
2020-11-13 16:44:39 +01:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
2024-01-19 23:35:02 +01:00
< button type = "button" class = "btn btn-success" ng-click = "userEdit.submit()" ng-disabled = "useredit_form.$invalid || userEdit.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "userEdit.busy" > < / i > {{ 'main.dialog.save' | tr }}< / button >
2019-08-30 13:32:20 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2019-08-30 13:32:20 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
<!-- Modal add group -->
< div class = "modal fade" id = "groupAddModal" tabindex = "-1" role = "dialog" >
2019-11-05 22:08:48 +01:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2020-11-13 16:44:39 +01:00
< h4 class = "modal-title" > {{ 'users.addGroupDialog.title' | tr }}< / h4 >
2019-11-05 22:08:48 +01:00
< / div >
< div class = "modal-body" >
< form name = "groupAddForm" role = "form" novalidate ng-submit = "groupAdd.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (groupAddForm.name.$dirty && groupAddForm.name.$invalid) || (!groupAddForm.name.$dirty && groupAdd.error.name) }" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" for = "groupAddName" > {{ 'users.group.name' | tr }}< / label >
2019-11-05 22:08:48 +01:00
< div class = "control-label" ng-show = "(!groupAddForm.name.$dirty && groupAdd.error.name) || (groupAddForm.name.$dirty && groupAddForm.name.$invalid) || (!groupAddForm.name.$dirty && groupAdd.error.name)" >
2020-11-13 16:44:39 +01:00
< small ng-show = "groupAddForm.name.$error.required" > {{ 'users.group.errorNameRequired' | tr }}< / small >
< small ng-show = "groupAddForm.name.$error.minlength" > {{ 'users.group.errorNameTooShort' | tr }}< / small >
< small ng-show = "groupAddForm.name.$error.maxlength" > {{ 'users.group.errorNameTooLong' | tr }}< / small >
2019-11-05 22:08:48 +01:00
< small ng-show = "!groupAddForm.name.$dirty && groupAdd.error.name" > {{ groupAdd.error.name }}< / small >
2018-01-22 13:01:38 -08:00
< / div >
2019-11-05 22:08:48 +01:00
< input type = "text" class = "form-control" ng-model = "groupAdd.name" id = "groupAddName" name = "name" ng-maxlength = "200" ng-minlength = "1" required autofocus >
< / div >
< div class = "form-group" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.group.users' | tr }}< / label >
2019-11-05 22:08:48 +01:00
< div class = "control-label" >
< multiselect ng-model = "groupAdd.selectedUsers" options = "(user.username || user.email) for user in allUsers" data-compare-by = "email" data-multiple = "true" filter-after-rows = "5" scroll-after-rows = "10" > < / multiselect >
2018-01-22 13:01:38 -08:00
< / div >
2019-11-05 22:08:48 +01:00
< / div >
< input class = "hide" type = "submit" ng-disabled = "groupAddForm.$invalid || groupAdd.busy" / >
< / form >
< / div >
< div class = "modal-footer" >
2020-11-13 16:44:39 +01:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
< button type = "button" class = "btn btn-success" ng-click = "groupAdd.submit()" ng-disabled = "groupAddForm.$invalid || groupAdd.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "groupAdd.busy" > < / i > {{ 'users.group.addGroupAction' | tr }}< / button >
2019-11-05 22:08:48 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2019-11-05 22:08:48 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2018-06-18 17:45:09 -07:00
<!-- Modal edit group -->
< div class = "modal fade" id = "groupEditModal" tabindex = "-1" role = "dialog" >
2019-11-05 22:08:48 +01:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2020-11-13 16:44:39 +01:00
< h4 class = "modal-title" > {{ 'users.editGroupDialog.title' | tr:{ name: groupEdit.groupInfo.name } }}< / h4 >
2019-11-05 22:08:48 +01:00
< / div >
< div class = "modal-body" >
2020-11-13 16:44:39 +01:00
< p class = "text-warning" ng-show = "groupEdit.source" > {{ 'users.editGroupDialog.externalLdapWarning' | tr }}< / p >
2020-06-05 08:18:40 +02:00
2019-11-05 22:08:48 +01:00
< form name = "groupEdit_form" role = "form" ng-submit = "groupEdit.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': groupEditForm.groupName.$invalid }" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.group.name' | tr }}< / label >
2020-06-05 08:18:40 +02:00
< input type = "text" class = "form-control" ng-model = "groupEdit.name" name = "groupName" ng-disabled = "groupEdit.busy || groupEdit.source" autofocus >
2019-11-05 22:08:48 +01:00
< / div >
< div class = "form-group" >
2020-11-13 16:44:39 +01:00
< label class = "control-label" > {{ 'users.group.users' | tr }}< / label >
2019-11-05 22:08:48 +01:00
< div class = "control-label" >
2024-01-13 22:14:40 +01:00
< multiselect ng-hide = "groupEdit.source" ng-model = "groupEdit.selectedUsers" ng-disabled = "groupEdit.busy" options = "(user.username || user.email) for user in allUsers" data-compare-by = "email" data-multiple = "true" filter-after-rows = "5" scroll-after-rows = "10" > < / multiselect >
2024-03-01 18:37:34 +01:00
< div ng-show = "groupEdit.source" > < span ng-repeat = "user in groupEdit.selectedUsers" > {{ (user.username || user.email) }}< / span > < / div >
2018-06-18 17:45:09 -07:00
< / div >
2019-11-05 22:08:48 +01:00
< / div >
2021-02-18 17:01:49 +01:00
< div class = "form-group" >
< label class = "control-label" > Access to Apps< / label >
< div class = "control-label" >
< multiselect ng-model = "groupEdit.selectedApps" options = "(app.label || app.fqdn) for app in groupEdit.apps" data-compare-by = "fqdn" data-multiple = "true" filter-after-rows = "5" scroll-after-rows = "10" > < / multiselect >
< / div >
< / div >
2024-01-20 00:11:10 +01:00
< input class = "hide" type = "submit" ng-disabled = "groupEdit_form.$invalid || groupEdit.busy" / >
2019-11-05 22:08:48 +01:00
< / form >
< / div >
< div class = "modal-footer" >
2020-11-13 16:44:39 +01:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
< button type = "button" class = "btn btn-success" ng-click = "groupEdit.submit()" ng-disabled = "groupEdit_form.$invalid || groupEdit.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "groupEdit.busy" > < / i > {{ 'main.dialog.save' | tr }}< / button >
2019-11-05 22:08:48 +01:00
< / div >
2018-06-18 17:45:09 -07:00
< / div >
2019-11-05 22:08:48 +01:00
< / div >
2018-06-18 17:45:09 -07:00
< / div >
2018-01-22 13:01:38 -08:00
<!-- Modal remove group -->
< div class = "modal fade" id = "groupRemoveModal" tabindex = "-1" role = "dialog" >
2019-05-13 23:55:54 +02:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2020-11-13 16:44:39 +01:00
< h4 class = "modal-title" > {{ 'users.deleteGroupDialog.title' | tr:{ name: groupRemove.group.name } }}< / h4 >
2019-05-13 23:55:54 +02:00
< / div >
< div class = "modal-body" >
< div ng-show = "groupRemove.memberCount" class = "text-danger" >
2020-11-13 16:44:39 +01:00
< b > {{ 'users.deleteGroupDialog.description' | tr:{ memberCount: groupRemove.memberCount } }}< / b >
2019-05-13 23:55:54 +02:00
< br / >
< br / >
2018-01-22 13:01:38 -08:00
< / div >
2019-05-13 23:55:54 +02:00
< / div >
< div class = "modal-footer" >
2020-11-13 16:44:39 +01:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
< button type = "button" class = "btn btn-danger" ng-click = "groupRemove.submit()" ng-disabled = "groupRemove.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "groupRemove.busy" > < / i > {{ 'users.deleteGroupDialog.deleteAction' | tr }}< / button >
2019-05-13 23:55:54 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2019-05-13 23:55:54 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2021-09-16 14:35:17 +02:00
<!-- Modal password reset -->
< div class = "modal fade" id = "passwordResetModal" tabindex = "-1" role = "dialog" >
2020-11-13 16:44:39 +01:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2021-09-16 14:35:17 +02:00
< h4 class = "modal-title" > {{ 'users.passwordResetDialog.title' | tr:{ username: (passwordReset.user.username || passwordReset.user.email) } }}< / h4 >
2020-11-13 16:44:39 +01:00
< / div >
< div class = "modal-body" >
2021-10-27 19:41:17 +02:00
< div class = "form-group" >
< label class = "control-label" > {{ 'users.passwordResetDialog.descriptionLink' | tr }}< / label >
< div class = "input-group" >
< input type = "text" id = "passwordResetLinkInput" class = "form-control" ng-value = "passwordReset.resetLink" readonly / >
< span class = "input-group-btn" >
2021-10-27 22:41:02 +02:00
< button class = "btn btn-primary" id = "passwordResetLinkClipboardButton" type = "button" data-clipboard-target = "#passwordResetLinkInput" > < i class = "fa fa-clipboard" > < / i > < / button >
2021-10-27 19:41:17 +02:00
< / span >
2021-10-27 18:36:41 +02:00
< / div >
2021-04-15 17:16:15 +02:00
< / div >
2021-10-27 18:36:41 +02:00
< br / >
2021-10-27 19:41:17 +02:00
< div class = "form-group" >
< label class = "control-label" > {{ 'users.passwordResetDialog.descriptionEmail' | tr }}< / label >
< div class = "input-group" >
2022-11-10 13:43:27 +01:00
< input type = "email" ng-change = "passwordReset.emailError = null" class = "form-control" ng-model = "passwordReset.email" / >
2021-10-27 19:41:17 +02:00
< span class = "input-group-btn" >
< button type = "button" class = "btn btn-primary" ng-click = "passwordReset.sendEmail()" ng-disabled = "passwordReset.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "passwordReset.busy" > < / i > {{ 'users.passwordResetDialog.sendAction' | tr }}< / button >
< / span >
2021-04-15 17:16:15 +02:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2022-11-10 13:43:27 +01:00
< div class = "text-success text-small text-bold" ng-show = "passwordReset.emailError === ''" > {{ 'profile.passwordResetNotification.body' | tr:{ email: passwordReset.email } }}< / div >
< div class = "text-danger text-small text-bold" ng-show = "passwordReset.emailError !== ''" > {{ passwordReset.emailError }}< / div >
2020-11-13 16:44:39 +01:00
< / div >
< div class = "modal-footer" >
2021-10-27 18:36:41 +02:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.close' | tr }}< / button >
2020-11-13 16:44:39 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2020-11-13 16:44:39 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2021-09-16 15:46:26 +02:00
<!-- Modal invitation -->
< div class = "modal fade" id = "invitationModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > {{ 'users.invitationDialog.title' | tr:{ username: (invitation.user.username || invitation.user.email) } }}< / h4 >
< / div >
2021-10-27 22:35:58 +02:00
< div class = "modal-body" >
< div class = "form-group" >
2021-10-27 19:57:57 +02:00
< label class = "control-label" > {{ 'users.invitationDialog.descriptionLink' | tr }}< / label >
< div class = "input-group" >
2021-09-16 15:46:26 +02:00
< input type = "text" id = "invitationLinkInput" class = "form-control" ng-value = "invitation.inviteLink" readonly / >
< span class = "input-group-btn" >
2021-10-27 22:41:02 +02:00
< button class = "btn btn-primary" id = "invitationLinkClipboardButton" type = "button" data-clipboard-target = "#invitationLinkInput" > < i class = "fa fa-clipboard" > < / i > < / button >
2021-10-27 19:57:57 +02:00
< / span >
< / div >
< / div >
< br / >
< div class = "form-group" >
< label class = "control-label" > {{ 'users.invitationDialog.descriptionEmail' | tr }}< / label >
< div class = "input-group" >
2021-10-27 21:59:30 +02:00
< input type = "email" class = "form-control" ng-model = "invitation.email" / >
2021-10-27 19:57:57 +02:00
< span class = "input-group-btn" >
< button type = "button" class = "btn btn-primary" ng-click = "invitation.sendEmail()" ng-disabled = "invitation.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "invitation.busy" > < / i > {{ 'users.invitationDialog.sendAction' | tr }}< / button >
2021-09-16 15:46:26 +02:00
< / span >
< / div >
< / div >
< / div >
< div class = "modal-footer" >
2021-10-27 19:57:57 +02:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > {{ 'main.dialog.close' | tr }}< / button >
2021-09-16 15:46:26 +02:00
< / div >
< / div >
< / div >
< / div >
2021-09-17 15:53:11 +02:00
<!-- Modal set ghost -->
< div class = "modal fade" id = "setGhostModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2021-09-17 16:08:13 +02:00
< h4 class = "modal-title" > {{ 'users.setGhostDialog.title' | tr: { username: setGhost.user.username} }}< / h4 >
2021-09-17 15:53:11 +02:00
< / div >
< div class = "modal-body" >
2021-10-27 19:32:09 +02:00
< p > {{ 'users.setGhostDialog.description' | tr }}< / p >
2021-09-17 15:53:11 +02:00
< form name = "setGhostForm" role = "form" novalidate ng-submit = "setGhost.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': setGhost.error }" >
2021-09-17 16:08:13 +02:00
< label class = "control-label" for = "setGhostPassword" > {{ 'users.setGhostDialog.password' | tr }}< / label >
2021-09-17 15:53:11 +02:00
< div class = "control-label" ng-show = "setGhost.error" >
< small ng-show = "setGhost.error" > {{ setGhost.error }}< / small >
< / div >
< div class = "input-group" >
2022-03-30 09:23:01 -07:00
< input type = "text" id = "setGhostPassword" class = "form-control" name = "ghostPassword" ng-model = "setGhost.password" required ng-readonly = "setGhost.success" / >
2021-09-17 15:53:11 +02:00
< span class = "input-group-btn" >
2024-12-10 12:58:22 +01:00
< button class = "btn btn-default" ng-hide = "setGhost.success" type = "button" uib-tooltip = "{{ 'users.setGhostDialog.generatePassword' | tr }}" ng-click = "setGhost.generatePassword()" > < i class = "fa fa-key" > < / i > < / button >
2021-11-24 16:35:54 +01:00
< button class = "btn btn-default" ng-show = "setGhost.success" type = "button" id = "setGhostClipboardButton" data-clipboard-target = "#setGhostPassword" > < i class = "fa fa-clipboard" > < / i > < / button >
2021-09-17 15:53:11 +02:00
< / span >
< / div >
< / div >
< input class = "hide" type = "submit" ng-disabled = "setGhostForm.$invalid || setGhost.busy" / >
< / form >
< / div >
< div class = "modal-footer" >
2021-09-17 16:08:13 +02:00
< button type = "button" class = "btn btn-default" ng-show = "setGhost.success" data-dismiss = "modal" > {{ 'main.dialog.close' | tr }}< / button >
< button type = "button" class = "btn btn-default" ng-hide = "setGhost.success" data-dismiss = "modal" > {{ 'main.dialog.cancel' | tr }}< / button >
2021-10-19 20:09:00 -07:00
< button type = "button" class = "btn btn-success" ng-hide = "setGhost.success" ng-click = "setGhost.submit()" ng-disabled = "setGhostForm.$invalid || setGhost.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "setGhost.busy" > < / i > {{ 'users.setGhostDialog.setPassword' | tr }}< / button >
2021-09-17 15:53:11 +02:00
< / div >
< / div >
< / div >
< / div >
2018-01-22 13:01:38 -08:00
< div class = "content content-large" >
2024-10-15 18:46:51 +02:00
< h1 class = "section-header" > {{ 'main.navbar.users' | tr }}< / h1 >
2022-02-08 15:05:27 +01:00
< div >
< div class = "users-toolbar" >
< input type = "text" id = "userSearchInput" class = "form-control" style = "max-width: 350px;" ng-model = "userSearchString" ng-model-options = "{ debounce: 1000 }" ng-change = "updateFilter()" placeholder = "{{ 'main.searchPlaceholder' | tr }}" / >
< multiselect ng-model = "userStateFilter" ms-header = "{{ 'apps.stateFilterHeader' | tr }}" ms-selected = "{{ userStateFilter }}" options = "state.label for state in userStates" data-multiple = "false" > < / multiselect >
< div style = "flex-grow: 1;" > < / div >
2024-01-19 23:35:02 +01:00
< button class = "btn btn-primary btn-outline" ng-click = "userAdd.show()" >
2022-02-08 15:05:27 +01:00
< i class = "fa fa-user-plus" > < / i > {{ 'users.newUserAction' | tr }}
< / button >
< / div >
2019-01-15 13:30:37 +01:00
< div class = "card card-large" >
2018-01-22 13:01:38 -08:00
< div class = "grid-item-top" >
2019-01-16 14:02:08 +01:00
< div class = "row ng-hide" ng-show = "userRefreshBusy" >
2019-01-15 13:30:37 +01:00
< div class = "col-lg-12 text-center" >
< h2 > < i class = "fa fa-circle-notch fa-spin" > < / i > < / h2 >
2018-01-22 13:01:38 -08:00
< / div >
2019-01-15 13:30:37 +01:00
< / div >
2019-01-16 14:02:08 +01:00
< div class = "row ng-hide" ng-hide = "userRefreshBusy" >
2019-01-15 13:30:37 +01:00
< div class = "col-lg-12" >
2019-01-16 14:02:08 +01:00
< table class = "table table-hover" style = "margin: 0;" >
2019-01-15 13:30:37 +01:00
< thead >
< tr >
< th style = "width: 0.5%;" > < / th >
2020-11-13 16:44:39 +01:00
< th style = "width:45%" > {{ 'users.users.user' | tr }}< / th >
< th style = "width:49.5%" class = "hidden-xs hidden-sm" > {{ 'users.users.groups' | tr }}< / th >
2020-11-11 22:50:57 +01:00
< th style = "width: 5%" class = "text-right" > {{ 'main.actions' | tr }}< / th >
2019-01-15 13:30:37 +01:00
< / tr >
< / thead >
< tbody >
2019-08-13 15:30:40 +02:00
< tr ng-show = "users.length === 0" >
2020-11-13 16:44:39 +01:00
< td colspan = "5" class = "text-center text-muted" > {{ 'users.users.empty' | tr }}< / td >
2019-08-13 15:30:40 +02:00
< / tr >
2019-08-08 07:39:43 -07:00
< tr ng-repeat = "user in users" ng-class = "{'text-muted': !user.active}" >
2021-12-09 21:21:21 +01:00
< td style = "min-width: 33.5px;" >
2021-12-02 17:58:43 -08:00
< i class = "fas fa-crown arrow" ng-show = "user.active && user.role === 'owner'" uib-tooltip = "{{ 'users.users.superadminTooltip' | tr }}" > < / i >
2021-03-30 13:31:24 +02:00
< i class = "fa fa-user-tie arrow" ng-show = "user.active && user.role === 'admin'" uib-tooltip = "{{ 'users.users.adminTooltip' | tr }}" > < / i >
< i class = "fas fa-users-cog arrow" ng-show = "user.active && user.role === 'usermanager'" uib-tooltip = "{{ 'users.users.usermanagerTooltip' | tr }}" > < / i >
2021-12-02 17:58:43 -08:00
< i class = "fas fa-mail-bulk arrow" ng-show = "user.active && user.role === 'mailmanager'" uib-tooltip = "{{ 'users.users.mailmanagerTooltip' | tr }}" > < / i >
2020-11-13 16:44:39 +01:00
< i class = "fa fa-ban" ng-show = "!user.active" uib-tooltip = "{{ 'users.users.inactiveTooltip' | tr }}" > < / i >
2019-01-15 13:30:37 +01:00
< / td >
2024-01-19 23:35:02 +01:00
< td class = "hand elide-table-cell" ng-click = "canEdit(user) && userEdit.show(user)" ng-show = "user.username" >
2020-11-13 16:44:39 +01:00
{{ user.displayName }} < span class = "text-muted" > {{ user.username }}< / span > < i ng-show = "user.source" class = "far fa-address-book" uib-tooltip = "{{ 'users.users.externalLdapTooltip' | tr }}" > < / i >
2019-01-15 13:30:37 +01:00
< / td >
2024-01-19 23:35:02 +01:00
< td class = "hand elide-table-cell" ng-click = "canEdit(user) && userEdit.show(user)" ng-hide = "user.username" >
2021-10-27 22:57:12 +02:00
< span class = "text-muted" uib-tooltip = "{{ 'users.users.notActivatedYetTooltip' | tr }}" > {{ user.email }}< / span >
2019-01-15 13:30:37 +01:00
< / td >
2024-01-19 23:35:02 +01:00
< td class = "text-left hand elide-table-cell hidden-xs hidden-sm" ng-click = "canEdit(user) && userEdit.show(user)" >
2019-01-15 13:30:37 +01:00
< span class = "group-badge" ng-repeat = "groupId in user.groupIds" >
{{ groupsById[groupId].name }}
< / span >
< / td >
2018-01-22 13:01:38 -08:00
2019-01-15 13:30:37 +01:00
< td class = "text-right no-wrap" style = "vertical-align: bottom" >
2022-04-24 22:11:35 +02:00
< button ng-disabled = "!canEdit(user)" ng-show = "!user.inviteAccepted && !isMe(user) && !user.source" class = "btn btn-xs btn-default" ng-click = "invitation.show(user)" uib-tooltip = "{{ 'users.users.invitationTooltip' | tr }}" > < i class = "fas fa-paper-plane" > < / i > < / button >
< button ng-disabled = "!canEdit(user)" ng-show = "user.inviteAccepted && !user.source" class = "btn btn-xs btn-default" ng-click = "passwordReset.show(user)" uib-tooltip = "{{ 'users.users.resetPasswordTooltip' | tr }}" > < i class = "fas fa-key" > < / i > < / button >
2022-02-26 14:09:36 +01:00
< button ng-disabled = "!canImpersonate(user)" class = "btn btn-xs btn-default" ng-click = "setGhost.show(user)" uib-tooltip = "{{ 'users.users.setGhostTooltip' | tr }}" > < i class = "fas fa-user-secret" > < / i > < / button >
2024-01-19 23:35:02 +01:00
< button ng-disabled = "!canEdit(user)" class = "btn btn-xs btn-default" ng-click = "userEdit.show(user)" uib-tooltip = "{{ 'users.users.editUserTooltip' | tr }}" > < i class = "fa fa-pencil-alt" > < / i > < / button >
< button ng-disabled = "!canEdit(user) || isMe(user)" class = "btn btn-xs btn-danger" ng-click = "userRemove.show(user)" uib-tooltip = "{{ 'users.users.removeUserTooltip' | tr }}" > < i class = "far fa-trash-alt" > < / i > < / button >
2019-01-15 13:30:37 +01:00
< / td >
< / tr >
< / tbody >
< / table >
2021-12-09 21:21:21 +01:00
< br / >
2022-03-05 17:33:23 +01:00
< div class = "pull-left" >
{{ 'users.users.count' | tr:{ count: allUsers.length } }}
< / div >
2021-12-09 21:21:21 +01:00
< div class = "pull-right" >
< button class = "btn btn-default btn-outline btn-xs" ng-click = "showPrevPage()" ng-class = "{ 'btn-primary': currentPage > 1 }" ng-disabled = "userRefreshBusy || currentPage <= 1" > < i class = "fa fa-angle-double-left" > < / i > {{ 'main.pagination.prev' | tr }}< / button >
2023-05-10 13:52:41 +02:00
< span style = "margin: 0 5px; line-height: 1.5; font-size: 12px;" > {{ currentPage }}< / span >
2021-12-09 21:21:21 +01:00
< button class = "btn btn-default btn-outline btn-xs" ng-click = "showNextPage()" ng-class = "{ 'btn-primary': users.length > pageItems }" ng-disabled = "userRefreshBusy || users.length < pageItems" > {{ 'main.pagination.next' | tr }} < i class = "fa fa-angle-double-right" > < / i > < / button >
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2019-01-15 13:30:37 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2019-01-15 13:30:37 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2024-10-15 18:46:51 +02:00
< h3 class = "section-header" >
{{ 'users.groups.title' | tr }}
< button class = "btn btn-primary btn-outline" ng-click = "groupAdd.show()" > < i class = "fa fa-plus" > < / i > {{ 'users.groups.newGroupAction' | tr }}< / button >
< / h3 >
2018-01-22 13:01:38 -08:00
< div class = "card card-large" >
2020-11-13 16:44:39 +01:00
< div class = "grid-item-top" >
< div class = "row ng-hide" ng-show = "!ready" >
< div class = "col-lg-12 text-center" >
< h2 > < i class = "fa fa-circle-notch fa-spin" > < / i > < / h2 >
< / div >
< / div >
< div class = "row animateMeOpacity ng-hide" ng-show = "ready" >
< div class = "col-lg-12" >
< table class = "table table-hover" style = "margin: 0;" >
< thead >
< tr >
< th style = "width: 45%" > {{ 'users.groups.name' | tr }}< / th >
< th style = "width: 49.5%" class = "hidden-xs hidden-sm" > {{ 'users.groups.users' | tr }}< / th >
< th style = "width: 5%" class = "text-right" > {{ 'main.actions' | tr }}< / th >
< / tr >
< / thead >
< tbody >
< tr ng-repeat = "group in groups" >
< td class = "hand elide-table-cell" style = "text-overflow: ellipsis; white-space: nowrap;" ng-click = "groupEdit.show(group)" >
{{ group.name }} < i ng-show = "group.source" class = "far fa-address-book" uib-tooltip = "{{ 'users.groups.externalLdapTooltip' | tr }}" > < / i >
< / td >
< td class = "hand elide-table-cell" style = "text-overflow: ellipsis; white-space: nowrap;" ng-click = "groupEdit.show(group)" >
{{ groupMembers(group) }}
< / td >
< td class = "text-right no-wrap" style = "vertical-align: bottom" >
< button class = "btn btn-xs btn-default" ng-click = "groupEdit.show(group)" uib-tooltip = "Edit Group" > < i class = "fa fa-pencil-alt" > < / i > < / button >
< button class = "btn btn-xs btn-danger" ng-click = "groupRemove.show(group)" uib-tooltip = "Remove Group" > < i class = "far fa-trash-alt" > < / i > < / button >
< / td >
< / tr >
< / tbody >
< / table >
< / div >
2018-01-22 13:01:38 -08:00
< / div >
2020-11-13 16:44:39 +01:00
< / div >
2018-01-22 13:01:38 -08:00
< / div >
< / div >