1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 21:33:27 +00:00

[SM-252] Enable strict templates (#3601)

This commit is contained in:
Oscar Hinton
2022-11-28 18:59:46 +01:00
committed by GitHub
parent b312f6b925
commit d994faa8a6
97 changed files with 302 additions and 301 deletions

View File

@@ -39,13 +39,10 @@
<div class="box-content-row" appBoxRow> <div class="box-content-row" appBoxRow>
<div class="box-content-row-flex"> <div class="box-content-row-flex">
<div class="row-main"> <div class="row-main">
<label for="masterPassword" <label for="masterPassword">
>{{ "masterPass" | i18n }} {{ "masterPass" | i18n }}
<strong <strong class="sub-label text-{{ color }}" *ngIf="text">
class="sub-label text-{{ passwordStrengthComponent?.masterPasswordScoreColor }}" {{ text }}
*ngIf="passwordStrengthComponent?.masterPasswordScoreText"
>
{{ passwordStrengthComponent?.masterPasswordScoreText }}
</strong> </strong>
</label> </label>
<input <input

View File

@@ -86,7 +86,9 @@
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="selectedProviderType === providerType.WebAuthn && !webAuthnNewTab"> <ng-container *ngIf="selectedProviderType === providerType.WebAuthn && !webAuthnNewTab">
<div id="web-authn-frame"><iframe id="webauthn_iframe" [allow]="webAuthnAllow"></iframe></div> <div id="web-authn-frame">
<iframe id="webauthn_iframe" [attr.allow]="webAuthnAllow"></iframe>
</div>
<div class="box"> <div class="box">
<div class="box-content"> <div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow> <div class="box-content-row box-content-row-checkbox" appBoxRow>

View File

@@ -57,11 +57,11 @@
appStopClick appStopClick
appA11yTitle="{{ 'regenerateUsername' | i18n }}" appA11yTitle="{{ 'regenerateUsername' | i18n }}"
(click)="regenerate()" (click)="regenerate()"
[disabled]="form.loading" [disabled]="$any(form).loading"
> >
<i <i
class="bwi bwi-lg bwi-generate" class="bwi bwi-lg bwi-generate"
[ngClass]="form.loading ? 'bwi-spin' : ''" [ngClass]="$any(form).loading ? 'bwi-spin' : ''"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -305,8 +305,11 @@
> >
<div class="row-main text-danger"> <div class="row-main text-danger">
<div class="icon text-danger" aria-hidden="true"> <div class="icon text-danger" aria-hidden="true">
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading"></i> <i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="$any(deleteBtn).loading"></i>
<i class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" [hidden]="!deleteBtn.loading"></i> <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!$any(deleteBtn).loading"
></i>
</div> </div>
<span>{{ "deleteSend" | i18n }}</span> <span>{{ "deleteSend" | i18n }}</span>
</div> </div>

View File

@@ -40,8 +40,11 @@
> >
<div class="row-main text-danger"> <div class="row-main text-danger">
<div class="icon text-danger" aria-hidden="true"> <div class="icon text-danger" aria-hidden="true">
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading"></i> <i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="$any(deleteBtn).loading"></i>
<i class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" [hidden]="!deleteBtn.loading"></i> <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!$any(deleteBtn).loading"
></i>
</div> </div>
<span>{{ "deleteFolder" | i18n }}</span> <span>{{ "deleteFolder" | i18n }}</span>
</div> </div>

View File

@@ -49,14 +49,14 @@
#refreshBtn #refreshBtn
type="button" type="button"
(click)="refresh()" (click)="refresh()"
[disabled]="refreshBtn.loading" [disabled]="$any(refreshBtn).loading"
[appApiAction]="refreshPromise" [appApiAction]="refreshPromise"
class="btn link block" class="btn link block"
> >
<span [hidden]="refreshBtn.loading">{{ "premiumRefresh" | i18n }}</span> <span [hidden]="$any(refreshBtn).loading">{{ "premiumRefresh" | i18n }}</span>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!refreshBtn.loading" [hidden]="!$any(refreshBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -17,11 +17,15 @@
class="btn block primary" class="btn block primary"
(click)="sync()" (click)="sync()"
#syncBtn #syncBtn
[disabled]="syncBtn.loading" [disabled]="$any(syncBtn).loading"
[appApiAction]="syncPromise" [appApiAction]="syncPromise"
> >
<span [hidden]="syncBtn.loading">{{ "syncVaultNow" | i18n }}</span> <span [hidden]="$any(syncBtn).loading">{{ "syncVaultNow" | i18n }}</span>
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!syncBtn.loading" aria-hidden="true"></i> <i
class="bwi bwi-spinner bwi-lg bwi-spin"
[hidden]="!$any(syncBtn).loading"
aria-hidden="true"
></i>
</button> </button>
<p class="text-center text-muted small">{{ "lastSync" | i18n }} {{ lastSync }}</p> <p class="text-center text-muted small">{{ "lastSync" | i18n }} {{ lastSync }}</p>
</div> </div>

View File

@@ -81,8 +81,8 @@
[(ngModel)]="f.value" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean" *ngIf="f.type === fieldType.Boolean"
appTrueFalseValue appTrueFalseValue
trueValue="true" [trueValue]="true"
falseValue="false" [falseValue]="false"
attr.aria-describedby="fieldName{{ i }}" attr.aria-describedby="fieldName{{ i }}"
[readonly]="!cipher.edit && editMode" [readonly]="!cipher.edit && editMode"
/> />

View File

@@ -88,17 +88,17 @@
appA11yTitle="{{ 'checkPassword' | i18n }}" appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()" (click)="checkPassword()"
[appApiAction]="checkPasswordPromise" [appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading" [disabled]="$any(checkPasswordBtn).loading"
*ngIf="cipher.viewPassword" *ngIf="cipher.viewPassword"
> >
<i <i
class="bwi bwi-lg bwi-check-circle" class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading" [hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-lg bwi-spinner bwi-spin" class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading" [hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>
@@ -487,7 +487,7 @@
type="text" type="text"
name="Login.Uris[{{ i }}].Uri" name="Login.Uris[{{ i }}].Uri"
[(ngModel)]="u.uri" [(ngModel)]="u.uri"
[hidden]="u.showUriOptionsInput === true" [hidden]="$any(u).showUriOptionsInput === true"
placeholder="{{ 'ex' | i18n }} https://google.com" placeholder="{{ 'ex' | i18n }} https://google.com"
inputmode="url" inputmode="url"
appInputVerbatim appInputVerbatim
@@ -500,7 +500,7 @@
id="currentUris{{ i }}" id="currentUris{{ i }}"
name="Login.Uris[{{ i }}].CurrentUris" name="Login.Uris[{{ i }}].CurrentUris"
[(ngModel)]="u.uri" [(ngModel)]="u.uri"
[hidden]="!u.showCurrentUris" [hidden]="!$any(u).showCurrentUris"
> >
<option [ngValue]="null">-- {{ "select" | i18n }} --</option> <option [ngValue]="null">-- {{ "select" | i18n }} --</option>
<option *ngFor="let u of currentUris" [ngValue]="u">{{ u }}</option> <option *ngFor="let u of currentUris" [ngValue]="u">{{ u }}</option>
@@ -512,7 +512,9 @@
id="loginUriMatch{{ i }}" id="loginUriMatch{{ i }}"
name="Login.Uris[{{ i }}].Match" name="Login.Uris[{{ i }}].Match"
[(ngModel)]="u.match" [(ngModel)]="u.match"
[hidden]="u.showOptions === false || (u.showOptions == null && u.match == null)" [hidden]="
$any(u).showOptions === false || ($any(u).showOptions == null && u.match == null)
"
(change)="loginUriMatchChanged(u)" (change)="loginUriMatchChanged(u)"
> >
<option *ngFor="let o of uriMatchOptions" [ngValue]="o.value">{{ o.name }}</option> <option *ngFor="let o of uriMatchOptions" [ngValue]="o.value">{{ o.name }}</option>
@@ -526,7 +528,7 @@
appStopClick appStopClick
appA11yTitle="{{ 'toggleCurrentUris' | i18n }}" appA11yTitle="{{ 'toggleCurrentUris' | i18n }}"
(click)="toggleUriInput(u)" (click)="toggleUriInput(u)"
[attr.aria-pressed]="u.showCurrentUris === true" [attr.aria-pressed]="$any(u).showCurrentUris === true"
> >
<i aria-hidden="true" class="bwi bwi-lg bwi-list"></i> <i aria-hidden="true" class="bwi bwi-lg bwi-list"></i>
</button> </button>
@@ -536,7 +538,7 @@
appStopClick appStopClick
appA11yTitle="{{ 'toggleOptions' | i18n }}" appA11yTitle="{{ 'toggleOptions' | i18n }}"
(click)="toggleUriOptions(u)" (click)="toggleUriOptions(u)"
[attr.aria-pressed]="u.showOptions === true" [attr.aria-pressed]="$any(u).showOptions === true"
> >
<i class="bwi bwi-lg bwi-cog" aria-hidden="true"></i> <i class="bwi bwi-lg bwi-cog" aria-hidden="true"></i>
</button> </button>
@@ -695,7 +697,7 @@
<input <input
id="collection_{{ i }}" id="collection_{{ i }}"
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
/> />
</div> </div>
@@ -713,8 +715,11 @@
> >
<div class="row-main text-danger"> <div class="row-main text-danger">
<div class="icon text-danger" aria-hidden="true"> <div class="icon text-danger" aria-hidden="true">
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading"></i> <i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="$any(deleteBtn).loading"></i>
<i class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" [hidden]="!deleteBtn.loading"></i> <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!$any(deleteBtn).loading"
></i>
</div> </div>
<span>{{ "deleteItem" | i18n }}</span> <span>{{ "deleteItem" | i18n }}</span>
</div> </div>

View File

@@ -37,16 +37,16 @@
(click)="delete(a)" (click)="delete(a)"
#deleteBtn #deleteBtn
[appApiAction]="deletePromises[a.id]" [appApiAction]="deletePromises[a.id]"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -33,7 +33,7 @@
<input <input
id="collection_{{ i }}" id="collection_{{ i }}"
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
/> />
</div> </div>

View File

@@ -200,7 +200,7 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
} }
} }
private async load() { protected async load() {
this.isLoading = false; this.isLoading = false;
this.tab = await BrowserApi.getTabFromCurrentWindow(); this.tab = await BrowserApi.getTabFromCurrentWindow();
if (this.tab != null) { if (this.tab != null) {

View File

@@ -27,11 +27,7 @@
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
> >
<button <button appStopClick (click)="selectAllVaults()">
appStopClick
(click)="selectAllVaults()"
[ngClass]="{ active: !myVaultOnly && !selectOrganizationId }"
>
<i class="bwi bwi-fw bwi-filter" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-filter" aria-hidden="true"></i>
&nbsp;{{ "allVaults" | i18n }} &nbsp;{{ "allVaults" | i18n }}
</button> </button>
@@ -60,7 +56,7 @@
<i <i
*ngIf="!organization.enabled" *ngIf="!organization.enabled"
class="bwi bwi-fw bwi-exclamation-triangle text-danger" class="bwi bwi-fw bwi-exclamation-triangle text-danger"
aria-label="{{ 'organizationIsDisabled' | i18n }}" attr.aria-label="{{ 'organizationIsDisabled' | i18n }}"
appA11yTitle="{{ 'organizationIsDisabled' | i18n }}" appA11yTitle="{{ 'organizationIsDisabled' | i18n }}"
></i> ></i>
</button> </button>

View File

@@ -88,17 +88,17 @@
appA11yTitle="{{ 'checkPassword' | i18n }}" appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()" (click)="checkPassword()"
[appApiAction]="checkPasswordPromise" [appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading" [disabled]="$any(checkPasswordBtn).loading"
*ngIf="cipher.viewPassword" *ngIf="cipher.viewPassword"
> >
<i <i
class="bwi bwi-lg bwi-check-circle" class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading" [hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-lg bwi-spinner bwi-spin" class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading" [hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>
@@ -537,12 +537,12 @@
<small class="row-sub-label">{{ attachment.sizeName }}</small> <small class="row-sub-label">{{ attachment.sizeName }}</small>
<i <i
class="bwi bwi-download bwi-fw row-sub-icon" class="bwi bwi-download bwi-fw row-sub-icon"
*ngIf="!attachment.downloading" *ngIf="!$any(attachment).downloading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-fw bwi-spin row-sub-icon" class="bwi bwi-spinner bwi-fw bwi-spin row-sub-icon"
*ngIf="attachment.downloading" *ngIf="$any(attachment).downloading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -15,6 +15,7 @@
} }
}, },
"angularCompilerOptions": { "angularCompilerOptions": {
"strictTemplates": true,
"preserveWhitespaces": true "preserveWhitespaces": true
}, },
"include": ["src", "../../libs/common/src/services/**/*.worker.ts"] "include": ["src", "../../libs/common/src/services/**/*.worker.ts"]

View File

@@ -57,7 +57,7 @@
class="primary" class="primary"
(click)="purchase()" (click)="purchase()"
*ngIf="!isPremium" *ngIf="!isPremium"
[disabled]="purchaseBtn.loading" [disabled]="$any(purchaseBtn).loading"
> >
<b>{{ "premiumPurchase" | i18n }}</b> <b>{{ "premiumPurchase" | i18n }}</b>
</button> </button>
@@ -67,18 +67,18 @@
#refreshBtn #refreshBtn
type="button" type="button"
(click)="refresh()" (click)="refresh()"
[disabled]="refreshBtn.loading" [disabled]="$any(refreshBtn).loading"
appA11yTitle="{{ 'premiumRefresh' | i18n }}" appA11yTitle="{{ 'premiumRefresh' | i18n }}"
[appApiAction]="refreshPromise" [appApiAction]="refreshPromise"
> >
<i <i
class="bwi bwi-refresh bwi-lg bwi-fw" class="bwi bwi-refresh bwi-lg bwi-fw"
[hidden]="refreshBtn.loading" [hidden]="$any(refreshBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!refreshBtn.loading" [hidden]="!$any(refreshBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -65,7 +65,7 @@
</ng-container> </ng-container>
<ng-container *ngIf="selectedProviderType === providerType.WebAuthn"> <ng-container *ngIf="selectedProviderType === providerType.WebAuthn">
<div id="web-authn-frame"> <div id="web-authn-frame">
<iframe id="webauthn_iframe" [allow]="webAuthnAllow"></iframe> <iframe id="webauthn_iframe" [attr.allow]="webAuthnAllow"></iframe>
</div> </div>
<div class="box first"> <div class="box first">
<div class="box-content"> <div class="box-content">

View File

@@ -5,12 +5,7 @@ import { Utils } from "@bitwarden/common/misc/utils";
@Component({ @Component({
selector: "app-avatar", selector: "app-avatar",
template: `<img template: `<img *ngIf="src" [src]="src" [ngClass]="{ 'rounded-circle': circle }" />`,
*ngIf="src"
[src]="src"
title="{{ data }}"
[ngClass]="{ 'rounded-circle': circle }"
/>`,
}) })
export class AvatarComponent implements OnChanges, OnInit { export class AvatarComponent implements OnChanges, OnInit {
@Input() size = 45; @Input() size = 45;
@@ -20,7 +15,7 @@ export class AvatarComponent implements OnChanges, OnInit {
@Input() circle = false; @Input() circle = false;
@Input() color?: string; @Input() color?: string;
@Input() id?: number; @Input() id?: string;
@Input() text?: string; @Input() text?: string;
private svgCharCount = 2; private svgCharCount = 2;

View File

@@ -12,7 +12,7 @@
<app-avatar <app-avatar
[text]="activeAccount.name" [text]="activeAccount.name"
[id]="activeAccount.id" [id]="activeAccount.id"
size="25" [size]="25"
[circle]="true" [circle]="true"
[fontSize]="14" [fontSize]="14"
[dynamic]="true" [dynamic]="true"
@@ -61,7 +61,7 @@
<app-avatar <app-avatar
[text]="a.value.profile.name ?? a.value.profile.email" [text]="a.value.profile.name ?? a.value.profile.email"
[id]="a.value.profile.userId" [id]="a.value.profile.userId"
size="25" [size]="25"
[circle]="true" [circle]="true"
[fontSize]="14" [fontSize]="14"
[dynamic]="true" [dynamic]="true"

View File

@@ -35,7 +35,7 @@
name="Type_{{ o.value }}" name="Type_{{ o.value }}"
id="type_{{ o.value }}" id="type_{{ o.value }}"
[value]="o.value" [value]="o.value"
(change)="typeChanged(o)" (change)="typeChanged()"
[checked]="send.type === o.value" [checked]="send.type === o.value"
[disabled]="disableSend" [disabled]="disableSend"
/> />
@@ -280,10 +280,14 @@
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
> >
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i> <i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -46,7 +46,6 @@
formControlName="defaultExpirationDateTime" formControlName="defaultExpirationDateTime"
required required
placeholder="MM/DD/YYYY HH:MM AM/PM" placeholder="MM/DD/YYYY HH:MM AM/PM"
[readOnly]="disableSend"
/> />
<small *ngIf="editMode" class="help-block">{{ "expirationDateDesc" | i18n }}</small> <small *ngIf="editMode" class="help-block">{{ "expirationDateDesc" | i18n }}</small>
</div> </div>

View File

@@ -79,8 +79,8 @@
[(ngModel)]="f.value" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean" *ngIf="f.type === fieldType.Boolean"
appTrueFalseValue appTrueFalseValue
trueValue="true" [trueValue]="true"
falseValue="false" [falseValue]="false"
attr.aria-describedby="fieldName{{ i }}" attr.aria-describedby="fieldName{{ i }}"
[readonly]="!cipher.edit && editMode" [readonly]="!cipher.edit && editMode"
/> />

View File

@@ -75,16 +75,16 @@
appA11yTitle="{{ 'checkPassword' | i18n }}" appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()" (click)="checkPassword()"
[appApiAction]="checkPasswordPromise" [appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading" [disabled]="$any(checkPasswordBtn).loading"
> >
<i <i
class="bwi bwi-lg bwi-check-circle" class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading" [hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-lg bwi-spinner bwi-spin" class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading" [hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>
@@ -485,7 +485,10 @@
id="loginUriMatch{{ i }}" id="loginUriMatch{{ i }}"
name="Login.Uris[{{ i }}].Match" name="Login.Uris[{{ i }}].Match"
[(ngModel)]="u.match" [(ngModel)]="u.match"
[hidden]="u.showOptions === false || (u.showOptions == null && u.match == null)" [hidden]="
$any(u).showOptions === false ||
($any(u).showOptions == null && u.match == null)
"
(change)="loginUriMatchChanged(u)" (change)="loginUriMatchChanged(u)"
> >
<option *ngFor="let o of uriMatchOptions" [ngValue]="o.value"> <option *ngFor="let o of uriMatchOptions" [ngValue]="o.value">
@@ -501,7 +504,10 @@
appA11yTitle="{{ 'toggleOptions' | i18n }}" appA11yTitle="{{ 'toggleOptions' | i18n }}"
(click)="toggleUriOptions(u)" (click)="toggleUriOptions(u)"
[attr.aria-expanded]=" [attr.aria-expanded]="
!(u.showOptions === false || (u.showOptions == null && u.match == null)) !(
$any(u).showOptions === false ||
($any(u).showOptions == null && u.match == null)
)
" "
> >
<i class="bwi bwi-lg bwi-cog" aria-hidden="true"></i> <i class="bwi bwi-lg bwi-cog" aria-hidden="true"></i>
@@ -634,7 +640,7 @@
<input <input
id="collection_{{ i }}" id="collection_{{ i }}"
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
/> />
</div> </div>
@@ -647,12 +653,16 @@
type="submit" type="submit"
class="primary" class="primary"
appA11yTitle="{{ 'save' | i18n }}" appA11yTitle="{{ 'save' | i18n }}"
[disabled]="form.loading" [disabled]="$any(form).loading"
> >
<i class="bwi bwi-save-changes bwi-lg bwi-fw" [hidden]="form.loading" aria-hidden="true"></i> <i
class="bwi bwi-save-changes bwi-lg bwi-fw"
[hidden]="$any(form).loading"
aria-hidden="true"
></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!form.loading" [hidden]="!$any(form).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>
@@ -675,13 +685,17 @@
class="danger" class="danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode && !cloneMode" *ngIf="editMode && !cloneMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i> <i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -21,16 +21,16 @@
(click)="delete(a)" (click)="delete(a)"
#deleteBtn #deleteBtn
[appApiAction]="deletePromises[a.id]" [appApiAction]="deletePromises[a.id]"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -19,7 +19,7 @@
<input <input
id="collection_{{ i }}" id="collection_{{ i }}"
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
/> />
</div> </div>

View File

@@ -47,17 +47,17 @@
class="danger" class="danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -52,11 +52,11 @@
appStopClick appStopClick
appA11yTitle="{{ 'regenerateUsername' | i18n }}" appA11yTitle="{{ 'regenerateUsername' | i18n }}"
(click)="regenerate()" (click)="regenerate()"
[disabled]="form.loading" [disabled]="$any(form).loading"
> >
<i <i
class="bwi bwi-lg bwi-generate" class="bwi bwi-lg bwi-generate"
[ngClass]="form.loading ? 'bwi-spin' : ''" [ngClass]="$any(form).loading ? 'bwi-spin' : ''"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -112,7 +112,6 @@
<i <i
*ngIf="!organization.enabled" *ngIf="!organization.enabled"
class="bwi bwi-fw bwi-exclamation-triangle text-danger mr-auto" class="bwi bwi-fw bwi-exclamation-triangle text-danger mr-auto"
aria-label="{{ 'organizationIsDisabled' | i18n }}"
appA11yTitle="{{ 'organizationIsDisabled' | i18n }}" appA11yTitle="{{ 'organizationIsDisabled' | i18n }}"
></i> ></i>
</span> </span>

View File

@@ -64,16 +64,16 @@
appA11yTitle="{{ 'checkPassword' | i18n }}" appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()" (click)="checkPassword()"
[appApiAction]="checkPasswordPromise" [appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading" [disabled]="$any(checkPasswordBtn).loading"
> >
<i <i
class="bwi bwi-lg bwi-check-circle" class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading" [hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-lg bwi-spinner bwi-spin" class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading" [hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>
@@ -472,12 +472,12 @@
<small class="row-sub-label">{{ attachment.sizeName }}</small> <small class="row-sub-label">{{ attachment.sizeName }}</small>
<i <i
class="bwi bwi-download bwi-fw row-sub-icon" class="bwi bwi-download bwi-fw row-sub-icon"
*ngIf="!attachment.downloading" *ngIf="!$any(attachment).downloading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-fw bwi-spin row-sub-icon" class="bwi bwi-spinner bwi-fw bwi-spin row-sub-icon"
*ngIf="attachment.downloading" *ngIf="$any(attachment).downloading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>

View File

@@ -16,6 +16,7 @@
} }
}, },
"angularCompilerOptions": { "angularCompilerOptions": {
"strictTemplates": true,
"preserveWhitespaces": true "preserveWhitespaces": true
}, },
"include": ["src", "../../libs/common/src/services/**/*.worker.ts"] "include": ["src", "../../libs/common/src/services/**/*.worker.ts"]

View File

@@ -55,7 +55,7 @@
<!-- Teams & Enterprise Body --> <!-- Teams & Enterprise Body -->
<div *ngIf="layout === 'teams1' || layout === 'teams2' || layout === 'enterprise2'"> <div *ngIf="layout === 'teams1' || layout === 'teams2' || layout === 'enterprise2'">
<h1> <h1>
Start Your <span *ngIf="layout === 'teams1' || layout === 'teams1'">Teams<br /></span Start Your <span *ngIf="layout === 'teams1'">Teams<br /></span
><span *ngIf="layout === 'enterprise2'">Enterprise</span> Free Trial Now ><span *ngIf="layout === 'enterprise2'">Enterprise</span> Free Trial Now
</h1> </h1>
<h2> <h2>

View File

@@ -1,5 +1,7 @@
import { CdkStepper } from "@angular/cdk/stepper"; import { CdkStepper } from "@angular/cdk/stepper";
import { Component, Input } from "@angular/core"; import { Component, Input, QueryList } from "@angular/core";
import { VerticalStep } from "./vertical-step.component";
@Component({ @Component({
selector: "app-vertical-stepper", selector: "app-vertical-stepper",
@@ -7,6 +9,8 @@ import { Component, Input } from "@angular/core";
providers: [{ provide: CdkStepper, useExisting: VerticalStepperComponent }], providers: [{ provide: CdkStepper, useExisting: VerticalStepperComponent }],
}) })
export class VerticalStepperComponent extends CdkStepper { export class VerticalStepperComponent extends CdkStepper {
readonly steps: QueryList<VerticalStep>;
@Input() @Input()
activeClass = "active"; activeClass = "active";

View File

@@ -80,7 +80,7 @@
</ng-container> </ng-container>
<ng-container *ngIf="selectedProviderType === providerType.WebAuthn"> <ng-container *ngIf="selectedProviderType === providerType.WebAuthn">
<div id="web-authn-frame" class="mb-3"> <div id="web-authn-frame" class="mb-3">
<iframe id="webauthn_iframe" [allow]="webAuthnAllow"></iframe> <iframe id="webauthn_iframe" [attr.allow]="webAuthnAllow"></iframe>
</div> </div>
</ng-container> </ng-container>
<ng-container <ng-container

View File

@@ -0,0 +1,23 @@
import { animate, style, transition, trigger } from "@angular/animations";
import { Component } from "@angular/core";
import { NG_VALUE_ACCESSOR } from "@angular/forms";
import { UserVerificationComponent as BaseComponent } from "@bitwarden/angular/components/user-verification.component";
@Component({
selector: "app-user-verification",
templateUrl: "user-verification.component.html",
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: UserVerificationComponent,
},
],
animations: [
trigger("sent", [
transition(":enter", [style({ opacity: 0 }), animate("100ms", style({ opacity: 1 }))]),
]),
],
})
export class UserVerificationComponent extends BaseComponent {}

View File

@@ -44,7 +44,7 @@
class="btn btn-outline-secondary btn-submit" class="btn btn-outline-secondary btn-submit"
(click)="reinstate()" (click)="reinstate()"
[appApiAction]="reinstatePromise" [appApiAction]="reinstatePromise"
[disabled]="reinstateBtn.loading" [disabled]="$any(reinstateBtn).loading"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "reinstateSubscription" | i18n }}</span> <span>{{ "reinstateSubscription" | i18n }}</span>
@@ -113,8 +113,8 @@
</button> </button>
<app-change-plan <app-change-plan
[organizationId]="organizationId" [organizationId]="organizationId"
(onChanged)="closeChangePlan(true)" (onChanged)="closeChangePlan()"
(onCanceled)="closeChangePlan(false)" (onCanceled)="closeChangePlan()"
*ngIf="showChangePlan" *ngIf="showChangePlan"
></app-change-plan> ></app-change-plan>
</ng-container> </ng-container>
@@ -143,7 +143,7 @@
class="btn btn-outline-danger btn-submit" class="btn btn-outline-danger btn-submit"
(click)="removeSponsorship()" (click)="removeSponsorship()"
[appApiAction]="removeSponsorshipPromise" [appApiAction]="removeSponsorshipPromise"
[disabled]="removeSponsorshipBtn.loading" [disabled]="$any(removeSponsorshipBtn).loading"
*ngIf="isSponsoredSubscription" *ngIf="isSponsoredSubscription"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
@@ -230,7 +230,7 @@
class="btn btn-outline-danger btn-submit ml-1" class="btn btn-outline-danger btn-submit ml-1"
(click)="cancel()" (click)="cancel()"
[appApiAction]="cancelPromise" [appApiAction]="cancelPromise"
[disabled]="cancelBtn.loading" [disabled]="$any(cancelBtn).loading"
*ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel" *ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@@ -53,11 +53,13 @@
<div class="tw-flex tw-flex-col"> <div class="tw-flex tw-flex-col">
<div class="tw-text-sm"> <div class="tw-text-sm">
{{ item.labelName }} {{ item.labelName }}
<span *ngIf="item.status == 0" bitBadge badgeType="secondary"> <span *ngIf="$any(item).status == 0" bitBadge badgeType="secondary">
{{ "invited" | i18n }} {{ "invited" | i18n }}
</span> </span>
</div> </div>
<div class="tw-text-xs tw-text-muted" *ngIf="item.status != 0">{{ item.email }}</div> <div class="tw-text-xs tw-text-muted" *ngIf="$any(item).status != 0">
{{ $any(item).email }}
</div>
</div> </div>
</div> </div>
@@ -110,11 +112,11 @@
</td> </td>
<td bitCell *ngIf="showMemberRoles"> <td bitCell *ngIf="showMemberRoles">
{{ item.role | userType: "-" }} {{ $any(item).role | userType: "-" }}
</td> </td>
<td bitCell *ngIf="showGroupColumn"> <td bitCell *ngIf="showGroupColumn">
{{ item.viaGroupName ?? "-" }} {{ $any(item).viaGroupName ?? "-" }}
</td> </td>
<td bitCell> <td bitCell>

