Skip to content

refactor(Application): Migrate shared and library UI components to Angular signals and OnPush change detection - #2360

Merged
hirokiterashima merged 10 commits into
developfrom
refactor-oct-2026
Oct 21, 2026
Merged

hirokiterashima merged 10 commits into
developfrom
refactor-oct-2026

Conversation

@hirokiterashima

Copy link
Copy Markdown
Member

Changes

Modernize several shared and library UI components to take advantage of Angular signals, signal-based queries/outputs, fine-grained reactivity, and OnPush change detection:

  • Migrated to Signal Inputs & Outputs: Replaced legacy @Input() and @Output() EventEmitter with input(), input.required(), output(), and booleanAttribute transforms for boolean inputs.
  • Adopted Signal Queries: Replaced @ContentChild and @ViewChild with contentChild() and viewChild().
  • Replaced Lifecycle Hooks with Signals & Effects: Replaced imperative ngOnInit and ngOnChanges state syncing with declarative computed() signals and effect() blocks, leveraging takeUntilDestroyed() for RxJS stream cleanup.
  • Enabled OnPush Change Detection: Added changeDetection: ChangeDetectionStrategy.OnPush across components for improved runtime performance.
  • Streamlined Imports & Template Control Flow: Replaced monolithic CommonModule imports with specific directives (NgClass, NgTemplateOutlet, RouterLink) and adopted modern built-in template control flow (@if / @else, @for).

Components Updated:

  1. SaveIndicatorComponent (src/app/modules/shared/save-indicator/): Migrated to signal inputs and OnPush.
  2. ProjectLanguageChooserComponent (src/app/modules/project/project-language-chooser/): Migrated inputs, selections, and locale mappings to signals and computed().
  3. ArchiveProjectsButtonComponent (src/app/modules/library/archive-projects-button/): Converted inputs and action outputs to input() / output().
  4. SelectAllItemsCheckboxComponent (src/app/modules/library/select-all-items-checkbox/): Replaced ngOnChanges calculation of selection status with computed(), and converted selection events to output().
  5. BlurbComponent (src/app/modules/shared/blurb/): Converted inputs and content projection templates to input() and contentChild().
  6. LibraryProjectDisciplinesComponent (src/app/modules/library/library-project-disciplines/): Converted disciplines and translations to signals and computed().
  7. CallToActionComponent (src/app/modules/shared/call-to-action/): Migrated 8 inputs and 2 template queries to signals, simplified template branching with @else, and added booleanAttribute coercion.
  8. SearchBarComponent (src/app/modules/shared/search-bar/): Converted inputs to signals, output to output({ alias: 'update' }), replaced ngOnChanges with reactive effect() syncing, and added takeUntilDestroyed().

Test

  • Ran and expanded unit test suites across all refactored components using fixture.componentRef.setInput(...) and fakeAsync / tick:
    • save-indicator.component.spec.ts: verified saving, saved, and error state indicators.
    • project-language-chooser.component.spec.ts: verified language selection emissions and label rendering.
    • archive-projects-button.component.spec.ts: verified button states and output emissions.
    • select-all-items-checkbox.component.spec.ts: verified indeterminate, checked, and unchecked states and click event outputs.
    • blurb.component.spec.ts: verified input bindings, image rendering, and projected template refs.
    • library-project-disciplines.component.spec.ts: verified discipline tags and localization.
    • call-to-action.component.spec.ts: verified internal routerLink, external links, SVG icons, and custom template projections.
    • search-bar.component.spec.ts: verified debounced search emission, input/disable synchronization via effects, and clear button behavior.

@qltysh

qltysh Bot commented Oct 21, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

Unable to calculate total coverage change because base branch coverage was not found.

Modified Files with Diff Coverage (8)

RatingFile% DiffUncovered Line #s
New file Coverage rating: A
...project-language-chooser/project-language-chooser.component.ts94.1%28
New file Coverage rating: A
...lect-all-items-checkbox/select-all-items-checkbox.component.ts100.0%
New file Coverage rating: A
src/app/modules/shared/call-to-action/call-to-action.component.ts100.0%
New file Coverage rating: A
src/app/modules/shared/blurb/blurb.component.ts100.0%
New file Coverage rating: A
...r/archive-projects-button/archive-projects-button.component.ts100.0%
New file Coverage rating: A
src/app/modules/shared/search-bar/search-bar.component.ts100.0%
New file Coverage rating: A
...y-project-disciplines/library-project-disciplines.component.ts100.0%
New file Coverage rating: A
...assets/wise5/common/save-indicator/save-indicator.component.ts100.0%
Total98.9%
🤖 Increase coverage with AI coding...
In the `refactor-oct-2026` branch, add test coverage for this new code:

- `src/app/common/project-language-chooser/project-language-chooser.component.ts` -- Line 28

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@hirokiterashima
hirokiterashima merged commit 887098d into develop Oct 21, 2026
4 checks passed
@hirokiterashima
hirokiterashima deleted the refactor-oct-2026 branch October 21, 2026 03:29
@hirokiterashima

Copy link
Copy Markdown
Member Author

🎉 This PR is included in version 5.249.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant