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 *ngIf="!isLoading">
|
||||||
<bit-section-header>
|
<bit-section-header>
|
||||||
<h2 bitTypography="h6">{{ "domainsTitle" | i18n }}</h2>
|
<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>
|
</bit-section-header>
|
||||||
|
<bit-item *ngFor="let domain of blockedDomainsState; let i = index; trackBy: trackByFunction">
|
||||||
<ng-container *ngIf="blockedDomainsState">
|
<bit-item-content *ngIf="i < fieldsEditThreshold">
|
||||||
<bit-item
|
<div id="blockedDomain{{ i }}">{{ domain }}</div>
|
||||||
*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-content>
|
</bit-item-content>
|
||||||
<button
|
<button
|
||||||
*ngIf="i < fieldsEditThreshold"
|
*ngIf="i < fieldsEditThreshold"
|
||||||
@@ -56,10 +39,31 @@
|
|||||||
(click)="removeDomain(i)"
|
(click)="removeDomain(i)"
|
||||||
></button>
|
></button>
|
||||||
</bit-item>
|
</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()">
|
<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 }}
|
<i class="bwi bwi-plus-circle bwi-fw" aria-hidden="true"></i> {{ "addDomain" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
|
</form>
|
||||||
</bit-section>
|
</bit-section>
|
||||||
</div>
|
</div>
|
||||||
<popup-footer slot="footer">
|
<popup-footer slot="footer">
|
||||||
|
|||||||
@@ -7,7 +7,13 @@ import {
|
|||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
ViewChildren,
|
ViewChildren,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormsModule } from "@angular/forms";
|
import {
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
FormBuilder,
|
||||||
|
FormGroup,
|
||||||
|
FormArray,
|
||||||
|
} from "@angular/forms";
|
||||||
import { RouterModule } from "@angular/router";
|
import { RouterModule } from "@angular/router";
|
||||||
import { Subject, takeUntil } from "rxjs";
|
import { Subject, takeUntil } from "rxjs";
|
||||||
|
|
||||||
@@ -44,6 +50,7 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
FormFieldModule,
|
FormFieldModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
IconButtonModule,
|
IconButtonModule,
|
||||||
ItemModule,
|
ItemModule,
|
||||||
JslibModule,
|
JslibModule,
|
||||||
@@ -66,6 +73,11 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
|||||||
isLoading = false;
|
isLoading = false;
|
||||||
blockedDomainsState: string[] = [];
|
blockedDomainsState: string[] = [];
|
||||||
storedBlockedDomains: string[] = [];
|
storedBlockedDomains: string[] = [];
|
||||||
|
|
||||||
|
protected domainListForm = new FormGroup({
|
||||||
|
domains: this.formBuilder.array([]),
|
||||||
|
});
|
||||||
|
|
||||||
// How many fields should be non-editable before editable fields
|
// How many fields should be non-editable before editable fields
|
||||||
fieldsEditThreshold: number = 0;
|
fieldsEditThreshold: number = 0;
|
||||||
|
|
||||||
@@ -75,8 +87,13 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
|||||||
private domainSettingsService: DomainSettingsService,
|
private domainSettingsService: DomainSettingsService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
get domainForms() {
|
||||||
|
return this.domainListForm.get("domains") as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
async ngAfterViewInit() {
|
async ngAfterViewInit() {
|
||||||
this.domainSettingsService.blockedInteractionsUris$
|
this.domainSettingsService.blockedInteractionsUris$
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
@@ -113,8 +130,7 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addNewDomain() {
|
async addNewDomain() {
|
||||||
// add empty field to the Domains list interface
|
this.domainForms.push(this.formBuilder.control(null));
|
||||||
this.blockedDomainsState.push("");
|
|
||||||
|
|
||||||
await this.fieldChange();
|
await this.fieldChange();
|
||||||
}
|
}
|
||||||
@@ -144,7 +160,8 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
|||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
const newBlockedDomainsSaveState: NeverDomains = {};
|
const newBlockedDomainsSaveState: NeverDomains = {};
|
||||||
const uniqueBlockedDomains = new Set(this.blockedDomainsState);
|
|
||||||
|
const uniqueBlockedDomains = new Set([...this.blockedDomainsState, ...this.domainForms.value]);
|
||||||
|
|
||||||
for (const uri of uniqueBlockedDomains) {
|
for (const uri of uniqueBlockedDomains) {
|
||||||
if (uri && uri !== "") {
|
if (uri && uri !== "") {
|
||||||
@@ -152,7 +169,7 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
|||||||
|
|
||||||
if (!validatedHost) {
|
if (!validatedHost) {
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
message: this.i18nService.t("excludedDomainsInvalidDomain", uri),
|
message: this.i18nService.t("blockedDomainsInvalidDomain", uri),
|
||||||
title: "",
|
title: "",
|
||||||
variant: "error",
|
variant: "error",
|
||||||
});
|
});
|
||||||
@@ -190,13 +207,14 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
|
|||||||
title: "",
|
title: "",
|
||||||
variant: "success",
|
variant: "success",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.domainForms.clear();
|
||||||
} catch {
|
} catch {
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
message: this.i18nService.t("unexpectedError"),
|
message: this.i18nService.t("unexpectedError"),
|
||||||
title: "",
|
title: "",
|
||||||
variant: "error",
|
variant: "error",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Don't reset via `handleStateUpdate` to preserve input values
|
// Don't reset via `handleStateUpdate` to preserve input values
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user