WEB-634 The dashboard menu should display the full credit traceability. - #3078
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. Note
|
| Cohort / File(s) | Summary |
|---|---|
Routing & Navigation src/app/loans/loans-routing.module.ts, src/app/loans/loans-view/loans-view.component.html |
Registered LoanAccountDashboardComponent at child route .../dashboard and added a Dashboard tab/link in the loans view navigation. |
Dashboard Component src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts, src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.html, src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.scss |
New standalone LoanAccountDashboardComponent (OnInit/AfterViewInit/OnDestroy). Reads resolved route data, computes loan metrics, renders a doughnut status chart and stacked payments chart via Chart.js, and includes loading/no-data states and responsive SCSS. |
Internationalization src/assets/translations/{en-US,cs-CS,de-DE,es-CL,es-MX,fr-FR,it-IT,ko-KO,lt-LT,lv-LV,ne-NE,pt-PT,sw-SW}.json |
Added dashboard-related translation keys across locales: "Loan Dashboard", "Repayment Progress", "Payment Schedule", "Dashboard", "Total Repaid", "Outstanding Balance", "Interest Charged", "Loading data", and "No repayment schedule available". |
Sequence Diagram
sequenceDiagram
participant Router as Angular Router
participant Resolver as LoanDetailsResolver
participant Component as LoanAccountDashboardComponent
participant ChartJS as Chart.js
Router->>Resolver: resolve loanDetailsData
Resolver-->>Router: loanDetailsData
Router->>Component: instantiate with resolved data
Component->>Component: ngOnInit -> set loanData & calculate metrics
Component->>ChartJS: createStatusChart() (doughnut)
ChartJS-->>Component: status chart rendered
Component->>ChartJS: createPaymentsChart() (stacked bar)
ChartJS-->>Component: payments chart rendered
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
- WEB-521 fix(i18n): add missing translations and apply translate pipes across web-app #2934 — Overlapping translation additions / normalization for dashboard-related UI keys.
Suggested reviewers
- IOhacker
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title references 'dashboard menu' and 'full credit traceability,' which aligns with the PR's implementation of a loan account dashboard with comprehensive metrics and visualizations. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 16
🤖 Fix all issues with AI agents
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.html`:
- Around line 64-82: The template loan-account-dashboard.component.html
references missing translation keys 'labels.text.Loading data' and
'labels.text.No repayment schedule available' (used near the Loading data div
and the repayment schedule no-data block that checks
loanData.repaymentSchedule.periods), so add these keys with appropriate
localized strings to every JSON/YAML in src/assets/translations/ (all 13 locale
files) using the same key names; ensure consistent phrasing across locales and
run the i18n/translation lint or app to verify the translations resolve in the
UI.
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts`:
- Around line 59-61: Remove the two console.log statements that print sensitive
loan data in loan-account-dashboard.component (the assignments to this.loanData
remain); specifically delete the lines logging 'Loan Data:' and 'Repayment
Schedule:' (references: this.loanData and this.loanData?.repaymentSchedule) or
replace them with a non-sensitive, environment-guarded debug log (e.g., use a
centralized logger or only log in dev builds) so no production console output
exposes loan details.
- Around line 96-98: In loan-account-dashboard.component (where
progressPercentage is computed from totalRepaid and totalExpected) ensure you
reset progressPercentage to 0 when totalExpected is 0 instead of leaving a stale
value; update the logic around totalExpected (the block currently computing
progressPercentage = (this.totalRepaid / this.totalExpected) * 100) to
explicitly set this.progressPercentage = 0 when this.totalExpected === 0 and
only compute the division otherwise.
- Around line 112-113: Clamp the computed repayment percentages to prevent
negative outstanding values: when calculating repaidPercentage in
LoanAccountDashboardComponent (using this.totalRepaid and this.totalExpected),
ensure repaidPercentage is clamped to the range [0,100] and then compute
outstandingPercentage as Math.max(0, 100 - repaidPercentage); update the
variables repaidPercentage and outstandingPercentage accordingly so overpayment
cannot produce a negative outstandingPercentage.
- Around line 118-121: Hard-coded chart labels in
loan-account-dashboard.component (e.g., the labels array
['Repaid','Outstanding'] and axis/dataset labels
'Period','Principal','Interest') must be replaced with translated strings using
the injected TranslateService; inject TranslateService in the component
constructor (if not already), replace literal strings with
this.translate.instant('your.translation.key') using the existing translation
keys (e.g., loan.repaid, loan.outstanding, loan.period, loan.principal,
loan.interest) when building chartOptions/datasets, and subscribe to
TranslateService.onLangChange to recompute/update the chart labels (call
chart.update() or rebuild the chart) so language switches reflect immediately.
In `@src/assets/translations/cs-CS.json`:
- Line 1803: The "Dashboard" translation entry currently uses "Přehled" which is
inconsistent with other Dashboard labels; update the value for the "Dashboard"
key in cs-CS.json to "Přístrojová deska" so it matches the rest of the file
(locate the JSON property "Dashboard" and replace its string value).
- Around line 948-950: Update the Czech translations to use consistent loan
terminology: change the value for the "Loan Dashboard" key from "Přehled půjček"
to a singular form "Přehled půjčky" and change the value for the "Payment
Schedule" key from "Platební kalendář" to the term used elsewhere "Splátkový
kalendář" so it matches the "Repayment Schedule" phrasing and the UI context for
a single loan account.
In `@src/assets/translations/de-DE.json`:
- Line 1805: The "Dashboard" entry in the German translations is inconsistent
with the rest of the locale; update the value for the "Dashboard" key in the
de-DE.json translations (the string keyed by "Dashboard") to "Armaturenbrett" so
the UI uses the same German term everywhere.
In `@src/assets/translations/es-CL.json`:
- Line 1805: The translation value for the "Dashboard" key in
src/assets/translations/es-CL.json is inconsistent (“Panel”); update the value
for the "Dashboard" key to "Tableros" so it matches other occurrences of the
Dashboard translation across the file and preserves consistent UI terminology.
In `@src/assets/translations/es-MX.json`:
- Line 1805: The translation entry for the key "Dashboard" in
src/assets/translations/es-MX.json is inconsistent with other namespaces; change
the value from "Panel" to "Tableros" so the "Dashboard" key uses the same
Spanish label across the app (locate the "Dashboard" JSON key and update its
value to "Tableros").
- Around line 948-950: The current es-MX translations use "préstamos" for "Loan
Dashboard" (Panel de préstamos) and similar keys, which is inconsistent with the
project's established "Crédito" terminology; update the translations for the
keys "Loan Dashboard", "Repayment Progress", and "Payment Schedule" to use
"Crédito" (e.g., "Panel de Crédito", adjust "Repayment Progress" and "Payment
Schedule" to include "Crédito" as appropriate) and ensure the capitalization of
"Crédito" matches existing translations throughout the file.
In `@src/assets/translations/it-IT.json`:
- Line 1804: The Italian translation entry for the JSON key "Dashboard"
currently uses the English string "Dashboard" and must be made consistent with
other entries by changing its value to "Pannello di controllo"; update the value
for the "Dashboard" key in src/assets/translations/it-IT.json so it reads
"Dashboard": "Pannello di controllo".
- Around line 948-950: The translation for the key "Payment Schedule" should be
aligned with existing repayment terminology; update the value for the "Payment
Schedule" key in src/assets/translations/it-IT.json from "Piano di pagamento" to
"Programma di rimborso" so it matches the other "Repayment Schedule"
translations and keeps UI terminology consistent.
In `@src/assets/translations/ko-KO.json`:
- Around line 949-951: The translation for the JSON key "Payment Schedule" uses
the unnatural term "지불 일정"; update the value for the key "Payment Schedule" to
the established loan-domain Korean term "상환 일정" to match other entries like
"Repayment Schedule" and maintain consistent terminology across the loan UI
(locate the "Payment Schedule" key in src/assets/translations/ko-KO.json and
replace its value).
In `@src/assets/translations/lt-LT.json`:
- Line 1803: The "Dashboard" translation entry currently uses "Suvestinė" (key
"Dashboard") which conflicts with other entries using "Prietaisų skydelis";
update this translation value to "Prietaisų skydelis" so all occurrences of the
"Dashboard" key use the same Lithuanian term.
- Around line 1307-1309: The Lithuanian translation for the "Interest Charged"
key uses a mismatched participle; update the value for the "Interest Charged"
key in the JSON (currently "Interest Charged") to use the correct plural
agreement with "palūkanos" (e.g., change the value to "Priskaičiuotos
palūkanos") so it grammatically matches the noun; leave the adjacent keys
("Total Repaid", "Outstanding Balance") unchanged.
🧹 Nitpick comments (4)
src/assets/translations/ko-KO.json (1)
1806-1806: Keep “Dashboard” translation consistent across the locale.
This key uses “대시보드”, while many existing “Dashboard” entries in this file are “계기반”. Mixed terminology will be visible in the UI. Please standardize to one term (ideally “대시보드”, which is the common UI term in Korean).✏️ Suggested update (if standardizing to “대시보드”)
- "Dashboard": "계기반", + "Dashboard": "대시보드",src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts (3)
39-44: Tighten types for chart instances and loan data.Using
anyhere weakens type safety and can hide API mismatches. Consider introducing interfaces for the loan payload and using Chart.js generics.As per coding guidelines: "For Angular code: verify component separation, trackBy on *ngFor, strict type safety, and clean observable patterns."♻️ Suggested typing
+interface LoanSummary { + totalRepayment?: number; + totalOutstanding?: number; + interestCharged?: number; + totalExpectedRepayment?: number; +} + +interface LoanPeriod { + period?: number; + principalDue?: number; + interestDue?: number; +} + +interface LoanDetailsData { + principal?: number; + summary?: LoanSummary; + repaymentSchedule?: { periods?: LoanPeriod[] }; +} + - private statusChart: any; - private paymentsChart: any; + private statusChart?: Chart<'doughnut', number[], string>; + private paymentsChart?: Chart<'bar', number[], string>; - loanData: any; + loanData?: LoanDetailsData;
57-68: PrefertakeUntilDestroyed(or equivalent) for the route data subscription.Keeps observable patterns clean and avoids potential leaks if the stream doesn’t complete as expected.
As per coding guidelines: "For Angular code: verify component separation, trackBy on *ngFor, strict type safety, and clean observable patterns."♻️ Suggested change
-import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, inject } from '@angular/core'; +import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, inject, DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; export class LoanAccountDashboardComponent implements OnInit, AfterViewInit { private route = inject(ActivatedRoute); + private destroyRef = inject(DestroyRef); ngOnInit(): void { this.loanId = this.route.parent?.snapshot.paramMap.get('loanId') || ''; - this.route.data.subscribe((data: { loanDetailsData: any }) => { + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanDetailsData: any }) => { if (data.loanDetailsData) { this.loanData = data.loanDetailsData; ... } - }); + }); }
54-76: Avoid setTimeout-driven chart init; gate on view + data readiness.The fixed 100 ms delay is brittle. A small readiness helper is more deterministic and removes timing race conditions.
♻️ Suggested pattern
+ private viewReady = false; + + private tryInitCharts(): void { + if (!this.viewReady || !this.loanData) return; + this.createStatusChart(); + this.createPaymentsChart(); + } ngOnInit(): void { ... this.route.data.subscribe((data: { loanDetailsData: any }) => { if (data.loanDetailsData) { this.loanData = data.loanDetailsData; this.calculateMetrics(); - setTimeout(() => { - this.createStatusChart(); - this.createPaymentsChart(); - }, 100); + this.tryInitCharts(); } }); } ngAfterViewInit(): void { - setTimeout(() => { - this.createStatusChart(); - this.createPaymentsChart(); - }, 100); + this.viewReady = true; + this.tryInitCharts(); }
|
@JaySoni1 there are comments about missing translation keys |
|
Ok @IOhacker I will update the PR |
d8a8623 to
40beab0
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts`:
- Around line 23-34: The component decorator for LoanAccountDashboardComponent
is missing the standalone flag required when using the imports array; update the
`@Component` decorator (selector: 'mifosx-loan-account-dashboard', templateUrl
'./loan-account-dashboard.component.html', etc.) to include standalone: true so
the imports (e.g., STANDALONE_SHARED_IMPORTS, MatCard, MatCardHeader,
MatCardContent, MatCardTitle) are valid and the component compiles.
In `@src/assets/translations/cs-CS.json`:
- Around line 2839-2840: Move the two translation keys "Loading data" and "No
repayment schedule available" out of the top-level labels object and nest them
under labels.text (creating the text object if it doesn't exist) so that the
template lookups for labels.text.Loading data and labels.text.No repayment
schedule available resolve correctly; update the labels object to include a
"text" child and place those two keys there.
🧹 Nitpick comments (3)
src/assets/translations/fr-FR.json (1)
949-951: Align “Payment Schedule” terminology with existing “Repayment Schedule.”Line 951 uses “Calendrier de paiement,” but the app already uses “Calendrier de remboursement” for repayment schedules. Keeping a single term avoids UX inconsistencies.
🔧 Proposed wording tweak
- "Payment Schedule": "Calendrier de paiement", + "Payment Schedule": "Calendrier de remboursement",src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts (2)
43-57: Tighten types for loan data and chart instances.The
anyusage weakens type safety. Consider using the existing loan details interface and typed Chart instances.As per coding guidelines: `src/app/**: For Angular code: verify component separation, trackBy on *ngFor, strict type safety, and clean observable patterns.`🔧 Example typing
- private statusChart: any; - private paymentsChart: any; + private statusChart?: Chart<'doughnut', number[], string>; + private paymentsChart?: Chart<'bar', number[], string>; ... - loanData: any; + loanData: LoanDetails | null = null;
58-79: PrefertakeUntilDestroyed(or similar) over manual subscriptions.
route.dataisn’t disposed, and the lang-change subscription could be simplified. UsingtakeUntilDestroyedavoids leaks and keeps observable patterns consistent.As per coding guidelines: `src/app/**: For Angular code: verify component separation, trackBy on *ngFor, strict type safety, and clean observable patterns.`♻️ Suggested pattern
-import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, inject, OnDestroy } from '@angular/core'; +import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, inject, OnDestroy, DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; ... + private destroyRef = inject(DestroyRef); ... - this.route.data.subscribe((data: { loanDetailsData: any }) => { + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanDetailsData: any }) => { ... - this.langChangeSubscription = this.translate.onLangChange.subscribe(() => { + this.translate.onLangChange + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => { ...
40beab0 to
e7557a1
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts`:
- Around line 62-71: The route.data.subscribe call in
loan-account-dashboard.component (the block that sets this.loanData, calls
calculateMetrics(), and later createStatusChart/createPaymentsChart) is never
unsubscribed; capture its Subscription (e.g., routeDataSubscription) or use an
existing destroy$ pattern (takeUntil) and ensure it is cleaned up in ngOnDestroy
alongside langChangeSubscription — add a private routeDataSubscription:
Subscription (or pipe takeUntil(this.destroy$)) when subscribing and call
routeDataSubscription.unsubscribe() (or complete destroy$) in ngOnDestroy so the
observable does not leak after component destruction.
In `@src/assets/translations/fr-FR.json`:
- Around line 949-951: Change the plural "Tableau de bord des prêts" for the
"Loan Dashboard" key to the singular "Tableau de bord du prêt"; update the
"Payment Schedule" key to use the same French phrasing used for the existing
"Repayment Schedule" translation (so both payment/schedule keys are consistent);
verify "Repayment Progress" ("Progrès de remboursement") remains consistent with
the other repayment wording.
In `@src/assets/translations/lv-LV.json`:
- Line 1805: The "Dashboard" translation value is inconsistent with the rest of
the locale; update the JSON entry for the "Dashboard" key to use the full phrase
"Mērinstrumentu panelis" instead of "Panelis" so UI text is consistent across
the locale (locate the "Dashboard" key in the translations file and replace its
value).
🧹 Nitpick comments (2)
src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts (2)
83-88: Consider removing duplicate chart creation logic.Both
ngOnInit(when route data arrives) andngAfterViewInitschedule chart creation withsetTimeout. When data is available synchronously, this results in redundant chart creation—though thedestroy()calls before creation mitigate visual issues.Since the route data subscription already handles chart creation when data is available, the
ngAfterViewInitlogic may only be necessary as a fallback. Consider consolidating to a single chart initialization point.♻️ Suggested simplification
ngAfterViewInit(): void { - setTimeout(() => { - this.createStatusChart(); - this.createPaymentsChart(); - }, 100); + // Charts are created in route.data subscription when data is available + // Only create here if data was loaded before view init (edge case) + if (this.loanData && !this.statusChart) { + setTimeout(() => { + this.createStatusChart(); + this.createPaymentsChart(); + }, 100); + } }
44-48: Consider adding type definitions for better type safety.The component uses
anyforstatusChart,paymentsChart,loanData, and callback parameters. Adding proper types would improve maintainability and enable better IDE support.♻️ Type improvement suggestions
+import { Chart, ChartConfiguration, registerables } from 'chart.js'; - private statusChart: any; - private paymentsChart: any; + private statusChart: Chart<'doughnut'> | null = null; + private paymentsChart: Chart<'bar'> | null = null; - /** Loan data */ - loanData: any; + /** Loan data */ + loanData: LoanDetailsData | null = null; +interface LoanDetailsData { + principal?: number; + summary?: { + totalRepayment?: number; + totalOutstanding?: number; + interestCharged?: number; + totalExpectedRepayment?: number; + }; + repaymentSchedule?: { + periods?: Array<{ + period?: number; + principalDue?: number; + interestDue?: number; + }>; + }; +}
29cb067 to
b86eab4
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.html`:
- Around line 79-81: The "no repayment schedule" check uses
!loanData?.repaymentSchedule?.periods and fires while loanData is still
undefined; update the template logic in loan-account-dashboard.component.html so
you first guard with the existing loading check for !loanData (same pattern used
at line 63) and only evaluate repaymentSchedule.periods once loanData is defined
(e.g., change the condition around the block rendering the "No repayment
schedule available" message to ensure loanData is present before checking
loanData.repaymentSchedule.periods or its length).
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts`:
- Around line 91-105: In calculateMetrics() ensure progressPercentage is clamped
to the 0–100 range to prevent the progress bar from exceeding its container:
after computing progressPercentage in loan-account-dashboard.component.ts
(inside the calculateMetrics method that sets this.progressPercentage from
this.totalRepaid / this.totalExpected), replace the direct assignment with logic
that bounds the value using Math.min/Math.max (or equivalent) so
progressPercentage never goes below 0 or above 100.
In `@src/assets/translations/cs-CS.json`:
- Around line 3581-3780: The tooltips object is mistakenly nested under
auditTrail.auditTrail (making keys like auditTrail.auditTrail.tooltips.*
unreachable); move the entire "tooltips" block out of the auditTrail.auditTrail
structure so it sits at the same top-level location as in other locale files
(i.e., export/define "tooltips" alongside other top-level keys), ensuring
references to "tooltips" (and consumers expecting tooltips.*) resolve correctly.
- Around line 3509-3556: The file contains a nested auditTrail
(auditTrail.auditTrail) which makes auditTrail.entities unreachable; remove the
inner "auditTrail" wrapper so that "entities" becomes a direct sibling of
"actions" under the top-level auditTrail (i.e., keep auditTrail.actions and move
the ROLE/CODEVALUE/... block out of auditTrail.auditTrail.entities into
auditTrail.entities), ensuring there are no duplicate "auditTrail" keys and
translation keys like auditTrail.entities.ROLE resolve correctly.
- Around line 3557-3580: The keys titles, messages, languages,
not_found_subtitle, and tooltips are currently nested under the auditTrail
object; move each of these keys out of auditTrail to the JSON root so their
structure matches the reference (de-DE) file; locate the auditTrail object and
remove these subkeys from it, then add them as top-level properties named
exactly titles, messages, languages, not_found_subtitle, and tooltips with their
current values.
In `@src/assets/translations/de-DE.json`:
- Around line 949-951: The translation for the "Loan Dashboard" key uses
"Darlehens-Dashboard" and should be aligned with the locale’s existing
"Armaturenbrett" terminology; update the value for "Loan Dashboard" to a
consistent German phrase such as "Darlehens-Armaturenbrett" (or "Armaturenbrett
für Darlehen") so it matches other keys that use "Armaturenbrett".
In `@src/assets/translations/ko-KO.json`:
- Line 1808: The "Dashboard" translation entry currently uses "대시보드" which
conflicts with other "Dashboard" keys that use "계기반"; update the translation
value for the "Dashboard" key to "계기반" so terminology is consistent across the
locale file (locate the "Dashboard" JSON key and replace its value accordingly).
🧹 Nitpick comments (1)
src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts (1)
37-58: Prefer strong typing overanyfor loan data and charts.Using
anyweakens compile‑time checks and makes template bindings harder to validate.As per coding guidelines: "For Angular code: verify component separation, trackBy on *ngFor, strict type safety, and clean observable patterns."♻️ Suggested typing upgrade
- private statusChart: any; - private paymentsChart: any; + private statusChart?: Chart<'doughnut', number[], string>; + private paymentsChart?: Chart<'bar', number[], string>; - loanData: any; + loanData?: LoanAccountDetails; // replace with actual loan model type
b86eab4 to
65a8c17
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@src/app/loans/loans-routing.module.ts`:
- Line 40: Remove the redundant child resolver from the child route in
loans-routing.module.ts (the child route that currently also resolves
loanDetailsData) and update the child route to no longer declare that resolver;
then refactor LoanAccountDashboardComponent (in ngOnInit) to stop subscribing to
this.route.data and instead read the resolved payload from
this.route.parent.data (e.g., subscribe to this.route.parent!.data and extract
loanDetailsData) so the component reuses the parent :loanId resolver and avoids
duplicate API calls.
In
`@src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts`:
- Around line 67-70: The setTimeout call that invokes this.createStatusChart()
and this.createPaymentsChart() can fire after the component is destroyed; store
the timeout id (e.g., this.initTimeout) when calling setTimeout and replace the
anonymous setTimeout with this.initTimeout = window.setTimeout(...), then
implement/extend ngOnDestroy to call clearTimeout(this.initTimeout) (and null
out the property) so the callback cannot run post-destruction; keep using the
existing early-return guards inside createStatusChart and createPaymentsChart.
In `@src/assets/translations/de-DE.json`:
- Around line 949-951: Replace the inconsistent German translation for the key
"Payment Schedule" (currently "Zahlungsplan") with the same term used elsewhere
("Rückzahlungsplan") to match "Repayment Schedule" terminology; update the value
for the "Payment Schedule" entry in src/assets/translations/de-DE.json so both
keys use "Rückzahlungsplan" ensuring consistent user-facing wording across the
app.
In `@src/assets/translations/es-CL.json`:
- Around line 2828-2829: The empty-state translation for the key "No repayment
schedule available" uses "calendario" but should match the label "Payment
Schedule" which uses "Cronograma de pagos"; update the translation value for "No
repayment schedule available" to "No hay cronograma de pagos disponible" so the
terminology is consistent with the "Payment Schedule" label.
🧹 Nitpick comments (3)
src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts (3)
28-34: Consider removing redundantMatCardandMatCardContentimports.
STANDALONE_SHARED_IMPORTSalready includesMatCardandMatCardContent. OnlyMatCardHeaderandMatCardTitleneed to be explicitly imported here.♻️ Suggested fix
imports: [ ...STANDALONE_SHARED_IMPORTS, - MatCard, MatCardHeader, - MatCardContent, MatCardTitle ]
45-49: Improve type safety by replacinganytypes.Per Angular coding guidelines, strict type safety should be maintained. Consider typing the chart instances and loan data.
♻️ Suggested type improvements
- private statusChart: any; - private paymentsChart: any; + private statusChart: Chart<'doughnut'> | null = null; + private paymentsChart: Chart<'bar'> | null = null; /** Loan data */ - loanData: any; + loanData: LoanDetailsData | null = null;Additionally, define an interface (or import from existing types) for the loan data structure:
interface LoanDetailsData { principal?: number; summary?: { totalRepayment?: number; totalOutstanding?: number; interestCharged?: number; totalExpectedRepayment?: number; }; repaymentSchedule?: { periods?: Array<{ period?: number; principalDue?: number; interestDue?: number; }>; }; }As per coding guidelines: "For Angular code: verify [...] strict type safety".
84-89: Guard chart creation inngAfterViewInitto avoid redundant work.This creates charts unconditionally, but
ngOnInit's route data subscription also creates charts when data arrives. This can result in charts being created twice or showing empty data momentarily.♻️ Suggested fix
ngAfterViewInit(): void { - setTimeout(() => { - this.createStatusChart(); - this.createPaymentsChart(); - }, 100); + // Only create charts here if data is already available and charts don't exist + if (this.loanData && !this.statusChart) { + setTimeout(() => { + this.createStatusChart(); + this.createPaymentsChart(); + }, 100); + } }
65a8c17 to
ee7d49e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/assets/translations/ko-KO.json`:
- Line 949: Replace the inconsistent Korean translation for the "Loan Dashboard"
key: change the value currently set to "대출 대시보드" to use the project-standard
term "계기반" (i.e., "대출 계기반") so it matches other "Dashboard" entries; update the
"Loan Dashboard" JSON entry accordingly.
ee7d49e to
7ee4336
Compare
|
LGTM |
|
@IOhacker Thank you for the review |
Changes Made :-
-Implemented loan dashboard at individual loan account level with repayment progress visualization, payment schedule charts, and key metric cards displaying total repaid, outstanding balance, and interest charged amounts.
-Added dashboard translations across all 13 supported languages .
-Added "Dashboard" tab to loan account view with responsive design and modern UI components.
WEB-634
Summary by CodeRabbit
New Features
Style
Localization