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">
11 <div class=
"left-buttons">
13 *
ngIf=
"isInSelectionMode()" i18n-label
label=
"Batch actions" theme=
"orange"
14 [actions]=
"bulkUserActions" [entry]=
"selectedUsers"
18 <a *
ngIf=
"!isInSelectionMode()" class=
"add-button" routerLink=
"/admin/users/create">
19 <my-global-icon iconName=
"user-add" aria-hidden=
"true"></my-global-icon>
20 <ng-container i18n
>Create user
</ng-container>
25 <div class=
"input-group has-feedback has-clear">
26 <div class=
"input-group-prepend c-hand" ngbDropdown
placement=
"bottom-left auto" container=
"body">
27 <div class=
"input-group-text" ngbDropdownToggle
>
28 <span class=
"caret" aria-haspopup=
"menu" role=
"button"></span>
31 <div role=
"menu" ngbDropdownMenu
>
32 <h6 class=
"dropdown-header" i18n
>Advanced user filters
</h6>
33 <a [routerLink]=
"[ '/admin/users/list' ]" [queryParams]=
"{ 'search': 'banned:true' }" class=
"dropdown-item" i18n
>Banned users
</a>
37 type=
"text" name=
"table-filter" id=
"table-filter" i18n-placeholder
placeholder=
"Filter..."
38 (keyup)=
"onSearch($event)"
40 <a class=
"glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)=
"resetTableFilter()"></a>
41 <span class=
"sr-only" i18n
>Clear filters
</span>
48 <ng-template pTemplate=
"header">
50 <th style=
"width: 40px">
51 <p-tableHeaderCheckbox ariaLabel=
"Select all rows" i18n-ariaLabel
></p-tableHeaderCheckbox>
53 <th style=
"width: 40px"></th>
54 <th style=
"width: 60px;">
55 <div class=
"c-hand column-toggle" ngbDropdown
placement=
"bottom-left auto" container=
"body" autoClose=
"outside">
56 <my-global-icon iconName=
"columns" ngbDropdownToggle
></my-global-icon>
58 <div role=
"menu" class=
"dropdown-menu" ngbDropdownMenu
>
59 <div class=
"dropdown-header" i18n
>Table parameters
</div>
60 <div ngbDropdownItem
class=
"dropdown-item">
63 [availableItems]=
"columns"
64 [selectableGroup]=
"false" [(ngModel)]=
"selectedColumns"
65 i18n-placeholder
placeholder=
"Select columns"
69 <div ngbDropdownItem
class=
"dropdown-item">
70 <my-peertube-checkbox inputName=
"highlightBannedUsers" [(ngModel)]=
"highlightBannedUsers"
71 i18n-labelText
labelText=
"Highlight banned users"></my-peertube-checkbox>
76 <th *
ngIf=
"isSelected('username')" pResizableColumn
pSortableColumn=
"username">{{ getColumn('username').label }}
<p-sortIcon field=
"username"></p-sortIcon></th>
77 <th *
ngIf=
"isSelected('email')">{{ getColumn('email').label }}
</th>
78 <th *
ngIf=
"isSelected('quota')" style=
"width: 160px;" pSortableColumn=
"videoQuotaUsed">{{ getColumn('quota').label }}
<p-sortIcon field=
"videoQuotaUsed"></p-sortIcon></th>
79 <th *
ngIf=
"isSelected('quotaDaily')" style=
"width: 160px;">{{ getColumn('quotaDaily').label }}
</th>
80 <th *
ngIf=
"isSelected('role')" style=
"width: 120px;" pSortableColumn=
"role">{{ getColumn('role').label }}
<p-sortIcon field=
"role"></p-sortIcon></th>
81 <th *
ngIf=
"isSelected('pluginAuth')" style=
"width: 140px;" pResizableColumn
>{{ getColumn('pluginAuth').label }}
</th>
82 <th *
ngIf=
"isSelected('createdAt')" style=
"width: 150px;" pSortableColumn=
"createdAt">{{ getColumn('createdAt').label }}
<p-sortIcon field=
"createdAt"></p-sortIcon></th>
83 <th *
ngIf=
"isSelected('lastLoginDate')" style=
"width: 150px;" pSortableColumn=
"lastLoginDate">{{ getColumn('lastLoginDate').label }}
<p-sortIcon field=
"lastLoginDate"></p-sortIcon></th>
87 <ng-template pTemplate=
"body" let-expanded=
"expanded" let-user
>
89 <tr [pSelectableRow]=
"user" [ngClass]=
"{ banned: highlightBannedUsers && user.blocked }">
90 <td class=
"checkbox-cell">
91 <p-tableCheckbox [value]=
"user" ariaLabel=
"Select this row" i18n-ariaLabel
></p-tableCheckbox>
94 <td class=
"expand-cell">
95 <span *
ngIf=
"user.blockedReason" class=
"expander" [pRowToggler]=
"user">
96 <i [ngClass]=
"expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
100 <td class=
"action-cell">
101 <my-user-moderation-dropdown *
ngIf=
"!isInSelectionMode()" [user]=
"user" container=
"body"
102 (userChanged)=
"onUserChanged()" (userDeleted)=
"onUserChanged()">
103 </my-user-moderation-dropdown>
106 <td *
ngIf=
"isSelected('username')">
107 <a i18n-title
title=
"Open account in a new tab" target=
"_blank" rel=
"noopener noreferrer" [routerLink]=
"[ '/accounts/' + user.username ]">
108 <div class=
"chip two-lines">
109 <my-account-avatar [account]=
"user?.account" size=
"32"></my-account-avatar>
111 <span class=
"user-table-primary-text">{{ user.account.displayName }}
</span>
112 <span class=
"text-muted">{{ user.username }}
</span>
118 <td *
ngIf=
"isSelected('email')" [title]=
"user.email">
119 <ng-container *
ngIf=
"!requiresEmailVerification || user.blocked; else emailWithVerificationStatus">
120 <a class=
"table-email" [href]=
"'mailto:' + user.email">{{ user.email }}
</a>
124 <ng-template #emailWithVerificationStatus
>
125 <td *
ngIf=
"user.emailVerified === false; else emailVerifiedNotFalse" i18n-title
title=
"User's email must be verified to login">
126 <em>? {{ user.email }}
</em>
128 <ng-template #emailVerifiedNotFalse
>
129 <td i18n-title
title=
"User's email is verified / User can login without email verification">
130 ✓ {{ user.email }}
135 <td *
ngIf=
"isSelected('quota')">
136 <div class=
"progress" i18n-title
title=
"Total video quota">
137 <div class=
"progress-bar" role=
"progressbar" [style]=
"{ width: getUserVideoQuotaPercentage(user) + '%' }"
138 [attr.aria-valuenow]=
"user.rawVideoQuotaUsed" aria-valuemin=
"0" [attr.aria-valuemax]=
"user.rawVideoQuota">
140 <span>{{ user.videoQuotaUsed }}
</span>
141 <span>{{ user.videoQuota }}
</span>
145 <td *
ngIf=
"isSelected('quotaDaily')">
146 <div class=
"progress" i18n-title
title=
"Total daily video quota">
147 <div class=
"progress-bar secondary" role=
"progressbar" [style]=
"{ width: getUserVideoQuotaDailyPercentage(user) + '%' }"
148 [attr.aria-valuenow]=
"user.rawVideoQuotaUsedDaily" aria-valuemin=
"0" [attr.aria-valuemax]=
"user.rawVideoQuotaDaily">
150 <span>{{ user.videoQuotaUsedDaily }}
</span>
151 <span>{{ user.videoQuotaDaily }}
</span>
155 <td *
ngIf=
"isSelected('role')">
156 <span *
ngIf=
"user.blocked" class=
"badge badge-banned" i18n-title
title=
"The user was banned">{{ user.roleLabel }}
</span>
157 <span *
ngIf=
"!user.blocked" class=
"badge" [ngClass]=
"getRoleClass(user.role)">{{ user.roleLabel }}
</span>
160 <td *
ngIf=
"isSelected('pluginAuth')">
161 <ng-container *
ngIf=
"user.pluginAuth">{{ user.pluginAuth }}
</ng-container>
164 <td *
ngIf=
"isSelected('createdAt')" [title]=
"user.createdAt">{{ user.createdAt | date: 'short' }}
</td>
166 <td *
ngIf=
"isSelected('lastLoginDate')" [title]=
"user.lastLoginDate">{{ user.lastLoginDate | date: 'short' }}
</td>
170 <ng-template pTemplate=
"rowexpansion" let-user
>
171 <tr class=
"user-blocked-reason">
173 <span i18n
class=
"ban-reason-label">Ban reason:
</span>
174 {{ user.blockedReason }}
180 <my-user-ban-modal #userBanModal (userBanned)=
"onUserChanged()"></my-user-ban-modal>