]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Improve (accessibility title) and move action-buttons on left in tables (#2980)
authorKim <1877318+kimsible@users.noreply.github.com>
Fri, 31 Jul 2020 09:30:57 +0000 (11:30 +0200)
committerGitHub <noreply@github.com>
Fri, 31 Jul 2020 09:30:57 +0000 (11:30 +0200)
* Improve and move action-buttons on left in tables

* Focus on my-delete and my-button

* Correct spaces syntax

* Move user-action dropdown on the left

Co-authored-by: kimsible <kimsible@users.noreply.github.com>
19 files changed:
client/src/app/+admin/follows/followers-list/followers-list.component.html
client/src/app/+admin/follows/following-list/following-list.component.html
client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html
client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html
client/src/app/+admin/users/user-list/user-list.component.html
client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.html
client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html
client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.html
client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html
client/src/app/+my-account/my-account-videos/my-account-videos.component.html
client/src/app/shared/shared-main/buttons/button.component.html
client/src/app/shared/shared-main/buttons/button.component.scss
client/src/app/shared/shared-main/buttons/delete-button.component.html
client/src/app/shared/shared-main/buttons/delete-button.component.ts
client/src/app/shared/shared-main/buttons/edit-button.component.html
client/src/app/shared/shared-main/buttons/edit-button.component.ts
client/src/app/shared/shared-moderation/account-blocklist.component.html
client/src/app/shared/shared-moderation/server-blocklist.component.html
client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts

index 050fe40fb1adf275abe04b30718a4007ba8127bb..622d464e4f855762b93de736c63b6196aa4acd19 100644 (file)
 
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 150px;">Actions</th>
       <th i18n>Follower handle</th>
       <th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th>
       <th style="width: 100px;" i18n pSortableColumn="score">Score <p-sortIcon field="score"></p-sortIcon></th>
       <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
-      <th style="width: 150px;"></th>
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-follow>
     <tr>
+      <td class="action-cell">
+        <ng-container *ngIf="follow.state === 'pending'">
+          <my-button i18n-title title="Accept" icon="tick" (click)="acceptFollower(follow)"></my-button>
+          <my-button i18n-title title="Refuse" icon="cross" (click)="rejectFollower(follow)"></my-button>
+        </ng-container>
+
+        <my-delete-button label *ngIf="follow.state === 'accepted'" (click)="deleteFollower(follow)"></my-delete-button>
+      </td>
       <td>
         <a [href]="follow.follower.url" i18n-title title="Open actor page in a new tab" target="_blank" rel="noopener noreferrer">
           {{ follow.follower.name + '@' + follow.follower.host }}
 
       <td>{{ follow.score }}</td>
       <td>{{ follow.createdAt | date: 'short' }}</td>
-
-      <td class="action-cell">
-        <ng-container *ngIf="follow.state === 'pending'">
-          <my-button i18n-title title="Accept" icon="tick" (click)="acceptFollower(follow)"></my-button>
-          <my-button i18n-title title="Refuse" icon="cross" (click)="rejectFollower(follow)"></my-button>
-        </ng-container>
-
-        <my-delete-button *ngIf="follow.state === 'accepted'" (click)="deleteFollower(follow)"></my-delete-button>
-      </td>
     </tr>
   </ng-template>
 
index 9dead2557b870d6e09b0db8609e4d18453b5867f..ed3899e711309b1aa243be93e587e1729acc478b 100644 (file)
 
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 150px;">Action</th>
       <th i18n>Host</th>
       <th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th>
       <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
       <th style="width: 160px;" i18n pSortableColumn="redundancyAllowed">Redundancy allowed <p-sortIcon field="redundancyAllowed"></p-sortIcon></th>
-      <th style="width: 150px;"></th>
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-follow>
     <tr>
+      <td class="action-cell">
+        <my-delete-button label (click)="removeFollowing(follow)"></my-delete-button>
+      </td>
       <td>
         <a [href]="'https://' + follow.following.host" i18n-title title="Open instance in a new tab" target="_blank" rel="noopener noreferrer">
           {{ follow.following.host }}
@@ -58,9 +61,6 @@
           [host]="follow.following.host" [redundancyAllowed]="follow.following.hostRedundancyAllowed"
         ></my-redundancy-checkbox>
       </td>
-      <td class="action-cell">
-        <my-delete-button (click)="removeFollowing(follow)"></my-delete-button>
-      </td>
     </tr>
   </ng-template>
 
index 552c9f02d6efcefa54fe6e780051fe82c0fd4994..a654e51a629acb3fd824d7af02eb7e08a1eba836 100644 (file)
   <ng-template pTemplate="header">
     <tr>
       <th style="width: 40px;"></th>
+      <th style="width: 150px;">Action</th>
       <th style="width: 160px;" i18n *ngIf="isDisplayingRemoteVideos()">Strategy</th>
       <th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th >
       <th style="width: 100px;" i18n *ngIf="isDisplayingRemoteVideos()">Total size</th>
-      <th style="width: 150px;"></th>
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-expanded="expanded" let-redundancy>
     <tr>
-
       <td>
         <span class="expander" i18n-ngbTooltip ngbTooltip="List redundancies" [pRowToggler]="redundancy">
           <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
         </span>
       </td>
 
+      <td class="action-cell">
+        <my-delete-button label (click)="removeRedundancy(redundancy)"></my-delete-button>
+      </td>
+
       <td *ngIf="isDisplayingRemoteVideos()">{{ getRedundancyStrategy(redundancy) }}</td>
 
       <td>
       </td>
 
       <td *ngIf="isDisplayingRemoteVideos()">{{ getTotalSize(redundancy) | bytes: 1 }}</td>
-
-      <td class="action-cell">
-        <my-delete-button (click)="removeRedundancy(redundancy)"></my-delete-button>
-      </td>
     </tr>
   </ng-template>
 
index 486785f35ef54cf97220b6c2b0fee1d60ada4226..f461ef31bb43ca2a66e05d5cd39e421b3dd5c6b9 100644 (file)
 
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 150px;">Action</th> <!-- column for action buttons -->
       <th style="width: 100%;" i18n>Account</th>
       <th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
-      <th style="width: 150px;"></th> <!-- column for action buttons -->
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-accountBlock>
     <tr>
+      <td class="action-cell">
+        <button class="unblock-button" (click)="unblockAccount(accountBlock)" i18n>Unmute</button>
+      </td>
+
       <td>
         <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
           <div class="chip two-lines">
@@ -45,9 +49,6 @@
       </td>
 
       <td>{{ accountBlock.createdAt | date: 'short' }}</td>
-      <td class="action-cell">
-        <button class="unblock-button" (click)="unblockAccount(accountBlock)" i18n>Unmute</button>
-      </td>
     </tr>
   </ng-template>
 
index e8a0842599702bbe57eac00ef826ef607e3703a0..012bb2d12b71412bd960d11cee025f7e1faf6127 100644 (file)
@@ -61,7 +61,7 @@
       <th style="width: 60px;">
         <div class="c-hand" ngbDropdown placement="bottom-right auto" container="body" autoClose="outside">
           <my-global-icon iconName="columns" ngbDropdownToggle></my-global-icon>
-  
+
           <div role="menu" class="dropdown-menu" ngbDropdownMenu>
             <div class="dropdown-header" i18n>Table parameters</div>
             <div ngbDropdownItem class="dropdown-item">
         </span>
       </td>
 
+      <td class="action-cell">
+        <my-user-moderation-dropdown *ngIf="!isInSelectionMode()" [user]="user" container="body"
+          (userChanged)="onUserChanged()" (userDeleted)="onUserChanged()">
+        </my-user-moderation-dropdown>
+      </td>
+
       <td *ngIf="getColumn('username')">
         <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/accounts/' + user.username ]">
           <div class="chip two-lines">
       <td *ngIf="getColumn('createdAt')" [title]="user.createdAt">{{ user.createdAt | date: 'short' }}</td>
 
       <td *ngIf="getColumn('lastLoginDate')" [title]="user.lastLoginDate">{{ user.lastLoginDate | date: 'short' }}</td>
-
-      <td class="action-cell">
-        <my-user-moderation-dropdown
-          *ngIf="!isInSelectionMode()"
-          [user]="user" container="body" (userChanged)="onUserChanged()" (userDeleted)="onUserChanged()"
-        >
-        </my-user-moderation-dropdown>
-      </td>
     </tr>
   </ng-template>
 
index c20215cf92ab796a41564b8796a30f4587b456b7..f4ff323662dfd2b0d860295014da74d7585d88e8 100644 (file)
@@ -34,8 +34,8 @@
       <div i18n class="video-channel-videos">{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}</div>
 
       <div class="video-channel-buttons">
-        <my-edit-button [routerLink]="[ 'update', videoChannel.nameWithHost ]"></my-edit-button>
-        <my-delete-button (click)="deleteVideoChannel(videoChannel)"></my-delete-button>
+        <my-edit-button label [routerLink]="[ 'update', videoChannel.nameWithHost ]"></my-edit-button>
+        <my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button>
       </div>
 
       <div *ngIf="!isInSmallView" class="w-100 d-flex justify-content-end">
index 4475178c719bddcc60de3ffc9fb1018f04a1d69c..fd2163fb469649de6559300c3d16d03108e27e2b 100644 (file)
@@ -15,6 +15,7 @@
 >
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 150px;" i18n>Actions</th>
       <th style="width: 35%;" i18n>Initiator</th>
       <th style="width: 65%;" i18n>Video</th>
       <th style="width: 150px;" i18n pSortableColumn="createdAt">
         <p-sortIcon field="createdAt"></p-sortIcon>
       </th>
       <th style="width: 100px;" i18n>Status</th>
-      <th style="width: 130px;" i18n>Action</th>
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-videoChangeOwnership>
     <tr>
+      <td class="action-cell">
+        <ng-container *ngIf="videoChangeOwnership.status === 'WAITING'">
+          <my-button i18n-title title="Accept" icon="tick" (click)="openAcceptModal(videoChangeOwnership)"></my-button>
+          <my-button i18n-title title="Refuse" icon="cross" (click)="refuse(videoChangeOwnership)"></my-button>
+        </ng-container>
+      </td>
       <td>
         <a [href]="videoChangeOwnership.initiatorAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
           <div class="chip two-lines">
       <td>{{ videoChangeOwnership.createdAt | date: 'short' }}</td>
 
       <td>
-        <span class="badge" [ngClass]="getStatusClass(videoChangeOwnership.status)">{{ videoChangeOwnership.status }}</span>
-      </td>
-
-      <td class="action-cell">
-        <ng-container *ngIf="videoChangeOwnership.status === 'WAITING'">
-          <my-button i18n-label label="Accept" icon="tick" (click)="openAcceptModal(videoChangeOwnership)"></my-button>
-          <my-button i18n-label label="Refuse" icon="cross" (click)="refuse(videoChangeOwnership)"></my-button>
-        </ng-container>
+        <span class="badge"
+          [ngClass]="getStatusClass(videoChangeOwnership.status)">{{ videoChangeOwnership.status }}</span>
       </td>
     </tr>
   </ng-template>
index 854126443732e5a98294367c853fd6dabe506014..1d3a45f764c377a6dff95905b7119ee218d4a7ad 100644 (file)
   <ng-template pTemplate="header">
     <tr>
       <th style="width: 40px;"></th>
+      <th style="width: 70px">Action</th>
       <th style="width: 45%" i18n>Target</th>
       <th style="width: 55%" i18n>Video</th>
       <th style="width: 150px" i18n>State</th>
       <th style="width: 150px" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
-      <th style="width: 70px"></th>
     </tr>
   </ng-template>
 
         </span>
       </td>
 
+      <td class="action-cell">
+        <my-edit-button *ngIf="isVideoImportSuccess(videoImport) && videoImport.video"
+          [routerLink]="getEditVideoUrl(videoImport.video)"></my-edit-button>
+      </td>
+
       <td>
         <a *ngIf="videoImport.targetUrl; else torrent" [href]="videoImport.targetUrl" target="_blank" rel="noopener noreferrer">{{ videoImport.targetUrl }}</a>
         <ng-template #torrent>
       </td>
 
       <td>{{ videoImport.createdAt | date: 'short' }}</td>
-
-      <td class="action-cell">
-        <my-edit-button label=" " *ngIf="isVideoImportSuccess(videoImport) && videoImport.video" [routerLink]="getEditVideoUrl(videoImport.video)"></my-edit-button>
-      </td>
     </tr>
   </ng-template>
 
index d8e3fb2faa9f1903fe4e16ab53e5ca8e1f9450e5..3176bb8da079401e184d1b422b6212f543ebf3a0 100644 (file)
@@ -24,9 +24,9 @@
     </div>
 
     <div *ngIf="isRegularPlaylist(playlist)" class="video-playlist-buttons">
-      <my-delete-button (click)="deleteVideoPlaylist(playlist)"></my-delete-button>
+      <my-delete-button label (click)="deleteVideoPlaylist(playlist)"></my-delete-button>
 
-      <my-edit-button [routerLink]="[ 'update', playlist.uuid ]"></my-edit-button>
+      <my-edit-button label [routerLink]="[ 'update', playlist.uuid ]"></my-edit-button>
     </div>
   </div>
 </div>
index faeb3b56cfa0f2735be012283dca57148c2162b6..779b42ab77037ab0700998f2872434de970ed5e1 100644 (file)
@@ -31,9 +31,9 @@
 
   <ng-template ptTemplate="rowButtons" let-video>
     <div class="action-button">
-      <my-delete-button (click)="deleteVideo(video)"></my-delete-button>
+      <my-delete-button label (click)="deleteVideo(video)"></my-delete-button>
 
-      <my-edit-button [routerLink]="[ '/videos', 'update', video.uuid ]"></my-edit-button>
+      <my-edit-button label [routerLink]="[ '/videos', 'update', video.uuid ]"></my-edit-button>
 
       <my-button i18n-label label="Change ownership"
                  className="action-button-change-ownership grey-button"
index 8eccd5c3c5fddda53246ca2e615f24a491c80a4e..65e06f7a4ddeb22ddd15260e0828760f0d426492 100644 (file)
@@ -1,8 +1,8 @@
-<span class="action-button" [ngClass]="getClasses()" [title]="getTitle()" tabindex="0">
+<span class="action-button" [ngClass]="getClasses()" [ngbTooltip]="getTitle()" tabindex="0">
   <my-global-icon *ngIf="!loading" [iconName]="icon"></my-global-icon>
   <my-small-loader [loading]="loading"></my-small-loader>
 
-  <span class="button-label">{{ label }}</span>
+  <span *ngIf="label" class="button-label">{{ label }}</span>
 
   <ng-content></ng-content>
 </span>
index 06fde9f1d41320f59ce223c460368666adb8102d..f73b7b8087ad903809fd02ce00edbafd243e0594 100644 (file)
@@ -1,6 +1,10 @@
 @import '_variables';
 @import '_mixins';
 
+:host {
+  outline: none;
+}
+
 my-small-loader ::ng-deep .root {
   display: inline-block;
   margin: 0 3px 0 0;
index 6643e6013ae8f610f865d62fb33fca914a352693..c94d8d0c9c8c2ef5f561e5cfe8eabce91f3adb6d 100644 (file)
@@ -1,6 +1,5 @@
-<span class="action-button action-button-delete grey-button" [title]="title" role="button" tabindex="0">
+<span class="action-button action-button-delete grey-button" [ngbTooltip]="title" role="button" tabindex="0">
   <my-global-icon iconName="delete" aria-hidden="true"></my-global-icon>
 
   <span class="button-label" *ngIf="label">{{ label }}</span>
-  <span class="button-label" i18n *ngIf="!label">Delete</span>
 </span>
index 39e31900fa3998423dba23683688bfc3b554575b..aced0f881308b788bbe2d3448b8af4c81505e794 100644 (file)
@@ -9,12 +9,23 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 
 export class DeleteButtonComponent implements OnInit {
   @Input() label: string
-
-  title: string
+  @Input() title: string
 
   constructor (private i18n: I18n) { }
 
   ngOnInit () {
-    this.title = this.label || this.i18n('Delete')
+    // <my-delete-button /> No label
+    if (this.label === undefined && !this.title) {
+      this.title = this.i18n('Delete')
+    }
+
+    // <my-delete-button label /> Use default label
+    if (this.label === '') {
+      this.label = this.i18n('Delete')
+
+      if (!this.title) {
+        this.title = this.label
+      }
+    }
   }
 }
index 4ffc563d980448bebd6c074abe93b40ad7e24489..ecb709be1c8d88045d878c022851c567a9b144a4 100644 (file)
@@ -1,6 +1,5 @@
-<a class="action-button action-button-edit grey-button" [routerLink]="routerLink" i18n-title title="Update">
+<a class="action-button action-button-edit grey-button" [routerLink]="routerLink" [ngbTooltip]="title">
   <my-global-icon iconName="edit" aria-hidden="true"></my-global-icon>
 
   <span class="button-label" *ngIf="label">{{ label }}</span>
-  <span class="button-label" i18n *ngIf="!label">Update</span>
 </a>
index 9cfe1a3bbd062ae2665b9ed8a6d675589e6c3794..d8ae39b84c58c290a206aa7a97bb54bd9a60c6bb 100644 (file)
@@ -1,4 +1,5 @@
-import { Component, Input } from '@angular/core'
+import { Component, Input, OnInit } from '@angular/core'
+import { I18n } from '@ngx-translate/i18n-polyfill'
 
 @Component({
   selector: 'my-edit-button',
@@ -6,7 +7,26 @@ import { Component, Input } from '@angular/core'
   templateUrl: './edit-button.component.html'
 })
 
-export class EditButtonComponent {
+export class EditButtonComponent implements OnInit {
   @Input() label: string
+  @Input() title: string
   @Input() routerLink: string[] | string = []
+
+  constructor (private i18n: I18n) { }
+
+  ngOnInit () {
+    // <my-edit-button /> No label
+    if (this.label === undefined && !this.title) {
+      this.title = this.i18n('Update')
+    }
+
+    // <my-edit-button label /> Use default label
+    if (this.label === '') {
+      this.label = this.i18n('Update')
+
+      if (!this.title) {
+        this.title = this.label
+      }
+    }
+  }
 }
index df98cf84e6e418647254285b848992e31e0db047..5af1095f1cdefaff93b8e65d13c10fa0e2713bee 100644 (file)
 
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 150px;">Action</th> <!-- column for action buttons -->
       <th style="width: 100%;" i18n>Account</th>
       <th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
-      <th style="width: 150px;"></th> <!-- column for action buttons -->
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-accountBlock>
     <tr>
+      <td class="action-cell">
+        <button class="unblock-button" (click)="unblockAccount(accountBlock)" i18n>Unmute</button>
+      </td>
       <td>
         <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
           <div class="chip two-lines">
@@ -50,9 +53,6 @@
       </td>
 
       <td>{{ accountBlock.createdAt | date: 'short' }}</td>
-      <td class="action-cell">
-        <button class="unblock-button" (click)="unblockAccount(accountBlock)" i18n>Unmute</button>
-      </td>
     </tr>
   </ng-template>
 
index 4621414d9c960087a400e5d6d6b3b7d2d0e0a1e7..598e1a42c0eaed45ffb18825011812eef1b7da0a 100644 (file)
 
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 150px;">Action</th> <!-- column for action buttons -->
       <th style="width: 100%;" i18n>Instance</th>
       <th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
-      <th style="width: 150px;"></th> <!-- column for action buttons -->
     </tr>
   </ng-template>
 
   <ng-template pTemplate="body" let-serverBlock>
     <tr>
+      <td class="action-cell">
+        <button class="unblock-button" (click)="unblockServer(serverBlock)" i18n>Unmute</button>
+      </td>
       <td>
         <a [href]="'https://' + serverBlock.blockedServer.host" i18n-title title="Open instance in a new tab" target="_blank" rel="noopener noreferrer">
           {{ serverBlock.blockedServer.host }}
@@ -43,9 +46,6 @@
         </a>
       </td>
       <td>{{ serverBlock.createdAt | date: 'short' }}</td>
-      <td class="action-cell">
-        <button class="unblock-button" (click)="unblockServer(serverBlock)" i18n>Unmute</button>
-      </td>
     </tr>
   </ng-template>
 
index 78c2658df60f91f9d9846a8dc77c07d0356c0f50..34fa7366cc4fd257223fabf80a44b1f200a9dd97 100644 (file)
@@ -19,7 +19,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
   @Input() prependActions: DropdownAction<{ user: User, account: Account }>[]
 
   @Input() buttonSize: 'normal' | 'small' = 'normal'
-  @Input() placement = 'left-top left-bottom auto'
+  @Input() placement = 'right-top right-bottom auto'
   @Input() label: string
   @Input() container: 'body' | undefined = undefined