New CFCFRMS > I4C Live section backed by /v1/i4c/admin and /v1/i4c/cases (the demo mock interceptor does not match these paths): - Dashboard, complaints from I4C, holds register, approvals, responses and API log, bank code master, intimation settings. - Hold popup: overview, hold transactions, customer intimation (automatic and manual), maker request (full / partial release, freeze, unfreeze), GRM / MRM and documents, request history. - GRM grievances, MRM restorations and MRM balance report pages; shared date range filter (today, yesterday, week, month, custom), server-side paging and filters on every list; document upload / download. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
567 lines
24 KiB
HTML
567 lines
24 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/.
|
|
-->
|
|
|
|
<div class="i4c-page">
|
|
<!-- Modern Toolbar & Filter Chips -->
|
|
<div class="i4c-toolbar">
|
|
<div class="i4c-filter-chips">
|
|
<button class="filter-chip" [class.filter-chip--active]="status === ''" (click)="setStatus('')">
|
|
<span>All Complaints</span>
|
|
</button>
|
|
@for (s of statuses; track s) {
|
|
<button class="filter-chip" [class.filter-chip--active]="status === s" (click)="setStatus(s)">
|
|
<span>{{ s }}</span>
|
|
</button>
|
|
}
|
|
</div>
|
|
|
|
<span class="i4c-toolbar__spacer"></span>
|
|
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="search-input">
|
|
<mat-label>Search acknowledgement / account / job id</mat-label>
|
|
<input matInput [(ngModel)]="search" (keyup.enter)="load(true)" placeholder="Type & hit enter..." />
|
|
</mat-form-field>
|
|
|
|
<button mat-flat-button color="primary" class="search-btn" (click)="load(true)">
|
|
<fa-icon icon="search"></fa-icon> Search
|
|
</button>
|
|
|
|
<span class="count-tag">{{ total }} records</span>
|
|
</div>
|
|
|
|
<div class="i4c-filter-bar">
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<mat-label>Sub-category</mat-label>
|
|
<input matInput [(ngModel)]="subCategory" (keyup.enter)="load(true)" (blur)="load(true)" placeholder="e.g. UPI" />
|
|
</mat-form-field>
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<mat-label>Layer</mat-label>
|
|
<mat-select [(ngModel)]="layer" (selectionChange)="load(true)">
|
|
<mat-option value="">All layers</mat-option>
|
|
<mat-option value="0">Layer 0 (victim's account)</mat-option>
|
|
<mat-option value="1">Layer 1+ (money landed here)</mat-option>
|
|
</mat-select>
|
|
</mat-form-field>
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<mat-label>Response to I4C</mat-label>
|
|
<mat-select [(ngModel)]="response" (selectionChange)="load(true)">
|
|
<mat-option value="">Any</mat-option>
|
|
<mat-option value="SENT">Sent</mat-option>
|
|
<mat-option value="PENDING">Pending / sending</mat-option>
|
|
<mat-option value="FAILED">Failed</mat-option>
|
|
<mat-option value="NONE">Not yet created</mat-option>
|
|
</mat-select>
|
|
</mat-form-field>
|
|
<mifosx-i4c-date-range label="Received" [range]="dates" (rangeChange)="onDates($event)"></mifosx-i4c-date-range>
|
|
<button mat-stroked-button class="i4c-filter-bar__clear" (click)="clearFilters()" [disabled]="!hasFilters">
|
|
<fa-icon icon="times"></fa-icon> Clear filters
|
|
</button>
|
|
</div>
|
|
|
|
@if (loading) {
|
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
|
}
|
|
@if (error) {
|
|
<div class="i4c-error">
|
|
<fa-icon icon="exclamation-circle"></fa-icon>
|
|
<span>{{ error }}</span>
|
|
</div>
|
|
}
|
|
|
|
<!-- Complaints Data Table -->
|
|
<div class="i4c-card">
|
|
<div class="i4c-card__head">
|
|
<fa-icon icon="inbox"></fa-icon>
|
|
<span>I4C-MHA Cyber Fraud Complaints Log</span>
|
|
<span class="head-hint">Click any complaint to open modern detail popup window</span>
|
|
</div>
|
|
|
|
<div class="i4c-table-wrap">
|
|
<table class="i4c-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Received</th>
|
|
<th>Acknowledgement No.</th>
|
|
<th>Sub-Category</th>
|
|
<th>Target Account</th>
|
|
<th class="num">Layer</th>
|
|
<th class="num">Incidents</th>
|
|
<th class="num">Held (₹)</th>
|
|
<th>Status</th>
|
|
<th>I4C Response</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (row of rows; track row.id) {
|
|
<tr class="clickable" (click)="openModal(row)">
|
|
<td>
|
|
<span class="date-main">{{ row.received_at | date: 'dd MMM yyyy' }}</span>
|
|
<div class="sub">{{ row.received_at | date: 'HH:mm:ss' }}</div>
|
|
</td>
|
|
<td>
|
|
<div class="ack-cell">
|
|
<span class="ack-no">{{ row.acknowledgement_no }}</span>
|
|
<button
|
|
class="copy-chip"
|
|
(click)="copyAck(row.acknowledgement_no, 'ack-' + row.id, $event)"
|
|
title="Copy Ack No."
|
|
>
|
|
<fa-icon icon="copy"></fa-icon>
|
|
<span>{{ copiedId === 'ack-' + row.id ? 'Copied' : 'Copy' }}</span>
|
|
</button>
|
|
</div>
|
|
<div class="sub">Job: {{ row.job_id }}</div>
|
|
</td>
|
|
<td>
|
|
<span class="cat-pill">{{ row.sub_category || 'N/A' }}</span>
|
|
</td>
|
|
<td>
|
|
<b>{{ row.payer_account_number }}</b>
|
|
</td>
|
|
<td class="num font-semibold">{{ row.max_layer }}</td>
|
|
<td class="num">{{ row.incidents }}</td>
|
|
<td class="num font-bold">₹{{ row.amount_held | number: '1.2-2' }}</td>
|
|
<td>
|
|
<span class="i4c-badge" [class]="statusClass(row.status)">{{ row.status }}</span>
|
|
@if (row.processing_error) {
|
|
<div class="sub err-text" [title]="row.processing_error">{{ row.processing_error }}</div>
|
|
}
|
|
</td>
|
|
<td>
|
|
<span class="i4c-badge" [class]="responseClass(row.response_status)">
|
|
{{ row.response_status || 'NOT YET' }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
} @empty {
|
|
<tr>
|
|
<td colspan="9" class="i4c-empty">
|
|
<div class="empty-icon"><fa-icon icon="inbox"></fa-icon></div>
|
|
<div>No complaints from I4C matched your query.</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<mat-paginator
|
|
class="i4c-paginator"
|
|
[length]="total"
|
|
[pageIndex]="pageIndex"
|
|
[pageSize]="pageSize"
|
|
[pageSizeOptions]="pageSizes"
|
|
(page)="onPage($event)"
|
|
showFirstLastButtons
|
|
aria-label="Complaints pages"
|
|
></mat-paginator>
|
|
</div>
|
|
|
|
<!-- ========================================================
|
|
MODERN POPUP WINDOW: COMPLAINT DETAILS MODAL
|
|
======================================================== -->
|
|
@if (selectedComplaint) {
|
|
<div class="i4c-modal-backdrop" (click)="closeModal()">
|
|
<div class="i4c-modal-window i4c-modal-window--wide" (click)="$event.stopPropagation()">
|
|
<!-- Header -->
|
|
<div class="i4c-modal-header">
|
|
<div class="i4c-modal-header__title">
|
|
<fa-icon icon="inbox"></fa-icon>
|
|
<div>
|
|
<div class="modal-title-row">
|
|
<span>Ack #{{ selectedComplaint.acknowledgement_no }}</span>
|
|
<span class="i4c-badge" [class]="statusClass(selectedComplaint.status)">{{
|
|
selectedComplaint.status
|
|
}}</span>
|
|
<button class="copy-chip" (click)="copyAck(selectedComplaint.acknowledgement_no, 'modal-ack')">
|
|
<fa-icon icon="copy"></fa-icon>
|
|
<span>{{ copiedId === 'modal-ack' ? 'Copied' : 'Copy Ack' }}</span>
|
|
</button>
|
|
</div>
|
|
<div class="i4c-modal-header__sub">
|
|
Job ID: {{ selectedComplaint.job_id }} • Received:
|
|
{{ selectedComplaint.received_at | date: 'dd MMM yyyy, HH:mm:ss' }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="i4c-modal-header__actions">
|
|
<button class="modal-close-btn" (click)="closeModal()" aria-label="Close">
|
|
<fa-icon icon="times"></fa-icon>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Navigation Tabs inside the Modal -->
|
|
<div class="i4c-modal-tabs">
|
|
<button class="modal-tab" [class.modal-tab--active]="modalTab === 'overview'" (click)="modalTab = 'overview'">
|
|
<fa-icon icon="info-circle"></fa-icon> Overview & Account
|
|
</button>
|
|
<button
|
|
class="modal-tab"
|
|
[class.modal-tab--active]="modalTab === 'incidents'"
|
|
(click)="modalTab = 'incidents'"
|
|
>
|
|
<fa-icon icon="tasks"></fa-icon> Incidents ({{
|
|
selectedComplaint.incidents?.length || selectedComplaint.incidents || 0
|
|
}})
|
|
</button>
|
|
<button class="modal-tab" [class.modal-tab--active]="modalTab === 'findings'" (click)="modalTab = 'findings'">
|
|
<fa-icon icon="list-alt"></fa-icon> Section 6 Findings ({{ selectedComplaint.findings?.length || 0 }})
|
|
</button>
|
|
<button class="modal-tab" [class.modal-tab--active]="modalTab === 'outbox'" (click)="modalTab = 'outbox'">
|
|
<fa-icon icon="paper-plane"></fa-icon> Outbox Responses ({{ selectedComplaint.outbox?.length || 0 }})
|
|
</button>
|
|
<button class="modal-tab" [class.modal-tab--active]="modalTab === 'payloads'" (click)="modalTab = 'payloads'">
|
|
<fa-icon icon="code"></fa-icon> Raw JSON
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Modal Body -->
|
|
<div class="i4c-modal-body">
|
|
@if (detailLoading) {
|
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
|
}
|
|
@if (detailError) {
|
|
<div class="i4c-error">{{ detailError }}</div>
|
|
}
|
|
|
|
<!-- TAB 1: OVERVIEW -->
|
|
@if (modalTab === 'overview') {
|
|
<div class="i4c-grid-2">
|
|
<div class="i4c-card">
|
|
<div class="i4c-card__head"><fa-icon icon="user-shield"></fa-icon> Target Customer Account</div>
|
|
<div class="i4c-card__body">
|
|
<dl class="i4c-kv">
|
|
<dt>Account Number</dt>
|
|
<dd>
|
|
<b>{{ selectedComplaint.payer_account_number }}</b>
|
|
</dd>
|
|
|
|
<dt>Sub-Category</dt>
|
|
<dd>{{ selectedComplaint.sub_category }}</dd>
|
|
|
|
<dt>Complainant Bank</dt>
|
|
<dd>
|
|
{{ selectedComplaint.payer_bank }}
|
|
{{ selectedComplaint.payer_bank_code ? '(' + selectedComplaint.payer_bank_code + ')' : '' }}
|
|
</dd>
|
|
|
|
<dt>Payment Mode</dt>
|
|
<dd>
|
|
{{ selectedComplaint.mode_of_payment || 'N/A' }}
|
|
{{ selectedComplaint.transaction_type ? '/ ' + selectedComplaint.transaction_type : '' }}
|
|
</dd>
|
|
|
|
<dt>Wallet Reference</dt>
|
|
<dd>{{ selectedComplaint.wallet || 'None' }}</dd>
|
|
|
|
<dt>State / District</dt>
|
|
<dd>{{ selectedComplaint.state }} / {{ selectedComplaint.district }}</dd>
|
|
|
|
<dt>Source IP</dt>
|
|
<dd>{{ selectedComplaint.source_ip || '-' }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="i4c-card">
|
|
<div class="i4c-card__head"><fa-icon icon="sync"></fa-icon> Processing Status</div>
|
|
<div class="i4c-card__body">
|
|
<dl class="i4c-kv">
|
|
<dt>Processing Status</dt>
|
|
<dd>
|
|
<span class="i4c-badge" [class]="statusClass(selectedComplaint.status)">{{
|
|
selectedComplaint.status
|
|
}}</span>
|
|
</dd>
|
|
|
|
<dt>Processing Attempts</dt>
|
|
<dd>{{ selectedComplaint.processing_attempts ?? 1 }}</dd>
|
|
|
|
<dt>Processed Timestamp</dt>
|
|
<dd>
|
|
{{
|
|
selectedComplaint.processed_at
|
|
? (selectedComplaint.processed_at | date: 'dd MMM yyyy, HH:mm:ss')
|
|
: 'Pending processing'
|
|
}}
|
|
</dd>
|
|
|
|
<dt>Total Held Amount</dt>
|
|
<dd>
|
|
<b class="amount-accent">₹{{ selectedComplaint.amount_held | number: '1.2-2' }}</b>
|
|
</dd>
|
|
|
|
<dt>Response to I4C</dt>
|
|
<dd>
|
|
<span class="i4c-badge" [class]="responseClass(selectedComplaint.response_status)">
|
|
{{ selectedComplaint.response_status || 'NOT YET SENT' }}
|
|
</span>
|
|
</dd>
|
|
|
|
@if (selectedComplaint.processing_error) {
|
|
<dt>Last Error</dt>
|
|
<dd class="err-text">{{ selectedComplaint.processing_error }}</dd>
|
|
}
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- TAB 2: INCIDENTS -->
|
|
@if (modalTab === 'incidents') {
|
|
<div class="i4c-card">
|
|
<div class="i4c-table-wrap">
|
|
<table class="i4c-table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>RRN</th>
|
|
<th>Date</th>
|
|
<th class="num">Amount (₹)</th>
|
|
<th class="num">Disputed (₹)</th>
|
|
<th class="num">Layer</th>
|
|
<th>Matched By</th>
|
|
<th>Outcome</th>
|
|
<th class="num">Held (₹)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (inc of selectedComplaint.incidents; track inc.id) {
|
|
<tr>
|
|
<td>
|
|
<b>{{ inc.seq_no }}</b>
|
|
</td>
|
|
<td>{{ inc.rrn }}</td>
|
|
<td>{{ inc.transaction_date }} {{ inc.transaction_time }}</td>
|
|
<td class="num">{{ inc.amount | number: '1.2-2' }}</td>
|
|
<td class="num">{{ inc.disputed_amount | number: '1.2-2' }}</td>
|
|
<td class="num">{{ inc.layer }}</td>
|
|
<td>
|
|
<span>{{ inc.match_method || 'EXACT' }}</span>
|
|
@if (inc.matched_txn_id) {
|
|
<div class="sub">Txn #{{ inc.matched_txn_id }}</div>
|
|
}
|
|
</td>
|
|
<td>
|
|
<span class="i4c-badge" [class]="outcomeClass(inc.outcome)">{{
|
|
inc.outcome || 'PENDING'
|
|
}}</span>
|
|
<div class="sub">Code: {{ inc.status_code || '-' }}</div>
|
|
</td>
|
|
<td class="num">
|
|
@if (holdFor(inc.id); as hold) {
|
|
₹{{ hold.amount_held | number: '1.2-2' }}
|
|
@if (hold.shortfall > 0) {
|
|
<div class="sub err-text">Short ₹{{ hold.shortfall | number: '1.2-2' }}</div>
|
|
}
|
|
} @else {
|
|
-
|
|
}
|
|
</td>
|
|
</tr>
|
|
} @empty {
|
|
<tr>
|
|
<td colspan="9" class="i4c-empty">No incident details found.</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- TAB 3: FINDINGS (SECTION 6) -->
|
|
@if (modalTab === 'findings') {
|
|
<div class="i4c-card">
|
|
<div class="i4c-table-wrap">
|
|
<table class="i4c-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Incident ID</th>
|
|
<th>Transaction Type</th>
|
|
<th class="num">Amount (₹)</th>
|
|
<th class="num">Disputed (₹)</th>
|
|
<th>Status Code</th>
|
|
<th>Raw JSON</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (f of selectedComplaint.findings; track f.id) {
|
|
<tr>
|
|
<td>{{ f.incident_id }}</td>
|
|
<td>{{ f.txn_type }} ({{ f.txn_type_id }})</td>
|
|
<td class="num">₹{{ f.amount | number: '1.2-2' }}</td>
|
|
@if (f.disputed_amount === null || f.disputed_amount === undefined) {
|
|
<td
|
|
class="num muted-cell"
|
|
title="The specification has no disputed amount in a Transaction Put on Hold entry"
|
|
>
|
|
-
|
|
</td>
|
|
} @else {
|
|
<td class="num">₹{{ f.disputed_amount | number: '1.2-2' }}</td>
|
|
}
|
|
<td>
|
|
<span
|
|
class="i4c-badge"
|
|
[class]="statusCodeClass(f.status_code)"
|
|
[title]="statusCodeMeaning(f.status_code)"
|
|
>
|
|
{{ f.status_code }} · {{ statusCodeMeaning(f.status_code) }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<button class="table-action-btn" (click)="toggleFindingJson(f.id)">
|
|
{{ openFindingJsonId === f.id ? 'Hide JSON' : 'View JSON' }}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
@if (openFindingJsonId === f.id) {
|
|
<tr class="finding-json-row">
|
|
<td colspan="6" class="finding-json-cell">
|
|
<div class="finding-json-box">
|
|
<div class="finding-json-head">
|
|
<span> <fa-icon icon="code"></fa-icon> Finding #{{ f.id }} Payload </span>
|
|
<button
|
|
type="button"
|
|
class="copy-chip"
|
|
(click)="copyAck(prettyJson(f.entry_json), 'finding-' + f.id, $event)"
|
|
>
|
|
<fa-icon icon="copy"></fa-icon>
|
|
<span>{{ copiedId === 'finding-' + f.id ? 'Copied!' : 'Copy' }}</span>
|
|
</button>
|
|
</div>
|
|
<pre class="i4c-json">{{ prettyJson(f.entry_json) }}</pre>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
} @empty {
|
|
<tr>
|
|
<td colspan="6" class="i4c-empty">No section 6 findings reported yet.</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- TAB 4: OUTBOX RESPONSES -->
|
|
@if (modalTab === 'outbox') {
|
|
<div class="i4c-card">
|
|
<div class="i4c-table-wrap">
|
|
<table class="i4c-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Created</th>
|
|
<th title="ACK: separate acknowledgement callback. RESPONSE: the Section 6 findings.">Type</th>
|
|
<th>Status</th>
|
|
<th class="num">Attempts</th>
|
|
<th>HTTP Code</th>
|
|
<th>Sent Time</th>
|
|
<th>Error</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (o of selectedComplaint.outbox; track o.id) {
|
|
<tr>
|
|
<td>{{ o.created_at | date: 'dd MMM, HH:mm:ss' }}</td>
|
|
<td>
|
|
<span class="i4c-badge" [class.i4c-badge--blue]="o.message_type === 'ACK'">{{
|
|
o.message_type === 'ACK' ? 'ACK' : 'RESPONSE'
|
|
}}</span>
|
|
</td>
|
|
<td>
|
|
<span class="i4c-badge" [class]="responseClass(o.status)">{{ o.status }}</span>
|
|
</td>
|
|
<td class="num">{{ o.attempts }}</td>
|
|
<td>{{ o.http_status ?? '-' }}</td>
|
|
<td>{{ o.sent_at ? (o.sent_at | date: 'dd MMM, HH:mm:ss') : '-' }}</td>
|
|
<td class="err-text">{{ o.last_error }}</td>
|
|
<td>
|
|
@if (o.status === 'FAILED') {
|
|
<button
|
|
class="table-action-btn"
|
|
(click)="retryOutboxItem(o.id)"
|
|
[disabled]="retryingOutboxId === o.id"
|
|
>
|
|
<fa-icon
|
|
icon="redo"
|
|
[animation]="retryingOutboxId === o.id ? 'spin' : undefined"
|
|
></fa-icon>
|
|
Retry
|
|
</button>
|
|
}
|
|
</td>
|
|
</tr>
|
|
} @empty {
|
|
<tr>
|
|
<td colspan="8" class="i4c-empty">No outbox delivery records yet.</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- TAB 5: RAW PAYLOADS -->
|
|
@if (modalTab === 'payloads') {
|
|
<div class="payloads-view">
|
|
<div class="payload-box">
|
|
<div class="payload-box__title">
|
|
<fa-icon icon="inbox"></fa-icon>
|
|
<span>Payload Received from I4C Gateway (Masked)</span>
|
|
<button class="copy-chip" (click)="copyAck(prettyJson(selectedComplaint.raw_payload), 'payload-in')">
|
|
<fa-icon icon="copy"></fa-icon> Copy
|
|
</button>
|
|
</div>
|
|
<pre class="i4c-json">{{ prettyJson(selectedComplaint.raw_payload) }}</pre>
|
|
</div>
|
|
|
|
@for (o of selectedComplaint.outbox; track o.id) {
|
|
<div class="payload-box">
|
|
<div class="payload-box__title">
|
|
<fa-icon icon="paper-plane"></fa-icon>
|
|
<span>Response #{{ o.id }} Delivered to I4C</span>
|
|
<button class="copy-chip" (click)="copyAck(prettyJson(o.payload), 'payload-out-' + o.id)">
|
|
<fa-icon icon="copy"></fa-icon> Copy
|
|
</button>
|
|
</div>
|
|
<pre class="i4c-json">{{ prettyJson(o.payload) }}</pre>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<div class="i4c-modal-footer">
|
|
@if (selectedComplaint.status === 'RETRY' || selectedComplaint.status === 'PROCESSING') {
|
|
<button
|
|
mat-flat-button
|
|
color="primary"
|
|
(click)="reprocessModal(selectedComplaint.id)"
|
|
[disabled]="reprocessing"
|
|
>
|
|
<fa-icon icon="redo" [animation]="reprocessing ? 'spin' : undefined"></fa-icon> Process Now
|
|
</button>
|
|
}
|
|
<button mat-stroked-button (click)="openFullPage(selectedComplaint.id)">
|
|
<fa-icon icon="external-link-alt"></fa-icon> Open in Full Page
|
|
</button>
|
|
<button class="footer-btn-close" (click)="closeModal()">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|