merging code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Nitesh Yadav
2026-04-20 14:26:25 +05:30
co-authored by Claude Sonnet 4.6
322 changed files with 28779 additions and 4976 deletions
@@ -44,9 +44,14 @@ $gray-900: #202124;
border-color: $border !important;
color: $gray-500 !important;
i { margin-right: 6px; }
i {
margin-right: 6px;
}
&:hover { color: $primary !important; border-color: $primary !important; }
&:hover {
color: $primary !important;
border-color: $primary !important;
}
}
// Card
@@ -92,7 +97,9 @@ $gray-900: #202124;
gap: 4px 16px;
padding: 16px 24px;
@media (max-width: 600px) { grid-template-columns: 1fr; }
@media (width <= 600px) {
grid-template-columns: 1fr;
}
}
.ar-field {
@@ -128,6 +135,9 @@ $gray-900: #202124;
height: 36px !important;
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
i { margin-right: 6px; font-size: 12px; }
i {
margin-right: 6px;
font-size: 12px;
}
}
}
@@ -48,7 +48,13 @@
<button type="button" mat-stroked-button [routerLink]="['../../']" class="er-actions__cancel">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button type="submit" mat-flat-button color="primary" [disabled]="!roleForm.valid || roleForm.pristine" class="er-actions__submit">
<button
type="submit"
mat-flat-button
color="primary"
[disabled]="!roleForm.valid || roleForm.pristine"
class="er-actions__submit"
>
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
</button>
</div>
@@ -44,9 +44,14 @@ $gray-900: #202124;
border-color: $border !important;
color: $gray-500 !important;
i { margin-right: 6px; }
i {
margin-right: 6px;
}
&:hover { color: $primary !important; border-color: $primary !important; }
&:hover {
color: $primary !important;
border-color: $primary !important;
}
}
// Card
@@ -92,7 +97,9 @@ $gray-900: #202124;
gap: 4px 16px;
padding: 16px 24px;
@media (max-width: 600px) { grid-template-columns: 1fr; }
@media (width <= 600px) {
grid-template-columns: 1fr;
}
}
.er-field {
@@ -128,6 +135,9 @@ $gray-900: #202124;
height: 36px !important;
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
i { margin-right: 6px; font-size: 12px; }
i {
margin-right: 6px;
font-size: 12px;
}
}
}
@@ -19,31 +19,45 @@
</div>
</div>
<div class="vr-topbar__actions">
<button mat-flat-button color="primary" class="vr-btn vr-btn--edit"
<button
mat-flat-button
color="primary"
class="vr-btn vr-btn--edit"
(click)="editRoles(); backupCheckValues()"
[disabled]="rolePermissionService.name === 'Super user'">
[disabled]="rolePermissionService.name === 'Super user'"
>
<fa-icon icon="edit" class="m-r-10"></fa-icon>
{{ 'labels.text.Edit Role' | translate }}
</button>
@if (!isRoleEnable(rolePermissionService.disabled)) {
<button mat-stroked-button class="vr-btn vr-btn--disable"
<button
mat-stroked-button
class="vr-btn vr-btn--disable"
(click)="disableRolesConfirmation()"
[disabled]="rolePermissionService.name === 'Super user'">
[disabled]="rolePermissionService.name === 'Super user'"
>
<fa-icon icon="lock" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Disable' | translate }} {{ 'labels.inputs.Role' | translate }}
</button>
}
@if (isRoleEnable(rolePermissionService.disabled)) {
<button mat-flat-button color="primary" class="vr-btn vr-btn--enable"
<button
mat-flat-button
color="primary"
class="vr-btn vr-btn--enable"
(click)="enableRolesConfirmation()"
[disabled]="rolePermissionService.name === 'Super user'">
[disabled]="rolePermissionService.name === 'Super user'"
>
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Enable' | translate }} {{ 'labels.inputs.Role' | translate }}
</button>
}
<button mat-stroked-button class="vr-btn vr-btn--delete"
<button
mat-stroked-button
class="vr-btn vr-btn--delete"
(click)="deleteRole()"
[disabled]="rolePermissionService.name === 'Super user'">
[disabled]="rolePermissionService.name === 'Super user'"
>
<fa-icon icon="trash" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Delete' | translate }} {{ 'labels.inputs.Role' | translate }}
</button>
@@ -54,7 +68,9 @@
<div class="vr-card">
<div class="vr-card__header">
<i class="fas fa-shield-alt"></i>
<h3>{{ 'labels.buttons.Permissions' | translate }}: <strong>{{ formatName(previousGrouping) }}</strong></h3>
<h3>
{{ 'labels.buttons.Permissions' | translate }}: <strong>{{ formatName(previousGrouping) }}</strong>
</h3>
@if (!isDisabled) {
<div class="vr-card__header-actions">
<button mat-flat-button color="primary" class="vr-btn-sm" (click)="selectAll()">
@@ -77,27 +93,49 @@
<span class="vr-group__name">{{ group.name }}</span>
<span class="vr-group__count">{{ getGroupPermCount(group) }}</span>
@if (!isDisabled) {
<button class="vr-group__select-btn vr-group__select-btn--check" (click)="selectAllGroup(group); $event.stopPropagation()" title="Select all in {{ group.name }}">
<button
class="vr-group__select-btn vr-group__select-btn--check"
(click)="selectAllGroup(group); $event.stopPropagation()"
title="Select all in {{ group.name }}"
>
<i class="fas fa-check-double"></i>
</button>
<button class="vr-group__select-btn vr-group__select-btn--clear" (click)="deselectAllGroup(group); $event.stopPropagation()" title="Deselect all in {{ group.name }}">
<button
class="vr-group__select-btn vr-group__select-btn--clear"
(click)="deselectAllGroup(group); $event.stopPropagation()"
title="Deselect all in {{ group.name }}"
>
<i class="fas fa-times"></i>
</button>
}
<i class="fas vr-group__chevron" [class.fa-chevron-down]="group.expanded" [class.fa-chevron-right]="!group.expanded"></i>
<i
class="fas vr-group__chevron"
[class.fa-chevron-down]="group.expanded"
[class.fa-chevron-right]="!group.expanded"
></i>
</div>
@if (group.expanded) {
<div class="vr-group__items">
@for (cat of group.categories; track cat) {
<div class="vr-category-item"
<div
class="vr-category-item"
[class.vr-category-item--active]="selectedItem === cat"
(click)="showPermissions(cat)">
(click)="showPermissions(cat)"
>
<span class="vr-category-item__name">{{ formatName(cat) }}</span>
@if (!isDisabled) {
<button class="vr-category-item__sel" (click)="selectAllCategory(cat); $event.stopPropagation()" title="Select all">
<button
class="vr-category-item__sel"
(click)="selectAllCategory(cat); $event.stopPropagation()"
title="Select all"
>
<i class="fas fa-check"></i>
</button>
<button class="vr-category-item__desel" (click)="deselectAllCategory(cat); $event.stopPropagation()" title="Deselect all">
<button
class="vr-category-item__desel"
(click)="deselectAllCategory(cat); $event.stopPropagation()"
title="Deselect all"
>
<i class="fas fa-times"></i>
</button>
}
@@ -113,20 +151,33 @@
<!-- Permission Checkboxes (Right) -->
<div class="vr-checkboxes">
<form [formGroup]="formGroup" (submit)="submit()">
<!-- Sub-grouped view for large categories -->
@if (permissionSubGroups.length > 0) {
@for (subGroup of permissionSubGroups; track subGroup.entity) {
<div class="vr-subgroup">
<div class="vr-subgroup__header" (click)="toggleSubGroup(subGroup)">
<i class="fas" [class.fa-chevron-down]="subGroup.expanded" [class.fa-chevron-right]="!subGroup.expanded"></i>
<i
class="fas"
[class.fa-chevron-down]="subGroup.expanded"
[class.fa-chevron-right]="!subGroup.expanded"
></i>
<span class="vr-subgroup__name">{{ getEntityDisplayName(subGroup.entity) }}</span>
<span class="vr-subgroup__count">{{ getSubGroupCount(subGroup) }}</span>
@if (!isDisabled) {
<button type="button" class="vr-subgroup__select" (click)="selectAllSubGroup(subGroup); $event.stopPropagation()" title="Select all">
<button
type="button"
class="vr-subgroup__select"
(click)="selectAllSubGroup(subGroup); $event.stopPropagation()"
title="Select all"
>
<i class="fas fa-check-double"></i>
</button>
<button type="button" class="vr-subgroup__deselect" (click)="deselectAllSubGroup(subGroup); $event.stopPropagation()" title="Deselect all">
<button
type="button"
class="vr-subgroup__deselect"
(click)="deselectAllSubGroup(subGroup); $event.stopPropagation()"
title="Deselect all"
>
<i class="fas fa-times"></i>
</button>
}
@@ -137,10 +188,20 @@
<div class="vr-subgroup__col-label">
<span>Maker</span>
@if (!isDisabled && subGroup.makerPerms.length > 0) {
<button type="button" class="vr-col-btn vr-col-btn--select" (click)="selectAllMaker(subGroup.makerPerms)" title="Select all maker">
<button
type="button"
class="vr-col-btn vr-col-btn--select"
(click)="selectAllMaker(subGroup.makerPerms)"
title="Select all maker"
>
<i class="fas fa-check"></i> All
</button>
<button type="button" class="vr-col-btn vr-col-btn--clear" (click)="deselectAllMaker(subGroup.makerPerms)" title="Deselect all maker">
<button
type="button"
class="vr-col-btn vr-col-btn--clear"
(click)="deselectAllMaker(subGroup.makerPerms)"
title="Deselect all maker"
>
<i class="fas fa-times"></i>
</button>
}
@@ -162,10 +223,20 @@
<div class="vr-subgroup__col-label vr-subgroup__col-label--checker">
<span>Checker</span>
@if (!isDisabled && subGroup.checkerPerms.length > 0) {
<button type="button" class="vr-col-btn vr-col-btn--select-warn" (click)="selectAllChecker(subGroup.checkerPerms)" title="Select all checker">
<button
type="button"
class="vr-col-btn vr-col-btn--select-warn"
(click)="selectAllChecker(subGroup.checkerPerms)"
title="Select all checker"
>
<i class="fas fa-check"></i> All
</button>
<button type="button" class="vr-col-btn vr-col-btn--clear" (click)="deselectAllChecker(subGroup.checkerPerms)" title="Deselect all checker">
<button
type="button"
class="vr-col-btn vr-col-btn--clear"
(click)="deselectAllChecker(subGroup.checkerPerms)"
title="Deselect all checker"
>
<i class="fas fa-times"></i>
</button>
}
@@ -194,10 +265,20 @@
<div class="vr-flat-col__label">
<span>Maker</span>
@if (!isDisabled && flatMakerPerms.length > 0) {
<button type="button" class="vr-col-btn vr-col-btn--select" (click)="selectAllMaker(flatMakerPerms)" title="Select all maker">
<button
type="button"
class="vr-col-btn vr-col-btn--select"
(click)="selectAllMaker(flatMakerPerms)"
title="Select all maker"
>
<i class="fas fa-check"></i> All
</button>
<button type="button" class="vr-col-btn vr-col-btn--clear" (click)="deselectAllMaker(flatMakerPerms)" title="Deselect all">
<button
type="button"
class="vr-col-btn vr-col-btn--clear"
(click)="deselectAllMaker(flatMakerPerms)"
title="Deselect all"
>
<i class="fas fa-times"></i>
</button>
}
@@ -216,10 +297,20 @@
<div class="vr-flat-col__label vr-flat-col__label--checker">
<span>Checker</span>
@if (!isDisabled && flatCheckerPerms.length > 0) {
<button type="button" class="vr-col-btn vr-col-btn--select-warn" (click)="selectAllChecker(flatCheckerPerms)" title="Select all checker">
<button
type="button"
class="vr-col-btn vr-col-btn--select-warn"
(click)="selectAllChecker(flatCheckerPerms)"
title="Select all checker"
>
<i class="fas fa-check"></i> All
</button>
<button type="button" class="vr-col-btn vr-col-btn--clear" (click)="deselectAllChecker(flatCheckerPerms)" title="Deselect all">
<button
type="button"
class="vr-col-btn vr-col-btn--clear"
(click)="deselectAllChecker(flatCheckerPerms)"
title="Deselect all"
>
<i class="fas fa-times"></i>
</button>
}
@@ -239,14 +330,18 @@
</div>
</div>
}
</form>
</div>
</div>
@if (!isDisabled) {
<div class="vr-card__footer">
<button type="button" mat-stroked-button class="vr-btn-action vr-btn-action--cancel" (click)="cancel(); restoreCheckboxes()">
<button
type="button"
mat-stroked-button
class="vr-btn-action vr-btn-action--cancel"
(click)="cancel(); restoreCheckboxes()"
>
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button mat-flat-button color="primary" class="vr-btn-action vr-btn-action--submit" (click)="submit()">
@@ -199,7 +199,9 @@ $gray-900: #202124;
.vr-group {
border-bottom: 1px solid #f1f3f5;
&:last-child { border-bottom: none; }
&:last-child {
border-bottom: none;
}
&__header {
display: flex;
@@ -210,7 +212,9 @@ $gray-900: #202124;
transition: background 0.15s;
user-select: none;
&:hover { background: #f0f4f8; }
&:hover {
background: #f0f4f8;
}
}
&__icon {
@@ -257,12 +261,21 @@ $gray-900: #202124;
&--check {
color: $accent;
&:hover { background: rgba($accent, 0.1); border-color: $accent; }
&:hover {
background: rgba($accent, 0.1);
border-color: $accent;
}
}
&--clear {
color: $gray-500;
&:hover { background: rgba(#ef4444, 0.05); border-color: #ef4444; color: #ef4444; }
&:hover {
background: rgba(#ef4444, 0.05);
border-color: #ef4444;
color: #ef4444;
}
}
}
@@ -297,7 +310,8 @@ $gray-900: #202124;
text-overflow: ellipsis;
}
&__sel, &__desel {
&__sel,
&__desel {
background: none;
border: 1px solid transparent;
border-radius: 3px;
@@ -313,16 +327,28 @@ $gray-900: #202124;
transition: all 0.15s;
}
&:hover &__sel, &:hover &__desel { opacity: 1; }
&:hover &__sel,
&:hover &__desel {
opacity: 1;
}
&__sel {
color: $accent;
&:hover { background: rgba($accent, 0.1); border-color: $accent; }
&:hover {
background: rgba($accent, 0.1);
border-color: $accent;
}
}
&__desel {
color: $gray-500;
&:hover { background: rgba(#ef4444, 0.05); border-color: #ef4444; color: #ef4444; }
&:hover {
background: rgba(#ef4444, 0.05);
border-color: #ef4444;
color: #ef4444;
}
}
&__count {
@@ -371,7 +397,9 @@ $gray-900: #202124;
overflow: hidden;
grid-column: 1 / -1;
& + & { margin-top: 6px; }
& + & {
margin-top: 6px;
}
&__header {
display: flex;
@@ -383,9 +411,15 @@ $gray-900: #202124;
transition: background 0.15s;
user-select: none;
&:hover { background: #f0f4f8; }
&:hover {
background: #f0f4f8;
}
> i { font-size: 9px; color: $gray-500; width: 12px; }
> i {
font-size: 9px;
color: $gray-500;
width: 12px;
}
}
&__name {
@@ -405,7 +439,8 @@ $gray-900: #202124;
flex-shrink: 0;
}
&__select, &__deselect {
&__select,
&__deselect {
background: none;
border: 1px solid $border;
border-radius: 4px;
@@ -422,12 +457,21 @@ $gray-900: #202124;
&__select {
color: $accent;
&:hover { background: rgba($accent, 0.1); border-color: $accent; }
&:hover {
background: rgba($accent, 0.1);
border-color: $accent;
}
}
&__deselect {
color: $gray-500;
&:hover { background: rgba(#ef4444, 0.05); border-color: #ef4444; color: #ef4444; }
&:hover {
background: rgba(#ef4444, 0.05);
border-color: #ef4444;
color: #ef4444;
}
}
&__columns {
@@ -458,9 +502,13 @@ $gray-900: #202124;
border-bottom: 1px solid #f1f3f5;
margin-bottom: 4px;
span { flex: 1; }
span {
flex: 1;
}
&--checker { color: #f59e0b; }
&--checker {
color: #f59e0b;
}
}
&__empty {
@@ -488,17 +536,30 @@ $gray-900: #202124;
&--select {
color: $accent;
&:hover { background: rgba($accent, 0.1); border-color: $accent; }
&:hover {
background: rgba($accent, 0.1);
border-color: $accent;
}
}
&--select-warn {
color: #f59e0b;
&:hover { background: rgba(#f59e0b, 0.1); border-color: #f59e0b; }
&:hover {
background: rgba(#f59e0b, 0.1);
border-color: #f59e0b;
}
}
&--clear {
color: $gray-500;
&:hover { background: rgba(#ef4444, 0.05); border-color: #ef4444; color: #ef4444; }
&:hover {
background: rgba(#ef4444, 0.05);
border-color: #ef4444;
color: #ef4444;
}
}
}
@@ -531,9 +592,13 @@ $gray-900: #202124;
border-bottom: 1px solid #f1f3f5;
margin-bottom: 4px;
span { flex: 1; }
span {
flex: 1;
}
&--checker { color: #f59e0b; }
&--checker {
color: #f59e0b;
}
}
}
@@ -579,12 +644,15 @@ $gray-900: #202124;
&--submit {
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
i { margin-right: 6px; font-size: 12px; }
i {
margin-right: 6px;
font-size: 12px;
}
}
}
// Responsive
@media (max-width: 768px) {
@media (width <= 768px) {
.vr-topbar {
flex-direction: column;
align-items: flex-start;
@@ -64,49 +64,49 @@ export class ViewRoleComponent implements OnInit {
/** Mapping of category groupings to role groups */
private categoryToGroupMap: { [key: string]: string } = {
// Special & Authorisation
'special': 'Special & Authorisation',
'authorisation': 'Special & Authorisation',
special: 'Special & Authorisation',
authorisation: 'Special & Authorisation',
// Configuration & Admin
'configuration': 'Configuration & Admin',
'organisation': 'Configuration & Admin',
'datatable': 'Configuration & Admin',
'jobs': 'Configuration & Admin',
configuration: 'Configuration & Admin',
organisation: 'Configuration & Admin',
datatable: 'Configuration & Admin',
jobs: 'Configuration & Admin',
// Portfolio — Client, Loan, Savings, FD, RD, Guarantor etc.
'portfolio': 'Portfolio',
'portfolio_group': 'Portfolio — Groups & Centers',
'portfolio_center': 'Portfolio — Groups & Centers',
portfolio: 'Portfolio',
portfolio_group: 'Portfolio — Groups & Centers',
portfolio_center: 'Portfolio — Groups & Centers',
// Transactions
'transaction_loan': 'Transactions — Loan',
'transaction_savings': 'Transactions — Savings',
'transaction_shareaccount': 'Transactions — Share Account',
transaction_loan: 'Transactions — Loan',
transaction_savings: 'Transactions — Savings',
transaction_shareaccount: 'Transactions — Share Account',
// Accounting & Finance
'accounting': 'Accounting & Finance',
'loan_provisioning': 'Accounting & Finance',
'loan_reschedule': 'Accounting & Finance',
accounting: 'Accounting & Finance',
loan_provisioning: 'Accounting & Finance',
loan_reschedule: 'Accounting & Finance',
// Cash Management
'cash_mgmt': 'Cash Management',
cash_mgmt: 'Cash Management',
// Reporting
'report': 'Reporting & Analytics',
report: 'Reporting & Analytics',
// Share Account
'shareaccount': 'Share Account',
shareaccount: 'Share Account',
// Heading Menu (Top Navigation Bar)
'heading_menu': 'Heading Menu',
heading_menu: 'Heading Menu',
// Left Panel Menu (Sidebar)
'sidebar_menu': 'Left Panel Menu',
sidebar_menu: 'Left Panel Menu'
};
private groupIcons: { [key: string]: string } = {
'Special & Authorisation': 'fa-star',
'Configuration & Admin': 'fa-cog',
'Portfolio': 'fa-briefcase',
Portfolio: 'fa-briefcase',
'Portfolio — Groups & Centers': 'fa-users',
'Transactions — Loan': 'fa-exchange-alt',
'Transactions — Savings': 'fa-piggy-bank',
@@ -116,7 +116,7 @@ export class ViewRoleComponent implements OnInit {
'Reporting & Analytics': 'fa-chart-bar',
'Share Account': 'fa-chart-pie',
'Heading Menu': 'fa-th-list',
'Left Panel Menu': 'fa-bars',
'Left Panel Menu': 'fa-bars'
};
/** Checks if its disabled */
isDisabled: Boolean = true;
@@ -264,8 +264,8 @@ export class ViewRoleComponent implements OnInit {
'Other'
];
this.roleGroups = order
.filter(name => groupMap[name])
.map(name => ({
.filter((name) => groupMap[name])
.map((name) => ({
name,
icon: this.groupIcons[name] || 'fa-folder',
categories: groupMap[name],
@@ -327,45 +327,79 @@ export class ViewRoleComponent implements OnInit {
/** Entity display names */
private entityNames: { [key: string]: string } = {
'CLIENT': 'Client', 'CLIENTIMAGE': 'Client Image', 'CLIENTIDENTIFIER': 'Client Identifier',
'CLIENTNOTE': 'Client Note', 'CLIENTCHARGE': 'Client Charge',
'LOAN': 'Loan', 'LOANNOTE': 'Loan Note', 'LOANCHARGE': 'Loan Charge',
'LOANTRANSACTIONNOTE': 'Loan Transaction Note',
'SAVINGSACCOUNT': 'Savings Account', 'SAVINGSACCOUNTCHARGE': 'Savings Account Charge',
'SAVINGNOTE': 'Savings Note',
'FIXEDDEPOSITACCOUNT': 'Fixed Deposit Account',
'RECURRINGDEPOSITACCOUNT': 'Recurring Deposit Account',
'SHAREACCOUNT': 'Share Account',
'GROUP': 'Group', 'GROUPNOTE': 'Group Note',
'CENTER': 'Center',
'GUARANTOR': 'Guarantor', 'COLLATERAL': 'Collateral', 'DOCUMENT': 'Document',
'ACCOUNTTRANSFER': 'Account Transfer', 'STANDINGINSTRUCTION': 'Standing Instruction',
'RESCHEDULELOAN': 'Reschedule Loan',
'JOURNALENTRY': 'Journal Entry',
'TELLER': 'Teller', 'CASHIER': 'Cashier',
'ROLE': 'Role', 'USER': 'User', 'PERMISSION': 'Permission',
'CODE': 'Code', 'CODEVALUE': 'Code Value',
'OFFICE': 'Office', 'OFFICETRANSACTION': 'Office Transaction',
'STAFF': 'Staff', 'STAFFIMAGE': 'Staff Image',
'CHARGE': 'Charge', 'FUND': 'Fund',
'LOANPRODUCT': 'Loan Product', 'SAVINGSPRODUCT': 'Savings Product',
'FIXEDDEPOSITPRODUCT': 'Fixed Deposit Product', 'RECURRINGDEPOSITPRODUCT': 'Recurring Deposit Product',
'SHAREPRODUCT': 'Share Product',
'CURRENCY': 'Currency', 'DATATABLE': 'Data Table', 'CALENDAR': 'Calendar',
'CONFIGURATION': 'Configuration', 'AUDIT': 'Audit',
'REPORT': 'Report', 'HOOK': 'Hook', 'TEMPLATE': 'Template',
'PAYMENTTYPE': 'Payment Type', 'HOLIDAY': 'Holiday', 'WORKINGDAYS': 'Working Days',
'GLACCOUNT': 'GL Account', 'GLCLOSURE': 'GL Closure',
'FINANCIALACTIVITYACCOUNT': 'Financial Activity Account',
'TAXCOMPONENT': 'Tax Component', 'TAXGROUP': 'Tax Group',
'PRODUCTMIX': 'Product Mix', 'EXTERNALSERVICES': 'External Services',
'SCHEDULER': 'Scheduler', 'MEETING': 'Meeting',
'INTERESTRATECHART': 'Interest Rate Chart', 'FLOATINGRATE': 'Floating Rate',
'ACCOUNTNUMBERFORMAT': 'Account Number Format', 'ACCOUNTINGRULE': 'Accounting Rule',
'ENTITYMAPPING': 'Entity Mapping', 'PROVISION': 'Provisioning',
'REPORTMAILINGJOB': 'Report Mailing Job',
'PASSWORD_PREFERENCES': 'Password Preferences', 'ADDRESS': 'Address',
'CACHE': 'Cache',
CLIENT: 'Client',
CLIENTIMAGE: 'Client Image',
CLIENTIDENTIFIER: 'Client Identifier',
CLIENTNOTE: 'Client Note',
CLIENTCHARGE: 'Client Charge',
LOAN: 'Loan',
LOANNOTE: 'Loan Note',
LOANCHARGE: 'Loan Charge',
LOANTRANSACTIONNOTE: 'Loan Transaction Note',
SAVINGSACCOUNT: 'Savings Account',
SAVINGSACCOUNTCHARGE: 'Savings Account Charge',
SAVINGNOTE: 'Savings Note',
FIXEDDEPOSITACCOUNT: 'Fixed Deposit Account',
RECURRINGDEPOSITACCOUNT: 'Recurring Deposit Account',
SHAREACCOUNT: 'Share Account',
GROUP: 'Group',
GROUPNOTE: 'Group Note',
CENTER: 'Center',
GUARANTOR: 'Guarantor',
COLLATERAL: 'Collateral',
DOCUMENT: 'Document',
ACCOUNTTRANSFER: 'Account Transfer',
STANDINGINSTRUCTION: 'Standing Instruction',
RESCHEDULELOAN: 'Reschedule Loan',
JOURNALENTRY: 'Journal Entry',
TELLER: 'Teller',
CASHIER: 'Cashier',
ROLE: 'Role',
USER: 'User',
PERMISSION: 'Permission',
CODE: 'Code',
CODEVALUE: 'Code Value',
OFFICE: 'Office',
OFFICETRANSACTION: 'Office Transaction',
STAFF: 'Staff',
STAFFIMAGE: 'Staff Image',
CHARGE: 'Charge',
FUND: 'Fund',
LOANPRODUCT: 'Loan Product',
SAVINGSPRODUCT: 'Savings Product',
FIXEDDEPOSITPRODUCT: 'Fixed Deposit Product',
RECURRINGDEPOSITPRODUCT: 'Recurring Deposit Product',
SHAREPRODUCT: 'Share Product',
CURRENCY: 'Currency',
DATATABLE: 'Data Table',
CALENDAR: 'Calendar',
CONFIGURATION: 'Configuration',
AUDIT: 'Audit',
REPORT: 'Report',
HOOK: 'Hook',
TEMPLATE: 'Template',
PAYMENTTYPE: 'Payment Type',
HOLIDAY: 'Holiday',
WORKINGDAYS: 'Working Days',
GLACCOUNT: 'GL Account',
GLCLOSURE: 'GL Closure',
FINANCIALACTIVITYACCOUNT: 'Financial Activity Account',
TAXCOMPONENT: 'Tax Component',
TAXGROUP: 'Tax Group',
PRODUCTMIX: 'Product Mix',
EXTERNALSERVICES: 'External Services',
SCHEDULER: 'Scheduler',
MEETING: 'Meeting',
INTERESTRATECHART: 'Interest Rate Chart',
FLOATINGRATE: 'Floating Rate',
ACCOUNTNUMBERFORMAT: 'Account Number Format',
ACCOUNTINGRULE: 'Accounting Rule',
ENTITYMAPPING: 'Entity Mapping',
PROVISION: 'Provisioning',
REPORTMAILINGJOB: 'Report Mailing Job',
PASSWORD_PREFERENCES: 'Password Preferences',
ADDRESS: 'Address',
CACHE: 'Cache'
};
/**
@@ -374,25 +408,83 @@ export class ViewRoleComponent implements OnInit {
private extractEntity(code: string): string {
// Common action prefixes to strip
const actions = [
'CREATE', 'READ', 'UPDATE', 'DELETE', 'APPROVE', 'REJECT', 'ACTIVATE', 'DEACTIVATE',
'CLOSE', 'DEPOSIT', 'WITHDRAWAL', 'WITHDRAW', 'DISBURSE', 'DISBURSETOSAVINGS',
'DISBURSALUNDO', 'DISBURSALLASTUNDO', 'REPAYMENT', 'ADJUST', 'WAIVE', 'WAIVEINTERESTPORTION',
'WRITEOFF', 'UNDOWRITEOFF', 'UNDOAPPROVAL', 'UNDOTRANSACTION', 'UNDO',
'CLOSEASRESCHEDULED', 'FORECLOSURE', 'REOPEN', 'REACTIVATE',
'POSTINTEREST', 'CALCULATEINTEREST', 'APPLYANNUALFEE', 'PREMATURECLOSE',
'UPDATEDEPOSITAMOUNT', 'WITHDRAWWITHHELD', 'UPDATELOANOFFICER', 'REMOVELOANOFFICER',
'BULKREASSIGN', 'REFUNDBYCASH', 'REFUNDBYTRANSFER',
'RECOVERGUARANTEES', 'RECOVERYPAYMENT',
'CREATESCHEDULEEXCEPTIONS', 'DELETESCHEDULEEXCEPTIONS',
'UPDATERUNNINGBALANCE', 'DEFINEOPENINGBALANCE', 'REVERSE',
'REGISTER', 'DEREGISTER', 'ENABLE', 'DISABLE', 'PERMISSIONS',
'INACTIVATE', 'PAY', 'PROPOSETRANSFER', 'ACCEPTTRANSFER', 'REJECTTRANSFER',
'WITHDRAWTRANSFER', 'ASSIGNSTAFF', 'UNASSIGNSTAFF', 'ASSIGNROLE', 'UPDATEROLE',
'DISASSOCIATECLIENTS', 'ASSOCIATECLIENTS', 'TRANSFERCLIENTS',
'ASSOCIATEGROUPS', 'DISASSOCIATEGROUPS',
'ALLOCATECASHIER', 'ALLOCATECASHTOCASHIER', 'SETTLECASHFROMCASHIER',
'EXECUTEJOB', 'EXECUTE', 'DIVIDEND',
'APPLYADDITIONALSHARES', 'APPROVEADDITIONALSHARES', 'REJECTADDITIONALSHARES', 'REDEEMSHARES',
'CREATE',
'READ',
'UPDATE',
'DELETE',
'APPROVE',
'REJECT',
'ACTIVATE',
'DEACTIVATE',
'CLOSE',
'DEPOSIT',
'WITHDRAWAL',
'WITHDRAW',
'DISBURSE',
'DISBURSETOSAVINGS',
'DISBURSALUNDO',
'DISBURSALLASTUNDO',
'REPAYMENT',
'ADJUST',
'WAIVE',
'WAIVEINTERESTPORTION',
'WRITEOFF',
'UNDOWRITEOFF',
'UNDOAPPROVAL',
'UNDOTRANSACTION',
'UNDO',
'CLOSEASRESCHEDULED',
'FORECLOSURE',
'REOPEN',
'REACTIVATE',
'POSTINTEREST',
'CALCULATEINTEREST',
'APPLYANNUALFEE',
'PREMATURECLOSE',
'UPDATEDEPOSITAMOUNT',
'WITHDRAWWITHHELD',
'UPDATELOANOFFICER',
'REMOVELOANOFFICER',
'BULKREASSIGN',
'REFUNDBYCASH',
'REFUNDBYTRANSFER',
'RECOVERGUARANTEES',
'RECOVERYPAYMENT',
'CREATESCHEDULEEXCEPTIONS',
'DELETESCHEDULEEXCEPTIONS',
'UPDATERUNNINGBALANCE',
'DEFINEOPENINGBALANCE',
'REVERSE',
'REGISTER',
'DEREGISTER',
'ENABLE',
'DISABLE',
'PERMISSIONS',
'INACTIVATE',
'PAY',
'PROPOSETRANSFER',
'ACCEPTTRANSFER',
'REJECTTRANSFER',
'WITHDRAWTRANSFER',
'ASSIGNSTAFF',
'UNASSIGNSTAFF',
'ASSIGNROLE',
'UPDATEROLE',
'DISASSOCIATECLIENTS',
'ASSOCIATECLIENTS',
'TRANSFERCLIENTS',
'ASSOCIATEGROUPS',
'DISASSOCIATEGROUPS',
'ALLOCATECASHIER',
'ALLOCATECASHTOCASHIER',
'SETTLECASHFROMCASHIER',
'EXECUTEJOB',
'EXECUTE',
'DIVIDEND',
'APPLYADDITIONALSHARES',
'APPROVEADDITIONALSHARES',
'REJECTADDITIONALSHARES',
'REDEEMSHARES'
];
// Try to match action_entity pattern
@@ -416,8 +508,8 @@ export class ViewRoleComponent implements OnInit {
*/
buildFlatMakerChecker() {
const perms = this.permissions.permissions;
this.flatMakerPerms = perms.filter(p => !this.isChecker(p.code));
this.flatCheckerPerms = perms.filter(p => this.isChecker(p.code));
this.flatMakerPerms = perms.filter((p) => !this.isChecker(p.code));
this.flatCheckerPerms = perms.filter((p) => this.isChecker(p.code));
}
/**
@@ -432,7 +524,9 @@ export class ViewRoleComponent implements OnInit {
return;
}
const groups: { [entity: string]: { maker: { code: string; id: number }[]; checker: { code: string; id: number }[] } } = {};
const groups: {
[entity: string]: { maker: { code: string; id: number }[]; checker: { code: string; id: number }[] };
} = {};
for (const p of perms) {
const entity = this.extractEntity(p.code);
if (!groups[entity]) {
@@ -445,7 +539,7 @@ export class ViewRoleComponent implements OnInit {
}
}
this.permissionSubGroups = Object.keys(groups).map(entity => ({
this.permissionSubGroups = Object.keys(groups).map((entity) => ({
entity,
makerPerms: groups[entity].maker,
checkerPerms: groups[entity].checker,
@@ -463,14 +557,20 @@ export class ViewRoleComponent implements OnInit {
selectAllSubGroup(subGroup: any) {
const roster = this.formGroup.get('roster') as FormArray;
for (const p of [...subGroup.makerPerms, ...subGroup.checkerPerms]) {
for (const p of [
...subGroup.makerPerms,
...subGroup.checkerPerms
]) {
roster.at(p.id).patchValue({ selected: true });
}
}
deselectAllSubGroup(subGroup: any) {
const roster = this.formGroup.get('roster') as FormArray;
for (const p of [...subGroup.makerPerms, ...subGroup.checkerPerms]) {
for (const p of [
...subGroup.makerPerms,
...subGroup.checkerPerms
]) {
roster.at(p.id).patchValue({ selected: false });
}
}
@@ -495,7 +595,11 @@ export class ViewRoleComponent implements OnInit {
selectAllChecker(perms: { code: string; id: number }[]) {
const dialogRef = this.dialog.open(EnableDialogComponent, {
data: { enableContext: this.translateService.instant('labels.text.all Checker permissions for this section. This grants approval authority') }
data: {
enableContext: this.translateService.instant(
'labels.text.all Checker permissions for this section. This grants approval authority'
)
}
});
dialogRef.afterClosed().subscribe((response: any) => {
if (response?.enable) {