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)=
"onUserSearch($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></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">
61 [options]=
"columns" [showToggleAll]=
"true" [(ngModel)]=
"selectedColumns" optionLabel=
"label"
62 emptyFilterMessage=
"No matching column found" i18n-emptyFilterMessage [filter]=
"false"
63 selectedItemsLabel=
"{0} columns displayed" i18n-emptyFilterMessage [showHeader]=
"false"
64 [maxSelectedLabels]=
"4"
67 <div ngbDropdownItem
class=
"dropdown-item">
68 <my-peertube-checkbox inputName=
"highlightBannedUsers" [(ngModel)]=
"highlightBannedUsers"
69 i18n-labelText
labelText=
"Highlight banned users"></my-peertube-checkbox>
74 <th *
ngIf=
"getColumn('username')" pResizableColumn i18n
pSortableColumn=
"username">{{ getColumn('username').label }}
<p-sortIcon field=
"username"></p-sortIcon></th>
75 <th *
ngIf=
"getColumn('email')" i18n
>{{ getColumn('email').label }}
</th>
76 <th *
ngIf=
"getColumn('quota')" style=
"width: 160px;" i18n
pSortableColumn=
"videoQuotaUsed">{{ getColumn('quota').label }}
<p-sortIcon field=
"videoQuotaUsed"></p-sortIcon></th>
77 <th *
ngIf=
"getColumn('quotaDaily')" style=
"width: 160px;" i18n
>{{ getColumn('quotaDaily').label }}
</th>
78 <th *
ngIf=
"getColumn('role')" style=
"width: 120px;" i18n
pSortableColumn=
"role">{{ getColumn('role').label }}
<p-sortIcon field=
"role"></p-sortIcon></th>
79 <th *
ngIf=
"getColumn('pluginAuth')" style=
"width: 140px;" pResizableColumn i18n
>{{ getColumn('pluginAuth').label }}
</th>
80 <th *
ngIf=
"getColumn('createdAt')" style=
"width: 150px;" i18n
pSortableColumn=
"createdAt">{{ getColumn('createdAt').label }}
<p-sortIcon field=
"createdAt"></p-sortIcon></th>
81 <th *
ngIf=
"getColumn('lastLoginDate')" style=
"width: 150px;" i18n
pSortableColumn=
"lastLoginDate">{{ getColumn('lastLoginDate').label }}
<p-sortIcon field=
"lastLoginDate"></p-sortIcon></th>
85 <ng-template pTemplate=
"body" let-expanded=
"expanded" let-user
>
87 <tr [pSelectableRow]=
"user" [ngClass]=
"{ banned: highlightBannedUsers && user.blocked }">
89 <p-tableCheckbox [value]=
"user"></p-tableCheckbox>
92 <td class=
"expand-cell">
93 <span *
ngIf=
"user.blockedReason" class=
"expander" [pRowToggler]=
"user">
94 <i [ngClass]=
"expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
98 <td class=
"action-cell">
99 <my-user-moderation-dropdown *
ngIf=
"!isInSelectionMode()" [user]=
"user" container=
"body"
100 (userChanged)=
"onUserChanged()" (userDeleted)=
"onUserChanged()">
101 </my-user-moderation-dropdown>
104 <td *
ngIf=
"getColumn('username')">
105 <a i18n-title
title=
"Open account in a new tab" target=
"_blank" rel=
"noopener noreferrer" [routerLink]=
"[ '/accounts/' + user.username ]">
106 <div class=
"chip two-lines">
109 [src]=
"user?.account?.avatar?.path"
110 (error)=
"switchToDefaultAvatar($event)"
114 <span class=
"user-table-primary-text">{{ user.account.displayName }}
</span>
115 <span class=
"text-muted">{{ user.username }}
</span>
121 <td *
ngIf=
"getColumn('email')" [title]=
"user.email">
122 <ng-container *
ngIf=
"!requiresEmailVerification || user.blocked; else emailWithVerificationStatus">
123 <a class=
"table-email" [href]=
"'mailto:' + user.email">{{ user.email }}
</a>
127 <ng-template #emailWithVerificationStatus
>
128 <td *
ngIf=
"user.emailVerified === false; else emailVerifiedNotFalse" i18n-title
title=
"User's email must be verified to login">
129 <em>? {{ user.email }}
</em>
131 <ng-template #emailVerifiedNotFalse
>
132 <td i18n-title
title=
"User's email is verified / User can login without email verification">
133 ✓ {{ user.email }}
138 <td *
ngIf=
"getColumn('quota')">
139 <div class=
"progress" i18n-title
title=
"Total video quota">
140 <div class=
"progress-bar" role=
"progressbar" [style]=
"{ width: getUserVideoQuotaPercentage(user) + '%' }"
141 [attr.aria-valuenow]=
"user.rawVideoQuotaUsed" aria-valuemin=
"0" [attr.aria-valuemax]=
"user.rawVideoQuota">
143 <span>{{ user.videoQuotaUsed }}
</span>
144 <span>{{ user.videoQuota }}
</span>
148 <td *
ngIf=
"getColumn('quotaDaily')">
149 <div class=
"progress" i18n-title
title=
"Total daily video quota">
150 <div class=
"progress-bar secondary" role=
"progressbar" [style]=
"{ width: getUserVideoQuotaDailyPercentage(user) + '%' }"
151 [attr.aria-valuenow]=
"user.rawVideoQuotaUsedDaily" aria-valuemin=
"0" [attr.aria-valuemax]=
"user.rawVideoQuotaDaily">
153 <span>{{ user.videoQuotaUsedDaily }}
</span>
154 <span>{{ user.videoQuotaDaily }}
</span>
158 <td *
ngIf=
"getColumn('role')">
159 <span *
ngIf=
"user.blocked" class=
"badge badge-banned" i18n-title
title=
"The user was banned">{{ user.roleLabel }}
</span>
160 <span *
ngIf=
"!user.blocked" class=
"badge" [ngClass]=
"getRoleClass(user.role)">{{ user.roleLabel }}
</span>
163 <td *
ngIf=
"getColumn('pluginAuth')">
164 <ng-container *
ngIf=
"user.pluginAuth">{{ user.pluginAuth }}
</ng-container>
167 <td *
ngIf=
"getColumn('createdAt')" [title]=
"user.createdAt">{{ user.createdAt | date: 'short' }}
</td>
169 <td *
ngIf=
"getColumn('lastLoginDate')" [title]=
"user.lastLoginDate">{{ user.lastLoginDate | date: 'short' }}
</td>
173 <ng-template pTemplate=
"rowexpansion" let-user
>
174 <tr class=
"user-blocked-reason">
176 <span i18n
class=
"ban-reason-label">Ban reason:
</span>
177 {{ user.blockedReason }}
183 <my-user-ban-modal #userBanModal (userBanned)=
"onUserChanged()"></my-user-ban-modal>