feat: non-individual entity UI improvements — hide individual-only sections, fix legal form display, send extended fields to API
- Hide Family Members tab/section for non-individual entities in client view, create flow, and preview - Hide Financial & Classification section for non-individual entities in personal data and preview - Fix legal form column in clients list — fetch legalForm from client API for correct display - Add person/business icon before client name in list rows - Remove unsupportedNpd filter — send authorizedSignatory, additionalInfo, dateOfRegistration to API - Add registration number format hint (mat-hint) based on constitution type - Add spacing between verification row and constitution type dropdowns - Reduce table cell padding and prevent action buttons from being clipped - Add missing MPL-2.0 license headers 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
ab01111424
commit
b890d24bb7
+89
-83
@@ -6,9 +6,10 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="tab-container mat-typography">
|
||||
<div class="search-row">
|
||||
<mat-form-field class="search-field">
|
||||
<div class="cv-tab-content">
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'labels.text.Search by user' | translate }}"
|
||||
@@ -18,7 +19,7 @@
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="toggleAdvancedSearch()"
|
||||
class="icon-button"
|
||||
class="cv-toggle-btn"
|
||||
[attr.aria-label]="
|
||||
showAdvancedSearch
|
||||
? ('labels.buttons.Hide advanced search' | translate)
|
||||
@@ -28,20 +29,23 @@
|
||||
>
|
||||
<mat-icon>{{ showAdvancedSearch ? 'arrow_drop_up' : 'arrow_drop_down' }}</mat-icon>
|
||||
</button>
|
||||
<button mat-raised-button class="mat-success tasks-action-btn" (click)="approveChecker()">
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="warn" (click)="deleteChecker()" class="action-button">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button class="mat-reject tasks-action-btn" (click)="rejectChecker()">
|
||||
<fa-icon icon="times" class="m-r-10"></fa-icon>{{ 'labels.buttons.Reject' | translate }}
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button mat-stroked-button class="cv-btn cv-btn-approve" (click)="approveChecker()">
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="cv-btn cv-btn-delete" (click)="deleteChecker()">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="cv-btn cv-btn-reject" (click)="rejectChecker()">
|
||||
<fa-icon icon="times" class="m-r-10"></fa-icon>{{ 'labels.buttons.Reject' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (showAdvancedSearch) {
|
||||
<form [formGroup]="makerCheckerSearchForm">
|
||||
<div class="advanced-search-container">
|
||||
<mat-form-field class="search-field" (click)="makerDateTimeFromPicker.open()">
|
||||
<div class="cv-advanced-search">
|
||||
<mat-form-field appearance="outline" class="cv-adv-field" (click)="makerDateTimeFromPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -53,7 +57,7 @@
|
||||
<mat-datepicker-toggle matSuffix [for]="makerDateTimeFromPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #makerDateTimeFromPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="search-field" (click)="makerDateTimetoPicker.open()">
|
||||
<mat-form-field appearance="outline" class="cv-adv-field" (click)="makerDateTimetoPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -65,7 +69,7 @@
|
||||
<mat-datepicker-toggle matSuffix [for]="makerDateTimetoPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #makerDateTimetoPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="search-field">
|
||||
<mat-form-field appearance="outline" class="cv-adv-field">
|
||||
<mat-label>{{ 'labels.inputs.Select action' | translate }}</mat-label>
|
||||
<mat-select formControlName="actionName">
|
||||
@for (action of makerCheckerTemplate.actionNames; track action) {
|
||||
@@ -75,7 +79,7 @@
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="search-field">
|
||||
<mat-form-field appearance="outline" class="cv-adv-field">
|
||||
<mat-label>{{ 'labels.inputs.Select entity' | translate }}</mat-label>
|
||||
<mat-select formControlName="entityName">
|
||||
@for (entity of makerCheckerTemplate.entityNames; track entity) {
|
||||
@@ -85,86 +89,88 @@
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="search-field">
|
||||
<mat-form-field appearance="outline" class="cv-adv-field">
|
||||
<mat-label>{{ 'labels.inputs.Resource id' | translate }}</mat-label>
|
||||
<input matInput formControlName="resourceId" />
|
||||
</mat-form-field>
|
||||
<button mat-raised-button color="primary" id="search-button" type="button" (click)="search()">
|
||||
<button mat-flat-button color="primary" class="cv-btn cv-btn-search" type="button" (click)="search()">
|
||||
<fa-icon icon="search" class="m-r-10"></fa-icon>{{ 'labels.buttons.Advanced Search' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
|
||||
@if (checkerData && !noSearchedData) {
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
[aria-label]="checkboxLabel()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.ID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="madeOnDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Made on Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.madeOnDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Status' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.processingResult }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="user">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.User' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.maker }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="action">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Action' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.actionName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="entity">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Entity' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.entityName }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr
|
||||
mat-row
|
||||
*matRowDef="let row; columns: displayedColumns"
|
||||
[routerLink]="[row.id, 'view']"
|
||||
class="select-row"
|
||||
></tr>
|
||||
</table>
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" class="modern-table">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
[aria-label]="checkboxLabel()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.ID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker" class="cell-mono">{{ makerChecker.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="madeOnDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Made on Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.madeOnDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Status' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">
|
||||
<span class="status-badge">{{ makerChecker.processingResult }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="user">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.User' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.maker }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="action">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Action' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.actionName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="entity">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Entity' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let makerChecker">{{ makerChecker.entityName }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr
|
||||
mat-row
|
||||
*matRowDef="let row; columns: displayedColumns"
|
||||
[routerLink]="[row.id, 'view']"
|
||||
class="table-row"
|
||||
></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (checkerData && noSearchedData) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check fa-2x"></i>
|
||||
{{ 'labels.text.No checker inbox data available for this search' | translate }}
|
||||
</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No checker inbox data available for this search' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!checkerData) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check fa-2x"></i>
|
||||
{{ 'labels.text.No checker inbox data available for this account' | translate }}
|
||||
</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No checker inbox data available for this account' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
+166
-164
@@ -6,185 +6,187 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
::ng-deep mat-form-field {
|
||||
width: 280px;
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
$brand: #1353a0;
|
||||
$border: #e2e8f0;
|
||||
$text: #0f172a;
|
||||
$text-muted: #64748b;
|
||||
|
||||
.cv-tab-content {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
// Action bar
|
||||
.cv-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 320px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-form-field-flex { height: 36px; }
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding: 6px 0;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.mat-mdc-text-field-wrapper {
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
.mdc-notched-outline {
|
||||
.mdc-notched-outline__leading { border-radius: 8px 0 0 8px; }
|
||||
.mdc-notched-outline__trailing { border-radius: 0 8px 8px 0; }
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-flex {
|
||||
width: 100%;
|
||||
.mat-mdc-form-field-icon-prefix {
|
||||
padding: 0 6px 0 8px;
|
||||
color: $text-muted;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
input {
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .mat-mdc-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::ng-deep .mat-mdc-select-trigger {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button.mat-mdc-raised-button {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
button.mat-mdc-icon-button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 0;
|
||||
background: #232323;
|
||||
color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow:
|
||||
0 2px 2px 0 rgb(0 0 0 / 14%),
|
||||
0 1px 5px 0 rgb(0 0 0 / 12%),
|
||||
0 3px 1px -2px rgb(0 0 0 / 20%);
|
||||
}
|
||||
|
||||
:host-context(.dark-theme) button.mat-mdc-icon-button {
|
||||
background: #232323 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.mat-mdc-raised-button.mat-success,
|
||||
.mat-mdc-raised-button.mat-reject {
|
||||
color: #232323;
|
||||
background-color: #fff;
|
||||
box-shadow:
|
||||
0 2px 2px 0 rgb(0 0 0 / 14%),
|
||||
0 1px 5px 0 rgb(0 0 0 / 12%),
|
||||
0 3px 1px -2px rgb(0 0 0 / 20%);
|
||||
}
|
||||
|
||||
:host-context(.dark-theme) .mat-mdc-raised-button.mat-success,
|
||||
:host-context(.dark-theme) .mat-mdc-raised-button.mat-reject {
|
||||
background-color: #424242;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tasks-action-btn {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button.mat-mdc-raised-button.action-button {
|
||||
box-shadow:
|
||||
0 2px 2px 0 rgb(0 0 0 / 14%),
|
||||
0 1px 5px 0 rgb(0 0 0 / 12%),
|
||||
0 3px 1px -2px rgb(0 0 0 / 20%);
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
letter-spacing: 0.5px;
|
||||
transition:
|
||||
background 0.3s,
|
||||
color 0.3s;
|
||||
}
|
||||
|
||||
/* ---------- SEARCH & LAYOUT ---------- */
|
||||
.search-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.search-field {
|
||||
width: 280px;
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
margin: 0;
|
||||
flex: 0 0 280px;
|
||||
}
|
||||
|
||||
.advanced-search-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#search-button {
|
||||
height: 2.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
margin: 0;
|
||||
background: #f5f5f5;
|
||||
color: #232323;
|
||||
}
|
||||
|
||||
:host-context(.dark-theme) .icon-button {
|
||||
background: #424242;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.view-details {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table {
|
||||
tr.select-row:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
input { font-size: 13px; }
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
background-color: #e8f4fd;
|
||||
padding: 6px 16px;
|
||||
font-size: 0.875rem;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.43;
|
||||
border-radius: 4px;
|
||||
letter-spacing: normal;
|
||||
margin: 10px;
|
||||
.cv-toggle-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: 1px solid $border;
|
||||
border-radius: 8px;
|
||||
color: $text-muted;
|
||||
background: #fff;
|
||||
|
||||
.message {
|
||||
padding: 8px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
::ng-deep .mat-mdc-button-persistent-ripple { border-radius: 8px; }
|
||||
}
|
||||
|
||||
.alert-check {
|
||||
color: #359ff4;
|
||||
margin-right: 2px;
|
||||
font-size: 1.4rem;
|
||||
.cv-action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.cv-btn {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border-radius: 8px !important;
|
||||
height: 36px;
|
||||
padding: 0 16px;
|
||||
font-family: 'DM Sans', 'Roboto', sans-serif;
|
||||
|
||||
fa-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-approve {
|
||||
border-color: #16a34a;
|
||||
color: #16a34a;
|
||||
|
||||
&:hover {
|
||||
background: #f0fdf4;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-delete {
|
||||
border-color: #dc2626;
|
||||
color: #dc2626;
|
||||
|
||||
&:hover {
|
||||
background: #fef2f2;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-reject {
|
||||
border-color: #64748b;
|
||||
color: #64748b;
|
||||
|
||||
&:hover {
|
||||
background: #f8fafc;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-search {
|
||||
height: 36px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
// Advanced search
|
||||
.cv-advanced-search {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
padding: 16px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
|
||||
.cv-adv-field {
|
||||
width: 100%;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding: 6px 0;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.mdc-notched-outline {
|
||||
.mdc-notched-outline__leading { border-radius: 8px 0 0 8px; }
|
||||
.mdc-notched-outline__trailing { border-radius: 0 8px 8px 0; }
|
||||
}
|
||||
|
||||
input,
|
||||
.mat-mdc-select-trigger { font-size: 13px; }
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-search {
|
||||
grid-column: 1 / -1;
|
||||
justify-self: start;
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive
|
||||
@media (max-width: 768px) {
|
||||
.cv-action-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cv-action-buttons {
|
||||
margin-left: 0;
|
||||
justify-content: stretch;
|
||||
|
||||
.cv-btn { flex: 1; }
|
||||
}
|
||||
|
||||
.cv-advanced-search {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
+62
-60
@@ -7,9 +7,10 @@
|
||||
-->
|
||||
|
||||
@if (showData) {
|
||||
<div class="tab-container mat-typography">
|
||||
<div class="tasks-header">
|
||||
<mat-form-field class="tasks-search-field">
|
||||
<div class="cv-tab-content">
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
#filterInput
|
||||
matInput
|
||||
@@ -17,71 +18,72 @@
|
||||
(keyup)="applyFilter(filterInput.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="success"
|
||||
*mifosxHasPermission="'ACTIVATE_CLIENT'"
|
||||
(click)="approveClients()"
|
||||
class="tasks-action-btn"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button
|
||||
mat-stroked-button
|
||||
class="cv-btn cv-btn-approve"
|
||||
*mifosxHasPermission="'ACTIVATE_CLIENT'"
|
||||
(click)="approveClients()"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@for (client of groupedClients | keyvalue; track client) {
|
||||
<h3>{{ client.key }}</h3>
|
||||
<h3 class="cv-group-title">{{ client.key }}</h3>
|
||||
@if (client.value.length > 0) {
|
||||
<table mat-table [dataSource]="client.value | accountsFilter: 'clientApproval'">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle(client.value) : null"
|
||||
[checked]="selection.hasValue() && isAllSelected(client.value)"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected(client.value)"
|
||||
[aria-label]="checkboxLabel(client.value)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" class="view-details" [routerLink]="['../../clients', element.id]">
|
||||
{{ element.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="accountNumber">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account Number' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" class="view-details" [routerLink]="['../../clients', element.id]">
|
||||
{{ element.accountNo }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="staff">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Staff' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" class="view-details" [routerLink]="['../../clients', element.id]">
|
||||
{{ element.staffName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)"></tr>
|
||||
</table>
|
||||
<div class="table-container cv-group-table">
|
||||
<table mat-table [dataSource]="client.value | accountsFilter: 'clientApproval'" class="modern-table">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle(client.value) : null"
|
||||
[checked]="selection.hasValue() && isAllSelected(client.value)"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected(client.value)"
|
||||
[aria-label]="checkboxLabel(client.value)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" class="cell-link" [routerLink]="['../../clients', element.id]">
|
||||
{{ element.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="accountNumber">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account Number' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" class="cell-mono" [routerLink]="['../../clients', element.id]" style="cursor: pointer;">
|
||||
{{ element.accountNo }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="staff">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Staff' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" [routerLink]="['../../clients', element.id]" style="cursor: pointer;">
|
||||
{{ element.staffName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)" class="table-row"></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!showData) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
{{ 'labels.text.No pending loans for approval' | translate }}
|
||||
</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-user-check empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No pending loans for approval' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
+91
-63
@@ -6,83 +6,111 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
$brand: #1353a0;
|
||||
$border: #e2e8f0;
|
||||
$text: #0f172a;
|
||||
$text-muted: #64748b;
|
||||
|
||||
.cv-tab-content {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.cv-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 320px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-form-field-flex { height: 32px; }
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding: 4px 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
::ng-deep mat-form-field {
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.mat-mdc-text-field-wrapper {
|
||||
margin-bottom: 0;
|
||||
.mdc-notched-outline {
|
||||
.mdc-notched-outline__leading { border-radius: 8px 0 0 8px; }
|
||||
.mdc-notched-outline__trailing { border-radius: 0 8px 8px 0; }
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
min-height: 48px;
|
||||
.mat-mdc-form-field-icon-prefix {
|
||||
padding: 0 6px 0 8px;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
button.mat-mdc-raised-button {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.mat-raised-button.mat-success {
|
||||
color: #fff;
|
||||
background-color: #008000ab;
|
||||
}
|
||||
|
||||
.view-details {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tasks-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tasks-search-field {
|
||||
width: 280px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tasks-action-btn {
|
||||
margin: 0;
|
||||
input { font-size: 13px; }
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
background-color: #e8f4fd;
|
||||
padding: 6px 16px;
|
||||
font-size: 0.875rem;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.43;
|
||||
border-radius: 4px;
|
||||
letter-spacing: normal;
|
||||
margin: 10px;
|
||||
.cv-action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 8px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
.cv-btn {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
height: 32px;
|
||||
padding: 0 14px;
|
||||
font-family: 'DM Sans', 'Roboto', sans-serif;
|
||||
|
||||
.alert-check {
|
||||
color: #359ff4;
|
||||
margin-right: 2px;
|
||||
font-size: 1.4rem;
|
||||
fa-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-approve {
|
||||
border-color: #16a34a;
|
||||
color: #16a34a;
|
||||
|
||||
&:hover {
|
||||
background: #f0fdf4;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-group-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $text;
|
||||
margin: 20px 0 8px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.cv-group-table {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cv-action-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cv-action-buttons {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
+72
-70
@@ -7,92 +7,94 @@
|
||||
-->
|
||||
|
||||
@if (showData) {
|
||||
<div class="tab-container mat-typography">
|
||||
<div class="tasks-header">
|
||||
<mat-form-field class="tasks-search-field">
|
||||
<div class="cv-tab-content">
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'labels.text.Filter by name' | translate }}"
|
||||
(keyup)="applyFilter($event.target.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="success"
|
||||
*mifosxHasPermission="'APPROVE_LOAN'"
|
||||
(click)="approveLoan()"
|
||||
class="tasks-action-btn"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button
|
||||
mat-stroked-button
|
||||
class="cv-btn cv-btn-approve"
|
||||
*mifosxHasPermission="'APPROVE_LOAN'"
|
||||
(click)="approveLoan()"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@for (office of officesArray; track office) {
|
||||
<h3 class="mat-h3">{{ office.name }}</h3>
|
||||
<h3 class="cv-group-title">{{ office.name }}</h3>
|
||||
@if (office.loans.length > 0) {
|
||||
<table mat-table [dataSource]="office.loans">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle(office.loans) : null"
|
||||
[checked]="selection.hasValue() && isAllSelected(office.loans)"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected(office.loans)"
|
||||
[aria-label]="checkboxLabel(office.loans)"
|
||||
<div class="table-container cv-group-table">
|
||||
<table mat-table [dataSource]="office.loans" class="modern-table">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle(office.loans) : null"
|
||||
[checked]="selection.hasValue() && isAllSelected(office.loans)"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected(office.loans)"
|
||||
[aria-label]="checkboxLabel(office.loans)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="clientName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="cell-link"
|
||||
[routerLink]="['../../clients', loan.clientId, 'general']"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
{{ loan.clientName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loan">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="cell-link"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans-accounts', 'loan.id']"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="clientName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'general']"
|
||||
>
|
||||
{{ loan.clientName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loan">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans-accounts', 'loan.id']"
|
||||
>
|
||||
{{ loan.loanProductName }}({{ loan.accountNo }})
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.principal | formatNumber }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanPurpose">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Purpose' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.loanPurposeName }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)"></tr>
|
||||
</table>
|
||||
{{ loan.loanProductName }}({{ loan.accountNo }})
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan" class="cell-mono">{{ loan.principal | formatNumber }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanPurpose">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Purpose' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.loanPurposeName }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)" class="table-row"></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!showData) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
{{ 'labels.text.No pending loans for approval' | translate }}
|
||||
</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-hand-holding-usd empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No pending loans for approval' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
+91
-63
@@ -6,83 +6,111 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
$brand: #1353a0;
|
||||
$border: #e2e8f0;
|
||||
$text: #0f172a;
|
||||
$text-muted: #64748b;
|
||||
|
||||
.cv-tab-content {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.cv-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 320px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-form-field-flex { height: 32px; }
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding: 4px 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
::ng-deep mat-form-field {
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.mat-mdc-text-field-wrapper {
|
||||
margin-bottom: 0;
|
||||
.mdc-notched-outline {
|
||||
.mdc-notched-outline__leading { border-radius: 8px 0 0 8px; }
|
||||
.mdc-notched-outline__trailing { border-radius: 0 8px 8px 0; }
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
min-height: 48px;
|
||||
.mat-mdc-form-field-icon-prefix {
|
||||
padding: 0 6px 0 8px;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
button.mat-mdc-raised-button {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.mat-raised-button.mat-success {
|
||||
color: #fff;
|
||||
background-color: #008000ab;
|
||||
}
|
||||
|
||||
.view-details {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tasks-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tasks-search-field {
|
||||
width: 280px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tasks-action-btn {
|
||||
margin: 0;
|
||||
input { font-size: 13px; }
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
background-color: #e8f4fd;
|
||||
padding: 6px 16px;
|
||||
font-size: 0.875rem;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.43;
|
||||
border-radius: 4px;
|
||||
letter-spacing: normal;
|
||||
margin: 10px;
|
||||
.cv-action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 8px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
.cv-btn {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
height: 32px;
|
||||
padding: 0 14px;
|
||||
font-family: 'DM Sans', 'Roboto', sans-serif;
|
||||
|
||||
.alert-check {
|
||||
color: #359ff4;
|
||||
margin-right: 2px;
|
||||
font-size: 1.4rem;
|
||||
fa-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-approve {
|
||||
border-color: #16a34a;
|
||||
color: #16a34a;
|
||||
|
||||
&:hover {
|
||||
background: #f0fdf4;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-group-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $text;
|
||||
margin: 20px 0 8px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.cv-group-table {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cv-action-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cv-action-buttons {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
+79
-76
@@ -7,9 +7,10 @@
|
||||
-->
|
||||
|
||||
@if (loans && loans.length > 0) {
|
||||
<div class="tab-container mat-typography">
|
||||
<div class="tasks-header">
|
||||
<mat-form-field class="tasks-search-field">
|
||||
<div class="cv-tab-content">
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
#filterInput
|
||||
matInput
|
||||
@@ -17,85 +18,87 @@
|
||||
(keyup)="applyFilter(filterInput.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="success"
|
||||
*mifosxHasPermission="'APPROVE_LOAN'"
|
||||
(click)="disburseLoan()"
|
||||
class="tasks-action-btn"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.menus.Disburse' | translate }}
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button
|
||||
mat-stroked-button
|
||||
class="cv-btn cv-btn-approve"
|
||||
*mifosxHasPermission="'APPROVE_LOAN'"
|
||||
(click)="disburseLoan()"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.menus.Disburse' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
[aria-label]="checkboxLabel()"
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" class="modern-table">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
[aria-label]="checkboxLabel()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="client">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client Name' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="cell-link"
|
||||
[routerLink]="['../../clients', loan.clientId, 'general']"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
{{ loan.clientName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanAccountNumber">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Account' | translate }}#</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="cell-mono"
|
||||
style="cursor: pointer;"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans-accounts', loan.id, 'general']"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="client">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client Name' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'general']"
|
||||
>
|
||||
{{ loan.clientName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanAccountNumber">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Account' | translate }}#</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans-accounts', loan.id, 'general']"
|
||||
>
|
||||
{{ loan.accountNo }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanProduct">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Product' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans-accounts', loan.id, 'general']"
|
||||
>
|
||||
{{ loan.loanProductName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="principal">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Principal' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.principal | formatNumber }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)"></tr>
|
||||
</table>
|
||||
{{ loan.accountNo }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanProduct">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Product' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans-accounts', loan.id, 'general']"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
{{ loan.loanProductName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="principal">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Principal' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan" class="cell-mono">{{ loan.principal | formatNumber }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)" class="table-row"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (loans.length === 0) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
{{ 'labels.text.No pending loan available for disbursal' | translate }}
|
||||
</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-money-bill-wave empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No pending loan available for disbursal' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
+78
-63
@@ -6,83 +6,98 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
$brand: #1353a0;
|
||||
$border: #e2e8f0;
|
||||
$text: #0f172a;
|
||||
$text-muted: #64748b;
|
||||
|
||||
.cv-tab-content {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.cv-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 320px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-form-field-flex { height: 32px; }
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding: 4px 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
::ng-deep mat-form-field {
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.mat-mdc-text-field-wrapper {
|
||||
margin-bottom: 0;
|
||||
.mdc-notched-outline {
|
||||
.mdc-notched-outline__leading { border-radius: 8px 0 0 8px; }
|
||||
.mdc-notched-outline__trailing { border-radius: 0 8px 8px 0; }
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
min-height: 48px;
|
||||
.mat-mdc-form-field-icon-prefix {
|
||||
padding: 0 6px 0 8px;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
button.mat-mdc-raised-button {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.mat-raised-button.mat-success {
|
||||
color: #fff;
|
||||
background-color: #008000ab;
|
||||
}
|
||||
|
||||
.view-details {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tasks-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tasks-search-field {
|
||||
width: 280px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tasks-action-btn {
|
||||
margin: 0;
|
||||
input { font-size: 13px; }
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
background-color: #e8f4fd;
|
||||
padding: 6px 16px;
|
||||
font-size: 0.875rem;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.43;
|
||||
border-radius: 4px;
|
||||
letter-spacing: normal;
|
||||
margin: 10px;
|
||||
.cv-action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 8px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
.cv-btn {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
height: 32px;
|
||||
padding: 0 14px;
|
||||
font-family: 'DM Sans', 'Roboto', sans-serif;
|
||||
|
||||
.alert-check {
|
||||
color: #359ff4;
|
||||
margin-right: 2px;
|
||||
font-size: 1.4rem;
|
||||
fa-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-approve {
|
||||
border-color: #16a34a;
|
||||
color: #16a34a;
|
||||
|
||||
&:hover {
|
||||
background: #f0fdf4;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cv-action-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cv-action-buttons {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
+84
-82
@@ -7,9 +7,10 @@
|
||||
-->
|
||||
|
||||
@if (loans && loans.length > 0) {
|
||||
<div class="tab-container mat-typography">
|
||||
<div class="tasks-header">
|
||||
<mat-form-field class="tasks-search-field">
|
||||
<div class="cv-tab-content">
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
#filterInput
|
||||
matInput
|
||||
@@ -17,91 +18,92 @@
|
||||
(keyup)="applyFilter(filterInput.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="success"
|
||||
*mifosxHasPermission="'APPROVE_LOANRESCHEDULE'"
|
||||
(click)="bulkLoanReschedule('Approve')"
|
||||
class="tasks-action-btn"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="reject"
|
||||
*mifosxHasPermission="'APPROVE_LOANRESCHEDULE'"
|
||||
(click)="bulkLoanReschedule('Reject')"
|
||||
class="tasks-action-btn"
|
||||
>
|
||||
<fa-icon icon="times" class="m-r-10"></fa-icon>{{ 'labels.buttons.Reject' | translate }}
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button
|
||||
mat-stroked-button
|
||||
class="cv-btn cv-btn-approve"
|
||||
*mifosxHasPermission="'APPROVE_LOANRESCHEDULE'"
|
||||
(click)="bulkLoanReschedule('Approve')"
|
||||
>
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-stroked-button
|
||||
class="cv-btn cv-btn-reject"
|
||||
*mifosxHasPermission="'APPROVE_LOANRESCHEDULE'"
|
||||
(click)="bulkLoanReschedule('Reject')"
|
||||
>
|
||||
<fa-icon icon="times" class="m-r-10"></fa-icon>{{ 'labels.buttons.Reject' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
[aria-label]="checkboxLabel()"
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" class="modern-table">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
[aria-label]="checkboxLabel()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="client">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="cell-link"
|
||||
[routerLink]="['../../clients', loan.clientId, 'general']"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
[aria-label]="checkboxLabel(row)"
|
||||
{{ loan.clientName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rescheduleRequestNo">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Reschedule Request' | translate }}#</th>
|
||||
<td mat-cell *matCellDef="let loan" class="cell-mono">{{ loan.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanAccountNo">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Account' | translate }}#</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="cell-mono"
|
||||
style="cursor: pointer;"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans', loan.loanId, 'general']"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="client">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'general']"
|
||||
>
|
||||
{{ loan.clientName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rescheduleRequestNo">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Reschedule Request' | translate }}#</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loanAccountNo">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Account' | translate }}#</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let loan"
|
||||
class="view-details"
|
||||
[routerLink]="['../../clients', loan.clientId, 'loans', loan.loanId, 'general']"
|
||||
>
|
||||
{{ loan.loanAccountNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rescheduleForm">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Reschedule Form' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.rescheduleFromDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rescheduleReason">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Reschedule Reason' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.rescheduleReasonCodeValue.name }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)"></tr>
|
||||
</table>
|
||||
{{ loan.loanAccountNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rescheduleForm">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Reschedule Form' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.rescheduleFromDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rescheduleReason">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Reschedule Reason' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.rescheduleReasonCodeValue.name }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" (click)="selection.toggle(row)" class="table-row"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (loans?.length === 0) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
{{ 'labels.text.No pending rescheduled loan available for this account' | translate }}
|
||||
</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-calendar-alt empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No pending rescheduled loan available for this account' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
+87
-63
@@ -6,83 +6,107 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
$brand: #1353a0;
|
||||
$border: #e2e8f0;
|
||||
$text: #0f172a;
|
||||
$text-muted: #64748b;
|
||||
|
||||
.cv-tab-content {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.cv-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 320px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-form-field-flex { height: 32px; }
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding: 4px 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
::ng-deep mat-form-field {
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.mat-mdc-text-field-wrapper {
|
||||
margin-bottom: 0;
|
||||
.mdc-notched-outline {
|
||||
.mdc-notched-outline__leading { border-radius: 8px 0 0 8px; }
|
||||
.mdc-notched-outline__trailing { border-radius: 0 8px 8px 0; }
|
||||
}
|
||||
|
||||
.mat-mdc-form-field-infix {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
min-height: 48px;
|
||||
.mat-mdc-form-field-icon-prefix {
|
||||
padding: 0 6px 0 8px;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
button.mat-mdc-raised-button {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.mat-raised-button.mat-success {
|
||||
color: #fff;
|
||||
background-color: #008000ab;
|
||||
}
|
||||
|
||||
.view-details {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tasks-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tasks-search-field {
|
||||
width: 280px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tasks-action-btn {
|
||||
margin: 0;
|
||||
input { font-size: 13px; }
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
background-color: #e8f4fd;
|
||||
padding: 6px 16px;
|
||||
font-size: 0.875rem;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.43;
|
||||
border-radius: 4px;
|
||||
letter-spacing: normal;
|
||||
margin: 10px;
|
||||
.cv-action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 8px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
.cv-btn {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
height: 32px;
|
||||
padding: 0 14px;
|
||||
font-family: 'DM Sans', 'Roboto', sans-serif;
|
||||
|
||||
.alert-check {
|
||||
color: #359ff4;
|
||||
margin-right: 2px;
|
||||
font-size: 1.4rem;
|
||||
fa-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-approve {
|
||||
border-color: #16a34a;
|
||||
color: #16a34a;
|
||||
|
||||
&:hover {
|
||||
background: #f0fdf4;
|
||||
}
|
||||
}
|
||||
|
||||
.cv-btn-reject {
|
||||
border-color: #64748b;
|
||||
color: #64748b;
|
||||
|
||||
&:hover {
|
||||
background: #f8fafc;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cv-action-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cv-search-field {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cv-action-buttons {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,66 +7,34 @@
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card class="tasks-card">
|
||||
<mat-card-content>
|
||||
<div class="card-heading pending-tasks-heading">{{ 'labels.heading.Pending Tasks' | translate }}</div>
|
||||
<mat-divider></mat-divider>
|
||||
<nav mat-tab-nav-bar class="navigation-tabs" [tabPanel]="tabPanel">
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./checker-inbox']"
|
||||
routerLinkActive
|
||||
#checkerInbox="routerLinkActive"
|
||||
[active]="checkerInbox.isActive"
|
||||
*mifosxHasPermission="'ALL_FUNCTIONS_READ'"
|
||||
>
|
||||
{{ 'labels.inputs.Checker Inbox' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./client-approval']"
|
||||
routerLinkActive
|
||||
#clientApproval="routerLinkActive"
|
||||
[active]="clientApproval.isActive"
|
||||
*mifosxHasPermission="'READ_CLIENT'"
|
||||
>
|
||||
{{ 'labels.inputs.Client Approval' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./loan-approval']"
|
||||
routerLinkActive
|
||||
#loanApproval="routerLinkActive"
|
||||
[active]="loanApproval.isActive"
|
||||
*mifosxHasPermission="'READ_LOAN'"
|
||||
>
|
||||
{{ 'labels.inputs.Loan Approval' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./loan-disbursal']"
|
||||
routerLinkActive
|
||||
#loanDisbursal="routerLinkActive"
|
||||
[active]="loanDisbursal.isActive"
|
||||
*mifosxHasPermission="'READ_LOAN'"
|
||||
>
|
||||
{{ 'labels.inputs.Loan Disbursal' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./reschedule-loan']"
|
||||
routerLinkActive
|
||||
#rescheduleLoan="routerLinkActive"
|
||||
[active]="rescheduleLoan.isActive"
|
||||
*mifosxHasPermission="'RESCHEDULE_LOAN'"
|
||||
>
|
||||
{{ 'labels.inputs.Reschedule Loan' | translate }}
|
||||
</a>
|
||||
</nav>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<span class="t-logomark"><span></span><span></span><span></span><span></span></span>
|
||||
{{ 'labels.heading.Pending Tasks' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-tab-nav-panel #tabPanel>
|
||||
<router-outlet></router-outlet>
|
||||
</mat-tab-nav-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<nav mat-tab-nav-bar class="cv-tab-nav" [tabPanel]="tabPanel">
|
||||
<a mat-tab-link [routerLink]="['./checker-inbox']" routerLinkActive #checkerInbox="routerLinkActive" [active]="checkerInbox.isActive" *mifosxHasPermission="'ALL_FUNCTIONS_READ'">
|
||||
<i class="fas fa-inbox cv-tab-icon"></i> {{ 'labels.inputs.Checker Inbox' | translate }}
|
||||
</a>
|
||||
<a mat-tab-link [routerLink]="['./client-approval']" routerLinkActive #clientApproval="routerLinkActive" [active]="clientApproval.isActive" *mifosxHasPermission="'READ_CLIENT'">
|
||||
<i class="fas fa-user-check cv-tab-icon"></i> {{ 'labels.inputs.Client Approval' | translate }}
|
||||
</a>
|
||||
<a mat-tab-link [routerLink]="['./loan-approval']" routerLinkActive #loanApproval="routerLinkActive" [active]="loanApproval.isActive" *mifosxHasPermission="'READ_LOAN'">
|
||||
<i class="fas fa-hand-holding-usd cv-tab-icon"></i> {{ 'labels.inputs.Loan Approval' | translate }}
|
||||
</a>
|
||||
<a mat-tab-link [routerLink]="['./loan-disbursal']" routerLinkActive #loanDisbursal="routerLinkActive" [active]="loanDisbursal.isActive" *mifosxHasPermission="'READ_LOAN'">
|
||||
<i class="fas fa-money-bill-wave cv-tab-icon"></i> {{ 'labels.inputs.Loan Disbursal' | translate }}
|
||||
</a>
|
||||
<a mat-tab-link [routerLink]="['./reschedule-loan']" routerLinkActive #rescheduleLoan="routerLinkActive" [active]="rescheduleLoan.isActive" *mifosxHasPermission="'RESCHEDULE_LOAN'">
|
||||
<i class="fas fa-calendar-alt cv-tab-icon"></i> {{ 'labels.inputs.Reschedule Loan' | translate }}
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<mat-tab-nav-panel #tabPanel>
|
||||
<router-outlet></router-outlet>
|
||||
</mat-tab-nav-panel>
|
||||
</div>
|
||||
|
||||
@@ -6,18 +6,26 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.card-heading {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 16px;
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
.cv-tab-icon {
|
||||
margin-right: 5px;
|
||||
font-size: 12px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
:host-context(.dark-theme) .pending-tasks-heading {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 4px rgb(0 0 0 / 70%);
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
.cv-tab-nav {
|
||||
margin-bottom: 16px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-tab-link {
|
||||
font-family: 'DM Sans', 'Roboto', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
min-width: 0;
|
||||
padding: 0 16px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user