Merge dev into demo-backup

Brings in all of dev's latest content not present on demo-backup
(Share Withdrawal/Closure feature, TDS reports, KYC exception tracking,
client-edit-email-dialog, form121 tab, search-select) while preserving
demo-backup's own unique changes (wrapping Approval Center tab nav,
Loan Origination/Investment mega-menus). 36 files that a prior "ours
wins" conflict resolution had silently dropped were restored explicitly
from dev's tip.
This commit is contained in:
2026-08-06 14:16:22 +05:30
54 changed files with 12219 additions and 6 deletions
@@ -0,0 +1,84 @@
<!--
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/.
-->
<h1 mat-dialog-title class="ced-title">
<span class="ced-title__icon">✉</span>
Approval Email
<div class="ced-status-row">
@if (data.emailSent) {
<span class="ced-chip ced-chip--sent">
<span class="ced-chip__dot"></span>Sent
</span>
} @else {
<span class="ced-chip ced-chip--notsent">
<span class="ced-chip__dot"></span>Not sent
</span>
}
@if (data.emailOpenedAt) {
<span class="ced-chip ced-chip--seen">
<fa-icon icon="eye" class="ced-chip__icon"></fa-icon>Seen
</span>
} @else {
<span class="ced-chip ced-chip--notseen">
<fa-icon icon="eye-slash" class="ced-chip__icon"></fa-icon>Not yet seen
</span>
}
</div>
</h1>
<div mat-dialog-content class="ced-content">
<!-- Classic Email Header (Gmail Style) -->
<div class="ced-gmail-header">
<h2 class="ced-gmail-subject">{{ data.emailSubject ?? '(No Subject)' }}</h2>
<div class="ced-gmail-meta">
<div class="ced-gmail-avatar">
<div class="ced-gmail-avatar-letter">C</div>
</div>
<div class="ced-gmail-meta-content">
<div class="ced-gmail-meta-top">
<span class="ced-gmail-sender-name">CBSNexora</span>
<span class="ced-gmail-sender-email">&lt;{{ data.emailFrom ?? 'noreply@cbsnexora.in' }}&gt;</span>
<span class="ced-gmail-spacer"></span>
<span class="ced-gmail-date">{{ data.emailSentAt ? formatDate(data.emailSentAt) : '—' }}</span>
</div>
<div class="ced-gmail-meta-bottom">
<span class="ced-gmail-to">
to
@if (data.emailTo) {
{{ data.emailTo }}
} @else {
<span style="font-style: italic; color: #d32f2f">No email on file</span>
}
</span>
<fa-icon icon="caret-down" class="ced-gmail-caret"></fa-icon>
</div>
</div>
</div>
</div>
<!-- HTML email body -->
@if (data.emailBody) {
<div class="ced-email-body" [innerHTML]="safeBody"></div>
} @else {
<div class="ced-empty">
<p>No email content available.</p>
@if (!data.emailSent) {
<p class="ced-empty__hint">The email has not been sent yet for this edit.</p>
}
</div>
}
</div>
<mat-dialog-actions align="end">
<button mat-raised-button color="primary" mat-dialog-close>Close</button>
</mat-dialog-actions>
@@ -0,0 +1,219 @@
/**
* Copyright since 2025 Mifos Initiative
* MPL-2.0
*/
:host {
display: block;
}
.ced-title {
display: flex;
align-items: center;
gap: 10px;
font-size: 1.15rem;
font-weight: 600;
color: #1a237e;
position: relative; /* For aligning badges to the right */
&__icon {
font-size: 1.3rem;
}
}
.ced-content {
min-width: 560px;
max-width: 760px;
max-height: 72vh;
overflow-y: auto;
padding: 0 4px;
}
/* ── Gmail-Style Email Header ─────────────────────────────────────────────────── */
.ced-gmail-header {
display: flex;
flex-direction: column;
margin-bottom: 30px;
padding: 0 4px;
font-family: 'Roboto', 'Inter', sans-serif; /* Gmail-like typography */
}
.ced-gmail-subject {
font-size: 1.35rem;
font-weight: 400;
color: #202124;
margin: 0 0 24px 0;
line-height: 1.4;
}
.ced-gmail-meta {
display: flex;
align-items: center; /* Avatar vertically centered with text */
gap: 12px;
}
.ced-gmail-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #f06292;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.ced-gmail-avatar-letter {
color: white;
font-size: 1.25rem;
font-weight: 500;
}
.ced-gmail-meta-content {
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
gap: 2px;
}
.ced-gmail-meta-top {
display: flex;
align-items: baseline;
width: 100%;
}
.ced-gmail-spacer {
flex-grow: 1;
}
.ced-gmail-sender-name {
font-size: 0.95rem;
font-weight: 600;
color: #202124;
margin-right: 6px;
}
.ced-gmail-sender-email {
color: #5f6368;
font-size: 0.8rem;
}
.ced-gmail-date {
color: #5f6368;
font-size: 0.75rem;
white-space: nowrap;
}
.ced-gmail-meta-bottom {
display: flex;
align-items: center;
gap: 4px;
}
.ced-gmail-to {
font-size: 0.75rem;
color: #5f6368;
}
.ced-gmail-caret {
font-size: 0.75rem;
color: #5f6368;
cursor: pointer;
}
.ced-status-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-left: auto; /* Pushes badges to the right in the flex container */
}
/* ── Status chips ───────────────────────────────────────────────────────── */
.ced-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 12px 4px 10px;
border-radius: 20px;
font-size: 0.82rem;
font-weight: 500;
&__dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
&__icon {
font-size: 0.82rem;
}
&--sent {
background: #e8f5e9;
color: #1b5e20;
.ced-chip__dot { background: #43a047; }
}
&--notsent {
background: #f5f5f5;
color: #757575;
.ced-chip__dot { background: #bdbdbd; }
}
&--seen {
background: #e3f2fd;
color: #0d47a1;
}
&--notseen {
background: #f5f5f5;
color: #9e9e9e;
}
}
/* ── Divider ────────────────────────────────────────────────────────────── */
.ced-divider {
border: none;
border-top: 1px solid #eeeeee;
margin: 12px 0;
}
/* ── Email body iframe-like container ───────────────────────────────────── */
.ced-email-body {
background: #fafafa;
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 20px 24px;
font-family: Arial, sans-serif;
font-size: 0.93rem;
line-height: 1.6;
color: #333;
// Reset any Angular Material overrides inside the rendered HTML
table {
border-collapse: collapse;
width: 100%;
}
td, th {
padding: 6px 12px;
border: 1px solid #e0e0e0;
}
p { margin: 0 0 10px; }
ul { padding-left: 20px; }
}
/* ── Empty state ────────────────────────────────────────────────────────── */
.ced-empty {
text-align: center;
padding: 32px 0;
color: #9e9e9e;
&__hint {
font-size: 0.85rem;
margin-top: 6px;
}
}
@@ -0,0 +1,65 @@
/**
* 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/.
*/
import { Component, inject } from '@angular/core';
import {
MAT_DIALOG_DATA,
MatDialogTitle,
MatDialogContent,
MatDialogActions,
MatDialogClose
} from '@angular/material/dialog';
import { CdkScrollable } from '@angular/cdk/scrolling';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
export interface ClientEditEmailDialogData {
emailSubject: string | null;
emailBody: string | null;
emailSent: boolean;
emailSentAt: string | null;
emailOpenedAt: string | null;
emailFrom: string | null;
emailTo: string | null;
}
/** Displays the exact confirmation email sent to the client when their pending edit was approved.
* Shows subject, HTML body (rendered), sent timestamp, and read/seen status. */
@Component({
selector: 'mifosx-client-edit-email-dialog',
templateUrl: './client-edit-email-dialog.component.html',
styleUrls: ['./client-edit-email-dialog.component.scss'],
standalone: true,
imports: [
...STANDALONE_SHARED_IMPORTS,
MatDialogTitle,
CdkScrollable,
MatDialogContent,
MatDialogActions,
MatDialogClose,
FaIconComponent
]
})
export class ClientEditEmailDialogComponent {
data = inject<ClientEditEmailDialogData>(MAT_DIALOG_DATA);
private sanitizer = inject(DomSanitizer);
get safeBody(): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(this.data.emailBody ?? '');
}
formatDate(isoDate: string | null | undefined): string {
if (!isoDate) return '—';
const d = new Date(isoDate);
return d.toLocaleString('en-IN', {
day: '2-digit', month: 'short', year: 'numeric',
hour: '2-digit', minute: '2-digit', hour12: true
});
}
}
@@ -0,0 +1,82 @@
<!--
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="pg-card">
<div class="pos-section-label">Share Closure Requests — Review, Approve or Reject</div>
<div class="inv-form-grid" style="padding: 12px 16px">
<label class="inv-form-field">
<span>Status</span>
<select [(ngModel)]="filterStatus" (change)="onFilterChange()">
@for (opt of statusOptions; track opt.value) {
<option [value]="opt.value">{{ opt.label }}</option>
}
</select>
</label>
<label class="inv-form-field" style="align-self: end">
<button type="button" class="pg-btn pg-btn--ghost" [disabled]="loading" (click)="load()">Refresh</button>
</label>
</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Client</th>
<th>Closed Date</th>
<th>Clerk</th>
<th>Manager</th>
<th>Submitted At</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
@if (loading) {
<tr>
<td colspan="8" class="pg-empty">Loading…</td>
</tr>
} @else if (loaded && requests.length === 0) {
<tr>
<td colspan="8" class="pg-empty">No {{ filterStatus | lowercase }} share closure requests.</td>
</tr>
} @else {
@for (r of requests; track r.id) {
<tr>
<td>
<span class="pg-chip">{{ r.account_no }}</span>
</td>
<td>{{ r.client_name }}</td>
<td>{{ formatDateTime(r.closed_date) }}</td>
<td>{{ r.clerk_name }}</td>
<td>{{ r.manager_name || r.manager_username || '—' }}</td>
<td>{{ formatDateTime(r.submitted_at) }}</td>
<td>
<span [class]="statusClass(r.status)">{{ statusLabel(r.status) }}</span>
</td>
<td>
<button type="button" class="pg-btn pg-btn--ghost" (click)="review(r)">Review</button>
</td>
</tr>
}
}
</tbody>
</table>
</div>
@if (showReviewModal && reviewRequestId) {
<div class="swr-list-popup-backdrop" (click)="closeReviewModal()">
<div class="swr-list-popup-panel" (click)="$event.stopPropagation()">
<mifosx-share-closure-request
[embedded]="true"
[overrideMode]="'review'"
[overrideRequestId]="reviewRequestId"
(closeRequested)="closeReviewModal()"
(actionCompleted)="onReviewActionCompleted()"
></mifosx-share-closure-request>
</div>
</div>
}
@@ -0,0 +1,128 @@
/**
* 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/.
*/
import { Component, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';
import { ClerkShareClosureService } from '../../../cashier/clerk-share-closure.service';
import { ShareClosureRequestComponent } from '../../../clerk/share-closure-request/share-closure-request.component';
/** Approval Center — Share Closure Requests tab. A Bank Manager (checker) reviews, approves or
* rejects share account closure requests submitted from the Clerk Dashboard. Mirrors
* ShareWithdrawalRequestsComponent. Clicking "Review" opens the review screen in a popup on top of
* this list, rather than navigating away, so approving/rejecting drops the manager straight back
* into the (now refreshed) list. */
@Component({
selector: 'mifosx-share-closure-requests',
templateUrl: './share-closure-requests.component.html',
styleUrls: [
'../../../cashier/cashier-shared.scss',
'../../../clerk/clerk-shared.scss',
'../share-withdrawal-requests/share-withdrawal-requests.component.scss'
],
standalone: true,
imports: [
CommonModule,
FormsModule,
ShareClosureRequestComponent
]
})
export class ShareClosureRequestsComponent implements OnInit {
private service = inject(ClerkShareClosureService);
requests: any[] = [];
totalRecords = 0;
loading = false;
loaded = false;
filterStatus = 'PENDING';
showReviewModal = false;
reviewRequestId: number | null = null;
get statusOptions(): { value: string; label: string }[] {
return [
{ value: 'PENDING', label: 'Pending' },
{ value: 'APPROVED', label: 'Approved' },
{ value: 'REJECTED', label: 'Rejected' }
];
}
ngOnInit(): void {
this.load();
}
load(): void {
this.loading = true;
this.service
.getPendingRequests(this.filterStatus, 0, 50)
.pipe(catchError(() => of({ pageItems: [], totalFilteredRecords: 0 })))
.subscribe((res: any) => {
this.requests = res?.pageItems ?? [];
this.totalRecords = Number(res?.totalFilteredRecords ?? 0);
this.loading = false;
this.loaded = true;
});
}
onFilterChange(): void {
this.load();
}
review(req: any): void {
this.reviewRequestId = req.id;
this.showReviewModal = true;
}
closeReviewModal(): void {
this.showReviewModal = false;
this.reviewRequestId = null;
}
onReviewActionCompleted(): void {
this.closeReviewModal();
this.load();
}
statusClass(status: string): string {
const map: Record<string, string> = {
PENDING: 'inv-badge--active',
APPROVED: 'inv-badge--matured',
REJECTED: 'inv-badge--written_off'
};
return `inv-badge ${map[status] ?? ''}`;
}
statusLabel(status: string): string {
const map: Record<string, string> = {
PENDING: 'Pending',
APPROVED: 'Approved',
REJECTED: 'Rejected'
};
return map[status] ?? status;
}
formatDateTime(val: any): string {
if (!val) return '—';
try {
const d = new Date(val);
return d.toLocaleString('en-IN', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch {
return String(val);
}
}
}
@@ -0,0 +1,86 @@
<!--
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="pg-card">
<div class="pos-section-label">Share Withdrawal Requests — Review, Approve or Reject</div>
<div class="inv-form-grid" style="padding: 12px 16px">
<label class="inv-form-field">
<span>Status</span>
<select [(ngModel)]="filterStatus" (change)="onFilterChange()">
@for (opt of statusOptions; track opt.value) {
<option [value]="opt.value">{{ opt.label }}</option>
}
</select>
</label>
<label class="inv-form-field" style="align-self: end">
<button type="button" class="pg-btn pg-btn--ghost" [disabled]="loading" (click)="load()">Refresh</button>
</label>
</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Client</th>
<th class="num">Shares</th>
<th>Resolution No.</th>
<th>Meeting Date</th>
<th>Clerk</th>
<th>Manager</th>
<th>Submitted At</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
@if (loading) {
<tr>
<td colspan="10" class="pg-empty">Loading…</td>
</tr>
} @else if (loaded && requests.length === 0) {
<tr>
<td colspan="10" class="pg-empty">No {{ filterStatus | lowercase }} share withdrawal requests.</td>
</tr>
} @else {
@for (r of requests; track r.id) {
<tr>
<td>
<span class="pg-chip">{{ r.account_no }}</span>
</td>
<td>{{ r.client_name }}</td>
<td class="num">{{ r.requested_shares }}</td>
<td>{{ r.resolution_number }}</td>
<td>{{ formatDateTime(r.meeting_date) }}</td>
<td>{{ r.clerk_name }}</td>
<td>{{ r.manager_name || r.manager_username || '—' }}</td>
<td>{{ formatDateTime(r.submitted_at) }}</td>
<td>
<span [class]="statusClass(r.status)">{{ statusLabel(r.status) }}</span>
</td>
<td>
<button type="button" class="pg-btn pg-btn--ghost" (click)="review(r)">Review</button>
</td>
</tr>
}
}
</tbody>
</table>
</div>
@if (showReviewModal && reviewRequestId) {
<div class="swr-list-popup-backdrop" (click)="closeReviewModal()">
<div class="swr-list-popup-panel" (click)="$event.stopPropagation()">
<mifosx-share-withdrawal-request
[embedded]="true"
[overrideMode]="'review'"
[overrideRequestId]="reviewRequestId"
(closeRequested)="closeReviewModal()"
(actionCompleted)="onReviewActionCompleted()"
></mifosx-share-withdrawal-request>
</div>
</div>
}
@@ -0,0 +1,64 @@
/**
* 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/.
*/
@keyframes swr-list-popup-fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes swr-list-popup-zoom {
from {
opacity: 0;
transform: scale(0.97) translateY(10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.swr-list-popup-backdrop {
position: fixed;
inset: 0;
// No backdrop-filter here: filter/backdrop-filter on an ancestor makes browsers treat it as a new
// containing block for `position: fixed` descendants — the embedded review screen inside this popup
// renders its OWN fixed-position dialogs (Validate, Reject, Confirm-Submit), which would then be
// confined to this backdrop's box instead of the real viewport. Extra opacity on the background
// color compensates for the loss of the blur look.
background: rgb(15 25 45 / 65%);
z-index: 1100;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 32px 20px;
overflow-y: auto;
animation: swr-list-popup-fade 0.2s ease-out;
}
.swr-list-popup-panel {
background: #f7f9fc;
border-radius: 16px;
width: 100%;
max-width: 1100px;
box-shadow: 0 24px 60px rgb(0 0 0 / 25%);
animation: swr-list-popup-zoom 0.25s ease-out;
padding: 4px;
}
@media (prefers-reduced-motion: reduce) {
.swr-list-popup-backdrop,
.swr-list-popup-panel {
animation: none;
}
}
@@ -0,0 +1,128 @@
/**
* 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/.
*/
import { Component, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';
import { ClerkShareWithdrawalService } from '../../../cashier/clerk-share-withdrawal.service';
import { ShareWithdrawalRequestComponent } from '../../../clerk/share-withdrawal-request/share-withdrawal-request.component';
/** Approval Center — Share Withdrawal Requests tab. A Bank Manager (checker) reviews, approves
* or rejects share withdrawal requests submitted from the Clerk Dashboard. Mirrors
* WithdrawalRequestsComponent (cash withdrawal), adapted for shares. Clicking "Review" opens the
* review screen in a popup on top of this list, rather than navigating away, so approving/rejecting
* drops the manager straight back into the (now refreshed) list. */
@Component({
selector: 'mifosx-share-withdrawal-requests',
templateUrl: './share-withdrawal-requests.component.html',
styleUrls: [
'../../../cashier/cashier-shared.scss',
'../../../clerk/clerk-shared.scss',
'./share-withdrawal-requests.component.scss'
],
standalone: true,
imports: [
CommonModule,
FormsModule,
ShareWithdrawalRequestComponent
]
})
export class ShareWithdrawalRequestsComponent implements OnInit {
private service = inject(ClerkShareWithdrawalService);
requests: any[] = [];
totalRecords = 0;
loading = false;
loaded = false;
filterStatus = 'PENDING';
showReviewModal = false;
reviewRequestId: number | null = null;
get statusOptions(): { value: string; label: string }[] {
return [
{ value: 'PENDING', label: 'Pending' },
{ value: 'APPROVED', label: 'Approved' },
{ value: 'REJECTED', label: 'Rejected' }
];
}
ngOnInit(): void {
this.load();
}
load(): void {
this.loading = true;
this.service
.getPendingRequests(this.filterStatus, 0, 50)
.pipe(catchError(() => of({ pageItems: [], totalFilteredRecords: 0 })))
.subscribe((res: any) => {
this.requests = res?.pageItems ?? [];
this.totalRecords = Number(res?.totalFilteredRecords ?? 0);
this.loading = false;
this.loaded = true;
});
}
onFilterChange(): void {
this.load();
}
review(req: any): void {
this.reviewRequestId = req.id;
this.showReviewModal = true;
}
closeReviewModal(): void {
this.showReviewModal = false;
this.reviewRequestId = null;
}
onReviewActionCompleted(): void {
this.closeReviewModal();
this.load();
}
statusClass(status: string): string {
const map: Record<string, string> = {
PENDING: 'inv-badge--active',
APPROVED: 'inv-badge--matured',
REJECTED: 'inv-badge--written_off'
};
return `inv-badge ${map[status] ?? ''}`;
}
statusLabel(status: string): string {
const map: Record<string, string> = {
PENDING: 'Pending',
APPROVED: 'Approved',
REJECTED: 'Rejected'
};
return map[status] ?? status;
}
formatDateTime(val: any): string {
if (!val) return '—';
try {
const d = new Date(val);
return d.toLocaleString('en-IN', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch {
return String(val);
}
}
}
@@ -135,6 +135,24 @@
<fa-icon icon="money-bill-wave" class="ac-tab__ic"></fa-icon>
<span>Withdrawal Requests</span>
</a>
<a
class="ac-tab"
routerLink="./share-withdrawal-requests"
routerLinkActive="ac-tab--active"
*mifosxHasPermission="'ALL_FUNCTIONS_READ'"
>
<fa-icon icon="hand-holding-usd" class="ac-tab__ic"></fa-icon>
<span>Share Withdrawal Requests</span>
</a>
<a
class="ac-tab"
routerLink="./share-closure-requests"
routerLinkActive="ac-tab--active"
*mifosxHasPermission="'ALL_FUNCTIONS_READ'"
>
<fa-icon icon="lock" class="ac-tab__ic"></fa-icon>
<span>Share Closure Requests</span>
</a>
<a
class="ac-tab"
routerLink="./deposit-requests"
+38
View File
@@ -17,6 +17,8 @@ import { Route } from '../core/route/route.service';
import { CheckerInboxAndTasksComponent } from './checker-inbox-and-tasks/checker-inbox-and-tasks.component';
import { CheckerInboxComponent } from './checker-inbox-and-tasks-tabs/checker-inbox/checker-inbox.component';
import { WithdrawalRequestsComponent } from './checker-inbox-and-tasks-tabs/withdrawal-requests/withdrawal-requests.component';
import { ShareWithdrawalRequestsComponent } from './checker-inbox-and-tasks-tabs/share-withdrawal-requests/share-withdrawal-requests.component';
import { ShareClosureRequestsComponent } from './checker-inbox-and-tasks-tabs/share-closure-requests/share-closure-requests.component';
import { DepositRequestsComponent } from './checker-inbox-and-tasks-tabs/deposit-requests/deposit-requests.component';
import { DisbursementRequestsComponent } from './checker-inbox-and-tasks-tabs/disbursement-requests/disbursement-requests.component';
import { ClientApprovalComponent } from './checker-inbox-and-tasks-tabs/client-approval/client-approval.component';
@@ -159,6 +161,16 @@ const routes: Routes = [
component: WithdrawalRequestsComponent,
data: { title: 'Withdrawal Requests' }
},
{
path: 'share-withdrawal-requests',
component: ShareWithdrawalRequestsComponent,
data: { title: 'Share Withdrawal Requests' }
},
{
path: 'share-closure-requests',
component: ShareClosureRequestsComponent,
data: { title: 'Share Closure Requests' }
},
{
path: 'deposit-requests',
component: DepositRequestsComponent,
@@ -200,6 +212,32 @@ const routes: Routes = [
}
]
},
{
path: 'checker-inbox-and-tasks/share-withdrawal-requests',
children: [
{
path: ':id/review',
loadComponent: () =>
import('../clerk/share-withdrawal-request/share-withdrawal-request.component').then(
(m) => m.ShareWithdrawalRequestComponent
),
data: { title: 'Review Share Withdrawal Request', breadcrumb: 'Review Share Withdrawal', mode: 'review' }
}
]
},
{
path: 'checker-inbox-and-tasks/share-closure-requests',
children: [
{
path: ':id/review',
loadComponent: () =>
import('../clerk/share-closure-request/share-closure-request.component').then(
(m) => m.ShareClosureRequestComponent
),
data: { title: 'Review Share Closure Request', breadcrumb: 'Review Share Closure', mode: 'review' }
}
]
},
{
path: 'checker-inbox-and-tasks/disbursement-requests',
children: [