View File

@@ -81,7 +81,7 @@
<td class="table-list-checkbox" (click)="check(g)"> <td class="table-list-checkbox" (click)="check(g)">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="g.checked" [(ngModel)]="$any(g).checked"
name="Groups[{{ i }}].Checked" name="Groups[{{ i }}].Checked"
[disabled]="g.accessAll || !this.canSave" [disabled]="g.accessAll || !this.canSave"
appStopProp appStopProp
@@ -101,17 +101,17 @@
<td class="text-center"> <td class="text-center">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="g.hidePasswords" [(ngModel)]="$any(g).hidePasswords"
name="Groups[{{ i }}].HidePasswords" name="Groups[{{ i }}].HidePasswords"
[disabled]="!g.checked || g.accessAll || !this.canSave" [disabled]="!$any(g).checked || g.accessAll || !this.canSave"
/> />
</td> </td>
<td class="text-center"> <td class="text-center">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="g.readOnly" [(ngModel)]="$any(g).readOnly"
name="Groups[{{ i }}].ReadOnly" name="Groups[{{ i }}].ReadOnly"
[disabled]="!g.checked || g.accessAll || !this.canSave" [disabled]="!$any(g).checked || g.accessAll || !this.canSave"
/> />
</td> </td>
</tr> </tr>
@@ -140,17 +140,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -52,11 +52,11 @@
type="button" type="button"
class="btn btn-sm btn-outline-primary ml-3" class="btn btn-sm btn-outline-primary ml-3"
(click)="loadEvents(true)" (click)="loadEvents(true)"
[disabled]="loaded && refreshBtn.loading" [disabled]="loaded && $any(refreshBtn).loading"
> >
<i <i
class="bwi bwi-refresh bwi-fw" class="bwi bwi-refresh bwi-fw"
[ngClass]="{ 'bwi-spin': loaded && refreshBtn.loading }" [ngClass]="{ 'bwi-spin': loaded && $any(refreshBtn).loading }"
aria-hidden="true" aria-hidden="true"
></i> ></i>
{{ "refresh" | i18n }} {{ "refresh" | i18n }}
@@ -101,7 +101,7 @@
type="button" type="button"
class="btn btn-block btn-link btn-submit" class="btn btn-block btn-link btn-submit"
(click)="loadEvents(false)" (click)="loadEvents(false)"
[disabled]="loaded && moreBtn.loading" [disabled]="loaded && $any(moreBtn).loading"
*ngIf="continuationToken" *ngIf="continuationToken"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@@ -95,7 +95,7 @@
bitButton bitButton
buttonType="primary" buttonType="primary"
(click)="loadEvents(false)" (click)="loadEvents(false)"
[disabled]="loaded && moreBtn.loading" [disabled]="loaded && $any(moreBtn).loading"
*ngIf="continuationToken" *ngIf="continuationToken"
> >
<i <i

