2 [value]=
"users" [lazy]=
"true" [paginator]=
"totalRecords > 0" [totalRecords]=
"totalRecords" [rows]=
"rowsPerPage" [rowsPerPageOptions]=
"rowsPerPageOptions"
3 [sortField]=
"sort.field" [sortOrder]=
"sort.order" (onLazyLoad)=
"loadLazy($event)" dataKey=
"id" [resizableColumns]=
"true"
4 [(selection)]=
"selectedUsers"
5 [showCurrentPageReport]=
"true" i18n-currentPageReportTemplate
6 currentPageReportTemplate=
"Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
7 (onPage)=
"onPage($event)" [expandedRowKeys]=
"expandedRows"
9 <ng-template pTemplate=
"caption">
13 *
ngIf=
"isInSelectionMode()" i18n-label
label=
"Batch actions" theme=
"orange"
14 [actions]=
"bulkUserActions" [entry]=
"selectedUsers"
20 <div class=
"input-group has-feedback has-clear">
21 <div class=
"input-group-prepend c-hand" ngbDropdown
placement=
"bottom-left auto" container=
"body">
22 <div class=
"input-group-text" ngbDropdownToggle
>
23 <span class=
"caret" aria-haspopup=
"menu" role=
"button"></span>
26 <div role=
"menu" ngbDropdownMenu
>
27 <h6 class=
"dropdown-header" i18n
>Advanced user filters
</h6>
28 <a [routerLink]=
"[ '/admin/users/list' ]" [queryParams]=
"{ 'search': 'banned:true' }" class=
"dropdown-item" i18n
>Banned users
</a>
32 type=
"text" name=
"table-filter" id=
"table-filter" i18n-placeholder
placeholder=
"Filter..."
33 (keyup)=
"onSearch($event)"
35 <a class=
"glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)=
"resetTableFilter()"></a>
36 <span class=
"sr-only" i18n
>Clear filters
</span>
40 <a class=
"ml-2 add-button" routerLink=
"/admin/users/create">
41 <my-global-icon iconName=
"user-add" aria-hidden=
"true"></my-global-icon>
42 <ng-container i18n
>Create user
</ng-container>
47 <ng-template pTemplate=
"header">
49 <th style=
"width: 40px">
50 <p-tableHeaderCheckbox ariaLabel=
"Select all rows" i18n-ariaLabel
></p-tableHeaderCheckbox>
52 <th style=
"width: 40px"></th>
53 <th style=
"width: 60px;">
54 <div class=
"c-hand column-toggle" ngbDropdown
placement=
"bottom-left auto" container=
"body" autoClose=
"outside">
55 <my-global-icon iconName=
"columns" ngbDropdownToggle
></my-global-icon>
57 <div role=
"menu" class=
"dropdown-menu" ngbDropdownMenu
>
58 <div class=
"dropdown-header" i18n
>Table parameters
</div>
59 <div ngbDropdownItem
class=
"dropdown-item">
62 [availableItems]=
"columns"
63 [selectableGroup]=
"false" [(ngModel)]=
"selectedColumns"
64 i18n-placeholder
placeholder=
"Select columns"
68 <div ngbDropdownItem
class=
"dropdown-item">
69 <my-peertube-checkbox inputName=
"highlightBannedUsers" [(ngModel)]=
"highlightBannedUsers"
70 i18n-labelText
labelText=
"Highlight banned users"></my-peertube-checkbox>
75 <th *
ngIf=
"isSelected('username')" pResizableColumn
pSortableColumn=
"username">{{ getColumn('username').label }}
<p-sortIcon field=
"username"></p-sortIcon></th>
76 <th *
ngIf=
"isSelected('email')">{{ getColumn('email').label }}
</th>
77 <th *
ngIf=
"isSelected('quota')" style=
"width: 160px;" pSortableColumn=
"videoQuotaUsed">{{ getColumn('quota').label }}
<p-sortIcon field=
"videoQuotaUsed"></p-sortIcon></th>
78 <th *
ngIf=
"isSelected('quotaDaily')" style=
"width: 160px;">{{ getColumn('quotaDaily').label }}
</th>
79 <th *
ngIf=
"isSelected('role')" style=
"width: 120px;" pSortableColumn=
"role">{{ getColumn('role').label }}
<p-sortIcon field=
"role"></p-sortIcon></th>
80 <th *
ngIf=
"isSelected('pluginAuth')" style=
"width: 140px;" pResizableColumn
>{{ getColumn('pluginAuth').label }}
</th>
81 <th *
ngIf=
"isSelected('createdAt')" style=
"width: 150px;" pSortableColumn=
"createdAt">{{ getColumn('createdAt').label }}
<p-sortIcon field=
"createdAt"></p-sortIcon></th>
82 <th *
ngIf=
"isSelected('lastLoginDate')" style=
"width: 150px;" pSortableColumn=
"lastLoginDate">{{ getColumn('lastLoginDate').label }}
<p-sortIcon field=
"lastLoginDate"></p-sortIcon></th>
86 <ng-template pTemplate=
"body" let-expanded=
"expanded" let-user
>
88 <tr [pSelectableRow]=
"user" [ngClass]=
"{ banned: highlightBannedUsers && user.blocked }">
89 <td class=
"checkbox-cell">
90 <p-tableCheckbox [value]=
"user" ariaLabel=
"Select this row" i18n-ariaLabel
></p-tableCheckbox>
93 <td class=
"expand-cell">
94 <span *
ngIf=
"user.blockedReason" class=
"expander" [pRowToggler]=
"user">
95 <i [ngClass]=
"expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
99 <td class=
"action-cell">
100 <my-user-moderation-dropdown *
ngIf=
"!isInSelectionMode()" [user]=
"user" container=
"body"
101 (userChanged)=
"onUserChanged()" (userDeleted)=
"onUserChanged()">
102 </my-user-moderation-dropdown>
105 <td *
ngIf=
"isSelected('username')">
106 <a i18n-title
title=
"Open account in a new tab" target=
"_blank" rel=
"noopener noreferrer" [routerLink]=
"[ '/accounts/' + user.username ]">
107 <div class=
"chip two-lines">
110 [src]=
"user?.account?.avatar?.path"
111 (error)=
"switchToDefaultAvatar($event)"
115 <span class=
"user-table-primary-text">{{ user.account.displayName }}
</span>
116 <span class=
"text-muted">{{ user.username }}
</span>
122 <td *
ngIf=
"isSelected('email')" [title]=
"user.email">
123 <ng-container *
ngIf=
"!requiresEmailVerification || user.blocked; else emailWithVerificationStatus">
124 <a class=
"table-email" [href]=
"'mailto:' + user.email">{{ user.email }}
</a>
128 <ng-template #emailWithVerificationStatus
>
129 <td *
ngIf=
"user.emailVerified === false; else emailVerifiedNotFalse" i18n-title
title=
"User's email must be verified to login">
130 <em>? {{ user.email }}
</em>
132 <ng-template #emailVerifiedNotFalse
>
133 <td i18n-title
title=
"User's email is verified / User can login without email verification">
134 ✓ {{ user.email }}
139 <td *
ngIf=
"isSelected('quota')">
140 <div class=
"progress" i18n-title
title=
"Total video quota">
141 <div class=
"progress-bar" role=
"progressbar" [style]=
"{ width: getUserVideoQuotaPercentage(user) + '%' }"
142 [attr.aria-valuenow]=
"user.rawVideoQuotaUsed" aria-valuemin=
"0" [attr.aria-valuemax]=
"user.rawVideoQuota">
144 <span>{{ user.videoQuotaUsed }}
</span>
145 <span>{{ user.videoQuota }}
</span>
149 <td *
ngIf=
"isSelected('quotaDaily')">
150 <div class=
"progress" i18n-title
title=
"Total daily video quota">
151 <div class=
"progress-bar secondary" role=
"progressbar" [style]=
"{ width: getUserVideoQuotaDailyPercentage(user) + '%' }"
152 [attr.aria-valuenow]=
"user.rawVideoQuotaUsedDaily" aria-valuemin=
"0" [attr.aria-valuemax]=
"user.rawVideoQuotaDaily">
154 <span>{{ user.videoQuotaUsedDaily }}
</span>
155 <span>{{ user.videoQuotaDaily }}
</span>
159 <td *
ngIf=
"isSelected('role')">
160 <span *
ngIf=
"user.blocked" class=
"badge badge-banned" i18n-title
title=
"The user was banned">{{ user.roleLabel }}
</span>
161 <span *
ngIf=
"!user.blocked" class=
"badge" [ngClass]=
"getRoleClass(user.role)">{{ user.roleLabel }}
</span>
164 <td *
ngIf=
"isSelected('pluginAuth')">
165 <ng-container *
ngIf=
"user.pluginAuth">{{ user.pluginAuth }}
</ng-container>
168 <td *
ngIf=
"isSelected('createdAt')" [title]=
"user.createdAt">{{ user.createdAt | date: 'short' }}
</td>
170 <td *
ngIf=
"isSelected('lastLoginDate')" [title]=
"user.lastLoginDate">{{ user.lastLoginDate | date: 'short' }}
</td>
174 <ng-template pTemplate=
"rowexpansion" let-user
>
175 <tr class=
"user-blocked-reason">
177 <span i18n
class=
"ban-reason-label">Ban reason:
</span>
178 {{ user.blockedReason }}
184 <my-user-ban-modal #userBanModal (userBanned)=
"onUserChanged()"></my-user-ban-modal>