feat(tasks): open a checker inbox entry in a popup instead of a page

Clicking a row navigated away to its own page, costing the checker the list and
whatever search they had set up. It now opens in a dialog over the list, the
same pattern the Disbursement and Closure Requests tabs already use.

ViewCheckerInboxComponent gained the optional MatDialogRef/MAT_DIALOG_DATA pair
rather than being duplicated, so the direct route still works for a bookmarked
link. Two differences follow from being a dialog:

 - the list rows carry only summary fields, so the detail (which is what has
   commandAsJson) is fetched here; by route it stays resolver-provided. The
   template reads checkerInboxDetail.* unguarded, so it is now behind an @if
   with a loading state -- otherwise a dialog would render against undefined.
 - commandAsJson is absent on some entries (a DELETE carries no payload) and
   JSON.parse(undefined) throws. By route that broke the page; in a dialog it
   would have left an empty shell open. Parsing is now guarded.

The list only reloads when something was actually actioned, since reload()
re-navigates the route and would otherwise discard the checker's search on a
plain close.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-01 18:30:24 +05:30
co-authored by Claude Opus 5
parent d9db217b91
commit e8097bc2cb
5 changed files with 251 additions and 113 deletions
@@ -33,6 +33,7 @@ import { SettingsService } from 'app/settings/settings.service';
/** Dialog Components */
import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component';
import { ViewCheckerInboxComponent } from '../../view-checker-inbox/view-checker-inbox.component';
import { Dates } from 'app/core/utils/dates';
import { TranslateService } from '@ngx-translate/core';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
@@ -288,6 +289,27 @@ export class CheckerInboxComponent implements OnInit {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
/**
* Opens one inbox entry in a popup rather than navigating to its own page, so the checker keeps
* the list (and any search/filter they set up) behind the dialog. The direct route stays available
* for a bookmarked link — ViewCheckerInboxComponent supports both entry points.
*/
viewEntry(row: any): void {
this.dialog
.open(ViewCheckerInboxComponent, {
data: { checkerId: row.id },
autoFocus: false
})
.afterClosed()
.subscribe((result: any) => {
// Only reload when something was actually actioned — a plain close must not throw away the
// checker's current search, which reload() does by re-navigating the route.
if (result?.refreshed) {
this.reload();
}
});
}
/**
* Refetches data for the component
* TODO: Replace by a custom reload component instead of hard-coded back-routing.