View File

@@ -119,7 +119,7 @@
<td class="table-list-checkbox" (click)="check(c)"> <td class="table-list-checkbox" (click)="check(c)">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
appStopProp appStopProp
/> />
@@ -132,7 +132,7 @@
type="checkbox" type="checkbox"
[(ngModel)]="c.hidePasswords" [(ngModel)]="c.hidePasswords"
name="Collection[{{ i }}].HidePasswords" name="Collection[{{ i }}].HidePasswords"
[disabled]="!c.checked" [disabled]="!$any(c).checked"
/> />
</td> </td>
<td class="text-center"> <td class="text-center">
@@ -140,7 +140,7 @@
type="checkbox" type="checkbox"
[(ngModel)]="c.readOnly" [(ngModel)]="c.readOnly"
name="Collection[{{ i }}].ReadOnly" name="Collection[{{ i }}].ReadOnly"
[disabled]="!c.checked" [disabled]="!$any(c).checked"
/> />
</td> </td>
</tr> </tr>
@@ -164,17 +164,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
></i> ></i>

View File

@@ -341,7 +341,7 @@
<td class="table-list-checkbox" (click)="check(c)"> <td class="table-list-checkbox" (click)="check(c)">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
appStopProp appStopProp
/> />
@@ -354,7 +354,7 @@
type="checkbox" type="checkbox"
[(ngModel)]="c.hidePasswords" [(ngModel)]="c.hidePasswords"
name="Collection[{{ i }}].HidePasswords" name="Collection[{{ i }}].HidePasswords"
[disabled]="!c.checked" [disabled]="!$any(c).checked"
/> />
</td> </td>
<td class="text-center"> <td class="text-center">
@@ -362,7 +362,7 @@
type="checkbox" type="checkbox"
[(ngModel)]="c.readOnly" [(ngModel)]="c.readOnly"
name="Collection[{{ i }}].ReadOnly" name="Collection[{{ i }}].ReadOnly"
[disabled]="!c.checked" [disabled]="!$any(c).checked"
/> />
</td> </td>
</tr> </tr>
@@ -416,17 +416,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -34,7 +34,7 @@
<td class="table-list-checkbox" (click)="check(g)"> <td class="table-list-checkbox" (click)="check(g)">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="g.checked" [(ngModel)]="$any(g).checked"
name="Groups[{{ i }}].Checked" name="Groups[{{ i }}].Checked"
appStopProp appStopProp
/> />

