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
@@ -6,23 +6,34 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_ADHOC'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create AdHoc Query' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<mat-card class="container">
|
||||
<!-- Header Bar -->
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
{{ 'labels.heading.AdHocQuery' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<input matInput placeholder="{{ 'labels.inputs.Filter' | translate }}" (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" [routerLink]="['create']" class="btn-create" *mifosxHasPermission="'CREATE_ADHOC'">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
{{ 'labels.buttons.Create AdHoc Query' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8 table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<!-- Table -->
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let adhocquery">{{ adhocquery.name }}</td>
|
||||
@@ -70,9 +81,9 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="select-row"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
+63
-64
@@ -6,115 +6,114 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="caq-container">
|
||||
<!-- Header -->
|
||||
<div class="caq-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="caq-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.AdHocQuery' | translate }}
|
||||
</button>
|
||||
<h2 class="caq-header__title">{{ 'labels.buttons.Create AdHoc Query' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="caq-card">
|
||||
<form [formGroup]="adhocQueryForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<!-- Query Details Section -->
|
||||
<div class="caq-section">
|
||||
<div class="caq-section__header">
|
||||
<i class="fas fa-database"></i>
|
||||
<h3>Query Details</h3>
|
||||
</div>
|
||||
<div class="caq-grid">
|
||||
<mat-form-field appearance="outline" class="caq-field">
|
||||
<mat-label>{{ 'labels.inputs.name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="name" />
|
||||
@if (adhocQueryForm.controls.name.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.name' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
<mat-error>{{ 'labels.inputs.name' | translate }} {{ 'labels.commons.is' | translate }} <strong>{{ 'labels.commons.required' | translate }}</strong></mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.SQL Query' | translate }}</mat-label>
|
||||
<textarea matInput required formControlName="query"></textarea>
|
||||
@if (adhocQueryForm.controls.query.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.SQL Query' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="caq-field">
|
||||
<mat-label>{{ 'labels.inputs.Insert into table' | translate }}</mat-label>
|
||||
<input matInput required formControlName="tableName" />
|
||||
@if (adhocQueryForm.controls.tableName.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Insert into table' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
<mat-error>{{ 'labels.inputs.Insert into table' | translate }} {{ 'labels.commons.is' | translate }} <strong>{{ 'labels.commons.required' | translate }}</strong></mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="caq-field caq-field--full">
|
||||
<mat-label>{{ 'labels.inputs.SQL Query' | translate }}</mat-label>
|
||||
<textarea matInput required formControlName="query" rows="3"></textarea>
|
||||
@if (adhocQueryForm.controls.query.hasError('required')) {
|
||||
<mat-error>{{ 'labels.inputs.SQL Query' | translate }} {{ 'labels.commons.is' | translate }} <strong>{{ 'labels.commons.required' | translate }}</strong></mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="caq-field caq-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Table Fields' | translate }}</mat-label>
|
||||
<textarea matInput required formControlName="tableFields"></textarea>
|
||||
<textarea matInput required formControlName="tableFields" rows="2"></textarea>
|
||||
@if (adhocQueryForm.controls.tableFields.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Table Fields' | translate }} {{ 'labels.commons.are' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
<mat-error>{{ 'labels.inputs.Table Fields' | translate }} {{ 'labels.commons.are' | translate }} <strong>{{ 'labels.commons.required' | translate }}</strong></mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field>
|
||||
<!-- Notification & Schedule Section -->
|
||||
<div class="caq-section">
|
||||
<div class="caq-section__header">
|
||||
<i class="fas fa-clock"></i>
|
||||
<h3>Notification & Schedule</h3>
|
||||
</div>
|
||||
<div class="caq-grid">
|
||||
<mat-form-field appearance="outline" class="caq-field">
|
||||
<mat-label>{{ 'labels.inputs.Email' | translate }}</mat-label>
|
||||
<input matInput formControlName="email" />
|
||||
@if (adhocQueryForm.controls.email.hasError('email')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Email' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.invalid' | translate }}</strong>
|
||||
</mat-error>
|
||||
<mat-error>{{ 'labels.inputs.Email' | translate }} {{ 'labels.commons.is' | translate }} <strong>{{ 'labels.commons.invalid' | translate }}</strong></mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="caq-field">
|
||||
<mat-label>{{ 'labels.inputs.Report Run Frequency' | translate }}</mat-label>
|
||||
<mat-select formControlName="reportRunFrequency">
|
||||
@for (reportRunFrequency of reportRunFrequencyData; track reportRunFrequency) {
|
||||
<mat-option [value]="reportRunFrequency.id">
|
||||
{{ reportRunFrequency.value }}
|
||||
</mat-option>
|
||||
<mat-option [value]="reportRunFrequency.id">{{ reportRunFrequency.value }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
@if (adhocQueryForm.controls.reportRunFrequency.value === 5) {
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="caq-field">
|
||||
<mat-label>{{ 'labels.inputs.Custom Report Run Frequency (Days)' | translate }}</mat-label>
|
||||
<input type="number" matInput required formControlName="reportRunEvery" />
|
||||
@if (adhocQueryForm.controls.reportRunEvery.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Custom Report Run Frequency' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
<mat-error>{{ 'labels.inputs.Custom Report Run Frequency' | translate }} {{ 'labels.commons.is' | translate }} <strong>{{ 'labels.commons.required' | translate }}</strong></mat-error>
|
||||
}
|
||||
@if (adhocQueryForm.controls.reportRunEvery.hasError('min')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Custom Report Run Frequency' | translate }}
|
||||
<strong>{{ 'labels.commons.must be larger than 0' | translate }}</strong>
|
||||
</mat-error>
|
||||
<mat-error>{{ 'labels.inputs.Custom Report Run Frequency' | translate }} <strong>{{ 'labels.commons.must be larger than 0' | translate }}</strong></mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-checkbox labelPosition="before" formControlName="isActive">
|
||||
{{ 'labels.inputs.Active' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="caq-checkbox">
|
||||
<mat-checkbox labelPosition="after" formControlName="isActive">
|
||||
{{ 'labels.inputs.Active' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<!-- Actions -->
|
||||
<div class="caq-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="caq-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[disabled]="!adhocQueryForm.valid"
|
||||
*mifosxHasPermission="'CREATE_ADHOC'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!adhocQueryForm.valid"
|
||||
*mifosxHasPermission="'CREATE_ADHOC'" class="caq-actions__submit">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+52
-2
@@ -6,6 +6,56 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.caq-container { max-width: 800px; margin: 0 auto; padding: 20px 16px; }
|
||||
|
||||
.caq-header {
|
||||
display: flex; align-items: center; gap: 14px; margin-bottom: 20px;
|
||||
&__title { font-size: 18px; font-weight: 600; color: $gray-900; margin: 0; }
|
||||
}
|
||||
|
||||
.caq-back {
|
||||
border-radius: 8px !important; font-size: 12px !important; font-weight: 600 !important;
|
||||
height: 32px !important; border-color: $border !important; color: $gray-500 !important;
|
||||
i { margin-right: 6px; }
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.caq-card { background: #fff; border: 1px solid $border; border-radius: 10px; overflow: hidden; }
|
||||
|
||||
.caq-section {
|
||||
&__header {
|
||||
display: flex; align-items: center; gap: 10px; padding: 12px 24px;
|
||||
background: $gray-50; border-bottom: 1px solid $gray-200;
|
||||
i { font-size: 14px; color: $accent; }
|
||||
h3 { margin: 0; font-size: 14px; font-weight: 600; color: $gray-900; }
|
||||
}
|
||||
& + & { border-top: 1px solid $gray-200; }
|
||||
}
|
||||
|
||||
.caq-grid {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 16px; padding: 16px 24px;
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.caq-field {
|
||||
width: 100%;
|
||||
&--full { grid-column: 1 / -1; }
|
||||
}
|
||||
|
||||
.caq-checkbox { grid-column: 1 / -1; padding: 8px 0; }
|
||||
|
||||
.caq-actions {
|
||||
display: flex; justify-content: flex-end; gap: 10px; padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200; background: $gray-50;
|
||||
&__cancel { border-radius: 8px !important; font-size: 13px !important; font-weight: 600 !important; height: 36px !important; border-color: $border !important; color: $gray-700 !important; }
|
||||
&__submit { border-radius: 8px !important; font-size: 13px !important; font-weight: 600 !important; height: 36px !important; box-shadow: 0 1px 3px rgba($primary, 0.3) !important; i { margin-right: 6px; font-size: 12px; } }
|
||||
}
|
||||
|
||||
@@ -6,347 +6,186 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<!-- TODO: Refactor Permissions -->
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="layout-row responsive-column gap-20px">
|
||||
<div class="flex-50">
|
||||
<mat-nav-list>
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Offices']">
|
||||
<fa-icon icon="building" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Offices']">{{ 'labels.heading.Offices' | translate }}</h4>
|
||||
@if (!arrowBooleans[0]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(0)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[0]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(0)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[0]) {
|
||||
<p matLine [routerLink]="['Offices']">
|
||||
{{ 'labels.text.Download, Upload Offices Template' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Users']">
|
||||
<fa-icon icon="user" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Users']">{{ 'labels.heading.Users' | translate }}</h4>
|
||||
@if (!arrowBooleans[1]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(1)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[1]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(1)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[1]) {
|
||||
<p matLine [routerLink]="['Users']">
|
||||
{{ 'labels.text.Download offices template and Upload office excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Groups']">
|
||||
<fa-icon icon="users" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Groups']">{{ 'labels.heading.Groups' | translate }}</h4>
|
||||
@if (!arrowBooleans[2]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(2)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[2]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(2)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[2]) {
|
||||
<p matLine [routerLink]="['Groups']">
|
||||
{{ 'labels.text.Download groups template and Upload group excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Loan Accounts']">
|
||||
<fa-icon icon="money-bill-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Loan Accounts']">{{ 'labels.heading.Loan Accounts' | translate }}</h4>
|
||||
@if (!arrowBooleans[3]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(3)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[3]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(3)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[3]) {
|
||||
<p matLine [routerLink]="['Loan Accounts']">
|
||||
{{ 'labels.text.Download loan accounts template and upload loan account excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Savings Accounts']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Savings Accounts']">{{ 'labels.heading.Savings Accounts' | translate }}</h4>
|
||||
@if (!arrowBooleans[4]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(4)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[4]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(4)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[4]) {
|
||||
<p matLine [routerLink]="['Savings Accounts']">
|
||||
{{
|
||||
'labels.text.Download savings accounts template and upload savings account excel files' | translate
|
||||
}}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Fixed Deposit Accounts']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Fixed Deposit Accounts']">
|
||||
{{ 'labels.heading.Fixed Deposit Accounts' | translate }}
|
||||
</h4>
|
||||
@if (!arrowBooleans[5]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(5)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[5]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(5)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[5]) {
|
||||
<p matLine [routerLink]="['Fixed Deposit Accounts']">
|
||||
{{
|
||||
'labels.text.Download fixed deposit accounts template and upload fixed deposit account excel files'
|
||||
| translate
|
||||
}}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Chart of Accounts']">
|
||||
<fa-icon icon="money-bill-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Chart of Accounts']">{{ 'labels.heading.Chart of Accounts' | translate }}</h4>
|
||||
@if (!arrowBooleans[6]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(6)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[6]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(6)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[6]) {
|
||||
<p matLine [routerLink]="['Chart of Accounts']">
|
||||
{{
|
||||
'labels.text.Download chart of accounts template and upload chart of account excel files' | translate
|
||||
}}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Share Accounts']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Share Accounts']">{{ 'labels.heading.Share Accounts' | translate }}</h4>
|
||||
@if (!arrowBooleans[7]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(7)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[7]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(7)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[7]) {
|
||||
<p matLine [routerLink]="['Share Accounts']">
|
||||
{{ 'labels.text.Download share accounts template and upload share account excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
<mat-nav-list>
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Employees']">
|
||||
<fa-icon icon="user" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Employees']">{{ 'labels.heading.Employees' | translate }}</h4>
|
||||
@if (!arrowBooleans[8]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(8)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[8]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(8)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[8]) {
|
||||
<p matLine [routerLink]="['Employees']">
|
||||
{{ 'labels.text.Download loan accounts template and upload loan account excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Clients']">
|
||||
<fa-icon icon="user" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Clients']">{{ 'labels.heading.Clients' | translate }}</h4>
|
||||
@if (!arrowBooleans[9]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(9)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[9]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(9)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[9]) {
|
||||
<p matLine [routerLink]="['Clients']">
|
||||
{{ 'labels.text.Download clients template and upload clients excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Centers']">
|
||||
<fa-icon icon="users" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Centers']">{{ 'labels.heading.Centers' | translate }}</h4>
|
||||
@if (!arrowBooleans[10]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(10)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[10]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(10)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[10]) {
|
||||
<p matLine [routerLink]="['Centers']">
|
||||
{{ 'labels.text.Download centers template and upload centers excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Loan Repayments']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Loan Repayments']">{{ 'labels.heading.Loan Repayments' | translate }}</h4>
|
||||
@if (!arrowBooleans[11]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(11)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[11]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(11)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[11]) {
|
||||
<p matLine [routerLink]="['Loan Repayments']">
|
||||
{{ 'labels.text.Download loan repayments template and upload loan repayment excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Savings Transactions']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Savings Transactions']">
|
||||
{{ 'labels.heading.Savings Transactions' | translate }}
|
||||
</h4>
|
||||
@if (!arrowBooleans[12]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(12)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[12]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(12)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[12]) {
|
||||
<p matLine [routerLink]="['Savings Transactions']">
|
||||
{{
|
||||
'labels.text.Download savings transactions template and upload savings transaction excel files'
|
||||
| translate
|
||||
}}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Fixed Deposit Transactions']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Fixed Deposit Transactions']">
|
||||
{{ 'labels.heading.Fixed Deposit Transactions' | translate }}
|
||||
</h4>
|
||||
@if (!arrowBooleans[13]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(13)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[13]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(13)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[13]) {
|
||||
<p matLine [routerLink]="['Fixed Deposit Transactions']">
|
||||
{{
|
||||
'labels.text.Download fixed deposit transactions template and upload fixed deposit transaction excel files'
|
||||
| translate
|
||||
}}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Recurring Deposit Transactions']">
|
||||
<fa-icon icon="briefcase" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Recurring Deposit Transactions']">
|
||||
{{ 'labels.heading.Recurring Deposit Transactions' | translate }}
|
||||
</h4>
|
||||
@if (!arrowBooleans[14]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(14)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[14]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(14)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[14]) {
|
||||
<p matLine [routerLink]="['Recurring Deposit Transactions']">
|
||||
{{
|
||||
'labels.text.Download recurring deposit transactions template and upload recurring deposit transaction excel files'
|
||||
| translate
|
||||
}}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Journal Entries']">
|
||||
<fa-icon icon="chevron-right" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Journal Entries']">{{ 'labels.heading.Journal Entries' | translate }}</h4>
|
||||
@if (!arrowBooleans[15]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(15)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[15]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(15)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[15]) {
|
||||
<p matLine [routerLink]="['Journal Entries']">
|
||||
{{ 'labels.text.Download journal entries template and upload journal entries excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<mat-icon matListIcon [routerLink]="['Guarantors']">
|
||||
<fa-icon icon="chevron-right" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<h4 matLine [routerLink]="['Guarantors']">{{ 'labels.heading.Guarantors' | translate }}</h4>
|
||||
@if (!arrowBooleans[16]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(16)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[16]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(16)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[16]) {
|
||||
<p matLine [routerLink]="['Guarantors']">
|
||||
{{ 'labels.text.Download guarantors template and upload guarantor excel files' | translate }}
|
||||
</p>
|
||||
}
|
||||
</mat-list-item>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
<div class="org-container">
|
||||
<div class="org-header">
|
||||
<div class="org-header__icon"><i class="fas fa-upload"></i></div>
|
||||
<div>
|
||||
<h1 class="org-header__title">{{ 'labels.heading.Bulk Import' | translate }}</h1>
|
||||
<p class="org-header__sub">Download templates and upload excel files for bulk data import</p>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<div class="org-grid">
|
||||
|
||||
<!-- Offices -->
|
||||
<a class="org-card" [routerLink]="['Offices']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--blue"><i class="fas fa-building"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Offices' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download, Upload Offices Template' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Users -->
|
||||
<a class="org-card" [routerLink]="['Users']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--purple"><i class="fas fa-user"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Users' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download offices template and Upload office excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Groups -->
|
||||
<a class="org-card" [routerLink]="['Groups']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--green"><i class="fas fa-users"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Groups' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download groups template and Upload group excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Loan Accounts -->
|
||||
<a class="org-card" [routerLink]="['Loan Accounts']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--orange"><i class="fas fa-money-bill-alt"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Loan Accounts' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download loan accounts template and upload loan account excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Savings Accounts -->
|
||||
<a class="org-card" [routerLink]="['Savings Accounts']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--emerald"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Savings Accounts' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download savings accounts template and upload savings account excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Fixed Deposit Accounts -->
|
||||
<a class="org-card" [routerLink]="['Fixed Deposit Accounts']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--teal"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Fixed Deposit Accounts' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download fixed deposit accounts template and upload fixed deposit account excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Chart of Accounts -->
|
||||
<a class="org-card" [routerLink]="['Chart of Accounts']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--amber"><i class="fas fa-money-bill-alt"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Chart of Accounts' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download chart of accounts template and upload chart of account excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Share Accounts -->
|
||||
<a class="org-card" [routerLink]="['Share Accounts']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--indigo"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Share Accounts' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download share accounts template and upload share account excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Employees -->
|
||||
<a class="org-card" [routerLink]="['Employees']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--purple"><i class="fas fa-user"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Employees' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download loan accounts template and upload loan account excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Clients -->
|
||||
<a class="org-card" [routerLink]="['Clients']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--cyan"><i class="fas fa-user"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Clients' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download clients template and upload clients excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Centers -->
|
||||
<a class="org-card" [routerLink]="['Centers']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--green"><i class="fas fa-users"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Centers' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download centers template and upload centers excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Loan Repayments -->
|
||||
<a class="org-card" [routerLink]="['Loan Repayments']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--rose"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Loan Repayments' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download loan repayments template and upload loan repayment excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Savings Transactions -->
|
||||
<a class="org-card" [routerLink]="['Savings Transactions']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--emerald"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Savings Transactions' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download savings transactions template and upload savings transaction excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Fixed Deposit Transactions -->
|
||||
<a class="org-card" [routerLink]="['Fixed Deposit Transactions']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--teal"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Fixed Deposit Transactions' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download fixed deposit transactions template and upload fixed deposit transaction excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Recurring Deposit Transactions -->
|
||||
<a class="org-card" [routerLink]="['Recurring Deposit Transactions']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--amber"><i class="fas fa-briefcase"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Recurring Deposit Transactions' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download recurring deposit transactions template and upload recurring deposit transaction excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Journal Entries -->
|
||||
<a class="org-card" [routerLink]="['Journal Entries']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--slate"><i class="fas fa-chevron-right"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Journal Entries' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download journal entries template and upload journal entries excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
<!-- Guarantors -->
|
||||
<a class="org-card" [routerLink]="['Guarantors']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--red"><i class="fas fa-chevron-right"></i></div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Guarantors' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Download guarantors template and upload guarantor excel files' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,3 +5,212 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8fafc;
|
||||
$gray-100: #f1f5f9;
|
||||
$gray-400: #94a3b8;
|
||||
$gray-500: #64748b;
|
||||
$gray-700: #334155;
|
||||
$gray-900: #0f172a;
|
||||
|
||||
// ── Container ──
|
||||
.org-container {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
// ── Page Header ──
|
||||
.org-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 28px;
|
||||
|
||||
&__icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, #0d3d78, #1a5276);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
&__sub {
|
||||
font-size: 13px;
|
||||
color: $gray-500;
|
||||
margin: 2px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Card Grid ──
|
||||
.org-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Individual Card ──
|
||||
.org-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 14px 16px;
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #cbd5e1;
|
||||
background: $gray-50;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
|
||||
.org-card__arrow {
|
||||
color: $gray-700;
|
||||
transform: translateX(2px);
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 9px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&--blue {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
&--amber {
|
||||
background: rgba(245, 158, 11, 0.1);
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
&--green {
|
||||
background: rgba(34, 197, 94, 0.1);
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
&--emerald {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
&--purple {
|
||||
background: rgba(139, 92, 246, 0.1);
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
&--indigo {
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
color: #4f46e5;
|
||||
}
|
||||
|
||||
&--slate {
|
||||
background: rgba(100, 116, 139, 0.1);
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
&--orange {
|
||||
background: rgba(249, 115, 22, 0.1);
|
||||
color: #ea580c;
|
||||
}
|
||||
|
||||
&--teal {
|
||||
background: rgba(20, 184, 166, 0.1);
|
||||
color: #0d9488;
|
||||
}
|
||||
|
||||
&--cyan {
|
||||
background: rgba(6, 182, 212, 0.1);
|
||||
color: #0891b2;
|
||||
}
|
||||
|
||||
&--rose {
|
||||
background: rgba(244, 63, 94, 0.1);
|
||||
color: #e11d48;
|
||||
}
|
||||
|
||||
&--red {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
|
||||
&__body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 13.5px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
&__desc {
|
||||
font-size: 11.5px;
|
||||
color: $gray-400;
|
||||
margin: 3px 0 0;
|
||||
line-height: 1.35;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&__arrow {
|
||||
font-size: 11px;
|
||||
color: #cbd5e1;
|
||||
flex-shrink: 0;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Dark mode ──
|
||||
:host-context(.dark-theme) {
|
||||
.org-header {
|
||||
&__title { color: #e2e8f0; }
|
||||
&__sub { color: #94a3b8; }
|
||||
}
|
||||
|
||||
.org-card {
|
||||
background: #1e1e1e;
|
||||
border-color: #333;
|
||||
|
||||
&:hover {
|
||||
background: #262626;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
&__title { color: #e2e8f0; }
|
||||
&__desc { color: #64748b; }
|
||||
&__arrow { color: #444; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
|
||||
/** Angular Imports */
|
||||
import { Component } from '@angular/core';
|
||||
import { MatNavList, MatListItem } from '@angular/material/list';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { MatLine } from '@angular/material/grid-list';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/**
|
||||
@@ -22,27 +18,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
templateUrl: './bulk-import.component.html',
|
||||
styleUrls: ['./bulk-import.component.scss'],
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
MatNavList,
|
||||
MatListItem,
|
||||
MatIcon,
|
||||
FaIconComponent,
|
||||
MatLine
|
||||
...STANDALONE_SHARED_IMPORTS
|
||||
]
|
||||
})
|
||||
export class BulkImportComponent {
|
||||
// Initialize an array of 17 boolean values, all set to false
|
||||
arrowBooleans: boolean[] = new Array(17).fill(false);
|
||||
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Popover function
|
||||
* @param arrowNumber - The index of the boolean value to toggle.
|
||||
*/
|
||||
|
||||
arrowBooleansToggle(arrowNumber: number) {
|
||||
// Toggle the boolean value at the given index
|
||||
this.arrowBooleans[arrowNumber] = !this.arrowBooleans[arrowNumber];
|
||||
}
|
||||
}
|
||||
export class BulkImportComponent {}
|
||||
|
||||
@@ -6,18 +6,28 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="bl-container">
|
||||
<div class="bl-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="bl-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Organization' | translate }}
|
||||
</button>
|
||||
<h2 class="bl-header__title">Bulk Loan Reassignment</h2>
|
||||
</div>
|
||||
|
||||
<div class="bl-card">
|
||||
<form [formGroup]="bulkLoanForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<!-- Section 1: Assignment Details -->
|
||||
<div class="bl-section">
|
||||
<div class="bl-section__header">
|
||||
<i class="fas fa-exchange-alt"></i>
|
||||
<h3>Assignment Details</h3>
|
||||
</div>
|
||||
<div class="bl-grid">
|
||||
<mat-form-field appearance="outline" class="bl-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="officeId" (selectionChange)="getOffice($event.value)">
|
||||
@for (office of offices; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
<mat-option [value]="office.id">{{ office.name }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (bulkLoanForm.controls.officeId.hasError('required')) {
|
||||
@@ -27,10 +37,8 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48" (click)="assignmentDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="bl-field" (click)="assignmentDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Assignment Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -50,11 +58,9 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
@if (fromLoanOfficers !== undefined) {
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="bl-field">
|
||||
<mat-label>{{ 'labels.inputs.From loan officer' | translate }}</mat-label>
|
||||
<mat-select
|
||||
required
|
||||
@@ -62,9 +68,7 @@
|
||||
(selectionChange)="getFromOfficers($event.value)"
|
||||
>
|
||||
@for (fromOfficers of fromLoanOfficers; track fromOfficers) {
|
||||
<mat-option [value]="fromOfficers.id">
|
||||
{{ fromOfficers.displayName }}
|
||||
</mat-option>
|
||||
<mat-option [value]="fromOfficers.id">{{ fromOfficers.displayName }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (bulkLoanForm.controls.fromLoanOfficerId.hasError('required')) {
|
||||
@@ -75,16 +79,12 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="bl-field">
|
||||
<mat-label>{{ 'labels.inputs.To loan officer' | translate }}</mat-label>
|
||||
<mat-select required formControlName="toLoanOfficerId">
|
||||
@for (toOfficers of toLoanOfficers; track toOfficers) {
|
||||
<mat-option [value]="toOfficers.id">
|
||||
{{ toOfficers.displayName }}
|
||||
</mat-option>
|
||||
<mat-option [value]="toOfficers.id">{{ toOfficers.displayName }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (bulkLoanForm.controls.toLoanOfficerId.hasError('required')) {
|
||||
@@ -95,84 +95,71 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
@if (officerTemplate !== undefined) {
|
||||
<table class="flex-48">
|
||||
<thead>
|
||||
<th>{{ 'labels.inputs.Clients' | translate }}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Section 2: Loan Selection -->
|
||||
@if (officerTemplate !== undefined) {
|
||||
<div class="bl-section">
|
||||
<div class="bl-section__header">
|
||||
<i class="fas fa-list-check"></i>
|
||||
<h3>Loan Selection</h3>
|
||||
</div>
|
||||
<div class="bl-tables">
|
||||
<div class="bl-loan-table">
|
||||
<div class="bl-loan-table__header">{{ 'labels.inputs.Clients' | translate }}</div>
|
||||
<div class="bl-loan-table__body">
|
||||
@for (clients of officerTemplate.accountSummaryCollection.clients; track clients) {
|
||||
<tr>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<strong> {{ clients.displayName }} </strong>
|
||||
</td>
|
||||
</tr>
|
||||
@for (loans of clients.loans; track loans) {
|
||||
<tr>
|
||||
<td>
|
||||
<mat-checkbox (change)="getLoans($event, loans.id)"
|
||||
>{{ loans.productName }}({{ loans.accountNo }})</mat-checkbox
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
</tr>
|
||||
<div class="bl-loan-group">
|
||||
<div class="bl-loan-group__name">{{ clients.displayName }}</div>
|
||||
@for (loans of clients.loans; track loans) {
|
||||
<div class="bl-loan-group__item">
|
||||
<mat-checkbox (change)="getLoans($event, loans.id)">
|
||||
{{ loans.productName }}({{ loans.accountNo }})
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (officerTemplate !== undefined) {
|
||||
<table class="flex-48">
|
||||
<thead>
|
||||
<th>{{ 'labels.inputs.Groups' | translate }}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<div class="bl-loan-table">
|
||||
<div class="bl-loan-table__header">{{ 'labels.inputs.Groups' | translate }}</div>
|
||||
<div class="bl-loan-table__body">
|
||||
@for (groups of officerTemplate.accountSummaryCollection.groups; track groups) {
|
||||
<tr>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<strong> {{ groups.displayName }} </strong>
|
||||
</td>
|
||||
</tr>
|
||||
@for (loans of groups.loans; track loans) {
|
||||
<tr>
|
||||
<td>
|
||||
<mat-checkbox (change)="getLoans($event, loans.id)"
|
||||
>{{ loans.productName }}({{ loans.accountNo }})</mat-checkbox
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
</tr>
|
||||
<div class="bl-loan-group">
|
||||
<div class="bl-loan-group__name">{{ groups.displayName }}</div>
|
||||
@for (loans of groups.loans; track loans) {
|
||||
<div class="bl-loan-group__item">
|
||||
<mat-checkbox (change)="getLoans($event, loans.id)">
|
||||
{{ loans.productName }}({{ loans.accountNo }})
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
}
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<!-- Footer Actions -->
|
||||
<div class="bl-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="bl-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
class="bl-actions__submit"
|
||||
[disabled]="!bulkLoanForm.valid"
|
||||
*mifosxHasPermission="'BULKREASSIGN_LOAN'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+189
-19
@@ -6,32 +6,202 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 16px 12px;
|
||||
}
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.container > mat-card {
|
||||
width: 100%;
|
||||
max-width: 560px;
|
||||
.bl-container {
|
||||
max-width: 860px;
|
||||
margin: 0 auto;
|
||||
border-radius: 4px;
|
||||
padding: 16px 20px;
|
||||
box-shadow:
|
||||
0 1px 3px rgb(16 24 40 / 10%),
|
||||
0 1px 2px rgb(16 24 40 / 6%);
|
||||
padding: 28px 24px;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
.bl-header {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&__title {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 16px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.bl-back {
|
||||
border: 1px solid $border !important;
|
||||
color: $gray-700 !important;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px !important;
|
||||
padding: 4px 14px !important;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
i {
|
||||
margin-right: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $gray-50 !important;
|
||||
border-color: $gray-500 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.bl-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 12px;
|
||||
padding: 0;
|
||||
box-shadow: 0 1px 3px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
|
||||
}
|
||||
|
||||
.bl-section {
|
||||
padding: 24px 28px;
|
||||
border-bottom: 1px solid $border;
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bl-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4px 20px;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.bl-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flex-48 {
|
||||
flex: 1 1 100%;
|
||||
min-width: 100%;
|
||||
// Loan selection tables
|
||||
.bl-tables {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
.bl-loan-table {
|
||||
border: 1px solid $border;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
&__header {
|
||||
background: $gray-50;
|
||||
padding: 12px 16px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: $gray-700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.4px;
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
&__body {
|
||||
padding: 8px 0;
|
||||
max-height: 360px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.bl-loan-group {
|
||||
padding: 0 16px;
|
||||
|
||||
&__name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
padding: 10px 0 4px;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
padding: 4px 0 4px 8px;
|
||||
font-size: 13px;
|
||||
color: $gray-700;
|
||||
|
||||
mat-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bl-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 18px 28px;
|
||||
|
||||
&__cancel {
|
||||
border: 1px solid $border !important;
|
||||
color: $gray-700 !important;
|
||||
border-radius: 8px !important;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
padding: 4px 20px !important;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: $gray-50 !important;
|
||||
border-color: $gray-500 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&__submit {
|
||||
background: $primary !important;
|
||||
color: #fff !important;
|
||||
border-radius: 8px !important;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
padding: 4px 20px !important;
|
||||
box-shadow: 0 1px 2px rgba(19, 83, 160, 0.15);
|
||||
transition: all 0.2s ease;
|
||||
|
||||
i {
|
||||
margin-right: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #0f4688 !important;
|
||||
box-shadow: 0 2px 6px rgba(19, 83, 160, 0.25);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: $gray-200 !important;
|
||||
color: $gray-500 !important;
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,40 +6,50 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<div #buttonAddEdit class="in-block">
|
||||
<button mat-raised-button color="primary" [routerLink]="'manage'" *mifosxHasPermission="'UPDATE_CURRENCY'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Add/Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div #filter class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-cogs title-icon"></i>
|
||||
{{ 'labels.heading.Currency Configuration' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-buttons">
|
||||
<div #buttonAddEdit class="in-block">
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="'manage'" *mifosxHasPermission="'UPDATE_CURRENCY'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Add/Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div #tableCurrencies class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Currency Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let currency">{{ currency.name }}</td>
|
||||
</ng-container>
|
||||
<div #filter class="table-container">
|
||||
<div #tableCurrencies>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Currency Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let currency">{{ currency.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="code">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Currency Code' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let currency">{{ currency.code }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="code">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Currency Code' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let currency">{{ currency.code }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
+86
-60
@@ -6,72 +6,98 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div #currencyFormRef class="currency-form-container">
|
||||
<form #formRef="ngForm" [formGroup]="currencyForm" class="layout-row gap-20px" (ngSubmit)="addCurrency()">
|
||||
<mat-form-field class="currency-search-field">
|
||||
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
|
||||
<mat-select required formControlName="currency">
|
||||
<mat-option>
|
||||
<ngx-mat-select-search
|
||||
placeholderLabel="{{ placeHolderLabel }}"
|
||||
noEntriesFoundLabel="{{ noEntriesFoundLabel }}"
|
||||
[formControl]="filterFormCtrl"
|
||||
></ngx-mat-select-search>
|
||||
</mat-option>
|
||||
@for (currency of currencyData | async; track currency) {
|
||||
<mat-option [value]="currency"> ({{ currency.code }}) {{ currency.name }} </mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (currencyForm.controls.currency.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<div class="mc-container">
|
||||
<!-- Header -->
|
||||
<div class="mc-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="mc-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Currency Configuration' | translate }}
|
||||
</button>
|
||||
<h2 class="mc-header__title">{{ 'labels.buttons.Add/Edit' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
class="add-currency-button"
|
||||
color="primary"
|
||||
[disabled]="!currencyForm.valid"
|
||||
[attr.aria-label]="'labels.buttons.Add Currency' | translate"
|
||||
[title]="'labels.buttons.Add Currency' | translate"
|
||||
*mifosxHasPermission="'UPDATE_CURRENCY'"
|
||||
>
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
</button>
|
||||
</form>
|
||||
<!-- Card -->
|
||||
<div class="mc-card">
|
||||
<!-- Add Currency Section -->
|
||||
<div class="mc-section">
|
||||
<div class="mc-section__header">
|
||||
<i class="fas fa-plus-circle"></i>
|
||||
<h3>{{ 'labels.buttons.Add Currency' | translate }}</h3>
|
||||
</div>
|
||||
<div class="mc-add" #currencyFormRef>
|
||||
<form #formRef="ngForm" [formGroup]="currencyForm" (ngSubmit)="addCurrency()" class="mc-add__form">
|
||||
<mat-form-field appearance="outline" class="mc-add__field">
|
||||
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
|
||||
<mat-select required formControlName="currency">
|
||||
<mat-option>
|
||||
<ngx-mat-select-search
|
||||
placeholderLabel="{{ placeHolderLabel }}"
|
||||
noEntriesFoundLabel="{{ noEntriesFoundLabel }}"
|
||||
[formControl]="filterFormCtrl"
|
||||
></ngx-mat-select-search>
|
||||
</mat-option>
|
||||
@for (currency of currencyData | async; track currency) {
|
||||
<mat-option [value]="currency"> ({{ currency.code }}) {{ currency.name }} </mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (currencyForm.controls.currency.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
class="mc-add__btn"
|
||||
[disabled]="!currencyForm.valid"
|
||||
[attr.aria-label]="'labels.buttons.Add Currency' | translate"
|
||||
[title]="'labels.buttons.Add Currency' | translate"
|
||||
*mifosxHasPermission="'UPDATE_CURRENCY'"
|
||||
>
|
||||
<i class="fas fa-plus"></i> Add
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-grid-list cols="2" rowHeight="50px">
|
||||
@for (currency of selectedCurrencies; track currency; let i = $index) {
|
||||
<mat-grid-tile class="grid-tile-content">
|
||||
<div class="grid-container">
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
mat-button
|
||||
color="warn"
|
||||
(click)="deleteCurrency(currency.code, i)"
|
||||
[attr.aria-label]="'labels.buttons.Delete' | translate"
|
||||
[title]="'labels.buttons.Delete' | translate"
|
||||
*mifosxHasPermission="'UPDATE_CURRENCY'"
|
||||
>
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
<!-- Selected Currencies Section -->
|
||||
<div class="mc-section">
|
||||
<div class="mc-section__header">
|
||||
<i class="fas fa-coins"></i>
|
||||
<h3>Selected Currencies</h3>
|
||||
</div>
|
||||
<div class="mc-list">
|
||||
@for (currency of selectedCurrencies; track currency; let i = $index) {
|
||||
<div class="mc-currency">
|
||||
<div class="mc-currency__info">
|
||||
<span class="mc-currency__code">{{ currency.code }}</span>
|
||||
<span class="mc-currency__name">{{ currency.name }}</span>
|
||||
</div>
|
||||
<span class="label m-l-10 p-t-5"
|
||||
><b>{{ currency.name }}</b></span
|
||||
<button
|
||||
type="button"
|
||||
mat-icon-button
|
||||
class="mc-currency__delete"
|
||||
(click)="deleteCurrency(currency.code, i)"
|
||||
[attr.aria-label]="'labels.buttons.Delete' | translate"
|
||||
[title]="'labels.buttons.Delete' | translate"
|
||||
*mifosxHasPermission="'UPDATE_CURRENCY'"
|
||||
>
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</mat-grid-tile>
|
||||
}
|
||||
</mat-grid-list>
|
||||
</mat-card>
|
||||
}
|
||||
@if (!selectedCurrencies || selectedCurrencies.length === 0) {
|
||||
<div class="mc-empty">
|
||||
<i class="fas fa-coins"></i>
|
||||
<p>No currencies selected</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #templateCurrencyFormRef let-popover="popover">
|
||||
|
||||
+105
-30
@@ -6,46 +6,121 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
width: 74rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.mc-container { max-width: 700px; margin: 0 auto; padding: 20px 16px; }
|
||||
|
||||
.mc-header {
|
||||
display: flex; align-items: center; gap: 14px; margin-bottom: 20px;
|
||||
&__title { font-size: 18px; font-weight: 600; color: $gray-900; margin: 0; }
|
||||
}
|
||||
|
||||
.currency-form-container {
|
||||
padding: 16px 24px;
|
||||
margin-bottom: 16px;
|
||||
.mc-back {
|
||||
border-radius: 8px !important; font-size: 12px !important; font-weight: 600 !important;
|
||||
height: 32px !important; border-color: $border !important; color: $gray-500 !important;
|
||||
i { margin-right: 6px; }
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.currency-search-field {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
margin-right: 20px;
|
||||
.mc-card { background: #fff; border: 1px solid $border; border-radius: 10px; overflow: hidden; }
|
||||
|
||||
.mc-section {
|
||||
&__header {
|
||||
display: flex; align-items: center; gap: 10px; padding: 12px 24px;
|
||||
background: $gray-50; border-bottom: 1px solid $gray-200;
|
||||
i { font-size: 14px; color: $accent; }
|
||||
h3 { margin: 0; font-size: 14px; font-weight: 600; color: $gray-900; }
|
||||
}
|
||||
& + & { border-top: 1px solid $gray-200; }
|
||||
}
|
||||
|
||||
.add-currency-button {
|
||||
// Add currency form
|
||||
.mc-add { padding: 16px 24px; }
|
||||
|
||||
.mc-add__form {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.mc-add__field { flex: 1; width: 100%; }
|
||||
|
||||
.mc-add__btn {
|
||||
flex-shrink: 0;
|
||||
min-width: 56px;
|
||||
width: 56px;
|
||||
padding: 0;
|
||||
height: 36px !important;
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
margin-top: 4px;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
|
||||
// Currency list
|
||||
.mc-list { padding: 8px 24px 16px; }
|
||||
|
||||
.mc-currency {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-self: center;
|
||||
margin-bottom: 35px;
|
||||
justify-content: space-between;
|
||||
padding: 10px 14px;
|
||||
background: $gray-50;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 6px;
|
||||
transition: background 0.12s;
|
||||
|
||||
&:hover { background: #f1f5f9; }
|
||||
|
||||
&__info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
&__code {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: $primary;
|
||||
background: rgba($primary, 0.08);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
letter-spacing: 0.5px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
&__delete {
|
||||
color: #ef4444 !important;
|
||||
width: 32px !important;
|
||||
height: 32px !important;
|
||||
line-height: 32px !important;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover { background: rgba(239, 68, 68, 0.08) !important; }
|
||||
}
|
||||
}
|
||||
|
||||
.currency-grid {
|
||||
max-width: 40%;
|
||||
justify-content: left !important;
|
||||
}
|
||||
|
||||
mat-grid-tile {
|
||||
justify-content: left !important;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
.mc-empty {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: left;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 32px 16px;
|
||||
color: #cbd5e1;
|
||||
|
||||
i { font-size: 28px; margin-bottom: 8px; }
|
||||
p { font-size: 13px; color: $gray-500; margin: 0; }
|
||||
}
|
||||
|
||||
@@ -6,29 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<form [formGroup]="employeeForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div #createEmployeeFormRef class="layout-column">
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="officeId">
|
||||
@for (office of officeData; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (employeeForm.controls.officeId.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<div class="ce-container">
|
||||
<!-- Header -->
|
||||
<div class="ce-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ce-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Employees' | translate }}
|
||||
</button>
|
||||
<h2 class="ce-header__title">{{ 'labels.heading.Create Employee' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<mat-form-field>
|
||||
<!-- Form Card -->
|
||||
<div class="ce-card">
|
||||
<form [formGroup]="employeeForm" (ngSubmit)="submit()">
|
||||
<!-- Personal Details Section -->
|
||||
<div class="ce-section">
|
||||
<div class="ce-section__header">
|
||||
<i class="fas fa-user"></i>
|
||||
<h3>Personal Details</h3>
|
||||
</div>
|
||||
<div class="ce-grid" #createEmployeeFormRef>
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.First Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="firstname" />
|
||||
@if (employeeForm.controls.firstname.hasError('required')) {
|
||||
@@ -45,7 +42,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Last Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="lastname" />
|
||||
@if (employeeForm.controls.lastname.hasError('required')) {
|
||||
@@ -61,26 +58,34 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-checkbox labelPosition="before" formControlName="isLoanOfficer" class="loan-officer">
|
||||
{{ 'labels.inputs.Is Loan Officer' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Mobile Number for SMS' | translate }}</mat-label>
|
||||
<input matInput formControlName="mobileNo" />
|
||||
@if (
|
||||
employeeForm.controls.mobileNo.hasError('pattern') &&
|
||||
(employeeForm.controls.mobileNo.dirty || employeeForm.controls.mobileNo.touched)
|
||||
) {
|
||||
<!-- Assignment Section -->
|
||||
<div class="ce-section">
|
||||
<div class="ce-section__header">
|
||||
<i class="fas fa-sitemap"></i>
|
||||
<h3>Assignment</h3>
|
||||
</div>
|
||||
<div class="ce-grid">
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="officeId">
|
||||
@for (office of officeData; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (employeeForm.controls.officeId.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Mobile Number for SMS' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.invalid' | translate }}</strong>
|
||||
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field (click)="joiningDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="ce-field" (click)="joiningDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Joining Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -99,24 +104,47 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="ce-checkbox-row">
|
||||
<mat-checkbox labelPosition="after" formControlName="isLoanOfficer">
|
||||
{{ 'labels.inputs.Is Loan Officer' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline" class="ce-field ce-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Mobile Number for SMS' | translate }}</mat-label>
|
||||
<input matInput formControlName="mobileNo" />
|
||||
@if (
|
||||
employeeForm.controls.mobileNo.hasError('pattern') &&
|
||||
(employeeForm.controls.mobileNo.dirty || employeeForm.controls.mobileNo.touched)
|
||||
) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Mobile Number for SMS' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.invalid' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="ce-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ce-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!employeeForm.valid"
|
||||
*mifosxHasPermission="'CREATE_STAFF'"
|
||||
class="ce-actions__submit"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #templateCreateEmployeeForm let-popover="popover">
|
||||
|
||||
@@ -6,10 +6,140 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.ce-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.loan-officer {
|
||||
padding: 17.5px 0;
|
||||
// Header
|
||||
.ce-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ce-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.ce-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.ce-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.ce-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ce-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.ce-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
padding: 8px 0;
|
||||
flex-wrap: wrap;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.ce-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,29 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<form [formGroup]="editEmployeeForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="officeId">
|
||||
@for (office of officeData; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (editEmployeeForm.controls.officeId.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<div class="ee-container">
|
||||
<!-- Header -->
|
||||
<div class="ee-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ee-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Employees' | translate }}
|
||||
</button>
|
||||
<h2 class="ee-header__title">{{ 'labels.heading.Edit Employee' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<mat-form-field>
|
||||
<!-- Form Card -->
|
||||
<div class="ee-card">
|
||||
<form [formGroup]="editEmployeeForm" (ngSubmit)="submit()">
|
||||
<!-- Personal Details Section -->
|
||||
<div class="ee-section">
|
||||
<div class="ee-section__header">
|
||||
<i class="fas fa-user"></i>
|
||||
<h3>Personal Details</h3>
|
||||
</div>
|
||||
<div class="ee-grid">
|
||||
<mat-form-field appearance="outline" class="ee-field">
|
||||
<mat-label>{{ 'labels.inputs.First Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="firstname" />
|
||||
@if (editEmployeeForm.controls.firstname.hasError('required')) {
|
||||
@@ -45,7 +42,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ee-field">
|
||||
<mat-label>{{ 'labels.inputs.Last Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="lastname" />
|
||||
@if (editEmployeeForm.controls.lastname.hasError('required')) {
|
||||
@@ -61,21 +58,34 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-checkbox labelPosition="before" formControlName="isLoanOfficer" class="m-b-10">
|
||||
{{ 'labels.inputs.Is Loan Officer' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Mobile Number for SMS' | translate }}</mat-label>
|
||||
<input matInput formControlName="mobileNo" />
|
||||
<!-- Assignment Section -->
|
||||
<div class="ee-section">
|
||||
<div class="ee-section__header">
|
||||
<i class="fas fa-sitemap"></i>
|
||||
<h3>Assignment</h3>
|
||||
</div>
|
||||
<div class="ee-grid">
|
||||
<mat-form-field appearance="outline" class="ee-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="officeId">
|
||||
@for (office of officeData; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
@if (editEmployeeForm.controls.officeId.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox labelPosition="before" formControlName="isActive">
|
||||
{{ 'labels.inputs.Active' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field (click)="joiningDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="ee-field" (click)="joiningDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Joining Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -94,22 +104,40 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="ee-checkbox-row">
|
||||
<mat-checkbox labelPosition="after" formControlName="isLoanOfficer">
|
||||
{{ 'labels.inputs.Is Loan Officer' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-checkbox labelPosition="after" formControlName="isActive">
|
||||
{{ 'labels.inputs.Active' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline" class="ee-field ee-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Mobile Number for SMS' | translate }}</mat-label>
|
||||
<input matInput formControlName="mobileNo" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="ee-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ee-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!editEmployeeForm.valid"
|
||||
*mifosxHasPermission="'UPDATE_STAFF'"
|
||||
class="ee-actions__submit"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,140 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.ee-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.ee-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ee-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.ee-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.ee-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.ee-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ee-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.ee-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
padding: 8px 0;
|
||||
flex-wrap: wrap;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.ee-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,36 +6,41 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<div #buttonImportEmployees>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
*mifosxHasPermission="'CREATE_STAFF'"
|
||||
[routerLink]="['/', 'organization', 'bulk-import', 'Employees']"
|
||||
>
|
||||
<fa-icon icon="upload" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Import Employees' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div #buttonCreateEmployee>
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_STAFF'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Employee' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div #filter class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-user title-icon"></i>
|
||||
{{ 'labels.heading.Manage Employees' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<div #filter class="table-search">
|
||||
<mat-form-field appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="table-buttons">
|
||||
<div #buttonImportEmployees>
|
||||
<button mat-stroked-button class="btn-import" *mifosxHasPermission="'CREATE_STAFF'" [routerLink]="['/', 'organization', 'bulk-import', 'Employees']">
|
||||
<fa-icon icon="upload" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Import Employees' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div #buttonCreateEmployee>
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['create']" *mifosxHasPermission="'CREATE_STAFF'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Employee' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div #tableEmployees class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<div #tableEmployees class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="firstname">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.First Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let employee">{{ employee.firstname }}</td>
|
||||
@@ -90,9 +95,8 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="select-row"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
@@ -6,77 +6,76 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_STAFF'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="ve-container">
|
||||
<!-- Header -->
|
||||
<div class="ve-header">
|
||||
<div class="ve-header__left">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ve-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Employees' | translate }}
|
||||
</button>
|
||||
<h2 class="ve-header__title">{{ employeeData.firstname }} {{ employeeData.lastname }}</h2>
|
||||
</div>
|
||||
<button mat-flat-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_STAFF'" class="ve-header__edit">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap">
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.First Name' | translate }}
|
||||
</div>
|
||||
<!-- Detail Card -->
|
||||
<div class="ve-card">
|
||||
<div class="ve-grid">
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.First Name' | translate }}</div>
|
||||
<div class="ve-cell__value">{{ employeeData.firstname }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ employeeData.firstname }}
|
||||
</div>
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.Last Name' | translate }}</div>
|
||||
<div class="ve-cell__value">{{ employeeData.lastname }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Last Name' | translate }}
|
||||
</div>
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.Office' | translate }}</div>
|
||||
<div class="ve-cell__value">{{ employeeData.officeName }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ employeeData.lastname }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Office' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ employeeData.officeName }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Is Loan Officer' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ employeeData.isLoanOfficer === true | yesNo }}
|
||||
</div>
|
||||
|
||||
@if (employeeData.mobileNo) {
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Mobile Number for SMS' | translate }}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (employeeData.mobileNo) {
|
||||
<div class="flex-50">
|
||||
{{ employeeData.mobileNo }}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Status' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ employeeData.isActive === true ? 'Active' : 'Inactive' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Joining Date' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ employeeData.joiningDate | dateFormat }}
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.Is Loan Officer' | translate }}</div>
|
||||
<div class="ve-cell__value">
|
||||
@if (employeeData.isLoanOfficer) {
|
||||
<span class="ve-bool ve-bool--yes">
|
||||
<i class="fas fa-check"></i> Yes
|
||||
</span>
|
||||
} @else {
|
||||
<span class="ve-bool ve-bool--no">
|
||||
<i class="fas fa-times"></i> No
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
@if (employeeData.mobileNo) {
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.Mobile Number for SMS' | translate }}</div>
|
||||
<div class="ve-cell__value">{{ employeeData.mobileNo }}</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.Status' | translate }}</div>
|
||||
<div class="ve-cell__value">
|
||||
@if (employeeData.isActive) {
|
||||
<span class="ve-badge ve-badge--active">Active</span>
|
||||
} @else {
|
||||
<span class="ve-badge ve-badge--inactive">Inactive</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ve-cell">
|
||||
<div class="ve-cell__label">{{ 'labels.inputs.Joining Date' | translate }}</div>
|
||||
<div class="ve-cell__value">{{ employeeData.joiningDate | dateFormat }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,13 +6,149 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.content {
|
||||
div {
|
||||
margin: 1rem 0;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.ve-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.ve-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__edit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ve-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.ve-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Grid
|
||||
.ve-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1px;
|
||||
padding: 20px 28px 24px;
|
||||
background: #fff;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ve-cell {
|
||||
padding: 14px 16px;
|
||||
background: #f8fafc;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
margin: 3px;
|
||||
transition: background 0.12s;
|
||||
|
||||
&:hover {
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
// Status badge
|
||||
.ve-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 3px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2px;
|
||||
|
||||
&--active {
|
||||
background: rgba(22, 163, 74, 0.1);
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
&--inactive {
|
||||
background: rgba(220, 38, 38, 0.1);
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
|
||||
// Boolean indicator (Yes/No with icon)
|
||||
.ve-bool {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
|
||||
i { font-size: 11px; }
|
||||
|
||||
&--yes {
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
&--no {
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { Component, inject } from '@angular/core';
|
||||
import { ActivatedRoute, RouterLink } from '@angular/router';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
|
||||
import { YesnoPipe } from '../../../pipes/yesno.pipe';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/**
|
||||
@@ -24,8 +23,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
FaIconComponent,
|
||||
DateFormatPipe,
|
||||
YesnoPipe
|
||||
DateFormatPipe
|
||||
]
|
||||
})
|
||||
export class ViewEmployeeComponent {
|
||||
|
||||
+31
-16
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="ce-container">
|
||||
<!-- Header -->
|
||||
<div class="ce-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ce-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Entity Data Table Checks' | translate }}
|
||||
</button>
|
||||
<h2 class="ce-header__title">{{ 'labels.heading.Create Entity Data Table Check' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="ce-card">
|
||||
<form [formGroup]="createEntityForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<!-- Check Configuration Section -->
|
||||
<div class="ce-section">
|
||||
<div class="ce-section__header">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<h3>Check Configuration</h3>
|
||||
</div>
|
||||
<div class="ce-grid">
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Entity' | translate }}</mat-label>
|
||||
<mat-select required formControlName="entity">
|
||||
@for (entity of entityTypes; track entity) {
|
||||
@@ -28,7 +42,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Status' | translate }}</mat-label>
|
||||
<mat-select required formControlName="status">
|
||||
@for (status of statusList; track status) {
|
||||
@@ -45,7 +59,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Data Table' | translate }}</mat-label>
|
||||
<mat-select required formControlName="datatableName">
|
||||
@for (dataTable of dataTableList; track dataTable) {
|
||||
@@ -63,7 +77,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
@if (entityType === 'm_loan') {
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Products' | translate }}</mat-label>
|
||||
<mat-select required formControlName="productId">
|
||||
@for (loanProducts of createEntityData.loanProductDatas; track loanProducts) {
|
||||
@@ -82,7 +96,7 @@
|
||||
}
|
||||
|
||||
@if (entityType === 'm_savings_account') {
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ce-field">
|
||||
<mat-label>{{ 'labels.inputs.Products' | translate }}</mat-label>
|
||||
<mat-select required formControlName="productId">
|
||||
@for (savingsProducts of createEntityData.savingsProductDatas; track savingsProducts) {
|
||||
@@ -100,16 +114,17 @@
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<!-- Actions -->
|
||||
<div class="ce-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ce-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!createEntityForm.valid">
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!createEntityForm.valid" class="ce-actions__submit">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+116
-2
@@ -6,6 +6,120 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.ce-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.ce-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ce-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.ce-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.ce-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.ce-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ce-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Actions
|
||||
.ce-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
+26
-20
@@ -6,28 +6,34 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[routerLink]="['create']"
|
||||
*mifosxHasPermission="'CREATE_ENTITY_DATATABLE_CHECK'"
|
||||
>
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<mat-card class="container">
|
||||
<!-- Header Bar -->
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-check"></i>
|
||||
{{ 'labels.heading.Entity Data Table Checks' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<input matInput placeholder="{{ 'labels.inputs.Filter' | translate }}" (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" [routerLink]="['create']" class="btn-create" *mifosxHasPermission="'CREATE_ENTITY_DATATABLE_CHECK'">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
{{ 'labels.buttons.Create' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<!-- Table -->
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="entity">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Entity' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let entityDataTableCheck">{{ entityDataTableCheck.entity }}</td>
|
||||
@@ -92,4 +98,4 @@
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -7,314 +7,372 @@
|
||||
-->
|
||||
|
||||
@if (!isCollapsed) {
|
||||
<mat-card class="container">
|
||||
<form [formGroup]="fundMappingForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap gap-2percent responsive-column align-start-center">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Loan Status' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanStatus" multiple>
|
||||
<mat-option value="all">{{ 'labels.inputs.All' | translate }}</mat-option>
|
||||
<mat-option value="active">{{ 'labels.inputs.Active' | translate }}</mat-option>
|
||||
<mat-option value="closed">{{ 'labels.inputs.Overpaid' | translate }}</mat-option>
|
||||
<mat-option value="overpaid">{{ 'labels.inputs.Closed (obligations met)' | translate }}</mat-option>
|
||||
<mat-option value="writeoff">{{ 'labels.inputs.Closed (written-off)' | translate }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<span class="flex-48 hide-lt-md"></span>
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Product' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanProducts" multiple>
|
||||
@for (product of advanceSearchTemplate.loanProducts; track product) {
|
||||
<mat-option [value]="product.id">
|
||||
{{ product.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select formControlName="offices" multiple>
|
||||
@for (office of advanceSearchTemplate.offices; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Date Type' | translate }}</mat-label>
|
||||
<mat-select required formControlName="loanDateOption">
|
||||
<mat-option value="approvalDate">{{ 'labels.inputs.Approval Date' | translate }}</mat-option>
|
||||
<mat-option value="createdDate">{{ 'labels.inputs.Creation Date' | translate }}</mat-option>
|
||||
<mat-option value="disbursalDate">{{ 'labels.inputs.Disbursement Date' | translate }}</mat-option>
|
||||
</mat-select>
|
||||
@if (fundMappingForm.controls.loanDateOption.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Date Type' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-31" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="fromDatePicker"
|
||||
formControlName="loanFromDate"
|
||||
required
|
||||
placeholder="{{ 'labels.inputs.From Date' | translate }}"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #fromDatePicker></mat-datepicker>
|
||||
@if (fundMappingForm.controls.loanFromDate.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.From Date' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-31" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="toDatePicker"
|
||||
formControlName="loanToDate"
|
||||
required
|
||||
placeholder="{{ 'labels.inputs.To Date' | translate }}"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="toDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #toDatePicker></mat-datepicker>
|
||||
@if (fundMappingForm.controls.loanToDate.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.To Date' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<mat-checkbox
|
||||
labelPosition="before"
|
||||
formControlName="includeOutStandingAmountPercentage"
|
||||
class="margin-b flex-73"
|
||||
>
|
||||
{{ 'labels.inputs.Loan Outstanding Percentage' | translate }}
|
||||
</mat-checkbox>
|
||||
@if (fundMappingForm.value.includeOutStandingAmountPercentage) {
|
||||
<div class="flex-fill layout-row-wrap gap-2percent layout-xs-column">
|
||||
@if (fundMappingForm.contains('outStandingAmountPercentageCondition')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Condition' | translate }}</mat-label>
|
||||
<mat-select required formControlName="outStandingAmountPercentageCondition">
|
||||
<mat-option value="between">{{ 'labels.inputs.between' | translate }}</mat-option>
|
||||
<mat-option value="<="><=</mat-option>
|
||||
<mat-option value=">=">>=</mat-option>
|
||||
<mat-option value="<"><</mat-option>
|
||||
<mat-option value=">">></mat-option>
|
||||
<mat-option value="=">=</mat-option>
|
||||
</mat-select>
|
||||
@if (fundMappingForm.controls.outStandingAmountPercentageCondition.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Condition' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
<div class="fm-container">
|
||||
<!-- Header -->
|
||||
<div class="fm-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="fm-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<h2 class="fm-header__title">Fund Mapping</h2>
|
||||
</div>
|
||||
|
||||
@if (fundMappingForm.contains('minOutStandingAmountPercentage')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Minimum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="minOutStandingAmountPercentage"
|
||||
placeholder="{{ 'labels.inputs.Minimum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.minOutStandingAmountPercentage.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Minimum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('outStandingAmountPercentage')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="outStandingAmountPercentage"
|
||||
placeholder="{{ 'labels.inputs.Comparison Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.outStandingAmountPercentage.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('maxOutStandingAmountPercentage')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Maximum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="maxOutStandingAmountPercentage"
|
||||
placeholder="{{ 'labels.inputs.Maximum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.maxOutStandingAmountPercentage.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Maximum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<mat-checkbox class="flex-73 margin-b" labelPosition="before" formControlName="includeOutstandingAmount">
|
||||
{{ 'labels.inputs.Loan Outstanding Amount' | translate }}
|
||||
</mat-checkbox>
|
||||
@if (fundMappingForm.value.includeOutstandingAmount) {
|
||||
<div class="flex-fill layout-row-wrap gap-2percent responsive-column">
|
||||
@if (fundMappingForm.contains('outstandingAmountCondition')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Condition' | translate }}</mat-label>
|
||||
<mat-select required formControlName="outstandingAmountCondition">
|
||||
<mat-option value="between">{{ 'labels.inputs.between' | translate }}</mat-option>
|
||||
<mat-option value="<="><=</mat-option>
|
||||
<mat-option value=">=">>=</mat-option>
|
||||
<mat-option value="<"><</mat-option>
|
||||
<mat-option value=">">></mat-option>
|
||||
<mat-option value="=">=</mat-option>
|
||||
</mat-select>
|
||||
@if (fundMappingForm.controls.outstandingAmountCondition.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Condition' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
<!-- Form Card -->
|
||||
<div class="fm-card">
|
||||
<form [formGroup]="fundMappingForm" (ngSubmit)="submit()">
|
||||
<!-- Section 1: Filter Criteria -->
|
||||
<div class="fm-section">
|
||||
<div class="fm-section__header">
|
||||
<i class="fas fa-filter"></i>
|
||||
<h3>Filter Criteria</h3>
|
||||
</div>
|
||||
<div class="fm-grid fm-grid--3col">
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Loan Status' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanStatus" multiple>
|
||||
<mat-option value="all">{{ 'labels.inputs.All' | translate }}</mat-option>
|
||||
<mat-option value="active">{{ 'labels.inputs.Active' | translate }}</mat-option>
|
||||
<mat-option value="closed">{{ 'labels.inputs.Overpaid' | translate }}</mat-option>
|
||||
<mat-option value="overpaid">{{ 'labels.inputs.Closed (obligations met)' | translate }}</mat-option>
|
||||
<mat-option value="writeoff">{{ 'labels.inputs.Closed (written-off)' | translate }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
@if (fundMappingForm.contains('minOutstandingAmount')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Minimum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="minOutstandingAmount"
|
||||
placeholder="{{ 'labels.inputs.Minimum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.minOutstandingAmount.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Minimum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('outstandingAmount')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="outstandingAmount"
|
||||
placeholder="{{ 'labels.inputs.Comparison Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.outstandingAmount.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('maxOutstandingAmount')) {
|
||||
<mat-form-field class="flex-31">
|
||||
<mat-label>{{ 'labels.inputs.Maximum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="maxOutstandingAmount"
|
||||
placeholder="{{ 'labels.inputs.Maximum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.maxOutstandingAmount.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Maximum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Product' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanProducts" multiple>
|
||||
@for (product of advanceSearchTemplate.loanProducts; track product) {
|
||||
<mat-option [value]="product.id">
|
||||
{{ product.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<mat-select formControlName="offices" multiple>
|
||||
@for (office of advanceSearchTemplate.offices; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" type="submit" [disabled]="!fundMappingForm.valid">
|
||||
<fa-icon icon="search"></fa-icon> {{ 'labels.buttons.Summary' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</form>
|
||||
</mat-card>
|
||||
|
||||
<!-- Section 2: Date Range -->
|
||||
<div class="fm-section">
|
||||
<div class="fm-section__header">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
<h3>Date Range</h3>
|
||||
</div>
|
||||
<div class="fm-grid fm-grid--3col">
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Date Type' | translate }}</mat-label>
|
||||
<mat-select required formControlName="loanDateOption">
|
||||
<mat-option value="approvalDate">{{ 'labels.inputs.Approval Date' | translate }}</mat-option>
|
||||
<mat-option value="createdDate">{{ 'labels.inputs.Creation Date' | translate }}</mat-option>
|
||||
<mat-option value="disbursalDate">{{ 'labels.inputs.Disbursement Date' | translate }}</mat-option>
|
||||
</mat-select>
|
||||
@if (fundMappingForm.controls.loanDateOption.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Date Type' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="fm-field" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="fromDatePicker"
|
||||
formControlName="loanFromDate"
|
||||
required
|
||||
placeholder="{{ 'labels.inputs.From Date' | translate }}"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #fromDatePicker></mat-datepicker>
|
||||
@if (fundMappingForm.controls.loanFromDate.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.From Date' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="fm-field" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="toDatePicker"
|
||||
formControlName="loanToDate"
|
||||
required
|
||||
placeholder="{{ 'labels.inputs.To Date' | translate }}"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="toDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #toDatePicker></mat-datepicker>
|
||||
@if (fundMappingForm.controls.loanToDate.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.To Date' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 3: Outstanding Criteria -->
|
||||
<div class="fm-section">
|
||||
<div class="fm-section__header">
|
||||
<i class="fas fa-percentage"></i>
|
||||
<h3>Outstanding Criteria</h3>
|
||||
</div>
|
||||
<div class="fm-grid">
|
||||
<!-- Loan Outstanding Percentage -->
|
||||
<div class="fm-checkbox-row">
|
||||
<mat-checkbox
|
||||
labelPosition="before"
|
||||
formControlName="includeOutStandingAmountPercentage"
|
||||
>
|
||||
{{ 'labels.inputs.Loan Outstanding Percentage' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
@if (fundMappingForm.value.includeOutStandingAmountPercentage) {
|
||||
<div class="fm-conditional-fields">
|
||||
@if (fundMappingForm.contains('outStandingAmountPercentageCondition')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Condition' | translate }}</mat-label>
|
||||
<mat-select required formControlName="outStandingAmountPercentageCondition">
|
||||
<mat-option value="between">{{ 'labels.inputs.between' | translate }}</mat-option>
|
||||
<mat-option value="<="><=</mat-option>
|
||||
<mat-option value=">=">>=</mat-option>
|
||||
<mat-option value="<"><</mat-option>
|
||||
<mat-option value=">">></mat-option>
|
||||
<mat-option value="=">=</mat-option>
|
||||
</mat-select>
|
||||
@if (fundMappingForm.controls.outStandingAmountPercentageCondition.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Condition' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (fundMappingForm.contains('minOutStandingAmountPercentage')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Minimum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="minOutStandingAmountPercentage"
|
||||
placeholder="{{ 'labels.inputs.Minimum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.minOutStandingAmountPercentage.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Minimum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('outStandingAmountPercentage')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="outStandingAmountPercentage"
|
||||
placeholder="{{ 'labels.inputs.Comparison Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.outStandingAmountPercentage.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('maxOutStandingAmountPercentage')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Maximum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="maxOutStandingAmountPercentage"
|
||||
placeholder="{{ 'labels.inputs.Maximum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.maxOutStandingAmountPercentage.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Maximum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Loan Outstanding Amount -->
|
||||
<div class="fm-checkbox-row">
|
||||
<mat-checkbox
|
||||
labelPosition="before"
|
||||
formControlName="includeOutstandingAmount"
|
||||
>
|
||||
{{ 'labels.inputs.Loan Outstanding Amount' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
@if (fundMappingForm.value.includeOutstandingAmount) {
|
||||
<div class="fm-conditional-fields">
|
||||
@if (fundMappingForm.contains('outstandingAmountCondition')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Condition' | translate }}</mat-label>
|
||||
<mat-select required formControlName="outstandingAmountCondition">
|
||||
<mat-option value="between">{{ 'labels.inputs.between' | translate }}</mat-option>
|
||||
<mat-option value="<="><=</mat-option>
|
||||
<mat-option value=">=">>=</mat-option>
|
||||
<mat-option value="<"><</mat-option>
|
||||
<mat-option value=">">></mat-option>
|
||||
<mat-option value="=">=</mat-option>
|
||||
</mat-select>
|
||||
@if (fundMappingForm.controls.outstandingAmountCondition.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Condition' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (fundMappingForm.contains('minOutstandingAmount')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Minimum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="minOutstandingAmount"
|
||||
placeholder="{{ 'labels.inputs.Minimum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.minOutstandingAmount.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Minimum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('outstandingAmount')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Comparison Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="outstandingAmount"
|
||||
placeholder="{{ 'labels.inputs.Comparison Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.outstandingAmount.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Comparison Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (fundMappingForm.contains('maxOutstandingAmount')) {
|
||||
<mat-form-field appearance="outline" class="fm-field">
|
||||
<mat-label>{{ 'labels.inputs.Maximum Value' | translate }}</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
required
|
||||
min="0"
|
||||
formControlName="maxOutstandingAmount"
|
||||
placeholder="{{ 'labels.inputs.Maximum Value' | translate }}"
|
||||
/>
|
||||
@if (fundMappingForm.controls.maxOutstandingAmount.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Maximum Value' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="fm-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="fm-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!fundMappingForm.valid" class="fm-actions__submit">
|
||||
<i class="fas fa-search"></i> {{ 'labels.buttons.Summary' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (isCollapsed) {
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="m-b-20">
|
||||
<button mat-raised-button color="primary" (click)="isCollapsed = false">
|
||||
{{ 'labels.buttons.Parameters' | translate }}
|
||||
</button>
|
||||
<div class="fm-container">
|
||||
<!-- Header -->
|
||||
<div class="fm-header">
|
||||
<button mat-stroked-button (click)="isCollapsed = false" class="fm-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.buttons.Parameters' | translate }}
|
||||
</button>
|
||||
<h2 class="fm-header__title">Fund Mapping Results</h2>
|
||||
</div>
|
||||
|
||||
<!-- Results Card -->
|
||||
<div class="fm-card">
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="officeName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Office Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.officeName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="productName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Product Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.loanProductName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="count">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Count' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.count }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="outstanding">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Outstanding' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.loanOutStanding }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="percentage">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Percentage' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.percentage }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
<table class="mat-elevation-z1" mat-table [dataSource]="dataSource" matSort>
|
||||
<ng-container matColumnDef="officeName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Office Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.officeName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="productName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Product Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.loanProductName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="count">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Count' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.count }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="outstanding">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Outstanding' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.loanOutStanding }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="percentage">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Percentage' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loan">{{ loan.percentage }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -6,18 +6,188 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 73rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.margin-v {
|
||||
margin: 1em 0;
|
||||
}
|
||||
.fm-container {
|
||||
max-width: 860px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.margin-b {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
// Header
|
||||
.fm-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.fm-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.fm-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.fm-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.fm-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
&--3col {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
&--3col { grid-template-columns: 1fr; }
|
||||
}
|
||||
}
|
||||
|
||||
.fm-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Checkbox row
|
||||
.fm-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
padding: 8px 0;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// Conditional fields
|
||||
.fm-conditional-fields {
|
||||
grid-column: 1 / -1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 0 0 8px;
|
||||
margin-top: -4px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.fm-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
// Results table
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.modern-table {
|
||||
width: 100%;
|
||||
|
||||
th.mat-header-cell {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: $gray-700;
|
||||
background: $gray-50;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.4px;
|
||||
}
|
||||
|
||||
td.mat-cell {
|
||||
font-size: 13px;
|
||||
color: $gray-900;
|
||||
padding: 11px 16px;
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
tr.mat-row:hover {
|
||||
background: rgba($accent, 0.04);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="ch-container">
|
||||
<!-- Header -->
|
||||
<div class="ch-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ch-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Holidays' | translate }}
|
||||
</button>
|
||||
<h2 class="ch-header__title">{{ 'labels.heading.Create Holiday' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="ch-card">
|
||||
<form [formGroup]="holidayForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<!-- Holiday Details Section -->
|
||||
<div class="ch-section">
|
||||
<div class="ch-section__header">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
<h3>{{ 'labels.heading.Holiday Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ch-grid">
|
||||
<mat-form-field appearance="outline" class="ch-field">
|
||||
<mat-label>{{ 'labels.inputs.name' | translate }}</mat-label>
|
||||
<input matInput required autofocus formControlName="name" />
|
||||
@if (holidayForm.controls.name.hasError('required')) {
|
||||
@@ -22,7 +36,12 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field (click)="fromDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="ch-field ch-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<input matInput formControlName="description" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="ch-field" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -42,7 +61,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field (click)="toDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="ch-field" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -61,8 +80,17 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field>
|
||||
<!-- Scheduling Section -->
|
||||
<div class="ch-section">
|
||||
<div class="ch-section__header">
|
||||
<i class="fas fa-clock"></i>
|
||||
<h3>{{ 'labels.heading.Scheduling' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ch-grid">
|
||||
<mat-form-field appearance="outline" class="ch-field">
|
||||
<mat-label>{{ 'labels.inputs.Repayment Scheduling Type' | translate }}</mat-label>
|
||||
<mat-select required formControlName="reschedulingType">
|
||||
@for (repayments of repaymentSchedulingTypes; track repayments) {
|
||||
@@ -80,7 +108,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
@if (holidayForm.contains('repaymentsRescheduledTo')) {
|
||||
<mat-form-field (click)="repaymentDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="ch-field" (click)="repaymentDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Repayment scheduled to' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -100,14 +128,16 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<input matInput formControlName="description" />
|
||||
</mat-form-field>
|
||||
|
||||
<label>{{ 'labels.inputs.Select applicable offices' | translate }}</label>
|
||||
|
||||
<!-- Applicable Offices Section -->
|
||||
<div class="ch-section">
|
||||
<div class="ch-section__header">
|
||||
<i class="fas fa-building"></i>
|
||||
<h3>{{ 'labels.inputs.Select applicable offices' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ch-tree-wrapper">
|
||||
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
|
||||
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding>
|
||||
<button mat-icon-button disabled></button>
|
||||
@@ -131,21 +161,24 @@
|
||||
</mat-tree-node>
|
||||
</mat-tree>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<!-- Actions -->
|
||||
<div class="ch-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ch-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!holidayForm.valid"
|
||||
class="ch-actions__submit"
|
||||
*mifosxHasPermission="'CREATE_HOLIDAY'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,143 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.ch-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.ch-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ch-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.ch-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.ch-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.ch-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ch-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Tree wrapper
|
||||
.ch-tree-wrapper {
|
||||
padding: 16px 24px;
|
||||
|
||||
::ng-deep {
|
||||
.mat-tree {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.mat-tree-node {
|
||||
min-height: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.ch-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="eh-container">
|
||||
<!-- Header -->
|
||||
<div class="eh-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="eh-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Holiday' | translate }}
|
||||
</button>
|
||||
<h2 class="eh-header__title">{{ 'labels.heading.Edit Holiday' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="eh-card">
|
||||
<form [formGroup]="holidayForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<!-- Holiday Details Section -->
|
||||
<div class="eh-section">
|
||||
<div class="eh-section__header">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
<h3>{{ 'labels.heading.Holiday Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="eh-grid">
|
||||
<mat-form-field appearance="outline" class="eh-field">
|
||||
<mat-label>{{ 'labels.inputs.name' | translate }}</mat-label>
|
||||
<input matInput required autofocus formControlName="name" />
|
||||
@if (holidayForm.controls.name.hasError('required')) {
|
||||
@@ -22,8 +36,13 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="eh-field eh-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<input matInput formControlName="description" />
|
||||
</mat-form-field>
|
||||
|
||||
@if (!isActiveHoliday) {
|
||||
<mat-form-field (click)="fromDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="eh-field" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -45,7 +64,7 @@
|
||||
}
|
||||
|
||||
@if (!isActiveHoliday) {
|
||||
<mat-form-field (click)="toDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="eh-field" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -65,9 +84,18 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!isActiveHoliday) {
|
||||
<mat-form-field>
|
||||
<!-- Scheduling Section -->
|
||||
@if (!isActiveHoliday) {
|
||||
<div class="eh-section">
|
||||
<div class="eh-section__header">
|
||||
<i class="fas fa-clock"></i>
|
||||
<h3>{{ 'labels.heading.Scheduling' | translate }}</h3>
|
||||
</div>
|
||||
<div class="eh-grid">
|
||||
<mat-form-field appearance="outline" class="eh-field">
|
||||
<mat-label>{{ 'labels.inputs.Repayment Scheduling Type' | translate }}</mat-label>
|
||||
<mat-select required formControlName="reschedulingType">
|
||||
@for (repayments of holidayData.repaymentSchedulingTypes; track repayments) {
|
||||
@@ -83,50 +111,48 @@
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (!isActiveHoliday && reSchedulingType === 2) {
|
||||
<mat-form-field (click)="repaymentDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Repayment scheduled to' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="repaymentDatePicker"
|
||||
required
|
||||
formControlName="repaymentsRescheduledTo"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="repaymentDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #repaymentDatePicker></mat-datepicker>
|
||||
@if (holidayForm.controls.repaymentsRescheduledTo.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Repayment scheduled to' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<input matInput formControlName="description" />
|
||||
</mat-form-field>
|
||||
@if (reSchedulingType === 2) {
|
||||
<mat-form-field appearance="outline" class="eh-field" (click)="repaymentDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Repayment scheduled to' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="repaymentDatePicker"
|
||||
required
|
||||
formControlName="repaymentsRescheduledTo"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="repaymentDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #repaymentDatePicker></mat-datepicker>
|
||||
@if (holidayForm.controls.repaymentsRescheduledTo.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Repayment scheduled to' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
}
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<!-- Actions -->
|
||||
<div class="eh-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="eh-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!holidayForm.valid"
|
||||
class="eh-actions__submit"
|
||||
*mifosxHasPermission="'UPDATE_HOLIDAY'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,128 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.eh-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.eh-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.eh-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.eh-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.eh-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.eh-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.eh-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.eh-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,35 +6,43 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<div #buttonCreateHoliday class="in-block">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_HOLIDAY'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Holiday' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div #filterRef class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label> {{ 'labels.inputs.Select Office' | translate }} </mat-label>
|
||||
<mat-select [formControl]="officeSelector">
|
||||
@for (office of officeData; track office) {
|
||||
<mat-option [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-calendar-alt title-icon"></i>
|
||||
{{ 'labels.heading.Manage Holidays' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<div #filterRef class="table-search">
|
||||
<mat-form-field appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-form-field appearance="outline" style="min-width: 180px;">
|
||||
<mat-label>{{ 'labels.inputs.Select Office' | translate }}</mat-label>
|
||||
<mat-select [formControl]="officeSelector">
|
||||
@for (office of officeData; track office) {
|
||||
<mat-option [value]="office.id">{{ office.name }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="table-buttons">
|
||||
<div #buttonCreateHoliday>
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['create']" *mifosxHasPermission="'CREATE_HOLIDAY'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Holiday' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8" [hidden]="!officeSelector.value">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<div class="table-container" [hidden]="!officeSelector.value">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Holiday Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let holidays">{{ holidays.name }}</td>
|
||||
@@ -67,9 +75,8 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="select-row" [routerLink]="[row.id]"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row" [routerLink]="[row.id]"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
@@ -6,69 +6,69 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="layout-row align-end gap-2px responsive-column container m-b-20">
|
||||
<div class="vh-container">
|
||||
<!-- Header -->
|
||||
<div class="vh-header">
|
||||
<div class="vh-header__left">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="vh-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Holidays' | translate }}
|
||||
</button>
|
||||
<h2 class="vh-header__title">{{ holidayData.name }}</h2>
|
||||
</div>
|
||||
<button mat-icon-button [matMenuTriggerFor]="actionMenu" class="vh-menu-btn" aria-label="Holiday actions">
|
||||
<fa-icon icon="ellipsis-v"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Detail Card -->
|
||||
<div class="vh-card">
|
||||
<div class="vh-grid">
|
||||
<div class="vh-cell">
|
||||
<div class="vh-cell__label">{{ 'labels.inputs.Name' | translate }}</div>
|
||||
<div class="vh-cell__value">{{ holidayData.name }}</div>
|
||||
</div>
|
||||
|
||||
<div class="vh-cell">
|
||||
<div class="vh-cell__label">{{ 'labels.inputs.From Date' | translate }}</div>
|
||||
<div class="vh-cell__value">{{ holidayData.fromDate | dateFormat }}</div>
|
||||
</div>
|
||||
|
||||
<div class="vh-cell">
|
||||
<div class="vh-cell__label">{{ 'labels.inputs.To Date' | translate }}</div>
|
||||
<div class="vh-cell__value">{{ holidayData.toDate | dateFormat }}</div>
|
||||
</div>
|
||||
|
||||
<div class="vh-cell">
|
||||
<div class="vh-cell__label">{{ 'labels.inputs.Repayments Scheduled To' | translate }}</div>
|
||||
<div class="vh-cell__value">
|
||||
@if (holidayData.repaymentsRescheduledTo !== undefined && holidayData.repaymentsRescheduledTo !== null) {
|
||||
{{ holidayData.repaymentsRescheduledTo | dateFormat }}
|
||||
}
|
||||
@if (holidayData.repaymentsRescheduledTo === undefined || holidayData.repaymentsRescheduledTo === null) {
|
||||
{{ 'labels.inputs.Next Repayment Date' | translate }}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions menu -->
|
||||
<mat-menu #actionMenu="matMenu">
|
||||
<span *mifosxHasPermission="'ACTIVATE_HOLIDAY'">
|
||||
@if (holidayData.status.value !== 'Active') {
|
||||
<button mat-raised-button color="accent" (click)="activateHoliday()">
|
||||
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
|
||||
<button mat-menu-item (click)="activateHoliday()">
|
||||
<fa-icon icon="lock-open" class="vh-menu-icon"></fa-icon>
|
||||
{{ 'labels.buttons.Activate' | translate }}
|
||||
</button>
|
||||
}
|
||||
</span>
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_HOLIDAY'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
<button mat-menu-item [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_HOLIDAY'">
|
||||
<fa-icon icon="edit" class="vh-menu-icon"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="warn" (click)="deleteHoliday()" *mifosxHasPermission="'DELETE_HOLIDAY'">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>
|
||||
<button mat-menu-item (click)="deleteHoliday()" *mifosxHasPermission="'DELETE_HOLIDAY'">
|
||||
<fa-icon icon="trash" class="vh-menu-icon vh-menu-icon--danger"></fa-icon>
|
||||
{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap">
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Name' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ holidayData.name }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.From Date' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ holidayData.fromDate | dateFormat }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.To Date' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ holidayData.toDate | dateFormat }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Repayments Scheduled To' | translate }}
|
||||
</div>
|
||||
|
||||
@if (holidayData.repaymentsRescheduledTo !== undefined && holidayData.repaymentsRescheduledTo !== null) {
|
||||
<div class="flex-50">
|
||||
{{ holidayData.repaymentsRescheduledTo | dateFormat }}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (holidayData.repaymentsRescheduledTo === undefined || holidayData.repaymentsRescheduledTo === null) {
|
||||
<div class="flex-50">
|
||||
{{ 'labels.inputs.Next Repayment Date' | translate }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
||||
@@ -6,17 +6,133 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.content {
|
||||
div {
|
||||
margin: 1rem 0;
|
||||
word-wrap: break-word;
|
||||
.vh-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
&.header {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
// Header
|
||||
.vh-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.vh-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.vh-menu-btn {
|
||||
color: $gray-700 !important;
|
||||
width: 36px !important;
|
||||
height: 36px !important;
|
||||
border: 1px solid $border;
|
||||
border-radius: 8px !important;
|
||||
|
||||
&:hover {
|
||||
background: $gray-50 !important;
|
||||
border-color: $gray-500 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Card
|
||||
.vh-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Grid
|
||||
.vh-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
padding: 20px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.vh-cell {
|
||||
padding: 14px 16px;
|
||||
background: $gray-50;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
transition: background 0.12s;
|
||||
|
||||
&:hover {
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
// Menu icons
|
||||
.vh-menu-icon {
|
||||
margin-right: 10px;
|
||||
color: $accent;
|
||||
font-size: 14px;
|
||||
width: 18px;
|
||||
text-align: center;
|
||||
|
||||
&--danger {
|
||||
color: #ef4444;
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive
|
||||
@media (max-width: 600px) {
|
||||
.vh-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import { ConfirmationDialogComponent } from '../../../shared/confirmation-dialog
|
||||
import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
@@ -32,6 +34,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
FaIconComponent,
|
||||
MatMenuModule,
|
||||
MatIconButton,
|
||||
DateFormatPipe
|
||||
]
|
||||
})
|
||||
|
||||
@@ -6,16 +6,30 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<mat-card class="container">
|
||||
<mat-card-content>
|
||||
<div class="investor-filter-section">
|
||||
<div class="filter-row">
|
||||
<mat-form-field class="filter-field">
|
||||
<div class="inv-container">
|
||||
<!-- Header -->
|
||||
<div class="inv-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="inv-back">
|
||||
<i class="fas fa-arrow-left"></i> Back
|
||||
</button>
|
||||
<h2 class="inv-header__title">Investors</h2>
|
||||
</div>
|
||||
|
||||
<!-- Search Card -->
|
||||
<div class="inv-card">
|
||||
<!-- Section: Search -->
|
||||
<div class="inv-section">
|
||||
<div class="inv-section__header">
|
||||
<i class="fas fa-search"></i>
|
||||
<h3>Search</h3>
|
||||
</div>
|
||||
<div class="inv-grid">
|
||||
<mat-form-field appearance="outline" class="inv-field">
|
||||
<mat-label>{{ 'labels.text.Search by Text' | translate }}</mat-label>
|
||||
<input matInput [formControl]="searchText" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="filter-field" (click)="effectiveFromDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="inv-field" (click)="effectiveFromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.text.Effective Date From' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -28,7 +42,7 @@
|
||||
<mat-datepicker #effectiveFromDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="filter-field" (click)="effectiveToDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="inv-field" (click)="effectiveToDatePicker.open()">
|
||||
<mat-label>{{ 'labels.text.Effective Date To' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -40,10 +54,8 @@
|
||||
<mat-datepicker-toggle matSuffix [for]="effectiveToDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #effectiveToDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="filter-row">
|
||||
<mat-form-field class="filter-field" (click)="settlementFromDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="inv-field" (click)="settlementFromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.text.Settlement Date From' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -56,7 +68,7 @@
|
||||
<mat-datepicker #settlementFromDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="filter-field" (click)="settlementToDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="inv-field" (click)="settlementToDatePicker.open()">
|
||||
<mat-label>{{ 'labels.text.Settlement Date To' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -69,185 +81,153 @@
|
||||
<mat-datepicker #settlementToDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="filter-button-container">
|
||||
<button mat-raised-button color="primary" (click)="searchEAO()" class="search-button">
|
||||
<fa-icon icon="search" class="m-r-10"></fa-icon> {{ 'labels.buttons.Search' | translate }}
|
||||
<div class="inv-search-btn-wrap">
|
||||
<button mat-flat-button color="primary" (click)="searchEAO()" class="inv-search-btn">
|
||||
<i class="fas fa-search"></i> {{ 'labels.buttons.Search' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8 container m-t-20">
|
||||
@if (isLoading) {
|
||||
<div class="loader">
|
||||
<div class="loading"></div>
|
||||
</div>
|
||||
}
|
||||
@if (existsDataToFilter) {
|
||||
<mat-accordion>
|
||||
@for (record of searchResults; track record; let i = $index) {
|
||||
<mat-expansion-panel class="record">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div [ngClass]="itemStatus(record.status)" class="m-r-20">
|
||||
<fa-icon icon="stop"></fa-icon>
|
||||
<span class="m-l-10 status">{{ record.status }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="field-name">{{ 'labels.inputs.Owner External Id' | translate }}</td>
|
||||
<td>
|
||||
<!-- Results Area -->
|
||||
<div class="inv-section">
|
||||
<div class="inv-section__header">
|
||||
<i class="fas fa-list"></i>
|
||||
<h3>Results</h3>
|
||||
</div>
|
||||
<div class="inv-results">
|
||||
@if (isLoading) {
|
||||
<div class="inv-loader">
|
||||
<div class="inv-loader__spinner"></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (existsDataToFilter) {
|
||||
<mat-accordion class="inv-accordion">
|
||||
@for (record of searchResults; track record; let i = $index) {
|
||||
<mat-expansion-panel class="inv-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<div class="inv-panel-summary">
|
||||
<div [ngClass]="itemStatus(record.status)" class="inv-status-badge">
|
||||
<fa-icon icon="stop"></fa-icon>
|
||||
<span class="inv-status-text">{{ record.status }}</span>
|
||||
</div>
|
||||
<div class="inv-panel-meta">
|
||||
<span class="inv-panel-label">{{ 'labels.inputs.Owner External Id' | translate }}</span>
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ record.owner.externalId }}"
|
||||
></mifosx-external-identifier>
|
||||
</td>
|
||||
<td class="field-name">{{ 'labels.inputs.Transfer External Id' | translate }}</td>
|
||||
<td>
|
||||
</div>
|
||||
<div class="inv-panel-meta">
|
||||
<span class="inv-panel-label">{{ 'labels.inputs.Transfer External Id' | translate }}</span>
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ record.transferExternalId }}"
|
||||
></mifosx-external-identifier>
|
||||
</td>
|
||||
<td class="field-name">{{ 'labels.inputs.Effective From' | translate }}</td>
|
||||
<td>{{ record.effectiveFrom | dateFormat }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div class="external-asset-transfer">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="m-l-5 flex-25">
|
||||
<b>{{ 'labels.inputs.Status' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-25 m-l-5 left">
|
||||
<div [ngClass]="itemStatus(record.status)">
|
||||
<fa-icon icon="stop"></fa-icon>
|
||||
<span class="m-l-5 status">{{ record.status }}</span>
|
||||
</div>
|
||||
<div class="inv-panel-meta">
|
||||
<span class="inv-panel-label">{{ 'labels.inputs.Effective From' | translate }}</span>
|
||||
<span>{{ record.effectiveFrom | dateFormat }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<!-- Expanded Content -->
|
||||
<div class="inv-detail">
|
||||
<div class="inv-detail__grid">
|
||||
<div class="inv-detail__item">
|
||||
<span class="inv-detail__label">{{ 'labels.inputs.Status' | translate }}</span>
|
||||
<div [ngClass]="itemStatus(record.status)" class="inv-status-badge">
|
||||
<fa-icon icon="stop"></fa-icon>
|
||||
<span class="inv-status-text">{{ record.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inv-detail__item">
|
||||
<span class="inv-detail__label">{{ 'labels.inputs.Owner External Id' | translate }}</span>
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ record.owner.externalId }}"
|
||||
completed="true"
|
||||
></mifosx-external-identifier>
|
||||
</div>
|
||||
<div class="inv-detail__item">
|
||||
<span class="inv-detail__label">{{ 'labels.inputs.Settlement Date' | translate }}</span>
|
||||
<span class="inv-detail__value">{{ record.settlementDate | dateFormat }}</span>
|
||||
</div>
|
||||
<div class="inv-detail__item">
|
||||
<span class="inv-detail__label">{{ 'labels.inputs.Effective Date' | translate }}</span>
|
||||
<span class="inv-detail__value">{{ record.effectiveFrom | dateFormat }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (record.details) {
|
||||
<div class="inv-financials">
|
||||
<h4 class="inv-financials__title">{{ 'labels.inputs.Details' | translate }}</h4>
|
||||
<div class="inv-financials__grid">
|
||||
<div class="inv-financials__row">
|
||||
<span class="inv-financials__label">{{ 'labels.inputs.Principal Outstanding' | translate }}</span>
|
||||
<span class="inv-financials__amount">{{ record.details.totalPrincipalOutstanding | formatNumber }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="m-l-5 flex-25">
|
||||
<b>{{ 'labels.inputs.Owner External Id' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-25 m-l-5 left">
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ record.owner.externalId }}"
|
||||
completed="true"
|
||||
></mifosx-external-identifier>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="m-l-5 flex-25">
|
||||
<b>{{ 'labels.inputs.Settlement Date' | translate }} :</b>
|
||||
</td>
|
||||
<td class="m-l-5 flex-25">
|
||||
{{ record.settlementDate | dateFormat }}
|
||||
</td>
|
||||
<td class="m-l-5 flex-25">
|
||||
<b>{{ 'labels.inputs.Effective Date' | translate }} :</b>
|
||||
</td>
|
||||
<td class="m-l-5 flex-25">
|
||||
{{ record.effectiveFrom | dateFormat }}
|
||||
</td>
|
||||
</tr>
|
||||
@if (record.details) {
|
||||
<tr>
|
||||
<td class="m-l-5 flex-25">
|
||||
<b>{{ 'labels.inputs.Details' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-75 left">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="flex-50 m-l-5">
|
||||
<b>{{ 'labels.inputs.Principal Outstanding' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-50 r-amount">
|
||||
{{ record.details.totalPrincipalOutstanding | formatNumber }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="flex-50 m-l-5">
|
||||
<b>{{ 'labels.inputs.Interest Outstanding' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-50 r-amount">
|
||||
{{ record.details.totalInterestOutstanding | formatNumber }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="flex-50 m-l-5">
|
||||
<b>{{ 'labels.inputs.Fees Outstanding' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-50 r-amount">
|
||||
{{ record.details.totalFeeChargesOutstanding | formatNumber }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="flex-50 m-l-5">
|
||||
<b>{{ 'labels.inputs.Penalties Outstanding' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-50 r-amount">
|
||||
{{ record.details.totalPenaltyChargesOutstanding | formatNumber }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="flex-50 m-l-5">
|
||||
<b>{{ 'labels.inputs.Outstanding' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-50 r-amount">{{ record.details.totalOutstanding | formatNumber }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="flex-50 m-l-5">
|
||||
<b>{{ 'labels.inputs.Overpaid' | translate }} :</b>
|
||||
</td>
|
||||
<td class="flex-50 r-amount">{{ record.details.totalOverpaid | formatNumber }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
@if (canBeCancelled(record)) {
|
||||
<div class="record-actions layout-row align-flex-end">
|
||||
<button
|
||||
mat-button
|
||||
color="warn"
|
||||
(click)="cancelPendingSale(record)"
|
||||
matTooltip="{{ 'labels.text.Cancel Pending Sale' | translate }}"
|
||||
>
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
<div class="inv-financials__row">
|
||||
<span class="inv-financials__label">{{ 'labels.inputs.Interest Outstanding' | translate }}</span>
|
||||
<span class="inv-financials__amount">{{ record.details.totalInterestOutstanding | formatNumber }}</span>
|
||||
</div>
|
||||
<div class="inv-financials__row">
|
||||
<span class="inv-financials__label">{{ 'labels.inputs.Fees Outstanding' | translate }}</span>
|
||||
<span class="inv-financials__amount">{{ record.details.totalFeeChargesOutstanding | formatNumber }}</span>
|
||||
</div>
|
||||
<div class="inv-financials__row">
|
||||
<span class="inv-financials__label">{{ 'labels.inputs.Penalties Outstanding' | translate }}</span>
|
||||
<span class="inv-financials__amount">{{ record.details.totalPenaltyChargesOutstanding | formatNumber }}</span>
|
||||
</div>
|
||||
<div class="inv-financials__row inv-financials__row--total">
|
||||
<span class="inv-financials__label">{{ 'labels.inputs.Outstanding' | translate }}</span>
|
||||
<span class="inv-financials__amount">{{ record.details.totalOutstanding | formatNumber }}</span>
|
||||
</div>
|
||||
<div class="inv-financials__row">
|
||||
<span class="inv-financials__label">{{ 'labels.inputs.Overpaid' | translate }}</span>
|
||||
<span class="inv-financials__amount">{{ record.details.totalOverpaid | formatNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</mat-expansion-panel>
|
||||
}
|
||||
</mat-accordion>
|
||||
}
|
||||
|
||||
@if (existsDataToFilter) {
|
||||
<mat-paginator
|
||||
[pageSize]="pageSize"
|
||||
[pageSizeOptions]="[50, 100, 200]"
|
||||
[length]="totalRows"
|
||||
(page)="pageChanged($event)"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
}
|
||||
</div>
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
@if (canBeCancelled(record)) {
|
||||
<div class="inv-panel-actions">
|
||||
<button
|
||||
mat-button
|
||||
color="warn"
|
||||
(click)="cancelPendingSale(record)"
|
||||
matTooltip="{{ 'labels.text.Cancel Pending Sale' | translate }}"
|
||||
>
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</mat-expansion-panel>
|
||||
}
|
||||
</mat-accordion>
|
||||
}
|
||||
|
||||
@if (!existsDataToFilter) {
|
||||
<div class="alert">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
{{ 'labels.text.No data found' | translate }}
|
||||
</div>
|
||||
@if (existsDataToFilter) {
|
||||
<mat-paginator
|
||||
[pageSize]="pageSize"
|
||||
[pageSizeOptions]="[50, 100, 200]"
|
||||
[length]="totalRows"
|
||||
(page)="pageChanged($event)"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
}
|
||||
|
||||
@if (!existsDataToFilter) {
|
||||
<div class="inv-empty">
|
||||
<i class="fas fa-inbox inv-empty__icon"></i>
|
||||
<p class="inv-empty__text">{{ 'labels.text.No data found' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,198 +6,303 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// Filter Section Styling
|
||||
.investor-filter-section {
|
||||
margin-bottom: 24px;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.filter-row {
|
||||
.inv-container {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.inv-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.inv-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.inv-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.inv-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
margin-bottom: 12px;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-field {
|
||||
flex: 1 1 calc(33.333% - 11px);
|
||||
min-width: 200px;
|
||||
max-width: 100%;
|
||||
|
||||
// Ensure consistent height across all fields
|
||||
::ng-deep .mat-mdc-form-field-infix {
|
||||
min-height: 56px;
|
||||
}
|
||||
|
||||
// Align datepicker icons consistently
|
||||
::ng-deep .mat-datepicker-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-button-container {
|
||||
flex: 1 1 calc(33.333% - 11px);
|
||||
min-width: 200px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-bottom: 4px;
|
||||
// Grid
|
||||
.inv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
.search-button {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
@media (max-width: 768px) { grid-template-columns: 1fr; }
|
||||
@media (max-width: 1024px) and (min-width: 769px) { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
margin-right: 8px;
|
||||
.inv-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.inv-search-btn-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 4px;
|
||||
|
||||
@media (max-width: 768px) { padding-top: 0; }
|
||||
}
|
||||
|
||||
.inv-search-btn {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 44px !important;
|
||||
width: 100%;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
|
||||
// Results area
|
||||
.inv-results {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
// Loader
|
||||
.inv-loader {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 40px 0;
|
||||
|
||||
&__spinner {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: 3px solid $gray-200;
|
||||
border-top-color: $accent;
|
||||
border-radius: 50%;
|
||||
animation: inv-spin 0.7s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes inv-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
// Accordion & Panels
|
||||
.inv-accordion {
|
||||
::ng-deep .mat-expansion-panel {
|
||||
border: 1px solid $border;
|
||||
border-radius: 8px !important;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: none !important;
|
||||
|
||||
&:not(.mat-expanded) {
|
||||
&:hover {
|
||||
border-color: #c5cdd8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive adjustments for tablets
|
||||
@media screen and (width <= 1024px) {
|
||||
.filter-field,
|
||||
.filter-button-container {
|
||||
flex: 1 1 calc(50% - 8px);
|
||||
min-width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive adjustments for mobile
|
||||
@media screen and (width <= 768px) {
|
||||
.filter-row {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.filter-field,
|
||||
.filter-button-container {
|
||||
flex: 1 1 100%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.filter-button-container {
|
||||
padding-bottom: 0;
|
||||
margin-top: 8px;
|
||||
&.mat-expanded {
|
||||
border-color: $accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
color: black;
|
||||
.inv-panel-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.field-name {
|
||||
font-weight: 800;
|
||||
.inv-panel-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.record-actions {
|
||||
margin-top: 1%;
|
||||
.inv-panel-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: $gray-500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 1%;
|
||||
// Status badge
|
||||
.inv-status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.inv-status-text {
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
// Detail (expanded)
|
||||
.inv-detail {
|
||||
padding: 8px 0 16px;
|
||||
|
||||
&__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: $gray-500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 13px;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
.external-asset-transfer {
|
||||
margin-top: 10px;
|
||||
min-height: 160px;
|
||||
}
|
||||
// Financials
|
||||
.inv-financials {
|
||||
background: $gray-50;
|
||||
border: 1px solid $gray-200;
|
||||
border-radius: 8px;
|
||||
padding: 14px 18px;
|
||||
|
||||
.record {
|
||||
.record-actions {
|
||||
margin-top: 1%;
|
||||
&__title {
|
||||
margin: 0 0 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 1%;
|
||||
&__grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 4px 0;
|
||||
|
||||
&--total {
|
||||
border-top: 1px solid $gray-200;
|
||||
padding-top: 8px;
|
||||
margin-top: 4px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1% auto;
|
||||
&__label {
|
||||
font-size: 13px;
|
||||
color: $gray-700;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 30px;
|
||||
margin-left: 2%;
|
||||
&__amount {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
}
|
||||
|
||||
$bar: 140px;
|
||||
$foo: $bar * 8;
|
||||
$color: #e2e4ec;
|
||||
|
||||
.loader {
|
||||
margin-bottom: 39px;
|
||||
// Panel actions
|
||||
.inv-panel-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 8px 0 0;
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
// Empty state
|
||||
.inv-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 48px 0;
|
||||
color: $gray-500;
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
left: 0;
|
||||
&__icon {
|
||||
font-size: 36px;
|
||||
margin-bottom: 12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
16.7% {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
33.3% {
|
||||
left: calc($foo / 2);
|
||||
}
|
||||
|
||||
50% {
|
||||
left: $foo - $bar;
|
||||
}
|
||||
|
||||
66.7% {
|
||||
left: calc($foo / 2);
|
||||
}
|
||||
|
||||
83.3% {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes grow {
|
||||
0% {
|
||||
width: $bar;
|
||||
}
|
||||
|
||||
16.7% {
|
||||
width: calc($foo / 2);
|
||||
}
|
||||
|
||||
33.3% {
|
||||
width: calc($foo / 2);
|
||||
}
|
||||
|
||||
50% {
|
||||
width: $bar;
|
||||
}
|
||||
|
||||
66.7% {
|
||||
width: calc($foo / 2);
|
||||
}
|
||||
|
||||
83.3% {
|
||||
width: calc($foo / 2);
|
||||
}
|
||||
|
||||
100% {
|
||||
width: $bar;
|
||||
&__text {
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-16
@@ -6,12 +6,23 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="cl-container">
|
||||
<div class="cl-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="cl-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Loan Originators' | translate }}
|
||||
</button>
|
||||
<h2 class="cl-header__title">{{ 'labels.heading.Create Loan Originator' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="cl-card">
|
||||
<form [formGroup]="loanOriginatorForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div #createLoanOriginatorFormRef class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="cl-section">
|
||||
<div class="cl-section__header">
|
||||
<i class="fas fa-handshake"></i>
|
||||
<h3>{{ 'labels.heading.Loan Originator Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="cl-grid" #createLoanOriginatorFormRef>
|
||||
<mat-form-field appearance="outline" class="cl-field">
|
||||
<mat-label>{{ 'labels.inputs.Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="name" />
|
||||
@if (loanOriginatorForm.controls.name.hasError('required')) {
|
||||
@@ -28,7 +39,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="cl-field">
|
||||
<mat-label>{{ 'labels.inputs.External Id' | translate }}</mat-label>
|
||||
<input matInput required formControlName="externalId" />
|
||||
@if (loanOriginatorForm.controls.externalId.hasError('required')) {
|
||||
@@ -45,7 +56,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="cl-field">
|
||||
<mat-label>{{ 'labels.inputs.Status' | translate }}</mat-label>
|
||||
<mat-select required formControlName="status">
|
||||
@for (status of statusOptions; track status) {
|
||||
@@ -62,7 +73,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="cl-field">
|
||||
<mat-label>{{ 'labels.inputs.Originator Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="originatorTypeId">
|
||||
@for (originatorType of originatorTypeOptions; track originatorType) {
|
||||
@@ -79,7 +90,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="cl-field">
|
||||
<mat-label>{{ 'labels.inputs.Channel Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="channelTypeId">
|
||||
@for (channelTypeI of channelTypeOptions; track channelTypeI) {
|
||||
@@ -96,21 +107,23 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="cl-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="cl-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!loanOriginatorForm.valid"
|
||||
class="cl-actions__submit"
|
||||
*mifosxHasPermission="'CREATE_LOAN_ORIGINATOR'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+111
-2
@@ -6,6 +6,115 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.cl-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cl-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cl-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.cl-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cl-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cl-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.cl-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cl-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
+29
-16
@@ -6,12 +6,23 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="el-container">
|
||||
<div class="el-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="el-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Loan Originators' | translate }}
|
||||
</button>
|
||||
<h2 class="el-header__title">{{ 'labels.heading.Edit Loan Originator' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="el-card">
|
||||
<form [formGroup]="loanOriginatorForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div #editEmployeeFormRef class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="el-section">
|
||||
<div class="el-section__header">
|
||||
<i class="fas fa-handshake"></i>
|
||||
<h3>{{ 'labels.heading.Loan Originator Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="el-grid">
|
||||
<mat-form-field appearance="outline" class="el-field">
|
||||
<mat-label>{{ 'labels.inputs.Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="name" />
|
||||
@if (loanOriginatorForm.controls.name.hasError('required')) {
|
||||
@@ -28,7 +39,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="el-field">
|
||||
<mat-label>{{ 'labels.inputs.External Id' | translate }}</mat-label>
|
||||
<input matInput formControlName="externalId" readonly />
|
||||
@if (loanOriginatorForm.controls.externalId.hasError('required')) {
|
||||
@@ -45,7 +56,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="el-field">
|
||||
<mat-label>{{ 'labels.inputs.Status' | translate }}</mat-label>
|
||||
<mat-select required formControlName="status">
|
||||
@for (status of statusOptions; track status) {
|
||||
@@ -62,7 +73,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="el-field">
|
||||
<mat-label>{{ 'labels.inputs.Originator Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="originatorTypeId">
|
||||
@for (originatorType of originatorTypeOptions; track originatorType) {
|
||||
@@ -79,7 +90,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="el-field">
|
||||
<mat-label>{{ 'labels.inputs.Channel Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="channelTypeId">
|
||||
@for (channelTypeI of channelTypeOptions; track channelTypeI) {
|
||||
@@ -96,21 +107,23 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="el-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="el-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!loanOriginatorForm.valid"
|
||||
class="el-actions__submit"
|
||||
*mifosxHasPermission="'UPDATE_LOAN_ORIGINATOR'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+111
-2
@@ -6,6 +6,115 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.el-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.el-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.el-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.el-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,25 +6,34 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<div #buttonCreateLoanOriginator>
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_LOAN_ORIGINATOR'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create' | translate }} {{ 'labels.inputs.Loan Originator' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-card class="container">
|
||||
<!-- Header Bar -->
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-edit"></i>
|
||||
{{ 'labels.heading.Manage Loan Originators' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div #filter class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<input matInput #filter placeholder="{{ 'labels.inputs.Filter' | translate }}" (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" [routerLink]="['create']" class="btn-create" *mifosxHasPermission="'CREATE_LOAN_ORIGINATOR'" #buttonCreateLoanOriginator>
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
{{ 'labels.buttons.Create' | translate }} {{ 'labels.inputs.Loan Originator' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div #tableLoanOriginators class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<!-- Table -->
|
||||
<div class="table-container" #tableLoanOriginators>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Id' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loanOriginator">{{ loanOriginator.id }}</td>
|
||||
@@ -65,6 +74,7 @@
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Channel Type' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loanOriginator">{{ loanOriginator.channelType?.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loanOriginator">
|
||||
@@ -82,10 +92,11 @@
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="select-row"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
+35
-52
@@ -6,63 +6,46 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_LOAN_ORIGINATOR'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="vl-container">
|
||||
<div class="vl-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="vl-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Loan Originators' | translate }}
|
||||
</button>
|
||||
<h2 class="vl-header__title">{{ loanOriginatorData.name }}</h2>
|
||||
<div class="vl-header__spacer"></div>
|
||||
<button mat-flat-button color="primary" [routerLink]="['edit']" class="vl-header__edit" *mifosxHasPermission="'UPDATE_LOAN_ORIGINATOR'">
|
||||
<i class="fas fa-pen"></i> {{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap">
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Name' | translate }}
|
||||
<div class="vl-card">
|
||||
<div class="vl-section">
|
||||
<div class="vl-section__header">
|
||||
<i class="fas fa-handshake"></i>
|
||||
<h3>{{ 'labels.heading.Loan Originator Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="vl-details">
|
||||
<div class="vl-detail">
|
||||
<span class="vl-detail__label">{{ 'labels.inputs.Name' | translate }}</span>
|
||||
<span class="vl-detail__value">{{ loanOriginatorData.name }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 wrap-content">
|
||||
{{ loanOriginatorData.name }}
|
||||
<div class="vl-detail">
|
||||
<span class="vl-detail__label">{{ 'labels.inputs.External Id' | translate }}</span>
|
||||
<span class="vl-detail__value">{{ loanOriginatorData.externalId }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.External Id' | translate }}
|
||||
<div class="vl-detail">
|
||||
<span class="vl-detail__label">{{ 'labels.inputs.Status' | translate }}</span>
|
||||
<span class="vl-detail__value">{{ loanOriginatorData.status }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 wrap-content">
|
||||
{{ loanOriginatorData.externalId }}
|
||||
<div class="vl-detail">
|
||||
<span class="vl-detail__label">{{ 'labels.inputs.Originator Type' | translate }}</span>
|
||||
<span class="vl-detail__value">{{ loanOriginatorData.originatorType?.name }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Status' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ loanOriginatorData.status }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Originator Type' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ loanOriginatorData.originatorType?.name }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.Channel Type' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ loanOriginatorData.channelType?.name }}
|
||||
<div class="vl-detail">
|
||||
<span class="vl-detail__label">{{ 'labels.inputs.Channel Type' | translate }}</span>
|
||||
<span class="vl-detail__value">{{ loanOriginatorData.channelType?.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
{{ 'labels.buttons.Back' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+110
-6
@@ -6,13 +6,117 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.content {
|
||||
div {
|
||||
margin: 1rem 0;
|
||||
word-wrap: break-word;
|
||||
.vl-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.vl-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__edit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
.vl-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.vl-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vl-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vl-details {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
padding: 20px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.vl-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
&__label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: $gray-500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
color: $gray-900;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
+98
-70
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div>
|
||||
<form [formGroup]="provisioningCriteriaForm">
|
||||
<div class="layout-row gap-2percent">
|
||||
<mat-form-field class="flex-fill">
|
||||
<div class="cp-container">
|
||||
<!-- Header -->
|
||||
<div class="cp-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="cp-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Provisioning Criteria' | translate }}
|
||||
</button>
|
||||
<h2 class="cp-header__title">{{ 'labels.heading.Create Provisioning Criteria' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="cp-card">
|
||||
<form [formGroup]="provisioningCriteriaForm">
|
||||
<!-- Criteria Details Section -->
|
||||
<div class="cp-section">
|
||||
<div class="cp-section__header">
|
||||
<i class="fas fa-edit"></i>
|
||||
<h3>Criteria Details</h3>
|
||||
</div>
|
||||
<div class="cp-grid">
|
||||
<mat-form-field appearance="outline" class="cp-field">
|
||||
<mat-label>{{ 'labels.inputs.Provisioning Criteria' | translate }}</mat-label>
|
||||
<input required matInput formControlName="criteriaName" />
|
||||
@if (provisioningCriteriaForm.controls.criteriaName.hasError('required')) {
|
||||
@@ -22,7 +36,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-form-field appearance="outline" class="cp-field">
|
||||
<mat-label>{{ 'labels.inputs.Selected Products' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanProducts" multiple>
|
||||
@for (product of loanProvisioningCriteriaTemplate.loanProducts; track product) {
|
||||
@@ -39,77 +53,91 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z1">
|
||||
@if (!provisioningCriteriaFormValid) {
|
||||
<mat-hint> {{ 'labels.text.Provisioning criteria definitions' | translate }}</mat-hint>
|
||||
}
|
||||
<!-- Definitions Section -->
|
||||
<div class="cp-section">
|
||||
<div class="cp-section__header">
|
||||
<i class="fas fa-table"></i>
|
||||
<h3>Definitions</h3>
|
||||
</div>
|
||||
<div class="cp-table-wrap">
|
||||
@if (!provisioningCriteriaFormValid) {
|
||||
<mat-hint class="cp-hint">{{ 'labels.text.Provisioning criteria definitions' | translate }}</mat-hint>
|
||||
}
|
||||
|
||||
<table mat-table class="m-t-10" [dataSource]="definitions">
|
||||
<ng-container matColumnDef="category">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Category' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.categoryName }}</td>
|
||||
</ng-container>
|
||||
<div class="table-container">
|
||||
<table mat-table class="modern-table" [dataSource]="definitions">
|
||||
<ng-container matColumnDef="category">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Category' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.categoryName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Min Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.minAge || '0' }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="minAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Min Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.minAge || '0' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Max Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.maxAge || '0' }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="maxAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Max Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.maxAge || '0' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="percentage">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Percentage' | translate }} (%)</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.provisioningPercentage || '0' }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="percentage">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Percentage' | translate }} (%)</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.provisioningPercentage || '0' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="liabilityAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Liability Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{
|
||||
(definition.liabilityAccount | find: loanProvisioningCriteriaTemplate.glAccounts : 'id' : 'name') || '-'
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="liabilityAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Liability Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{
|
||||
(definition.liabilityAccount | find: loanProvisioningCriteriaTemplate.glAccounts : 'id' : 'name') || '-'
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="expenseAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Expense Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{ (definition.expenseAccount | find: loanProvisioningCriteriaTemplate.glAccounts : 'id' : 'name') || '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="expenseAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Expense Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{ (definition.expenseAccount | find: loanProvisioningCriteriaTemplate.glAccounts : 'id' : 'name') || '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
<button mat-button color="primary" (click)="editDefinition(definition)">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
<button mat-button color="primary" (click)="editDefinition(definition)">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-t-20 layout-row layout-align-center gap-20px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">{{ 'labels.buttons.Cancel' | translate }}</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[disabled]="!provisioningCriteriaFormValid"
|
||||
(click)="submit()"
|
||||
*mifosxHasPermission="'CREATE_PROVISIONING_CRITERIA'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</mat-card>
|
||||
<!-- Actions -->
|
||||
<div class="cp-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="cp-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!provisioningCriteriaFormValid"
|
||||
(click)="submit()"
|
||||
*mifosxHasPermission="'CREATE_PROVISIONING_CRITERIA'"
|
||||
class="cp-actions__submit"
|
||||
>
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+121
-48
@@ -6,65 +6,138 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
padding: 0.5rem;
|
||||
max-width: 1200px;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.cp-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.layout-row {
|
||||
// Header
|
||||
.cp-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
padding: 1rem;
|
||||
box-shadow: 0 2px 8px rgb(0 0 0 / 10%) !important;
|
||||
border-radius: 8px;
|
||||
|
||||
.layout-row {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-elevation-z1 {
|
||||
padding: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
th {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.m-t-20 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.layout-align-center {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
@media (width <= 768px) {
|
||||
.container {
|
||||
padding: 0.5rem;
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
mat-card {
|
||||
padding: 1rem;
|
||||
.cp-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.cp-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.cp-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-row {
|
||||
flex-direction: column;
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.cp-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.cp-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Table wrap
|
||||
.cp-table-wrap {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
.cp-hint {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: $gray-500;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
// Actions
|
||||
.cp-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
.gap-20px {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
+101
-73
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div>
|
||||
<form [formGroup]="provisioningCriteriaForm">
|
||||
<div class="layout-row gap-2percent">
|
||||
<mat-form-field class="flex-fill">
|
||||
<div class="ep-container">
|
||||
<!-- Header -->
|
||||
<div class="ep-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ep-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Provisioning Criteria' | translate }}
|
||||
</button>
|
||||
<h2 class="ep-header__title">{{ 'labels.heading.Edit Provisioning Criteria' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="ep-card">
|
||||
<form [formGroup]="provisioningCriteriaForm">
|
||||
<!-- Criteria Details Section -->
|
||||
<div class="ep-section">
|
||||
<div class="ep-section__header">
|
||||
<i class="fas fa-edit"></i>
|
||||
<h3>Criteria Details</h3>
|
||||
</div>
|
||||
<div class="ep-grid">
|
||||
<mat-form-field appearance="outline" class="ep-field">
|
||||
<mat-label>{{ 'labels.inputs.Provisioning Criteria' | translate }}</mat-label>
|
||||
<input required matInput formControlName="criteriaName" />
|
||||
@if (provisioningCriteriaForm.controls.criteriaName.hasError('required')) {
|
||||
@@ -22,7 +36,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-form-field appearance="outline" class="ep-field">
|
||||
<mat-label>{{ 'labels.inputs.Selected Products' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanProducts" [compareWith]="compareOptions" multiple>
|
||||
@for (product of loanProducts; track product) {
|
||||
@@ -33,80 +47,94 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z1">
|
||||
@if (!provisioningCriteriaFormValid) {
|
||||
<mat-hint>{{ 'labels.text.Provisioning criteria definitions' | translate }}</mat-hint>
|
||||
}
|
||||
<!-- Definitions Section -->
|
||||
<div class="ep-section">
|
||||
<div class="ep-section__header">
|
||||
<i class="fas fa-table"></i>
|
||||
<h3>Definitions</h3>
|
||||
</div>
|
||||
<div class="ep-table-wrap">
|
||||
@if (!provisioningCriteriaFormValid) {
|
||||
<mat-hint class="ep-hint">{{ 'labels.text.Provisioning criteria definitions' | translate }}</mat-hint>
|
||||
}
|
||||
|
||||
<table mat-table class="m-t-10" [dataSource]="definitions">
|
||||
<ng-container matColumnDef="category">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Category' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.categoryName }}</td>
|
||||
</ng-container>
|
||||
<div class="table-container">
|
||||
<table mat-table class="modern-table" [dataSource]="definitions">
|
||||
<ng-container matColumnDef="category">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Category' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.categoryName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Min Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.minAge || '0' }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="minAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Min Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.minAge || '0' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Max Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.maxAge || '0' }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="maxAge">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Max Age' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.maxAge || '0' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="percentage">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Percentage' | translate }} (%)</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.provisioningPercentage || '0' }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="percentage">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Percentage' | translate }} (%)</th>
|
||||
<td mat-cell *matCellDef="let definition">{{ definition.provisioningPercentage || '0' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="liabilityAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Liability Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{
|
||||
(definition.liabilityAccount | find: loanProvisioningCriteriaAndTemplate.glAccounts : 'id' : 'name') ||
|
||||
'-'
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="liabilityAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Liability Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{
|
||||
(definition.liabilityAccount | find: loanProvisioningCriteriaAndTemplate.glAccounts : 'id' : 'name') ||
|
||||
'-'
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="expenseAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Expense Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{
|
||||
(definition.expenseAccount | find: loanProvisioningCriteriaAndTemplate.glAccounts : 'id' : 'name') || '-'
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="expenseAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Expense Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
{{
|
||||
(definition.expenseAccount | find: loanProvisioningCriteriaAndTemplate.glAccounts : 'id' : 'name') || '-'
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
<button mat-button color="primary" (click)="editDefinition(definition)">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let definition">
|
||||
<button mat-button color="primary" (click)="editDefinition(definition)">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-t-20 layout-row layout-align-center gap-20px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">{{ 'labels.buttons.Cancel' | translate }}</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[disabled]="!provisioningCriteriaFormValid"
|
||||
(click)="submit()"
|
||||
*mifosxHasPermission="'UPDATE_CRITERIA'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</mat-card>
|
||||
<!-- Actions -->
|
||||
<div class="ep-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ep-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!provisioningCriteriaFormValid"
|
||||
(click)="submit()"
|
||||
*mifosxHasPermission="'UPDATE_CRITERIA'"
|
||||
class="ep-actions__submit"
|
||||
>
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+136
@@ -5,3 +5,139 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.ep-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.ep-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ep-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.ep-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.ep-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.ep-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ep-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Table wrap
|
||||
.ep-table-wrap {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
.ep-hint {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: $gray-500;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
// Actions
|
||||
.ep-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
+27
-26
@@ -6,28 +6,34 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[routerLink]="['create']"
|
||||
*mifosxHasPermission="'CREATE_PROVISIONING_CRITERIA'"
|
||||
>
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Provisioning Criteria' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<mat-card class="container">
|
||||
<!-- Header Bar -->
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-edit"></i>
|
||||
{{ 'labels.heading.Loan Provisioning Criteria' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<input matInput placeholder="{{ 'labels.inputs.Filter' | translate }}" (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" [routerLink]="['create']" class="btn-create" *mifosxHasPermission="'CREATE_PROVISIONING_CRITERIA'">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
{{ 'labels.buttons.Create Provisioning Criteria' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<!-- Table -->
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="criteriaName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let loanProvisioningCriteria">{{ loanProvisioningCriteria.criteriaName }}</td>
|
||||
@@ -39,14 +45,9 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr
|
||||
mat-row
|
||||
*matRowDef="let row; columns: displayedColumns"
|
||||
[routerLink]="[row.criteriaId]"
|
||||
class="select-row"
|
||||
></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.criteriaId]" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
+2
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
@@ -6,12 +6,23 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="cf-container">
|
||||
<div class="cf-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="cf-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Manage Funds' | translate }}
|
||||
</button>
|
||||
<h2 class="cf-header__title">{{ 'labels.heading.Create Fund' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="cf-card">
|
||||
<form [formGroup]="fundForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="cf-section">
|
||||
<div class="cf-section__header">
|
||||
<i class="fas fa-wallet"></i>
|
||||
<h3>{{ 'labels.heading.Fund Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="cf-grid">
|
||||
<mat-form-field appearance="outline" class="cf-field">
|
||||
<mat-label>{{ 'labels.inputs.name' | translate }}</mat-label>
|
||||
<input matInput required autofocus formControlName="name" />
|
||||
@if (fundForm.controls.name.hasError('required')) {
|
||||
@@ -22,21 +33,21 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="cf-field">
|
||||
<mat-label>{{ 'labels.inputs.External Id' | translate }}</mat-label>
|
||||
<input matInput autofocus formControlName="externalId" />
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="cf-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="cf-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!fundForm.valid" *mifosxHasPermission="'CREATE_FUND'">
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!fundForm.valid" class="cf-actions__submit" *mifosxHasPermission="'CREATE_FUND'">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,115 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.cf-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cf-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.cf-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cf-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cf-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.cf-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cf-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,23 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="ef-container">
|
||||
<div class="ef-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ef-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Manage Funds' | translate }}
|
||||
</button>
|
||||
<h2 class="ef-header__title">{{ 'labels.heading.Edit Fund' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="ef-card">
|
||||
<form [formGroup]="fundForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="ef-section">
|
||||
<div class="ef-section__header">
|
||||
<i class="fas fa-wallet"></i>
|
||||
<h3>{{ 'labels.heading.Fund Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ef-grid">
|
||||
<mat-form-field appearance="outline" class="ef-field">
|
||||
<mat-label>{{ 'labels.inputs.name' | translate }}</mat-label>
|
||||
<input matInput required autofocus formControlName="name" />
|
||||
@if (fundForm.controls.name.hasError('required')) {
|
||||
@@ -22,21 +33,21 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ef-field">
|
||||
<mat-label>{{ 'labels.inputs.External Id' | translate }}</mat-label>
|
||||
<input matInput autofocus formControlName="externalId" />
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="ef-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ef-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!fundForm.valid" *mifosxHasPermission="'UPDATE_FUND'">
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!fundForm.valid" class="ef-actions__submit" *mifosxHasPermission="'UPDATE_FUND'">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,115 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.ef-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.ef-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ef-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.ef-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ef-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ef-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ef-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ef-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,42 +6,52 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<div #fundFormRef class="in-block">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_FUND'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Fund' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div #filter class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-money-bill-alt title-icon"></i>
|
||||
{{ 'labels.heading.Manage Funds' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-buttons">
|
||||
<div #fundFormRef class="in-block">
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['create']" *mifosxHasPermission="'CREATE_FUND'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Fund' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div #chargesTable class="mat-elevation-z8 table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.name }}</td>
|
||||
</ng-container>
|
||||
<div #filter class="table-container">
|
||||
<div #chargesTable>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.External Id' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
<mifosx-external-identifier externalId="{{ charge.externalId }}"></mifosx-external-identifier>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.External Id' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
<mifosx-external-identifier externalId="{{ charge.externalId }}"></mifosx-external-identifier>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="select-row"></tr>
|
||||
</table>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
@@ -6,42 +6,39 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="layout-row align-end gap-2px responsive-column container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_FUND'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="vf-container">
|
||||
<div class="vf-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="vf-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Manage Funds' | translate }}
|
||||
</button>
|
||||
<h2 class="vf-header__title">{{ fundData.name }}</h2>
|
||||
<div class="vf-header__spacer"></div>
|
||||
<button mat-flat-button color="primary" [routerLink]="['edit']" class="vf-header__edit" *mifosxHasPermission="'UPDATE_FUND'">
|
||||
<i class="fas fa-pen"></i> {{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap">
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.name' | translate }}
|
||||
<div class="vf-card">
|
||||
<div class="vf-section">
|
||||
<div class="vf-section__header">
|
||||
<i class="fas fa-wallet"></i>
|
||||
<h3>{{ 'labels.heading.Fund Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="vf-details">
|
||||
<div class="vf-detail">
|
||||
<span class="vf-detail__label">{{ 'labels.inputs.name' | translate }}</span>
|
||||
<span class="vf-detail__value">{{ fundData.name }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ fundData.name }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'labels.inputs.External Id' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ fundData.externalId }}"
|
||||
completed="true"
|
||||
></mifosx-external-identifier>
|
||||
<div class="vf-detail">
|
||||
<span class="vf-detail__label">{{ 'labels.inputs.External Id' | translate }}</span>
|
||||
<span class="vf-detail__value">
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ fundData.externalId }}"
|
||||
completed="true"
|
||||
></mifosx-external-identifier>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-row layout-align-center gap-2percent column-on-mobile">
|
||||
<button type="button" mat-raised-button color="primary" [routerLink]="['../']">
|
||||
{{ 'labels.buttons.Back' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,13 +6,117 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.content {
|
||||
div {
|
||||
margin: 1rem 0;
|
||||
word-wrap: break-word;
|
||||
.vf-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.vf-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__edit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
.vf-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.vf-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vf-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vf-details {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
padding: 20px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.vf-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
&__label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: $gray-500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
color: $gray-900;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="co-container">
|
||||
<!-- Header -->
|
||||
<div class="co-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="co-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Offices' | translate }}
|
||||
</button>
|
||||
<h2 class="co-header__title">{{ 'labels.heading.Create Office' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="co-card">
|
||||
<form [formGroup]="officeForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div #createOfficeFormRef class="layout-column">
|
||||
<mat-form-field>
|
||||
<!-- Office Details Section -->
|
||||
<div class="co-section">
|
||||
<div class="co-section__header">
|
||||
<i class="fas fa-building"></i>
|
||||
<h3>{{ 'labels.heading.Office Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="co-grid" #createOfficeFormRef>
|
||||
<mat-form-field appearance="outline" class="co-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<input required matInput formControlName="name" />
|
||||
@if (officeForm.controls.name.hasError('required')) {
|
||||
@@ -22,7 +36,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="co-field">
|
||||
<mat-label>{{ 'labels.inputs.Parent Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="parentId">
|
||||
@for (office of officeData; track office) {
|
||||
@@ -39,7 +53,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field (click)="openedOnDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="co-field" (click)="openedOnDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Opened On' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -59,23 +73,24 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="co-field">
|
||||
<mat-label>{{ 'labels.inputs.External ID' | translate }}</mat-label>
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<!-- Actions -->
|
||||
<div class="co-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="co-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!officeForm.valid" *mifosxHasPermission="'CREATE_OFFICE'">
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!officeForm.valid" class="co-actions__submit" *mifosxHasPermission="'CREATE_OFFICE'">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #templateCreateOfficeForm let-popover="popover">
|
||||
|
||||
@@ -6,6 +6,128 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.co-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.co-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.co-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.co-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.co-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.co-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.co-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.co-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,26 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="eo-container">
|
||||
<!-- Header -->
|
||||
<div class="eo-header">
|
||||
<button mat-stroked-button [routerLink]="['../general']" class="eo-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Office' | translate }}
|
||||
</button>
|
||||
<h2 class="eo-header__title">{{ 'labels.heading.Edit Office' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Form Card -->
|
||||
<div class="eo-card">
|
||||
<form [formGroup]="officeForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<!-- Office Details Section -->
|
||||
<div class="eo-section">
|
||||
<div class="eo-section__header">
|
||||
<i class="fas fa-building"></i>
|
||||
<h3>{{ 'labels.heading.Office Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="eo-grid">
|
||||
<mat-form-field appearance="outline" class="eo-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<input matInput required formControlName="name" />
|
||||
@if (officeForm.controls.name.hasError('required')) {
|
||||
@@ -23,7 +37,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
@if (officeForm.contains('parentId')) {
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="eo-field">
|
||||
<mat-label>{{ 'labels.inputs.Parent Office' | translate }}</mat-label>
|
||||
<mat-select required formControlName="parentId">
|
||||
@for (office of officeData.allowedParents; track office) {
|
||||
@@ -41,7 +55,7 @@
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-form-field (click)="openingDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="eo-field" (click)="openingDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Opened On' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -61,21 +75,22 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="eo-field">
|
||||
<mat-label>{{ 'labels.inputs.External ID' | translate }}</mat-label>
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../general']">
|
||||
<!-- Actions -->
|
||||
<div class="eo-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../general']" class="eo-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!officeForm.valid" *mifosxHasPermission="'UPDATE_OFFICE'">
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="!officeForm.valid" class="eo-actions__submit" *mifosxHasPermission="'UPDATE_OFFICE'">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,128 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.eo-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
// Header
|
||||
.eo-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.eo-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
// Card
|
||||
.eo-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Section
|
||||
.eo-section {
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
// Grid
|
||||
.eo-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.eo-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
.eo-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,178 +6,177 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<mat-button-toggle-group #buttonTreeView [formControl]="viewGroup">
|
||||
<mat-button-toggle value="listView">
|
||||
<fa-icon icon="list"></fa-icon>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle value="treeView">
|
||||
<fa-icon icon="sitemap"></fa-icon>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
|
||||
<div #buttonCreateOffice class="in-block">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_OFFICE'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Office' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div #buttonImportOffices class="in-block">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
*mifosxHasPermission="'CREATE_OFFICE'"
|
||||
[routerLink]="['/organization', 'bulk-import', 'Offices']"
|
||||
>
|
||||
<fa-icon icon="upload" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Import Offices' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container" [hidden]="viewGroup.value !== 'listView'">
|
||||
<div #filter class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="container">
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-building title-icon"></i>
|
||||
{{ 'labels.heading.Manage Offices' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<div class="table-search">
|
||||
<mat-form-field appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'Filter' | translate }}</mat-label>
|
||||
<input #filter matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-button-toggle-group #buttonTreeView [formControl]="viewGroup">
|
||||
<mat-button-toggle value="listView">
|
||||
<fa-icon icon="list"></fa-icon>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle value="treeView">
|
||||
<fa-icon icon="sitemap"></fa-icon>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
<div class="table-buttons">
|
||||
<div #buttonImportOffices>
|
||||
<button mat-stroked-button class="btn-import" *mifosxHasPermission="'CREATE_OFFICE'" [routerLink]="['/organization', 'bulk-import', 'Offices']">
|
||||
<fa-icon icon="upload" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Import Offices' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div #buttonCreateOffice>
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['create']" *mifosxHasPermission="'CREATE_OFFICE'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Office' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- List View -->
|
||||
<div #tableOffices class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' Office Name ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.name }}</td>
|
||||
</ng-container>
|
||||
<div [hidden]="viewGroup.value !== 'listView'">
|
||||
<div #tableOffices class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' Office Name ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' External ID ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.externalId }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' External ID ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.externalId }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="parentName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' Parent Office ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.parentName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="parentName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' Parent Office ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.parentName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="openingDate">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' Opened On ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.openingDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="openingDate">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ ' Opened On ' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let offices">{{ offices.openingDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr
|
||||
mat-row
|
||||
*matRowDef="let row; columns: displayedColumns"
|
||||
class="select-row"
|
||||
[routerLink]="[row.id, 'general']"
|
||||
></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tree View -->
|
||||
<div class="container" [hidden]="viewGroup.value !== 'treeView'">
|
||||
<div class="m-b-20 layout-row align-start gap-20px">
|
||||
<button mat-raised-button (click)="toggleExpandCollapse()">
|
||||
{{ (isTreeExpanded ? 'labels.buttons.Collapse All' : 'labels.buttons.Expand All') | translate }}
|
||||
</button>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row" [routerLink]="[row.id, 'general']"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-row gap-4percent responsive-column">
|
||||
<div class="flex-fill">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<mat-tree [dataSource]="nestedTreeDataSource" [treeControl]="nestedTreeControl" class="office-tree">
|
||||
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
|
||||
<li class="mat-tree-node">
|
||||
<button mat-icon-button disabled></button>
|
||||
<span (click)="viewOfficeNode(node)" class="m-r-10">
|
||||
{{ node.name }}
|
||||
</span>
|
||||
</li>
|
||||
</mat-tree-node>
|
||||
<!-- Tree View -->
|
||||
<div [hidden]="viewGroup.value !== 'treeView'">
|
||||
<div class="m-b-20 layout-row align-start gap-20px">
|
||||
<button mat-raised-button (click)="toggleExpandCollapse()">
|
||||
{{ (isTreeExpanded ? 'labels.buttons.Collapse All' : 'labels.buttons.Expand All') | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-nested-tree-node *matTreeNodeDef="let node; when: hasNestedChild">
|
||||
<li>
|
||||
<div class="mat-tree-node">
|
||||
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
|
||||
<fa-icon
|
||||
class="mat-icon-rtl-mirror"
|
||||
icon="{{ nestedTreeControl.isExpanded(node) ? 'chevron-down' : 'chevron-right' }}"
|
||||
></fa-icon>
|
||||
</button>
|
||||
<div class="layout-row gap-4percent responsive-column">
|
||||
<div class="flex-fill">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<mat-tree [dataSource]="nestedTreeDataSource" [treeControl]="nestedTreeControl" class="office-tree">
|
||||
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
|
||||
<li class="mat-tree-node">
|
||||
<button mat-icon-button disabled></button>
|
||||
<span (click)="viewOfficeNode(node)" class="m-r-10">
|
||||
{{ node.name }}
|
||||
</span>
|
||||
</div>
|
||||
<ul [class.office-tree-invisible]="!nestedTreeControl.isExpanded(node)">
|
||||
<ng-container matTreeNodeOutlet></ng-container>
|
||||
</ul>
|
||||
</li>
|
||||
</mat-nested-tree-node>
|
||||
</mat-tree>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</li>
|
||||
</mat-tree-node>
|
||||
|
||||
@if (office) {
|
||||
<div class="flex-48">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row">
|
||||
<mat-card-title>
|
||||
{{ office.name }}
|
||||
</mat-card-title>
|
||||
<div class="flex align-end">
|
||||
<button mat-icon-button (click)="closeOffice()">
|
||||
<fa-icon icon="times"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-tab-group>
|
||||
<mat-tab label="General">
|
||||
<div class="layout-row-wrap">
|
||||
@if (office.parentId) {
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Parent Office' | translate }}
|
||||
</div>
|
||||
}
|
||||
@if (office.parentId) {
|
||||
<div class="flex-50">
|
||||
{{ office.parentName }}
|
||||
</div>
|
||||
}
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ ' Opened On' | translate }}
|
||||
<mat-nested-tree-node *matTreeNodeDef="let node; when: hasNestedChild">
|
||||
<li>
|
||||
<div class="mat-tree-node">
|
||||
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
|
||||
<fa-icon
|
||||
class="mat-icon-rtl-mirror"
|
||||
icon="{{ nestedTreeControl.isExpanded(node) ? 'chevron-down' : 'chevron-right' }}"
|
||||
></fa-icon>
|
||||
</button>
|
||||
<span (click)="viewOfficeNode(node)" class="m-r-10">
|
||||
{{ node.name }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex-50">
|
||||
{{ office.openingDate | date }}
|
||||
</div>
|
||||
@if (office.externalId) {
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'External Id' | translate }}
|
||||
</div>
|
||||
}
|
||||
@if (office.externalId) {
|
||||
<div class="flex-50">
|
||||
<mifosx-external-identifier externalId="{{ office.externalId }}"></mifosx-external-identifier>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</mat-tab>
|
||||
@for (dataTable of dataTablesData; track dataTable) {
|
||||
<mat-tab label="{{ dataTable.registeredTableName }}"></mat-tab>
|
||||
}
|
||||
</mat-tab-group>
|
||||
<ul [class.office-tree-invisible]="!nestedTreeControl.isExpanded(node)">
|
||||
<ng-container matTreeNodeOutlet></ng-container>
|
||||
</ul>
|
||||
</li>
|
||||
</mat-nested-tree-node>
|
||||
</mat-tree>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (office) {
|
||||
<div class="flex-48">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row">
|
||||
<mat-card-title>
|
||||
{{ office.name }}
|
||||
</mat-card-title>
|
||||
<div class="flex align-end">
|
||||
<button mat-icon-button (click)="closeOffice()">
|
||||
<fa-icon icon="times"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-tab-group>
|
||||
<mat-tab label="General">
|
||||
<div class="layout-row-wrap">
|
||||
@if (office.parentId) {
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Parent Office' | translate }}
|
||||
</div>
|
||||
}
|
||||
@if (office.parentId) {
|
||||
<div class="flex-50">
|
||||
{{ office.parentName }}
|
||||
</div>
|
||||
}
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ ' Opened On' | translate }}
|
||||
</div>
|
||||
<div class="flex-50">
|
||||
{{ office.openingDate | date }}
|
||||
</div>
|
||||
@if (office.externalId) {
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'External Id' | translate }}
|
||||
</div>
|
||||
}
|
||||
@if (office.externalId) {
|
||||
<div class="flex-50">
|
||||
<mifosx-external-identifier externalId="{{ office.externalId }}"></mifosx-external-identifier>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</mat-tab>
|
||||
@for (dataTable of dataTablesData; track dataTable) {
|
||||
<mat-tab label="{{ dataTable.registeredTableName }}"></mat-tab>
|
||||
}
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
@@ -6,48 +6,33 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="office-card-wrapper">
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
{{ 'labels.heading.General' | translate }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="gt-detail">
|
||||
<div class="gt-grid">
|
||||
<div class="gt-cell">
|
||||
<div class="gt-cell__label">{{ 'labels.inputs.Parent Office' | translate }}</div>
|
||||
<div class="gt-cell__value">{{ officeData.parentName ? officeData.parentName : 'N/A' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-container mat-typography compact-view">
|
||||
<div class="layout-row-wrap responsive-column compact-details condensed">...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-container mat-typography compact-view">
|
||||
<div class="layout-row-wrap responsive-column compact-details condensed">
|
||||
<div class="flex-45 mat-body-strong left">{{ 'labels.inputs.Parent Office' | translate }}</div>
|
||||
<div class="flex-50 right">
|
||||
{{ officeData.parentName ? officeData.parentName : 'N/A' }}
|
||||
</div>
|
||||
<hr class="section-divider" />
|
||||
|
||||
<div class="flex-45 mat-body-strong left">{{ 'labels.inputs.Opened On' | translate }}</div>
|
||||
<div class="flex-50 right">
|
||||
{{ officeData.openingDate ? (officeData.openingDate | dateFormat) : 'Unassigned' }}
|
||||
<div class="gt-cell">
|
||||
<div class="gt-cell__label">{{ 'labels.inputs.Opened On' | translate }}</div>
|
||||
<div class="gt-cell__value">{{ officeData.openingDate ? (officeData.openingDate | dateFormat) : 'Unassigned' }}</div>
|
||||
</div>
|
||||
<hr class="section-divider" />
|
||||
|
||||
<div class="flex-45 mat-body-strong left">{{ 'labels.inputs.Name Decorated' | translate }}</div>
|
||||
<div class="flex-50 right">
|
||||
{{ officeData.nameDecorated ? officeData.nameDecorated : 'Unassigned' }}
|
||||
<div class="gt-cell">
|
||||
<div class="gt-cell__label">{{ 'labels.inputs.Name Decorated' | translate }}</div>
|
||||
<div class="gt-cell__value">{{ officeData.nameDecorated ? officeData.nameDecorated : 'Unassigned' }}</div>
|
||||
</div>
|
||||
<hr class="section-divider" />
|
||||
|
||||
<div class="flex-45 mat-body-strong left">{{ 'labels.inputs.External Id' | translate }}</div>
|
||||
@if (officeData.externalId) {
|
||||
<div class="flex-50 right">
|
||||
<mifosx-external-identifier externalId="{{ officeData.externalId }}"></mifosx-external-identifier>
|
||||
<div class="gt-cell">
|
||||
<div class="gt-cell__label">{{ 'labels.inputs.External Id' | translate }}</div>
|
||||
<div class="gt-cell__value">
|
||||
@if (officeData.externalId) {
|
||||
<mifosx-external-identifier externalId="{{ officeData.externalId }}"></mifosx-external-identifier>
|
||||
}
|
||||
@if (!officeData.externalId) {
|
||||
{{ 'labels.inputs.Unassigned' | translate }}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (!officeData.externalId) {
|
||||
<div class="flex-50 right">
|
||||
{{ 'labels.inputs.Unassigned' | translate }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,124 +6,52 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.office-card-wrapper {
|
||||
max-width: 450px;
|
||||
margin: 0 auto;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.gt-detail {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0.75rem 0.75rem 0.25rem;
|
||||
// Grid
|
||||
.gt-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
padding: 0.5rem;
|
||||
margin: 1% auto;
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
|
||||
.delete-button {
|
||||
margin-left: 1%;
|
||||
}
|
||||
}
|
||||
|
||||
.table-name {
|
||||
padding-left: 2%;
|
||||
}
|
||||
|
||||
.table-data {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.compact-button {
|
||||
padding: 0.25rem 0.75rem;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.compact-details {
|
||||
font-size: 0.9rem;
|
||||
|
||||
.left,
|
||||
.right {
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
.mat-body-strong {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-button-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 2rem;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.edit-button {
|
||||
min-width: 120px;
|
||||
padding: 0.5rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 3px 5px rgb(0 0 0 / 20%);
|
||||
transition: all 0.3s ease;
|
||||
.gt-cell {
|
||||
padding: 14px 16px;
|
||||
background: $gray-50;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
transition: background 0.12s;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 8px rgb(0 0 0 / 30%);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.layout-row-wrap {
|
||||
margin: 0 auto;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-top: 1px solid rgb(0 0 0 / 10%);
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.compact-view {
|
||||
padding: 0.3rem;
|
||||
margin: 0 auto;
|
||||
max-width: 450px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.condensed {
|
||||
.flex-45,
|
||||
.flex-50 {
|
||||
padding: 0.2rem 0;
|
||||
font-size: 0.85rem;
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
margin: 4px 0;
|
||||
&__label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
.small-buttons {
|
||||
margin-top: 1rem;
|
||||
|
||||
.edit-button {
|
||||
min-width: 100px;
|
||||
padding: 0.35rem 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-container.compact-view {
|
||||
max-width: 450px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
@@ -6,53 +6,53 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container narrow-container extra-small">
|
||||
<div class="action-bar">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
class="edit-button"
|
||||
[routerLink]="['./edit']"
|
||||
*mifosxHasPermission="'UPDATE_OFFICE'"
|
||||
>
|
||||
<div class="vo-container">
|
||||
<!-- Header -->
|
||||
<div class="vo-header">
|
||||
<div class="vo-header__left">
|
||||
<button mat-stroked-button [routerLink]="['../../']" class="vo-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.inputs.Offices' | translate }}
|
||||
</button>
|
||||
<h2 class="vo-header__title">{{ 'labels.heading.Office Details' | translate }}</h2>
|
||||
</div>
|
||||
<button mat-flat-button color="primary" [routerLink]="['./edit']" class="vo-edit-btn" *mifosxHasPermission="'UPDATE_OFFICE'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-card class="office-card">
|
||||
<mat-card-content class="card-content">
|
||||
<nav mat-tab-nav-bar class="navigation-tabs" [tabPanel]="tabPanel">
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./general']"
|
||||
routerLinkActive
|
||||
#general="routerLinkActive"
|
||||
[active]="general.isActive"
|
||||
class="compact-tab"
|
||||
>
|
||||
{{ 'labels.inputs.General' | translate }}
|
||||
</a>
|
||||
@for (officeDatatable of officeDatatables; track officeDatatable) {
|
||||
<span>
|
||||
<a
|
||||
mat-tab-link
|
||||
*mifosxHasPermission="'READ_' + officeDatatable.registeredTableName"
|
||||
[routerLink]="['./datatables', officeDatatable.registeredTableName]"
|
||||
routerLinkActive
|
||||
#datatable="routerLinkActive"
|
||||
[active]="datatable.isActive"
|
||||
class="compact-tab"
|
||||
>
|
||||
{{ officeDatatable.registeredTableName }}
|
||||
</a>
|
||||
</span>
|
||||
}
|
||||
</nav>
|
||||
<!-- Tab Card -->
|
||||
<div class="vo-card">
|
||||
<nav mat-tab-nav-bar class="vo-tabs" [tabPanel]="tabPanel">
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./general']"
|
||||
routerLinkActive
|
||||
#general="routerLinkActive"
|
||||
[active]="general.isActive"
|
||||
class="vo-tab"
|
||||
>
|
||||
{{ 'labels.inputs.General' | translate }}
|
||||
</a>
|
||||
@for (officeDatatable of officeDatatables; track officeDatatable) {
|
||||
<span>
|
||||
<a
|
||||
mat-tab-link
|
||||
*mifosxHasPermission="'READ_' + officeDatatable.registeredTableName"
|
||||
[routerLink]="['./datatables', officeDatatable.registeredTableName]"
|
||||
routerLinkActive
|
||||
#datatable="routerLinkActive"
|
||||
[active]="datatable.isActive"
|
||||
class="vo-tab"
|
||||
>
|
||||
{{ officeDatatable.registeredTableName }}
|
||||
</a>
|
||||
</span>
|
||||
}
|
||||
</nav>
|
||||
|
||||
<mat-tab-nav-panel #tabPanel class="tab-panel">
|
||||
<router-outlet></router-outlet>
|
||||
</mat-tab-nav-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<mat-tab-nav-panel #tabPanel class="vo-panel">
|
||||
<router-outlet></router-outlet>
|
||||
</mat-tab-nav-panel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,104 +6,95 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.action-button {
|
||||
width: 85%;
|
||||
margin: 0.2rem auto;
|
||||
padding: 0.3rem;
|
||||
border-radius: 3px;
|
||||
transition: all 0.3s ease;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgb(0 0 0 / 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.office-card {
|
||||
width: 100%;
|
||||
margin: 0.75rem auto;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px !important;
|
||||
box-shadow: 0 2px 8px rgb(0 0 0 / 10%) !important;
|
||||
|
||||
.navigation-tabs {
|
||||
overflow: auto;
|
||||
padding: 0.2rem 0;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: rgb(0 0 0 / 20%);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mat-tab-label {
|
||||
min-width: 80px;
|
||||
padding: 0 0.5rem;
|
||||
height: 36px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 768px) {
|
||||
width: 85%;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.narrow-container {
|
||||
max-width: 600px;
|
||||
.vo-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 0.75rem;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.extra-small {
|
||||
max-width: 500px;
|
||||
// Header
|
||||
.vo-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.compact-tab {
|
||||
.vo-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.vo-edit-btn {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
}
|
||||
|
||||
// Card
|
||||
.vo-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Tabs
|
||||
.vo-tabs {
|
||||
padding: 0 24px;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
}
|
||||
|
||||
.vo-tab {
|
||||
min-width: auto;
|
||||
padding: 0 12px;
|
||||
padding: 0 16px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 0.5rem;
|
||||
// Panel
|
||||
.vo-panel {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
.tab-panel {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
max-width: 600px;
|
||||
margin: 0 auto 0.5rem;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.edit-button {
|
||||
min-width: 110px;
|
||||
padding: 0.4rem 1rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.tab-header-with-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.5rem 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.tab-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
// Responsive
|
||||
@media (max-width: 600px) {
|
||||
.vo-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,552 +6,289 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="layout-row responsive-column gap-20px">
|
||||
<div class="flex-50">
|
||||
<mat-nav-list>
|
||||
<div #office>
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['offices']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="building" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Manage Offices' | translate }}
|
||||
@if (arrowBooleans[0]) {
|
||||
<p matLine [routerLink]="['offices']" class="menu-explanation">
|
||||
{{ 'labels.text.Add new office or modify or deactivate office' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[0]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(0)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[0]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(0)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #holidays>
|
||||
<mat-list-item *mifosxHasPermission="'READ_HOLIDAY'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['holidays']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="calendar-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Manage Holidays' | translate }}
|
||||
@if (arrowBooleans[1]) {
|
||||
<p matLine [routerLink]="['holidays']" class="menu-explanation">
|
||||
{{ 'labels.text.Define holidays for office' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[1]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(1)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[1]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(1)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #employee>
|
||||
<mat-list-item *mifosxHasPermission="'READ_STAFF'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['employees']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="user" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Manage Employees' | translate }}
|
||||
@if (arrowBooleans[2]) {
|
||||
<p matLine [routerLink]="['employees']" class="menu-explanation">
|
||||
{{ 'labels.text.Employee represents loan officers' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[2]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(2)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[2]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(2)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #standinginstructions>
|
||||
<mat-list-item *mifosxHasPermission="'READ_STANDINGINSTRUCTION'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['standing-instructions-history']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="book" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Standing Instructions History' | translate }}
|
||||
@if (arrowBooleans[3]) {
|
||||
<p matLine [routerLink]="['standing-instructions-history']" class="menu-explanation">
|
||||
{{ 'labels.text.View logged history' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[3]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(3)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[3]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(3)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #investor>
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['investors']">
|
||||
<mat-icon>
|
||||
<fa-icon icon="user-tie" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.text.Investors' | translate }}
|
||||
@if (arrowBooleans[4]) {
|
||||
<p matLine [routerLink]="['investors']" class="menu-explanation">
|
||||
{{ 'labels.text.View the loan account details associated with the investors' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[4]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(4)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[4]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(4)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #fundmapping>
|
||||
<mat-list-item *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['fund-mapping']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="money-bill-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Fund Mapping' | translate }}
|
||||
@if (arrowBooleans[5]) {
|
||||
<p matLine [routerLink]="['fund-mapping']" class="menu-explanation">
|
||||
{{ 'labels.text.Bulk entry screen for mapping' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[5]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(5)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[5]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(5)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #passwordpreferences>
|
||||
<mat-list-item *mifosxHasPermission="'READ_PASSWORD_VALIDATION_POLICY'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['password-preferences']">
|
||||
<mat-icon>
|
||||
<fa-icon icon="lock" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Password Preferences' | translate }}
|
||||
@if (arrowBooleans[6]) {
|
||||
<p matLine [routerLink]="['password-preferences']" class="menu-explanation">
|
||||
{{ 'labels.text.The usage of stronger passwords' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[6]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(6)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[6]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(6)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #provisioning>
|
||||
<mat-list-item *mifosxHasPermission="'VIEW_PROVISIONS'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['provisioning-criteria']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="edit" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Loan Provisioning Criteria' | translate }}
|
||||
@if (arrowBooleans[7]) {
|
||||
<p matLine [routerLink]="['provisioning-criteria']" class="menu-explanation">
|
||||
{{ 'labels.text.Loan Provisioning Criteria Organization' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[7]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(7)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[7]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(7)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #entitydatatable>
|
||||
<mat-list-item *mifosxHasPermission="'READ_ENTITY_DATATABLE_CHECK'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['entity-data-table-checks']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="check" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Entity Data Table Checks' | translate }}
|
||||
@if (arrowBooleans[8]) {
|
||||
<p matLine [routerLink]="['entity-data-table-checks']" class="menu-explanation">
|
||||
{{ 'labels.text.Entity Data Table Checks Organization' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[8]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(8)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[8]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(8)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
<mat-nav-list>
|
||||
<div #addEditCurrency>
|
||||
<mat-list-item *mifosxHasPermission="'READ_CURRENCY'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['currencies']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="cogs" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Currency Configuration' | translate }}
|
||||
@if (arrowBooleans[9]) {
|
||||
<p matLine [routerLink]="['currencies']" class="menu-explanation">
|
||||
{{ 'labels.text.Currencies available across organization' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[9]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(9)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[9]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(9)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #manageFunds>
|
||||
<mat-list-item *mifosxHasPermission="'READ_FUND'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['manage-funds']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="money-bill-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Manage Funds' | translate }}
|
||||
@if (arrowBooleans[10]) {
|
||||
<p matLine [routerLink]="['manage-funds']" class="menu-explanation">
|
||||
{{ 'labels.text.Funds are associated with loans' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[10]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(10)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[10]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(10)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #manageLoanOriginators>
|
||||
<mat-list-item *mifosxHasPermission="'READ_LOAN_ORIGINATOR'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['manage-loan-originators']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="edit" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Manage Loan Originators' | translate }}
|
||||
@if (arrowBooleans[18]) {
|
||||
<p matLine [routerLink]="['manage-loan-originators']" class="menu-explanation">
|
||||
{{ 'labels.text.Loan Originators are associated with loan accounts' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[18]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(18)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[18]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(18)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #bulkloan>
|
||||
<mat-list-item *mifosxHasPermission="'BULKREASSIGN_LOAN'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['bulkloan']">
|
||||
<mat-icon>
|
||||
<fa-icon icon="money-bill-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Bulk Loan Reassignment' | translate }}
|
||||
@if (arrowBooleans[11]) {
|
||||
<p matLine [routerLink]="['bulkloan']" class="menu-explanation">
|
||||
{{ 'labels.text.Easy way to reassign all the loan' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[11]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(11)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[11]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(11)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #tellers>
|
||||
<mat-list-item *mifosxHasPermission="'READ_TELLER'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['tellers']">
|
||||
<mat-icon>
|
||||
<fa-icon icon="money-bill-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Teller / Cashier Management' | translate }}
|
||||
@if (arrowBooleans[12]) {
|
||||
<p matLine [routerLink]="['tellers']" class="menu-explanation">
|
||||
{{ 'labels.text.Manage Tellers / Cashiers' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[12]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(12)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[12]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(12)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #workingDays>
|
||||
<mat-list-item *mifosxHasPermission="'READ_WORKINGDAYS'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['working-days']">
|
||||
<mat-icon>
|
||||
<fa-icon icon="calendar-alt" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Working Days' | translate }}
|
||||
@if (arrowBooleans[13]) {
|
||||
<p matLine [routerLink]="['working-days']" class="menu-explanation">
|
||||
{{ 'labels.text.Working days and configure behaviour of payments' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[13]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(13)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[13]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(13)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #paymenttypes>
|
||||
<mat-list-item *mifosxHasPermission="'READ_PAYMENTTYPE'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['payment-types']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="dollar-sign" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Payment Type' | translate }}
|
||||
@if (arrowBooleans[14]) {
|
||||
<p matLine [routerLink]="['payment-types']" class="menu-explanation">
|
||||
{{ 'labels.text.Manage payment types' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[14]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(14)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[14]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(14)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #smscampaigns>
|
||||
<mat-list-item *mifosxHasPermission="'VIEW_SMSCAMPAIGNS'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['sms-campaigns']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="envelope" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.SMS Campaigns' | translate }}
|
||||
@if (arrowBooleans[15]) {
|
||||
<p matLine [routerLink]="['sms-campaigns']" class="menu-explanation">
|
||||
{{ 'labels.text.Define SMS Campaigns for Organization' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[15]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(15)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[15]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(15)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #adhocquery>
|
||||
<mat-list-item *mifosxHasPermission="'VIEW_ADHOC'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['adhoc-query']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="chevron-right" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.AdHocQuery' | translate }}
|
||||
@if (arrowBooleans[16]) {
|
||||
<p matLine [routerLink]="['adhoc-query']" class="menu-explanation">
|
||||
{{ 'labels.text.Define AdHocQuery for Organization' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[16]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(16)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[16]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(16)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
||||
<div #bulkimport>
|
||||
<mat-list-item *mifosxHasPermission="'VIEW_BULKIMPORT'">
|
||||
<div class="menu-list-item-content">
|
||||
<div class="menu-left-section" [routerLink]="['bulk-import']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="upload" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<div matLine>
|
||||
{{ 'labels.heading.Bulk Import' | translate }}
|
||||
@if (arrowBooleans[17]) {
|
||||
<p matLine [routerLink]="['bulk-import']" class="menu-explanation">
|
||||
{{ 'labels.text.Bulk data import using excel spreadsheet templates' | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-right-section">
|
||||
@if (!arrowBooleans[17]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(17)" icon="arrow-down" size="md"></fa-icon>
|
||||
}
|
||||
@if (arrowBooleans[17]) {
|
||||
<fa-icon (click)="arrowBooleansToggle(17)" icon="arrow-up" size="md"></fa-icon>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
<div class="org-container">
|
||||
<!-- Page header -->
|
||||
<div class="org-header">
|
||||
<div class="org-header__icon">
|
||||
<i class="fas fa-sitemap"></i>
|
||||
</div>
|
||||
</mat-card>
|
||||
<div>
|
||||
<h1 class="org-header__title">{{ 'labels.heading.Organization' | translate }}</h1>
|
||||
<p class="org-header__sub">Manage offices, employees, currencies and other organizational settings</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Grid -->
|
||||
<div class="org-grid">
|
||||
<!-- Manage Offices -->
|
||||
<div #office>
|
||||
<a class="org-card" [routerLink]="['offices']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--blue">
|
||||
<i class="fas fa-building"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Manage Offices' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Add new office or modify or deactivate office' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Currency Configuration -->
|
||||
<div #addEditCurrency>
|
||||
<a class="org-card" [routerLink]="['currencies']" *mifosxHasPermission="'READ_CURRENCY'">
|
||||
<div class="org-card__icon org-card__icon--amber">
|
||||
<i class="fas fa-cogs"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Currency Configuration' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Currencies available across organization' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Manage Holidays -->
|
||||
<div #holidays>
|
||||
<a class="org-card" [routerLink]="['holidays']" *mifosxHasPermission="'READ_HOLIDAY'">
|
||||
<div class="org-card__icon org-card__icon--green">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Manage Holidays' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Define holidays for office' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Manage Funds -->
|
||||
<div #manageFunds>
|
||||
<a class="org-card" [routerLink]="['manage-funds']" *mifosxHasPermission="'READ_FUND'">
|
||||
<div class="org-card__icon org-card__icon--emerald">
|
||||
<i class="fas fa-money-bill-alt"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Manage Funds' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Funds are associated with loans' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Manage Employees -->
|
||||
<div #employee>
|
||||
<a class="org-card" [routerLink]="['employees']" *mifosxHasPermission="'READ_STAFF'">
|
||||
<div class="org-card__icon org-card__icon--purple">
|
||||
<i class="fas fa-user"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Manage Employees' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Employee represents loan officers' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Manage Loan Originators -->
|
||||
<div #manageLoanOriginators>
|
||||
<a class="org-card" [routerLink]="['manage-loan-originators']" *mifosxHasPermission="'READ_LOAN_ORIGINATOR'">
|
||||
<div class="org-card__icon org-card__icon--indigo">
|
||||
<i class="fas fa-edit"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Manage Loan Originators' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Loan Originators are associated with loan accounts' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Standing Instructions History -->
|
||||
<div #standinginstructions>
|
||||
<a class="org-card" [routerLink]="['standing-instructions-history']" *mifosxHasPermission="'READ_STANDINGINSTRUCTION'">
|
||||
<div class="org-card__icon org-card__icon--slate">
|
||||
<i class="fas fa-book"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Standing Instructions History' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.View logged history' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Bulk Loan Reassignment -->
|
||||
<div #bulkloan>
|
||||
<a class="org-card" [routerLink]="['bulkloan']" *mifosxHasPermission="'BULKREASSIGN_LOAN'">
|
||||
<div class="org-card__icon org-card__icon--orange">
|
||||
<i class="fas fa-money-bill-alt"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Bulk Loan Reassignment' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Easy way to reassign all the loan' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Investors -->
|
||||
<div #investor>
|
||||
<a class="org-card" [routerLink]="['investors']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--teal">
|
||||
<i class="fas fa-user-tie"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.text.Investors' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.View the loan account details associated with the investors' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Teller / Cashier Management -->
|
||||
<div #tellers>
|
||||
<a class="org-card" [routerLink]="['tellers']" *mifosxHasPermission="'READ_TELLER'">
|
||||
<div class="org-card__icon org-card__icon--cyan">
|
||||
<i class="fas fa-cash-register"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Teller / Cashier Management' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Manage Tellers / Cashiers' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Fund Mapping -->
|
||||
<div #fundmapping>
|
||||
<a class="org-card" [routerLink]="['fund-mapping']" *mifosxHasPermission="'READ_OFFICE'">
|
||||
<div class="org-card__icon org-card__icon--rose">
|
||||
<i class="fas fa-money-bill-alt"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Fund Mapping' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Bulk entry screen for mapping' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Working Days -->
|
||||
<div #workingDays>
|
||||
<a class="org-card" [routerLink]="['working-days']" *mifosxHasPermission="'READ_WORKINGDAYS'">
|
||||
<div class="org-card__icon org-card__icon--green">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Working Days' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Working days and configure behaviour of payments' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Password Preferences -->
|
||||
<div #passwordpreferences>
|
||||
<a class="org-card" [routerLink]="['password-preferences']" *mifosxHasPermission="'READ_PASSWORD_VALIDATION_POLICY'">
|
||||
<div class="org-card__icon org-card__icon--red">
|
||||
<i class="fas fa-lock"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Password Preferences' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.The usage of stronger passwords' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Payment Type -->
|
||||
<div #paymenttypes>
|
||||
<a class="org-card" [routerLink]="['payment-types']" *mifosxHasPermission="'READ_PAYMENTTYPE'">
|
||||
<div class="org-card__icon org-card__icon--emerald">
|
||||
<i class="fas fa-dollar-sign"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Payment Type' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Manage payment types' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Loan Provisioning Criteria -->
|
||||
<div #provisioning>
|
||||
<a class="org-card" [routerLink]="['provisioning-criteria']" *mifosxHasPermission="'VIEW_PROVISIONS'">
|
||||
<div class="org-card__icon org-card__icon--indigo">
|
||||
<i class="fas fa-edit"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Loan Provisioning Criteria' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Loan Provisioning Criteria Organization' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- SMS Campaigns -->
|
||||
<div #smscampaigns>
|
||||
<a class="org-card" [routerLink]="['sms-campaigns']" *mifosxHasPermission="'VIEW_SMSCAMPAIGNS'">
|
||||
<div class="org-card__icon org-card__icon--purple">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.SMS Campaigns' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Define SMS Campaigns for Organization' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Entity Data Table Checks -->
|
||||
<div #entitydatatable>
|
||||
<a class="org-card" [routerLink]="['entity-data-table-checks']" *mifosxHasPermission="'READ_ENTITY_DATATABLE_CHECK'">
|
||||
<div class="org-card__icon org-card__icon--slate">
|
||||
<i class="fas fa-check"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Entity Data Table Checks' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Entity Data Table Checks Organization' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- AdHocQuery -->
|
||||
<div #adhocquery>
|
||||
<a class="org-card" [routerLink]="['adhoc-query']" *mifosxHasPermission="'VIEW_ADHOC'">
|
||||
<div class="org-card__icon org-card__icon--amber">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.AdHocQuery' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Define AdHocQuery for Organization' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Bulk Import -->
|
||||
<div #bulkimport>
|
||||
<a class="org-card" [routerLink]="['bulk-import']" *mifosxHasPermission="'VIEW_BULKIMPORT'">
|
||||
<div class="org-card__icon org-card__icon--blue">
|
||||
<i class="fas fa-upload"></i>
|
||||
</div>
|
||||
<div class="org-card__body">
|
||||
<h3 class="org-card__title">{{ 'labels.heading.Bulk Import' | translate }}</h3>
|
||||
<p class="org-card__desc">{{ 'labels.text.Bulk data import using excel spreadsheet templates' | translate }}</p>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right org-card__arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Wizard Templates (unchanged) -->
|
||||
<ng-template #templateOffice let-popover="popover">
|
||||
<h2>{{ 'labels.heading.Manage Offices' | translate }}</h2>
|
||||
<p class="mw300">{{ 'labels.text.Manage Offices page allows you to create, edit' | translate }}</p>
|
||||
|
||||
@@ -5,3 +5,212 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8fafc;
|
||||
$gray-100: #f1f5f9;
|
||||
$gray-400: #94a3b8;
|
||||
$gray-500: #64748b;
|
||||
$gray-700: #334155;
|
||||
$gray-900: #0f172a;
|
||||
|
||||
// ── Container ──
|
||||
.org-container {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
// ── Page Header ──
|
||||
.org-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 28px;
|
||||
|
||||
&__icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, #0d3d78, #1a5276);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
&__sub {
|
||||
font-size: 13px;
|
||||
color: $gray-500;
|
||||
margin: 2px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Card Grid ──
|
||||
.org-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Individual Card ──
|
||||
.org-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 14px 16px;
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #cbd5e1;
|
||||
background: $gray-50;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
|
||||
.org-card__arrow {
|
||||
color: $gray-700;
|
||||
transform: translateX(2px);
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 9px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&--blue {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
&--amber {
|
||||
background: rgba(245, 158, 11, 0.1);
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
&--green {
|
||||
background: rgba(34, 197, 94, 0.1);
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
&--emerald {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
&--purple {
|
||||
background: rgba(139, 92, 246, 0.1);
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
&--indigo {
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
color: #4f46e5;
|
||||
}
|
||||
|
||||
&--slate {
|
||||
background: rgba(100, 116, 139, 0.1);
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
&--orange {
|
||||
background: rgba(249, 115, 22, 0.1);
|
||||
color: #ea580c;
|
||||
}
|
||||
|
||||
&--teal {
|
||||
background: rgba(20, 184, 166, 0.1);
|
||||
color: #0d9488;
|
||||
}
|
||||
|
||||
&--cyan {
|
||||
background: rgba(6, 182, 212, 0.1);
|
||||
color: #0891b2;
|
||||
}
|
||||
|
||||
&--rose {
|
||||
background: rgba(244, 63, 94, 0.1);
|
||||
color: #e11d48;
|
||||
}
|
||||
|
||||
&--red {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
|
||||
&__body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 13.5px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
&__desc {
|
||||
font-size: 11.5px;
|
||||
color: $gray-400;
|
||||
margin: 3px 0 0;
|
||||
line-height: 1.35;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&__arrow {
|
||||
font-size: 11px;
|
||||
color: #cbd5e1;
|
||||
flex-shrink: 0;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Dark mode ──
|
||||
:host-context(.dark-theme) {
|
||||
.org-header {
|
||||
&__title { color: #e2e8f0; }
|
||||
&__sub { color: #94a3b8; }
|
||||
}
|
||||
|
||||
.org-card {
|
||||
background: #1e1e1e;
|
||||
border-color: #333;
|
||||
|
||||
&:hover {
|
||||
background: #262626;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
&__title { color: #e2e8f0; }
|
||||
&__desc { color: #64748b; }
|
||||
&__arrow { color: #444; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,6 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
/** Custom Services */
|
||||
import { ConfigurationWizardService } from '../configuration-wizard/configuration-wizard.service';
|
||||
import { PopoverService } from '../configuration-wizard/popover/popover.service';
|
||||
import { MatNavList, MatListItem } from '@angular/material/list';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { MatLine } from '@angular/material/grid-list';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/**
|
||||
@@ -27,12 +23,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
templateUrl: './organization.component.html',
|
||||
styleUrls: ['./organization.component.scss'],
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
MatNavList,
|
||||
MatListItem,
|
||||
MatIcon,
|
||||
FaIconComponent,
|
||||
MatLine
|
||||
...STANDALONE_SHARED_IMPORTS
|
||||
]
|
||||
})
|
||||
export class OrganizationComponent implements AfterViewInit {
|
||||
@@ -66,8 +57,6 @@ export class OrganizationComponent implements AfterViewInit {
|
||||
@ViewChild('manageFunds') manageFunds: ElementRef<any>;
|
||||
/* Template for popover on manage funds */
|
||||
@ViewChild('templateManageFunds') templateManageFunds: TemplateRef<any>;
|
||||
// Initialize an array of 18 boolean values, all set to false
|
||||
arrowBooleans: boolean[] = new Array(19).fill(false);
|
||||
|
||||
/**
|
||||
* Popover function
|
||||
@@ -226,8 +215,4 @@ export class OrganizationComponent implements AfterViewInit {
|
||||
this.router.navigate(['/products/recurring-deposit-products']);
|
||||
}
|
||||
|
||||
arrowBooleansToggle(arrowNumber: number) {
|
||||
// Toggle the boolean value at the given index
|
||||
this.arrowBooleans[arrowNumber] = !this.arrowBooleans[arrowNumber];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
<!--
|
||||
Copyright since 2025 Mifos Initiative
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
<div class="pp-container">
|
||||
<div class="pp-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="pp-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Organization' | translate }}
|
||||
</button>
|
||||
<h2 class="pp-header__title">{{ 'labels.heading.Password Preferences' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="pp-card">
|
||||
<form [formGroup]="passwordPreferencesForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<mat-radio-group class="password-cards-container" formControlName="validationPolicyId">
|
||||
<div
|
||||
*ngFor="let passwordPreference of passwordPreferencesData; trackBy: trackByPasswordPreference"
|
||||
class="password-card"
|
||||
[class.selected]="passwordPreferencesForm.get('validationPolicyId')?.value === passwordPreference.id"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div class="card-heading">
|
||||
{{ getPasswordLabel(passwordPreference) | translate }}
|
||||
<div class="pp-section">
|
||||
<div class="pp-section__header">
|
||||
<i class="fas fa-lock"></i>
|
||||
<h3>Password Validation Policy</h3>
|
||||
</div>
|
||||
<div class="pp-body">
|
||||
<mat-radio-group class="pp-options" formControlName="validationPolicyId">
|
||||
<div *ngFor="let passwordPreference of passwordPreferencesData; trackBy: trackByPasswordPreference"
|
||||
class="pp-option"
|
||||
[class.pp-option--selected]="passwordPreferencesForm.get('validationPolicyId')?.value === passwordPreference.id">
|
||||
<div class="pp-option__header">
|
||||
<div class="pp-option__title">{{ getPasswordLabel(passwordPreference) | translate }}</div>
|
||||
<mat-radio-button [value]="passwordPreference.id"></mat-radio-button>
|
||||
</div>
|
||||
<mat-radio-button [value]="passwordPreference.id"></mat-radio-button>
|
||||
<div class="pp-option__desc">{{ passwordPreference.description | translateKey: 'passwordPreferences' }}</div>
|
||||
</div>
|
||||
</mat-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-description">
|
||||
<span class="description-wrap">
|
||||
{{ passwordPreference.description | translateKey: 'passwordPreferences' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-radio-group>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="pp-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="pp-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[disabled]="passwordPreferencesForm.pristine"
|
||||
*mifosxHasPermission="'UPDATE_PASSWORD_VALIDATION_POLICY'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<button type="submit" mat-flat-button color="primary" [disabled]="passwordPreferencesForm.pristine"
|
||||
*mifosxHasPermission="'UPDATE_PASSWORD_VALIDATION_POLICY'" class="pp-actions__submit">
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,49 +5,57 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.description-wrap {
|
||||
white-space: normal;
|
||||
.pp-container { max-width: 700px; margin: 0 auto; padding: 20px 16px; }
|
||||
|
||||
.pp-header {
|
||||
display: flex; align-items: center; gap: 14px; margin-bottom: 20px;
|
||||
&__title { font-size: 18px; font-weight: 600; color: $gray-900; margin: 0; }
|
||||
}
|
||||
|
||||
.password-cards-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
.pp-back {
|
||||
border-radius: 8px !important; font-size: 12px !important; font-weight: 600 !important;
|
||||
height: 32px !important; border-color: $border !important; color: $gray-500 !important;
|
||||
i { margin-right: 6px; }
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.password-card {
|
||||
width: 100%;
|
||||
border: 1px solid rgb(0 0 0 / 12%);
|
||||
border-radius: 4px;
|
||||
padding: 1.5rem;
|
||||
box-sizing: border-box;
|
||||
.pp-card { background: #fff; border: 1px solid $border; border-radius: 10px; overflow: hidden; }
|
||||
|
||||
&.selected {
|
||||
border-color: currentcolor;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-heading {
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.card-description {
|
||||
padding-left: 0;
|
||||
|
||||
.description-wrap {
|
||||
white-space: normal;
|
||||
display: block;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.pp-section {
|
||||
&__header {
|
||||
display: flex; align-items: center; gap: 10px; padding: 12px 24px;
|
||||
background: $gray-50; border-bottom: 1px solid $gray-200;
|
||||
i { font-size: 14px; color: $accent; }
|
||||
h3 { margin: 0; font-size: 14px; font-weight: 600; color: $gray-900; }
|
||||
}
|
||||
}
|
||||
|
||||
.pp-body { padding: 20px 24px; }
|
||||
|
||||
.pp-options { display: flex; flex-direction: column; gap: 12px; }
|
||||
|
||||
.pp-option {
|
||||
border: 1px solid $border; border-radius: 8px; padding: 16px 20px;
|
||||
transition: all 0.15s;
|
||||
&:hover { border-color: #cbd5e1; background: $gray-50; }
|
||||
&--selected { border-color: $primary; border-width: 2px; background: rgba($primary, 0.02); }
|
||||
&__header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
|
||||
&__title { font-size: 14px; font-weight: 600; color: $gray-900; }
|
||||
&__desc { font-size: 13px; color: $gray-700; line-height: 1.5; }
|
||||
}
|
||||
|
||||
.pp-actions {
|
||||
display: flex; justify-content: flex-end; gap: 10px; padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200; background: $gray-50;
|
||||
&__cancel { border-radius: 8px !important; font-size: 13px !important; font-weight: 600 !important; height: 36px !important; border-color: $border !important; color: $gray-700 !important; }
|
||||
&__submit { border-radius: 8px !important; font-size: 13px !important; font-weight: 600 !important; height: 36px !important; box-shadow: 0 1px 3px rgba($primary, 0.3) !important; i { margin-right: 6px; font-size: 12px; } }
|
||||
}
|
||||
|
||||
+38
-23
@@ -6,12 +6,23 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="cp-container">
|
||||
<div class="cp-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="cp-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Payment Type' | translate }}
|
||||
</button>
|
||||
<h2 class="cp-header__title">{{ 'labels.heading.Create Payment Type' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="cp-card">
|
||||
<form [formGroup]="paymentTypeForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="cp-section">
|
||||
<div class="cp-section__header">
|
||||
<i class="fas fa-dollar-sign"></i>
|
||||
<h3>{{ 'labels.heading.Payment Type Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="cp-grid">
|
||||
<mat-form-field appearance="outline" class="cp-field">
|
||||
<mat-label>{{ 'labels.inputs.Payment Type' | translate }}</mat-label>
|
||||
<input required matInput formControlName="name" />
|
||||
@if (paymentTypeForm.controls.name.hasError('required')) {
|
||||
@@ -22,16 +33,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<textarea matInput formControlName="description" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox labelPosition="before" formControlName="isCashPayment" class="status">
|
||||
{{ 'labels.inputs.Is Cash Payment' | translate }}?
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="cp-field">
|
||||
<mat-label>{{ 'labels.inputs.Position' | translate }}</mat-label>
|
||||
<input required matInput type="number" min="1" formControlName="position" />
|
||||
@if (paymentTypeForm.controls.position.hasError('required')) {
|
||||
@@ -44,22 +46,35 @@
|
||||
<mat-error> {{ 'labels.inputs.Position' | translate }} must be a positive number. </mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<mat-form-field appearance="outline" class="cp-field cp-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<textarea matInput formControlName="description" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="cp-checkbox-row">
|
||||
<mat-checkbox labelPosition="after" formControlName="isCashPayment">
|
||||
{{ 'labels.inputs.Is Cash Payment' | translate }}?
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cp-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="cp-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!paymentTypeForm.valid"
|
||||
class="cp-actions__submit"
|
||||
*mifosxHasPermission="'CREATE_PAYMENTTYPE'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+128
-5
@@ -6,10 +6,133 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
}
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.status {
|
||||
padding: 17.5px 0;
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.cp-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cp-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.cp-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cp-section {
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cp-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.cp-field {
|
||||
width: 100% !important;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-actions {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50 !important;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
-26
@@ -6,12 +6,23 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="ep-container">
|
||||
<div class="ep-header">
|
||||
<button mat-stroked-button [routerLink]="['../../']" class="ep-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Payment Type' | translate }}
|
||||
</button>
|
||||
<h2 class="ep-header__title">{{ 'labels.heading.Edit Payment Type' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="ep-card">
|
||||
<form [formGroup]="paymentTypeForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="ep-section">
|
||||
<div class="ep-section__header">
|
||||
<i class="fas fa-dollar-sign"></i>
|
||||
<h3>{{ 'labels.heading.Payment Type Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ep-grid">
|
||||
<mat-form-field appearance="outline" class="ep-field">
|
||||
<mat-label>{{ 'labels.inputs.Payment Type' | translate }}</mat-label>
|
||||
<input required matInput formControlName="name" />
|
||||
@if (paymentTypeForm.controls.name.hasError('required')) {
|
||||
@@ -22,44 +33,48 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<textarea matInput formControlName="description" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox labelPosition="before" formControlName="isCashPayment" class="status">
|
||||
{{ 'labels.inputs.Is Cash Payment' | translate }}?
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="ep-field">
|
||||
<mat-label>{{ 'labels.inputs.Position' | translate }}</mat-label>
|
||||
<input required matInput type="number" min="1" formControlName="position" />
|
||||
@if (paymentTypeForm.controls.position.hasError('min')) {
|
||||
<mat-error> {{ 'labels.inputs.Position' | translate }} must be a positive number. </mat-error>
|
||||
}
|
||||
@if (paymentTypeForm.controls.position.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Position' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
@if (paymentTypeForm.controls.position.hasError('min')) {
|
||||
<mat-error> {{ 'labels.inputs.Position' | translate }} must be a positive number. </mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../../']">
|
||||
<mat-form-field appearance="outline" class="ep-field ep-field--full">
|
||||
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
|
||||
<textarea matInput formControlName="description" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="ep-checkbox-row">
|
||||
<mat-checkbox labelPosition="after" formControlName="isCashPayment">
|
||||
{{ 'labels.inputs.Is Cash Payment' | translate }}?
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ep-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../../']" class="ep-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!paymentTypeForm.valid"
|
||||
class="ep-actions__submit"
|
||||
*mifosxHasPermission="'UPDATE_PAYMENTTYPE'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+128
-5
@@ -6,10 +6,133 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
}
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.status {
|
||||
padding: 17.5px 0;
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.ep-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.ep-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ep-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.ep-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ep-section {
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ep-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.ep-field {
|
||||
width: 100% !important;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.ep-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.ep-actions {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50 !important;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,31 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_PAYMENTTYPE'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Payment Type' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-dollar-sign title-icon"></i>
|
||||
{{ 'labels.heading.Payment Type' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['create']" *mifosxHasPermission="'CREATE_PAYMENTTYPE'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create Payment Type' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8 table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let paymentType">{{ paymentType.name }}</td>
|
||||
@@ -41,48 +49,18 @@
|
||||
<ng-container matColumnDef="isSystemDefined">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.System Defined' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let paymentType">
|
||||
<div [className]="paymentType.isSystemDefined === true ? 'true text-center' : 'false text-center'">
|
||||
@if (paymentType.isSystemDefined) {
|
||||
<fa-icon
|
||||
icon="check-circle"
|
||||
size="lg"
|
||||
matTooltip="{{ 'tooltips.Yes' | translate }}"
|
||||
matTooltipPosition="right"
|
||||
></fa-icon>
|
||||
}
|
||||
@if (!paymentType.isSystemDefined) {
|
||||
<fa-icon
|
||||
icon="times-circle"
|
||||
size="lg"
|
||||
matTooltip="{{ 'tooltips.No' | translate }}"
|
||||
matTooltipPosition="right"
|
||||
></fa-icon>
|
||||
}
|
||||
</div>
|
||||
<span [class]="paymentType.isSystemDefined ? 'bool-badge bool-badge--yes' : 'bool-badge bool-badge--no'">
|
||||
{{ paymentType.isSystemDefined ? ('tooltips.Yes' | translate) : ('tooltips.No' | translate) }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="isCashPayment">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Cash Payment' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let paymentType">
|
||||
<div [className]="paymentType.isCashPayment === true ? 'true text-center' : 'false text-center'">
|
||||
@if (paymentType.isCashPayment) {
|
||||
<fa-icon
|
||||
icon="check-circle"
|
||||
size="lg"
|
||||
matTooltip="{{ 'tooltips.Yes' | translate }}"
|
||||
matTooltipPosition="right"
|
||||
></fa-icon>
|
||||
}
|
||||
@if (!paymentType.isCashPayment) {
|
||||
<fa-icon
|
||||
icon="times-circle"
|
||||
size="lg"
|
||||
matTooltip="{{ 'tooltips.No' | translate }}"
|
||||
matTooltipPosition="right"
|
||||
></fa-icon>
|
||||
}
|
||||
</div>
|
||||
<span [class]="paymentType.isCashPayment ? 'bool-badge bool-badge--yes' : 'bool-badge bool-badge--no'">
|
||||
{{ paymentType.isCashPayment ? ('tooltips.Yes' | translate) : ('tooltips.No' | translate) }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@@ -93,22 +71,22 @@
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let paymentType" class="layout-row">
|
||||
<td mat-cell *matCellDef="let paymentType" (click)="$event.stopPropagation()">
|
||||
@if (!paymentType.isSystemDefined) {
|
||||
<button mat-button [routerLink]="[paymentType.id, 'edit']" color="primary" class="no-wrap">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
}
|
||||
@if (!paymentType.isSystemDefined) {
|
||||
<button mat-button (click)="deletePaymentType(paymentType.id)" color="warn" class="no-wrap">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
<div class="action-links">
|
||||
<a class="cell-link" [routerLink]="[paymentType.id, 'edit']">
|
||||
<i class="fas fa-pen" style="margin-right: 4px; font-size: 11px;"></i>{{ 'labels.buttons.Edit' | translate }}
|
||||
</a>
|
||||
<a class="cell-link cell-link--danger" (click)="deletePaymentType(paymentType.id)">
|
||||
<i class="fas fa-trash-alt" style="margin-right: 4px; font-size: 11px;"></i>{{ 'labels.buttons.Delete' | translate }}
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
@@ -6,19 +6,53 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.table-container {
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
$primary: #1353a0;
|
||||
|
||||
.bool-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&--yes {
|
||||
background: #ecfdf5;
|
||||
color: #059669;
|
||||
|
||||
&::before { background: #059669; }
|
||||
}
|
||||
|
||||
&--no {
|
||||
background: #f1f5f9;
|
||||
color: #94a3b8;
|
||||
|
||||
&::before { background: #94a3b8; }
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
.action-links {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.true {
|
||||
color: #32cd32;
|
||||
}
|
||||
.cell-link--danger {
|
||||
color: #dc2626 !important;
|
||||
cursor: pointer;
|
||||
|
||||
.false {
|
||||
color: #f44366;
|
||||
&:hover { text-decoration: underline; }
|
||||
}
|
||||
|
||||
@@ -6,23 +6,34 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_SMSCAMPAIGN'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Create SMS Campaign' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<mat-card class="container">
|
||||
<!-- Header Bar -->
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-envelope"></i>
|
||||
{{ 'labels.heading.SMS Campaigns' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<input matInput placeholder="{{ 'labels.inputs.Filter' | translate }}" (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" [routerLink]="['create']" class="btn-create" *mifosxHasPermission="'CREATE_SMSCAMPAIGN'">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
{{ 'labels.buttons.Create SMS Campaign' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8 table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<!-- Table -->
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="campaignName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let smsCampaign">{{ smsCampaign.campaignName }}</td>
|
||||
@@ -63,9 +74,9 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="select-row" [routerLink]="[row.id]"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="[row.id]" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
+49
-50
@@ -6,89 +6,88 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container input">
|
||||
<div class="si-container">
|
||||
@if (!isCollapsed) {
|
||||
<mat-card>
|
||||
<div class="si-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="si-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Organization' | translate }}
|
||||
</button>
|
||||
<h2 class="si-header__title">{{ 'labels.heading.Standing Instructions History' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="si-card">
|
||||
<form [formGroup]="instructionForm" (ngSubmit)="search()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field>
|
||||
<div class="si-section">
|
||||
<div class="si-section__header">
|
||||
<i class="fas fa-search"></i>
|
||||
<h3>Search Parameters</h3>
|
||||
</div>
|
||||
<div class="si-grid">
|
||||
<mat-form-field appearance="outline" class="si-field">
|
||||
<mat-label>{{ 'labels.inputs.Client Name' | translate }}</mat-label>
|
||||
<input matInput formControlName="clientName" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="si-field">
|
||||
<mat-label>{{ 'labels.inputs.Client Id' | translate }}</mat-label>
|
||||
<input matInput formControlName="clientId" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="si-field">
|
||||
<mat-label>{{ 'labels.inputs.Transfer Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="transferType">
|
||||
@for (transferType of standingInstructionsTemplate.transferTypeOptions; track transferType) {
|
||||
<mat-option [value]="transferType.id">
|
||||
{{ transferType.value }}
|
||||
</mat-option>
|
||||
<mat-option [value]="transferType.id">{{ transferType.value }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="si-field">
|
||||
<mat-label>{{ 'labels.inputs.Account Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="fromAccountType">
|
||||
@for (accountType of standingInstructionsTemplate.fromAccountTypeOptions; track accountType) {
|
||||
<mat-option [value]="accountType.id">
|
||||
{{ accountType.value }}
|
||||
</mat-option>
|
||||
<mat-option [value]="accountType.id">{{ accountType.value }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
@if (instructionForm.contains('fromAccountId')) {
|
||||
<mat-form-field>
|
||||
<mat-form-field appearance="outline" class="si-field">
|
||||
<mat-label>{{ 'labels.inputs.From Account ID' | translate }}</mat-label>
|
||||
<input matInput formControlName="fromAccountId" />
|
||||
</mat-form-field>
|
||||
}
|
||||
<mat-form-field (click)="fromDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="si-field" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
formControlName="fromDate"
|
||||
[matDatepicker]="fromDatePicker"
|
||||
/>
|
||||
<input matInput [min]="minDate" [max]="maxDate" formControlName="fromDate" [matDatepicker]="fromDatePicker" />
|
||||
<mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #fromDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field (click)="toDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="si-field" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To Date' | translate }}</mat-label>
|
||||
<input matInput [min]="minDate" [max]="maxDate" formControlName="toDate" [matDatepicker]="toDatePicker" />
|
||||
<mat-datepicker-toggle matSuffix [for]="toDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #toDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" *mifosxHasPermission="'READ_STANDINGINSTRUCTION'">
|
||||
<fa-icon icon="search"></fa-icon>
|
||||
{{ 'labels.buttons.Search Instructions' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</form>
|
||||
</mat-card>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (isCollapsed) {
|
||||
<div class="container output">
|
||||
<mat-card>
|
||||
<div class="m-b-20">
|
||||
<button mat-raised-button color="primary" (click)="isCollapsed = false">
|
||||
{{ 'labels.buttons.Parameters' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<table class="mat-elevation-z1" mat-table [dataSource]="dataSource" matSort>
|
||||
<div class="si-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="si-actions__cancel">{{ 'labels.buttons.Cancel' | translate }}</button>
|
||||
<button type="submit" mat-flat-button color="primary" class="si-actions__submit" *mifosxHasPermission="'READ_STANDINGINSTRUCTION'">
|
||||
<i class="fas fa-search"></i> {{ 'labels.buttons.Search Instructions' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (isCollapsed) {
|
||||
<div class="si-header">
|
||||
<button mat-stroked-button (click)="isCollapsed = false" class="si-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.buttons.Parameters' | translate }}
|
||||
</button>
|
||||
<h2 class="si-header__title">{{ 'labels.heading.Standing Instructions History' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="fromClient">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.From Client' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">
|
||||
@@ -139,6 +138,6 @@
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</mat-card>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
+179
-3
@@ -6,11 +6,182 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.input {
|
||||
max-width: 37rem;
|
||||
@use '../../shared/styles/list-layout' as *;
|
||||
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.si-container {
|
||||
max-width: 860px;
|
||||
margin: 0 auto;
|
||||
padding: 28px 24px;
|
||||
}
|
||||
|
||||
.output {
|
||||
.si-header {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&__title {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 16px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.si-back {
|
||||
border: 1px solid $border !important;
|
||||
color: $gray-700 !important;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px !important;
|
||||
padding: 4px 14px !important;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
i {
|
||||
margin-right: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $gray-50 !important;
|
||||
border-color: $gray-500 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.si-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 12px;
|
||||
padding: 0;
|
||||
box-shadow: 0 1px 3px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
|
||||
}
|
||||
|
||||
.si-section {
|
||||
padding: 24px 28px;
|
||||
border-bottom: 1px solid $border;
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.si-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4px 20px;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.si-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.si-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 18px 28px;
|
||||
|
||||
&__cancel {
|
||||
border: 1px solid $border !important;
|
||||
color: $gray-700 !important;
|
||||
border-radius: 8px !important;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
padding: 4px 20px !important;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: $gray-50 !important;
|
||||
border-color: $gray-500 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&__submit {
|
||||
background: $primary !important;
|
||||
color: #fff !important;
|
||||
border-radius: 8px !important;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
padding: 4px 20px !important;
|
||||
box-shadow: 0 1px 2px rgba(19, 83, 160, 0.15);
|
||||
transition: all 0.2s ease;
|
||||
|
||||
i {
|
||||
margin-right: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #0f4688 !important;
|
||||
box-shadow: 0 2px 6px rgba(19, 83, 160, 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Results table
|
||||
.table-container {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
|
||||
}
|
||||
|
||||
.modern-table {
|
||||
width: 100%;
|
||||
|
||||
th.mat-header-cell {
|
||||
background: $gray-50;
|
||||
color: $gray-700;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.4px;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
td.mat-cell {
|
||||
color: $gray-900;
|
||||
font-size: 13px;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
tr.mat-row:hover {
|
||||
background: $gray-50;
|
||||
}
|
||||
|
||||
tr.mat-row:last-child td.mat-cell {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.error-log {
|
||||
min-width: 26px;
|
||||
padding: 0 6px;
|
||||
@@ -18,3 +189,8 @@
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .mat-mdc-paginator {
|
||||
border-top: 1px solid $border;
|
||||
background: $gray-50;
|
||||
}
|
||||
|
||||
@@ -6,32 +6,51 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="ac-container">
|
||||
<div class="ac-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ac-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Cashiers' | translate }}
|
||||
</button>
|
||||
<h2 class="ac-header__title">{{ 'labels.heading.Allocate Cash' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="ac-card">
|
||||
<form [formGroup]="allocateCashForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<div class="ac-section">
|
||||
<div class="ac-section__header">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<h3>{{ 'labels.heading.Cashier Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ac-grid">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<input matInput required formControlName="office" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Teller Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="tellerName" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Cashier' | translate }}</mat-label>
|
||||
<input matInput required formControlName="cashier" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Assignment Period' | translate }}</mat-label>
|
||||
<input matInput formControlName="assignmentPeriod" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="cashDatePicker.open()">
|
||||
<div class="ac-section">
|
||||
<div class="ac-section__header">
|
||||
<i class="fas fa-arrow-up"></i>
|
||||
<h3>{{ 'labels.heading.Allocate Cash' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ac-grid">
|
||||
<mat-form-field appearance="outline" class="ac-field" (click)="cashDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -51,7 +70,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
|
||||
<mat-select required formControlName="currencyCode">
|
||||
@for (currency of cashierData.currencyOptions; track currency) {
|
||||
@@ -68,7 +87,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Amount' | translate }}</mat-label>
|
||||
<input matInput required formControlName="txnAmount" />
|
||||
@if (allocateCashForm.controls.txnAmount.hasError('required')) {
|
||||
@@ -79,7 +98,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ac-field">
|
||||
<mat-label>{{ 'labels.inputs.Notes/Comments' | translate }}</mat-label>
|
||||
<input matInput required formControlName="txnNote" />
|
||||
@if (allocateCashForm.controls.txnNote.hasError('required')) {
|
||||
@@ -90,21 +109,23 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="ac-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ac-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!allocateCashForm.valid"
|
||||
class="ac-actions__submit"
|
||||
*mifosxHasPermission="'ALLOCATECASHIER_TELLER'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,3 +5,125 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.ac-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.ac-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ac-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.ac-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ac-section {
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ac-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.ac-field {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.ac-actions {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50 !important;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,28 +6,31 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container m-b-20 layout-row align-end gap-20px">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[routerLink]="['create']"
|
||||
*mifosxHasPermission="'CREATE_CASHIERS_FOR_TELLER'"
|
||||
>
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.New Cashier' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="layout-row gap-20px">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-user-tie title-icon"></i>
|
||||
{{ 'labels.heading.Cashiers' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="table-actions">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['create']" *mifosxHasPermission="'CREATE_CASHIERS_FOR_TELLER'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.New Cashier' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="period">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Period' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let cashier">
|
||||
@@ -46,46 +49,39 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="vaultActions">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Vault Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let cashier">
|
||||
<button
|
||||
class="cashier-action-button"
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
matTooltip="{{ 'tooltips.Allocate Cash' | translate }}"
|
||||
(click)="routeEdit($event)"
|
||||
[routerLink]="[cashier.id, 'allocate']"
|
||||
*mifosxHasPermission="'ALLOCATECASHIER_TELLER'"
|
||||
>
|
||||
<i class="fa fa-arrow-up"></i>
|
||||
</button>
|
||||
<button
|
||||
class="cashier-action-button"
|
||||
mat-raised-button
|
||||
color="warn"
|
||||
matTooltip="{{ 'tooltips.Settle Cash' | translate }}"
|
||||
(click)="routeEdit($event)"
|
||||
[routerLink]="[cashier.id, 'settle']"
|
||||
*mifosxHasPermission="'SETTLECASHIER_TELLER'"
|
||||
>
|
||||
<i class="fa fa-arrow-down"></i>
|
||||
</button>
|
||||
<button
|
||||
class="cashier-action-button"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
matTooltip="{{ 'tooltips.View Transactions' | translate }}"
|
||||
(click)="routeEdit($event)"
|
||||
[routerLink]="[cashier.id, 'transactions']"
|
||||
*mifosxHasPermission="'ALLOCATECASHIER_TELLER'"
|
||||
>
|
||||
<i class="fa fa-eye"></i>
|
||||
</button>
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Vault Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let cashier" (click)="$event.stopPropagation()">
|
||||
<div class="vault-actions">
|
||||
<a
|
||||
class="vault-btn vault-btn--allocate"
|
||||
matTooltip="{{ 'tooltips.Allocate Cash' | translate }}"
|
||||
[routerLink]="[cashier.id, 'allocate']"
|
||||
*mifosxHasPermission="'ALLOCATECASHIER_TELLER'"
|
||||
>
|
||||
<i class="fas fa-arrow-up"></i>
|
||||
</a>
|
||||
<a
|
||||
class="vault-btn vault-btn--settle"
|
||||
matTooltip="{{ 'tooltips.Settle Cash' | translate }}"
|
||||
[routerLink]="[cashier.id, 'settle']"
|
||||
*mifosxHasPermission="'SETTLECASHIER_TELLER'"
|
||||
>
|
||||
<i class="fas fa-arrow-down"></i>
|
||||
</a>
|
||||
<a
|
||||
class="vault-btn vault-btn--view"
|
||||
matTooltip="{{ 'tooltips.View Transactions' | translate }}"
|
||||
[routerLink]="[cashier.id, 'transactions']"
|
||||
*mifosxHasPermission="'ALLOCATECASHIER_TELLER'"
|
||||
>
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="select-row" [routerLink]="[row.id]"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row" [routerLink]="[row.id]"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
@@ -6,17 +6,47 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
@use '../../../shared/styles/list-layout' as *;
|
||||
|
||||
.cashier-action-button {
|
||||
min-width: 26px;
|
||||
padding: 0 6px;
|
||||
margin: 4px;
|
||||
line-height: 25px;
|
||||
$primary: #1353a0;
|
||||
|
||||
.vault-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.vault-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.15s, transform 0.15s;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.select-row:hover {
|
||||
cursor: pointer;
|
||||
&--allocate {
|
||||
background: #ecfdf5;
|
||||
color: #059669;
|
||||
border: 1px solid #a7f3d0;
|
||||
}
|
||||
|
||||
&--settle {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
border: 1px solid #fecaca;
|
||||
}
|
||||
|
||||
&--view {
|
||||
background: #eff6ff;
|
||||
color: $primary;
|
||||
border: 1px solid #bfdbfe;
|
||||
}
|
||||
}
|
||||
|
||||
+54
-41
@@ -6,22 +6,33 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="cc-container">
|
||||
<div class="cc-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="cc-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Cashiers' | translate }}
|
||||
</button>
|
||||
<h2 class="cc-header__title">{{ 'labels.heading.Create Cashier' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="cc-card">
|
||||
<form [formGroup]="createCashierForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<div class="cc-section">
|
||||
<div class="cc-section__header">
|
||||
<i class="fas fa-user-tie"></i>
|
||||
<h3>{{ 'labels.heading.Cashier Assignment' | translate }}</h3>
|
||||
</div>
|
||||
<div class="cc-grid">
|
||||
<mat-form-field appearance="outline" class="cc-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<input matInput required autofocus [value]="cashierTemplate.officeName" disabled />
|
||||
<input matInput required [value]="cashierTemplate.officeName" disabled />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="cc-field">
|
||||
<mat-label>{{ 'labels.inputs.Teller Name' | translate }}</mat-label>
|
||||
<input matInput required autofocus [value]="cashierTemplate.tellerName" disabled />
|
||||
<input matInput required [value]="cashierTemplate.tellerName" disabled />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="cc-field">
|
||||
<mat-label>{{ 'labels.inputs.Cashier' | translate }}</mat-label>
|
||||
<mat-select formControlName="staffId">
|
||||
@for (staff of cashierTemplate.staffOptions; track staff) {
|
||||
@@ -38,12 +49,20 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="cc-field">
|
||||
<mat-label>{{ 'labels.inputs.Description/Notes' | translate }}</mat-label>
|
||||
<input matInput autofocus formControlName="description" />
|
||||
<input matInput formControlName="description" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="fromDatePicker.open()">
|
||||
<div class="cc-section">
|
||||
<div class="cc-section__header">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
<h3>{{ 'labels.heading.Schedule' | translate }}</h3>
|
||||
</div>
|
||||
<div class="cc-grid">
|
||||
<mat-form-field appearance="outline" class="cc-field" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -63,7 +82,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="toDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="cc-field" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -84,21 +103,17 @@
|
||||
</mat-form-field>
|
||||
|
||||
@if (!createCashierForm.value.isFullDay) {
|
||||
<div class="flex-48 layout-row gap-10px">
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label
|
||||
>
|
||||
<div class="cc-time-row">
|
||||
<mat-form-field appearance="outline" class="cc-time-field">
|
||||
<mat-label>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label>
|
||||
<mat-select formControlName="hourStartTime">
|
||||
@for (hour of hours; track hour) {
|
||||
<mat-option [value]="hour">{{ hour }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label
|
||||
>
|
||||
<mat-form-field appearance="outline" class="cc-time-field">
|
||||
<mat-label>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label>
|
||||
<mat-select formControlName="minStartTime">
|
||||
@for (minute of minutes; track minute) {
|
||||
<mat-option [value]="minute">{{ minute }}</mat-option>
|
||||
@@ -106,21 +121,17 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="flex-48 layout-row gap-10px">
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label
|
||||
>
|
||||
<div class="cc-time-row">
|
||||
<mat-form-field appearance="outline" class="cc-time-field">
|
||||
<mat-label>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label>
|
||||
<mat-select formControlName="hourEndTime">
|
||||
@for (hour of hours; track hour) {
|
||||
<mat-option [value]="hour">{{ hour }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label
|
||||
>
|
||||
<mat-form-field appearance="outline" class="cc-time-field">
|
||||
<mat-label>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label>
|
||||
<mat-select formControlName="minEndTime">
|
||||
@for (minute of minutes; track minute) {
|
||||
<mat-option [value]="minute">{{ minute }}</mat-option>
|
||||
@@ -129,7 +140,7 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@if (createCashierForm.hasError('invalidTimeRange')) {
|
||||
<div class="flex-48">
|
||||
<div class="cc-field--full">
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.End Time' | translate }} {{ 'labels.commons.must' | translate }}
|
||||
{{ 'labels.commons.be' | translate }} {{ 'labels.commons.greater than' | translate }}
|
||||
@@ -139,27 +150,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
<div class="space flex-100">
|
||||
<mat-checkbox labelPosition="before" formControlName="isFullDay">
|
||||
<div class="cc-checkbox-row">
|
||||
<mat-checkbox labelPosition="after" formControlName="isFullDay">
|
||||
{{ 'labels.inputs.Full Day' | translate }}?
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="cc-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="cc-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!createCashierForm.valid"
|
||||
class="cc-actions__submit"
|
||||
*mifosxHasPermission="'UPDATECASHIERALLOCATION_TELLER'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+145
-2
@@ -6,6 +6,149 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.space {
|
||||
padding-top: 10px;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.cc-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.cc-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cc-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.cc-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cc-section {
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cc-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.cc-field {
|
||||
width: 100% !important;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.cc-time-row {
|
||||
display: flex !important;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: 600px) { flex-direction: column; gap: 4px; }
|
||||
}
|
||||
|
||||
.cc-time-field {
|
||||
flex: 1;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.cc-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.cc-actions {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50 !important;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,34 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="ec-container">
|
||||
<div class="ec-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="ec-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Cashiers' | translate }}
|
||||
</button>
|
||||
<h2 class="ec-header__title">{{ 'labels.heading.Edit Cashier' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="ec-card">
|
||||
<form [formGroup]="editCashierForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<div class="ec-section">
|
||||
<div class="ec-section__header">
|
||||
<i class="fas fa-user-tie"></i>
|
||||
<h3>{{ 'labels.heading.Cashier Assignment' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ec-grid">
|
||||
<mat-form-field appearance="outline" class="ec-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<input matInput required autofocus [value]="cashierData.template.officeName" disabled />
|
||||
<input matInput required [value]="cashierData.template.officeName" disabled />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ec-field">
|
||||
<mat-label>{{ 'labels.inputs.Teller Name' | translate }}</mat-label>
|
||||
<input matInput required autofocus [value]="cashierData.data.tellerName" disabled />
|
||||
<input matInput required [value]="cashierData.data.tellerName" disabled />
|
||||
</mat-form-field>
|
||||
|
||||
@if (isStaffId) {
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ec-field">
|
||||
<mat-label>{{ 'labels.inputs.Cashier' | translate }}</mat-label>
|
||||
<mat-select formControlName="staffId">
|
||||
@for (staff of cashierData.template.staffOptions; track staff) {
|
||||
@@ -35,24 +46,30 @@
|
||||
}
|
||||
|
||||
@if (!isStaffId) {
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ec-field">
|
||||
<mat-label>{{ 'labels.inputs.Cashier' | translate }}</mat-label>
|
||||
@if (!isStaffId) {
|
||||
<mat-select formControlName="staffId">
|
||||
<mat-option [value]="cashierData.data.staffId">
|
||||
{{ 'labels.inputs.Select Option' | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
}
|
||||
<mat-select formControlName="staffId">
|
||||
<mat-option [value]="cashierData.data.staffId">
|
||||
{{ 'labels.inputs.Select Option' | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="ec-field">
|
||||
<mat-label>{{ 'labels.inputs.Description/Notes' | translate }}</mat-label>
|
||||
<input matInput autofocus formControlName="description" />
|
||||
<input matInput formControlName="description" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="fromDatePicker.open()">
|
||||
<div class="ec-section">
|
||||
<div class="ec-section__header">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
<h3>{{ 'labels.heading.Schedule' | translate }}</h3>
|
||||
</div>
|
||||
<div class="ec-grid">
|
||||
<mat-form-field appearance="outline" class="ec-field" (click)="fromDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.From' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -72,7 +89,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="toDatePicker.open()">
|
||||
<mat-form-field appearance="outline" class="ec-field" (click)="toDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.To' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -93,21 +110,17 @@
|
||||
</mat-form-field>
|
||||
|
||||
@if (!editCashierForm.value.isFullDay) {
|
||||
<div class="flex-48 layout-row gap-10px">
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label
|
||||
>
|
||||
<div class="ec-time-row">
|
||||
<mat-form-field appearance="outline" class="ec-time-field">
|
||||
<mat-label>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label>
|
||||
<mat-select formControlName="hourStartTime">
|
||||
@for (hour of hours; track hour) {
|
||||
<mat-option [value]="hour">{{ hour }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label
|
||||
>
|
||||
<mat-form-field appearance="outline" class="ec-time-field">
|
||||
<mat-label>{{ 'labels.inputs.Start Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label>
|
||||
<mat-select formControlName="minStartTime">
|
||||
@for (minute of minutes; track minute) {
|
||||
<mat-option [value]="minute">{{ minute }}</mat-option>
|
||||
@@ -115,21 +128,17 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="flex-48 layout-row gap-10px">
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label
|
||||
>
|
||||
<div class="ec-time-row">
|
||||
<mat-form-field appearance="outline" class="ec-time-field">
|
||||
<mat-label>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Hour' | translate }})</mat-label>
|
||||
<mat-select formControlName="hourEndTime">
|
||||
@for (hour of hours; track hour) {
|
||||
<mat-option [value]="hour">{{ hour }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-50">
|
||||
<mat-label
|
||||
>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label
|
||||
>
|
||||
<mat-form-field appearance="outline" class="ec-time-field">
|
||||
<mat-label>{{ 'labels.inputs.End Time' | translate }} ({{ 'labels.inputs.Minute' | translate }})</mat-label>
|
||||
<mat-select formControlName="minEndTime">
|
||||
@for (minute of minutes; track minute) {
|
||||
<mat-option [value]="minute">{{ minute }}</mat-option>
|
||||
@@ -138,7 +147,7 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@if (editCashierForm.hasError('invalidTimeRange')) {
|
||||
<div class="flex-48">
|
||||
<div class="ec-field--full">
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.End Time' | translate }} {{ 'labels.commons.must' | translate }}
|
||||
{{ 'labels.commons.be' | translate }} {{ 'labels.commons.greater than' | translate }}
|
||||
@@ -148,27 +157,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
<div class="space flex-100">
|
||||
<mat-checkbox labelPosition="before" formControlName="isFullDay">
|
||||
<div class="ec-checkbox-row">
|
||||
<mat-checkbox labelPosition="after" formControlName="isFullDay">
|
||||
{{ 'labels.inputs.Full Day' | translate }}?
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="ec-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="ec-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!editCashierForm.valid"
|
||||
class="ec-actions__submit"
|
||||
*mifosxHasPermission="'UPDATECASHIERALLOCATION_TELLER'"
|
||||
>
|
||||
{{ 'labels.buttons.Submit' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Submit' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,149 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.space {
|
||||
padding-top: 10px;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.ec-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.ec-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ec-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.ec-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ec-section {
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ec-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.ec-field {
|
||||
width: 100% !important;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.ec-time-row {
|
||||
display: flex !important;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: 600px) { flex-direction: column; gap: 4px; }
|
||||
}
|
||||
|
||||
.ec-time-field {
|
||||
flex: 1;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.ec-checkbox-row {
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
|
||||
::ng-deep .mat-mdc-checkbox {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.ec-actions {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50 !important;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,32 +6,51 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<div class="sc-container">
|
||||
<div class="sc-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="sc-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Cashiers' | translate }}
|
||||
</button>
|
||||
<h2 class="sc-header__title">{{ 'labels.heading.Settle Cash' | translate }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="sc-card">
|
||||
<form [formGroup]="settleCashForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<div class="sc-section">
|
||||
<div class="sc-section__header">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<h3>{{ 'labels.heading.Cashier Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="sc-grid">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
|
||||
<input matInput required formControlName="office" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Teller Name' | translate }}</mat-label>
|
||||
<input matInput required formControlName="tellerName" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Cashier' | translate }}</mat-label>
|
||||
<input matInput required formControlName="cashier" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Assignment Period' | translate }}</mat-label>
|
||||
<input matInput formControlName="assignmentPeriod" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="cashDatePicker.open()">
|
||||
<div class="sc-section">
|
||||
<div class="sc-section__header">
|
||||
<i class="fas fa-arrow-down"></i>
|
||||
<h3>{{ 'labels.heading.Settle Cash' | translate }}</h3>
|
||||
</div>
|
||||
<div class="sc-grid">
|
||||
<mat-form-field appearance="outline" class="sc-field" (click)="cashDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -51,7 +70,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
|
||||
<mat-select required formControlName="currencyCode">
|
||||
@for (currency of cashierData.currencyOptions; track currency) {
|
||||
@@ -68,7 +87,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Amount' | translate }}</mat-label>
|
||||
<input matInput required formControlName="txnAmount" />
|
||||
@if (settleCashForm.controls.txnAmount.hasError('required')) {
|
||||
@@ -79,7 +98,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-form-field appearance="outline" class="sc-field">
|
||||
<mat-label>{{ 'labels.inputs.Notes/Comments' | translate }}</mat-label>
|
||||
<input matInput required formControlName="txnNote" />
|
||||
@if (settleCashForm.controls.txnNote.hasError('required')) {
|
||||
@@ -90,21 +109,23 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">
|
||||
<div class="sc-actions">
|
||||
<button type="button" mat-stroked-button [routerLink]="['../']" class="sc-actions__cancel">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
type="submit"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!settleCashForm.valid"
|
||||
class="sc-actions__submit"
|
||||
*mifosxHasPermission="'SETTLECASHFROMCASHIER_TELLER'"
|
||||
>
|
||||
{{ 'labels.buttons.Settle Cash' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'labels.buttons.Settle Cash' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,3 +5,125 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.sc-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.sc-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sc-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.sc-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sc-section {
|
||||
& + & {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sc-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.sc-field {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.sc-actions {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 10px;
|
||||
padding: 14px 24px;
|
||||
border-top: 1px solid $gray-200;
|
||||
background: $gray-50 !important;
|
||||
|
||||
&__cancel {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
border-radius: 8px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,128 +6,115 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="layout-row gap-1percent layout-align-end container m-b-20">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[routerLink]="['../allocate']"
|
||||
*mifosxHasPermission="'ALLOCATECASHIER_TELLER'"
|
||||
>
|
||||
<fa-icon icon="arrow-up" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Allocate Cash' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="warn"
|
||||
[routerLink]="['../settle']"
|
||||
*mifosxHasPermission="'SETTLECASHFROMCASHIER_TELLER'"
|
||||
>
|
||||
<fa-icon icon="arrow-down" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Settle Cash' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (cashierData) {
|
||||
<div class="container m-b-20">
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap">
|
||||
<div class="flex-25 header">
|
||||
{{ 'labels.inputs.Branch' | translate }}
|
||||
</div>
|
||||
<div class="flex-25">
|
||||
{{ cashierData.officeName }}
|
||||
</div>
|
||||
<div class="flex-25 header">
|
||||
{{ 'labels.inputs.Teller' | translate }}
|
||||
</div>
|
||||
<div class="flex-25">
|
||||
{{ cashierData.tellerName }}
|
||||
</div>
|
||||
<div class="flex-25 header">
|
||||
{{ 'labels.inputs.Cashier' | translate }}
|
||||
</div>
|
||||
<div class="flex-25">
|
||||
{{ cashierData.cashierName }}
|
||||
</div>
|
||||
<div class="flex-25 header">
|
||||
{{ 'labels.inputs.Net Cash' | translate }}
|
||||
</div>
|
||||
<div class="flex-25">{{ cashierData.netCash | formatNumber }} [{{ currencySelector.value }}]</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="container">
|
||||
<mat-card class="layout-column gap-2percent mat-elevation-z8">
|
||||
<div class="layout-row gap-2percent">
|
||||
<mat-form-field class="flex-fill">
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label> {{ 'labels.inputs.Select Currency' | translate }} </mat-label>
|
||||
<mat-select [formControl]="currencySelector" required>
|
||||
@for (currency of currencyData; track currency) {
|
||||
<mat-option [value]="currency.code">
|
||||
{{ currency.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="table-header">
|
||||
<div class="table-title-group">
|
||||
<h2 class="table-title">
|
||||
<i class="fas fa-exchange-alt title-icon"></i>
|
||||
{{ 'labels.heading.Cash Transactions' | translate }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@if (cashierData) {
|
||||
<div>
|
||||
<table class="mat-elevation-z1" mat-table [dataSource]="dataSource" matSort>
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let transaction">{{ transaction.txnDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="transactions">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Transactions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let transaction">{{ transaction.txnType.value }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="allocation">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Allocation' | translate }} ({{ cashierData.sumCashAllocation | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Allocate Cash' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="cashIn">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Cash In' | translate }} ({{ cashierData.sumInwardCash | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Cash In' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="cashOut">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Cash Out' | translate }} ({{ cashierData.sumOutwardCash | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Cash Out' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="settlement">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Settlement' | translate }} ({{ cashierData.sumCashSettlement | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Settle Cash' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
<div class="table-actions">
|
||||
<div class="table-buttons">
|
||||
<button mat-flat-button color="primary" class="btn-create" [routerLink]="['../allocate']" *mifosxHasPermission="'ALLOCATECASHIER_TELLER'">
|
||||
<fa-icon icon="arrow-up" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Allocate Cash' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="btn-import" [routerLink]="['../settle']" *mifosxHasPermission="'SETTLECASHFROMCASHIER_TELLER'">
|
||||
<fa-icon icon="arrow-down" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Settle Cash' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (cashierData) {
|
||||
<div class="txn-summary">
|
||||
<div class="txn-summary__item">
|
||||
<span class="txn-summary__label">{{ 'labels.inputs.Branch' | translate }}</span>
|
||||
<span class="txn-summary__value">{{ cashierData.officeName }}</span>
|
||||
</div>
|
||||
<div class="txn-summary__item">
|
||||
<span class="txn-summary__label">{{ 'labels.inputs.Teller' | translate }}</span>
|
||||
<span class="txn-summary__value">{{ cashierData.tellerName }}</span>
|
||||
</div>
|
||||
<div class="txn-summary__item">
|
||||
<span class="txn-summary__label">{{ 'labels.inputs.Cashier' | translate }}</span>
|
||||
<span class="txn-summary__value">{{ cashierData.cashierName }}</span>
|
||||
</div>
|
||||
<div class="txn-summary__item">
|
||||
<span class="txn-summary__label">{{ 'labels.inputs.Net Cash' | translate }}</span>
|
||||
<span class="txn-summary__value txn-summary__value--highlight">{{ cashierData.netCash | formatNumber }} [{{ currencySelector.value }}]</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="table-actions" style="margin-bottom: 12px;">
|
||||
<mat-form-field class="table-search" appearance="outline">
|
||||
<i matPrefix class="fas fa-search"></i>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="table-search" style="max-width: 220px;">
|
||||
<mat-label>{{ 'labels.inputs.Select Currency' | translate }}</mat-label>
|
||||
<mat-select [formControl]="currencySelector" required>
|
||||
@for (currency of currencyData; track currency) {
|
||||
<mat-option [value]="currency.code">
|
||||
{{ currency.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
@if (cashierData) {
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" matSort class="modern-table">
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let transaction">{{ transaction.txnDate | dateFormat }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="transactions">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Transactions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let transaction">{{ transaction.txnType.value }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="allocation">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Allocation' | translate }} ({{ cashierData.sumCashAllocation | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Allocate Cash' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="cashIn">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Cash In' | translate }} ({{ cashierData.sumInwardCash | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Cash In' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="cashOut">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Cash Out' | translate }} ({{ cashierData.sumOutwardCash | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Cash Out' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="settlement">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||
{{ 'labels.inputs.Settlement' | translate }} ({{ cashierData.sumCashSettlement | formatNumber }})
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let transaction">
|
||||
{{ transaction.txnType.value === 'Settle Cash' ? (transaction.txnAmount | formatNumber) : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -6,16 +6,53 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.content {
|
||||
div {
|
||||
line-height: 3rem;
|
||||
@use '../../../../shared/styles/list-layout' as *;
|
||||
|
||||
&.header {
|
||||
font-weight: 500;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.txn-summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
padding: 16px 20px;
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: $gray-500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: $gray-900;
|
||||
|
||||
&--highlight {
|
||||
color: $primary;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -6,79 +6,55 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="layout-row align-end gap-2px responsive-column container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_CASHIER'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="warn" (click)="deleteCashier()" *mifosxHasPermission="'DELETECASHIER_TELLER'">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="vc-container">
|
||||
<div class="vc-header">
|
||||
<button mat-stroked-button [routerLink]="['..']" class="vc-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Cashiers' | translate }}
|
||||
</button>
|
||||
<h2 class="vc-header__title">{{ cashierData.staffName }}</h2>
|
||||
<div class="vc-header__spacer"></div>
|
||||
<button mat-flat-button color="primary" [routerLink]="['edit']" class="vc-header__action" *mifosxHasPermission="'UPDATE_CASHIER'">
|
||||
<i class="fas fa-pen"></i> {{ 'labels.buttons.Edit' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button color="warn" (click)="deleteCashier()" class="vc-header__delete" *mifosxHasPermission="'DELETECASHIER_TELLER'">
|
||||
<i class="fas fa-trash-alt"></i> {{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<div class="layout-row-wrap">
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Name' | translate }}
|
||||
<div class="vc-card">
|
||||
<div class="vc-section">
|
||||
<div class="vc-section__header">
|
||||
<i class="fas fa-user-tie"></i>
|
||||
<h3>{{ 'labels.heading.Cashier Details' | translate }}</h3>
|
||||
</div>
|
||||
<div class="vc-details">
|
||||
<div class="vc-detail">
|
||||
<span class="vc-detail__label">{{ 'labels.inputs.Name' | translate }}</span>
|
||||
<span class="vc-detail__value">{{ cashierData.staffName }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ cashierData.staffName }}
|
||||
<div class="vc-detail">
|
||||
<span class="vc-detail__label">{{ 'labels.inputs.Teller' | translate }}</span>
|
||||
<span class="vc-detail__value">{{ cashierData.tellerName }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Teller' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ cashierData.tellerName }}
|
||||
</div>
|
||||
|
||||
@if (cashierData.description !== '') {
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Description' | translate }}
|
||||
<div class="vc-detail vc-detail--full">
|
||||
<span class="vc-detail__label">{{ 'labels.inputs.Description' | translate }}</span>
|
||||
<span class="vc-detail__value">{{ cashierData.description }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (cashierData.description !== '') {
|
||||
<div class="flex-50">
|
||||
{{ cashierData.description }}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Start Date' | translate }}
|
||||
<div class="vc-detail">
|
||||
<span class="vc-detail__label">{{ 'labels.inputs.Start Date' | translate }}</span>
|
||||
<span class="vc-detail__value">{{ cashierData.startDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ cashierData.startDate | dateFormat }}
|
||||
<div class="vc-detail">
|
||||
<span class="vc-detail__label">{{ 'labels.inputs.End Date' | translate }}</span>
|
||||
<span class="vc-detail__value">{{ cashierData.endDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.End Date' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ cashierData.endDate | dateFormat }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 header">
|
||||
{{ 'labels.inputs.Full Day/Time' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ cashierData.isFullDay }}
|
||||
<div class="vc-detail">
|
||||
<span class="vc-detail__label">{{ 'labels.inputs.Full Day/Time' | translate }}</span>
|
||||
<span class="vc-detail__value">{{ cashierData.isFullDay | yesNo }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
|
||||
<button type="button" color="primary" mat-raised-button [routerLink]="['..']">
|
||||
{{ 'labels.buttons.Back' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,17 +6,136 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
$primary: #1353a0;
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-500: #9aa0a6;
|
||||
$gray-700: #5f6368;
|
||||
$gray-900: #202124;
|
||||
|
||||
.content {
|
||||
div {
|
||||
margin: 1rem 0;
|
||||
word-wrap: break-word;
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
&.header {
|
||||
font-weight: 500;
|
||||
.vc-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.vc-header {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__action {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
box-shadow: 0 1px 3px rgba($primary, 0.3) !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
|
||||
&__delete {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
|
||||
i { margin-right: 6px; font-size: 12px; }
|
||||
}
|
||||
}
|
||||
|
||||
.vc-back {
|
||||
border-radius: 8px !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
height: 32px !important;
|
||||
border-color: $border !important;
|
||||
color: $gray-500 !important;
|
||||
|
||||
i { margin-right: 6px; }
|
||||
|
||||
&:hover { color: $primary !important; border-color: $primary !important; }
|
||||
}
|
||||
|
||||
.vc-card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vc-section {
|
||||
&__header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50 !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vc-details {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
gap: 16px;
|
||||
padding: 20px 24px;
|
||||
|
||||
@media (max-width: 600px) { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
|
||||
.vc-detail {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
gap: 4px;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: $gray-500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
&__value {
|
||||
font-size: 14px;
|
||||
color: $gray-900;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user