mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 17:53:39 +00:00
[PM-17819] Replicate ReactiveForms and bit-* component changes to Blocked Domains from Excluded Domains update [PM-13808]. (#13180)
This commit is contained in:
@@ -20,30 +20,13 @@
|
||||
<bit-section *ngIf="!isLoading">
|
||||
<bit-section-header>
|
||||
<h2 bitTypography="h6">{{ "domainsTitle" | i18n }}</h2>
|
||||
<span bitTypography="body2" slot="end">{{ blockedDomainsState?.length || 0 }}</span>
|
||||
<span bitTypography="body2" slot="end">{{
|
||||
blockedDomainsState.length + domainForms.value.length
|
||||
}}</span>
|
||||
</bit-section-header>
|
||||
|
||||
<ng-container *ngIf="blockedDomainsState">
|
||||
<bit-item
|
||||
*ngFor="let domain of blockedDomainsState; let i = index; trackBy: trackByFunction"
|
||||
>
|
||||
<bit-item-content>
|
||||
<bit-label *ngIf="i >= fieldsEditThreshold">{{
|
||||
"websiteItemLabel" | i18n: i + 1
|
||||
}}</bit-label>
|
||||
<input
|
||||
*ngIf="i >= fieldsEditThreshold"
|
||||
#uriInput
|
||||
appInputVerbatim
|
||||
bitInput
|
||||
id="excludedDomain{{ i }}"
|
||||
inputmode="url"
|
||||
name="excludedDomain{{ i }}"
|
||||
type="text"
|
||||
(change)="fieldChange()"
|
||||
[(ngModel)]="blockedDomainsState[i]"
|
||||
/>
|
||||
<div id="excludedDomain{{ i }}" *ngIf="i < fieldsEditThreshold">{{ domain }}</div>
|
||||
<bit-item *ngFor="let domain of blockedDomainsState; let i = index; trackBy: trackByFunction">
|
||||
<bit-item-content *ngIf="i < fieldsEditThreshold">
|
||||
<div id="blockedDomain{{ i }}">{{ domain }}</div>
|
||||
</bit-item-content>
|
||||
<button
|
||||
*ngIf="i < fieldsEditThreshold"
|
||||
@@ -56,10 +39,31 @@
|
||||
(click)="removeDomain(i)"
|
||||
></button>
|
||||
</bit-item>
|
||||
</ng-container>
|
||||
<form [formGroup]="domainListForm">
|
||||
<bit-card
|
||||
formArrayName="domains"
|
||||
*ngFor="let domain of domainForms.controls; let i = index"
|
||||
>
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>{{ "websiteItemLabel" | i18n: i + fieldsEditThreshold + 1 }}</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
#uriInput
|
||||
appInputVerbatim
|
||||
bitInput
|
||||
id="blockedDomain{{ i + fieldsEditThreshold }}"
|
||||
inputmode="url"
|
||||
name="blockedDomain{{ i + fieldsEditThreshold }}"
|
||||
type="text"
|
||||
(change)="fieldChange()"
|
||||
formControlName="{{ i }}"
|
||||
/>
|
||||
</bit-form-field>
|
||||
</bit-card>
|
||||
<button bitLink class="tw-pt-2" type="button" linkType="primary" (click)="addNewDomain()">
|
||||
<i class="bwi bwi-plus-circle bwi-fw" aria-hidden="true"></i> {{ "addDomain" | i18n }}
|
||||
</button>
|
||||
</form>
|
||||
</bit-section>
|
||||
</div>
|
||||
<popup-footer slot="footer">
|
||||
|
||||
@@ -7,7 +7,13 @@ import {
|
||||
AfterViewInit,
|
||||
ViewChildren,
|
||||
} from "@angular/core";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import {
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
FormBuilder,
|
||||
FormGroup,
|
||||
FormArray,
|
||||
} from "@angular/forms";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
|
||||
@@ -44,6 +50,7 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co
|
||||
CommonModule,
|
||||
FormFieldModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
IconButtonModule,
|
||||
ItemModule,
|
||||
JslibModule,
|
||||
@@ -66,6 +73,11 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
||||
isLoading = false;
|
||||
blockedDomainsState: string[] = [];
|
||||
storedBlockedDomains: string[] = [];
|
||||
|
||||
protected domainListForm = new FormGroup({
|
||||
domains: this.formBuilder.array([]),
|
||||
});
|
||||
|
||||
// How many fields should be non-editable before editable fields
|
||||
fieldsEditThreshold: number = 0;
|
||||
|
||||
@@ -75,8 +87,13 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
||||
private domainSettingsService: DomainSettingsService,
|
||||
private i18nService: I18nService,
|
||||
private toastService: ToastService,
|
||||
private formBuilder: FormBuilder,
|
||||
) {}
|
||||
|
||||
get domainForms() {
|
||||
return this.domainListForm.get("domains") as FormArray;
|
||||
}
|
||||
|
||||
async ngAfterViewInit() {
|
||||
this.domainSettingsService.blockedInteractionsUris$
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
@@ -113,8 +130,7 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
async addNewDomain() {
|
||||
// add empty field to the Domains list interface
|
||||
this.blockedDomainsState.push("");
|
||||
this.domainForms.push(this.formBuilder.control(null));
|
||||
|
||||
await this.fieldChange();
|
||||
}
|
||||
@@ -144,7 +160,8 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
||||
this.isLoading = true;
|
||||
|
||||
const newBlockedDomainsSaveState: NeverDomains = {};
|
||||
const uniqueBlockedDomains = new Set(this.blockedDomainsState);
|
||||
|
||||
const uniqueBlockedDomains = new Set([...this.blockedDomainsState, ...this.domainForms.value]);
|
||||
|
||||
for (const uri of uniqueBlockedDomains) {
|
||||
if (uri && uri !== "") {
|
||||
@@ -152,7 +169,7 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
||||
|
||||
if (!validatedHost) {
|
||||
this.toastService.showToast({
|
||||
message: this.i18nService.t("excludedDomainsInvalidDomain", uri),
|
||||
message: this.i18nService.t("blockedDomainsInvalidDomain", uri),
|
||||
title: "",
|
||||
variant: "error",
|
||||
});
|
||||
@@ -190,13 +207,14 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
||||
title: "",
|
||||
variant: "success",
|
||||
});
|
||||
|
||||
this.domainForms.clear();
|
||||
} catch {
|
||||
this.toastService.showToast({
|
||||
message: this.i18nService.t("unexpectedError"),
|
||||
title: "",
|
||||
variant: "error",
|
||||
});
|
||||
|
||||
// Don't reset via `handleStateUpdate` to preserve input values
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user