View File

@@ -29,7 +29,7 @@ export class PoliciesComponent implements OnInit {
organization: Organization; organization: Organization;
private orgPolicies: PolicyResponse[]; private orgPolicies: PolicyResponse[];
private policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>(); protected policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,

View File

@@ -18,7 +18,6 @@ import { StateService } from "@bitwarden/common/abstractions/state.service";
import { TotpService } from "@bitwarden/common/abstractions/totp.service"; import { TotpService } from "@bitwarden/common/abstractions/totp.service";
import { CipherData } from "@bitwarden/common/models/data/cipher.data"; import { CipherData } from "@bitwarden/common/models/data/cipher.data";
import { Cipher } from "@bitwarden/common/models/domain/cipher"; import { Cipher } from "@bitwarden/common/models/domain/cipher";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CipherCreateRequest } from "@bitwarden/common/models/request/cipher-create.request"; import { CipherCreateRequest } from "@bitwarden/common/models/request/cipher-create.request";
import { CipherRequest } from "@bitwarden/common/models/request/cipher.request"; import { CipherRequest } from "@bitwarden/common/models/request/cipher.request";
@@ -29,7 +28,6 @@ import { AddEditComponent as BaseAddEditComponent } from "../../vault/add-edit.c
templateUrl: "../../vault/add-edit.component.html", templateUrl: "../../vault/add-edit.component.html",
}) })
export class AddEditComponent extends BaseAddEditComponent { export class AddEditComponent extends BaseAddEditComponent {
organization: Organization;
originalCipher: Cipher = null; originalCipher: Cipher = null;
constructor( constructor(

View File

@@ -12,7 +12,6 @@ import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { StateService } from "@bitwarden/common/abstractions/state.service"; import { StateService } from "@bitwarden/common/abstractions/state.service";
import { TokenService } from "@bitwarden/common/abstractions/token.service"; import { TokenService } from "@bitwarden/common/abstractions/token.service";
import { TotpService } from "@bitwarden/common/abstractions/totp.service"; import { TotpService } from "@bitwarden/common/abstractions/totp.service";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CipherView } from "@bitwarden/common/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/models/view/cipher.view";
import { VaultItemsComponent as BaseVaultItemsComponent } from "../../vault/vault-items.component"; import { VaultItemsComponent as BaseVaultItemsComponent } from "../../vault/vault-items.component";
@@ -24,9 +23,6 @@ import { VaultItemsComponent as BaseVaultItemsComponent } from "../../vault/vaul
export class VaultItemsComponent extends BaseVaultItemsComponent { export class VaultItemsComponent extends BaseVaultItemsComponent {
@Output() onEventsClicked = new EventEmitter<CipherView>(); @Output() onEventsClicked = new EventEmitter<CipherView>();
organization: Organization;
accessEvents = false;
protected allCiphers: CipherView[] = []; protected allCiphers: CipherView[] = [];
constructor( constructor(
@@ -86,6 +82,7 @@ export class VaultItemsComponent extends BaseVaultItemsComponent {
async search(timeout: number = null) { async search(timeout: number = null) {
await super.search(timeout, this.allCiphers); await super.search(timeout, this.allCiphers);
} }
events(c: CipherView) { events(c: CipherView) {
this.onEventsClicked.emit(c); this.onEventsClicked.emit(c);
} }

View File

@@ -19,7 +19,7 @@
<h1> <h1>
{{ "vaultItems" | i18n }} {{ "vaultItems" | i18n }}
<small #actionSpinner [appApiAction]="vaultItemsComponent.actionPromise"> <small #actionSpinner [appApiAction]="vaultItemsComponent.actionPromise">
<ng-container *ngIf="actionSpinner.loading"> <ng-container *ngIf="$any(actionSpinner).loading">
<i <i
class="bwi bwi-spinner bwi-spin text-muted" class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"

View File

@@ -1,5 +1,6 @@
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { OrganizationBadgeModule } from "../../vault/organization-badge/organization-badge.module";
import { VaultSharedModule } from "../../vault/shared/vault-shared.module"; import { VaultSharedModule } from "../../vault/shared/vault-shared.module";
import { VaultFilterModule } from "./vault-filter/vault-filter.module"; import { VaultFilterModule } from "./vault-filter/vault-filter.module";
@@ -8,7 +9,7 @@ import { VaultRoutingModule } from "./vault-routing.module";
import { VaultComponent } from "./vault.component"; import { VaultComponent } from "./vault.component";
@NgModule({ @NgModule({
imports: [VaultSharedModule, VaultRoutingModule, VaultFilterModule], imports: [VaultSharedModule, VaultRoutingModule, VaultFilterModule, OrganizationBadgeModule],
declarations: [VaultComponent, VaultItemsComponent], declarations: [VaultComponent, VaultItemsComponent],
exports: [VaultComponent], exports: [VaultComponent],
}) })

View File

@@ -8,6 +8,7 @@ import { PasswordRepromptService } from "@bitwarden/common/abstractions/password
import { StateService } from "@bitwarden/common/abstractions/state.service"; import { StateService } from "@bitwarden/common/abstractions/state.service";
import { CipherType } from "@bitwarden/common/enums/cipherType"; import { CipherType } from "@bitwarden/common/enums/cipherType";
import { CipherView } from "@bitwarden/common/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/models/view/cipher.view";
import { BadgeTypes } from "@bitwarden/components";
import { CipherReportComponent } from "./cipher-report.component"; import { CipherReportComponent } from "./cipher-report.component";
@@ -16,7 +17,7 @@ import { CipherReportComponent } from "./cipher-report.component";
templateUrl: "weak-passwords-report.component.html", templateUrl: "weak-passwords-report.component.html",
}) })
export class WeakPasswordsReportComponent extends CipherReportComponent implements OnInit { export class WeakPasswordsReportComponent extends CipherReportComponent implements OnInit {
passwordStrengthMap = new Map<string, [string, string]>(); passwordStrengthMap = new Map<string, [string, BadgeTypes]>();
private passwordStrengthCache = new Map<string, number>(); private passwordStrengthCache = new Map<string, number>();
@@ -110,7 +111,7 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen
return true; return true;
} }
private scoreKey(score: number): [string, string] { private scoreKey(score: number): [string, BadgeTypes] {
switch (score) { switch (score) {
case 4: case 4:
return ["strong", "success"]; return ["strong", "success"];

View File

@@ -1,5 +1,7 @@
import { Component, Input } from "@angular/core"; import { Component, Input } from "@angular/core";
import { Icon } from "@bitwarden/components";
import { ReportVariant } from "../models/report-variant"; import { ReportVariant } from "../models/report-variant";
@Component({ @Component({
@@ -10,7 +12,7 @@ export class ReportCardComponent {
@Input() title: string; @Input() title: string;
@Input() description: string; @Input() description: string;
@Input() route: string; @Input() route: string;
@Input() icon: string; @Input() icon: Icon;
@Input() variant: ReportVariant; @Input() variant: ReportVariant;
protected get disabled() { protected get disabled() {

View File

@@ -81,7 +81,7 @@
id="text" id="text"
rows="8" rows="8"
name="Text" name="Text"
[(ngModel)]="sendText" [ngModel]="sendText"
class="form-control" class="form-control"
readonly readonly
></textarea> ></textarea>

View File

@@ -55,7 +55,7 @@
name="Type_{{ o.value }}" name="Type_{{ o.value }}"
id="type_{{ o.value }}" id="type_{{ o.value }}"
[value]="o.value" [value]="o.value"
(change)="typeChanged(o)" (change)="typeChanged()"
[checked]="send.type === o.value" [checked]="send.type === o.value"
/> />
<label class="form-check-label" for="type_{{ o.value }}"> <label class="form-check-label" for="type_{{ o.value }}">
@@ -120,14 +120,7 @@
<h3 class="mt-5">{{ "share" | i18n }}</h3> <h3 class="mt-5">{{ "share" | i18n }}</h3>
<div class="form-group" *ngIf="link"> <div class="form-group" *ngIf="link">
<label for="link">{{ "sendLinkLabel" | i18n }}</label> <label for="link">{{ "sendLinkLabel" | i18n }}</label>
<input <input type="text" readonly id="link" name="Link" [ngModel]="link" class="form-control" />
type="text"
readonly
id="link"
name="Link"
[(ngModel)]="link"
class="form-control"
/>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="form-check">
@@ -286,17 +279,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -13,7 +13,6 @@
formControlName="fallbackDeletionDate" formControlName="fallbackDeletionDate"
required required
placeholder="MM/DD/YYYY" placeholder="MM/DD/YYYY"
[readOnly]="disableSend"
data-date-format="mm/dd/yyyy" data-date-format="mm/dd/yyyy"
/> />
<input <input
@@ -24,7 +23,6 @@
formControlName="fallbackDeletionTime" formControlName="fallbackDeletionTime"
required required
placeholder="HH:MM AM/PM" placeholder="HH:MM AM/PM"
[readOnly]="disableSend"
/> />
</div> </div>
</ng-container> </ng-container>
@@ -38,7 +36,6 @@
formControlName="fallbackDeletionDate" formControlName="fallbackDeletionDate"
required required
placeholder="MM/DD/YYYY" placeholder="MM/DD/YYYY"
[readOnly]="disableSend"
data-date-format="mm/dd/yyyy" data-date-format="mm/dd/yyyy"
/> />
<select <select

View File

@@ -59,7 +59,7 @@
<h1> <h1>
{{ "send" | i18n }} {{ "send" | i18n }}
<small #actionSpinner [appApiAction]="actionPromise"> <small #actionSpinner [appApiAction]="actionPromise">
<ng-container *ngIf="actionSpinner.loading"> <ng-container *ngIf="$any(actionSpinner).loading">
<i <i
class="bwi bwi-spinner bwi-spin text-muted" class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"

View File

@@ -121,16 +121,16 @@
(click)="delete()" (click)="delete()"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -240,14 +240,6 @@
{{ "monthAbbr" | i18n }} = {{ "monthAbbr" | i18n }} =
{{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "year" | i18n }} {{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "year" | i18n }}
</small> </small>
<small *ngIf="selectablePlan.hasPremiumAccessOption && premiumAccessAddon">
{{ "premiumAccess" | i18n }}:
{{ selectablePlan.premiumAccessOptionCost / 12 | currency: "$" }} &times; 12
{{ "monthAbbr" | i18n }}
=
{{ 40 | currency: "$" }}
/{{ "year" | i18n }}
</small>
</ng-container> </ng-container>
<ng-container *ngIf="!selectablePlan.isAnnual"> <ng-container *ngIf="!selectablePlan.isAnnual">
{{ "monthly" | i18n }} {{ "monthly" | i18n }}
@@ -272,17 +264,6 @@
{{ "monthAbbr" | i18n }} = {{ "monthAbbr" | i18n }} =
{{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "month" | i18n }} {{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "month" | i18n }}
</small> </small>
<small
*ngIf="
selectablePlan.hasPremiumAccessOption &&
formGroup.controls['premiumAccessAddon'].value
"
>
{{ "premiumAccess" | i18n }}:
{{ selectablePlan.premiumAccessOptionCost | currency: "$" }} {{ "monthAbbr" | i18n }} =
{{ 40 | currency: "$" }}
/{{ "month" | i18n }}
</small>
</ng-container> </ng-container>
</label> </label>
</div> </div>

View File

@@ -25,7 +25,7 @@
*ngIf="!isSelfHosted && !sponsoringOrg.familySponsorshipValidUntil" *ngIf="!isSelfHosted && !sponsoringOrg.familySponsorshipValidUntil"
[appApiAction]="resendEmailPromise" [appApiAction]="resendEmailPromise"
class="dropdown-item btn-submit" class="dropdown-item btn-submit"
[disabled]="resendEmailBtn.loading" [disabled]="$any(resendEmailBtn).loading"
(click)="resendEmail()" (click)="resendEmail()"
[attr.aria-label]="'resendEmailLabel' | i18n: sponsoringOrg.familySponsorshipFriendlyName" [attr.aria-label]="'resendEmailLabel' | i18n: sponsoringOrg.familySponsorshipFriendlyName"
> >
@@ -36,7 +36,7 @@
#revokeSponsorshipBtn #revokeSponsorshipBtn
[appApiAction]="revokeSponsorshipPromise" [appApiAction]="revokeSponsorshipPromise"
class="dropdown-item text-danger btn-submit" class="dropdown-item text-danger btn-submit"
[disabled]="revokeSponsorshipBtn.loading" [disabled]="$any(revokeSponsorshipBtn).loading"
(click)="revokeSponsorship()" (click)="revokeSponsorship()"
[attr.aria-label]="'revokeAccount' | i18n: sponsoringOrg.familySponsorshipFriendlyName" [attr.aria-label]="'revokeAccount' | i18n: sponsoringOrg.familySponsorshipFriendlyName"
> >

View File

@@ -18,7 +18,7 @@
<app-two-factor-verify <app-two-factor-verify
[organizationId]="organizationId" [organizationId]="organizationId"
[type]="type" [type]="type"
(onAuthed)="auth($event)" (onAuthed)="auth($any($event))"
*ngIf="!authed" *ngIf="!authed"
> >
</app-two-factor-verify> </app-two-factor-verify>

View File

@@ -18,7 +18,7 @@
<app-two-factor-verify <app-two-factor-verify
[organizationId]="organizationId" [organizationId]="organizationId"
[type]="type" [type]="type"
(onAuthed)="auth($event)" (onAuthed)="auth($any($event))"
*ngIf="!authed" *ngIf="!authed"
> >
</app-two-factor-verify> </app-two-factor-verify>

View File

@@ -18,7 +18,7 @@
<app-two-factor-verify <app-two-factor-verify
[organizationId]="organizationId" [organizationId]="organizationId"
[type]="type" [type]="type"
(onAuthed)="auth($event)" (onAuthed)="auth($any($event))"
*ngIf="!authed" *ngIf="!authed"
> >
</app-two-factor-verify> </app-two-factor-verify>
@@ -61,7 +61,7 @@
class="btn btn-outline-primary btn-sm btn-submit align-self-start" class="btn btn-outline-primary btn-sm btn-submit align-self-start"
(click)="sendEmail()" (click)="sendEmail()"
[appApiAction]="emailPromise" [appApiAction]="emailPromise"
[disabled]="sendBtn.loading" [disabled]="$any(sendBtn).loading"
> >
<i <i
class="bwi bwi-spinner bwi-spin" class="bwi bwi-spinner bwi-spin"

View File

@@ -15,12 +15,7 @@
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<app-two-factor-verify <app-two-factor-verify [type]="type" (onAuthed)="auth($event)" *ngIf="!authed">
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
*ngIf="!authed"
>
</app-two-factor-verify> </app-two-factor-verify>
<ng-container *ngIf="authed"> <ng-container *ngIf="authed">
<div class="modal-body text-center"> <div class="modal-body text-center">

View File

@@ -18,7 +18,7 @@
<app-two-factor-verify <app-two-factor-verify
[organizationId]="organizationId" [organizationId]="organizationId"
[type]="type" [type]="type"
(onAuthed)="auth($event)" (onAuthed)="auth($any($event))"
*ngIf="!authed" *ngIf="!authed"
> >
</app-two-factor-verify> </app-two-factor-verify>
@@ -54,7 +54,7 @@
<i class="bwi bwi-li bwi-key"></i> <i class="bwi bwi-li bwi-key"></i>
<strong *ngIf="!k.configured || !k.name">{{ "webAuthnkeyX" | i18n: i + 1 }}</strong> <strong *ngIf="!k.configured || !k.name">{{ "webAuthnkeyX" | i18n: i + 1 }}</strong>
<strong *ngIf="k.configured && k.name">{{ k.name }}</strong> <strong *ngIf="k.configured && k.name">{{ k.name }}</strong>
<ng-container *ngIf="k.configured && !removeKeyBtn.loading"> <ng-container *ngIf="k.configured && !$any(removeKeyBtn).loading">
<ng-container *ngIf="k.migrated"> <ng-container *ngIf="k.migrated">
<span>{{ "webAuthnMigrated" | i18n }}</span> <span>{{ "webAuthnMigrated" | i18n }}</span>
</ng-container> </ng-container>
@@ -63,7 +63,7 @@
<i <i
class="bwi bwi-spin bwi-spinner text-muted bwi-fw" class="bwi bwi-spin bwi-spinner text-muted bwi-fw"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
*ngIf="removeKeyBtn.loading" *ngIf="$any(removeKeyBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
- -
@@ -96,16 +96,16 @@
type="button" type="button"
(click)="readKey()" (click)="readKey()"
class="btn btn-outline-secondary mr-2" class="btn btn-outline-secondary mr-2"
[disabled]="readKeyBtn.loading || webAuthnListening || !keyIdAvailable" [disabled]="$any(readKeyBtn).loading || webAuthnListening || !keyIdAvailable"
#readKeyBtn #readKeyBtn
[appApiAction]="challengePromise" [appApiAction]="challengePromise"
> >
{{ "readKey" | i18n }} {{ "readKey" | i18n }}
</button> </button>
<ng-container *ngIf="readKeyBtn.loading"> <ng-container *ngIf="$any(readKeyBtn).loading">
<i class="bwi bwi-spinner bwi-spin text-muted" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin text-muted" aria-hidden="true"></i>
</ng-container> </ng-container>
<ng-container *ngIf="!readKeyBtn.loading"> <ng-container *ngIf="!$any(readKeyBtn).loading">
<ng-container *ngIf="webAuthnListening"> <ng-container *ngIf="webAuthnListening">
<i class="bwi bwi-spinner bwi-spin text-muted" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin text-muted" aria-hidden="true"></i>
{{ "twoFactorU2fWaiting" | i18n }}... {{ "twoFactorU2fWaiting" | i18n }}...
@@ -138,8 +138,7 @@
#disableBtn #disableBtn
type="button" type="button"
class="btn btn-outline-secondary btn-submit" class="btn btn-outline-secondary btn-submit"
[appApiAction]="disablePromise" [disabled]="$any(disableBtn).loading"
[disabled]="disableBtn.loading"
(click)="disable()" (click)="disable()"
*ngIf="enabled" *ngIf="enabled"
> >

View File

@@ -18,7 +18,7 @@
<app-two-factor-verify <app-two-factor-verify
[organizationId]="organizationId" [organizationId]="organizationId"
[type]="type" [type]="type"
(onAuthed)="auth($event)" (onAuthed)="auth($any($event))"
*ngIf="!authed" *ngIf="!authed"
> >
</app-two-factor-verify> </app-two-factor-verify>
@@ -104,7 +104,7 @@
type="button" type="button"
class="btn btn-outline-secondary btn-submit" class="btn btn-outline-secondary btn-submit"
[appApiAction]="disablePromise" [appApiAction]="disablePromise"
[disabled]="disableBtn.loading" [disabled]="$any(disableBtn).loading"
(click)="disable()" (click)="disable()"
*ngIf="enabled" *ngIf="enabled"
> >

View File

@@ -46,7 +46,7 @@
class="btn-submit" class="btn-submit"
(click)="reinstate()" (click)="reinstate()"
[appApiAction]="reinstatePromise" [appApiAction]="reinstatePromise"
[disabled]="reinstateBtn.loading" [disabled]="$any(reinstateBtn).loading"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "reinstateSubscription" | i18n }}</span> <span>{{ "reinstateSubscription" | i18n }}</span>
@@ -147,7 +147,7 @@
class="btn-submit tw-ml-auto" class="btn-submit tw-ml-auto"
(click)="cancel()" (click)="cancel()"
[appApiAction]="cancelPromise" [appApiAction]="cancelPromise"
[disabled]="cancelBtn.loading" [disabled]="$any(cancelBtn).loading"
*ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel" *ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@@ -9,7 +9,7 @@
class="btn btn-block btn-outline-secondary btn-submit" class="btn btn-block btn-outline-secondary btn-submit"
#sendBtn #sendBtn
[appApiAction]="actionPromise" [appApiAction]="actionPromise"
[disabled]="sendBtn.loading" [disabled]="$any(sendBtn).loading"
(click)="send()" (click)="send()"
> >
<i class="bwi bwi-spin bwi-spinner" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spin bwi-spinner" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@@ -1,7 +1,5 @@
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { UserVerificationComponent } from "@bitwarden/angular/components/user-verification.component";
import { AcceptEmergencyComponent } from "../accounts/accept-emergency.component"; import { AcceptEmergencyComponent } from "../accounts/accept-emergency.component";
import { AcceptOrganizationComponent } from "../accounts/accept-organization.component"; import { AcceptOrganizationComponent } from "../accounts/accept-organization.component";
import { HintComponent } from "../accounts/hint.component"; import { HintComponent } from "../accounts/hint.component";
@@ -24,6 +22,7 @@ import { OrganizationSwitcherComponent } from "../components/organization-switch
import { PasswordRepromptComponent } from "../components/password-reprompt.component"; import { PasswordRepromptComponent } from "../components/password-reprompt.component";
import { PremiumBadgeComponent } from "../components/premium-badge.component"; import { PremiumBadgeComponent } from "../components/premium-badge.component";
import { UserVerificationPromptComponent } from "../components/user-verification-prompt.component"; import { UserVerificationPromptComponent } from "../components/user-verification-prompt.component";
import { UserVerificationComponent } from "../components/user-verification.component";
import { FooterComponent } from "../layouts/footer.component"; import { FooterComponent } from "../layouts/footer.component";
import { FrontendLayoutComponent } from "../layouts/frontend-layout.component"; import { FrontendLayoutComponent } from "../layouts/frontend-layout.component";
import { NavbarComponent } from "../layouts/navbar.component"; import { NavbarComponent } from "../layouts/navbar.component";
@@ -124,7 +123,6 @@ import { BulkRestoreComponent } from "../vault/bulk-restore.component";
import { BulkShareComponent } from "../vault/bulk-share.component"; import { BulkShareComponent } from "../vault/bulk-share.component";
import { CollectionsComponent } from "../vault/collections.component"; import { CollectionsComponent } from "../vault/collections.component";
import { FolderAddEditComponent } from "../vault/folder-add-edit.component"; import { FolderAddEditComponent } from "../vault/folder-add-edit.component";
import { OrganizationBadgeModule } from "../vault/organization-badge/organization-badge.module";
import { ShareComponent } from "../vault/share.component"; import { ShareComponent } from "../vault/share.component";
import { VaultFilterModule } from "../vault/vault-filter/vault-filter.module"; import { VaultFilterModule } from "../vault/vault-filter/vault-filter.module";
@@ -133,13 +131,7 @@ import { SharedModule } from ".";
// Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left. // Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left.
// If you are building new functionality, please create or extend a feature module instead. // If you are building new functionality, please create or extend a feature module instead.
@NgModule({ @NgModule({
imports: [ imports: [SharedModule, VaultFilterModule, OrganizationCreateModule, RegisterFormModule],
SharedModule,
VaultFilterModule,
OrganizationBadgeModule,
OrganizationCreateModule,
RegisterFormModule,
],
declarations: [ declarations: [
PremiumBadgeComponent, PremiumBadgeComponent,
AcceptEmergencyComponent, AcceptEmergencyComponent,

View File

@@ -408,7 +408,7 @@
type="button" type="button"
class="btn btn-submit btn-primary" class="btn btn-submit btn-primary"
(click)="regenerate()" (click)="regenerate()"
[disabled]="form.loading" [disabled]="$any(form).loading"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "regenerateUsername" | i18n }}</span> <span>{{ "regenerateUsername" | i18n }}</span>

View File

@@ -157,7 +157,8 @@
<button <button
type="submit" type="submit"
class="btn btn-primary btn-submit" class="btn btn-primary btn-submit"
[disabled]="form.loading || disabled" [disabled]="form.loading || disabledByPolicy"
[ngClass]="{ manual: disabledByPolicy }"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "confirmFormat" | i18n }}</span> <span>{{ "confirmFormat" | i18n }}</span>

View File

@@ -80,11 +80,13 @@
right) and select "Settings". Go to "Export" and find the "Export to .csv File" option. Click right) and select "Settings". Go to "Export" and find the "Export to .csv File" option. Click
"Export" to save the CSV file. "Export" to save the CSV file.
</ng-container> </ng-container>
<!--
<ng-container *ngIf="format === 'keeperjson'"> <ng-container *ngIf="format === 'keeperjson'">
Log into the Keeper web vault (keepersecurity.com/vault). Click on your "account email" (top Log into the Keeper web vault (keepersecurity.com/vault). Click on your "account email" (top
right) and select "Settings". Go to "Export" and find the "Export to .json File" option. Click right) and select "Settings". Go to "Export" and find the "Export to .json File" option. Click
"Export" to save the JSON file. "Export" to save the JSON file.
</ng-container> </ng-container>
-->
<ng-container <ng-container
*ngIf="format === 'chromecsv' || format === 'operacsv' || format === 'vivaldicsv'" *ngIf="format === 'chromecsv' || format === 'operacsv' || format === 'vivaldicsv'"
> >

View File

@@ -122,8 +122,8 @@
[(ngModel)]="f.value" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean" *ngIf="f.type === fieldType.Boolean"
appTrueFalseValue appTrueFalseValue
trueValue="true" [trueValue]="true"
falseValue="false" [falseValue]="false"
[disabled]="cipher.isDeleted || viewOnly" [disabled]="cipher.isDeleted || viewOnly"
attr.aria-describedby="fieldName{{ i }}" attr.aria-describedby="fieldName{{ i }}"
/> />

View File

@@ -118,13 +118,13 @@
> >
<i <i
class="bwi bwi-lg bwi-fw bwi-check-circle" class="bwi bwi-lg bwi-fw bwi-check-circle"
[hidden]="checkPasswordBtn.loading" [hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-lg bwi-fw bwi-spinner bwi-spin" class="bwi bwi-lg bwi-fw bwi-spinner bwi-spin"
aria-hidden="true" aria-hidden="true"
[hidden]="!checkPasswordBtn.loading" [hidden]="!$any(checkPasswordBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
></i> ></i>
</a> </a>
@@ -838,7 +838,7 @@
<input <input
class="form-check-input" class="form-check-input"
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
id="collection-{{ i }}" id="collection-{{ i }}"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
[disabled]="cipher.isDeleted || viewOnly" [disabled]="cipher.isDeleted || viewOnly"
@@ -935,17 +935,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ (cipher.isDeleted ? 'permanentlyDelete' : 'delete') | i18n }}" appA11yTitle="{{ (cipher.isDeleted ? 'permanentlyDelete' : 'delete') | i18n }}"
*ngIf="editMode && !cloneMode && !(!cipher.edit && editMode)" *ngIf="editMode && !cloneMode && !(!cipher.edit && editMode)"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -26,10 +26,14 @@
<tbody> <tbody>
<tr *ngFor="let a of cipher.attachments"> <tr *ngFor="let a of cipher.attachments">
<td class="table-list-icon"> <td class="table-list-icon">
<i class="bwi bwi-fw bwi-lg bwi-file" *ngIf="!a.downloading" aria-hidden="true"></i> <i
class="bwi bwi-fw bwi-lg bwi-file"
*ngIf="!$any(a).downloading"
aria-hidden="true"
></i>
<i <i
class="bwi bwi-spinner bwi-lg bwi-fw bwi-spin" class="bwi bwi-spinner bwi-lg bwi-fw bwi-spin"
*ngIf="a.downloading" *ngIf="$any(a).downloading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
</td> </td>
@@ -55,7 +59,7 @@
(click)="reupload(a)" (click)="reupload(a)"
#reuploadBtn #reuploadBtn
[appApiAction]="reuploadPromises[a.id]" [appApiAction]="reuploadPromises[a.id]"
[disabled]="reuploadBtn.loading" [disabled]="$any(reuploadBtn).loading"
> >
{{ "fix" | i18n }} {{ "fix" | i18n }}
</button> </button>
@@ -72,16 +76,16 @@
(click)="delete(a)" (click)="delete(a)"
#deleteBtn #deleteBtn
[appApiAction]="deletePromises[a.id]" [appApiAction]="deletePromises[a.id]"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -54,7 +54,7 @@
<td class="table-list-checkbox"> <td class="table-list-checkbox">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
appStopProp appStopProp
/> />

View File

@@ -37,7 +37,7 @@
<td class="table-list-checkbox"> <td class="table-list-checkbox">
<input <input
type="checkbox" type="checkbox"
[(ngModel)]="c.checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
appStopProp appStopProp
/> />

View File

@@ -46,17 +46,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -167,7 +167,6 @@
<i <i
*ngIf="!organization.enabled" *ngIf="!organization.enabled"
class="org-options bwi bwi-fw bwi-exclamation-triangle text-danger" class="org-options bwi bwi-fw bwi-exclamation-triangle text-danger"
aria-label="{{ 'organizationIsDisabled' | i18n }}"
appA11yTitle="{{ 'organizationIsDisabled' | i18n }}" appA11yTitle="{{ 'organizationIsDisabled' | i18n }}"
></i ></i
><button [bitMenuTriggerFor]="orgMenu" class="org-options"> ><button [bitMenuTriggerFor]="orgMenu" class="org-options">

View File

@@ -1,6 +1,9 @@
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { SharedModule } from "../../../shared"; import { SharedModule } from "../../../shared";
import { LinkSsoComponent } from "../organization-filter/link-sso.component";
import { OrganizationFilterComponent } from "../organization-filter/organization-filter.component";
import { OrganizationOptionsComponent } from "../organization-filter/organization-options.component";
import { CollectionFilterComponent } from "./collection-filter/collection-filter.component"; import { CollectionFilterComponent } from "./collection-filter/collection-filter.component";
import { FolderFilterComponent } from "./folder-filter/folder-filter.component"; import { FolderFilterComponent } from "./folder-filter/folder-filter.component";
@@ -15,6 +18,9 @@ import { VaultFilterService } from "./vault-filter.service";
FolderFilterComponent, FolderFilterComponent,
StatusFilterComponent, StatusFilterComponent,
TypeFilterComponent, TypeFilterComponent,
OrganizationFilterComponent,
OrganizationOptionsComponent,
LinkSsoComponent,
], ],
exports: [ exports: [
SharedModule, SharedModule,
@@ -22,6 +28,9 @@ import { VaultFilterService } from "./vault-filter.service";
FolderFilterComponent, FolderFilterComponent,
StatusFilterComponent, StatusFilterComponent,
TypeFilterComponent, TypeFilterComponent,
OrganizationFilterComponent,
OrganizationOptionsComponent,
LinkSsoComponent,
], ],
providers: [VaultFilterService], providers: [VaultFilterService],
}) })

View File

@@ -1,19 +1,11 @@
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { LinkSsoComponent } from "./organization-filter/link-sso.component";
import { OrganizationFilterComponent } from "./organization-filter/organization-filter.component";
import { OrganizationOptionsComponent } from "./organization-filter/organization-options.component";
import { VaultFilterSharedModule } from "./shared/vault-filter-shared.module"; import { VaultFilterSharedModule } from "./shared/vault-filter-shared.module";
import { VaultFilterComponent } from "./vault-filter.component"; import { VaultFilterComponent } from "./vault-filter.component";
@NgModule({ @NgModule({
imports: [VaultFilterSharedModule], imports: [VaultFilterSharedModule],
declarations: [ declarations: [VaultFilterComponent],
VaultFilterComponent,
OrganizationFilterComponent,
OrganizationOptionsComponent,
LinkSsoComponent,
],
exports: [VaultFilterComponent], exports: [VaultFilterComponent],
}) })
export class VaultFilterModule {} export class VaultFilterModule {}

View File

@@ -10,7 +10,7 @@
<tbody> <tbody>
<tr *ngFor="let c of filteredCiphers"> <tr *ngFor="let c of filteredCiphers">
<td (click)="checkCipher(c)" class="table-list-checkbox"> <td (click)="checkCipher(c)" class="table-list-checkbox">
<input type="checkbox" [(ngModel)]="c.checked" appStopProp /> <input type="checkbox" [(ngModel)]="$any(c).checked" appStopProp />
</td> </td>
<td (click)="checkCipher(c)" class="table-list-icon"> <td (click)="checkCipher(c)" class="table-list-icon">
<app-vault-icon [cipher]="c"></app-vault-icon> <app-vault-icon [cipher]="c"></app-vault-icon>

View File

@@ -289,6 +289,10 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnDe
this.onOrganzationBadgeClicked.emit(organizationId); this.onOrganzationBadgeClicked.emit(organizationId);
} }
events(c: CipherView) {
// TODO: This should be removed but is needed since we reuse the same template
}
protected deleteCipher(id: string, permanent: boolean) { protected deleteCipher(id: string, permanent: boolean) {
return permanent return permanent
? this.cipherService.deleteWithServer(id) ? this.cipherService.deleteWithServer(id)

View File

@@ -21,7 +21,7 @@
<h1> <h1>
{{ "vaultItems" | i18n }} {{ "vaultItems" | i18n }}
<small #actionSpinner [appApiAction]="vaultItemsComponent.actionPromise"> <small #actionSpinner [appApiAction]="vaultItemsComponent.actionPromise">
<ng-container *ngIf="actionSpinner.loading"> <ng-container *ngIf="$any(actionSpinner).loading">
<i <i
class="bwi bwi-spinner bwi-spin text-muted" class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"

View File

@@ -12,6 +12,7 @@
} }
}, },
"angularCompilerOptions": { "angularCompilerOptions": {
"strictTemplates": true,
"preserveWhitespaces": true "preserveWhitespaces": true
}, },
"files": ["src/polyfills.ts", "src/main.ts", "../../bitwarden_license/bit-web/src/main.ts"], "files": ["src/polyfills.ts", "src/main.ts", "../../bitwarden_license/bit-web/src/main.ts"],

View File

@@ -70,7 +70,7 @@
</ng-container> </ng-container>
<ng-container #rotateButton [appApiAction]="rotatePromise"> <ng-container #rotateButton [appApiAction]="rotatePromise">
<button <button
[disabled]="rotateButton.loading" [disabled]="$any(rotateButton).loading"
type="button" type="button"
bitSuffix bitSuffix
bitButton bitButton
@@ -80,7 +80,7 @@
<i <i
aria-hidden="true" aria-hidden="true"
class="bwi bwi-lg bwi-generate" class="bwi bwi-lg bwi-generate"
[ngClass]="{ 'bwi-spin': rotateButton.loading }" [ngClass]="{ 'bwi-spin': $any(rotateButton).loading }"
></i> ></i>
</button> </button>
</ng-container> </ng-container>

View File

@@ -97,13 +97,13 @@ export class SsoComponent implements OnInit, OnDestroy {
spMetadataUrl: string; spMetadataUrl: string;
spAcsUrl: string; spAcsUrl: string;
private enabled = this.formBuilder.control(false); protected enabled = this.formBuilder.control(false);
private ssoIdentifier = this.formBuilder.control("", { protected ssoIdentifier = this.formBuilder.control("", {
validators: [Validators.maxLength(50), Validators.required], validators: [Validators.maxLength(50), Validators.required],
}); });
private openIdForm = this.formBuilder.group<ControlsOf<SsoConfigView["openId"]>>( protected openIdForm = this.formBuilder.group<ControlsOf<SsoConfigView["openId"]>>(
{ {
authority: new FormControl("", Validators.required), authority: new FormControl("", Validators.required),
clientId: new FormControl("", Validators.required), clientId: new FormControl("", Validators.required),
@@ -126,7 +126,7 @@ export class SsoComponent implements OnInit, OnDestroy {
} }
); );
private samlForm = this.formBuilder.group<ControlsOf<SsoConfigView["saml"]>>( protected samlForm = this.formBuilder.group<ControlsOf<SsoConfigView["saml"]>>(
{ {
spNameIdFormat: new FormControl(Saml2NameIdFormat.NotConfigured), spNameIdFormat: new FormControl(Saml2NameIdFormat.NotConfigured),
spOutboundSigningAlgorithm: new FormControl(defaultSigningAlgorithm), spOutboundSigningAlgorithm: new FormControl(defaultSigningAlgorithm),
@@ -150,7 +150,7 @@ export class SsoComponent implements OnInit, OnDestroy {
} }
); );
private ssoConfigForm = this.formBuilder.group<ControlsOf<SsoConfigView>>({ protected ssoConfigForm = this.formBuilder.group<ControlsOf<SsoConfigView>>({
configType: new FormControl(SsoType.None), configType: new FormControl(SsoType.None),
keyConnectorEnabled: new FormControl(false), keyConnectorEnabled: new FormControl(false),
keyConnectorUrl: new FormControl(""), keyConnectorUrl: new FormControl(""),

View File

@@ -98,7 +98,7 @@
type="button" type="button"
class="btn btn-block btn-link btn-submit" class="btn btn-block btn-link btn-submit"
(click)="loadEvents(false)" (click)="loadEvents(false)"
[disabled]="loaded && moreBtn.loading" [disabled]="loaded && $any(moreBtn).loading"
*ngIf="continuationToken" *ngIf="continuationToken"
> >
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@@ -149,7 +149,6 @@
<td> <td>
<span *ngIf="u.type === userType.ProviderAdmin">{{ "providerAdmin" | i18n }}</span> <span *ngIf="u.type === userType.ProviderAdmin">{{ "providerAdmin" | i18n }}</span>
<span *ngIf="u.type === userType.ServiceUser">{{ "serviceUser" | i18n }}</span> <span *ngIf="u.type === userType.ServiceUser">{{ "serviceUser" | i18n }}</span>
<span *ngIf="u.type === userType.Custom">{{ "custom" | i18n }}</span>
</td> </td>
<td class="table-list-options"> <td class="table-list-options">
<div class="dropdown" appListDropdown> <div class="dropdown" appListDropdown>
@@ -184,16 +183,6 @@
<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> </a>
<a
class="dropdown-item"
href="#"
appStopClick
(click)="groups(u)"
*ngIf="accessGroups"
>
<i class="bwi bwi-fw bwi-sitemap" aria-hidden="true"></i>
{{ "groups" | i18n }}
</a>
<a <a
class="dropdown-item" class="dropdown-item"
href="#" href="#"

View File

@@ -102,17 +102,17 @@
class="btn btn-outline-danger" class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}" appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode" *ngIf="editMode"
[disabled]="deleteBtn.loading" [disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise" [appApiAction]="deletePromise"
> >
<i <i
class="bwi bwi-trash bwi-lg bwi-fw" class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading" [hidden]="$any(deleteBtn).loading"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<i <i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading" [hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}" title="{{ 'loading' | i18n }}"
aria-hidden="true" aria-hidden="true"
></i> ></i>

View File

@@ -30,9 +30,6 @@
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "submit" | i18n }}</span> <span>{{ "submit" | i18n }}</span>
</button> </button>
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" *ngIf="showCancel">
{{ "cancel" | i18n }}
</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -23,6 +23,7 @@ import { SecureNoteType } from "@bitwarden/common/enums/secureNoteType";
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType"; import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
import { Utils } from "@bitwarden/common/misc/utils"; import { Utils } from "@bitwarden/common/misc/utils";
import { Cipher } from "@bitwarden/common/models/domain/cipher"; import { Cipher } from "@bitwarden/common/models/domain/cipher";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CardView } from "@bitwarden/common/models/view/card.view"; import { CardView } from "@bitwarden/common/models/view/card.view";
import { CipherView } from "@bitwarden/common/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/models/view/cipher.view";
import { CollectionView } from "@bitwarden/common/models/view/collection.view"; import { CollectionView } from "@bitwarden/common/models/view/collection.view";
@@ -74,6 +75,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
allowPersonal = true; allowPersonal = true;
reprompt = false; reprompt = false;
canUseReprompt = true; canUseReprompt = true;
organization: Organization;
protected destroy$ = new Subject<void>(); protected destroy$ = new Subject<void>();
protected writeableCollections: CollectionView[]; protected writeableCollections: CollectionView[];

View File

@@ -292,4 +292,8 @@ export class AttachmentsComponent implements OnInit {
protected deleteCipherAttachment(attachmentId: string) { protected deleteCipherAttachment(attachmentId: string) {
return this.cipherService.deleteAttachmentWithServer(this.cipher.id, attachmentId); return this.cipherService.deleteAttachmentWithServer(this.cipher.id, attachmentId);
} }
protected async reupload(attachment: AttachmentView) {
// TODO: This should be removed but is needed since we re-use the same template
}
} }

View File

@@ -1,6 +1,5 @@
import { animate, style, transition, trigger } from "@angular/animations"; import { Directive, OnInit } from "@angular/core";
import { Component, OnInit } from "@angular/core"; import { ControlValueAccessor, FormControl } from "@angular/forms";
import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormControl } from "@angular/forms";
import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service"; import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service";
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
@@ -14,21 +13,8 @@ import { Verification } from "@bitwarden/common/types/verification";
* This is exposed to the parent component via the ControlValueAccessor interface (e.g. bind it to a FormControl). * This is exposed to the parent component via the ControlValueAccessor interface (e.g. bind it to a FormControl).
* Use UserVerificationService to verify the user's input. * Use UserVerificationService to verify the user's input.
*/ */
@Component({ @Directive({
selector: "app-user-verification", selector: "app-user-verification",
templateUrl: "user-verification.component.html",
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: UserVerificationComponent,
},
],
animations: [
trigger("sent", [
transition(":enter", [style({ opacity: 0 }), animate("100ms", style({ opacity: 1 }))]),
]),
],
}) })
// eslint-disable-next-line rxjs-angular/prefer-takeuntil // eslint-disable-next-line rxjs-angular/prefer-takeuntil
export class UserVerificationComponent implements ControlValueAccessor, OnInit { export class UserVerificationComponent implements ControlValueAccessor, OnInit {

View File

@@ -1,6 +1,7 @@
import { Directive, EventEmitter, Input, Output } from "@angular/core"; import { Directive, EventEmitter, Input, Output } from "@angular/core";
import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CipherView } from "@bitwarden/common/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/models/view/cipher.view";
@Directive() @Directive()
@@ -17,6 +18,8 @@ export class VaultItemsComponent {
searchPlaceholder: string = null; searchPlaceholder: string = null;
filter: (cipher: CipherView) => boolean = null; filter: (cipher: CipherView) => boolean = null;
deleted = false; deleted = false;
organization: Organization;
accessEvents = false;
protected searchPending = false; protected searchPending = false;

View File

@@ -8,7 +8,7 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
export class I18nPipe implements PipeTransform { export class I18nPipe implements PipeTransform {
constructor(private i18nService: I18nService) {} constructor(private i18nService: I18nService) {}
transform(id: string, p1?: string, p2?: string, p3?: string): string { transform(id: string, p1?: string | number, p2?: string | number, p3?: string | number): string {
return this.i18nService.t(id, p1, p2, p3); return this.i18nService.t(id, p1, p2, p3);
} }
} }

View File

@@ -6,6 +6,6 @@ export abstract class I18nService {
translationLocale: string; translationLocale: string;
collator: Intl.Collator; collator: Intl.Collator;
localeNames: Map<string, string>; localeNames: Map<string, string>;
t: (id: string, p1?: string, p2?: string, p3?: string) => string; t: (id: string, p1?: string | number, p2?: string | number, p3?: string | number) => string;
translate: (id: string, p1?: string, p2?: string, p3?: string) => string; translate: (id: string, p1?: string, p2?: string, p3?: string) => string;
} }

View File

@@ -122,7 +122,7 @@ export class I18nService implements I18nServiceAbstraction {
return this.translate(id, p1, p2, p3); return this.translate(id, p1, p2, p3);
} }
translate(id: string, p1?: string, p2?: string, p3?: string): string { translate(id: string, p1?: string | number, p2?: string | number, p3?: string | number): string {
let result: string; let result: string;
// eslint-disable-next-line // eslint-disable-next-line
if (this.localeMessages.hasOwnProperty(id) && this.localeMessages[id]) { if (this.localeMessages.hasOwnProperty(id) && this.localeMessages[id]) {
@@ -136,13 +136,13 @@ export class I18nService implements I18nServiceAbstraction {
if (result !== "") { if (result !== "") {
if (p1 != null) { if (p1 != null) {
result = result.split("__$1__").join(p1); result = result.split("__$1__").join(p1.toString());
} }
if (p2 != null) { if (p2 != null) {
result = result.split("__$2__").join(p2); result = result.split("__$2__").join(p2.toString());
} }
if (p3 != null) { if (p3 != null) {
result = result.split("__$3__").join(p3); result = result.split("__$3__").join(p3.toString());
} }
} }

View File

@@ -1,6 +1,6 @@
import { Directive, ElementRef, HostBinding, Input } from "@angular/core"; import { Directive, ElementRef, HostBinding, Input } from "@angular/core";
type BadgeTypes = "primary" | "secondary" | "success" | "danger" | "warning" | "info"; export type BadgeTypes = "primary" | "secondary" | "success" | "danger" | "warning" | "info";
const styles: Record<BadgeTypes, string[]> = { const styles: Record<BadgeTypes, string[]> = {
primary: ["tw-bg-primary-500"], primary: ["tw-bg-primary-500"],