diff options
Diffstat (limited to 'client/src/app/+admin')
33 files changed, 424 insertions, 385 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-advanced-configuration.component.html b/client/src/app/+admin/config/edit-custom-config/edit-advanced-configuration.component.html index 0ab80e5a9..a17b13fdf 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-advanced-configuration.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-advanced-configuration.component.html | |||
@@ -1,15 +1,15 @@ | |||
1 | <ng-container [formGroup]="form"> | 1 | <ng-container [formGroup]="form"> |
2 | 2 | ||
3 | <div class="form-row mt-5"> <!-- cache grid --> | 3 | <div class="row mt-5"> <!-- cache grid --> |
4 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 4 | |
5 | <div class="col-12 col-lg-4 col-xl-3"> | ||
5 | <div i18n class="inner-form-title">CACHE</div> | 6 | <div i18n class="inner-form-title">CACHE</div> |
6 | <div i18n class="inner-form-description"> | 7 | <div i18n class="inner-form-description"> |
7 | Some files are not federated, and fetched when necessary. Define their caching policies. | 8 | Some files are not federated, and fetched when necessary. Define their caching policies. |
8 | </div> | 9 | </div> |
9 | </div> | 10 | </div> |
10 | 11 | ||
11 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 12 | <div class="col-12 col-lg-8 col-xl-9"> |
12 | |||
13 | <ng-container formGroupName="cache"> | 13 | <ng-container formGroupName="cache"> |
14 | <div class="form-group" formGroupName="previews"> | 14 | <div class="form-group" formGroupName="previews"> |
15 | <label i18n for="cachePreviewsSize">Number of previews to keep in cache</label> | 15 | <label i18n for="cachePreviewsSize">Number of previews to keep in cache</label> |
@@ -57,8 +57,8 @@ | |||
57 | </div> | 57 | </div> |
58 | </div> | 58 | </div> |
59 | 59 | ||
60 | <div class="form-row mt-4"> <!-- cache grid --> | 60 | <div class="row mt-4"> <!-- cache grid --> |
61 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 61 | <div class="col-12 col-lg-4 col-xl-3"> |
62 | <div class="anchor" id="customizations"></div> <!-- customizations anchor --> | 62 | <div class="anchor" id="customizations"></div> <!-- customizations anchor --> |
63 | <div i18n class="inner-form-title">CUSTOMIZATIONS</div> | 63 | <div i18n class="inner-form-title">CUSTOMIZATIONS</div> |
64 | <div i18n class="inner-form-description"> | 64 | <div i18n class="inner-form-description"> |
@@ -66,8 +66,7 @@ | |||
66 | </div> | 66 | </div> |
67 | </div> | 67 | </div> |
68 | 68 | ||
69 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 69 | <div class="col-12 col-lg-8 col-xl-9"> |
70 | |||
71 | <ng-container formGroupName="instance"> | 70 | <ng-container formGroupName="instance"> |
72 | <ng-container formGroupName="customizations"> | 71 | <ng-container formGroupName="customizations"> |
73 | <div class="form-group"> | 72 | <div class="form-group"> |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html b/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html index bae9d9775..c62ea7700 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html | |||
@@ -1,13 +1,13 @@ | |||
1 | <ng-container [formGroup]="form"> | 1 | <ng-container [formGroup]="form"> |
2 | <div class="form-row mt-5"> <!-- appearance grid --> | 2 | <div class="row mt-5"> <!-- appearance grid --> |
3 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 3 | <div class="col-12 col-lg-4 col-xl-3"> |
4 | <div i18n class="inner-form-title">APPEARANCE</div> | 4 | <div i18n class="inner-form-title">APPEARANCE</div> |
5 | <div i18n class="inner-form-description"> | 5 | <div i18n class="inner-form-description"> |
6 | Use <a routerLink="/admin/plugins">plugins & themes</a> for more involved changes, or <a routerLink="/admin/config/edit-custom" fragment="advanced-configuration">add slight customizations</a>. | 6 | Use <a class="link-orange" routerLink="/admin/plugins">plugins & themes</a> for more involved changes, or add slight <a class="link-orange" routerLink="/admin/config/edit-custom" fragment="advanced-configuration">customizations</a>. |
7 | </div> | 7 | </div> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 10 | <div class="col-12 col-lg-8 col-xl-9"> |
11 | 11 | ||
12 | <ng-container formGroupName="theme"> | 12 | <ng-container formGroupName="theme"> |
13 | <div class="form-group"> | 13 | <div class="form-group"> |
@@ -88,15 +88,15 @@ | |||
88 | </div> | 88 | </div> |
89 | </div> | 89 | </div> |
90 | 90 | ||
91 | <div class="form-row mt-4"> <!-- broadcast grid --> | 91 | <div class="row mt-4"> <!-- broadcast grid --> |
92 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 92 | <div class="col-12 col-lg-4 col-xl-3"> |
93 | <div i18n class="inner-form-title">BROADCAST MESSAGE</div> | 93 | <div i18n class="inner-form-title">BROADCAST MESSAGE</div> |
94 | <div i18n class="inner-for-description"> | 94 | <div i18n class="inner-form-description"> |
95 | Display a message on your instance | 95 | Display a message on your instance |
96 | </div> | 96 | </div> |
97 | </div> | 97 | </div> |
98 | 98 | ||
99 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 99 | <div class="col-12 col-lg-8 col-xl-9"> |
100 | 100 | ||
101 | <ng-container formGroupName="broadcastMessage"> | 101 | <ng-container formGroupName="broadcastMessage"> |
102 | 102 | ||
@@ -144,15 +144,15 @@ | |||
144 | </div> | 144 | </div> |
145 | </div> | 145 | </div> |
146 | 146 | ||
147 | <div class="form-row mt-4"> <!-- new users grid --> | 147 | <div class="row mt-4"> <!-- new users grid --> |
148 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 148 | <div class="col-12 col-lg-4 col-xl-3"> |
149 | <div i18n class="inner-form-title">NEW USERS</div> | 149 | <div i18n class="inner-form-title">NEW USERS</div> |
150 | <div i18n class="inner-for-description"> | 150 | <div i18n class="inner-form-description"> |
151 | Manage <a routerLink="/admin/users">users</a> to set their quota individually. | 151 | Manage <a class="link-orange" routerLink="/admin/users">users</a> to set their quota individually. |
152 | </div> | 152 | </div> |
153 | </div> | 153 | </div> |
154 | 154 | ||
155 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 155 | <div class="col-12 col-lg-8 col-xl-9"> |
156 | 156 | ||
157 | <ng-container formGroupName="signup"> | 157 | <ng-container formGroupName="signup"> |
158 | <div class="form-group"> | 158 | <div class="form-group"> |
@@ -163,7 +163,7 @@ | |||
163 | <ng-container ngProjectAs="description"> | 163 | <ng-container ngProjectAs="description"> |
164 | <span i18n>⚠️ This functionality requires a lot of attention and extra moderation.</span> | 164 | <span i18n>⚠️ This functionality requires a lot of attention and extra moderation.</span> |
165 | 165 | ||
166 | <div class="alert alert-info alert-signup" *ngIf="signupAlertMessage">{{ signupAlertMessage }}</div> | 166 | <div class="alert pt-alert-primary alert-signup" *ngIf="signupAlertMessage">{{ signupAlertMessage }}</div> |
167 | </ng-container> | 167 | </ng-container> |
168 | 168 | ||
169 | <ng-container ngProjectAs="extra"> | 169 | <ng-container ngProjectAs="extra"> |
@@ -185,7 +185,7 @@ | |||
185 | 185 | ||
186 | <div *ngIf="formErrors.signup.limit" class="form-error">{{ formErrors.signup.limit }}</div> | 186 | <div *ngIf="formErrors.signup.limit" class="form-error">{{ formErrors.signup.limit }}</div> |
187 | 187 | ||
188 | <small i18n *ngIf="hasUnlimitedSignup()" class="muted">Signup won't be limited to a fixed number of users.</small> | 188 | <small i18n *ngIf="hasUnlimitedSignup()" class="muted small">Signup won't be limited to a fixed number of users.</small> |
189 | </div> | 189 | </div> |
190 | 190 | ||
191 | <div [ngClass]="getDisabledSignupClass()" class="mt-3"> | 191 | <div [ngClass]="getDisabledSignupClass()" class="mt-3"> |
@@ -239,20 +239,20 @@ | |||
239 | </div> | 239 | </div> |
240 | </div> | 240 | </div> |
241 | 241 | ||
242 | <div class="form-row mt-4"> <!-- videos grid --> | 242 | <div class="row mt-4"> <!-- videos grid --> |
243 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 243 | <div class="col-12 col-lg-4 col-xl-3"> |
244 | <div i18n class="inner-form-title">VIDEOS</div> | 244 | <div i18n class="inner-form-title">VIDEOS</div> |
245 | </div> | 245 | </div> |
246 | 246 | ||
247 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 247 | <div class="col-12 col-lg-8 col-xl-9"> |
248 | 248 | ||
249 | <ng-container formGroupName="import"> | 249 | <ng-container formGroupName="import"> |
250 | 250 | ||
251 | <ng-container formGroupName="videos"> | 251 | <ng-container formGroupName="videos"> |
252 | 252 | ||
253 | <div class="form-group mt-4"> | 253 | <div class="form-group"> |
254 | <label i18n for="importConcurrency">Import jobs concurrency</label> | 254 | <label i18n for="importConcurrency">Import jobs concurrency</label> |
255 | <span i18n class="muted ml-1">allows to import multiple videos in parallel. ⚠️ Requires a PeerTube restart.</span> | 255 | <span i18n class="small muted ms-1">allows to import multiple videos in parallel. ⚠️ Requires a PeerTube restart.</span> |
256 | 256 | ||
257 | <div class="number-with-unit"> | 257 | <div class="number-with-unit"> |
258 | <input type="number" name="importConcurrency" formControlName="concurrency" /> | 258 | <input type="number" name="importConcurrency" formControlName="concurrency" /> |
@@ -268,7 +268,7 @@ | |||
268 | i18n-labelText labelText="Allow import with HTTP URL (e.g. YouTube)" | 268 | i18n-labelText labelText="Allow import with HTTP URL (e.g. YouTube)" |
269 | > | 269 | > |
270 | <ng-container ngProjectAs="description"> | 270 | <ng-container ngProjectAs="description"> |
271 | <span i18n>⚠️ If enabled, we recommend to use <a href="https://docs.joinpeertube.org/maintain-configuration?id=security">a HTTP proxy</a> to prevent private URL access from your PeerTube server</span> | 271 | <span i18n>⚠️ If enabled, we recommend to use <a class="link-orange" href="https://docs.joinpeertube.org/maintain-configuration?id=security">a HTTP proxy</a> to prevent private URL access from your PeerTube server</span> |
272 | </ng-container> | 272 | </ng-container> |
273 | </my-peertube-checkbox> | 273 | </my-peertube-checkbox> |
274 | </div> | 274 | </div> |
@@ -309,12 +309,12 @@ | |||
309 | </div> | 309 | </div> |
310 | </div> | 310 | </div> |
311 | 311 | ||
312 | <div class="form-row mt-4"> <!-- video channels grid --> | 312 | <div class="row mt-4"> <!-- video channels grid --> |
313 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 313 | <div class="col-12 col-lg-4 col-xl-3"> |
314 | <div i18n class="inner-form-title">VIDEO CHANNELS</div> | 314 | <div i18n class="inner-form-title">VIDEO CHANNELS</div> |
315 | </div> | 315 | </div> |
316 | 316 | ||
317 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 317 | <div class="col-12 col-lg-8 col-xl-9"> |
318 | <div class="form-group" formGroupName="videoChannels"> | 318 | <div class="form-group" formGroupName="videoChannels"> |
319 | <label i18n for="videoChannelsMaxPerUser">Max video channels per user</label> | 319 | <label i18n for="videoChannelsMaxPerUser">Max video channels per user</label> |
320 | 320 | ||
@@ -331,12 +331,12 @@ | |||
331 | </div> | 331 | </div> |
332 | </div> | 332 | </div> |
333 | 333 | ||
334 | <div class="form-row mt-4"> <!-- search grid --> | 334 | <div class="row mt-4"> <!-- search grid --> |
335 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 335 | <div class="col-12 col-lg-4 col-xl-3"> |
336 | <div i18n class="inner-form-title">SEARCH</div> | 336 | <div i18n class="inner-form-title">SEARCH</div> |
337 | </div> | 337 | </div> |
338 | 338 | ||
339 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 339 | <div class="col-12 col-lg-8 col-xl-9"> |
340 | 340 | ||
341 | <ng-container formGroupName="search"> | 341 | <ng-container formGroupName="search"> |
342 | <ng-container formGroupName="remoteUri"> | 342 | <ng-container formGroupName="remoteUri"> |
@@ -372,11 +372,11 @@ | |||
372 | i18n-labelText labelText="Enable global search" | 372 | i18n-labelText labelText="Enable global search" |
373 | > | 373 | > |
374 | <ng-container ngProjectAs="description"> | 374 | <ng-container ngProjectAs="description"> |
375 | <p i18n>⚠️ This functionality depends heavily on the moderation of instances followed by the search index you select.</p> | 375 | <div i18n>⚠️ This functionality depends heavily on the moderation of instances followed by the search index you select.</div> |
376 | 376 | ||
377 | <span i18n> | 377 | <div i18n> |
378 | You should only use moderated search indexes in production, or <a href="https://framagit.org/framasoft/peertube/search-index">host your own</a>. | 378 | You should only use moderated search indexes in production, or <a class="link-orange" href="https://framagit.org/framasoft/peertube/search-index">host your own</a>. |
379 | </span> | 379 | </div> |
380 | </ng-container> | 380 | </ng-container> |
381 | 381 | ||
382 | <ng-container ngProjectAs="extra"> | 382 | <ng-container ngProjectAs="extra"> |
@@ -420,15 +420,15 @@ | |||
420 | </div> | 420 | </div> |
421 | </div> | 421 | </div> |
422 | 422 | ||
423 | <div class="form-row mt-4"> <!-- federation grid --> | 423 | <div class="row mt-4"> <!-- federation grid --> |
424 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 424 | <div class="col-12 col-lg-4 col-xl-3"> |
425 | <div i18n class="inner-form-title">FEDERATION</div> | 425 | <div i18n class="inner-form-title">FEDERATION</div> |
426 | <div i18n class="inner-form-description"> | 426 | <div i18n class="inner-form-description"> |
427 | Manage <a routerLink="/admin/follows">relations</a> with other instances. | 427 | Manage <a class="link-orange" routerLink="/admin/follows">relations</a> with other instances. |
428 | </div> | 428 | </div> |
429 | </div> | 429 | </div> |
430 | 430 | ||
431 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 431 | <div class="col-12 col-lg-8 col-xl-9"> |
432 | 432 | ||
433 | <ng-container formGroupName="followers"> | 433 | <ng-container formGroupName="followers"> |
434 | <ng-container formGroupName="instance"> | 434 | <ng-container formGroupName="instance"> |
@@ -472,10 +472,10 @@ | |||
472 | i18n-labelText labelText="Automatically follow instances of a public index" | 472 | i18n-labelText labelText="Automatically follow instances of a public index" |
473 | > | 473 | > |
474 | <ng-container ngProjectAs="description"> | 474 | <ng-container ngProjectAs="description"> |
475 | <p i18n>⚠️ This functionality requires a lot of attention and extra moderation.</p> | 475 | <div i18n>⚠️ This functionality requires a lot of attention and extra moderation.</div> |
476 | 476 | ||
477 | <span i18n> | 477 | <span i18n> |
478 | See <a href="https://docs.joinpeertube.org/admin-following-instances?id=automatically-follow-other-instances" rel="noopener noreferrer" target="_blank">the documentation</a> for more information about the expected URL | 478 | See <a class="link-orange" href="https://docs.joinpeertube.org/admin-following-instances?id=automatically-follow-other-instances" rel="noopener noreferrer" target="_blank">the documentation</a> for more information about the expected URL |
479 | </span> | 479 | </span> |
480 | </ng-container> | 480 | </ng-container> |
481 | 481 | ||
@@ -499,12 +499,12 @@ | |||
499 | </div> | 499 | </div> |
500 | </div> | 500 | </div> |
501 | 501 | ||
502 | <div class="form-row mt-4"> <!-- administrators grid --> | 502 | <div class="row mt-4"> <!-- administrators grid --> |
503 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 503 | <div class="col-12 col-lg-4 col-xl-3"> |
504 | <div i18n class="inner-form-title">ADMINISTRATORS</div> | 504 | <div i18n class="inner-form-title">ADMINISTRATORS</div> |
505 | </div> | 505 | </div> |
506 | 506 | ||
507 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 507 | <div class="col-12 col-lg-8 col-xl-9"> |
508 | 508 | ||
509 | <div class="form-group" formGroupName="admin"> | 509 | <div class="form-group" formGroupName="admin"> |
510 | <label i18n for="adminEmail">Admin email</label> | 510 | <label i18n for="adminEmail">Admin email</label> |
@@ -527,8 +527,8 @@ | |||
527 | </div> | 527 | </div> |
528 | </div> | 528 | </div> |
529 | 529 | ||
530 | <div class="form-row mt-4"> <!-- Twitter grid --> | 530 | <div class="row mt-4"> <!-- Twitter grid --> |
531 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 531 | <div class="col-12 col-lg-4 col-xl-3"> |
532 | <div i18n class="inner-form-title">TWITTER</div> | 532 | <div i18n class="inner-form-title">TWITTER</div> |
533 | <div i18n class="inner-form-description"> | 533 | <div i18n class="inner-form-description"> |
534 | Provide the Twitter account representing your instance to improve link previews. | 534 | Provide the Twitter account representing your instance to improve link previews. |
@@ -536,7 +536,7 @@ | |||
536 | </div> | 536 | </div> |
537 | </div> | 537 | </div> |
538 | 538 | ||
539 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 539 | <div class="col-12 col-lg-8 col-xl-9"> |
540 | 540 | ||
541 | <ng-container formGroupName="services"> | 541 | <ng-container formGroupName="services"> |
542 | <ng-container formGroupName="twitter"> | 542 | <ng-container formGroupName="twitter"> |
@@ -563,7 +563,7 @@ | |||
563 | If your instance is explicitly allowed by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> | 563 | If your instance is explicitly allowed by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> |
564 | If the instance is not, we use an image link card that will redirect to your PeerTube instance.<br /><br /> | 564 | If the instance is not, we use an image link card that will redirect to your PeerTube instance.<br /><br /> |
565 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/w/blabla) on | 565 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/w/blabla) on |
566 | <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> | 566 | <a class="link-orange" target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> |
567 | to see if you instance is allowed. | 567 | to see if you instance is allowed. |
568 | </ng-container> | 568 | </ng-container> |
569 | </ng-template> | 569 | </ng-template> |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts b/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts index 9b55cb43c..96f5b830e 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { Injectable } from '@angular/core' | 1 | import { Injectable } from '@angular/core' |
2 | import { FormGroup } from '@angular/forms' | 2 | import { FormGroup } from '@angular/forms' |
3 | import { prepareIcu } from '@app/helpers' | ||
3 | 4 | ||
4 | export type ResolutionOption = { | 5 | export type ResolutionOption = { |
5 | id: string | 6 | id: string |
@@ -86,9 +87,10 @@ export class EditConfigurationService { | |||
86 | return { | 87 | return { |
87 | value, | 88 | value, |
88 | atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible | 89 | atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible |
89 | unit: value > 1 | 90 | unit: prepareIcu($localize`{value, plural, =1 {thread} other {threads}}`)( |
90 | ? $localize`threads` | 91 | { value }, |
91 | : $localize`thread` | 92 | $localize`threads` |
93 | ) | ||
92 | } | 94 | } |
93 | } | 95 | } |
94 | } | 96 | } |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html index 8fef39b79..cc8e699f3 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html | |||
@@ -1,4 +1,4 @@ | |||
1 | <h1 class="sr-only" i18n>Configuration</h1> | 1 | <h1 class="visually-hidden" i18n>Configuration</h1> |
2 | 2 | ||
3 | <div class="alert alert-warning" *ngIf="!isUpdateAllowed()" i18n> | 3 | <div class="alert alert-warning" *ngIf="!isUpdateAllowed()" i18n> |
4 | Updating instance configuration from the web interface is disabled by the system administrator. | 4 | Updating instance configuration from the web interface is disabled by the system administrator. |
@@ -64,7 +64,7 @@ | |||
64 | 64 | ||
65 | <div [ngbNavOutlet]="nav"></div> | 65 | <div [ngbNavOutlet]="nav"></div> |
66 | 66 | ||
67 | <div class="form-row mt-4"> <!-- submit placement block --> | 67 | <div class="row mt-4"> <!-- submit placement block --> |
68 | <div class="col-md-7 col-xl-5"></div> | 68 | <div class="col-md-7 col-xl-5"></div> |
69 | <div class="col-md-5 col-xl-5"> | 69 | <div class="col-md-5 col-xl-5"> |
70 | 70 | ||
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss index 0458d257f..f3bce8ee0 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss | |||
@@ -3,11 +3,6 @@ | |||
3 | 3 | ||
4 | $form-base-input-width: 340px; | 4 | $form-base-input-width: 340px; |
5 | 5 | ||
6 | label { | ||
7 | font-weight: $font-regular; | ||
8 | font-size: 100%; | ||
9 | } | ||
10 | |||
11 | form { | 6 | form { |
12 | padding-bottom: 1.5rem; | 7 | padding-bottom: 1.5rem; |
13 | } | 8 | } |
@@ -30,7 +25,7 @@ input[type=number] { | |||
30 | 25 | ||
31 | input[type=number] + span { | 26 | input[type=number] + span { |
32 | position: absolute; | 27 | position: absolute; |
33 | top: 5px; | 28 | top: 0.2em; |
34 | right: 2.5rem; | 29 | right: 2.5rem; |
35 | } | 30 | } |
36 | 31 | ||
@@ -74,6 +69,10 @@ input[type=submit] { | |||
74 | @include settings-big-title; | 69 | @include settings-big-title; |
75 | } | 70 | } |
76 | 71 | ||
72 | .inner-form-description { | ||
73 | font-size: 15px; | ||
74 | } | ||
75 | |||
77 | textarea { | 76 | textarea { |
78 | @include peertube-textarea(500px, 150px); | 77 | @include peertube-textarea(500px, 150px); |
79 | 78 | ||
@@ -88,6 +87,7 @@ textarea { | |||
88 | .label-small-info { | 87 | .label-small-info { |
89 | font-style: italic; | 88 | font-style: italic; |
90 | margin-bottom: 10px; | 89 | margin-bottom: 10px; |
90 | font-size: 14px; | ||
91 | } | 91 | } |
92 | 92 | ||
93 | .disabled-checkbox-extra { | 93 | .disabled-checkbox-extra { |
@@ -102,11 +102,6 @@ input[disabled] { | |||
102 | opacity: 0.5; | 102 | opacity: 0.5; |
103 | } | 103 | } |
104 | 104 | ||
105 | |||
106 | .form-group-right { | ||
107 | padding-top: 2px; | ||
108 | } | ||
109 | |||
110 | ngb-tabset:not(.previews) ::ng-deep { | 105 | ngb-tabset:not(.previews) ::ng-deep { |
111 | .nav-link { | 106 | .nav-link { |
112 | font-size: 105%; | 107 | font-size: 105%; |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-homepage.component.html b/client/src/app/+admin/config/edit-custom-config/edit-homepage.component.html index 2286a5a1a..701c3c0c1 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-homepage.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-homepage.component.html | |||
@@ -2,12 +2,12 @@ | |||
2 | 2 | ||
3 | <ng-container formGroupName="instanceCustomHomepage"> | 3 | <ng-container formGroupName="instanceCustomHomepage"> |
4 | 4 | ||
5 | <div class="form-row mt-5"> <!-- homepage grid --> | 5 | <div class="row mt-5"> <!-- homepage grid --> |
6 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 6 | <div class="col-12 col-lg-4 col-xl-3"> |
7 | <div i18n class="inner-form-title">INSTANCE HOMEPAGE</div> | 7 | <div i18n class="inner-form-title">INSTANCE HOMEPAGE</div> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 10 | <div class="col-12 col-lg-8 col-xl-9"> |
11 | 11 | ||
12 | <div class="form-group"> | 12 | <div class="form-group"> |
13 | <label i18n for="instanceCustomHomepageContent">Homepage</label> | 13 | <label i18n for="instanceCustomHomepageContent">Homepage</label> |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html b/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html index d806616bd..5931cb459 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html | |||
@@ -2,13 +2,12 @@ | |||
2 | 2 | ||
3 | <ng-container formGroupName="instance"> | 3 | <ng-container formGroupName="instance"> |
4 | 4 | ||
5 | <div class="form-row mt-5"> <!-- instance grid --> | 5 | <div class="row mt-5"> <!-- instance grid --> |
6 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 6 | <div class="col-12 col-lg-4 col-xl-3"> |
7 | <div i18n class="inner-form-title">INSTANCE</div> | 7 | <div i18n class="inner-form-title">INSTANCE</div> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 10 | <div class="col-12 col-lg-8 col-xl-9"> |
11 | |||
12 | <div class="form-group"> | 11 | <div class="form-group"> |
13 | <label i18n for="instanceName">Name</label> | 12 | <label i18n for="instanceName">Name</label> |
14 | 13 | ||
@@ -77,16 +76,15 @@ | |||
77 | </div> | 76 | </div> |
78 | </div> | 77 | </div> |
79 | 78 | ||
80 | <div class="form-row mt-4"> <!-- moderation & nsfw grid --> | 79 | <div class="row mt-4"> <!-- moderation & nsfw grid --> |
81 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 80 | <div class="col-12 col-lg-4 col-xl-3"> |
82 | <div i18n class="inner-form-title">MODERATION & NSFW</div> | 81 | <div i18n class="inner-form-title">MODERATION & NSFW</div> |
83 | <div i18n class="inner-for-description"> | 82 | <div i18row="inner-form-description"> |
84 | Manage <a routerLink="/admin/users">users</a> to build a moderation team. | 83 | Manage <a class="link-orange" routerLink="/admin/users">users</a> to build a moderation team. |
85 | </div> | 84 | </div> |
86 | </div> | 85 | </div> |
87 | 86 | ||
88 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 87 | <div class="col-12 col-lg-8 col-xl-9"> |
89 | |||
90 | <div class="form-group"> | 88 | <div class="form-group"> |
91 | <my-peertube-checkbox inputName="instanceIsNSFW" formControlName="isNSFW"> | 89 | <my-peertube-checkbox inputName="instanceIsNSFW" formControlName="isNSFW"> |
92 | <ng-template ptTemplate="label"> | 90 | <ng-template ptTemplate="label"> |
@@ -162,12 +160,12 @@ | |||
162 | </div> | 160 | </div> |
163 | </div> | 161 | </div> |
164 | 162 | ||
165 | <div class="form-row mt-4"> <!-- you and your instance grid --> | 163 | <div class="row mt-4"> <!-- you and your instance grid --> |
166 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 164 | <div class="col-12 col-lg-4 col-xl-3"> |
167 | <div i18n class="inner-form-title">YOU AND YOUR INSTANCE</div> | 165 | <div i18n class="inner-form-title">YOU AND YOUR INSTANCE</div> |
168 | </div> | 166 | </div> |
169 | 167 | ||
170 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 168 | <div class="col-12 col-lg-8 col-xl-9"> |
171 | 169 | ||
172 | <div class="form-group"> | 170 | <div class="form-group"> |
173 | <label i18n for="instanceAdministrator">Who is behind the instance?</label><my-help helpType="markdownText"></my-help> | 171 | <label i18n for="instanceAdministrator">Who is behind the instance?</label><my-help helpType="markdownText"></my-help> |
@@ -220,12 +218,12 @@ | |||
220 | </div> | 218 | </div> |
221 | </div> | 219 | </div> |
222 | 220 | ||
223 | <div class="form-row mt-4"> <!-- other information grid --> | 221 | <div class="row mt-4"> <!-- other information grid --> |
224 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 222 | <div class="col-12 col-lg-4 col-xl-3"> |
225 | <div i18n class="inner-form-title">OTHER INFORMATION</div> | 223 | <div i18n class="inner-form-title">OTHER INFORMATION</div> |
226 | </div> | 224 | </div> |
227 | 225 | ||
228 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 226 | <div class="col-12 col-lg-8 col-xl-9"> |
229 | 227 | ||
230 | <div class="form-group"> | 228 | <div class="form-group"> |
231 | <label i18n for="instanceHardwareInformation">What server/hardware does the instance run on?</label> | 229 | <label i18n for="instanceHardwareInformation">What server/hardware does the instance run on?</label> |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-live-configuration.component.html b/client/src/app/+admin/config/edit-custom-config/edit-live-configuration.component.html index 71d5d91f0..ae79e54fc 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-live-configuration.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-live-configuration.component.html | |||
@@ -1,14 +1,14 @@ | |||
1 | <ng-container [formGroup]="form"> | 1 | <ng-container [formGroup]="form"> |
2 | 2 | ||
3 | <div class="form-row mt-5"> | 3 | <div class="row mt-5"> |
4 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 4 | <div class="col-12 col-lg-4 col-xl-3"> |
5 | <div i18n class="inner-form-title">LIVE</div> | 5 | <div i18n class="inner-form-title">LIVE</div> |
6 | <div i18n class="inner-form-description"> | 6 | <div i18n class="inner-form-description"> |
7 | Enable users of your instance to stream live. | 7 | Enable users of your instance to stream live. |
8 | </div> | 8 | </div> |
9 | </div> | 9 | </div> |
10 | 10 | ||
11 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 11 | <div class="col-12 col-lg-8 col-xl-9"> |
12 | 12 | ||
13 | <ng-container formGroupName="live"> | 13 | <ng-container formGroupName="live"> |
14 | 14 | ||
@@ -46,9 +46,9 @@ | |||
46 | </div> | 46 | </div> |
47 | 47 | ||
48 | <div class="form-group" [ngClass]="getDisabledLiveClass()"> | 48 | <div class="form-group" [ngClass]="getDisabledLiveClass()"> |
49 | <label i18n for="liveMaxInstanceLives"> | 49 | <label i18n for="liveMaxInstanceLives">Max simultaneous lives created on your instance</label> |
50 | Max simultaneous lives created on your instance <span class="muted">(-1 for "unlimited")</span> | 50 | |
51 | </label> | 51 | <span class="ms-2 small muted">(-1 for "unlimited")</span> |
52 | 52 | ||
53 | <div class="number-with-unit"> | 53 | <div class="number-with-unit"> |
54 | <input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" /> | 54 | <input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" /> |
@@ -59,9 +59,8 @@ | |||
59 | </div> | 59 | </div> |
60 | 60 | ||
61 | <div class="form-group" [ngClass]="getDisabledLiveClass()"> | 61 | <div class="form-group" [ngClass]="getDisabledLiveClass()"> |
62 | <label i18n for="liveMaxUserLives"> | 62 | <label i18n for="liveMaxUserLives">Max simultaneous lives created per user</label> |
63 | Max simultaneous lives created per user <span class="muted">(-1 for "unlimited")</span> | 63 | <span class="ms-2 small muted">(-1 for "unlimited")</span> |
64 | </label> | ||
65 | 64 | ||
66 | <div class="number-with-unit"> | 65 | <div class="number-with-unit"> |
67 | <input type="number" name="liveMaxUserLives" formControlName="maxUserLives" /> | 66 | <input type="number" name="liveMaxUserLives" formControlName="maxUserLives" /> |
@@ -89,15 +88,15 @@ | |||
89 | </div> | 88 | </div> |
90 | </div> | 89 | </div> |
91 | 90 | ||
92 | <div class="form-row"> <!-- transcoding live streams grid --> | 91 | <div class="row"> <!-- transcoding live streams grid --> |
93 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 92 | <div class="col-12 col-lg-4 col-xl-3"> |
94 | <div i18n class="inner-form-title">TRANSCODING</div> | 93 | <div i18n class="inner-form-title">TRANSCODING</div> |
95 | <div i18n class="inner-form-description"> | 94 | <div i18n class="inner-form-description"> |
96 | Same as VOD transcoding, transcoding live streams so that they are in a streamable form that any device can play. Requires a beefy CPU, and then some. | 95 | Same as VOD transcoding, transcoding live streams so that they are in a streamable form that any device can play. Requires a beefy CPU, and then some. |
97 | </div> | 96 | </div> |
98 | </div> | 97 | </div> |
99 | 98 | ||
100 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 99 | <div class="col-12 col-lg-8 col-xl-9"> |
101 | 100 | ||
102 | <ng-container formGroupName="live"> | 101 | <ng-container formGroupName="live"> |
103 | <ng-container formGroupName="transcoding"> | 102 | <ng-container formGroupName="transcoding"> |
@@ -115,7 +114,7 @@ | |||
115 | <div class="form-group" [ngClass]="getDisabledLiveTranscodingClass()"> | 114 | <div class="form-group" [ngClass]="getDisabledLiveTranscodingClass()"> |
116 | <label i18n for="liveTranscodingThreads">Live resolutions to generate</label> | 115 | <label i18n for="liveTranscodingThreads">Live resolutions to generate</label> |
117 | 116 | ||
118 | <div class="ml-2 mt-2 d-flex flex-column"> | 117 | <div class="ms-2 mt-2 d-flex flex-column"> |
119 | <ng-container formGroupName="resolutions"> | 118 | <ng-container formGroupName="resolutions"> |
120 | 119 | ||
121 | <div class="form-group" *ngFor="let resolution of liveResolutions"> | 120 | <div class="form-group" *ngFor="let resolution of liveResolutions"> |
@@ -136,7 +135,7 @@ | |||
136 | <div class="form-group" [ngClass]="getDisabledLiveTranscodingClass()"> | 135 | <div class="form-group" [ngClass]="getDisabledLiveTranscodingClass()"> |
137 | <label i18n for="liveTranscodingThreads">Live transcoding threads</label> | 136 | <label i18n for="liveTranscodingThreads">Live transcoding threads</label> |
138 | 137 | ||
139 | <span class="muted ml-1"> | 138 | <span class="small muted ms-1"> |
140 | <ng-container *ngIf="getTotalTranscodingThreads().atMost" i18n> | 139 | <ng-container *ngIf="getTotalTranscodingThreads().atMost" i18n> |
141 | will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with VOD transcoding | 140 | will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with VOD transcoding |
142 | </ng-container> | 141 | </ng-container> |
@@ -157,7 +156,7 @@ | |||
157 | 156 | ||
158 | <div class="form-group mt-4" [ngClass]="getDisabledLiveTranscodingClass()"> | 157 | <div class="form-group mt-4" [ngClass]="getDisabledLiveTranscodingClass()"> |
159 | <label i18n for="liveTranscodingProfile">Live transcoding profile</label> | 158 | <label i18n for="liveTranscodingProfile">Live transcoding profile</label> |
160 | <span class="muted ml-1" i18n>new live transcoding profiles can be added by PeerTube plugins</span> | 159 | <span class="small muted ms-1" i18n>new live transcoding profiles can be added by PeerTube plugins</span> |
161 | 160 | ||
162 | <my-select-options | 161 | <my-select-options |
163 | id="liveTranscodingProfile" | 162 | id="liveTranscodingProfile" |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-vod-transcoding.component.html b/client/src/app/+admin/config/edit-custom-config/edit-vod-transcoding.component.html index 5c0bea4a5..66e421b16 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-vod-transcoding.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-vod-transcoding.component.html | |||
@@ -1,28 +1,23 @@ | |||
1 | <ng-container [formGroup]="form"> | 1 | <ng-container [formGroup]="form"> |
2 | 2 | ||
3 | <div class="form-row mt-4"> <!-- transcoding grid --> | 3 | <div class="row mt-4"> <!-- transcoding grid --> |
4 | <div class="form-group col-12 col-lg-4 col-xl-3"></div> | 4 | <div class="col-12 col-lg-4 col-xl-3"></div> |
5 | <div class="form-group form-group-right col-12 col-lg-8"> | 5 | <div class="col-12 col-lg-8"> |
6 | 6 | ||
7 | <div class="callout callout-info"> | 7 | <div class="callout callout-orange"> |
8 | <span i18n> | 8 | <span i18n> |
9 | Estimating a server's capacity to transcode and stream videos isn't easy and we can't tune PeerTube automatically. | 9 | Estimating a server's capacity to transcode and stream videos isn't easy and we can't tune PeerTube automatically. |
10 | </span> | 10 | </span> |
11 | |||
11 | <span i18n> | 12 | <span i18n> |
12 | However, you may want to read our guidelines before tweaking the following values. | 13 | However, you may want to read <a class="link-orange" target="_blank" rel="noopener noreferrer" href="https://docs.joinpeertube.org/admin-configuration?id=transcoding">our guidelines</a> before tweaking the following values. |
13 | </span> | 14 | </span> |
14 | |||
15 | <div class="callout-container"> | ||
16 | <a class="callout-link" target="_blank" rel="noopener noreferrer" href="https://docs.joinpeertube.org/admin-configuration?id=transcoding" i18n> | ||
17 | Read guidelines | ||
18 | </a> | ||
19 | </div> | ||
20 | </div> | 15 | </div> |
21 | </div> | 16 | </div> |
22 | </div> | 17 | </div> |
23 | 18 | ||
24 | <div class="form-row mt-2"> <!-- transcoding grid --> | 19 | <div class="row mt-4"> <!-- transcoding grid --> |
25 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 20 | <div class="col-12 col-lg-4 col-xl-3"> |
26 | <div i18n class="inner-form-title">TRANSCODING</div> | 21 | <div i18n class="inner-form-title">TRANSCODING</div> |
27 | <div i18n class="inner-form-description"> | 22 | <div i18n class="inner-form-description"> |
28 | Process uploaded videos so that they are in a streamable form that any device can play. Though costly in | 23 | Process uploaded videos so that they are in a streamable form that any device can play. Though costly in |
@@ -30,11 +25,11 @@ | |||
30 | </div> | 25 | </div> |
31 | </div> | 26 | </div> |
32 | 27 | ||
33 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 28 | <div class="col-12 col-lg-8 col-xl-9"> |
34 | 29 | ||
35 | <ng-container formGroupName="transcoding"> | 30 | <ng-container formGroupName="transcoding"> |
36 | 31 | ||
37 | <div class="form-group mb-0 col-12 col-xl-11"> | 32 | <div class="col-12 col-xl-11"> |
38 | <my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled" [recommended]="true"> | 33 | <my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled" [recommended]="true"> |
39 | <ng-template ptTemplate="label"> | 34 | <ng-template ptTemplate="label"> |
40 | <ng-container i18n>Transcoding enabled</ng-container> | 35 | <ng-container i18n>Transcoding enabled</ng-container> |
@@ -115,7 +110,11 @@ | |||
115 | <div class="form-group" [ngClass]="getTranscodingDisabledClass()"> | 110 | <div class="form-group" [ngClass]="getTranscodingDisabledClass()"> |
116 | <label i18n>Resolutions to generate per enabled format</label> | 111 | <label i18n>Resolutions to generate per enabled format</label> |
117 | 112 | ||
118 | <div class="ml-2 mt-2 d-flex flex-column"> | 113 | <div class="ms-2 d-flex flex-column"> |
114 | <span class="mb-3 small muted" i18n> | ||
115 | The original file resolution will be the default target if no option is selected. | ||
116 | </span> | ||
117 | |||
119 | <ng-container formGroupName="resolutions"> | 118 | <ng-container formGroupName="resolutions"> |
120 | <div class="form-group" *ngFor="let resolution of resolutions"> | 119 | <div class="form-group" *ngFor="let resolution of resolutions"> |
121 | <my-peertube-checkbox | 120 | <my-peertube-checkbox |
@@ -127,10 +126,6 @@ | |||
127 | </ng-template> | 126 | </ng-template> |
128 | </my-peertube-checkbox> | 127 | </my-peertube-checkbox> |
129 | </div> | 128 | </div> |
130 | |||
131 | <span class="mb-2 muted" i18n> | ||
132 | The original file resolution will be the default target if no option is selected. | ||
133 | </span> | ||
134 | </ng-container> | 129 | </ng-container> |
135 | </div> | 130 | </div> |
136 | </div> | 131 | </div> |
@@ -142,7 +137,8 @@ | |||
142 | 137 | ||
143 | <div class="form-group mt-4" [ngClass]="getTranscodingDisabledClass()"> | 138 | <div class="form-group mt-4" [ngClass]="getTranscodingDisabledClass()"> |
144 | <label i18n for="transcodingThreads">Transcoding threads</label> | 139 | <label i18n for="transcodingThreads">Transcoding threads</label> |
145 | <span class="muted ml-1"> | 140 | |
141 | <span class="small muted ms-1"> | ||
146 | <ng-container *ngIf="getTotalTranscodingThreads().atMost" i18n> | 142 | <ng-container *ngIf="getTotalTranscodingThreads().atMost" i18n> |
147 | will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with live transcoding | 143 | will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with live transcoding |
148 | </ng-container> | 144 | </ng-container> |
@@ -162,9 +158,9 @@ | |||
162 | <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div> | 158 | <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div> |
163 | </div> | 159 | </div> |
164 | 160 | ||
165 | <div class="form-group mt-4" [ngClass]="getTranscodingDisabledClass()"> | 161 | <div class="form-group" [ngClass]="getTranscodingDisabledClass()"> |
166 | <label i18n for="transcodingConcurrency">Transcoding jobs concurrency</label> | 162 | <label i18n for="transcodingConcurrency">Transcoding jobs concurrency</label> |
167 | <span class="muted ml-1" i18n>allows to transcode multiple files in parallel. ⚠️ Requires a PeerTube restart</span> | 163 | <span class="small muted ms-1" i18n>allows to transcode multiple files in parallel. ⚠️ Requires a PeerTube restart</span> |
168 | 164 | ||
169 | <div class="number-with-unit"> | 165 | <div class="number-with-unit"> |
170 | <input type="number" name="transcodingConcurrency" formControlName="concurrency" /> | 166 | <input type="number" name="transcodingConcurrency" formControlName="concurrency" /> |
@@ -174,9 +170,9 @@ | |||
174 | <div *ngIf="formErrors.transcoding.concurrency" class="form-error">{{ formErrors.transcoding.concurrency }}</div> | 170 | <div *ngIf="formErrors.transcoding.concurrency" class="form-error">{{ formErrors.transcoding.concurrency }}</div> |
175 | </div> | 171 | </div> |
176 | 172 | ||
177 | <div class="form-group mt-4" [ngClass]="getTranscodingDisabledClass()"> | 173 | <div class="form-group" [ngClass]="getTranscodingDisabledClass()"> |
178 | <label i18n for="transcodingProfile">Transcoding profile</label> | 174 | <label i18n for="transcodingProfile">Transcoding profile</label> |
179 | <span class="muted ml-1" i18n>new transcoding profiles can be added by PeerTube plugins</span> | 175 | <span class="small muted ms-1" i18n>new transcoding profiles can be added by PeerTube plugins</span> |
180 | 176 | ||
181 | <my-select-options | 177 | <my-select-options |
182 | id="transcodingProfile" | 178 | id="transcodingProfile" |
@@ -193,15 +189,15 @@ | |||
193 | </div> | 189 | </div> |
194 | </div> | 190 | </div> |
195 | 191 | ||
196 | <div class="form-row mt-2"> <!-- video studio grid --> | 192 | <div class="row mt-2"> <!-- video studio grid --> |
197 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 193 | <div class="col-12 col-lg-4 col-xl-3"> |
198 | <div i18n class="inner-form-title">VIDEO STUDIO</div> | 194 | <div i18n class="inner-form-title">VIDEO STUDIO</div> |
199 | <div i18n class="inner-form-description"> | 195 | <div i18n class="inner-form-description"> |
200 | Allows your users to edit their video (cut, add intro/outro, add a watermark etc) | 196 | Allows your users to edit their video (cut, add intro/outro, add a watermark etc) |
201 | </div> | 197 | </div> |
202 | </div> | 198 | </div> |
203 | 199 | ||
204 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | 200 | <div class="col-12 col-lg-8 col-xl-9"> |
205 | 201 | ||
206 | <ng-container formGroupName="videoStudio"> | 202 | <ng-container formGroupName="videoStudio"> |
207 | <div class="form-group" [ngClass]="getTranscodingDisabledClass()"> | 203 | <div class="form-group" [ngClass]="getTranscodingDisabledClass()"> |
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html index 1df7bb164..5367bf517 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.html +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html | |||
@@ -12,7 +12,7 @@ | |||
12 | > | 12 | > |
13 | <ng-template pTemplate="caption"> | 13 | <ng-template pTemplate="caption"> |
14 | <div class="caption"> | 14 | <div class="caption"> |
15 | <div class="ml-auto"> | 15 | <div class="ms-auto"> |
16 | <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter> | 16 | <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter> |
17 | </div> | 17 | </div> |
18 | </div> | 18 | </div> |
@@ -41,15 +41,15 @@ | |||
41 | <td> | 41 | <td> |
42 | <a [href]="follow.follower.url" i18n-title title="Open actor page in a new tab" target="_blank" rel="noopener noreferrer"> | 42 | <a [href]="follow.follower.url" i18n-title title="Open actor page in a new tab" target="_blank" rel="noopener noreferrer"> |
43 | {{ follow.follower.name + '@' + follow.follower.host }} | 43 | {{ follow.follower.name + '@' + follow.follower.host }} |
44 | <span class="glyphicon glyphicon-new-window"></span> | 44 | <my-global-icon iconName="external-link"></my-global-icon> |
45 | </a> | 45 | </a> |
46 | </td> | 46 | </td> |
47 | 47 | ||
48 | <td *ngIf="follow.state === 'accepted'"> | 48 | <td *ngIf="follow.state === 'accepted'"> |
49 | <span class="badge badge-green" i18n>Accepted</span> | 49 | <span class="pt-badge badge-green" i18n>Accepted</span> |
50 | </td> | 50 | </td> |
51 | <td *ngIf="follow.state === 'pending'"> | 51 | <td *ngIf="follow.state === 'pending'"> |
52 | <span class="badge badge-yellow" i18n>Pending</span> | 52 | <span class="pt-badge badge-yellow" i18n>Pending</span> |
53 | </td> | 53 | </td> |
54 | 54 | ||
55 | <td>{{ follow.score }}</td> | 55 | <td>{{ follow.score }}</td> |
@@ -59,7 +59,7 @@ | |||
59 | 59 | ||
60 | <ng-template pTemplate="emptymessage"> | 60 | <ng-template pTemplate="emptymessage"> |
61 | <tr> | 61 | <tr> |
62 | <td colspan="6"> | 62 | <td colspan="5"> |
63 | <div class="no-results"> | 63 | <div class="no-results"> |
64 | <ng-container *ngIf="search" i18n>No follower found matching current filters.</ng-container> | 64 | <ng-container *ngIf="search" i18n>No follower found matching current filters.</ng-container> |
65 | <ng-container *ngIf="!search" i18n>Your instance doesn't have any follower.</ng-container> | 65 | <ng-container *ngIf="!search" i18n>Your instance doesn't have any follower.</ng-container> |
diff --git a/client/src/app/+admin/follows/following-list/follow-modal.component.ts b/client/src/app/+admin/follows/following-list/follow-modal.component.ts index c40b36e10..bac7b2b01 100644 --- a/client/src/app/+admin/follows/following-list/follow-modal.component.ts +++ b/client/src/app/+admin/follows/following-list/follow-modal.component.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' | 1 | import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' |
2 | import { Notifier } from '@app/core' | 2 | import { Notifier } from '@app/core' |
3 | import { prepareIcu } from '@app/helpers' | ||
3 | import { splitAndGetNotEmpty, UNIQUE_HOSTS_OR_HANDLE_VALIDATOR } from '@app/shared/form-validators/host-validators' | 4 | import { splitAndGetNotEmpty, UNIQUE_HOSTS_OR_HANDLE_VALIDATOR } from '@app/shared/form-validators/host-validators' |
4 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 5 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' |
5 | import { InstanceFollowService } from '@app/shared/shared-instance' | 6 | import { InstanceFollowService } from '@app/shared/shared-instance' |
@@ -60,7 +61,13 @@ export class FollowModalComponent extends FormReactive implements OnInit { | |||
60 | this.followService.follow(hostsOrHandles) | 61 | this.followService.follow(hostsOrHandles) |
61 | .subscribe({ | 62 | .subscribe({ |
62 | next: () => { | 63 | next: () => { |
63 | this.notifier.success($localize`Follow request(s) sent!`) | 64 | this.notifier.success( |
65 | prepareIcu($localize`{count, plural, =1 {Follow request} other {Follow requests}} sent!`)( | ||
66 | { count: hostsOrHandles.length }, | ||
67 | $localize`Follow request(s) sent!` | ||
68 | ) | ||
69 | ) | ||
70 | |||
64 | this.newFollow.emit() | 71 | this.newFollow.emit() |
65 | }, | 72 | }, |
66 | 73 | ||
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html index 767e92d18..106e1805e 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.html +++ b/client/src/app/+admin/follows/following-list/following-list.component.html | |||
@@ -19,7 +19,7 @@ | |||
19 | </a> | 19 | </a> |
20 | </div> | 20 | </div> |
21 | 21 | ||
22 | <div class="ml-auto"> | 22 | <div class="ms-auto"> |
23 | <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter> | 23 | <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter> |
24 | </div> | 24 | </div> |
25 | </div> | 25 | </div> |
@@ -43,15 +43,15 @@ | |||
43 | <td> | 43 | <td> |
44 | <a [href]="follow.following.url" i18n-title title="Open instance in a new tab" target="_blank" rel="noopener noreferrer"> | 44 | <a [href]="follow.following.url" i18n-title title="Open instance in a new tab" target="_blank" rel="noopener noreferrer"> |
45 | {{ follow.following.name + '@' + follow.following.host }} | 45 | {{ follow.following.name + '@' + follow.following.host }} |
46 | <span class="glyphicon glyphicon-new-window"></span> | 46 | <my-global-icon iconName="external-link"></my-global-icon> |
47 | </a> | 47 | </a> |
48 | </td> | 48 | </td> |
49 | 49 | ||
50 | <td *ngIf="follow.state === 'accepted'"> | 50 | <td *ngIf="follow.state === 'accepted'"> |
51 | <span class="badge badge-green" i18n>Accepted</span> | 51 | <span class="pt-badge badge-green" i18n>Accepted</span> |
52 | </td> | 52 | </td> |
53 | <td *ngIf="follow.state === 'pending'"> | 53 | <td *ngIf="follow.state === 'pending'"> |
54 | <span class="badge badge-yellow" i18n>Pending</span> | 54 | <span class="pt-badge badge-yellow" i18n>Pending</span> |
55 | </td> | 55 | </td> |
56 | 56 | ||
57 | <td>{{ follow.createdAt | date: 'short' }}</td> | 57 | <td>{{ follow.createdAt | date: 'short' }}</td> |
diff --git a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html index f13a0c378..12b07da11 100644 --- a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html +++ b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html | |||
@@ -46,7 +46,7 @@ | |||
46 | <td> | 46 | <td> |
47 | <a [href]="redundancy.url" i18n-title title="Open video in a new tab" target="_blank" rel="noopener noreferrer"> | 47 | <a [href]="redundancy.url" i18n-title title="Open video in a new tab" target="_blank" rel="noopener noreferrer"> |
48 | {{ redundancy.name }} | 48 | {{ redundancy.name }} |
49 | <span class="glyphicon glyphicon-new-window"></span> | 49 | <my-global-icon iconName="external-link"></my-global-icon> |
50 | </a> | 50 | </a> |
51 | </td> | 51 | </td> |
52 | 52 | ||
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html index 3634951c9..b302014b6 100644 --- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html +++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html | |||
@@ -13,7 +13,7 @@ | |||
13 | > | 13 | > |
14 | <ng-template pTemplate="caption"> | 14 | <ng-template pTemplate="caption"> |
15 | <div class="caption"> | 15 | <div class="caption"> |
16 | <div class="ml-auto"> | 16 | <div class="ms-auto"> |
17 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> | 17 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> |
18 | </div> | 18 | </div> |
19 | </div> | 19 | </div> |
@@ -53,11 +53,11 @@ | |||
53 | </td> | 53 | </td> |
54 | 54 | ||
55 | <td> | 55 | <td> |
56 | <span *ngIf="videoBlock.video.nsfw" class="badge badge-red" i18n>NSFW</span> | 56 | <span *ngIf="videoBlock.video.nsfw" class="pt-badge badge-red" i18n>NSFW</span> |
57 | </td> | 57 | </td> |
58 | 58 | ||
59 | <td> | 59 | <td> |
60 | <span *ngIf="videoBlock.unfederated" class="badge badge-blue" i18n>Unfederated</span> | 60 | <span *ngIf="videoBlock.unfederated" class="pt-badge badge-blue" i18n>Unfederated</span> |
61 | </td> | 61 | </td> |
62 | 62 | ||
63 | <td> | 63 | <td> |
diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.html b/client/src/app/+admin/overview/comments/video-comment-list.component.html index 27a5d82ff..6fdefbfe2 100644 --- a/client/src/app/+admin/overview/comments/video-comment-list.component.html +++ b/client/src/app/+admin/overview/comments/video-comment-list.component.html | |||
@@ -25,7 +25,7 @@ | |||
25 | </my-action-dropdown> | 25 | </my-action-dropdown> |
26 | </div> | 26 | </div> |
27 | 27 | ||
28 | <div class="ml-auto right-form"> | 28 | <div class="ms-auto right-form"> |
29 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> | 29 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> |
30 | 30 | ||
31 | <my-button i18n-label label="Refresh" icon="refresh" (click)="reloadData()"></my-button> | 31 | <my-button i18n-label label="Refresh" icon="refresh" (click)="reloadData()"></my-button> |
diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.ts b/client/src/app/+admin/overview/comments/video-comment-list.component.ts index f3f43a900..f1b27d846 100644 --- a/client/src/app/+admin/overview/comments/video-comment-list.component.ts +++ b/client/src/app/+admin/overview/comments/video-comment-list.component.ts | |||
@@ -7,6 +7,7 @@ import { DropdownAction } from '@app/shared/shared-main' | |||
7 | import { BulkService } from '@app/shared/shared-moderation' | 7 | import { BulkService } from '@app/shared/shared-moderation' |
8 | import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment' | 8 | import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment' |
9 | import { FeedFormat, UserRight } from '@shared/models' | 9 | import { FeedFormat, UserRight } from '@shared/models' |
10 | import { prepareIcu } from '@app/helpers' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | selector: 'my-video-comment-list', | 13 | selector: 'my-video-comment-list', |
@@ -145,7 +146,13 @@ export class VideoCommentListComponent extends RestTable implements OnInit { | |||
145 | this.videoCommentService.deleteVideoComments(commentArgs) | 146 | this.videoCommentService.deleteVideoComments(commentArgs) |
146 | .subscribe({ | 147 | .subscribe({ |
147 | next: () => { | 148 | next: () => { |
148 | this.notifier.success($localize`${commentArgs.length} comments deleted.`) | 149 | this.notifier.success( |
150 | prepareIcu($localize`{count, plural, =1 {1 comment} other {{count} comments}} deleted.`)( | ||
151 | { count: commentArgs.length }, | ||
152 | $localize`${commentArgs.length} comment(s) deleted.` | ||
153 | ) | ||
154 | ) | ||
155 | |||
149 | this.reloadData() | 156 | this.reloadData() |
150 | }, | 157 | }, |
151 | 158 | ||
diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.component.html b/client/src/app/+admin/overview/users/user-edit/user-edit.component.html index 772ebf272..bfa414164 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.component.html | |||
@@ -57,7 +57,7 @@ | |||
57 | </div> | 57 | </div> |
58 | </ng-template> | 58 | </ng-template> |
59 | 59 | ||
60 | <div class="form-row" *ngIf="!isInBigView()"> <!-- hidden on large screens, as it is then displayed on the right side of the form --> | 60 | <div class="row d-xxl-none"> <!-- hidden on large screens, as it is then displayed on the right side of the form --> |
61 | <div class="col-12 col-xl-3"></div> | 61 | <div class="col-12 col-xl-3"></div> |
62 | 62 | ||
63 | <div class="col-12 col-xl-9"> | 63 | <div class="col-12 col-xl-9"> |
@@ -67,8 +67,8 @@ | |||
67 | 67 | ||
68 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | 68 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> |
69 | 69 | ||
70 | <div class="form-row mt-4"> <!-- user grid --> | 70 | <div class="row mt-4"> <!-- user grid --> |
71 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 71 | <div class="col-12 col-lg-4 col-xl-3"> |
72 | <div class="anchor" id="user"></div> <!-- user anchor --> | 72 | <div class="anchor" id="user"></div> <!-- user anchor --> |
73 | <div *ngIf="isCreation()" class="account-title" i18n>NEW USER</div> | 73 | <div *ngIf="isCreation()" class="account-title" i18n>NEW USER</div> |
74 | <div *ngIf="!isCreation() && user" class="account-title"> | 74 | <div *ngIf="!isCreation() && user" class="account-title"> |
@@ -76,150 +76,150 @@ | |||
76 | </div> | 76 | </div> |
77 | </div> | 77 | </div> |
78 | 78 | ||
79 | <div class="form-group col-12 col-lg-8 col-xl-9" [ngClass]="{ 'form-row': isInBigView() }"> | 79 | <div class="col-12 col-lg-8 col-xl-9"> |
80 | 80 | <div class="row"> | |
81 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form" [ngClass]="{ 'col-5': isInBigView() }"> | 81 | <form class="col" role="form" (ngSubmit)="formValidated()" [formGroup]="form"> |
82 | <div class="form-group" *ngIf="isCreation()"> | 82 | <div class="form-group" *ngIf="isCreation()"> |
83 | <label i18n for="username">Username</label> | 83 | <label i18n for="username">Username</label> |
84 | <input | 84 | <input |
85 | type="text" id="username" i18n-placeholder placeholder="john" class="form-control" | 85 | type="text" id="username" i18n-placeholder placeholder="john" class="form-control" |
86 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" | 86 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" |
87 | > | 87 | > |
88 | <div *ngIf="formErrors.username" class="form-error"> | 88 | <div *ngIf="formErrors.username" class="form-error"> |
89 | {{ formErrors.username }} | 89 | {{ formErrors.username }} |
90 | </div> | ||
90 | </div> | 91 | </div> |
91 | </div> | ||
92 | 92 | ||
93 | <div class="form-group" *ngIf="isCreation()"> | 93 | <div class="form-group" *ngIf="isCreation()"> |
94 | <label i18n for="channelName">Channel name</label> | 94 | <label i18n for="channelName">Channel name</label> |
95 | <input | 95 | <input |
96 | type="text" id="channelName" i18n-placeholder placeholder="john_channel" class="form-control" | 96 | type="text" id="channelName" i18n-placeholder placeholder="john_channel" class="form-control" |
97 | formControlName="channelName" [ngClass]="{ 'input-error': formErrors['channelName'] }" | 97 | formControlName="channelName" [ngClass]="{ 'input-error': formErrors['channelName'] }" |
98 | > | 98 | > |
99 | <div *ngIf="formErrors.channelName" class="form-error"> | 99 | <div *ngIf="formErrors.channelName" class="form-error"> |
100 | {{ formErrors.channelName }} | 100 | {{ formErrors.channelName }} |
101 | </div> | ||
101 | </div> | 102 | </div> |
102 | </div> | ||
103 | 103 | ||
104 | <div class="form-group"> | 104 | <div class="form-group"> |
105 | <label i18n for="email">Email</label> | 105 | <label i18n for="email">Email</label> |
106 | <input | 106 | <input |
107 | type="text" id="email" i18n-placeholder placeholder="mail@example.com" class="form-control" | 107 | type="text" id="email" i18n-placeholder placeholder="mail@example.com" class="form-control" |
108 | formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }" | 108 | formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }" |
109 | autocomplete="off" [readonly]="user && user.pluginAuth !== null" | 109 | autocomplete="off" [readonly]="user && user.pluginAuth !== null" |
110 | > | 110 | > |
111 | <div *ngIf="formErrors.email" class="form-error"> | 111 | <div *ngIf="formErrors.email" class="form-error"> |
112 | {{ formErrors.email }} | 112 | {{ formErrors.email }} |
113 | </div> | ||
113 | </div> | 114 | </div> |
114 | </div> | ||
115 | 115 | ||
116 | <div class="form-group" *ngIf="isCreation()"> | 116 | <div class="form-group" *ngIf="isCreation()"> |
117 | <label i18n for="password">Password</label> | 117 | <label i18n for="password">Password</label> |
118 | <my-help *ngIf="isPasswordOptional()"> | 118 | <my-help *ngIf="isPasswordOptional()"> |
119 | <ng-template ptTemplate="customHtml"> | 119 | <ng-template ptTemplate="customHtml"> |
120 | <ng-container i18n> | 120 | <ng-container i18n> |
121 | If you leave the password empty, an email will be sent to the user. | 121 | If you leave the password empty, an email will be sent to the user. |
122 | </ng-container> | 122 | </ng-container> |
123 | </ng-template> | 123 | </ng-template> |
124 | </my-help> | 124 | </my-help> |
125 | 125 | ||
126 | <my-input-toggle-hidden | 126 | <my-input-text |
127 | formControlName="password" inputId="password" [ngClass]="{ 'input-error': formErrors['password'] }" autocomplete="new-password" | 127 | formControlName="password" inputId="password" [ngClass]="{ 'input-error': formErrors['password'] }" autocomplete="new-password" |
128 | ></my-input-toggle-hidden> | 128 | ></my-input-text> |
129 | 129 | ||
130 | <div *ngIf="formErrors.password" class="form-error"> | 130 | <div *ngIf="formErrors.password" class="form-error"> |
131 | {{ formErrors.password }} | 131 | {{ formErrors.password }} |
132 | </div> | ||
132 | </div> | 133 | </div> |
133 | </div> | ||
134 | 134 | ||
135 | <div class="form-group"> | 135 | <div class="form-group"> |
136 | <label i18n for="role">Role</label> | 136 | <label i18n for="role">Role</label> |
137 | <div class="peertube-select-container"> | 137 | <div class="peertube-select-container"> |
138 | <select id="role" formControlName="role" class="form-control"> | 138 | <select id="role" formControlName="role" class="form-control"> |
139 | <option *ngFor="let role of roles" [value]="role.value"> | 139 | <option *ngFor="let role of roles" [value]="role.value"> |
140 | {{ role.label }} | 140 | {{ role.label }} |
141 | </option> | 141 | </option> |
142 | </select> | 142 | </select> |
143 | </div> | ||
144 | |||
145 | <div *ngIf="formErrors.role" class="form-error"> | ||
146 | {{ formErrors.role }} | ||
147 | </div> | ||
143 | </div> | 148 | </div> |
144 | 149 | ||
145 | <div *ngIf="formErrors.role" class="form-error"> | 150 | <div class="form-group"> |
146 | {{ formErrors.role }} | 151 | <label i18n for="videoQuota">Video quota</label> |
152 | |||
153 | <my-select-custom-value | ||
154 | id="videoQuota" | ||
155 | [items]="videoQuotaOptions" | ||
156 | formControlName="videoQuota" | ||
157 | i18n-inputSuffix inputSuffix="bytes" inputType="number" | ||
158 | [clearable]="false" | ||
159 | ></my-select-custom-value> | ||
160 | |||
161 | <div i18n class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()"> | ||
162 | Transcoding is enabled. The video quota only takes into account <strong>original</strong> video size. <br /> | ||
163 | At most, this user could upload ~ {{ computeQuotaWithTranscoding() | bytes: 0 }}. | ||
164 | </div> | ||
165 | |||
166 | <div *ngIf="formErrors.videoQuota" class="form-error"> | ||
167 | {{ formErrors.videoQuota }} | ||
168 | </div> | ||
147 | </div> | 169 | </div> |
148 | </div> | ||
149 | 170 | ||
150 | <div class="form-group"> | 171 | <div class="form-group"> |
151 | <label i18n for="videoQuota">Video quota</label> | 172 | <label i18n for="videoQuotaDaily">Daily video quota</label> |
152 | |||
153 | <my-select-custom-value | ||
154 | id="videoQuota" | ||
155 | [items]="videoQuotaOptions" | ||
156 | formControlName="videoQuota" | ||
157 | i18n-inputSuffix inputSuffix="bytes" inputType="number" | ||
158 | [clearable]="false" | ||
159 | ></my-select-custom-value> | ||
160 | |||
161 | <div i18n class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()"> | ||
162 | Transcoding is enabled. The video quota only takes into account <strong>original</strong> video size. <br /> | ||
163 | At most, this user could upload ~ {{ computeQuotaWithTranscoding() | bytes: 0 }}. | ||
164 | </div> | ||
165 | 173 | ||
166 | <div *ngIf="formErrors.videoQuota" class="form-error"> | 174 | <my-select-custom-value |
167 | {{ formErrors.videoQuota }} | 175 | id="videoQuotaDaily" |
168 | </div> | 176 | [items]="videoQuotaDailyOptions" |
169 | </div> | 177 | formControlName="videoQuotaDaily" |
178 | i18n-inputSuffix inputSuffix="bytes" inputType="number" | ||
179 | [clearable]="false" | ||
180 | ></my-select-custom-value> | ||
170 | 181 | ||
171 | <div class="form-group"> | 182 | <div *ngIf="formErrors.videoQuotaDaily" class="form-error"> |
172 | <label i18n for="videoQuotaDaily">Daily video quota</label> | 183 | {{ formErrors.videoQuotaDaily }} |
173 | 184 | </div> | |
174 | <my-select-custom-value | ||
175 | id="videoQuotaDaily" | ||
176 | [items]="videoQuotaDailyOptions" | ||
177 | formControlName="videoQuotaDaily" | ||
178 | i18n-inputSuffix inputSuffix="bytes" inputType="number" | ||
179 | [clearable]="false" | ||
180 | ></my-select-custom-value> | ||
181 | |||
182 | <div *ngIf="formErrors.videoQuotaDaily" class="form-error"> | ||
183 | {{ formErrors.videoQuotaDaily }} | ||
184 | </div> | 185 | </div> |
185 | </div> | ||
186 | 186 | ||
187 | <div class="form-group" *ngIf="!isCreation() && getAuthPlugins().length !== 0"> | 187 | <div class="form-group" *ngIf="!isCreation() && getAuthPlugins().length !== 0"> |
188 | <label i18n for="pluginAuth">Auth plugin</label> | 188 | <label i18n for="pluginAuth">Auth plugin</label> |
189 | 189 | ||
190 | <div class="peertube-select-container"> | 190 | <div class="peertube-select-container"> |
191 | <select id="pluginAuth" formControlName="pluginAuth" class="form-control"> | 191 | <select id="pluginAuth" formControlName="pluginAuth" class="form-control"> |
192 | <option [value]="null" i18n>None (local authentication)</option> | 192 | <option [value]="null" i18n>None (local authentication)</option> |
193 | <option *ngFor="let authPlugin of getAuthPlugins()" [value]="authPlugin">{{ authPlugin }}</option> | 193 | <option *ngFor="let authPlugin of getAuthPlugins()" [value]="authPlugin">{{ authPlugin }}</option> |
194 | </select> | 194 | </select> |
195 | </div> | ||
195 | </div> | 196 | </div> |
196 | </div> | ||
197 | 197 | ||
198 | <div class="form-group"> | 198 | <div class="form-group"> |
199 | <my-peertube-checkbox | 199 | <my-peertube-checkbox |
200 | inputName="byPassAutoBlock" formControlName="byPassAutoBlock" | 200 | inputName="byPassAutoBlock" formControlName="byPassAutoBlock" |
201 | i18n-labelText labelText="Doesn't need review before a video goes public" | 201 | i18n-labelText labelText="Doesn't need review before a video goes public" |
202 | ></my-peertube-checkbox> | 202 | ></my-peertube-checkbox> |
203 | </div> | 203 | </div> |
204 | 204 | ||
205 | <input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid"> | 205 | <input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid"> |
206 | </form> | 206 | </form> |
207 | 207 | ||
208 | <div *ngIf="isInBigView()" class="col-7"> | 208 | <div class="d-none d-xxl-block col-7"> |
209 | <ng-template *ngTemplateOutlet="dashboard"></ng-template> | 209 | <ng-template *ngTemplateOutlet="dashboard"></ng-template> |
210 | </div> | ||
210 | </div> | 211 | </div> |
211 | |||
212 | </div> | 212 | </div> |
213 | </div> | 213 | </div> |
214 | 214 | ||
215 | 215 | ||
216 | <div *ngIf="!isCreation() && user && user.pluginAuth === null" class="form-row mt-4"> <!-- danger zone grid --> | 216 | <div *ngIf="!isCreation() && user && user.pluginAuth === null" class="row mt-4"> <!-- danger zone grid --> |
217 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 217 | <div class="col-12 col-lg-4 col-xl-3"> |
218 | <div class="anchor" id="danger"></div> <!-- danger zone anchor --> | 218 | <div class="anchor" id="danger"></div> <!-- danger zone anchor --> |
219 | <div i18n class="account-title account-title-danger">DANGER ZONE</div> | 219 | <div i18n class="account-title account-title-danger">DANGER ZONE</div> |
220 | </div> | 220 | </div> |
221 | 221 | ||
222 | <div class="form-group col-12 col-lg-8 col-xl-9" [ngClass]="{ 'form-row': isInBigView() }"> | 222 | <div class="col-12 col-lg-8 col-xl-9"> |
223 | 223 | ||
224 | <div class="danger-zone"> | 224 | <div class="danger-zone"> |
225 | <div class="form-group reset-password-email"> | 225 | <div class="form-group reset-password-email"> |
diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss b/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss index d7932154b..254286ae3 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss | |||
@@ -4,11 +4,6 @@ | |||
4 | 4 | ||
5 | $form-base-input-width: 340px; | 5 | $form-base-input-width: 340px; |
6 | 6 | ||
7 | label { | ||
8 | font-weight: $font-regular; | ||
9 | font-size: 100%; | ||
10 | } | ||
11 | |||
12 | .account-title { | 7 | .account-title { |
13 | @include settings-big-title; | 8 | @include settings-big-title; |
14 | 9 | ||
@@ -22,7 +17,7 @@ input:not([type=submit]) { | |||
22 | display: block; | 17 | display: block; |
23 | } | 18 | } |
24 | 19 | ||
25 | my-input-toggle-hidden { | 20 | my-input-text { |
26 | @include responsive-width($form-base-input-width); | 21 | @include responsive-width($form-base-input-width); |
27 | 22 | ||
28 | display: block; | 23 | display: block; |
diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.ts b/client/src/app/+admin/overview/users/user-edit/user-edit.ts index 069b62a53..395d07423 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.ts | |||
@@ -46,10 +46,6 @@ export abstract class UserEdit extends FormReactive implements OnInit { | |||
46 | .concat(this.serverConfig.plugin.registeredExternalAuths.map(p => p.npmName)) | 46 | .concat(this.serverConfig.plugin.registeredExternalAuths.map(p => p.npmName)) |
47 | } | 47 | } |
48 | 48 | ||
49 | isInBigView () { | ||
50 | return this.screenService.getWindowInnerWidth() > 1600 | ||
51 | } | ||
52 | |||
53 | buildRoles () { | 49 | buildRoles () { |
54 | const authUser = this.auth.getUser() | 50 | const authUser = this.auth.getUser() |
55 | 51 | ||
diff --git a/client/src/app/+admin/overview/users/user-edit/user-password.component.html b/client/src/app/+admin/overview/users/user-edit/user-password.component.html index 1238d1839..35f36e465 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-password.component.html +++ b/client/src/app/+admin/overview/users/user-edit/user-password.component.html | |||
@@ -1,20 +1,16 @@ | |||
1 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> | 1 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> |
2 | <div class="form-group"> | 2 | <div class="input-group"> |
3 | <input id="password" [attr.type]="showPassword ? 'text' : 'password'" class="form-control" | ||
4 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | ||
5 | > | ||
6 | <button class="btn btn-sm btn-outline-secondary" (click)="togglePasswordVisibility()" type="button"> | ||
7 | <ng-container *ngIf="!showPassword" i18n>Show</ng-container> | ||
8 | <ng-container *ngIf="!!showPassword" i18n>Hide</ng-container> | ||
9 | </button> | ||
10 | </div> | ||
3 | 11 | ||
4 | <div class="input-group"> | 12 | <div *ngIf="formErrors.password" class="form-error"> |
5 | <input id="password" [attr.type]="showPassword ? 'text' : 'password'" class="form-control" | 13 | {{ formErrors.password }} |
6 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | ||
7 | > | ||
8 | <div class="input-group-append"> | ||
9 | <button class="btn btn-sm btn-outline-secondary" (click)="togglePasswordVisibility()" type="button"> | ||
10 | <ng-container *ngIf="!showPassword" i18n>Show</ng-container> | ||
11 | <ng-container *ngIf="!!showPassword" i18n>Hide</ng-container> | ||
12 | </button> | ||
13 | </div> | ||
14 | </div> | ||
15 | <div *ngIf="formErrors.password" class="form-error"> | ||
16 | {{ formErrors.password }} | ||
17 | </div> | ||
18 | </div> | 14 | </div> |
19 | 15 | ||
20 | <input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid"> | 16 | <input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid"> |
diff --git a/client/src/app/+admin/overview/users/user-edit/user-password.component.scss b/client/src/app/+admin/overview/users/user-edit/user-password.component.scss index acb680682..54f782086 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-password.component.scss +++ b/client/src/app/+admin/overview/users/user-edit/user-password.component.scss | |||
@@ -1,13 +1,9 @@ | |||
1 | @use '_variables' as *; | 1 | @use '_variables' as *; |
2 | @use '_mixins' as *; | 2 | @use '_mixins' as *; |
3 | 3 | ||
4 | input:not([type=submit]):not([type=checkbox]) { | 4 | input[type=text], |
5 | input[type=password] { | ||
5 | @include peertube-input-text(340px); | 6 | @include peertube-input-text(340px); |
6 | |||
7 | display: block; | ||
8 | border-top-right-radius: 0; | ||
9 | border-bottom-right-radius: 0; | ||
10 | border-right: 0; | ||
11 | } | 7 | } |
12 | 8 | ||
13 | input[type=submit] { | 9 | input[type=submit] { |
@@ -17,7 +13,3 @@ input[type=submit] { | |||
17 | 13 | ||
18 | margin-top: 10px; | 14 | margin-top: 10px; |
19 | } | 15 | } |
20 | |||
21 | .input-group-append { | ||
22 | height: 30px; | ||
23 | } | ||
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.html b/client/src/app/+admin/overview/users/user-list/user-list.component.html index 30d10e3cf..4da46dc7b 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.html +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.html | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | <p-table | 6 | <p-table |
7 | [value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" | 7 | [value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" |
8 | [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true" [(selection)]="selectedUsers" | 8 | [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true" [(selection)]="selectedUsers" |
9 | [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true" | 9 | [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true" |
10 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate | 10 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate |
11 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users" | 11 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users" |
@@ -26,7 +26,7 @@ | |||
26 | </a> | 26 | </a> |
27 | </div> | 27 | </div> |
28 | 28 | ||
29 | <div class="ml-auto"> | 29 | <div class="ms-auto"> |
30 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> | 30 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> |
31 | </div> | 31 | </div> |
32 | 32 | ||
@@ -90,7 +90,7 @@ | |||
90 | </my-user-moderation-dropdown> | 90 | </my-user-moderation-dropdown> |
91 | </td> | 91 | </td> |
92 | 92 | ||
93 | <td *ngIf="isSelected('username')"> | 93 | <td *ngIf="isSelected('username')" class="cell-username"> |
94 | <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/a/' + user.username ]"> | 94 | <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/a/' + user.username ]"> |
95 | <div class="chip two-lines"> | 95 | <div class="chip two-lines"> |
96 | <my-actor-avatar [account]="user?.account" size="32"></my-actor-avatar> | 96 | <my-actor-avatar [account]="user?.account" size="32"></my-actor-avatar> |
@@ -101,13 +101,13 @@ | |||
101 | </div> | 101 | </div> |
102 | </a> | 102 | </a> |
103 | 103 | ||
104 | <div *ngIf="user.accountMutedStatus.mutedByInstance" class="badges-username badge badge-red" i18n>Muted</div> | 104 | <div *ngIf="user.accountMutedStatus.mutedByInstance" class="pt-badge badge-red" i18n>Muted</div> |
105 | <div *ngIf="user.blocked" class="badges-username badge badge-red" i18n>Banned</div> | 105 | <div *ngIf="user.blocked" class="pt-badge badge-red" i18n>Banned</div> |
106 | </td> | 106 | </td> |
107 | 107 | ||
108 | <td *ngIf="isSelected('role')"> | 108 | <td *ngIf="isSelected('role')"> |
109 | <span *ngIf="user.blocked" class="badge badge-banned" i18n-title title="The user was banned">{{ user.roleLabel }}</span> | 109 | <span *ngIf="user.blocked" class="pt-badge badge-banned" i18n-title title="The user was banned">{{ user.roleLabel }}</span> |
110 | <span *ngIf="!user.blocked" class="badge" [ngClass]="getRoleClass(user.role)">{{ user.roleLabel }}</span> | 110 | <span *ngIf="!user.blocked" class="pt-badge" [ngClass]="getRoleClass(user.role)">{{ user.roleLabel }}</span> |
111 | </td> | 111 | </td> |
112 | 112 | ||
113 | <td *ngIf="isSelected('email')" [title]="user.email"> | 113 | <td *ngIf="isSelected('email')" [title]="user.email"> |
@@ -139,7 +139,7 @@ | |||
139 | 139 | ||
140 | <td *ngIf="isSelected('quotaDaily')"> | 140 | <td *ngIf="isSelected('quotaDaily')"> |
141 | <div class="progress" i18n-title title="Total daily video quota"> | 141 | <div class="progress" i18n-title title="Total daily video quota"> |
142 | <div class="progress-bar secondary" role="progressbar" [style]="{ width: getUserVideoQuotaDailyPercentage(user) + '%' }" | 142 | <div class="progress-bar" role="progressbar" [style]="{ width: getUserVideoQuotaDailyPercentage(user) + '%' }" |
143 | [attr.aria-valuenow]="user.rawVideoQuotaUsedDaily" aria-valuemin="0" [attr.aria-valuemax]="user.rawVideoQuotaDaily"> | 143 | [attr.aria-valuenow]="user.rawVideoQuotaUsedDaily" aria-valuemin="0" [attr.aria-valuemax]="user.rawVideoQuotaDaily"> |
144 | </div> | 144 | </div> |
145 | <span>{{ user.videoQuotaUsedDaily }}</span> | 145 | <span>{{ user.videoQuotaUsedDaily }}</span> |
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.scss b/client/src/app/+admin/overview/users/user-list/user-list.component.scss index 8160703f0..3c775cac5 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.scss +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.scss | |||
@@ -1,5 +1,6 @@ | |||
1 | @use '_variables' as *; | 1 | @use '_variables' as *; |
2 | @use '_mixins' as *; | 2 | @use '_mixins' as *; |
3 | @use '~bootstrap/scss/functions' as *; | ||
3 | 4 | ||
4 | .add-button { | 5 | .add-button { |
5 | @include create-button; | 6 | @include create-button; |
@@ -23,15 +24,8 @@ tr.banned > td { | |||
23 | font-weight: $font-semibold; | 24 | font-weight: $font-semibold; |
24 | } | 25 | } |
25 | 26 | ||
26 | .badges-username { | 27 | .cell-username .pt-badge { |
27 | margin-left: 15px; | 28 | @include margin-left(15px); |
28 | } | ||
29 | |||
30 | .user-table-primary-text .glyphicon { | ||
31 | @include margin-left(0.1rem); | ||
32 | |||
33 | font-size: 80%; | ||
34 | color: #808080; | ||
35 | } | 29 | } |
36 | 30 | ||
37 | p-tableCheckbox { | 31 | p-tableCheckbox { |
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.ts b/client/src/app/+admin/overview/users/user-list/user-list.component.ts index d22e1355e..c3a7646cc 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import { SortMeta } from 'primeng/api' | 1 | import { SortMeta } from 'primeng/api' |
2 | import { Component, OnInit, ViewChild } from '@angular/core' | 2 | import { Component, OnInit, ViewChild } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' | 4 | import { AuthService, ConfirmService, LocalStorageService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' |
5 | import { getAPIHost } from '@app/helpers' | 5 | import { prepareIcu, getAPIHost } from '@app/helpers' |
6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' | 6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' |
7 | import { Actor, DropdownAction } from '@app/shared/shared-main' | 7 | import { Actor, DropdownAction } from '@app/shared/shared-main' |
8 | import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation' | 8 | import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation' |
@@ -22,6 +22,8 @@ type UserForList = User & { | |||
22 | styleUrls: [ './user-list.component.scss' ] | 22 | styleUrls: [ './user-list.component.scss' ] |
23 | }) | 23 | }) |
24 | export class UserListComponent extends RestTable implements OnInit { | 24 | export class UserListComponent extends RestTable implements OnInit { |
25 | private static readonly LOCAL_STORAGE_SELECTED_COLUMNS_KEY = 'admin-user-list-selected-columns' | ||
26 | |||
25 | @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent | 27 | @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent |
26 | 28 | ||
27 | users: (User & { accountMutedStatus: AccountMutedStatus })[] = [] | 29 | users: (User & { accountMutedStatus: AccountMutedStatus })[] = [] |
@@ -56,7 +58,7 @@ export class UserListComponent extends RestTable implements OnInit { | |||
56 | 58 | ||
57 | requiresEmailVerification = false | 59 | requiresEmailVerification = false |
58 | 60 | ||
59 | private _selectedColumns: string[] | 61 | private _selectedColumns: string[] = [] |
60 | 62 | ||
61 | constructor ( | 63 | constructor ( |
62 | protected route: ActivatedRoute, | 64 | protected route: ActivatedRoute, |
@@ -66,7 +68,8 @@ export class UserListComponent extends RestTable implements OnInit { | |||
66 | private serverService: ServerService, | 68 | private serverService: ServerService, |
67 | private auth: AuthService, | 69 | private auth: AuthService, |
68 | private blocklist: BlocklistService, | 70 | private blocklist: BlocklistService, |
69 | private userAdminService: UserAdminService | 71 | private userAdminService: UserAdminService, |
72 | private peertubeLocalStorage: LocalStorageService | ||
70 | ) { | 73 | ) { |
71 | super() | 74 | super() |
72 | } | 75 | } |
@@ -76,11 +79,13 @@ export class UserListComponent extends RestTable implements OnInit { | |||
76 | } | 79 | } |
77 | 80 | ||
78 | get selectedColumns () { | 81 | get selectedColumns () { |
79 | return this._selectedColumns | 82 | return this._selectedColumns || [] |
80 | } | 83 | } |
81 | 84 | ||
82 | set selectedColumns (val: string[]) { | 85 | set selectedColumns (val: string[]) { |
83 | this._selectedColumns = val | 86 | this._selectedColumns = val |
87 | |||
88 | this.saveSelectedColumns() | ||
84 | } | 89 | } |
85 | 90 | ||
86 | ngOnInit () { | 91 | ngOnInit () { |
@@ -126,14 +131,35 @@ export class UserListComponent extends RestTable implements OnInit { | |||
126 | { id: 'role', label: $localize`Role` }, | 131 | { id: 'role', label: $localize`Role` }, |
127 | { id: 'email', label: $localize`Email` }, | 132 | { id: 'email', label: $localize`Email` }, |
128 | { id: 'quota', label: $localize`Video quota` }, | 133 | { id: 'quota', label: $localize`Video quota` }, |
129 | { id: 'createdAt', label: $localize`Created` } | 134 | { id: 'createdAt', label: $localize`Created` }, |
135 | { id: 'lastLoginDate', label: $localize`Last login` }, | ||
136 | |||
137 | { id: 'quotaDaily', label: $localize`Daily quota` }, | ||
138 | { id: 'pluginAuth', label: $localize`Auth plugin` } | ||
130 | ] | 139 | ] |
131 | 140 | ||
132 | this.selectedColumns = this.columns.map(c => c.id) | 141 | this.loadSelectedColumns() |
142 | } | ||
143 | |||
144 | loadSelectedColumns () { | ||
145 | const result = this.peertubeLocalStorage.getItem(UserListComponent.LOCAL_STORAGE_SELECTED_COLUMNS_KEY) | ||
133 | 146 | ||
134 | this.columns.push({ id: 'quotaDaily', label: $localize`Daily quota` }) | 147 | if (result) { |
135 | this.columns.push({ id: 'pluginAuth', label: $localize`Auth plugin` }) | 148 | try { |
136 | this.columns.push({ id: 'lastLoginDate', label: $localize`Last login` }) | 149 | this.selectedColumns = JSON.parse(result) |
150 | return | ||
151 | } catch (err) { | ||
152 | console.error('Cannot load selected columns.', err) | ||
153 | } | ||
154 | } | ||
155 | |||
156 | // Default behaviour | ||
157 | this.selectedColumns = [ 'username', 'role', 'email', 'quota', 'createdAt', 'lastLoginDate' ] | ||
158 | return | ||
159 | } | ||
160 | |||
161 | saveSelectedColumns () { | ||
162 | this.peertubeLocalStorage.setItem(UserListComponent.LOCAL_STORAGE_SELECTED_COLUMNS_KEY, JSON.stringify(this.selectedColumns)) | ||
137 | } | 163 | } |
138 | 164 | ||
139 | getIdentifier () { | 165 | getIdentifier () { |
@@ -164,6 +190,7 @@ export class UserListComponent extends RestTable implements OnInit { | |||
164 | } | 190 | } |
165 | 191 | ||
166 | getUserVideoQuotaDailyPercentage (user: UserForList) { | 192 | getUserVideoQuotaDailyPercentage (user: UserForList) { |
193 | console.log(user.rawVideoQuotaUsedDaily * 100 / user.rawVideoQuotaDaily) | ||
167 | return user.rawVideoQuotaUsedDaily * 100 / user.rawVideoQuotaDaily | 194 | return user.rawVideoQuotaUsedDaily * 100 / user.rawVideoQuotaDaily |
168 | } | 195 | } |
169 | 196 | ||
@@ -183,13 +210,25 @@ export class UserListComponent extends RestTable implements OnInit { | |||
183 | } | 210 | } |
184 | 211 | ||
185 | async unbanUsers (users: User[]) { | 212 | async unbanUsers (users: User[]) { |
186 | const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`) | 213 | const res = await this.confirmService.confirm( |
214 | prepareIcu($localize`Do you really want to unban {count, plural, =1 {1 user} other {{count} users}}?`)( | ||
215 | { count: users.length }, | ||
216 | $localize`Do you really want to unban ${users.length} users?` | ||
217 | ), | ||
218 | $localize`Unban` | ||
219 | ) | ||
220 | |||
187 | if (res === false) return | 221 | if (res === false) return |
188 | 222 | ||
189 | this.userAdminService.unbanUsers(users) | 223 | this.userAdminService.unbanUsers(users) |
190 | .subscribe({ | 224 | .subscribe({ |
191 | next: () => { | 225 | next: () => { |
192 | this.notifier.success($localize`${users.length} users unbanned.`) | 226 | this.notifier.success( |
227 | prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} unbanned.`)( | ||
228 | { count: users.length }, | ||
229 | $localize`${users.length} users unbanned.` | ||
230 | ) | ||
231 | ) | ||
193 | this.reloadData() | 232 | this.reloadData() |
194 | }, | 233 | }, |
195 | 234 | ||
@@ -198,21 +237,28 @@ export class UserListComponent extends RestTable implements OnInit { | |||
198 | } | 237 | } |
199 | 238 | ||
200 | async removeUsers (users: User[]) { | 239 | async removeUsers (users: User[]) { |
201 | for (const user of users) { | 240 | if (users.some(u => u.username === 'root')) { |
202 | if (user.username === 'root') { | 241 | this.notifier.error($localize`You cannot delete root.`) |
203 | this.notifier.error($localize`You cannot delete root.`) | 242 | return |
204 | return | ||
205 | } | ||
206 | } | 243 | } |
207 | 244 | ||
208 | const message = $localize`If you remove these users, you will not be able to create others with the same username!` | 245 | const message = $localize`<p>You can't create users or channels with a username that already used by a deleted user/channel.</p>` + |
246 | $localize`It means the following usernames will be permanently deleted and cannot be recovered:` + | ||
247 | '<ul>' + users.map(u => '<li>' + u.username + '</li>').join('') + '</ul>' | ||
248 | |||
209 | const res = await this.confirmService.confirm(message, $localize`Delete`) | 249 | const res = await this.confirmService.confirm(message, $localize`Delete`) |
210 | if (res === false) return | 250 | if (res === false) return |
211 | 251 | ||
212 | this.userAdminService.removeUser(users) | 252 | this.userAdminService.removeUser(users) |
213 | .subscribe({ | 253 | .subscribe({ |
214 | next: () => { | 254 | next: () => { |
215 | this.notifier.success($localize`${users.length} users deleted.`) | 255 | this.notifier.success( |
256 | prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} deleted.`)( | ||
257 | { count: users.length }, | ||
258 | $localize`${users.length} users deleted.` | ||
259 | ) | ||
260 | ) | ||
261 | |||
216 | this.reloadData() | 262 | this.reloadData() |
217 | }, | 263 | }, |
218 | 264 | ||
@@ -224,7 +270,13 @@ export class UserListComponent extends RestTable implements OnInit { | |||
224 | this.userAdminService.updateUsers(users, { emailVerified: true }) | 270 | this.userAdminService.updateUsers(users, { emailVerified: true }) |
225 | .subscribe({ | 271 | .subscribe({ |
226 | next: () => { | 272 | next: () => { |
227 | this.notifier.success($localize`${users.length} users email set as verified.`) | 273 | this.notifier.success( |
274 | prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} email set as verified.`)( | ||
275 | { count: users.length }, | ||
276 | $localize`${users.length} users email set as verified.` | ||
277 | ) | ||
278 | ) | ||
279 | |||
228 | this.reloadData() | 280 | this.reloadData() |
229 | }, | 281 | }, |
230 | 282 | ||
diff --git a/client/src/app/+admin/overview/videos/video-list.component.html b/client/src/app/+admin/overview/videos/video-list.component.html index 75d9be5f1..2f36c27b7 100644 --- a/client/src/app/+admin/overview/videos/video-list.component.html +++ b/client/src/app/+admin/overview/videos/video-list.component.html | |||
@@ -21,7 +21,7 @@ | |||
21 | </my-action-dropdown> | 21 | </my-action-dropdown> |
22 | </div> | 22 | </div> |
23 | 23 | ||
24 | <div class="ml-auto right-form"> | 24 | <div class="ms-auto right-form"> |
25 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> | 25 | <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter> |
26 | 26 | ||
27 | <my-button i18n-label label="Refresh" icon="refresh" (click)="reloadData()"></my-button> | 27 | <my-button i18n-label label="Refresh" icon="refresh" (click)="reloadData()"></my-button> |
@@ -67,25 +67,25 @@ | |||
67 | </td> | 67 | </td> |
68 | 68 | ||
69 | <td> | 69 | <td> |
70 | <span class="badge badge-blue" *ngIf="video.isLocal">Local</span> | 70 | <span class="pt-badge badge-blue" *ngIf="video.isLocal">Local</span> |
71 | <span class="badge badge-purple" *ngIf="!video.isLocal">Remote</span> | 71 | <span class="pt-badge badge-purple" *ngIf="!video.isLocal">Remote</span> |
72 | 72 | ||
73 | <span [ngClass]="getPrivacyBadgeClass(video)" class="badge">{{ video.privacy.label }}</span> | 73 | <span [ngClass]="getPrivacyBadgeClass(video)" class="pt-badge">{{ video.privacy.label }}</span> |
74 | 74 | ||
75 | <span *ngIf="video.nsfw" class="badge badge-red" i18n>NSFW</span> | 75 | <span *ngIf="video.nsfw" class="pt-badge badge-red" i18n>NSFW</span> |
76 | 76 | ||
77 | <span *ngIf="isUnpublished(video)" class="badge badge-yellow" i18n>{{ video.state.label }}</span> | 77 | <span *ngIf="isUnpublished(video)" class="pt-badge badge-yellow" i18n>{{ video.state.label }}</span> |
78 | 78 | ||
79 | <span *ngIf="isAccountBlocked(video)" class="badge badge-red" i18n>Account muted</span> | 79 | <span *ngIf="isAccountBlocked(video)" class="pt-badge badge-red" i18n>Account muted</span> |
80 | <span *ngIf="isServerBlocked(video)" class="badge badge-red" i18n>Server muted</span> | 80 | <span *ngIf="isServerBlocked(video)" class="pt-badge badge-red" i18n>Server muted</span> |
81 | 81 | ||
82 | <span *ngIf="isVideoBlocked(video)" class="badge badge-red" i18n>Blocked</span> | 82 | <span *ngIf="isVideoBlocked(video)" class="pt-badge badge-red" i18n>Blocked</span> |
83 | </td> | 83 | </td> |
84 | 84 | ||
85 | <td> | 85 | <td> |
86 | <span *ngIf="isHLS(video)" class="badge badge-blue">HLS</span> | 86 | <span *ngIf="isHLS(video)" class="pt-badge badge-blue">HLS</span> |
87 | <span *ngIf="isWebTorrent(video)" class="badge badge-blue">WebTorrent ({{ video.files.length }})</span> | 87 | <span *ngIf="isWebTorrent(video)" class="pt-badge badge-blue">WebTorrent ({{ video.files.length }})</span> |
88 | <span *ngIf="video.isLive" class="badge badge-blue">Live</span> | 88 | <span *ngIf="video.isLive" class="pt-badge badge-blue">Live</span> |
89 | 89 | ||
90 | <span *ngIf="!isImport(video) && !video.isLive && video.isLocal">{{ getFilesSize(video) | bytes: 1 }}</span> | 90 | <span *ngIf="!isImport(video) && !video.isLive && video.isLocal">{{ getFilesSize(video) | bytes: 1 }}</span> |
91 | </td> | 91 | </td> |
@@ -121,7 +121,7 @@ | |||
121 | </ul> | 121 | </ul> |
122 | </div> | 122 | </div> |
123 | 123 | ||
124 | <my-embed class="ml-auto" [video]="video"></my-embed> | 124 | <my-embed class="ms-auto" [video]="video"></my-embed> |
125 | </div> | 125 | </div> |
126 | </td> | 126 | </td> |
127 | </tr> | 127 | </tr> |
diff --git a/client/src/app/+admin/overview/videos/video-list.component.scss b/client/src/app/+admin/overview/videos/video-list.component.scss index cb47b6548..dcd41a1b4 100644 --- a/client/src/app/+admin/overview/videos/video-list.component.scss +++ b/client/src/app/+admin/overview/videos/video-list.component.scss | |||
@@ -7,10 +7,8 @@ my-embed { | |||
7 | width: 50%; | 7 | width: 50%; |
8 | } | 8 | } |
9 | 9 | ||
10 | .badge { | 10 | .pt-badge { |
11 | @include peertube-badge; | 11 | @include margin-right(5px); |
12 | |||
13 | margin-right: 5px; | ||
14 | } | 12 | } |
15 | 13 | ||
16 | .video-info > div { | 14 | .video-info > div { |
diff --git a/client/src/app/+admin/overview/videos/video-list.component.ts b/client/src/app/+admin/overview/videos/video-list.component.ts index 82ff372aa..67e52d100 100644 --- a/client/src/app/+admin/overview/videos/video-list.component.ts +++ b/client/src/app/+admin/overview/videos/video-list.component.ts | |||
@@ -3,6 +3,7 @@ import { finalize } from 'rxjs/operators' | |||
3 | import { Component, OnInit, ViewChild } from '@angular/core' | 3 | import { Component, OnInit, ViewChild } from '@angular/core' |
4 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' | 5 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' |
6 | import { prepareIcu } from '@app/helpers' | ||
6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' | 7 | import { AdvancedInputFilter } from '@app/shared/shared-forms' |
7 | import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' | 8 | import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' |
8 | import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation' | 9 | import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation' |
@@ -196,14 +197,24 @@ export class VideoListComponent extends RestTable implements OnInit { | |||
196 | } | 197 | } |
197 | 198 | ||
198 | private async removeVideos (videos: Video[]) { | 199 | private async removeVideos (videos: Video[]) { |
199 | const message = $localize`Are you sure you want to delete these ${videos.length} videos?` | 200 | const message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {this video} other {these {count} videos}}?`)( |
201 | { count: videos.length }, | ||
202 | $localize`Are you sure you want to delete these ${videos.length} videos?` | ||
203 | ) | ||
204 | |||
200 | const res = await this.confirmService.confirm(message, $localize`Delete`) | 205 | const res = await this.confirmService.confirm(message, $localize`Delete`) |
201 | if (res === false) return | 206 | if (res === false) return |
202 | 207 | ||
203 | this.videoService.removeVideo(videos.map(v => v.id)) | 208 | this.videoService.removeVideo(videos.map(v => v.id)) |
204 | .subscribe({ | 209 | .subscribe({ |
205 | next: () => { | 210 | next: () => { |
206 | this.notifier.success($localize`Deleted ${videos.length} videos.`) | 211 | this.notifier.success( |
212 | prepareIcu($localize`Deleted {count, plural, =1 {1 video} other {{count} videos}}.`)( | ||
213 | { count: videos.length }, | ||
214 | $localize`Deleted ${videos.length} videos.` | ||
215 | ) | ||
216 | ) | ||
217 | |||
207 | this.reloadData() | 218 | this.reloadData() |
208 | }, | 219 | }, |
209 | 220 | ||
@@ -215,7 +226,13 @@ export class VideoListComponent extends RestTable implements OnInit { | |||
215 | this.videoBlockService.unblockVideo(videos.map(v => v.id)) | 226 | this.videoBlockService.unblockVideo(videos.map(v => v.id)) |
216 | .subscribe({ | 227 | .subscribe({ |
217 | next: () => { | 228 | next: () => { |
218 | this.notifier.success($localize`Unblocked ${videos.length} videos.`) | 229 | this.notifier.success( |
230 | prepareIcu($localize`Unblocked {count, plural, =1 {1 video} other {{count} videos}}.`)( | ||
231 | { count: videos.length }, | ||
232 | $localize`Unblocked ${videos.length} videos.` | ||
233 | ) | ||
234 | ) | ||
235 | |||
219 | this.reloadData() | 236 | this.reloadData() |
220 | }, | 237 | }, |
221 | 238 | ||
@@ -224,9 +241,21 @@ export class VideoListComponent extends RestTable implements OnInit { | |||
224 | } | 241 | } |
225 | 242 | ||
226 | private async removeVideoFiles (videos: Video[], type: 'hls' | 'webtorrent') { | 243 | private async removeVideoFiles (videos: Video[], type: 'hls' | 'webtorrent') { |
227 | const message = type === 'hls' | 244 | let message: string |
228 | ? $localize`Are you sure you want to delete ${videos.length} HLS streaming playlists?` | 245 | |
229 | : $localize`Are you sure you want to delete WebTorrent files of ${videos.length} videos?` | 246 | if (type === 'hls') { |
247 | // eslint-disable-next-line max-len | ||
248 | message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {1 HLS streaming playlist} other {{count} HLS streaming playlists}}?`)( | ||
249 | { count: videos.length }, | ||
250 | $localize`Are you sure you want to delete ${videos.length} HLS streaming playlists?` | ||
251 | ) | ||
252 | } else { | ||
253 | // eslint-disable-next-line max-len | ||
254 | message = prepareIcu($localize`Are you sure you want to delete WebTorrent files of {count, plural, =1 {1 video} other {{count} videos}}?`)( | ||
255 | { count: videos.length }, | ||
256 | $localize`Are you sure you want to delete WebTorrent files of ${videos.length} videos?` | ||
257 | ) | ||
258 | } | ||
230 | 259 | ||
231 | const res = await this.confirmService.confirm(message, $localize`Delete`) | 260 | const res = await this.confirmService.confirm(message, $localize`Delete`) |
232 | if (res === false) return | 261 | if (res === false) return |
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html index 33575ef52..c989d2e38 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html | |||
@@ -1,6 +1,6 @@ | |||
1 | <my-plugin-navigation [pluginType]="pluginType"></my-plugin-navigation> | 1 | <my-plugin-navigation [pluginType]="pluginType"></my-plugin-navigation> |
2 | 2 | ||
3 | <div class="alert alert-info" i18n *ngIf="pluginInstalled"> | 3 | <div class="alert pt-alert-primary" i18n *ngIf="pluginInstalled"> |
4 | To load your new installed plugins or themes, refresh the page. | 4 | To load your new installed plugins or themes, refresh the page. |
5 | </div> | 5 | </div> |
6 | 6 | ||
@@ -32,9 +32,9 @@ | |||
32 | <ng-container *ngFor="let plugin of plugins" > | 32 | <ng-container *ngFor="let plugin of plugins" > |
33 | <my-plugin-card [plugin]="plugin" [version]="plugin.latestVersion" [pluginType]="pluginType"> | 33 | <my-plugin-card [plugin]="plugin" [version]="plugin.latestVersion" [pluginType]="pluginType"> |
34 | <div ngProjectAs="badges"> | 34 | <div ngProjectAs="badges"> |
35 | <span i18n *ngIf="plugin.installed" class="badge badge-success">Installed</span> | 35 | <span i18n *ngIf="plugin.installed" class="pt-badge badge-success">Installed</span> |
36 | 36 | ||
37 | <span *ngIf="plugin.official" class="badge badge-primary" i18n i18n-title title="This plugin is developed by Framasoft"> | 37 | <span *ngIf="plugin.official" class="pt-badge badge-primary" i18n i18n-title title="This plugin is developed by Framasoft"> |
38 | Official | 38 | Official |
39 | </span> | 39 | </span> |
40 | </div> | 40 | </div> |
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss index 10401e9df..d7b41f4d8 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss | |||
@@ -17,16 +17,13 @@ | |||
17 | 17 | ||
18 | input { | 18 | input { |
19 | @include peertube-input-text(500px); | 19 | @include peertube-input-text(500px); |
20 | |||
21 | height: 35px; | ||
22 | } | 20 | } |
23 | } | 21 | } |
24 | 22 | ||
25 | .badge { | 23 | .pt-badge { |
26 | @include margin-left(15px); | 24 | @include margin-left(15px); |
27 | 25 | ||
28 | font-size: 13px; | 26 | font-size: 13px; |
29 | font-weight: $font-semibold; | ||
30 | } | 27 | } |
31 | 28 | ||
32 | .alert { | 29 | .alert { |
diff --git a/client/src/app/+admin/plugins/shared/plugin-card.component.scss b/client/src/app/+admin/plugins/shared/plugin-card.component.scss index 608064722..9f05f9db6 100644 --- a/client/src/app/+admin/plugins/shared/plugin-card.component.scss +++ b/client/src/app/+admin/plugins/shared/plugin-card.component.scss | |||
@@ -14,7 +14,6 @@ | |||
14 | .plugin-name { | 14 | .plugin-name { |
15 | @include margin-right(10px); | 15 | @include margin-right(10px); |
16 | 16 | ||
17 | font-size: 16px; | ||
18 | font-weight: $font-semibold; | 17 | font-weight: $font-semibold; |
19 | } | 18 | } |
20 | 19 | ||
diff --git a/client/src/app/+admin/system/debug/debug.component.scss b/client/src/app/+admin/system/debug/debug.component.scss index 7f5e861e2..bcbc3fc7c 100644 --- a/client/src/app/+admin/system/debug/debug.component.scss +++ b/client/src/app/+admin/system/debug/debug.component.scss | |||
@@ -1,11 +1,7 @@ | |||
1 | @use '_variables' as *; | 1 | @use '_variables' as *; |
2 | @use '_mixins' as *; | 2 | @use '_mixins' as *; |
3 | 3 | ||
4 | .root { | 4 | code { |
5 | font-size: 15px; | 5 | font-size: 14px; |
6 | 6 | font-weight: $font-semibold; | |
7 | code { | ||
8 | font-size: 14px; | ||
9 | font-weight: $font-semibold; | ||
10 | } | ||
11 | } | 7 | } |
diff --git a/client/src/app/+admin/system/jobs/jobs.component.html b/client/src/app/+admin/system/jobs/jobs.component.html index 301591786..8068fe626 100644 --- a/client/src/app/+admin/system/jobs/jobs.component.html +++ b/client/src/app/+admin/system/jobs/jobs.component.html | |||
@@ -21,7 +21,7 @@ | |||
21 | <span i18n="Selector for the list displaying jobs, filtering by their state">any</span> | 21 | <span i18n="Selector for the list displaying jobs, filtering by their state">any</span> |
22 | </ng-option> | 22 | </ng-option> |
23 | <ng-option *ngFor="let state of jobStates" [value]="state"> | 23 | <ng-option *ngFor="let state of jobStates" [value]="state"> |
24 | <span class="badge" [ngClass]="getJobStateClass(state)">{{ state }}</span> | 24 | <span class="pt-badge" [ngClass]="getJobStateClass(state)">{{ state }}</span> |
25 | </ng-option> | 25 | </ng-option> |
26 | </ng-select> | 26 | </ng-select> |
27 | </div> | 27 | </div> |
@@ -62,7 +62,7 @@ | |||
62 | <td class="job-priority c-hand" [pRowToggler]="job">{{ job.priority }}</td> | 62 | <td class="job-priority c-hand" [pRowToggler]="job">{{ job.priority }}</td> |
63 | 63 | ||
64 | <td class="job-state c-hand" [pRowToggler]="job" *ngIf="jobState === 'all'"> | 64 | <td class="job-state c-hand" [pRowToggler]="job" *ngIf="jobState === 'all'"> |
65 | <span class="badge" [ngClass]="getJobStateClass(job.state)">{{ job.state }}</span> | 65 | <span class="pt-badge" [ngClass]="getJobStateClass(job.state)">{{ job.state }}</span> |
66 | </td> | 66 | </td> |
67 | 67 | ||
68 | <td *ngIf="hasGlobalProgress()" class="job-progress c-hand" [pRowToggler]="job"> | 68 | <td *ngIf="hasGlobalProgress()" class="job-progress c-hand" [pRowToggler]="job"> |
@@ -107,8 +107,8 @@ | |||
107 | </ng-container> | 107 | </ng-container> |
108 | 108 | ||
109 | <ng-container *ngIf="jobState !== 'all'"> | 109 | <ng-container *ngIf="jobState !== 'all'"> |
110 | <ng-container *ngIf="jobType === 'all'" i18n>No <span class="badge" [ngClass]="getJobStateClass(jobState)">{{ jobState }}</span> jobs found.</ng-container> | 110 | <ng-container *ngIf="jobType === 'all'" i18n>No <span class="pt-badge" [ngClass]="getJobStateClass(jobState)">{{ jobState }}</span> jobs found.</ng-container> |
111 | <ng-container *ngIf="jobType !== 'all'" i18n>No <code>{{ jobType }}</code> jobs found that are <span class="badge" [ngClass]="getJobStateClass(jobState)">{{ jobState }}</span>.</ng-container> | 111 | <ng-container *ngIf="jobType !== 'all'" i18n>No <code>{{ jobType }}</code> jobs found that are <span class="pt-badge" [ngClass]="getJobStateClass(jobState)">{{ jobState }}</span>.</ng-container> |
112 | </ng-container> | 112 | </ng-container> |
113 | </div> | 113 | </div> |
114 | </div> | 114 | </div> |
diff --git a/client/src/app/+admin/system/jobs/jobs.component.scss b/client/src/app/+admin/system/jobs/jobs.component.scss index a9e5e8d4b..4a76f1783 100644 --- a/client/src/app/+admin/system/jobs/jobs.component.scss +++ b/client/src/app/+admin/system/jobs/jobs.component.scss | |||
@@ -44,10 +44,6 @@ | |||
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | td .glyphicon { | ||
48 | @include margin-right(10px); | ||
49 | } | ||
50 | |||
51 | pre { | 47 | pre { |
52 | font-size: 11px; | 48 | font-size: 11px; |
53 | } | 49 | } |
@@ -55,7 +51,3 @@ pre { | |||
55 | .job-error { | 51 | .job-error { |
56 | color: #ff0000; | 52 | color: #ff0000; |
57 | } | 53 | } |
58 | |||
59 | .select-filter-block .badge { | ||
60 | @include peertube-badge; | ||
61 | } | ||