feat: add CFCFRMS module, bank menus, mock backend, and dashboard redesign
- CFCFRMS cyber fraud complaint management with dashboard, complaints, escalation, report suspect/mule/fraud txn, FMR submission, CFR lookup - Mock HTTP interceptor with 20 dummy complaints and all endpoints - Simulator service for I4C/MHA integration testing - 3-row menu bar with 22 items (7+8+8 layout) - Mega menus for General Ledger, Sub Ledger, Deposits, Share, Others, HRM, RBI with search and grouped columns - Dropdowns for Cashier, Clearing, NPA, CKYC, Advances, Letter Mgmt, Insurance, Digital - Dashboard redesign with regulatory, financial health, deposits, risk/NPA sections using static banking data - All translations added to en-US.json - FontAwesome icons registered for all new menu items Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
0a32d7135e
commit
b3a4cce0cf
@@ -18,8 +18,8 @@
|
||||
.breadcrumb {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 1.5rem 0;
|
||||
line-height: 40px;
|
||||
margin: 0.5rem 0;
|
||||
line-height: 32px;
|
||||
|
||||
.breadcrumb-title {
|
||||
font-size: 1.25rem;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,30 +34,31 @@ $color: #e2e4ec;
|
||||
|
||||
.sidenav {
|
||||
overflow-x: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sub-menu-bar {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
background-color: #1074b9;
|
||||
padding: 2px 0.5rem 2px calc(48px + 2rem);
|
||||
padding: 0 100px 0 48px;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
letter-spacing: normal;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.sub-menu-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 6px 0.5rem;
|
||||
flex: 1;
|
||||
padding: 11px 2px;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
@@ -81,6 +82,149 @@ $color: #e2e4ec;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.sub-menu-spacer {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.menu-item-icon {
|
||||
margin-right: 10px;
|
||||
width: 16px;
|
||||
color: #667085;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Deposits Mega Panel (inside mat-menu overlay) */
|
||||
.deposit-menu-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px 24px;
|
||||
padding: 8px 12px;
|
||||
min-width: 600px;
|
||||
}
|
||||
|
||||
.deposit-menu-group {
|
||||
.deposit-group-title {
|
||||
font-weight: 700;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.6px;
|
||||
color: #1074b9;
|
||||
padding: 4px 16px 6px;
|
||||
margin-bottom: 2px;
|
||||
border-bottom: 2px solid #1074b9;
|
||||
}
|
||||
}
|
||||
|
||||
/* General Ledger Mega Menu */
|
||||
.gl-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.gl-mega-menu {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #fff;
|
||||
width: 860px;
|
||||
max-width: 95vw;
|
||||
padding: 20px 24px;
|
||||
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.22);
|
||||
border-radius: 0 0 10px 10px;
|
||||
z-index: 1000;
|
||||
border-top: 3px solid #0d47a1;
|
||||
}
|
||||
|
||||
.gl-search {
|
||||
width: 100%;
|
||||
padding: 10px 14px;
|
||||
margin-bottom: 16px;
|
||||
border: 1px solid #d0d5dd;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
background: #f9fafb;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #0d47a1;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 0 3px rgba(13, 71, 161, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.gl-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.gl-group-title {
|
||||
font-weight: 700;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
color: #0d47a1;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 2px solid #0d47a1;
|
||||
}
|
||||
|
||||
.gl-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 7px 6px;
|
||||
text-decoration: none;
|
||||
color: #344054;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
transition:
|
||||
background 0.15s,
|
||||
color 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: #e3f2fd;
|
||||
color: #0d47a1;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-icon {
|
||||
width: 18px;
|
||||
margin-right: 8px;
|
||||
color: #667085;
|
||||
font-size: 13px;
|
||||
|
||||
.gl-link:hover & {
|
||||
color: #0d47a1;
|
||||
}
|
||||
}
|
||||
|
||||
/* RBI Mega Menu */
|
||||
.rbi-mega-menu {
|
||||
width: 1100px;
|
||||
max-width: 97vw;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
border-top-color: #b71c1c;
|
||||
}
|
||||
|
||||
.rbi-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
left: 0;
|
||||
|
||||
@@ -66,6 +66,33 @@ export class ShellComponent implements OnInit, OnDestroy {
|
||||
/** Subscription to progress bar. */
|
||||
progressBar$: Subscription;
|
||||
|
||||
/** Sub Ledger mega menu state */
|
||||
subLedgerOpen = false;
|
||||
subLedgerSearch = '';
|
||||
|
||||
/** General Ledger mega menu state */
|
||||
glMenuOpen = false;
|
||||
glSearch = '';
|
||||
|
||||
/** RBI mega menu state */
|
||||
rbiMenuOpen = false;
|
||||
rbiSearch = '';
|
||||
|
||||
matchesSubLedgerSearch(label: string): boolean {
|
||||
if (!this.subLedgerSearch) return true;
|
||||
return label.toLowerCase().includes(this.subLedgerSearch.toLowerCase());
|
||||
}
|
||||
|
||||
matchesGlSearch(label: string): boolean {
|
||||
if (!this.glSearch) return true;
|
||||
return label.toLowerCase().includes(this.glSearch.toLowerCase());
|
||||
}
|
||||
|
||||
matchesRbiSearch(label: string): boolean {
|
||||
if (!this.rbiSearch) return true;
|
||||
return label.toLowerCase().includes(this.rbiSearch.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to progress bar to update its mode.
|
||||
*/
|
||||
@@ -85,6 +112,10 @@ export class ShellComponent implements OnInit, OnDestroy {
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
openConfigWizard(): void {
|
||||
// Placeholder — config wizard is handled by toolbar component
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes from progress bar.
|
||||
*/
|
||||
|
||||
@@ -171,6 +171,119 @@
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.Analytics' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<!-- CFCFRMS Section -->
|
||||
<div class="nav-item-sep mt-1">
|
||||
<mat-divider></mat-divider>
|
||||
<span class="text-muted">{{ 'labels.menus.CFCFRMS' | translate }}</span>
|
||||
</div>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/dashboard']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.CFCFRMS Dashboard' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="shield-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.CFCFRMS Dashboard' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/complaints']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.Complaints' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="list-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.Complaints' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/escalate']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.Escalate Complaint' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="arrow-up" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.Escalate' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/report-suspect']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.Report Suspect' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="user-shield" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.Report Suspect' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/report-mule']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.Report Mule Account' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="user-slash" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.Report Mule' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/report-fraud-txn']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.Report Fraud Transaction' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="exclamation-triangle" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.Report Fraud Txn' | translate }}</a>
|
||||
</mat-list-item>
|
||||
|
||||
<!-- RBI Integration Section -->
|
||||
<div class="nav-item-sep mt-1">
|
||||
<mat-divider></mat-divider>
|
||||
<span class="text-muted">{{ 'labels.menus.RBI Integration' | translate }}</span>
|
||||
</div>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/fmr-submission']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.FMR Submission' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="university" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.FMR Submission' | translate }}</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
[routerLink]="['/cfcfrms/cfr-lookup']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
matTooltip="{{ 'tooltips.CFR Lookup' | translate }}"
|
||||
routerLinkActive="active-menu"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
>
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="search" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<a matLine>{{ 'labels.menus.CFR Lookup' | translate }}</a>
|
||||
</mat-list-item>
|
||||
|
||||
<div class="nav-item-sep mt-1">
|
||||
<mat-divider></mat-divider>
|
||||
<span class="text-muted">{{ 'labels.menus.Main Items' | translate }}</span>
|
||||
</div>
|
||||
|
||||
<mat-list-item
|
||||
[routerLink]="['/rbi-circulars']"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
|
||||
@@ -35,87 +35,14 @@
|
||||
</button>
|
||||
}
|
||||
|
||||
<div class="tab-nav-bar">
|
||||
<a
|
||||
#institution
|
||||
class="tab-link"
|
||||
[matMenuTriggerFor]="institutionMenu"
|
||||
#institutionMenuTrigger="matMenuTrigger"
|
||||
tabindex="0"
|
||||
*mifosxHasPermission="'READ_INSTITUTION'"
|
||||
>
|
||||
<fa-icon class="mr-05" icon="university" size="lg"></fa-icon>
|
||||
{{ 'labels.menus.Institution' | translate }}
|
||||
<fa-icon icon="caret-down" class="ml-05"></fa-icon>
|
||||
</a>
|
||||
|
||||
<span class="hide-lt-md">
|
||||
<a
|
||||
#tasks
|
||||
class="tab-link tasks-link"
|
||||
[routerLink]="['/checker-inbox-and-tasks/checker-inbox']"
|
||||
tabindex="0"
|
||||
*mifosxHasPermission="'ALL_FUNCTIONS_READ'"
|
||||
>
|
||||
<fa-icon class="mr-05" icon="check" size="lg"></fa-icon>
|
||||
{{ 'labels.menus.Tasks' | translate }}
|
||||
</a>
|
||||
<a
|
||||
#accounting
|
||||
class="tab-link accounting-link"
|
||||
[routerLink]="['/accounting']"
|
||||
tabindex="0"
|
||||
*mifosxHasPermission="'READ_ACCOUNTING'"
|
||||
>
|
||||
<fa-icon class="mr-05" icon="money-bill-alt" size="lg"></fa-icon>
|
||||
{{ 'labels.menus.Accounting' | translate }}
|
||||
</a>
|
||||
<a
|
||||
#reports
|
||||
class="tab-link"
|
||||
[matMenuTriggerFor]="reportsMenu"
|
||||
#reportsMenuTrigger="matMenuTrigger"
|
||||
tabindex="0"
|
||||
*mifosxHasPermission="'READ_REPORTS'"
|
||||
>
|
||||
<fa-icon class="mr-05" icon="chart-bar" size="lg"></fa-icon>
|
||||
{{ 'labels.menus.Reports' | translate }}
|
||||
<fa-icon icon="caret-down" class="ml-05"></fa-icon>
|
||||
</a>
|
||||
<a
|
||||
#admin
|
||||
class="tab-link"
|
||||
[matMenuTriggerFor]="adminMenu"
|
||||
#adminMenuTrigger="matMenuTrigger"
|
||||
tabindex="0"
|
||||
*mifosxHasPermission="'READ_ADMIN'"
|
||||
>
|
||||
<fa-icon class="mr-05" icon="shield-alt" size="lg"></fa-icon>
|
||||
{{ 'labels.menus.Admin' | translate }}
|
||||
<fa-icon icon="caret-down" class="ml-05"></fa-icon>
|
||||
</a>
|
||||
<a #configWizard class="tab-link" (click)="openDialog()" tabindex="0" *mifosxHasPermission="'READ_CONFIG_WIZARD'">
|
||||
<fa-icon class="mr-05" icon="info" size="lg"></fa-icon>
|
||||
{{ 'labels.menus.Configuration Wizard' | translate }}
|
||||
</a>
|
||||
<a class="tab-link" [matMenuTriggerFor]="ledgerMenu" tabindex="0">
|
||||
<fa-icon class="mr-05" icon="book" size="lg"></fa-icon>
|
||||
Ledger
|
||||
<fa-icon icon="caret-down" class="ml-05"></fa-icon>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span class="toolbar-spacer"></span>
|
||||
|
||||
<div #notifications>
|
||||
<mifosx-notifications-tray #notificationsTray class="hide-lt-md" tabindex="0"></mifosx-notifications-tray>
|
||||
</div>
|
||||
|
||||
<div #themeToggle>
|
||||
<mifosx-theme-toggle tabindex="0"></mifosx-theme-toggle>
|
||||
</div>
|
||||
|
||||
<div #appMenu>
|
||||
<button mat-icon-button class="ml-1 img-button" [matMenuTriggerFor]="applicationMenu" tabindex="0">
|
||||
<img src="assets/images/user_placeholder.png" [alt]="'labels.headings.User Profile' | translate" />
|
||||
@@ -144,11 +71,220 @@
|
||||
</span>
|
||||
</mat-menu>
|
||||
|
||||
<!-- Ledger Menu -->
|
||||
<mat-menu #ledgerMenu="matMenu" [overlapTrigger]="false">
|
||||
<button mat-menu-item tabindex="0">Sub Ledger</button>
|
||||
<button mat-menu-item tabindex="0">General Ledger</button>
|
||||
</mat-menu>
|
||||
<!-- Sub Ledger Mega Menu -->
|
||||
@if (subLedgerOpen) {
|
||||
<div class="subledger-backdrop" (click)="subLedgerOpen = false"></div>
|
||||
<div class="subledger-mega-menu">
|
||||
<input
|
||||
type="text"
|
||||
class="subledger-search"
|
||||
placeholder="Search menu..."
|
||||
(input)="subLedgerSearch = $event.target.value"
|
||||
/>
|
||||
<div class="subledger-columns">
|
||||
<!-- Transactions -->
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Transactions</div>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesSearch('Cash / Clearing / Transfer')"
|
||||
(click)="subLedgerOpen = false"
|
||||
>
|
||||
<fa-icon icon="money-bill" class="subledger-icon"></fa-icon> Cash / Clearing / Transfer
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Batch Transaction')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="layer-group" class="subledger-icon"></fa-icon> Batch Transaction
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Draft Reconcile')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="file-invoice" class="subledger-icon"></fa-icon> Draft Reconcile
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Insurance Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="shield-alt" class="subledger-icon"></fa-icon> Insurance Entry
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Share Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="chart-line" class="subledger-icon"></fa-icon> Share Entry
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Instruments -->
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Instruments</div>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Draft / Payorder')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="file-signature" class="subledger-icon"></fa-icon> Draft / Payorder
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Passbook Issue')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="book" class="subledger-icon"></fa-icon> Passbook Issue
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Cheque Book')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="credit-card" class="subledger-icon"></fa-icon> Cheque Book
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('DD Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="money-check-alt" class="subledger-icon"></fa-icon> DD Entry
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Deposits -->
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Deposits</div>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('FD / RD Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="piggy-bank" class="subledger-icon"></fa-icon> FD / RD Entry
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('DDS Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="coins" class="subledger-icon"></fa-icon> DDS Entry
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Customer -->
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Customer</div>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesSearch('Client Master')"
|
||||
routerLink="/clients"
|
||||
(click)="subLedgerOpen = false"
|
||||
>
|
||||
<fa-icon icon="user" class="subledger-icon"></fa-icon> Client Master
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Account Master')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="id-card" class="subledger-icon"></fa-icon> Account Master
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Aadhaar Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="address-card" class="subledger-icon"></fa-icon> Aadhaar Entry
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Minor to Major')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="child" class="subledger-icon"></fa-icon> Minor to Major
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Account Status -->
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Account Status</div>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesSearch('Inoperative to Operative')"
|
||||
(click)="subLedgerOpen = false"
|
||||
>
|
||||
<fa-icon icon="lock-open" class="subledger-icon"></fa-icon> Inoperative → Operative
|
||||
</a>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesSearch('Account Status Master')"
|
||||
(click)="subLedgerOpen = false"
|
||||
>
|
||||
<fa-icon icon="cog" class="subledger-icon"></fa-icon> Account Status Master
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Restrict Account')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="ban" class="subledger-icon"></fa-icon> Restrict Account
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Account Death')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="user-slash" class="subledger-icon"></fa-icon> Account Death
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Closed Account')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="times" class="subledger-icon"></fa-icon> Closed Account
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Others -->
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Others</div>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Suit File Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="balance-scale" class="subledger-icon"></fa-icon> Suit File Entry
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Locker Entry')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="lock" class="subledger-icon"></fa-icon> Locker Entry
|
||||
</a>
|
||||
<a class="subledger-link" [class.hidden]="!matchesSearch('Holiday Marking')" (click)="subLedgerOpen = false">
|
||||
<fa-icon icon="calendar" class="subledger-icon"></fa-icon> Holiday Marking
|
||||
</a>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesSearch('Open Closed Register')"
|
||||
(click)="subLedgerOpen = false"
|
||||
>
|
||||
<fa-icon icon="book-open" class="subledger-icon"></fa-icon> Open Closed Register
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- General Ledger Mega Menu -->
|
||||
@if (glMenuOpen) {
|
||||
<div class="subledger-backdrop" (click)="glMenuOpen = false"></div>
|
||||
<div class="subledger-mega-menu">
|
||||
<input
|
||||
type="text"
|
||||
class="subledger-search"
|
||||
placeholder="Search GL reports..."
|
||||
(input)="glSearch = $event.target.value"
|
||||
/>
|
||||
<div class="subledger-columns">
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Financial Statements</div>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('Trial Balance')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="balance-scale" class="subledger-icon"></fa-icon> Trial Balance</a
|
||||
>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('Profit and Loss')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="chart-line" class="subledger-icon"></fa-icon> Profit and Loss</a
|
||||
>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesGlSearch('Consolidate Balance Sheet')"
|
||||
(click)="glMenuOpen = false"
|
||||
><fa-icon icon="file-alt" class="subledger-icon"></fa-icon> Consolidate Balance Sheet</a
|
||||
>
|
||||
</div>
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">GL Reports</div>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('GL Average Balance')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="calculator" class="subledger-icon"></fa-icon> GL Average Balance</a
|
||||
>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesGlSearch('GL Mapping for Report')"
|
||||
(click)="glMenuOpen = false"
|
||||
><fa-icon icon="project-diagram" class="subledger-icon"></fa-icon> GL Mapping for Report</a
|
||||
>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesGlSearch('Account wise Balance List')"
|
||||
(click)="glMenuOpen = false"
|
||||
><fa-icon icon="list" class="subledger-icon"></fa-icon> Account wise Balance List</a
|
||||
>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesGlSearch('Distribution of Balance')"
|
||||
(click)="glMenuOpen = false"
|
||||
><fa-icon icon="chart-pie" class="subledger-icon"></fa-icon> Distribution of Balance</a
|
||||
>
|
||||
</div>
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Account Reports</div>
|
||||
<a
|
||||
class="subledger-link"
|
||||
[class.hidden]="!matchesGlSearch('Client wise Balance Report')"
|
||||
(click)="glMenuOpen = false"
|
||||
><fa-icon icon="users" class="subledger-icon"></fa-icon> Client wise Balance Report</a
|
||||
>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('Contingent Expense')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="exclamation-circle" class="subledger-icon"></fa-icon> Contingent Expense</a
|
||||
>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('Banker Head Report')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="university" class="subledger-icon"></fa-icon> Banker Head Report</a
|
||||
>
|
||||
</div>
|
||||
<div class="subledger-group">
|
||||
<div class="subledger-group-title">Registers</div>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('Sundry Register')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="clipboard-list" class="subledger-icon"></fa-icon> Sundry Register</a
|
||||
>
|
||||
<a class="subledger-link" [class.hidden]="!matchesGlSearch('Voucher Register')" (click)="glMenuOpen = false"
|
||||
><fa-icon icon="receipt" class="subledger-icon"></fa-icon> Voucher Register</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Toolbar Menus -->
|
||||
<mat-menu #reportsMenu="matMenu" [overlapTrigger]="false">
|
||||
|
||||
@@ -7,28 +7,25 @@
|
||||
*/
|
||||
|
||||
#mifosx-toolbar {
|
||||
position: relative;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
pointer-events: none;
|
||||
min-height: 0;
|
||||
height: 44px;
|
||||
padding: 0 4px;
|
||||
|
||||
.tab-nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 1rem;
|
||||
* {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.tab-link {
|
||||
min-width: auto;
|
||||
padding: 15px 0.5rem;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: rgb(255 255 255 / 70%);
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
cursor: pointer;
|
||||
.mat-mdc-icon-button {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.img-button {
|
||||
@@ -39,20 +36,121 @@
|
||||
}
|
||||
}
|
||||
|
||||
.ml-05 {
|
||||
margin-left: 0.35rem;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ml-1 {
|
||||
margin-left: 1rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mr-1 {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
::host-context(.dark-theme) #mifosx-toolbar {
|
||||
// transparent, inherits from sub-menu-bar background
|
||||
}
|
||||
|
||||
.toolbar-spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* Toolbar Deposit Mega Grid */
|
||||
.toolbar-deposit-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px 24px;
|
||||
padding: 8px 12px;
|
||||
min-width: 600px;
|
||||
}
|
||||
|
||||
.toolbar-deposit-group {
|
||||
.toolbar-deposit-title {
|
||||
font-weight: 700;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.6px;
|
||||
color: #1074b9;
|
||||
padding: 4px 16px 6px;
|
||||
margin-bottom: 2px;
|
||||
border-bottom: 2px solid #1074b9;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sub Ledger Mega Menu */
|
||||
.subledger-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.subledger-mega-menu {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #fff;
|
||||
width: 800px;
|
||||
max-width: 95vw;
|
||||
padding: 16px 20px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
||||
border-radius: 0 0 8px 8px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.subledger-search {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #1074b9;
|
||||
}
|
||||
}
|
||||
|
||||
.subledger-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.subledger-group-title {
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 8px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 2px solid #1074b9;
|
||||
}
|
||||
|
||||
.subledger-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 4px;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: #e3f2fd;
|
||||
color: #1074b9;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.subledger-icon {
|
||||
width: 18px;
|
||||
margin-right: 8px;
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,19 @@ export class ToolbarComponent implements OnInit, AfterViewInit, AfterContentChec
|
||||
/** Sets the initial state of sidenav as collapsed. Not collapsed if false. */
|
||||
sidenavCollapsed = true;
|
||||
|
||||
/** Sub Ledger mega menu state */
|
||||
subLedgerOpen = false;
|
||||
subLedgerSearch = '';
|
||||
|
||||
/** General Ledger mega menu state */
|
||||
glMenuOpen = false;
|
||||
glSearch = '';
|
||||
|
||||
matchesGlSearch(label: string): boolean {
|
||||
if (!this.glSearch) return true;
|
||||
return label.toLowerCase().includes(this.glSearch.toLowerCase());
|
||||
}
|
||||
|
||||
/** Instance of sidenav. */
|
||||
@Input() sidenav: MatSidenav;
|
||||
/** Sidenav collapse event. */
|
||||
@@ -251,6 +264,11 @@ export class ToolbarComponent implements OnInit, AfterViewInit, AfterContentChec
|
||||
}
|
||||
}
|
||||
|
||||
matchesSearch(label: string): boolean {
|
||||
if (!this.subLedgerSearch) return true;
|
||||
return label.toLowerCase().includes(this.subLedgerSearch.toLowerCase());
|
||||
}
|
||||
|
||||
navigateMenu(routePath: string): void {
|
||||
this.router.navigate([routePath]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user