128 lines
4.5 KiB
HTML
128 lines
4.5 KiB
HTML
<!--
|
|
Copyright since 2025 Mifos Initiative
|
|
|
|
This Source Code Form is subject to the terms of the Mozilla Public
|
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
-->
|
|
|
|
<h2 mat-dialog-title class="rr-dialog-title">
|
|
<mat-icon>fact_check</mat-icon>
|
|
Review Repeat Activity — {{ data.row.clientDisplayName }}
|
|
</h2>
|
|
|
|
<mat-dialog-content class="rr-dialog-content">
|
|
<div class="rr-summary">
|
|
<div class="rr-summary-row">
|
|
<span class="rr-label">Customer</span>
|
|
<span class="rr-value">
|
|
{{ data.row.clientDisplayName }}
|
|
<span class="rr-muted"
|
|
>(ID {{ data.row.clientId }}{{ data.row.accountNo ? ' · ' + data.row.accountNo : '' }})</span
|
|
>
|
|
</span>
|
|
</div>
|
|
<div class="rr-summary-row">
|
|
<span class="rr-label">Alerts</span>
|
|
<span class="rr-value">
|
|
<strong>{{ data.row.alertCount }}</strong> in the last {{ data.windowDays }} days ·
|
|
{{ data.row.highRiskCount }} High risk · {{ data.row.distinctRules }} distinct rule(s)
|
|
</span>
|
|
</div>
|
|
<div class="rr-summary-row">
|
|
<span class="rr-label">Value</span>
|
|
<span class="rr-value rr-mono">{{ amount(data.row.totalAmount) }}</span>
|
|
</div>
|
|
<div class="rr-summary-row">
|
|
<span class="rr-label">Rules</span>
|
|
<span class="rr-value">{{ data.row.ruleCodes?.join(', ') || '—' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- The triggering transactions, so the decision is made against the evidence -->
|
|
<div class="rr-alerts">
|
|
<span class="rr-alerts-legend">Triggering transactions</span>
|
|
<div class="rr-alerts-scroll">
|
|
<table class="rr-alerts-tbl">
|
|
<thead>
|
|
<tr>
|
|
<th>Raised On</th>
|
|
<th>Transaction</th>
|
|
<th>Rule</th>
|
|
<th class="ta-r">Amount</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr *ngFor="let a of data.row.alerts">
|
|
<td>{{ a.raisedOnDate | date: 'dd MMM yyyy, HH:mm' }}</td>
|
|
<td>{{ a.transactionType }} #{{ a.transactionId }}</td>
|
|
<td>{{ a.ruleCode }}</td>
|
|
<td class="ta-r rr-mono">{{ amount(a.amount) }}</td>
|
|
<td>{{ a.status }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="data.row.lastReviewedOn" class="rr-prior">
|
|
<mat-icon>history</mat-icon>
|
|
<span>
|
|
Last reviewed by <strong>{{ data.row.lastReviewedByUsername }}</strong> on
|
|
{{ data.row.lastReviewedOnDate | date: 'dd MMM yyyy' }} at {{ data.row.alertCountAtLastReview }} alert(s) —
|
|
{{ data.row.lastReviewOutcome }}. {{ data.row.lastReviewNotes }}
|
|
</span>
|
|
</div>
|
|
|
|
<div *ngIf="errorMessage" class="rr-error">
|
|
<mat-icon>error_outline</mat-icon>
|
|
<span>{{ errorMessage }}</span>
|
|
</div>
|
|
|
|
<form [formGroup]="reviewForm" autocomplete="off">
|
|
<div class="rr-outcome">
|
|
<span class="rr-outcome-legend">Conclusion</span>
|
|
<mat-radio-group formControlName="outcome" class="rr-outcome-options">
|
|
<mat-radio-button *ngFor="let o of outcomes" [value]="o.value" class="rr-outcome-option">
|
|
{{ o.label }}
|
|
<span class="rr-muted">— {{ o.hint }}</span>
|
|
</mat-radio-button>
|
|
</mat-radio-group>
|
|
</div>
|
|
|
|
<mat-form-field appearance="outline" class="rr-notes-field">
|
|
<mat-label>Why does this customer keep surfacing?</mat-label>
|
|
<textarea
|
|
matInput
|
|
rows="4"
|
|
formControlName="notes"
|
|
placeholder="What the pattern is, what was checked, and what was decided"
|
|
></textarea>
|
|
<mat-error *ngIf="reviewForm.get('notes')?.hasError('required')">
|
|
Required — this is the audit record for the decision
|
|
</mat-error>
|
|
<mat-error *ngIf="reviewForm.get('notes')?.hasError('maxlength')">Keep this under 1000 characters</mat-error>
|
|
</mat-form-field>
|
|
|
|
<p class="rr-note">
|
|
Recorded against the current count of {{ data.row.alertCount }} alert(s). The customer returns to this queue if
|
|
the engine flags them again.
|
|
</p>
|
|
</form>
|
|
</mat-dialog-content>
|
|
|
|
<mat-dialog-actions align="end" class="rr-dialog-actions">
|
|
<button mat-stroked-button type="button" [disabled]="submitting" (click)="cancel()">Cancel</button>
|
|
<button
|
|
mat-flat-button
|
|
color="primary"
|
|
type="button"
|
|
[disabled]="reviewForm.invalid || submitting"
|
|
(click)="submit()"
|
|
>
|
|
<mat-spinner *ngIf="submitting" diameter="18" class="rr-spinner"></mat-spinner>
|
|
{{ submitting ? 'Saving…' : 'Record Review' }}
|
|
</button>
|
|
</mat-dialog-actions>
|