1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 22:03:36 +00:00

[PS-787] Emergency access page UI issues (#2864)

* Add loading spinner to emergency access page

* Update options menu to use new triple-dot menu

* Fix broken save button spinner

* Use bitButton directive

* Prettier fix
This commit is contained in:
Shane Melton
2022-06-08 13:17:46 -07:00
committed by GitHub
parent d5112cc8cb
commit 1a0695d366
3 changed files with 119 additions and 116 deletions

View File

@@ -101,28 +101,29 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button <button
#submitBtn bitButton
type="submit" type="submit"
class="btn btn-primary" buttonType="primary"
[disabled]="loading || submitBtn.loading || readOnly" [disabled]="loading || form.loading || readOnly"
> >
<i <i
class="bwi bwi-spinner bwi-spin" class="bwi bwi-spinner bwi-spin"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
*ngIf="loading || submitBtn.loading" *ngIf="loading || form.loading"
></i> ></i>
<span *ngIf="!loading && !submitBtn.loading">{{ "save" | i18n }}</span> <span *ngIf="!loading && !form.loading">{{ "save" | i18n }}</span>
</button> </button>
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal"> <button bitButton buttonType="secondary" type="button" data-dismiss="modal">
{{ "cancel" | i18n }} {{ "cancel" | i18n }}
</button> </button>
<div class="ml-auto"> <div class="ml-auto">
<button <button
#deleteBtn #deleteBtn
bitButton
buttonType="danger"
type="button" type="button"
(click)="delete()" (click)="delete()"
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="deleteBtn.loading"

View File

@@ -74,73 +74,71 @@
<small class="text-muted d-block" *ngIf="c.name">{{ c.name }}</small> <small class="text-muted d-block" *ngIf="c.name">{{ c.name }}</small>
</td> </td>
<td class="table-list-options"> <td class="table-list-options">
<div class="dropdown" appListDropdown>
<button <button
class="btn btn-outline-secondary dropdown-toggle" [bitMenuTriggerFor]="trustedContactOptions"
class="tw-border-none tw-bg-transparent tw-text-main"
type="button" type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
appA11yTitle="{{ 'options' | i18n }}" appA11yTitle="{{ 'options' | i18n }}"
> >
<i class="bwi bwi-cog bwi-lg" aria-hidden="true"></i> <i class="bwi bwi-ellipsis-v bwi-lg" aria-hidden="true"></i>
</button> </button>
<div class="dropdown-menu dropdown-menu-right"> <bit-menu #trustedContactOptions>
<a <button
class="dropdown-item" bitMenuItem
href="#"
appStopClick
(click)="reinvite(c)"
*ngIf="c.status === emergencyAccessStatusType.Invited" *ngIf="c.status === emergencyAccessStatusType.Invited"
(click)="reinvite(c)"
> >
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
{{ "resendInvitation" | i18n }} {{ "resendInvitation" | i18n }}
</a> </button>
<a <button
class="dropdown-item text-success" bitMenuItem
href="#"
appStopClick
(click)="confirm(c)"
*ngIf="c.status === emergencyAccessStatusType.Accepted" *ngIf="c.status === emergencyAccessStatusType.Accepted"
(click)="confirm(c)"
> >
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
{{ "confirm" | i18n }} {{ "confirm" | i18n }}
</a> </button>
<a <button
class="dropdown-item text-success" bitMenuItem
href="#"
appStopClick
(click)="approve(c)"
*ngIf="c.status === emergencyAccessStatusType.RecoveryInitiated" *ngIf="c.status === emergencyAccessStatusType.RecoveryInitiated"
(click)="approve(c)"
> >
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
{{ "approve" | i18n }} {{ "approve" | i18n }}
</a> </button>
<a <button
class="dropdown-item text-warning" bitMenuItem
href="#"
appStopClick
(click)="reject(c)"
*ngIf=" *ngIf="
c.status === emergencyAccessStatusType.RecoveryInitiated || c.status === emergencyAccessStatusType.RecoveryInitiated ||
c.status === emergencyAccessStatusType.RecoveryApproved c.status === emergencyAccessStatusType.RecoveryApproved
" "
(click)="reject(c)"
> >
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
{{ "reject" | i18n }} {{ "reject" | i18n }}
</a> </button>
<a class="dropdown-item text-danger" href="#" appStopClick (click)="remove(c)"> <button bitMenuItem (click)="remove(c)">
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
{{ "remove" | i18n }} {{ "remove" | i18n }}
</a> </button>
</div> </bit-menu>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p *ngIf="!trustedContacts || !trustedContacts.length">{{ "noTrustedContacts" | i18n }}</p> <ng-container *ngIf="!trustedContacts || !trustedContacts.length">
<p *ngIf="loaded">{{ "noTrustedContacts" | i18n }}</p>
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "loading" | i18n }}</span>
</ng-container>
</ng-container>
<div class="page-header spaced-header"> <div class="page-header spaced-header">
<h2>{{ "designatedEmergencyContacts" | i18n }}</h2> <h2>{{ "designatedEmergencyContacts" | i18n }}</h2>
@@ -190,64 +188,66 @@
<small class="text-muted d-block" *ngIf="c.name">{{ c.name }}</small> <small class="text-muted d-block" *ngIf="c.name">{{ c.name }}</small>
</td> </td>
<td class="table-list-options"> <td class="table-list-options">
<div class="dropdown" appListDropdown>
<button <button
class="btn btn-outline-secondary dropdown-toggle" [bitMenuTriggerFor]="grantedContactOptions"
class="tw-border-none tw-bg-transparent tw-text-main"
type="button" type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
appA11yTitle="{{ 'options' | i18n }}" appA11yTitle="{{ 'options' | i18n }}"
> >
<i class="bwi bwi-cog bwi-lg" aria-hidden="true"></i> <i class="bwi bwi-ellipsis-v bwi-lg" aria-hidden="true"></i>
</button> </button>
<div class="dropdown-menu dropdown-menu-right"> <bit-menu #grantedContactOptions>
<a <button
class="dropdown-item" bitMenuItem
href="#"
appStopClick
(click)="requestAccess(c)"
*ngIf="c.status === emergencyAccessStatusType.Confirmed" *ngIf="c.status === emergencyAccessStatusType.Confirmed"
(click)="requestAccess(c)"
> >
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
{{ "requestAccess" | i18n }} {{ "requestAccess" | i18n }}
</a> </button>
<a <button
class="dropdown-item" bitMenuItem
href="#"
appStopClick
(click)="takeover(c)"
*ngIf=" *ngIf="
c.status === emergencyAccessStatusType.RecoveryApproved && c.status === emergencyAccessStatusType.RecoveryApproved &&
c.type === emergencyAccessType.Takeover c.type === emergencyAccessType.Takeover
" "
(click)="takeover(c)"
> >
<i class="bwi bwi-fw bwi-key" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-key" aria-hidden="true"></i>
{{ "takeover" | i18n }} {{ "takeover" | i18n }}
</a> </button>
<a <button
class="dropdown-item" bitMenuItem
[routerLink]="c.id"
*ngIf=" *ngIf="
c.status === emergencyAccessStatusType.RecoveryApproved && c.status === emergencyAccessStatusType.RecoveryApproved &&
c.type === emergencyAccessType.View c.type === emergencyAccessType.View
" "
[routerLink]="c.id"
> >
<i class="bwi bwi-fw bwi-eye" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-eye" aria-hidden="true"></i>
{{ "view" | i18n }} {{ "view" | i18n }}
</a> </button>
<a class="dropdown-item text-danger" href="#" appStopClick (click)="remove(c)"> <button bitMenuItem (click)="remove(c)">
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
{{ "remove" | i18n }} {{ "remove" | i18n }}
</a> </button>
</div> </bit-menu>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p *ngIf="!grantedContacts || !grantedContacts.length">{{ "noGrantedAccess" | i18n }}</p> <ng-container *ngIf="!grantedContacts || !grantedContacts.length">
<p *ngIf="loaded">{{ "noGrantedAccess" | i18n }}</p>
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "loading" | i18n }}</span>
</ng-container>
</ng-container>
<ng-template #addEdit></ng-template> <ng-template #addEdit></ng-template>
<ng-template #takeoverTemplate></ng-template> <ng-template #takeoverTemplate></ng-template>

View File

@@ -34,6 +34,7 @@ export class EmergencyAccessComponent implements OnInit {
@ViewChild("confirmTemplate", { read: ViewContainerRef, static: true }) @ViewChild("confirmTemplate", { read: ViewContainerRef, static: true })
confirmModalRef: ViewContainerRef; confirmModalRef: ViewContainerRef;
loaded = false;
canAccessPremium: boolean; canAccessPremium: boolean;
trustedContacts: EmergencyAccessGranteeDetailsResponse[]; trustedContacts: EmergencyAccessGranteeDetailsResponse[];
grantedContacts: EmergencyAccessGrantorDetailsResponse[]; grantedContacts: EmergencyAccessGrantorDetailsResponse[];
@@ -65,6 +66,7 @@ export class EmergencyAccessComponent implements OnInit {
async load() { async load() {
this.trustedContacts = (await this.apiService.getEmergencyAccessTrusted()).data; this.trustedContacts = (await this.apiService.getEmergencyAccessTrusted()).data;
this.grantedContacts = (await this.apiService.getEmergencyAccessGranted()).data; this.grantedContacts = (await this.apiService.getEmergencyAccessGranted()).data;
this.loaded = true;
} }
async premiumRequired() { async premiumRequired() {