diff --git a/apps/browser/src/platform/popup/layout/popup-footer.component.ts b/apps/browser/src/platform/popup/layout/popup-footer.component.ts index 928394b0ad4..c44dfc5079f 100644 --- a/apps/browser/src/platform/popup/layout/popup-footer.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-footer.component.ts @@ -1,5 +1,7 @@ import { Component } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "popup-footer", templateUrl: "popup-footer.component.html", diff --git a/apps/browser/src/platform/popup/layout/popup-header.component.ts b/apps/browser/src/platform/popup/layout/popup-header.component.ts index b580b84f39b..2e95e7ab587 100644 --- a/apps/browser/src/platform/popup/layout/popup-header.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-header.component.ts @@ -16,6 +16,8 @@ import { PopupRouterCacheService } from "../view-cache/popup-router-cache.servic import { PopupPageComponent } from "./popup-page.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "popup-header", templateUrl: "popup-header.component.html", @@ -23,13 +25,19 @@ import { PopupPageComponent } from "./popup-page.component"; }) export class PopupHeaderComponent { private popupRouterCacheService = inject(PopupRouterCacheService); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals protected pageContentScrolled: Signal = inject(PopupPageComponent).isScrolled; /** Background color */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() background: "default" | "alt" = "default"; /** Display the back button, which uses Location.back() to go back one page in history */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() get showBackButton() { return this._showBackButton; @@ -41,6 +49,8 @@ export class PopupHeaderComponent { private _showBackButton = false; /** Title string that will be inserted as an h1 */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ required: true }) pageTitle: string; /** @@ -48,6 +58,8 @@ export class PopupHeaderComponent { * * If unset, will call `location.back()` **/ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() backAction: FunctionReturningAwaitable = async () => { return this.popupRouterCacheService.back(); diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index 2fa37e3ecd9..ca79a6d9d14 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -41,6 +41,8 @@ import { PopupHeaderComponent } from "./popup-header.component"; import { PopupPageComponent } from "./popup-page.component"; import { PopupTabNavigationComponent } from "./popup-tab-navigation.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "extension-container", template: ` @@ -51,6 +53,8 @@ import { PopupTabNavigationComponent } from "./popup-tab-navigation.component"; }) class ExtensionContainerComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "extension-popped-container", template: ` @@ -62,6 +66,8 @@ class ExtensionContainerComponent {} }) class ExtensionPoppedContainerComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "vault-placeholder", template: /*html*/ ` @@ -95,6 +101,8 @@ class VaultComponent { protected data = Array.from(Array(20).keys()); } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-add-button", template: ` @@ -107,6 +115,8 @@ class VaultComponent { }) class MockAddButtonComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-popout-button", template: ` @@ -116,6 +126,8 @@ class MockAddButtonComponent {} }) class MockPopoutButtonComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-current-account", template: ` @@ -127,6 +139,8 @@ class MockPopoutButtonComponent {} }) class MockCurrentAccountComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-search", template: ` `, @@ -134,6 +148,8 @@ class MockCurrentAccountComponent {} }) class MockSearchComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-banner", template: ` @@ -145,6 +161,8 @@ class MockSearchComponent {} }) class MockBannerComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-vault-page", template: ` @@ -172,6 +190,8 @@ class MockBannerComponent {} }) class MockVaultPageComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-vault-page-popped", template: ` @@ -195,6 +215,8 @@ class MockVaultPageComponent {} }) class MockVaultPagePoppedComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-generator-page", template: ` @@ -219,6 +241,8 @@ class MockVaultPagePoppedComponent {} }) class MockGeneratorPageComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-send-page", template: ` @@ -243,6 +267,8 @@ class MockGeneratorPageComponent {} }) class MockSendPageComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-settings-page", template: ` @@ -267,6 +293,8 @@ class MockSendPageComponent {} }) class MockSettingsPageComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "mock-vault-subpage", template: ` diff --git a/apps/browser/src/platform/popup/layout/popup-page.component.ts b/apps/browser/src/platform/popup/layout/popup-page.component.ts index e7675978622..db5ea641691 100644 --- a/apps/browser/src/platform/popup/layout/popup-page.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-page.component.ts @@ -4,6 +4,8 @@ import { booleanAttribute, Component, inject, Input, signal } from "@angular/cor import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ScrollLayoutHostDirective } from "@bitwarden/components"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "popup-page", templateUrl: "popup-page.component.html", @@ -15,15 +17,23 @@ import { ScrollLayoutHostDirective } from "@bitwarden/components"; export class PopupPageComponent { protected i18nService = inject(I18nService); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() loading = false; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) disablePadding = false; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals protected scrolled = signal(false); isScrolled = this.scrolled.asReadonly(); /** Accessible loading label for the spinner. Defaults to "loading" */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() loadingText?: string = this.i18nService.t("loading"); handleScroll(event: Event) { diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts index 742b12bb7ad..4abd9cd4803 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts @@ -15,6 +15,8 @@ export type NavButton = { showBerry?: boolean; }; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "popup-tab-navigation", templateUrl: "popup-tab-navigation.component.html", @@ -24,6 +26,8 @@ export type NavButton = { }, }) export class PopupTabNavigationComponent { + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() navButtons: NavButton[] = []; constructor(private i18nService: I18nService) {} diff --git a/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts b/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts index 8fca1b057ff..3a50f03e982 100644 --- a/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts +++ b/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts @@ -29,6 +29,8 @@ export interface ExtensionAnonLayoutWrapperData extends AnonLayoutWrapperData { hideFooter?: boolean; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ templateUrl: "extension-anon-layout-wrapper.component.html", imports: [ diff --git a/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts b/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts index 7c97bc764f2..7a30e15582c 100644 --- a/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts +++ b/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts @@ -164,6 +164,8 @@ type Story = StoryObj; // Default Example +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-default-primary-outlet-example-component", template: "

Primary Outlet Example:
your primary component goes here

", @@ -171,6 +173,8 @@ type Story = StoryObj; }) class DefaultPrimaryOutletExampleComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-default-secondary-outlet-example-component", template: "

Secondary Outlet Example:
your secondary component goes here

", @@ -178,6 +182,8 @@ class DefaultPrimaryOutletExampleComponent {} }) class DefaultSecondaryOutletExampleComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-default-env-selector-outlet-example-component", template: "

Env Selector Outlet Example:
your env selector component goes here

", @@ -261,6 +267,8 @@ const changedData: ExtensionAnonLayoutWrapperData = { showLogo: false, }; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-dynamic-content-example-component", template: ` diff --git a/apps/web/src/app/layouts/frontend-layout.component.ts b/apps/web/src/app/layouts/frontend-layout.component.ts index a91fc92df61..ef52550321e 100644 --- a/apps/web/src/app/layouts/frontend-layout.component.ts +++ b/apps/web/src/app/layouts/frontend-layout.component.ts @@ -7,6 +7,8 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { EnvironmentSelectorComponent } from "../components/environment-selector/environment-selector.component"; import { SharedModule } from "../shared"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-frontend-layout", templateUrl: "frontend-layout.component.html", diff --git a/apps/web/src/app/layouts/header/web-header.component.ts b/apps/web/src/app/layouts/header/web-header.component.ts index 67d447723e1..694ee5c4ae9 100644 --- a/apps/web/src/app/layouts/header/web-header.component.ts +++ b/apps/web/src/app/layouts/header/web-header.component.ts @@ -14,6 +14,8 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { UserId } from "@bitwarden/common/types/guid"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-header", templateUrl: "./web-header.component.html", @@ -23,11 +25,15 @@ export class WebHeaderComponent { /** * Custom title that overrides the route data `titleId` */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() title: string; /** * Icon to show before the title */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() icon: string; protected routeData$: Observable<{ titleId: string }>; diff --git a/apps/web/src/app/layouts/header/web-header.stories.ts b/apps/web/src/app/layouts/header/web-header.stories.ts index 7abddf01f2b..ccc68cf5db9 100644 --- a/apps/web/src/app/layouts/header/web-header.stories.ts +++ b/apps/web/src/app/layouts/header/web-header.stories.ts @@ -46,6 +46,8 @@ class MockStateService { accounts$ = new BehaviorSubject({ "1": { profile: { name: "Foo" } } }).asObservable(); } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "product-switcher", template: ``, @@ -53,6 +55,8 @@ class MockStateService { }) class MockProductSwitcher {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "dynamic-avatar", template: ``, @@ -68,6 +72,8 @@ class MockDynamicAvatar implements Partial { ), ); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() text?: string; diff --git a/apps/web/src/app/layouts/org-switcher/org-switcher.component.ts b/apps/web/src/app/layouts/org-switcher/org-switcher.component.ts index 31689914f13..bf5c2754d4e 100644 --- a/apps/web/src/app/layouts/org-switcher/org-switcher.component.ts +++ b/apps/web/src/app/layouts/org-switcher/org-switcher.component.ts @@ -14,6 +14,8 @@ import { DialogService, NavigationModule } from "@bitwarden/components"; import { OrganizationWarningsModule } from "@bitwarden/web-vault/app/billing/organizations/warnings/organization-warnings.module"; import { OrganizationWarningsService } from "@bitwarden/web-vault/app/billing/organizations/warnings/services"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "org-switcher", templateUrl: "org-switcher.component.html", @@ -43,20 +45,28 @@ export class OrgSwitcherComponent { * const smFilter = (org: Organization) => org.canAccessSecretsManager * // */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() filter: (org: Organization) => boolean = () => true; /** * Is `true` if the expanded content is visible */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() open = false; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() openChange = new EventEmitter(); /** * Visibility of the New Organization button */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() hideNewButton = false; diff --git a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.spec.ts b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.spec.ts index 38e7d12f278..873b306a450 100644 --- a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.spec.ts +++ b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.spec.ts @@ -16,6 +16,8 @@ import { ProductSwitcherItem, ProductSwitcherService } from "../shared/product-s import { NavigationProductSwitcherComponent } from "./navigation-switcher.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-upgrade-nav-button", template: "
Upgrade Nav Button
", diff --git a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.ts b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.ts index 8a02fdd7647..ab835b67545 100644 --- a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.ts +++ b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.component.ts @@ -3,6 +3,8 @@ import { map, Observable } from "rxjs"; import { ProductSwitcherItem, ProductSwitcherService } from "../shared/product-switcher.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "navigation-product-switcher", templateUrl: "./navigation-switcher.component.html", diff --git a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts index fe2821e3d2c..faf1b796b00 100644 --- a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts @@ -37,6 +37,8 @@ class MockOrganizationService implements Partial { return MockOrganizationService._orgs.asObservable(); } + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() set mockOrgs(orgs: Organization[]) { MockOrganizationService._orgs.next(orgs); @@ -54,6 +56,8 @@ class MockProviderService implements Partial { return MockProviderService._providers.asObservable(); } + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() set mockProviders(providers: Provider[]) { MockProviderService._providers.next(providers); @@ -93,6 +97,8 @@ class MockConfigService implements Partial { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "story-layout", template: ``, @@ -100,6 +106,8 @@ class MockConfigService implements Partial { }) class StoryLayoutComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "story-content", template: ``, diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher-content.component.ts b/apps/web/src/app/layouts/product-switcher/product-switcher-content.component.ts index 5a6572e15be..0157e7b321a 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher-content.component.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher-content.component.ts @@ -6,12 +6,16 @@ import { MenuComponent } from "@bitwarden/components"; import { ProductSwitcherService } from "./shared/product-switcher.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "product-switcher-content", templateUrl: "./product-switcher-content.component.html", standalone: false, }) export class ProductSwitcherContentComponent { + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ViewChild("menu") menu: MenuComponent; diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts index 5dd29815ef2..114d95097a2 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts @@ -5,6 +5,8 @@ import { AfterViewInit, ChangeDetectorRef, Component, Input } from "@angular/cor import { IconButtonType } from "@bitwarden/components/src/icon-button/icon-button.component"; import { ProductSwitcherService } from "./shared/product-switcher.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "product-switcher", templateUrl: "./product-switcher.component.html", @@ -14,6 +16,8 @@ export class ProductSwitcherComponent implements AfterViewInit { /** * Passed to the product switcher's `bitIconButton` */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() buttonType: IconButtonType = "main"; diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts index 66b6a6fb3cf..4c6af713464 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts @@ -37,6 +37,8 @@ class MockOrganizationService implements Partial { return MockOrganizationService._orgs.asObservable(); } + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() set mockOrgs(orgs: Organization[]) { MockOrganizationService._orgs.next(orgs); @@ -54,6 +56,8 @@ class MockProviderService implements Partial { return MockProviderService._providers.asObservable(); } + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() set mockProviders(providers: Provider[]) { MockProviderService._providers.next(providers); @@ -93,6 +97,8 @@ class MockConfigService implements Partial { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "story-layout", template: ``, @@ -100,6 +106,8 @@ class MockConfigService implements Partial { }) class StoryLayoutComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "story-content", template: ``, diff --git a/apps/web/src/app/layouts/toggle-width.component.ts b/apps/web/src/app/layouts/toggle-width.component.ts index 411fc73b175..25b8790bb4a 100644 --- a/apps/web/src/app/layouts/toggle-width.component.ts +++ b/apps/web/src/app/layouts/toggle-width.component.ts @@ -4,6 +4,8 @@ import { Component } from "@angular/core"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { NavigationModule } from "@bitwarden/components"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-toggle-width", template: `({ alias: "appA11yTitle" }); + readonly title = input.required({ alias: "appA11yTitle" }); constructor(private el: ElementRef) { const originalTitle = this.el.nativeElement.getAttribute("title"); diff --git a/libs/components/src/anon-layout/anon-layout-wrapper.component.ts b/libs/components/src/anon-layout/anon-layout-wrapper.component.ts index a17e11b424c..553da0c541b 100644 --- a/libs/components/src/anon-layout/anon-layout-wrapper.component.ts +++ b/libs/components/src/anon-layout/anon-layout-wrapper.component.ts @@ -46,6 +46,8 @@ export interface AnonLayoutWrapperData { hideBackgroundIllustration?: boolean; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ templateUrl: "anon-layout-wrapper.component.html", imports: [AnonLayoutComponent, RouterModule], diff --git a/libs/components/src/anon-layout/anon-layout-wrapper.stories.ts b/libs/components/src/anon-layout/anon-layout-wrapper.stories.ts index 7fc022a5ad9..76fcc8976c7 100644 --- a/libs/components/src/anon-layout/anon-layout-wrapper.stories.ts +++ b/libs/components/src/anon-layout/anon-layout-wrapper.stories.ts @@ -103,6 +103,8 @@ type Story = StoryObj; // Default Example +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-default-primary-outlet-example-component", template: "

Primary Outlet Example:
your primary component goes here

", @@ -110,6 +112,8 @@ type Story = StoryObj; }) export class DefaultPrimaryOutletExampleComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-default-secondary-outlet-example-component", template: "

Secondary Outlet Example:
your secondary component goes here

", @@ -117,6 +121,8 @@ export class DefaultPrimaryOutletExampleComponent {} }) export class DefaultSecondaryOutletExampleComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-default-env-selector-outlet-example-component", template: "

Env Selector Outlet Example:
your env selector component goes here

", @@ -192,6 +198,8 @@ const changedData: AnonLayoutWrapperData = { pageIcon: RegistrationCheckEmailIcon, }; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-dynamic-content-example-component", template: ` diff --git a/libs/components/src/anon-layout/anon-layout.component.ts b/libs/components/src/anon-layout/anon-layout.component.ts index c58b8d7e164..596a54f8825 100644 --- a/libs/components/src/anon-layout/anon-layout.component.ts +++ b/libs/components/src/anon-layout/anon-layout.component.ts @@ -27,6 +27,8 @@ import { TypographyModule } from "../typography"; export type AnonLayoutMaxWidth = "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "auth-anon-layout", templateUrl: "./anon-layout.component.html", diff --git a/libs/components/src/app/app.component.ts b/libs/components/src/app/app.component.ts index ed8cf595d5e..c2829956219 100644 --- a/libs/components/src/app/app.component.ts +++ b/libs/components/src/app/app.component.ts @@ -1,5 +1,7 @@ import { Component } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-root", template: "", diff --git a/libs/components/src/async-actions/in-forms.stories.ts b/libs/components/src/async-actions/in-forms.stories.ts index af5034c49d5..7a19908cbbf 100644 --- a/libs/components/src/async-actions/in-forms.stories.ts +++ b/libs/components/src/async-actions/in-forms.stories.ts @@ -39,6 +39,8 @@ const template = ` `; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-promise-example", template, @@ -84,6 +86,8 @@ class PromiseExampleComponent { }; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-observable-example", template, diff --git a/libs/components/src/async-actions/standalone.stories.ts b/libs/components/src/async-actions/standalone.stories.ts index 150bdb8813b..52c1e990c23 100644 --- a/libs/components/src/async-actions/standalone.stories.ts +++ b/libs/components/src/async-actions/standalone.stories.ts @@ -20,6 +20,8 @@ const template = /*html*/ ` `; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template, selector: "app-promise-example", @@ -37,6 +39,8 @@ class PromiseExampleComponent { }; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template, selector: "app-action-resolves-quickly", @@ -55,6 +59,8 @@ class ActionResolvesQuicklyComponent { }; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template, selector: "app-observable-example", @@ -66,6 +72,8 @@ class ObservableExampleComponent { }; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template, selector: "app-rejected-promise-example", diff --git a/libs/components/src/avatar/avatar.component.ts b/libs/components/src/avatar/avatar.component.ts index 8ece033c73d..38f85bd7b1e 100644 --- a/libs/components/src/avatar/avatar.component.ts +++ b/libs/components/src/avatar/avatar.component.ts @@ -19,6 +19,8 @@ const SizeClasses: Record = { * A variance in color across the avatar component is important as it is used in Account Switching as a * visual indicator to recognize which of a personal or work account a user is logged into. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-avatar", template: ` diff --git a/libs/components/src/badge-list/badge-list.component.ts b/libs/components/src/badge-list/badge-list.component.ts index b9d9a666261..e3d1403be43 100644 --- a/libs/components/src/badge-list/badge-list.component.ts +++ b/libs/components/src/badge-list/badge-list.component.ts @@ -8,6 +8,8 @@ function transformMaxItems(value: number | undefined) { return value == undefined ? undefined : Math.max(1, value); } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-badge-list", templateUrl: "badge-list.component.html", diff --git a/libs/components/src/badge/badge.component.ts b/libs/components/src/badge/badge.component.ts index 37be13ef15a..8a953b30226 100644 --- a/libs/components/src/badge/badge.component.ts +++ b/libs/components/src/badge/badge.component.ts @@ -55,6 +55,8 @@ const hoverStyles: Record = { * > `NOTE:` The `disabled` state only applies to buttons. * */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "span[bitBadge], a[bitBadge], button[bitBadge]", providers: [{ provide: FocusableElement, useExisting: BadgeComponent }], diff --git a/libs/components/src/banner/banner.component.ts b/libs/components/src/banner/banner.component.ts index 632bccae953..f258ed0c48c 100644 --- a/libs/components/src/banner/banner.component.ts +++ b/libs/components/src/banner/banner.component.ts @@ -23,6 +23,8 @@ const defaultIcon: Record = { * - Avoid stacking multiple banners. * - Banners can contain a button or anchor that uses the `bitLink` directive with `linkType="secondary"`. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-banner", templateUrl: "./banner.component.html", @@ -40,6 +42,8 @@ export class BannerComponent implements OnInit { readonly useAlertRole = input(true); readonly showClose = input(true); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() onClose = new EventEmitter(); ngOnInit(): void { diff --git a/libs/components/src/breadcrumbs/breadcrumb.component.ts b/libs/components/src/breadcrumbs/breadcrumb.component.ts index 783cb2655f7..6c79b449a28 100644 --- a/libs/components/src/breadcrumbs/breadcrumb.component.ts +++ b/libs/components/src/breadcrumbs/breadcrumb.component.ts @@ -1,6 +1,8 @@ import { Component, EventEmitter, Output, TemplateRef, input, viewChild } from "@angular/core"; import { QueryParamsHandling } from "@angular/router"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-breadcrumb", templateUrl: "./breadcrumb.component.html", @@ -14,6 +16,8 @@ export class BreadcrumbComponent { readonly queryParamsHandling = input(); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() click = new EventEmitter(); diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.ts b/libs/components/src/breadcrumbs/breadcrumbs.component.ts index 3c24f91be99..f0e4c4557c3 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.component.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.component.ts @@ -15,6 +15,8 @@ import { BreadcrumbComponent } from "./breadcrumb.component"; * Bitwarden uses this component to indicate the user's current location in a set of data organized in * containers (Collections, Folders, or Projects). */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-breadcrumbs", templateUrl: "./breadcrumbs.component.html", @@ -25,6 +27,8 @@ export class BreadcrumbsComponent { private breadcrumbs: BreadcrumbComponent[] = []; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ContentChildren(BreadcrumbComponent) protected set breadcrumbList(value: QueryList) { this.breadcrumbs = value.toArray(); diff --git a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts index 989b72adbd5..3064ffe3cb4 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts @@ -18,6 +18,8 @@ interface Breadcrumb { route: string; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: "", }) diff --git a/libs/components/src/button/button.component.spec.ts b/libs/components/src/button/button.component.spec.ts index 1651b6cf12a..745be014a0c 100644 --- a/libs/components/src/button/button.component.spec.ts +++ b/libs/components/src/button/button.component.spec.ts @@ -56,6 +56,8 @@ describe("Button", () => { }); }); +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-app", template: ` diff --git a/libs/components/src/button/button.component.ts b/libs/components/src/button/button.component.ts index 47612685c16..350d493f832 100644 --- a/libs/components/src/button/button.component.ts +++ b/libs/components/src/button/button.component.ts @@ -57,6 +57,8 @@ const buttonStyles: Record = { unstyled: [], }; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "button[bitButton], a[bitButton]", templateUrl: "button.component.html", @@ -97,7 +99,7 @@ export class ButtonComponent implements ButtonLikeAbstraction { .concat(buttonSizeStyles[this.size() || "default"]); } - protected disabledAttr = computed(() => { + protected readonly disabledAttr = computed(() => { const disabled = this.disabled() != null && this.disabled() !== false; return disabled || this.loading(); }); @@ -110,7 +112,7 @@ export class ButtonComponent implements ButtonLikeAbstraction { * We can't use `disabledAttr` for this, because it returns `true` when `loading` is `true`. * We only want to show disabled styles during loading if `showLoadingStyles` is `true`. */ - protected showDisabledStyles = computed(() => { + protected readonly showDisabledStyles = computed(() => { return this.showLoadingStyle() || (this.disabledAttr() && this.loading() === false); }); @@ -134,11 +136,11 @@ export class ButtonComponent implements ButtonLikeAbstraction { * This pattern of converting a signal to an observable and back to a signal is not * recommended. TODO -- find better way to use debounce with signals (CL-596) */ - protected showLoadingStyle = toSignal( + protected readonly showLoadingStyle = toSignal( toObservable(this.loading).pipe(debounce((isLoading) => interval(isLoading ? 75 : 0))), ); - disabled = model(false); + readonly disabled = model(false); private el = inject(ElementRef); constructor() { diff --git a/libs/components/src/callout/callout.component.ts b/libs/components/src/callout/callout.component.ts index c15bc132035..bda5d4585d7 100644 --- a/libs/components/src/callout/callout.component.ts +++ b/libs/components/src/callout/callout.component.ts @@ -28,6 +28,8 @@ let nextId = 0; * sparingly, as they command a large amount of visual attention. Avoid using more than 1 callout in * the same location. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-callout", templateUrl: "callout.component.html", diff --git a/libs/components/src/checkbox/checkbox.component.ts b/libs/components/src/checkbox/checkbox.component.ts index d8df53943f3..61d5bb7251c 100644 --- a/libs/components/src/checkbox/checkbox.component.ts +++ b/libs/components/src/checkbox/checkbox.component.ts @@ -3,6 +3,8 @@ import { NgControl, Validators } from "@angular/forms"; import { BitFormControlAbstraction } from "../form-control"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "input[type=checkbox][bitCheckbox]", template: "", diff --git a/libs/components/src/checkbox/checkbox.stories.ts b/libs/components/src/checkbox/checkbox.stories.ts index ee3e4ab402d..6355581b251 100644 --- a/libs/components/src/checkbox/checkbox.stories.ts +++ b/libs/components/src/checkbox/checkbox.stories.ts @@ -28,6 +28,8 @@ const template = /*html*/ ` `; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-example", template, @@ -38,10 +40,14 @@ class ExampleComponent { checkbox: [false, Validators.requiredTrue], }); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() set checked(value: boolean) { this.formObj.patchValue({ checkbox: value }); } + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() set disabled(disable: boolean) { if (disable) { this.formObj.disable(); diff --git a/libs/components/src/chip-select/chip-select.component.ts b/libs/components/src/chip-select/chip-select.component.ts index 14f740f3bbe..78f12c400b5 100644 --- a/libs/components/src/chip-select/chip-select.component.ts +++ b/libs/components/src/chip-select/chip-select.component.ts @@ -35,6 +35,8 @@ export type ChipSelectOption = Option & { /** * `` is a select element that is commonly used to filter items in lists or tables. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-chip-select", templateUrl: "chip-select.component.html", @@ -49,6 +51,8 @@ export type ChipSelectOption = Option & { }) export class ChipSelectComponent implements ControlValueAccessor, AfterViewInit { readonly menu = viewChild(MenuComponent); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ViewChildren(MenuItemDirective) menuItems?: QueryList; readonly chipSelectButton = viewChild>("chipSelectButton"); @@ -63,6 +67,8 @@ export class ChipSelectComponent implements ControlValueAccessor, A // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. /** The select options to render */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ required: true }) get options(): ChipSelectOption[] { return this._options; @@ -75,6 +81,8 @@ export class ChipSelectComponent implements ControlValueAccessor, A /** Disables the entire chip */ // TODO: Skipped for signal migration because: // Your application code writes to the input. This prevents migration. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) disabled = false; /** Chip will stretch to full width of its container */ @@ -83,7 +91,7 @@ export class ChipSelectComponent implements ControlValueAccessor, A /** * We have `:focus-within` and `:focus-visible` but no `:focus-visible-within` */ - protected focusVisibleWithin = signal(false); + protected readonly focusVisibleWithin = signal(false); @HostListener("focusin", ["$event.target"]) onFocusIn(target: HTMLElement) { this.focusVisibleWithin.set(target.matches("[data-fvw-target]:focus-visible")); diff --git a/libs/components/src/color-password/color-password.component.ts b/libs/components/src/color-password/color-password.component.ts index 3a35eaab333..bd7f3beb403 100644 --- a/libs/components/src/color-password/color-password.component.ts +++ b/libs/components/src/color-password/color-password.component.ts @@ -9,6 +9,8 @@ type CharacterType = "letter" | "emoji" | "special" | "number"; * the logic for displaying letters as `text-main`, numbers as `primary`, and special symbols as * `danger`. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-color-password", template: `@for (character of passwordCharArray(); track $index; let i = $index) { @@ -21,11 +23,11 @@ type CharacterType = "letter" | "emoji" | "special" | "number"; }`, }) export class ColorPasswordComponent { - password = input(""); - showCount = input(false); + readonly password = input(""); + readonly showCount = input(false); // Convert to an array to handle cases that strings have special characters, i.e.: emoji. - passwordCharArray = computed(() => { + readonly passwordCharArray = computed(() => { return Array.from(this.password() ?? ""); }); diff --git a/libs/components/src/container/container.component.ts b/libs/components/src/container/container.component.ts index 9f6a4cbef94..40b19b16598 100644 --- a/libs/components/src/container/container.component.ts +++ b/libs/components/src/container/container.component.ts @@ -3,6 +3,8 @@ import { Component } from "@angular/core"; /** * bit-container is a minimally styled component that limits the max width of its content to the tailwind theme variable '4xl'. '4xl' is equal to the value of 56rem */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-container", templateUrl: "container.component.html", diff --git a/libs/components/src/copy-click/copy-click.directive.spec.ts b/libs/components/src/copy-click/copy-click.directive.spec.ts index 321a18596e4..ed3640b7d6d 100644 --- a/libs/components/src/copy-click/copy-click.directive.spec.ts +++ b/libs/components/src/copy-click/copy-click.directive.spec.ts @@ -9,6 +9,8 @@ import { ToastService, CopyClickListener, COPY_CLICK_LISTENER } from "../"; import { CopyClickDirective } from "./copy-click.directive"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @@ -25,9 +27,17 @@ import { CopyClickDirective } from "./copy-click.directive"; imports: [CopyClickDirective], }) class TestCopyClickComponent { + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ViewChild("noToast") noToastButton!: ElementRef; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ViewChild("infoToast") infoToastButton!: ElementRef; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ViewChild("successToast") successToastButton!: ElementRef; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ViewChild("toastWithLabel") toastWithLabelButton!: ElementRef; } diff --git a/libs/components/src/copy-click/copy-click.directive.ts b/libs/components/src/copy-click/copy-click.directive.ts index 3eb075a2b5c..f12880f8781 100644 --- a/libs/components/src/copy-click/copy-click.directive.ts +++ b/libs/components/src/copy-click/copy-click.directive.ts @@ -26,11 +26,11 @@ export const COPY_CLICK_LISTENER = new InjectionToken("CopyCl selector: "[appCopyClick]", }) export class CopyClickDirective { - private _showToast = computed(() => { + private readonly _showToast = computed(() => { return this.showToast() !== undefined; }); - private toastVariant = computed(() => { + private readonly toastVariant = computed(() => { const showToast = this.showToast(); // When the `showToast` is set without a value, an empty string will be passed if (showToast === "" || showToast === undefined) { @@ -68,7 +68,7 @@ export class CopyClickDirective { * * ``` */ - showToast = input(); + readonly showToast = input(); @HostListener("click") onClick() { const valueToCopy = this.valueToCopy(); diff --git a/libs/components/src/dialog/dialog.service.stories.ts b/libs/components/src/dialog/dialog.service.stories.ts index caa7a86a2a8..9bcb704a7fd 100644 --- a/libs/components/src/dialog/dialog.service.stories.ts +++ b/libs/components/src/dialog/dialog.service.stories.ts @@ -21,6 +21,8 @@ interface Animal { animal: string; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @@ -62,6 +64,8 @@ class StoryDialogComponent { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @@ -91,6 +95,8 @@ class StoryDialogContentComponent { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` >("scrollBottom"); + private readonly scrollableBody = viewChild.required(CdkScrollable); + private readonly scrollBottom = viewChild.required>("scrollBottom"); protected dialogRef = inject(DialogRef, { optional: true }); protected bodyHasScrolledFrom = hasScrolledFrom(this.scrollableBody); diff --git a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts index 4c04f0e29c9..eed031d76fb 100644 --- a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts +++ b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts @@ -26,6 +26,8 @@ const DEFAULT_COLOR: Record = { danger: "tw-text-danger", }; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ templateUrl: "./simple-configurable-dialog.component.html", imports: [ diff --git a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts index 036ef1177e6..7d1b5974d51 100644 --- a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts @@ -10,6 +10,8 @@ import { CalloutModule } from "../../../callout"; import { I18nMockService } from "../../../utils/i18n-mock.service"; import { DialogModule } from "../../dialog.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @for (group of dialogs; track group) { diff --git a/libs/components/src/dialog/simple-dialog/simple-dialog.component.ts b/libs/components/src/dialog/simple-dialog/simple-dialog.component.ts index 85f1bed8cf5..cd44a79c271 100644 --- a/libs/components/src/dialog/simple-dialog/simple-dialog.component.ts +++ b/libs/components/src/dialog/simple-dialog/simple-dialog.component.ts @@ -9,6 +9,8 @@ import { DialogTitleContainerDirective } from "../directives/dialog-title-contai }) export class IconDirective {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-simple-dialog", templateUrl: "./simple-dialog.component.html", @@ -16,12 +18,14 @@ export class IconDirective {} imports: [DialogTitleContainerDirective, TypographyDirective], }) export class SimpleDialogComponent { + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ContentChild(IconDirective) icon!: IconDirective; /** * Optional flag to hide the dialog's center icon. Defaults to false. */ - hideIcon = input(false, { transform: booleanAttribute }); + readonly hideIcon = input(false, { transform: booleanAttribute }); get hasIcon() { return this.icon != null; diff --git a/libs/components/src/dialog/simple-dialog/simple-dialog.service.stories.ts b/libs/components/src/dialog/simple-dialog/simple-dialog.service.stories.ts index ce9f7b46fef..5c94a959f25 100644 --- a/libs/components/src/dialog/simple-dialog/simple-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-dialog/simple-dialog.service.stories.ts @@ -15,6 +15,8 @@ interface Animal { animal: string; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @@ -57,6 +59,8 @@ class StoryDialogComponent { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @@ -87,6 +91,8 @@ class SimpleDialogContent { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` @@ -116,6 +122,8 @@ class NonDismissableWithPrimaryButtonContent { } } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` diff --git a/libs/components/src/disclosure/disclosure.component.ts b/libs/components/src/disclosure/disclosure.component.ts index 2d73d7d8ad6..60e886f1dcc 100644 --- a/libs/components/src/disclosure/disclosure.component.ts +++ b/libs/components/src/disclosure/disclosure.component.ts @@ -34,12 +34,16 @@ let nextId = 0; * ``` * */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-disclosure", template: ``, }) export class DisclosureComponent { /** Emits the visibility of the disclosure content */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() openChange = new EventEmitter(); private _open?: boolean; @@ -48,6 +52,8 @@ export class DisclosureComponent { */ // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) set open(isOpen: boolean) { this._open = isOpen; this.openChange.emit(isOpen); diff --git a/libs/components/src/drawer/drawer-header.component.ts b/libs/components/src/drawer/drawer-header.component.ts index 36addcd2bea..006c48e091d 100644 --- a/libs/components/src/drawer/drawer-header.component.ts +++ b/libs/components/src/drawer/drawer-header.component.ts @@ -24,7 +24,7 @@ export class DrawerHeaderComponent { /** * The title to display */ - title = input.required(); + readonly title = input.required(); /** We don't want to set the HTML title attribute with `this.title` */ @HostBinding("attr.title") diff --git a/libs/components/src/drawer/drawer-host.directive.ts b/libs/components/src/drawer/drawer-host.directive.ts index 64eea6a9c06..7804d111ed6 100644 --- a/libs/components/src/drawer/drawer-host.directive.ts +++ b/libs/components/src/drawer/drawer-host.directive.ts @@ -10,7 +10,7 @@ import { Directive, signal } from "@angular/core"; selector: "[bitDrawerHost]", }) export class DrawerHostDirective { - private _portal = signal | undefined>(undefined); + private readonly _portal = signal | undefined>(undefined); /** The portal to display */ portal = this._portal.asReadonly(); diff --git a/libs/components/src/drawer/drawer.component.ts b/libs/components/src/drawer/drawer.component.ts index 7a3c764b16f..042d1eace79 100644 --- a/libs/components/src/drawer/drawer.component.ts +++ b/libs/components/src/drawer/drawer.component.ts @@ -25,7 +25,7 @@ import { DrawerService } from "./drawer.service"; }) export class DrawerComponent { private drawerHost = inject(DrawerService); - private portal = viewChild.required(CdkPortal); + private readonly portal = viewChild.required(CdkPortal); /** * Whether or not the drawer is open. @@ -33,7 +33,7 @@ export class DrawerComponent { * Note: Does not support implicit boolean transform due to Angular limitation. Must be bound explicitly `[open]="true"` instead of just `open`. * https://github.com/angular/angular/issues/55166#issuecomment-2032150999 **/ - open = model(false); + readonly open = model(false); /** * The ARIA role of the drawer. @@ -43,7 +43,7 @@ export class DrawerComponent { * - [navigation](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/navigation_role) * - For drawers that primary contain links to other content. */ - role = input<"complementary" | "navigation">("complementary"); + readonly role = input<"complementary" | "navigation">("complementary"); constructor() { effect( diff --git a/libs/components/src/drawer/drawer.service.ts b/libs/components/src/drawer/drawer.service.ts index dd8575efee8..71b3ff967d7 100644 --- a/libs/components/src/drawer/drawer.service.ts +++ b/libs/components/src/drawer/drawer.service.ts @@ -3,7 +3,7 @@ import { Injectable, signal } from "@angular/core"; @Injectable({ providedIn: "root" }) export class DrawerService { - private _portal = signal | undefined>(undefined); + private readonly _portal = signal | undefined>(undefined); /** The portal to display */ portal = this._portal.asReadonly(); diff --git a/libs/components/src/form-control/form-control.component.ts b/libs/components/src/form-control/form-control.component.ts index be1a071bcab..642d280bdcb 100644 --- a/libs/components/src/form-control/form-control.component.ts +++ b/libs/components/src/form-control/form-control.component.ts @@ -8,6 +8,8 @@ import { TypographyDirective } from "../typography/typography.directive"; import { BitFormControlAbstraction } from "./form-control.abstraction"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-form-control", templateUrl: "form-control.component.html", diff --git a/libs/components/src/form-control/label.component.ts b/libs/components/src/form-control/label.component.ts index 224e00c31da..57f9e338bb6 100644 --- a/libs/components/src/form-control/label.component.ts +++ b/libs/components/src/form-control/label.component.ts @@ -6,6 +6,8 @@ import { FormControlComponent } from "./form-control.component"; // Increments for each instance of this component let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-label", templateUrl: "label.component.html", diff --git a/libs/components/src/form-field/error-summary.component.ts b/libs/components/src/form-field/error-summary.component.ts index 1b0b5bb3cbf..cf26fd1e21f 100644 --- a/libs/components/src/form-field/error-summary.component.ts +++ b/libs/components/src/form-field/error-summary.component.ts @@ -3,6 +3,8 @@ import { AbstractControl, UntypedFormGroup } from "@angular/forms"; import { I18nPipe } from "@bitwarden/ui-common"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-error-summary", template: ` @if (errorCount > 0) { diff --git a/libs/components/src/form-field/error.component.ts b/libs/components/src/form-field/error.component.ts index ed9d7eafe8d..9d931a64db2 100644 --- a/libs/components/src/form-field/error.component.ts +++ b/libs/components/src/form-field/error.component.ts @@ -5,6 +5,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic // Increments for each instance of this component let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-error", template: ` {{ displayError }}`, diff --git a/libs/components/src/form-field/form-field.component.ts b/libs/components/src/form-field/form-field.component.ts index 26038caa466..ccfdcec4132 100644 --- a/libs/components/src/form-field/form-field.component.ts +++ b/libs/components/src/form-field/form-field.component.ts @@ -22,6 +22,8 @@ import { inputBorderClasses } from "../input/input.directive"; import { BitErrorComponent } from "./error.component"; import { BitFormFieldControl } from "./form-field-control"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-form-field", templateUrl: "./form-field.component.html", @@ -42,11 +44,13 @@ export class BitFormFieldComponent implements AfterContentChecked { /** If `true`, remove the bottom border for `readonly` inputs */ // TODO: Skipped for signal migration because: // Your application code writes to the input. This prevents migration. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) disableReadOnlyBorder = false; - protected prefixHasChildren = signal(false); - protected suffixHasChildren = signal(false); + protected readonly prefixHasChildren = signal(false); + protected readonly suffixHasChildren = signal(false); get inputBorderClasses(): string { const shouldFocusBorderAppear = this.defaultContentIsFocused(); @@ -87,7 +91,7 @@ export class BitFormFieldComponent implements AfterContentChecked { * This is necessary because the `tw-group/bit-form-field` wraps the input and any prefix/suffix * buttons */ - protected defaultContentIsFocused = signal(false); + protected readonly defaultContentIsFocused = signal(false); @HostListener("focusin", ["$event.target"]) onFocusIn(target: HTMLElement) { this.defaultContentIsFocused.set(target.matches("[data-default-content] *:focus-visible")); diff --git a/libs/components/src/form-field/password-input-toggle.directive.ts b/libs/components/src/form-field/password-input-toggle.directive.ts index 251878f5cef..ba5539250a6 100644 --- a/libs/components/src/form-field/password-input-toggle.directive.ts +++ b/libs/components/src/form-field/password-input-toggle.directive.ts @@ -27,6 +27,8 @@ export class BitPasswordInputToggleDirective implements AfterContentInit, OnChan * Whether the input is toggled to show the password. */ readonly toggled = model(false); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() toggledChange = new EventEmitter(); @HostBinding("attr.title") title = this.i18nService.t("toggleVisibility"); diff --git a/libs/components/src/form-field/password-input-toggle.spec.ts b/libs/components/src/form-field/password-input-toggle.spec.ts index 2b82fad9876..2a90622513a 100644 --- a/libs/components/src/form-field/password-input-toggle.spec.ts +++ b/libs/components/src/form-field/password-input-toggle.spec.ts @@ -13,6 +13,8 @@ import { BitFormFieldComponent } from "./form-field.component"; import { FormFieldModule } from "./form-field.module"; import { BitPasswordInputToggleDirective } from "./password-input-toggle.directive"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-form-field", template: ` diff --git a/libs/components/src/icon-button/icon-button.component.ts b/libs/components/src/icon-button/icon-button.component.ts index d712d5cb2b8..f1edee7c089 100644 --- a/libs/components/src/icon-button/icon-button.component.ts +++ b/libs/components/src/icon-button/icon-button.component.ts @@ -81,6 +81,8 @@ const sizes: Record = { * Similar to the main button components, spacing between multiple icon buttons should be .5rem. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "button[bitIconButton]:not(button[bitButton])", templateUrl: "icon-button.component.html", @@ -143,7 +145,7 @@ export class BitIconButtonComponent implements ButtonLikeAbstraction, FocusableE return [this.icon(), "!tw-m-0"]; } - protected disabledAttr = computed(() => { + protected readonly disabledAttr = computed(() => { const disabled = this.disabled() != null && this.disabled() !== false; return disabled || this.loading(); }); @@ -156,7 +158,7 @@ export class BitIconButtonComponent implements ButtonLikeAbstraction, FocusableE * We can't use `disabledAttr` for this, because it returns `true` when `loading` is `true`. * We only want to show disabled styles during loading if `showLoadingStyles` is `true`. */ - protected showDisabledStyles = computed(() => { + protected readonly showDisabledStyles = computed(() => { return this.showLoadingStyle() || (this.disabledAttr() && this.loading() === false); }); @@ -174,7 +176,7 @@ export class BitIconButtonComponent implements ButtonLikeAbstraction, FocusableE * This pattern of converting a signal to an observable and back to a signal is not * recommended. TODO -- find better way to use debounce with signals (CL-596) */ - protected showLoadingStyle = toSignal( + protected readonly showLoadingStyle = toSignal( toObservable(this.loading).pipe(debounce((isLoading) => interval(isLoading ? 75 : 0))), ); diff --git a/libs/components/src/icon-tile/icon-tile.component.ts b/libs/components/src/icon-tile/icon-tile.component.ts index 54e92f9f004..68eed007df0 100644 --- a/libs/components/src/icon-tile/icon-tile.component.ts +++ b/libs/components/src/icon-tile/icon-tile.component.ts @@ -56,6 +56,8 @@ const shapeStyles: Record> = { * - Create visual hierarchy in lists or cards * - Show app or service icons in a consistent format */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-icon-tile", templateUrl: "icon-tile.component.html", diff --git a/libs/components/src/icon/icon.component.ts b/libs/components/src/icon/icon.component.ts index 1ef7185c88b..f57a3627383 100644 --- a/libs/components/src/icon/icon.component.ts +++ b/libs/components/src/icon/icon.component.ts @@ -3,6 +3,8 @@ import { DomSanitizer, SafeHtml } from "@angular/platform-browser"; import { Icon, isIcon } from "@bitwarden/assets/svg"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-icon", host: { diff --git a/libs/components/src/input/input.directive.ts b/libs/components/src/input/input.directive.ts index 465736f7baa..ce34b70e88b 100644 --- a/libs/components/src/input/input.directive.ts +++ b/libs/components/src/input/input.directive.ts @@ -74,6 +74,8 @@ export class BitInputDirective implements BitFormFieldControl { // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. @HostBinding() + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() get required() { return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false; diff --git a/libs/components/src/item/item-action.component.ts b/libs/components/src/item/item-action.component.ts index acbc805cf90..b7ce1705f7c 100644 --- a/libs/components/src/item/item-action.component.ts +++ b/libs/components/src/item/item-action.component.ts @@ -1,5 +1,7 @@ import { Component } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-item-action", imports: [], diff --git a/libs/components/src/item/item-content.component.ts b/libs/components/src/item/item-content.component.ts index 1f4ac73c77e..9c24d010946 100644 --- a/libs/components/src/item/item-content.component.ts +++ b/libs/components/src/item/item-content.component.ts @@ -29,7 +29,7 @@ import { TypographyModule } from "../typography"; export class ItemContentComponent implements AfterContentChecked { readonly endSlot = viewChild>("endSlot"); - protected endSlotHasChildren = signal(false); + protected readonly endSlotHasChildren = signal(false); /** * Determines whether text will truncate or wrap. diff --git a/libs/components/src/item/item.component.ts b/libs/components/src/item/item.component.ts index f6f2c3d7e35..a3fa8386325 100644 --- a/libs/components/src/item/item.component.ts +++ b/libs/components/src/item/item.component.ts @@ -22,7 +22,7 @@ export class ItemComponent { /** * We have `:focus-within` and `:focus-visible` but no `:focus-visible-within` */ - protected focusVisibleWithin = signal(false); + protected readonly focusVisibleWithin = signal(false); @HostListener("focusin", ["$event.target"]) onFocusIn(target: HTMLElement) { this.focusVisibleWithin.set(target.matches("[data-fvw-target]:focus-visible")); diff --git a/libs/components/src/layout/layout.component.ts b/libs/components/src/layout/layout.component.ts index 54b0341603c..1b357424205 100644 --- a/libs/components/src/layout/layout.component.ts +++ b/libs/components/src/layout/layout.component.ts @@ -12,6 +12,8 @@ import { SharedModule } from "../shared"; import { ScrollLayoutHostDirective } from "./scroll-layout.directive"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-layout", templateUrl: "layout.component.html", @@ -34,7 +36,7 @@ export class LayoutComponent { protected sideNavService = inject(SideNavService); protected drawerPortal = inject(DrawerService).portal; - private mainContent = viewChild.required>("main"); + private readonly mainContent = viewChild.required>("main"); protected focusMainContent() { this.mainContent().nativeElement.focus(); } @@ -45,7 +47,7 @@ export class LayoutComponent { * * @see https://github.com/angular/components/issues/10247#issuecomment-384060265 **/ - private skipLink = viewChild.required>("skipLink"); + private readonly skipLink = viewChild.required>("skipLink"); handleKeydown(ev: KeyboardEvent) { if (isNothingFocused()) { ev.preventDefault(); diff --git a/libs/components/src/layout/scroll-layout.directive.ts b/libs/components/src/layout/scroll-layout.directive.ts index cb2c2a4e431..35a4c5b63d8 100644 --- a/libs/components/src/layout/scroll-layout.directive.ts +++ b/libs/components/src/layout/scroll-layout.directive.ts @@ -17,7 +17,7 @@ import { filter, fromEvent, Observable, switchMap } from "rxjs"; **/ @Injectable({ providedIn: "root" }) export class ScrollLayoutService { - scrollableRef = signal | null>(null); + readonly scrollableRef = signal | null>(null); scrollableRef$ = toObservable(this.scrollableRef); } diff --git a/libs/components/src/link/link.directive.ts b/libs/components/src/link/link.directive.ts index 7c93b185a79..e6de8ac8402 100644 --- a/libs/components/src/link/link.directive.ts +++ b/libs/components/src/link/link.directive.ts @@ -99,7 +99,7 @@ export class AnchorLinkDirective extends LinkDirective { export class ButtonLinkDirective extends LinkDirective { private el = inject(ElementRef); - disabled = input(false, { transform: booleanAttribute }); + readonly disabled = input(false, { transform: booleanAttribute }); @HostBinding("class") get classList() { return ["before:-tw-inset-y-[0.25rem]"] diff --git a/libs/components/src/menu/menu-divider.component.ts b/libs/components/src/menu/menu-divider.component.ts index 194506ee50f..3bf992d3688 100644 --- a/libs/components/src/menu/menu-divider.component.ts +++ b/libs/components/src/menu/menu-divider.component.ts @@ -1,5 +1,7 @@ import { Component } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-menu-divider", templateUrl: "./menu-divider.component.html", diff --git a/libs/components/src/menu/menu-item.directive.ts b/libs/components/src/menu/menu-item.directive.ts index 088e2a4293f..e19e208f7b0 100644 --- a/libs/components/src/menu/menu-item.directive.ts +++ b/libs/components/src/menu/menu-item.directive.ts @@ -3,6 +3,8 @@ import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { NgClass } from "@angular/common"; import { Component, ElementRef, HostBinding, Input } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "[bitMenuItem]", templateUrl: "menu-item.component.html", @@ -42,6 +44,8 @@ export class MenuItemDirective implements FocusableOption { // TODO: Skipped for signal migration because: // This input overrides a field from a superclass, while the superclass field // is not migrated. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: coerceBooleanProperty }) disabled?: boolean = false; constructor(public elementRef: ElementRef) {} diff --git a/libs/components/src/menu/menu.component.spec.ts b/libs/components/src/menu/menu.component.spec.ts index 3153fd4eb37..59ad7c6dbc8 100644 --- a/libs/components/src/menu/menu.component.spec.ts +++ b/libs/components/src/menu/menu.component.spec.ts @@ -68,6 +68,8 @@ describe("Menu", () => { }); }); +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-app", template: ` diff --git a/libs/components/src/menu/menu.component.ts b/libs/components/src/menu/menu.component.ts index 3cc4de9f90f..f32a790ef69 100644 --- a/libs/components/src/menu/menu.component.ts +++ b/libs/components/src/menu/menu.component.ts @@ -12,6 +12,8 @@ import { import { MenuItemDirective } from "./menu-item.directive"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-menu", templateUrl: "./menu.component.html", @@ -20,6 +22,8 @@ import { MenuItemDirective } from "./menu-item.directive"; }) export class MenuComponent implements AfterContentInit { readonly templateRef = viewChild.required(TemplateRef); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() closed = new EventEmitter(); readonly menuItems = contentChildren(MenuItemDirective, { descendants: true }); keyManager?: FocusKeyManager; diff --git a/libs/components/src/multi-select/multi-select.component.ts b/libs/components/src/multi-select/multi-select.component.ts index 917bb7a9e3d..4e755d1deda 100644 --- a/libs/components/src/multi-select/multi-select.component.ts +++ b/libs/components/src/multi-select/multi-select.component.ts @@ -34,6 +34,8 @@ import { SelectItemView } from "./models/select-item-view"; // Increments for each instance of this component let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-multi-select", templateUrl: "./multi-select.component.html", @@ -64,6 +66,8 @@ export class MultiSelectComponent implements OnInit, BitFormFieldControl, Contro readonly loading = input(false); // TODO: Skipped for signal migration because: // Your application code writes to the input. This prevents migration. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) disabled?: boolean; // Internal tracking of selected items @@ -79,6 +83,8 @@ export class MultiSelectComponent implements OnInit, BitFormFieldControl, Contro /**Implemented as part of NG_VALUE_ACCESSOR */ private notifyOnTouched?: () => void; + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() onItemsConfirmed = new EventEmitter(); constructor( @@ -208,6 +214,8 @@ export class MultiSelectComponent implements OnInit, BitFormFieldControl, Contro // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. @HostBinding("attr.required") + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() get required() { return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false; diff --git a/libs/components/src/navigation/nav-base.component.ts b/libs/components/src/navigation/nav-base.component.ts index 1ca40545cbb..9092ac4447c 100644 --- a/libs/components/src/navigation/nav-base.component.ts +++ b/libs/components/src/navigation/nav-base.component.ts @@ -61,5 +61,7 @@ export abstract class NavBaseComponent { /** * Fires when main content is clicked */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() mainContentClicked: EventEmitter = new EventEmitter(); } diff --git a/libs/components/src/navigation/nav-divider.component.ts b/libs/components/src/navigation/nav-divider.component.ts index 52fb433c54d..2f33883fd58 100644 --- a/libs/components/src/navigation/nav-divider.component.ts +++ b/libs/components/src/navigation/nav-divider.component.ts @@ -3,6 +3,8 @@ import { Component } from "@angular/core"; import { SideNavService } from "./side-nav.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-nav-divider", templateUrl: "./nav-divider.component.html", diff --git a/libs/components/src/navigation/nav-group.component.ts b/libs/components/src/navigation/nav-group.component.ts index 1fa03ef52be..e3bb02bb75a 100644 --- a/libs/components/src/navigation/nav-group.component.ts +++ b/libs/components/src/navigation/nav-group.component.ts @@ -19,6 +19,8 @@ import { NavBaseComponent } from "./nav-base.component"; import { NavGroupAbstraction, NavItemComponent } from "./nav-item.component"; import { SideNavService } from "./side-nav.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-nav-group", templateUrl: "./nav-group.component.html", @@ -51,6 +53,8 @@ export class NavGroupComponent extends NavBaseComponent { */ readonly hideIfEmpty = input(false, { transform: booleanAttribute }); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() openChange = new EventEmitter(); diff --git a/libs/components/src/navigation/nav-group.stories.ts b/libs/components/src/navigation/nav-group.stories.ts index 8bfd8007ac0..29ad169bba9 100644 --- a/libs/components/src/navigation/nav-group.stories.ts +++ b/libs/components/src/navigation/nav-group.stories.ts @@ -12,6 +12,8 @@ import { I18nMockService } from "../utils/i18n-mock.service"; import { NavGroupComponent } from "./nav-group.component"; import { NavigationModule } from "./navigation.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: "", }) diff --git a/libs/components/src/navigation/nav-item.component.ts b/libs/components/src/navigation/nav-item.component.ts index 8d57a752702..5b5709ebebb 100644 --- a/libs/components/src/navigation/nav-item.component.ts +++ b/libs/components/src/navigation/nav-item.component.ts @@ -13,6 +13,8 @@ export abstract class NavGroupAbstraction { abstract setOpen(open: boolean): void; } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-nav-item", templateUrl: "./nav-item.component.html", diff --git a/libs/components/src/navigation/nav-logo.component.ts b/libs/components/src/navigation/nav-logo.component.ts index 96258740d74..0602e8b753c 100644 --- a/libs/components/src/navigation/nav-logo.component.ts +++ b/libs/components/src/navigation/nav-logo.component.ts @@ -8,6 +8,8 @@ import { BitIconComponent } from "../icon/icon.component"; import { SideNavService } from "./side-nav.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-nav-logo", templateUrl: "./nav-logo.component.html", diff --git a/libs/components/src/navigation/side-nav.component.ts b/libs/components/src/navigation/side-nav.component.ts index fe428c7011f..b373a89d47e 100644 --- a/libs/components/src/navigation/side-nav.component.ts +++ b/libs/components/src/navigation/side-nav.component.ts @@ -11,6 +11,8 @@ import { SideNavService } from "./side-nav.service"; export type SideNavVariant = "primary" | "secondary"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-side-nav", templateUrl: "side-nav.component.html", diff --git a/libs/components/src/no-items/no-items.component.ts b/libs/components/src/no-items/no-items.component.ts index 517abfc9533..c6e52a1f83d 100644 --- a/libs/components/src/no-items/no-items.component.ts +++ b/libs/components/src/no-items/no-items.component.ts @@ -7,6 +7,8 @@ import { BitIconComponent } from "../icon/icon.component"; /** * Component for displaying a message when there are no items to display. Expects title, description and button slots. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-no-items", templateUrl: "./no-items.component.html", diff --git a/libs/components/src/popover/popover.component.ts b/libs/components/src/popover/popover.component.ts index 78bc2abe369..024a293ada3 100644 --- a/libs/components/src/popover/popover.component.ts +++ b/libs/components/src/popover/popover.component.ts @@ -5,6 +5,8 @@ import { IconButtonModule } from "../icon-button/icon-button.module"; import { SharedModule } from "../shared/shared.module"; import { TypographyModule } from "../typography"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-popover", imports: [A11yModule, IconButtonModule, SharedModule, TypographyModule], @@ -14,5 +16,7 @@ import { TypographyModule } from "../typography"; export class PopoverComponent { readonly templateRef = viewChild.required(TemplateRef); readonly title = input(""); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() closed = new EventEmitter(); } diff --git a/libs/components/src/progress/progress.component.ts b/libs/components/src/progress/progress.component.ts index cd1d55ac9eb..c04b7c90609 100644 --- a/libs/components/src/progress/progress.component.ts +++ b/libs/components/src/progress/progress.component.ts @@ -20,6 +20,8 @@ const BackgroundClasses: Record = { /** * Progress indicators may be used to visually indicate progress or to visually measure some other value, such as a password strength indicator. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-progress", templateUrl: "./progress.component.html", diff --git a/libs/components/src/radio-button/radio-button.component.spec.ts b/libs/components/src/radio-button/radio-button.component.spec.ts index b47c1823160..3ce5ebae65e 100644 --- a/libs/components/src/radio-button/radio-button.component.spec.ts +++ b/libs/components/src/radio-button/radio-button.component.spec.ts @@ -53,6 +53,8 @@ describe("RadioButton", () => { }); }); +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-component", template: ` diff --git a/libs/components/src/radio-button/radio-button.component.ts b/libs/components/src/radio-button/radio-button.component.ts index 84ed240b3f8..a004e7e07e2 100644 --- a/libs/components/src/radio-button/radio-button.component.ts +++ b/libs/components/src/radio-button/radio-button.component.ts @@ -7,6 +7,8 @@ import { RadioInputComponent } from "./radio-input.component"; let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-radio-button", templateUrl: "radio-button.component.html", diff --git a/libs/components/src/radio-button/radio-group.component.spec.ts b/libs/components/src/radio-button/radio-group.component.spec.ts index ff01b9323f7..94cc7bc25cb 100644 --- a/libs/components/src/radio-button/radio-group.component.spec.ts +++ b/libs/components/src/radio-button/radio-group.component.spec.ts @@ -63,6 +63,8 @@ describe("RadioGroupComponent", () => { }); }); +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-app", template: ` diff --git a/libs/components/src/radio-button/radio-group.component.ts b/libs/components/src/radio-button/radio-group.component.ts index baa2cd58d80..dd44623b313 100644 --- a/libs/components/src/radio-button/radio-group.component.ts +++ b/libs/components/src/radio-button/radio-group.component.ts @@ -8,6 +8,8 @@ import { BitLabel } from "../form-control/label.component"; let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-radio-group", templateUrl: "radio-group.component.html", diff --git a/libs/components/src/radio-button/radio-input.component.ts b/libs/components/src/radio-button/radio-input.component.ts index e32dc5c572d..47bb799d88e 100644 --- a/libs/components/src/radio-button/radio-input.component.ts +++ b/libs/components/src/radio-button/radio-input.component.ts @@ -5,6 +5,8 @@ import { BitFormControlAbstraction } from "../form-control"; let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "input[type=radio][bitRadio]", template: "", diff --git a/libs/components/src/resize-observer/resize-observer.directive.ts b/libs/components/src/resize-observer/resize-observer.directive.ts index 5943636f450..68b859c3191 100644 --- a/libs/components/src/resize-observer/resize-observer.directive.ts +++ b/libs/components/src/resize-observer/resize-observer.directive.ts @@ -13,6 +13,8 @@ export class ResizeObserverDirective implements OnDestroy { } }); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() resize = new EventEmitter(); diff --git a/libs/components/src/search/search.component.ts b/libs/components/src/search/search.component.ts index 65568b241fb..576031d50a7 100644 --- a/libs/components/src/search/search.component.ts +++ b/libs/components/src/search/search.component.ts @@ -18,6 +18,8 @@ let nextId = 0; /** * Do not nest Search components inside another `
`, as they already contain their own standalone `` element for searching. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-search", templateUrl: "./search.component.html", @@ -45,10 +47,12 @@ export class SearchComponent implements ControlValueAccessor, FocusableElement { // Use `type="text"` for Safari to improve rendering performance protected inputType = isBrowserSafariApi() ? ("text" as const) : ("search" as const); - protected isInputFocused = signal(false); - protected isFormHovered = signal(false); + protected readonly isInputFocused = signal(false); + protected readonly isFormHovered = signal(false); - protected showResetButton = computed(() => this.isInputFocused() || this.isFormHovered()); + protected readonly showResetButton = computed( + () => this.isInputFocused() || this.isFormHovered(), + ); readonly disabled = model(); readonly placeholder = input(); diff --git a/libs/components/src/section/section-header.component.ts b/libs/components/src/section/section-header.component.ts index c96f9486b52..27577590f41 100644 --- a/libs/components/src/section/section-header.component.ts +++ b/libs/components/src/section/section-header.component.ts @@ -2,6 +2,8 @@ import { Component } from "@angular/core"; import { TypographyModule } from "../typography"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-section-header", templateUrl: "./section-header.component.html", diff --git a/libs/components/src/section/section.component.ts b/libs/components/src/section/section.component.ts index f65c492a0c1..1ad80610637 100644 --- a/libs/components/src/section/section.component.ts +++ b/libs/components/src/section/section.component.ts @@ -2,6 +2,8 @@ import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { CommonModule } from "@angular/common"; import { Component, input } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-section", imports: [CommonModule], diff --git a/libs/components/src/select/option.component.ts b/libs/components/src/select/option.component.ts index ae75fe6514d..b981d0e0bdc 100644 --- a/libs/components/src/select/option.component.ts +++ b/libs/components/src/select/option.component.ts @@ -2,6 +2,8 @@ import { Component, booleanAttribute, input } from "@angular/core"; import { MappedOptionComponent } from "./option"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-option", template: ``, diff --git a/libs/components/src/select/select.component.spec.ts b/libs/components/src/select/select.component.spec.ts index cfc69636224..21ae50611a7 100644 --- a/libs/components/src/select/select.component.spec.ts +++ b/libs/components/src/select/select.component.spec.ts @@ -9,6 +9,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { SelectComponent } from "./select.component"; import { SelectModule } from "./select.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ imports: [SelectModule, ReactiveFormsModule], template: ` diff --git a/libs/components/src/select/select.component.ts b/libs/components/src/select/select.component.ts index 90b39e9c13a..f6358ccf6c6 100644 --- a/libs/components/src/select/select.component.ts +++ b/libs/components/src/select/select.component.ts @@ -34,6 +34,8 @@ import { OptionComponent } from "./option.component"; let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-select", templateUrl: "select.component.html", @@ -50,10 +52,12 @@ export class SelectComponent implements BitFormFieldControl, ControlValueAcce readonly items = model[] | undefined>(); readonly placeholder = input(this.i18nService.t("selectPlaceholder")); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() closed = new EventEmitter(); - protected selectedValue = signal(undefined); - selectedOption: Signal | null | undefined> = computed(() => + protected readonly selectedValue = signal(undefined); + readonly selectedOption: Signal | null | undefined> = computed(() => this.findSelectedOption(this.items(), this.selectedValue()), ); protected searchInputId = `bit-select-search-input-${nextId++}`; @@ -70,6 +74,8 @@ export class SelectComponent implements BitFormFieldControl, ControlValueAcce } } + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ContentChildren(OptionComponent) protected set options(value: QueryList>) { if (value == null || value.length == 0) { @@ -94,6 +100,8 @@ export class SelectComponent implements BitFormFieldControl, ControlValueAcce } // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() get disabled() { return this._disabled ?? this.ngControl?.disabled ?? false; @@ -166,6 +174,8 @@ export class SelectComponent implements BitFormFieldControl, ControlValueAcce // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. @HostBinding("attr.required") + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() get required() { return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false; diff --git a/libs/components/src/skeleton/skeleton-group.component.ts b/libs/components/src/skeleton/skeleton-group.component.ts index 8895397ae89..c1d236eafb9 100644 --- a/libs/components/src/skeleton/skeleton-group.component.ts +++ b/libs/components/src/skeleton/skeleton-group.component.ts @@ -7,6 +7,8 @@ import { Component } from "@angular/core"; * Pass skeleton loaders into the start, default, and end content slots. The content within each slot * is fully customizable. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-skeleton-group", templateUrl: "./skeleton-group.component.html", diff --git a/libs/components/src/skeleton/skeleton-text.component.ts b/libs/components/src/skeleton/skeleton-text.component.ts index 1bc88bd3204..a3d2c4a8451 100644 --- a/libs/components/src/skeleton/skeleton-text.component.ts +++ b/libs/components/src/skeleton/skeleton-text.component.ts @@ -10,6 +10,8 @@ import { SkeletonComponent } from "./skeleton.component"; * Customize the number of lines represented with the `lines` input. Customize the width * by applying a class to the `bit-skeleton-text` element (i.e. `tw-w-1/2`). */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-skeleton-text", templateUrl: "./skeleton-text.component.html", @@ -27,5 +29,5 @@ export class SkeletonTextComponent { /** * Array-transformed version of the `lines` to loop over */ - protected linesArray = computed(() => [...Array(this.lines()).keys()]); + protected readonly linesArray = computed(() => [...Array(this.lines()).keys()]); } diff --git a/libs/components/src/skeleton/skeleton.component.ts b/libs/components/src/skeleton/skeleton.component.ts index a9d83dd80a5..56de186c2e4 100644 --- a/libs/components/src/skeleton/skeleton.component.ts +++ b/libs/components/src/skeleton/skeleton.component.ts @@ -10,6 +10,8 @@ import { Component, input } from "@angular/core"; * * If you're looking to represent lines of text, use the `bit-skeleton-text` helper component. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-skeleton", templateUrl: "./skeleton.component.html", diff --git a/libs/components/src/spinner/spinner.component.ts b/libs/components/src/spinner/spinner.component.ts index c18e95d70fa..d0c2b90a165 100644 --- a/libs/components/src/spinner/spinner.component.ts +++ b/libs/components/src/spinner/spinner.component.ts @@ -3,6 +3,8 @@ import { Component, HostBinding, Input, booleanAttribute } from "@angular/core"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-spinner", templateUrl: "spinner.component.html", @@ -13,21 +15,29 @@ export class SpinnerComponent { /** * The size of the spinner. Defaults to `large`. */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() size: "fill" | "small" | "large" = "large"; /** * Disable the default color of the spinner, inherits the text color. */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) noColor = false; /** * Accessibility title. Defaults to `Loading`. */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() title = this.i18nService.t("loading"); /** * Display text for screen readers. */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input({ transform: booleanAttribute }) sr = true; @HostBinding("class") get classList() { diff --git a/libs/components/src/stepper/step.component.ts b/libs/components/src/stepper/step.component.ts index 6d558964d89..2d42dcb23cb 100644 --- a/libs/components/src/stepper/step.component.ts +++ b/libs/components/src/stepper/step.component.ts @@ -1,6 +1,8 @@ import { CdkStep, CdkStepper } from "@angular/cdk/stepper"; import { Component, input } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-step", templateUrl: "step.component.html", @@ -8,7 +10,7 @@ import { Component, input } from "@angular/core"; standalone: true, }) export class StepComponent extends CdkStep { - subLabel = input(); + readonly subLabel = input(); constructor(stepper: CdkStepper) { super(stepper); diff --git a/libs/components/src/stepper/stepper.component.ts b/libs/components/src/stepper/stepper.component.ts index befd4b40cf3..abef0dc3f9a 100644 --- a/libs/components/src/stepper/stepper.component.ts +++ b/libs/components/src/stepper/stepper.component.ts @@ -12,6 +12,8 @@ import { StepComponent } from "./step.component"; * The `` component extends the * [Angular CdkStepper](https://material.angular.io/cdk/stepper/api#CdkStepper) component */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-stepper", templateUrl: "stepper.component.html", @@ -44,6 +46,8 @@ export class StepperComponent extends CdkStepper { // overriding CdkStepper orientation input so we can default to vertical // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() override get orientation() { return this.internalOrientation || "vertical"; diff --git a/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts b/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts index 7f6a6c42f32..60353a28fb6 100644 --- a/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts @@ -7,6 +7,8 @@ import { ScrollLayoutDirective } from "../../../layout"; import { SectionComponent } from "../../../section"; import { TableDataSource, TableModule } from "../../../table"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "dialog-virtual-scroll-block", standalone: true, diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts index eb9f2fccac9..8f49415e0dd 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts @@ -7,6 +7,8 @@ import { DialogService } from "../../../dialog"; import { I18nMockService } from "../../../utils/i18n-mock.service"; import { KitchenSinkSharedModule } from "../kitchen-sink-shared.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-kitchen-sink-form", imports: [KitchenSinkSharedModule], diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts index a96964db8d5..f96217ffb63 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts @@ -8,6 +8,8 @@ import { KitchenSinkForm } from "./kitchen-sink-form.component"; import { KitchenSinkTable } from "./kitchen-sink-table.component"; import { KitchenSinkToggleList } from "./kitchen-sink-toggle-list.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ imports: [KitchenSinkSharedModule], template: ` @@ -85,6 +87,8 @@ class KitchenSinkDialog { constructor(public dialogRef: DialogRef) {} } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-main", imports: [KitchenSinkSharedModule, KitchenSinkTable, KitchenSinkToggleList, KitchenSinkForm], @@ -175,7 +179,7 @@ class KitchenSinkDialog { export class KitchenSinkMainComponent { constructor(public dialogService: DialogService) {} - protected drawerOpen = signal(false); + protected readonly drawerOpen = signal(false); openDialog() { this.dialogService.open(KitchenSinkDialog); diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-table.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-table.component.ts index 302d9f6c0a8..d8d2e20f9ae 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-table.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-table.component.ts @@ -2,6 +2,8 @@ import { Component } from "@angular/core"; import { KitchenSinkSharedModule } from "../kitchen-sink-shared.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-kitchen-sink-table", imports: [KitchenSinkSharedModule], diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts index ec8787af1bd..18846ce2831 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts @@ -2,6 +2,8 @@ import { Component } from "@angular/core"; import { KitchenSinkSharedModule } from "../kitchen-sink-shared.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-kitchen-sink-toggle-list", imports: [KitchenSinkSharedModule], diff --git a/libs/components/src/switch/switch.component.spec.ts b/libs/components/src/switch/switch.component.spec.ts index 4d24dbcd150..241035501fa 100644 --- a/libs/components/src/switch/switch.component.spec.ts +++ b/libs/components/src/switch/switch.component.spec.ts @@ -13,6 +13,8 @@ describe("SwitchComponent", () => { let switchComponent: SwitchComponent; let inputEl: HTMLInputElement; + // TODO: Fix this the next time the file is edited. + // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-host", imports: [FormsModule, BitLabel, ReactiveFormsModule, SwitchModule], @@ -70,6 +72,8 @@ describe("SwitchComponent", () => { }); it("should update checked when selected input changes outside of a form", async () => { + // TODO: Fix this the next time the file is edited. + // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-selected-host", template: `Element`, diff --git a/libs/components/src/switch/switch.component.ts b/libs/components/src/switch/switch.component.ts index f08ed9f46ef..52b726ac353 100644 --- a/libs/components/src/switch/switch.component.ts +++ b/libs/components/src/switch/switch.component.ts @@ -21,6 +21,8 @@ let nextId = 0; /** * Switch component for toggling between two states. Switch actions are meant to take place immediately and are not to be used in a form where saving/submiting actions are required. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-switch", providers: [ @@ -46,19 +48,19 @@ export class SwitchComponent implements ControlValueAccessor, AfterViewInit { /** * Model signal for selected state binding when used outside of a form */ - protected selected = model(false); + protected readonly selected = model(false); /** * Model signal for disabled binding when used outside of a form */ - protected disabled = model(false); - protected disabledReasonText = input(null); + protected readonly disabled = model(false); + protected readonly disabledReasonText = input(null); - private hintComponent = contentChild(BitHintComponent); + private readonly hintComponent = contentChild(BitHintComponent); private disabledReasonTextId = `bit-switch-disabled-text-${nextId++}`; - private describedByIds = computed(() => { + private readonly describedByIds = computed(() => { const ids: string[] = []; if (this.disabledReasonText() && this.disabled()) { diff --git a/libs/components/src/table/sortable.component.ts b/libs/components/src/table/sortable.component.ts index 6d5f72dd379..b46c1ee9fbd 100644 --- a/libs/components/src/table/sortable.component.ts +++ b/libs/components/src/table/sortable.component.ts @@ -5,6 +5,8 @@ import { Component, HostBinding, OnInit, input } from "@angular/core"; import type { SortDirection, SortFn } from "./table-data-source"; import { TableComponent } from "./table.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "th[bitSortable]", template: ` diff --git a/libs/components/src/table/table-scroll.component.ts b/libs/components/src/table/table-scroll.component.ts index 2f9436baa0b..fcdd401a1a2 100644 --- a/libs/components/src/table/table-scroll.component.ts +++ b/libs/components/src/table/table-scroll.component.ts @@ -44,6 +44,8 @@ export class BitRowDef { * * Utilizes virtual scrolling to render large datasets. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-table-scroll", templateUrl: "./table-scroll.component.html", diff --git a/libs/components/src/table/table.component.ts b/libs/components/src/table/table.component.ts index 7fdd0c40e91..fff36472a14 100644 --- a/libs/components/src/table/table.component.ts +++ b/libs/components/src/table/table.component.ts @@ -21,6 +21,8 @@ export class TableBodyDirective { constructor(public readonly template: TemplateRef) {} } +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-table", templateUrl: "./table.component.html", diff --git a/libs/components/src/tabs/shared/tab-header.component.ts b/libs/components/src/tabs/shared/tab-header.component.ts index 9a35e5a846f..aa0272aa917 100644 --- a/libs/components/src/tabs/shared/tab-header.component.ts +++ b/libs/components/src/tabs/shared/tab-header.component.ts @@ -3,6 +3,8 @@ import { Component } from "@angular/core"; /** * Component used for styling the tab header/background for both content and navigation tabs */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-header", host: { diff --git a/libs/components/src/tabs/shared/tab-list-item.directive.ts b/libs/components/src/tabs/shared/tab-list-item.directive.ts index c8b96141ecd..bc70fdf6e4b 100644 --- a/libs/components/src/tabs/shared/tab-list-item.directive.ts +++ b/libs/components/src/tabs/shared/tab-list-item.directive.ts @@ -13,6 +13,8 @@ export class TabListItemDirective implements FocusableOption { // TODO: Skipped for signal migration because: // This input overrides a field from a superclass, while the superclass field // is not migrated. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() disabled = false; @HostBinding("attr.disabled") diff --git a/libs/components/src/tabs/tab-group/tab-body.component.ts b/libs/components/src/tabs/tab-group/tab-body.component.ts index 2dec4ca180d..7382c8576c3 100644 --- a/libs/components/src/tabs/tab-group/tab-body.component.ts +++ b/libs/components/src/tabs/tab-group/tab-body.component.ts @@ -1,6 +1,8 @@ import { TemplatePortal, CdkPortalOutlet } from "@angular/cdk/portal"; import { Component, effect, HostBinding, input } from "@angular/core"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-body", templateUrl: "tab-body.component.html", diff --git a/libs/components/src/tabs/tab-group/tab-group.component.ts b/libs/components/src/tabs/tab-group/tab-group.component.ts index aad60d876ec..cd9d876945c 100644 --- a/libs/components/src/tabs/tab-group/tab-group.component.ts +++ b/libs/components/src/tabs/tab-group/tab-group.component.ts @@ -27,6 +27,8 @@ import { TabComponent } from "./tab.component"; /** Used to generate unique ID's for each tab component */ let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-group", templateUrl: "./tab-group.component.html", @@ -57,14 +59,16 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit { readonly preserveContent = input(false); /** Error if no `TabComponent` is supplied. (`contentChildren`, used to query for all the tabs, doesn't support `required`) */ - private _tab = contentChild.required(TabComponent); + private readonly _tab = contentChild.required(TabComponent); - protected tabs = contentChildren(TabComponent); + protected readonly tabs = contentChildren(TabComponent); readonly tabLabels = viewChildren(TabListItemDirective); /** The index of the active tab. */ // TODO: Skipped for signal migration because: // Accessor inputs cannot be migrated as they are too complex. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() get selectedIndex(): number | null { return this._selectedIndex; @@ -75,9 +79,13 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit { private _selectedIndex: number | null = null; /** Output to enable support for two-way binding on `[(selectedIndex)]` */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() readonly selectedIndexChange: EventEmitter = new EventEmitter(); /** Event emitted when the tab selection has changed. */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() readonly selectedTabChange: EventEmitter = new EventEmitter(); diff --git a/libs/components/src/tabs/tab-group/tab.component.ts b/libs/components/src/tabs/tab-group/tab.component.ts index 2eb63cce29d..c021f1aff20 100644 --- a/libs/components/src/tabs/tab-group/tab.component.ts +++ b/libs/components/src/tabs/tab-group/tab.component.ts @@ -11,6 +11,8 @@ import { import { TabLabelDirective } from "./tab-label.directive"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab", templateUrl: "./tab.component.html", @@ -33,6 +35,8 @@ export class TabComponent implements OnInit { readonly contentTabIndex = input(); readonly implicitContent = viewChild.required(TemplateRef); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @ContentChild(TabLabelDirective) templateLabel?: TabLabelDirective; private _contentPortal: TemplatePortal | null = null; diff --git a/libs/components/src/tabs/tab-nav-bar/tab-link.component.ts b/libs/components/src/tabs/tab-nav-bar/tab-link.component.ts index 402c05bfef7..e94118f5f4b 100644 --- a/libs/components/src/tabs/tab-nav-bar/tab-link.component.ts +++ b/libs/components/src/tabs/tab-nav-bar/tab-link.component.ts @@ -16,6 +16,8 @@ import { TabListItemDirective } from "../shared/tab-list-item.directive"; import { TabNavBarComponent } from "./tab-nav-bar.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-link", templateUrl: "tab-link.component.html", @@ -38,6 +40,8 @@ export class TabLinkComponent implements FocusableOption, AfterViewInit { // TODO: Skipped for signal migration because: // This input overrides a field from a superclass, while the superclass field // is not migrated. + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() disabled = false; @HostListener("keydown", ["$event"]) onKeyDown(event: KeyboardEvent) { diff --git a/libs/components/src/tabs/tab-nav-bar/tab-nav-bar.component.ts b/libs/components/src/tabs/tab-nav-bar/tab-nav-bar.component.ts index 26082b1f17e..c7eec302125 100644 --- a/libs/components/src/tabs/tab-nav-bar/tab-nav-bar.component.ts +++ b/libs/components/src/tabs/tab-nav-bar/tab-nav-bar.component.ts @@ -6,6 +6,8 @@ import { TabListContainerDirective } from "../shared/tab-list-container.directiv import { TabLinkComponent } from "./tab-link.component"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-nav-bar", templateUrl: "tab-nav-bar.component.html", diff --git a/libs/components/src/tabs/tabs.stories.ts b/libs/components/src/tabs/tabs.stories.ts index 1f3f5e353b9..e822e4c72eb 100644 --- a/libs/components/src/tabs/tabs.stories.ts +++ b/libs/components/src/tabs/tabs.stories.ts @@ -12,30 +12,40 @@ import { I18nMockService } from "../utils"; import { TabGroupComponent } from "./tab-group/tab-group.component"; import { TabsModule } from "./tabs.module"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-active-dummy", template: "Router - Active selected", }) class ActiveDummyComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-item-2-dummy", template: "Router - Item 2 selected", }) class ItemTwoDummyComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-item-3-dummy", template: "Router - Item 3 selected", }) class ItemThreeDummyComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-disabled-dummy", template: "Router - Disabled selected", }) class DisabledDummyComponent {} +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tab-item-with-child-counter-dummy", template: "Router - Item With Child Counter selected", diff --git a/libs/components/src/toast/toast-container.component.ts b/libs/components/src/toast/toast-container.component.ts index 128cf82d355..e455428db9f 100644 --- a/libs/components/src/toast/toast-container.component.ts +++ b/libs/components/src/toast/toast-container.component.ts @@ -1,6 +1,8 @@ import { Component, OnInit, viewChild } from "@angular/core"; import { ToastContainerDirective, ToastrService } from "ngx-toastr"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-toast-container", templateUrl: "toast-container.component.html", diff --git a/libs/components/src/toast/toast.component.ts b/libs/components/src/toast/toast.component.ts index 1aeca24d0e2..2bc0feebb72 100644 --- a/libs/components/src/toast/toast.component.ts +++ b/libs/components/src/toast/toast.component.ts @@ -25,6 +25,8 @@ const variants: Record = { }, }; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-toast", templateUrl: "toast.component.html", @@ -49,6 +51,8 @@ export class ToastComponent { readonly progressWidth = input(0); /** Emits when the user presses the close button */ + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() onClose = new EventEmitter(); protected get iconClass(): string { diff --git a/libs/components/src/toast/toast.stories.ts b/libs/components/src/toast/toast.stories.ts index 89c8bffad5c..f7eeadce971 100644 --- a/libs/components/src/toast/toast.stories.ts +++ b/libs/components/src/toast/toast.stories.ts @@ -17,12 +17,16 @@ import { ToastOptions, ToastService } from "./toast.service"; const toastServiceExampleTemplate = ` `; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "toast-service-example", template: toastServiceExampleTemplate, imports: [ButtonModule], }) export class ToastServiceExampleComponent { + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-signals @Input() toastOptions?: ToastOptions; diff --git a/libs/components/src/toast/toastr.component.ts b/libs/components/src/toast/toastr.component.ts index 3b7665f1d64..5f96cb9128d 100644 --- a/libs/components/src/toast/toastr.component.ts +++ b/libs/components/src/toast/toastr.component.ts @@ -7,6 +7,8 @@ import { ToastComponent } from "./toast.component"; /** * Toasts are ephemeral notifications. They most often communicate the result of a user action. Due to their ephemeral nature, long messages and critical alerts should not utilize toasts. */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ template: ` { }); }); +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-app", template: ` diff --git a/libs/components/src/toggle-group/toggle-group.component.ts b/libs/components/src/toggle-group/toggle-group.component.ts index 16c4063f9e2..bde8f0ea9b6 100644 --- a/libs/components/src/toggle-group/toggle-group.component.ts +++ b/libs/components/src/toggle-group/toggle-group.component.ts @@ -10,6 +10,8 @@ import { let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-toggle-group", templateUrl: "./toggle-group.component.html", @@ -20,6 +22,8 @@ export class ToggleGroupComponent { readonly fullWidth = input(undefined, { transform: booleanAttribute }); readonly selected = model(); + // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals + // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref @Output() selectedChange = new EventEmitter(); @HostBinding("attr.role") role = "radiogroup"; diff --git a/libs/components/src/toggle-group/toggle.component.spec.ts b/libs/components/src/toggle-group/toggle.component.spec.ts index 1eec7e54e38..d3bc2e0eeed 100644 --- a/libs/components/src/toggle-group/toggle.component.spec.ts +++ b/libs/components/src/toggle-group/toggle.component.spec.ts @@ -45,6 +45,8 @@ describe("Toggle", () => { }); }); +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "test-component", template: ` diff --git a/libs/components/src/toggle-group/toggle.component.ts b/libs/components/src/toggle-group/toggle.component.ts index 0301fe17979..62e886ca572 100644 --- a/libs/components/src/toggle-group/toggle.component.ts +++ b/libs/components/src/toggle-group/toggle.component.ts @@ -14,6 +14,8 @@ import { ToggleGroupComponent } from "./toggle-group.component"; let nextId = 0; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-toggle", templateUrl: "./toggle.component.html", @@ -31,8 +33,8 @@ export class ToggleComponent implements AfterContentChecked, AfterViewIn @HostBinding("tabIndex") tabIndex = "-1"; @HostBinding("class") classList = ["tw-group/toggle", "tw-flex", "tw-min-w-16"]; - protected bitBadgeContainerHasChidlren = signal(false); - protected labelTitle = signal(null); + protected readonly bitBadgeContainerHasChidlren = signal(false); + protected readonly labelTitle = signal(null); get name() { return this.groupComponent.name; diff --git a/libs/components/src/tooltip/tooltip.component.ts b/libs/components/src/tooltip/tooltip.component.ts index 6b240507311..34c67015004 100644 --- a/libs/components/src/tooltip/tooltip.component.ts +++ b/libs/components/src/tooltip/tooltip.component.ts @@ -22,6 +22,8 @@ export const TOOLTIP_DATA = new InjectionToken("TOOLTIP_DATA"); /** * tooltip component used internally by the tooltip.directive. Not meant to be used explicitly */ +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-tooltip", templateUrl: "./tooltip.component.html", diff --git a/libs/components/src/tooltip/tooltip.directive.ts b/libs/components/src/tooltip/tooltip.directive.ts index 153fecfe7bf..b2c1621d710 100644 --- a/libs/components/src/tooltip/tooltip.directive.ts +++ b/libs/components/src/tooltip/tooltip.directive.ts @@ -39,7 +39,7 @@ export class TooltipDirective implements OnInit { */ readonly tooltipPosition = input("above-center"); - private isVisible = signal(false); + private readonly isVisible = signal(false); private overlayRef: OverlayRef | undefined; private elementRef = inject(ElementRef); private overlay = inject(Overlay); diff --git a/libs/components/src/tooltip/tooltip.spec.ts b/libs/components/src/tooltip/tooltip.spec.ts index 57e05e4f65f..b6a49acbc77 100644 --- a/libs/components/src/tooltip/tooltip.spec.ts +++ b/libs/components/src/tooltip/tooltip.spec.ts @@ -12,6 +12,8 @@ import { Observable, Subject } from "rxjs"; import { TooltipDirective } from "./tooltip.directive"; +// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush +// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ standalone: true, imports: [TooltipDirective],