[EC-1074] fix: block interaction during async action (#4732)

The user is able to interact with vault-items while actions like delete are happening. This commit is a temporary fix to disable all interaction surfaces during those async actions.
This commit is contained in:
Andreas Coroiu 2023-02-15 09:01:09 +01:00 committed by GitHub
parent 4e4de9812e
commit 957ed50c82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 5 deletions

View File

@ -16,6 +16,7 @@
type="checkbox" type="checkbox"
bitCheckbox bitCheckbox
id="checkAll" id="checkAll"
[disabled]="isProcessingAction"
(change)="checkAll($any($event.target).checked)" (change)="checkAll($any($event.target).checked)"
[(ngModel)]="isAllChecked" [(ngModel)]="isAllChecked"
/> />
@ -33,6 +34,7 @@
<th bitCell class="tw-min-w-fit tw-text-right"> <th bitCell class="tw-min-w-fit tw-text-right">
<button <button
[bitMenuTriggerFor]="headerMenu" [bitMenuTriggerFor]="headerMenu"
[disabled]="isProcessingAction"
bitIconButton="bwi-ellipsis-v" bitIconButton="bwi-ellipsis-v"
size="small" size="small"
type="button" type="button"
@ -77,8 +79,8 @@
<tr <tr
bitRow bitRow
*ngFor="let col of filteredCollections" *ngFor="let col of filteredCollections"
(click)="navigateCollection(col)" [class.tw-cursor-pointer]="!isProcessingAction"
class="tw-cursor-pointer" (click)="!isProcessingAction && navigateCollection(col)"
alignContent="middle" alignContent="middle"
> >
<td bitCell (click)="checkRow(col)" appStopProp> <td bitCell (click)="checkRow(col)" appStopProp>
@ -87,6 +89,7 @@
class="tw-cursor-pointer" class="tw-cursor-pointer"
type="checkbox" type="checkbox"
bitCheckbox bitCheckbox
[disabled]="isProcessingAction"
[(ngModel)]="$any(col).checked" [(ngModel)]="$any(col).checked"
appStopProp appStopProp
/> />
@ -102,6 +105,7 @@
class="tw-text-start" class="tw-text-start"
linkType="secondary" linkType="secondary"
(click)="navigateCollection(col)" (click)="navigateCollection(col)"
[disabled]="isProcessingAction"
> >
{{ col.node.name }} {{ col.node.name }}
</button> </button>
@ -128,6 +132,7 @@
<button <button
*ngIf="canEditCollection(col.node) || canDeleteCollection(col.node)" *ngIf="canEditCollection(col.node) || canDeleteCollection(col.node)"
[bitMenuTriggerFor]="collectionOptions" [bitMenuTriggerFor]="collectionOptions"
[disabled]="isProcessingAction"
size="small" size="small"
bitIconButton="bwi-ellipsis-v" bitIconButton="bwi-ellipsis-v"
type="button" type="button"
@ -167,12 +172,18 @@
<tr <tr
bitRow bitRow
*ngFor="let c of filteredCiphers" *ngFor="let c of filteredCiphers"
class="tw-cursor-pointer" [class.tw-cursor-pointer]="!isProcessingAction"
(click)="selectCipher(c)" (click)="!isProcessingAction && selectCipher(c)"
alignContent="middle" alignContent="middle"
> >
<td bitCell (click)="checkRow(c)" appStopProp> <td bitCell (click)="checkRow(c)" appStopProp>
<input type="checkbox" bitCheckbox [(ngModel)]="$any(c).checked" appStopProp /> <input
type="checkbox"
bitCheckbox
[disabled]="isProcessingAction"
[(ngModel)]="$any(c).checked"
appStopProp
/>
</td> </td>
<td bitCell> <td bitCell>
<app-vault-icon [cipher]="c"></app-vault-icon> <app-vault-icon [cipher]="c"></app-vault-icon>
@ -185,6 +196,7 @@
[queryParams]="{ itemId: c.id }" [queryParams]="{ itemId: c.id }"
queryParamsHandling="merge" queryParamsHandling="merge"
title="{{ 'editItem' | i18n }}" title="{{ 'editItem' | i18n }}"
[disabled]="isProcessingAction"
> >
{{ c.name }} {{ c.name }}
</button> </button>
@ -230,6 +242,7 @@
<td bitCell class="tw-text-right"> <td bitCell class="tw-text-right">
<button <button
[bitMenuTriggerFor]="cipherOptions" [bitMenuTriggerFor]="cipherOptions"
[disabled]="isProcessingAction"
size="small" size="small"
bitIconButton="bwi-ellipsis-v" bitIconButton="bwi-ellipsis-v"
type="button" type="button"

View File

@ -530,6 +530,13 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnDe
return false; // Always return false for non org vault return false; // Always return false for non org vault
} }
/**
* @deprecated Block interaction using long running modal dialog instead
*/
protected get isProcessingAction() {
return this.actionPromise != null;
}
protected updateSearchedCollections(collections: TreeNode<CollectionFilter>[]) { protected updateSearchedCollections(collections: TreeNode<CollectionFilter>[]) {
if (this.searchService.isSearchable(this.searchText)) { if (this.searchService.isSearchable(this.searchText)) {
this.searchedCollections = this.searchPipe.transform( this.searchedCollections = this.searchPipe.transform(

View File

@ -310,6 +310,13 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnDe
} }
} }
/**
* @deprecated Block interaction using long running modal dialog instead
*/
protected get isProcessingAction() {
return this.actionPromise != null;
}
protected deleteCipherWithServer(id: string, permanent: boolean) { protected deleteCipherWithServer(id: string, permanent: boolean) {
if (!this.organization?.canEditAnyCollection) { if (!this.organization?.canEditAnyCollection) {
return super.deleteCipherWithServer(id, this.deleted); return super.deleteCipherWithServer(id, this.deleted);