Aman-Mittal opened a new issue, #184:
URL: https://github.com/apache/fineract-backoffice-ui/issues/184

   ## Summary
   
   Across the application, component state that is assigned from an HTTP 
callback is held in plain
   class fields and read directly by the component's template. 
`scripts/audit-async-state.mjs`
   counts **429 such fields across 184 components**. This issue tracks 
converting all of them to
   signals, along with the remaining decorator-based `@Input()` / `@Output()` 
declarations.
   
   ## Business value
   
   **This is a correctness problem, not a style preference.** Angular 22 makes 
`OnPush` the default
   change-detection strategy: a component that does not declare 
`changeDetection` *is* `OnPush`.
   Assigning a plain field from a `subscribe` callback changes the value the 
template reads without
   marking the view dirty, so the new value renders only if some unrelated 
interaction happens to
   trigger a check.
   
   The user-visible symptom is a screen that silently shows stale or empty data 
— an API-fed dropdown
   that renders zero options, a detail panel that stays blank after the record 
loads, a saved change
   that does not appear until the user clicks elsewhere. In a loan servicing 
back office these are
   not cosmetic: an officer who cannot see a product option or an outstanding 
balance cannot complete
   the operation, and there is no error message pointing at the cause.
   
   Concretely this delivers:
   
   - **Data that is on screen when it arrives**, on every screen, rather than 
on the ones that happen
     to get an extra change-detection pass.
   - **A working `NG0100` signal in CI.** The e2e fixture already watches for
     `ExpressionChangedAfterItHasBeenChecked`. While hundreds of fields 
legitimately produce that
     error, the check has to stay advisory. Once the count is zero it can be 
enforced, and the next
     regression of this kind fails a pull request instead of reaching a user.
   - **A pre-condition for `provideZonelessChangeDetection()`.** Zone.js 
currently provides a second,
     accidental trigger that masks these fields. Removing zone.js without 
converting them first would
     break every one of them at once, so this work has to land before that 
change can be considered.
   - **A clean lint gate.** `eslint-suppressions.json` exists to hold 
pre-existing violations of
     `@angular-eslint/prefer-signals`. Emptying it means new violations are 
caught on the pull request
     that introduces them, instead of being absorbed into a baseline.
   
   ## Scope
   
   - Convert all fields reported by `scripts/audit-async-state.mjs` to 
`signal()` / `computed()`.
   - Replace the remaining `@Input()` / `@Output()` declarations with 
`input()`, `output()` and
     `model()`, and the last `ngOnChanges` with an `effect()`.
   - Split `[(ngModel)]` bindings that now target a signal into `[ngModel]` + 
`(ngModelChange)`, since
     a signal cannot be a two-way binding target.
   - Reduce `eslint-suppressions.json` to empty.
   
   ### Modal components
   
   Dialogs are the blocker for the input conversion. Ionic delivers 
`componentProps` with
   `Object.assign` unless `useSetInputAPI` is enabled, which would overwrite 
the `InputSignal` on the
   instance with the raw value and leave the template calling a plain object. 
Enabling it lets the
   dialog family move to signal inputs; it requires every key passed through 
`DialogService.open` to
   be a declared input on the target component.
   
   ## Acceptance criteria
   
   - [ ] `node scripts/audit-async-state.mjs` reports 0 fields.
   - [ ] No `@Input()` / `@Output()` decorators or `ngOnChanges` 
implementations remain outside the
         generated API client.
   - [ ] `eslint-suppressions.json` is empty and `npm run lint` passes with 
nothing suppressed.
   - [ ] `npm run build` succeeds — it is the only check that type-checks 
templates, so it is what
         catches a signal read that is missing its call.
   - [ ] The unit suite and the mocked Playwright project both pass.
   
   ## Verification
   
   ```bash
   node scripts/audit-async-state.mjs        # expect: 0 plain fields across 0 
components
   npm run lint                              # expect: clean, with an empty 
suppressions file
   npm run build                             # type-checks every template
   npm run test -- --watch=false --browsers=ChromeHeadless 
--project=fineract-backoffice-ui
   npx playwright test --project=mocked
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to