merge angular-17 into dev to upgrade from Angular v16 to v17
This commit is contained in:
@@ -4,9 +4,9 @@ name: build-run
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events for specific branches
|
||||
push:
|
||||
branches: [main, dev, angular-update]
|
||||
branches: [main, dev, angular-update-17-2]
|
||||
pull_request:
|
||||
branches: [main, dev, angular-update]
|
||||
branches: [main, dev, angular-update-17-2]
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
@@ -40,6 +40,9 @@ jobs:
|
||||
- name: Run prettier
|
||||
run: npx prettier . --check
|
||||
|
||||
- name: HTMLHint
|
||||
run: npx htmlhint "src" --config .htmlhintrc
|
||||
|
||||
- name: Run build
|
||||
run: npm run build:prod
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev, angular-update]
|
||||
branches: [main, dev, angular-update-17-2]
|
||||
pull_request:
|
||||
branches: [main, dev, angular-update]
|
||||
branches: [main, dev, angular-update-17-2]
|
||||
|
||||
jobs:
|
||||
testRigor:
|
||||
|
||||
+4
-4
@@ -93,14 +93,14 @@
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "mifosx-web-app:build"
|
||||
"buildTarget": "mifosx-web-app:build"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"browserTarget": "mifosx-web-app:build:development"
|
||||
"buildTarget": "mifosx-web-app:build:development"
|
||||
},
|
||||
"production": {
|
||||
"browserTarget": "mifosx-web-app:build:production"
|
||||
"buildTarget": "mifosx-web-app:build:production"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
@@ -108,7 +108,7 @@
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "mifosx-web-app:build"
|
||||
"buildTarget": "mifosx-web-app:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
|
||||
Generated
+3982
-4330
File diff suppressed because it is too large
Load Diff
+33
-27
@@ -29,22 +29,21 @@
|
||||
"cypress:run": "cypress run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular-devkit/schematics": "16.2.16",
|
||||
"@angular-material-components/datetime-picker": "^16.0.1",
|
||||
"@angular/animations": "16.2.12",
|
||||
"@angular/cdk": "^16.2.14",
|
||||
"@angular/common": "16.2.12",
|
||||
"@angular/compiler": "16.2.12",
|
||||
"@angular/core": "16.2.12",
|
||||
"@angular/forms": "16.2.12",
|
||||
"@angular/localize": "16.2.12",
|
||||
"@angular/material": "^16.2.14",
|
||||
"@angular/platform-browser": "16.2.12",
|
||||
"@angular/platform-browser-dynamic": "16.2.12",
|
||||
"@angular/router": "16.2.12",
|
||||
"@angular-devkit/schematics": "17.3.17",
|
||||
"@angular/animations": "17.3.12",
|
||||
"@angular/cdk": "^17.3.10",
|
||||
"@angular/common": "17.3.12",
|
||||
"@angular/compiler": "17.3.12",
|
||||
"@angular/core": "17.3.12",
|
||||
"@angular/forms": "17.3.12",
|
||||
"@angular/localize": "17.3.12",
|
||||
"@angular/material": "^17.3.10",
|
||||
"@angular/platform-browser": "17.3.12",
|
||||
"@angular/platform-browser-dynamic": "17.3.12",
|
||||
"@angular/router": "17.3.12",
|
||||
"@ckeditor/ckeditor5-angular": "6.0.1",
|
||||
"@ckeditor/ckeditor5-build-classic": "40.2.0",
|
||||
"@fortawesome/angular-fontawesome": "^0.13.0",
|
||||
"@fortawesome/angular-fontawesome": "0.14.1",
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@fortawesome/fontawesome-svg-core": "6.2.1",
|
||||
"@fortawesome/free-brands-svg-icons": "6.7.2",
|
||||
@@ -55,6 +54,7 @@
|
||||
"@tailwindcss/forms": "^0.5.4",
|
||||
"chart.js": "3.0.0-alpha",
|
||||
"d3": "^7.9.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jspdf": "^3.0.1",
|
||||
"jspdf-autotable": "^5.0.2",
|
||||
@@ -65,25 +65,25 @@
|
||||
"tslib": "^2.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xlsx": "^0.18.5",
|
||||
"zone.js": "0.13.3"
|
||||
"zone.js": "0.14.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^16.2.16",
|
||||
"@angular-eslint/builder": "^19.3.0",
|
||||
"@angular-eslint/eslint-plugin": "^19.3.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^19.3.0",
|
||||
"@angular-eslint/schematics": "19.3.0",
|
||||
"@angular-eslint/template-parser": "^19.3.0",
|
||||
"@angular/cli": "16.2.16",
|
||||
"@angular/compiler-cli": "16.2.12",
|
||||
"@angular/language-service": "16.2.12",
|
||||
"@biesbjerg/ngx-translate-extract": "^7.0.4",
|
||||
"@angular-devkit/build-angular": "^17.3.17",
|
||||
"@angular-eslint/builder": "^19.7.0",
|
||||
"@angular-eslint/eslint-plugin": "^19.7.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^19.7.0",
|
||||
"@angular-eslint/schematics": "^19.7.0",
|
||||
"@angular-eslint/template-parser": "^19.7.0",
|
||||
"@angular/cli": "17.3.17",
|
||||
"@angular/compiler-cli": "17.3.12",
|
||||
"@angular/language-service": "17.3.12",
|
||||
"@vendure/ngx-translate-extract": "^9.4.0",
|
||||
"@cypress/schematic": "^2.5.2",
|
||||
"@types/d3-dispatch": "^3.0.1",
|
||||
"@types/d3-drag": "^3.0.1",
|
||||
"@types/d3-scale": "^3.2.2",
|
||||
"@types/d3-shape": "^3.1.0",
|
||||
"@types/d3-timer": "^3.0.0",
|
||||
"@types/d3-scale": "^3.2.2",
|
||||
"@types/jasmine": "3.3.13",
|
||||
"@types/jasminewd2": "2.0.6",
|
||||
"@types/lodash": "4.14.132",
|
||||
@@ -118,7 +118,7 @@
|
||||
"stylelint-scss": "^6.8.1",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"ts-node": "8.2.0",
|
||||
"typescript": "~4.9.5"
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -135,5 +135,11 @@
|
||||
"*.{js,jsx,ts,tsx}": "eslint --cache",
|
||||
"*.{css,scss}": "stylelint",
|
||||
"*": "prettier --check --ignore-unknown"
|
||||
},
|
||||
"overrides": {
|
||||
"exceljs": {
|
||||
"archiver": "^7.0.1",
|
||||
"unzipper": "^0.12.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ export class CreateStandingInstructionsComponent implements OnInit {
|
||||
/** Refine Object
|
||||
* Removes the object param with null or '' values
|
||||
*/
|
||||
refineObject(dataObj: Object) {
|
||||
refineObject(dataObj: { [key: string]: any }) {
|
||||
const propNames = Object.getOwnPropertyNames(dataObj);
|
||||
for (let i = 0; i < propNames.length; i++) {
|
||||
const propName = propNames[i];
|
||||
|
||||
@@ -43,6 +43,9 @@ export class CenterActionsComponent {
|
||||
) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
const name = this.route.snapshot.params['action'];
|
||||
this.actions[name] = true;
|
||||
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ export class ClientActionsComponent {
|
||||
'Accept Transfer': boolean;
|
||||
'Reject Transfer': boolean;
|
||||
Reactivate: boolean;
|
||||
Activate: boolean;
|
||||
'Undo Rejection': boolean;
|
||||
'Add Charge': boolean;
|
||||
'Take Survey': boolean;
|
||||
@@ -41,6 +42,7 @@ export class ClientActionsComponent {
|
||||
'Accept Transfer': false,
|
||||
'Reject Transfer': false,
|
||||
Reactivate: false,
|
||||
Activate: false,
|
||||
'Undo Rejection': false,
|
||||
'Add Charge': false,
|
||||
'Take Survey': false,
|
||||
@@ -57,7 +59,7 @@ export class ClientActionsComponent {
|
||||
private router: Router
|
||||
) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
const name = this.route.snapshot.params['name'];
|
||||
const name = this.route.snapshot.params['name'] as keyof typeof this.actions;
|
||||
this.actions[name] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export class TakeSurveyComponent {
|
||||
|
||||
// TODO: document the function
|
||||
groupBy(array: any, func: any) {
|
||||
const groups = {};
|
||||
const groups: { [key: string]: any[] } = {};
|
||||
array.forEach((ele: any) => {
|
||||
const group = JSON.stringify(func(ele));
|
||||
groups[group] = groups[group] || [];
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox formControlName="isDependent" labelPosition="before" class="flex-50-minus-25px">
|
||||
>{{ 'labels.inputs.Is Dependent' | translate }}?
|
||||
{{ 'labels.inputs.Is Dependent' | translate }}?
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field class="flex-50-minus-25px">
|
||||
|
||||
+25
-3
@@ -52,7 +52,10 @@ export class IndividualCollectionSheetComponent implements OnInit {
|
||||
/** checks and stores the local storage values */
|
||||
Success: boolean;
|
||||
/** Bulk Disbursement Transactions Data */
|
||||
bulkDisbursementTransactionsData = {};
|
||||
bulkDisbursementTransactionsData: {
|
||||
bulkRepaymentTransactions?: any[];
|
||||
bulkSavingsDueTransactions?: any[];
|
||||
} = {};
|
||||
/** Bulk Repayment Transactions Data */
|
||||
bulkRepaymentTransactions: any[] = [];
|
||||
/** Bulk Savings Due Data */
|
||||
@@ -261,7 +264,16 @@ export class IndividualCollectionSheetComponent implements OnInit {
|
||||
if (response.data) {
|
||||
if (type === 'loans') {
|
||||
const totalDue = this.getLoanTotalDueAmount(selectedData);
|
||||
const loanTransaction = {
|
||||
const loanTransaction: {
|
||||
loanId: any;
|
||||
transactionAmount: number;
|
||||
paymentTypeId?: string;
|
||||
accountNumber?: any;
|
||||
checkNumber?: number;
|
||||
routingCode?: string;
|
||||
receiptNumber?: number;
|
||||
bankNumber?: number;
|
||||
} = {
|
||||
loanId: selectedData.loanId,
|
||||
transactionAmount: totalDue
|
||||
};
|
||||
@@ -279,7 +291,17 @@ export class IndividualCollectionSheetComponent implements OnInit {
|
||||
if (isNaN(dueAmount)) {
|
||||
dueAmount = 0;
|
||||
}
|
||||
const savingsTransaction = {
|
||||
const savingsTransaction: {
|
||||
savingsId: any;
|
||||
transactionAmount: any;
|
||||
depositAccountType: number;
|
||||
accountNumber?: any;
|
||||
checkNumber?: number;
|
||||
routingCode?: string;
|
||||
receiptNumber?: number;
|
||||
bankNumber?: number;
|
||||
paymentTypeId?: string;
|
||||
} = {
|
||||
savingsId: selectedData.savingsId,
|
||||
transactionAmount: dueAmount,
|
||||
depositAccountType:
|
||||
|
||||
@@ -10,7 +10,7 @@ import { environment } from '../../../environments/environment';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
|
||||
/** Http request (default) options headers. */
|
||||
const httpOptions = {
|
||||
const httpOptions: { headers: { [key: string]: string } } = {
|
||||
headers: {
|
||||
'Fineract-Platform-TenantId': environment.fineractPlatformTenantId
|
||||
}
|
||||
|
||||
@@ -107,7 +107,8 @@ export class HttpCacheService {
|
||||
*/
|
||||
setPersistence(persistence?: 'local' | 'session') {
|
||||
this.cleanCache();
|
||||
this.storage = persistence === 'local' || persistence === 'session' ? window[persistence + 'Storage'] : null;
|
||||
this.storage =
|
||||
persistence === 'local' ? window.localStorage : persistence === 'session' ? window.sessionStorage : null;
|
||||
this.loadCacheData();
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -41,6 +41,8 @@ export class FixedDepositsAccountActionsComponent {
|
||||
*/
|
||||
constructor(private route: ActivatedRoute) {
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -5,6 +5,7 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Currency, PaymentType } from 'app/shared/models/general.model';
|
||||
import { TransactionCommand, TransactionTypeFlags } from '../../../transaction.model';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposits-cash-transaction',
|
||||
@@ -23,9 +24,9 @@ export class FixedDepositsCashTransactionComponent implements OnInit {
|
||||
/** Flag to enable payment details fields. */
|
||||
addPaymentDetailsFlag: Boolean = false;
|
||||
/** transaction type flag to render required UI */
|
||||
transactionType: { deposit: boolean; withdrawal: boolean } = { deposit: false, withdrawal: false };
|
||||
transactionType: TransactionTypeFlags = { deposit: false, withdrawal: false };
|
||||
/** transaction command for submit request */
|
||||
transactionCommand: string;
|
||||
transactionCommand: TransactionCommand;
|
||||
actionName: string;
|
||||
/** saving account's Id */
|
||||
accountId: string;
|
||||
@@ -53,8 +54,14 @@ export class FixedDepositsCashTransactionComponent implements OnInit {
|
||||
this.paymentTypeOptions = data.fixedDepositsAccountActionData.paymentTypeOptions;
|
||||
});
|
||||
this.actionName = this.route.snapshot.params['name'];
|
||||
this.transactionCommand = this.actionName.toLowerCase();
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
const lowerName = this.actionName.toLowerCase();
|
||||
if (lowerName === 'deposit' || lowerName === 'withdrawal') {
|
||||
this.transactionCommand = lowerName;
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
} else {
|
||||
throw new Error(`Invalid transaction action: ${this.actionName}`);
|
||||
}
|
||||
|
||||
this.accountId = this.route.parent.snapshot.params['fixedDepositAccountId'];
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -8,6 +8,7 @@ import { RecurringDepositsService } from '../../recurring-deposits.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { TransactionCommand, TransactionTypeFlags } from '../../../transaction.model';
|
||||
|
||||
/**
|
||||
* Deposits Recurring Deposits Account Component
|
||||
@@ -39,8 +40,8 @@ export class DepositRecurringDepositsAccountComponent implements OnInit {
|
||||
|
||||
action: string;
|
||||
actionName: string;
|
||||
transactionCommand: string;
|
||||
transactionType: { deposit: boolean; withdrawal: boolean } = { deposit: false, withdrawal: false };
|
||||
transactionCommand: TransactionCommand;
|
||||
transactionType: TransactionTypeFlags = { deposit: false, withdrawal: false };
|
||||
|
||||
/**
|
||||
* Retrieves action details transactions template data from `resolve`
|
||||
@@ -66,13 +67,18 @@ export class DepositRecurringDepositsAccountComponent implements OnInit {
|
||||
data.recurringDepositsAccountActionData.outstandingChargeAmount > 0
|
||||
) {
|
||||
this.outstandingChargeAmount = data.recurringDepositsAccountActionData.outstandingChargeAmount;
|
||||
this.transactionAmount = this.transactionAmount + this.outstandingChargeAmount;
|
||||
this.transactionAmount += this.outstandingChargeAmount;
|
||||
}
|
||||
});
|
||||
this.actionName = this.route.snapshot.params['name'];
|
||||
this.action = this.actionName.toLowerCase();
|
||||
this.transactionCommand = this.action.toLowerCase();
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
if (this.action === 'deposit' || this.action === 'withdrawal') {
|
||||
this.transactionCommand = this.action;
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
} else {
|
||||
throw new Error(`Invalid transaction action: ${this.actionName}`);
|
||||
}
|
||||
|
||||
this.accountId = this.route.parent.snapshot.params['recurringDepositAccountId'];
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -47,6 +47,8 @@ export class RecurringDepositsAccountActionsComponent {
|
||||
}
|
||||
});
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -69,8 +69,7 @@
|
||||
{{ 'labels.inputs.Note' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
*ngIf="transactionData.note">
|
||||
<div class="flex-50" *ngIf="transactionData.note">
|
||||
{{ transactionData.note }}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export type TransactionCommand = 'deposit' | 'withdrawal';
|
||||
|
||||
export type TransactionTypeFlags = {
|
||||
[key in TransactionCommand]: boolean;
|
||||
};
|
||||
@@ -44,6 +44,8 @@ export class GroupActionsComponent {
|
||||
) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
const action = this.route.snapshot.params['action'];
|
||||
this.actions[action] = true;
|
||||
if (action && action in this.actions) {
|
||||
this.actions[action as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ export class LoansAccountDatatableStepComponent implements OnInit {
|
||||
get payload(): any {
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const datatableDataValues = this.datatableForm.value;
|
||||
const data = {
|
||||
const data: { [key: string]: any } = {
|
||||
locale: this.settingsService.language.code
|
||||
};
|
||||
let existDate = false;
|
||||
|
||||
+7
-1
@@ -15,6 +15,12 @@ import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { CodeName, OptionData } from 'app/shared/models/option-data.model';
|
||||
|
||||
interface DisbursementData {
|
||||
id?: number;
|
||||
principal: number;
|
||||
expectedDisbursementDate: string | Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Loans Account Terms Step
|
||||
*/
|
||||
@@ -62,7 +68,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
|
||||
/** Client Active Loan Data */
|
||||
clientActiveLoanData: any;
|
||||
/** Multi Disbursement Data */
|
||||
disbursementDataSource: {}[] = [];
|
||||
disbursementDataSource: DisbursementData[] = [];
|
||||
/** Loan repayment strategies */
|
||||
transactionProcessingStrategyOptions: any = [];
|
||||
repaymentStrategyDisabled = false;
|
||||
|
||||
+3
-1
@@ -24,7 +24,9 @@ export class EditRepaymentScheduleComponent implements OnInit {
|
||||
/** Indicates If the Schedule has been validated */
|
||||
wasValidated = false;
|
||||
/** Stores the Repayment Schedule data */
|
||||
repaymentScheduleDetails: any[] | null = null;
|
||||
repaymentScheduleDetails: {
|
||||
periods: { period?: number; dueDate: string; totalDueForPeriod?: number; changed?: boolean }[];
|
||||
} | null = null;
|
||||
/** Stores the Installments changed */
|
||||
repaymentScheduleChanges: any = {};
|
||||
|
||||
|
||||
@@ -56,7 +56,12 @@ export class RescheduleLoanTabComponent {
|
||||
if (response.confirm) {
|
||||
const locale = this.settingsService.language.code;
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const payload = {
|
||||
const payload: {
|
||||
dateFormat: string;
|
||||
locale: string;
|
||||
approvedOnDate?: string;
|
||||
rejectedOnDate?: string;
|
||||
} = {
|
||||
dateFormat,
|
||||
locale
|
||||
};
|
||||
|
||||
@@ -386,7 +386,7 @@ export class TransactionsTabComponent implements OnInit {
|
||||
value: this.dateUtils.parseDate(transactionDate),
|
||||
type: 'datetime-local',
|
||||
required: true,
|
||||
minDate: transaction.date,
|
||||
minDate: this.dateUtils.parseDate(transaction.date),
|
||||
order: 1
|
||||
}),
|
||||
new InputBase({
|
||||
|
||||
+1
-2
@@ -43,8 +43,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75">
|
||||
(click)="addPaymentDetails()">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75" (click)="addPaymentDetails()">
|
||||
<mat-slide-toggle>
|
||||
<div [className]="showPaymentDetails ? 'enabled' : 'disabled'">
|
||||
<span class="m-l-10">{{ 'labels.inputs.Show Payment Details' | translate }}</span>
|
||||
|
||||
@@ -25,9 +25,7 @@
|
||||
[routerLink]="[routeMap[row.objectType], row.objectId]"
|
||||
></tr>
|
||||
<tr *matNoDataRow>
|
||||
<td [attr.colspan]="displayedColumns.length" style="text-align: center; padding: 16px; color: #999">
|
||||
You don't have any notifications
|
||||
</td>
|
||||
<td [attr.colspan]="displayedColumns.length">You don't have any notifications</td>
|
||||
</tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
@@ -37,7 +37,7 @@ export class CreateHolidayComponent implements OnInit {
|
||||
// Stores office data in a trie-like structure
|
||||
officesTrie: any;
|
||||
// Stores office data for access from DOM via Office ID
|
||||
officesDict = {};
|
||||
officesDict: { [key: string]: any } = {};
|
||||
|
||||
// Angular Material Tree Configuration start ------------
|
||||
|
||||
@@ -100,7 +100,7 @@ export class CreateHolidayComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
constructOfficeHierarchy() {
|
||||
const trie = {};
|
||||
const trie: Record<string, any> = {};
|
||||
// Iterates over all the offices
|
||||
this.officesData.forEach((office: any) => {
|
||||
this.officesDict[office.id] = office;
|
||||
@@ -114,7 +114,7 @@ export class CreateHolidayComponent implements OnInit {
|
||||
|
||||
// Temporary variable to store current object
|
||||
|
||||
let root = trie;
|
||||
let root: Record<string, any> = trie;
|
||||
|
||||
if (hierarchy.length === 0) {
|
||||
root[office.id] = {};
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ export class BusinessRuleParametersComponent implements OnInit, OnChanges {
|
||||
formattedResponse[newKey] = value;
|
||||
break;
|
||||
case 'select':
|
||||
formattedResponse[newKey] = value['id'];
|
||||
formattedResponse[newKey] = (value as { id: string | number })['id'];
|
||||
break;
|
||||
case 'date':
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
|
||||
@@ -48,6 +48,6 @@ export class StatusLookupPipe implements PipeTransform {
|
||||
'smsCampaignStatus.closed': 'status-closed',
|
||||
'purchasedSharesStatusType.applied': 'status-pending'
|
||||
};
|
||||
return cssClassNameLookup[status];
|
||||
return cssClassNameLookup[status as keyof typeof cssClassNameLookup] ?? 'status-unknown';
|
||||
}
|
||||
}
|
||||
|
||||
+45
-10
@@ -91,7 +91,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
this.clientClassificationData = this.fixedDepositProductsTemplate.chartTemplate.clientClassificationOptions;
|
||||
this.incentiveTypeData = this.fixedDepositProductsTemplate.chartTemplate.incentiveTypeOptions;
|
||||
|
||||
if (!(this.fixedDepositProductsTemplate === undefined)) {
|
||||
if (this.fixedDepositProductsTemplate) {
|
||||
this.assignFormData();
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
formArray.push(chartSlabInfo);
|
||||
|
||||
// Iterate for every slab in chartSlab
|
||||
const chartIncentiveControl = chartDetailControl.controls['chartSlabs']['controls'][j];
|
||||
const chartIncentiveControl = (chartDetailControl.controls['chartSlabs'] as UntypedFormArray).controls[j];
|
||||
|
||||
// Iterate to input all the incentive for particular chart slab
|
||||
this.chartsDetail[i].chartSlabs[j].incentives.forEach((chartIncentiveDetail: any) => {
|
||||
@@ -158,8 +158,8 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
chartIncentiveDetail.attributeName,
|
||||
Validators.required
|
||||
],
|
||||
attribureValue: [
|
||||
chartIncentiveDetail.attribureValue,
|
||||
attributeValue: [
|
||||
chartIncentiveDetail.attributeValue,
|
||||
Validators.required
|
||||
],
|
||||
conditionType: [
|
||||
@@ -175,7 +175,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
const newFormArray = chartIncentiveControl['controls']['incentives'] as UntypedFormArray;
|
||||
const newFormArray = (chartIncentiveControl as UntypedFormGroup).controls['incentives'] as UntypedFormArray;
|
||||
newFormArray.push(incentiveInfo);
|
||||
});
|
||||
});
|
||||
@@ -183,8 +183,8 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
}
|
||||
|
||||
getChartsDetailsData() {
|
||||
this.chartDetailData.forEach((chartData: any) => {
|
||||
const chart = {
|
||||
this.chartDetailData.forEach((chartData: ChartData) => {
|
||||
const chart: Chart = {
|
||||
endDate: chartData.endDate ? new Date(chartData.endDate) : '',
|
||||
fromDate: chartData.fromDate ? new Date(chartData.fromDate) : '',
|
||||
isPrimaryGroupingByAmount: chartData.isPrimaryGroupingByAmount,
|
||||
@@ -193,7 +193,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
chartSlabs: this.getChartSlabsData(chartData)
|
||||
};
|
||||
if (chartData.id) {
|
||||
chart['id'] = chartData.id;
|
||||
chart.id = chartData.id;
|
||||
}
|
||||
this.chartsDetail.push(chart);
|
||||
});
|
||||
@@ -213,7 +213,17 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
}
|
||||
|
||||
chartSlabData.forEach((eachChartSlabData: any) => {
|
||||
const chartSlab = {
|
||||
const chartSlab: {
|
||||
id?: any;
|
||||
periodType: any;
|
||||
amountRangeFrom: any;
|
||||
amountRangeTo: any;
|
||||
annualInterestRate: any;
|
||||
description: any;
|
||||
fromPeriod: any;
|
||||
toPeriod: any;
|
||||
incentives: any[];
|
||||
} = {
|
||||
periodType: eachChartSlabData.periodType.id,
|
||||
amountRangeFrom: eachChartSlabData.amountRangeFrom,
|
||||
amountRangeTo: eachChartSlabData.amountRangeTo,
|
||||
@@ -221,7 +231,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
description: eachChartSlabData.description ? eachChartSlabData.description : '',
|
||||
fromPeriod: eachChartSlabData.fromPeriod,
|
||||
toPeriod: eachChartSlabData.toPeriod,
|
||||
incentives: this.getIncentivesData(chartSlabData)
|
||||
incentives: this.getIncentivesData(eachChartSlabData)
|
||||
};
|
||||
if (eachChartSlabData.id) {
|
||||
chartSlab['id'] = eachChartSlabData.id;
|
||||
@@ -468,3 +478,28 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
return fixedDepositProductInterestRateChart;
|
||||
}
|
||||
}
|
||||
|
||||
interface ChartData {
|
||||
id?: number;
|
||||
endDate?: string;
|
||||
fromDate?: string;
|
||||
isPrimaryGroupingByAmount: boolean;
|
||||
name: string;
|
||||
description: string;
|
||||
chartSlabs: ChartSlab[];
|
||||
}
|
||||
|
||||
interface ChartSlab {
|
||||
periodType?: string;
|
||||
fromPeriod?: number;
|
||||
toPeriod?: number;
|
||||
amountRangeFrom?: number;
|
||||
amountRangeTo?: number;
|
||||
annualInterestRate?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
interface Chart extends Omit<ChartData, 'endDate' | 'fromDate'> {
|
||||
endDate: Date | string;
|
||||
fromDate: Date | string;
|
||||
}
|
||||
|
||||
+2
-2
@@ -378,7 +378,7 @@
|
||||
|
||||
<div class="flex-fill layout-row">
|
||||
<span class="flex-47">{{ 'labels.inputs.Repayment Strategy' | translate }}:</span>
|
||||
<span class="flex-53" class="repayment-strategy">{{
|
||||
<span class="flex-53 repayment-strategy">{{
|
||||
loanProduct.transactionProcessingStrategyName | translateKey: 'catalogs'
|
||||
}}</span>
|
||||
</div>
|
||||
@@ -563,7 +563,7 @@
|
||||
<span class="flex-53">{{ loanProduct.canUseForTopup | yesNo }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" class="flex-fill">{{ 'labels.heading.Interest Recalculation' | translate }}</h3>
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Interest Recalculation' | translate }}</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@
|
||||
|
||||
<span class="flex-48 hide-lt-md"></span>
|
||||
|
||||
<div style="display: flex; justify-content: flex-start; width: 100%">
|
||||
<div class="full-width-flex">
|
||||
<div *ngIf="isAdvancedTransactionProcessingStrategy">
|
||||
<h3 class="mat-h4 flex-98">{{ 'labels.inputs.Loan Charge-off behaviour' | translate }}</h3>
|
||||
|
||||
|
||||
@@ -21,14 +21,12 @@
|
||||
<fa-icon
|
||||
(click)="arrowBooleansToggle(0); $event.stopPropagation()"
|
||||
*ngIf="!arrowBooleans[0]"
|
||||
style="z-index: 1000"
|
||||
icon="arrow-down"
|
||||
size="md"
|
||||
></fa-icon>
|
||||
<fa-icon
|
||||
(click)="arrowBooleansToggle(0); $event.stopPropagation()"
|
||||
*ngIf="arrowBooleans[0]"
|
||||
style="z-index: 1000"
|
||||
icon="arrow-up"
|
||||
size="md"
|
||||
></fa-icon>
|
||||
|
||||
+21
-4
@@ -145,7 +145,7 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
formArray.push(chartSlabInfo);
|
||||
|
||||
// Iterate for every slab in chartSlab
|
||||
const chartIncentiveControl = chartDetailControl.controls['chartSlabs']['controls'][j];
|
||||
const chartIncentiveControl = (chartDetailControl.controls['chartSlabs'] as UntypedFormArray).controls[j];
|
||||
|
||||
// Iterate to input all the incentive for particular chart slab
|
||||
this.chartsDetail[i].chartSlabs[j].incentives.forEach((chartIncentiveDetail: any) => {
|
||||
@@ -175,7 +175,7 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
const newFormArray = chartIncentiveControl['controls']['incentives'] as UntypedFormArray;
|
||||
const newFormArray = (chartIncentiveControl as UntypedFormGroup).controls['incentives'] as UntypedFormArray;
|
||||
newFormArray.push(incentiveInfo);
|
||||
});
|
||||
});
|
||||
@@ -184,7 +184,14 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
|
||||
getChartsDetailsData() {
|
||||
this.chartDetailData.forEach((chartData: any) => {
|
||||
const chart = {
|
||||
const chart: {
|
||||
id?: any;
|
||||
endDate: string | Date;
|
||||
fromDate: string | Date;
|
||||
isPrimaryGroupingByAmount: any;
|
||||
name: any;
|
||||
chartSlabs: any[];
|
||||
} = {
|
||||
endDate: chartData.endDate ? new Date(chartData.endDate) : '',
|
||||
fromDate: chartData.fromDate ? new Date(chartData.fromDate) : '',
|
||||
isPrimaryGroupingByAmount: chartData.isPrimaryGroupingByAmount,
|
||||
@@ -212,7 +219,17 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
}
|
||||
|
||||
chartSlabData.forEach((eachChartSlabData: any) => {
|
||||
const chartSlab = {
|
||||
const chartSlab: {
|
||||
id?: any;
|
||||
periodType: any;
|
||||
amountRangeFrom: any;
|
||||
amountRangeTo: any;
|
||||
annualInterestRate: any;
|
||||
description: any;
|
||||
fromPeriod: any;
|
||||
toPeriod: any;
|
||||
incentives: any[];
|
||||
} = {
|
||||
periodType: eachChartSlabData.periodType.id,
|
||||
amountRangeFrom: eachChartSlabData.amountRangeFrom,
|
||||
amountRangeTo: eachChartSlabData.amountRangeTo,
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SelectOption } from '../common-models/select-option.model';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
import * as ExcelJS from 'exceljs';
|
||||
import { AlertService } from 'app/core/alert/alert.service';
|
||||
|
||||
/**
|
||||
@@ -251,7 +251,7 @@ export class RunReportComponent implements OnInit {
|
||||
formattedResponse[newKey] = value;
|
||||
break;
|
||||
case 'select':
|
||||
formattedResponse[newKey] = value['id'];
|
||||
formattedResponse[newKey] = (value as { id: string | number })['id'];
|
||||
break;
|
||||
case 'date':
|
||||
if (this.isTableReport()) {
|
||||
@@ -339,18 +339,46 @@ export class RunReportComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
exportToXLS(reportName: string, csvData: any, displayedColumns: string[]): void {
|
||||
async exportToXLS(reportName: string, csvData: any, displayedColumns: string[]): Promise<void> {
|
||||
const fileName = `${reportName}.xlsx`;
|
||||
|
||||
// Format data for ExcelJS
|
||||
const data = csvData.map((object: any) => {
|
||||
const row = {};
|
||||
const row: Record<string, any> = {};
|
||||
for (let i = 0; i < displayedColumns.length; i++) {
|
||||
row[displayedColumns[i]] = object.row[i];
|
||||
}
|
||||
return row;
|
||||
});
|
||||
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data, { header: displayedColumns });
|
||||
const wb: XLSX.WorkBook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'report');
|
||||
XLSX.writeFile(wb, fileName);
|
||||
|
||||
// Create workbook and worksheet
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('report');
|
||||
|
||||
// Add header
|
||||
worksheet.addRow(displayedColumns);
|
||||
|
||||
// Add data rows
|
||||
data.forEach((rowObj: any) => {
|
||||
worksheet.addRow(displayedColumns.map((col) => rowObj[col]));
|
||||
});
|
||||
|
||||
// Write to buffer and trigger download
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
const blob = new Blob([buffer], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
});
|
||||
|
||||
// Native download logic (no FileSaver)
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
||||
import { environment } from 'environments/environment';
|
||||
import { ProgressBarService } from 'app/core/progress-bar/progress-bar.service';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
import * as ExcelJS from 'exceljs';
|
||||
|
||||
/**
|
||||
* Table and SMS Component
|
||||
@@ -143,16 +143,33 @@ export class TableAndSmsComponent implements OnChanges {
|
||||
exportToXLS(): void {
|
||||
const fileName = `${this.dataObject.report.name}.xlsx`;
|
||||
const data = this.csvData.map((object: any) => {
|
||||
const row = {};
|
||||
const row: { [key: string]: any } = {};
|
||||
for (let i = 0; i < this.displayedColumns.length; i++) {
|
||||
row[this.displayedColumns[i]] = object.row[i];
|
||||
}
|
||||
return row;
|
||||
});
|
||||
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data, { header: this.displayedColumns });
|
||||
const wb: XLSX.WorkBook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'Report');
|
||||
XLSX.writeFile(wb, fileName);
|
||||
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('Report');
|
||||
|
||||
// Add header row
|
||||
worksheet.addRow(this.displayedColumns);
|
||||
|
||||
// Add data rows
|
||||
data.forEach((rowObj: any) => {
|
||||
worksheet.addRow(this.displayedColumns.map((col) => rowObj[col]));
|
||||
});
|
||||
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'filename.xlsx';
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+12
-8
@@ -7,6 +7,15 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
|
||||
type TransactionCommandType = 'holdamount' | 'blockaccount' | 'blockdeposit' | 'blockwithdrawal';
|
||||
|
||||
interface TransactionType {
|
||||
holdamount: boolean;
|
||||
blockaccount: boolean;
|
||||
blockdeposit: boolean;
|
||||
blockwithdrawal: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-manage-savings-account',
|
||||
templateUrl: './manage-savings-account.component.html',
|
||||
@@ -22,16 +31,11 @@ export class ManageSavingsAccountComponent implements OnInit {
|
||||
manageSavingsAccountForm: UntypedFormGroup;
|
||||
/** Savings Account Id */
|
||||
savingAccountId: string;
|
||||
transactionCommand: string;
|
||||
transactionCommand: TransactionCommandType;
|
||||
|
||||
reasonOptions: any = [];
|
||||
|
||||
transactionType: {
|
||||
holdamount: boolean;
|
||||
blockaccount: boolean;
|
||||
blockdeposit: boolean;
|
||||
blockwithdrawal: boolean;
|
||||
} = {
|
||||
transactionType: TransactionType = {
|
||||
holdamount: false,
|
||||
blockaccount: false,
|
||||
blockdeposit: false,
|
||||
@@ -130,7 +134,7 @@ export class ManageSavingsAccountComponent implements OnInit {
|
||||
|
||||
submit() {
|
||||
let command = '';
|
||||
let payload = {};
|
||||
let payload: { transactionAmount?: number; [key: string]: any } = {};
|
||||
|
||||
if (this.transactionType.holdamount) {
|
||||
const manageSavingsAccountFormData = this.manageSavingsAccountForm.value;
|
||||
|
||||
@@ -68,7 +68,9 @@ export class SavingAccountActionsComponent {
|
||||
this.currency = data.savingsAccountActionData.currency;
|
||||
}
|
||||
});
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
const name = this.route.snapshot.params['name'] as string;
|
||||
if (name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ export class SavingsAccountTransactionsComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
this.transactionCommand = this.route.snapshot.params['name'].toLowerCase();
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
this.transactionType[this.transactionCommand as 'deposit' | 'withdrawal'] = true;
|
||||
this.savingAccountId = this.route.snapshot.params['savingAccountId'];
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ export class SavingsAccountViewComponent implements OnInit {
|
||||
taskPermissionName: 'CREATE_ACCOUNTTRANSFER'
|
||||
});
|
||||
}
|
||||
if (this.savingsAccountData.externalId && environment.interbankTransfers === 'true') {
|
||||
if (this.savingsAccountData.externalId && environment.interbankTransfers) {
|
||||
this.buttonConfig.addOption({
|
||||
name: 'Interbank Transfer',
|
||||
taskPermissionName: 'CREATE_ACCOUNTTRANSFER'
|
||||
|
||||
+1
-2
@@ -38,8 +38,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75">
|
||||
(click)="addPaymentDetails()">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75" (click)="addPaymentDetails()">
|
||||
<mat-slide-toggle>
|
||||
<div [className]="showPaymentDetails ? 'enabled' : 'disabled'">
|
||||
<span class="m-l-10">{{ 'labels.inputs.Show Payment Details' | translate }}</span>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
/* eslint-disable @angular-eslint/prefer-standalone */
|
||||
@Component({
|
||||
selector: 'ngx-mat-datetime-picker',
|
||||
template: `
|
||||
<mat-datepicker-toggle [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
`,
|
||||
standalone: false
|
||||
})
|
||||
export class DatetimePickerStubComponent {
|
||||
@Input() enableMeridian: boolean = true;
|
||||
}
|
||||
@@ -50,14 +50,12 @@
|
||||
<mat-label>{{ formfield.label }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[ngxMatDatetimePicker]="datetimePicker"
|
||||
type="datetime-local"
|
||||
[min]="formfield.minDate"
|
||||
[max]="formfield.maxDate"
|
||||
[formControlName]="formfield.controlName"
|
||||
[required]="formfield.required"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="datetimePicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #datetimePicker [enableMeridian]="true"></ngx-mat-datetime-picker>
|
||||
<mat-error *ngIf="form.controls[formfield.controlName].hasError('required')">
|
||||
{{ formfield.label }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
interface DatepickerOptions {
|
||||
minDate?: Date;
|
||||
maxDate?: Date;
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export class DatepickerBase extends FormfieldBase {
|
||||
controlType = 'datepicker';
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: DatepickerOptions = {}) {
|
||||
super(options);
|
||||
this.minDate = options['minDate'] || new Date(2000, 0, 1);
|
||||
this.maxDate = options['maxDate'] || new Date();
|
||||
this.minDate = options.minDate || new Date(2000, 0, 1);
|
||||
this.maxDate = options.maxDate || new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
// Define the base options interface based on FormfieldBase requirements
|
||||
interface FormfieldBaseOptions {
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
// Extend the base options for DateTimePicker
|
||||
interface DateTimePickerOptions extends FormfieldBaseOptions {
|
||||
minDate?: Date;
|
||||
maxDate?: Date;
|
||||
}
|
||||
|
||||
export class DateTimepickerBase extends FormfieldBase {
|
||||
controlType = 'datetimepicker';
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: DateTimePickerOptions = {}) {
|
||||
super(options);
|
||||
this.minDate = options['minDate'] || new Date(2000, 0, 1);
|
||||
this.maxDate = options['maxDate'] || new Date();
|
||||
this.minDate = options.minDate || new Date(2000, 0, 1);
|
||||
this.maxDate = options.maxDate || new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
interface InputBaseOptions extends FormfieldBaseOptions {
|
||||
type?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface FormfieldBaseOptions {
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export class InputBase extends FormfieldBase {
|
||||
controlType = 'input';
|
||||
type: string;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: InputBaseOptions = {}) {
|
||||
super(options);
|
||||
this.type = options['type'] || 'text';
|
||||
this.type = options.type || 'text';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
interface SelectOption {
|
||||
label: string;
|
||||
value: string;
|
||||
data: {}[];
|
||||
}
|
||||
|
||||
interface SelectBaseOptions {
|
||||
options?: SelectOption;
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export class SelectBase extends FormfieldBase {
|
||||
controlType = 'select';
|
||||
options: {
|
||||
label: string;
|
||||
value: string;
|
||||
data: {}[];
|
||||
};
|
||||
options: SelectOption;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: SelectBaseOptions = {}) {
|
||||
super(options);
|
||||
this.options = options['options'];
|
||||
this.options = options.options || { label: '', value: '', data: [] };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import { EntityDatatableTabComponent } from './tabs/entity-datatable-tab/entity-
|
||||
import { DatatableSingleRowComponent } from './tabs/entity-datatable-tab/datatable-single-row/datatable-single-row.component';
|
||||
import { DatatableMultiRowComponent } from './tabs/entity-datatable-tab/datatable-multi-row/datatable-multi-row.component';
|
||||
import { SvgIconComponent } from './svg-icon/svg-icon.component';
|
||||
import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-material-components/datetime-picker';
|
||||
// import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-material-components/datetime-picker';
|
||||
import { ViewJournalEntryComponent } from './accounting/view-journal-entry/view-journal-entry.component';
|
||||
import { ViewJournalEntryTransactionComponent } from './accounting/view-journal-entry-transaction/view-journal-entry-transaction.component';
|
||||
import { AccountNumberComponent } from './account-number/account-number.component';
|
||||
@@ -51,6 +51,7 @@ import { LongTextComponent } from './long-text/long-text.component';
|
||||
import { DropdownComponent } from './dropdown/dropdown.component';
|
||||
import { InputAmountComponent } from './input-amount/input-amount.component';
|
||||
import { InputPasswordComponent } from './input-password/input-password.component';
|
||||
import { DatetimePickerStubComponent } from './datetime-picker-stub/datetime-picker-stub.component'; // import Datetime Picker Stub
|
||||
|
||||
/**
|
||||
* Shared Module
|
||||
@@ -65,9 +66,9 @@ import { InputPasswordComponent } from './input-password/input-password.componen
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
PipesModule,
|
||||
DirectivesModule,
|
||||
NgxMatDatetimePickerModule,
|
||||
NgxMatNativeDateModule
|
||||
DirectivesModule
|
||||
// NgxMatDatetimePickerModule,
|
||||
// NgxMatNativeDateModule
|
||||
],
|
||||
declarations: [
|
||||
FormfieldComponent,
|
||||
@@ -108,7 +109,9 @@ import { InputPasswordComponent } from './input-password/input-password.componen
|
||||
LongTextComponent,
|
||||
DropdownComponent,
|
||||
InputAmountComponent,
|
||||
InputPasswordComponent
|
||||
InputPasswordComponent,
|
||||
DatetimePickerStubComponent // temporarily added stub for datetime picker
|
||||
|
||||
],
|
||||
exports: [
|
||||
FileUploadComponent,
|
||||
@@ -143,7 +146,9 @@ import { InputPasswordComponent } from './input-password/input-password.componen
|
||||
ThemeToggleComponent,
|
||||
LongTextComponent,
|
||||
DropdownComponent,
|
||||
InputAmountComponent
|
||||
InputAmountComponent,
|
||||
DatetimePickerStubComponent // Export stub for datetime picker
|
||||
|
||||
]
|
||||
})
|
||||
export class SharedModule {}
|
||||
|
||||
@@ -44,6 +44,8 @@ export class SharesAccountActionsComponent {
|
||||
*/
|
||||
constructor(private route: ActivatedRoute) {
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+60
-36
@@ -8,31 +8,48 @@ import { PopoverService } from '../../configuration-wizard/popover/popover.servi
|
||||
import { ConfigurationWizardService } from '../../configuration-wizard/configuration-wizard.service';
|
||||
import { SystemService } from '../system.service';
|
||||
|
||||
interface Permission {
|
||||
code: string;
|
||||
id: number;
|
||||
selected: boolean;
|
||||
grouping?: string;
|
||||
}
|
||||
|
||||
interface PermissionGroup {
|
||||
permissions: Permission[];
|
||||
}
|
||||
|
||||
interface PermissionData {
|
||||
[key: string]: PermissionGroup;
|
||||
}
|
||||
|
||||
interface SubmitPermissionData {
|
||||
permissions: {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-configure-maker-checker-tasks',
|
||||
templateUrl: './configure-maker-checker-tasks.component.html',
|
||||
styleUrls: ['./configure-maker-checker-tasks.component.scss']
|
||||
})
|
||||
export class ConfigureMakerCheckerTasksComponent implements OnInit, AfterViewInit {
|
||||
permissionsData: any;
|
||||
permissionsData: Permission[] = [];
|
||||
groupings: string[] = [];
|
||||
currentGrouping = '';
|
||||
tempPermissionUIData: PermissionData = {};
|
||||
permissions: PermissionGroup = { permissions: [] };
|
||||
|
||||
formData = {};
|
||||
isDisabled = true;
|
||||
newEntry: any;
|
||||
selectedItem = '';
|
||||
previousGrouping = '';
|
||||
checkboxesChanged: Boolean = false;
|
||||
currentGrouping: string;
|
||||
formGroup: UntypedFormGroup;
|
||||
backupform: UntypedFormGroup;
|
||||
|
||||
permissions: {
|
||||
permissions: { code: string; id: number }[];
|
||||
};
|
||||
tempPermissionUIData: {
|
||||
permissions: { code: string }[];
|
||||
}[];
|
||||
|
||||
/* Reference of edit button */
|
||||
@ViewChild('buttonEdit') buttonEdit: ElementRef<any>;
|
||||
/* Template for popover on edit button */
|
||||
@@ -95,29 +112,33 @@ export class ConfigureMakerCheckerTasksComponent implements OnInit, AfterViewIni
|
||||
});
|
||||
}
|
||||
|
||||
setMakerCheckerTask() {
|
||||
this.tempPermissionUIData = [
|
||||
{
|
||||
permissions: []
|
||||
}
|
||||
];
|
||||
for (const i in this.permissionsData) {
|
||||
if (this.permissionsData[i]) {
|
||||
if (this.permissionsData[i].grouping !== this.currentGrouping) {
|
||||
this.currentGrouping = this.permissionsData[i].grouping;
|
||||
this.groupings.push(this.currentGrouping);
|
||||
this.tempPermissionUIData[this.currentGrouping] = { permissions: [] };
|
||||
}
|
||||
const temp = { code: this.permissionsData[i].code, id: i, selected: this.permissionsData[i].selected };
|
||||
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||
setMakerCheckerTask(): void {
|
||||
this.tempPermissionUIData = {};
|
||||
|
||||
for (const permission of this.permissionsData) {
|
||||
if (permission.grouping !== this.currentGrouping) {
|
||||
this.currentGrouping = permission.grouping || '';
|
||||
this.groupings.push(this.currentGrouping);
|
||||
this.tempPermissionUIData[this.currentGrouping] = { permissions: [] };
|
||||
}
|
||||
|
||||
const temp: Permission = {
|
||||
code: permission.code,
|
||||
id: permission.id,
|
||||
selected: permission.selected
|
||||
};
|
||||
|
||||
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||
}
|
||||
}
|
||||
|
||||
showPermissions(grouping: string) {
|
||||
this.permissions = this.tempPermissionUIData[grouping];
|
||||
this.selectedItem = grouping;
|
||||
this.previousGrouping = grouping;
|
||||
showPermissions(grouping: string): void {
|
||||
const group = this.tempPermissionUIData[grouping];
|
||||
if (group) {
|
||||
this.permissions = group;
|
||||
this.selectedItem = grouping;
|
||||
this.previousGrouping = grouping;
|
||||
}
|
||||
}
|
||||
|
||||
permissionName = function (name: any) {
|
||||
@@ -175,17 +196,20 @@ export class ConfigureMakerCheckerTasksComponent implements OnInit, AfterViewIni
|
||||
this.formGroup.controls.roster.disable();
|
||||
}
|
||||
|
||||
submit() {
|
||||
const value = this.formGroup.get('roster').value;
|
||||
const data = {};
|
||||
const permissionData = {
|
||||
submit(): void {
|
||||
const value = this.formGroup.get('roster')?.value;
|
||||
const permissionData: SubmitPermissionData = {
|
||||
permissions: {}
|
||||
};
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
data[value[i].code] = value[i].selected;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((item) => {
|
||||
if (item.code && typeof item.selected === 'boolean') {
|
||||
permissionData.permissions[item.code] = item.selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
permissionData.permissions = data;
|
||||
this.formGroup.controls.roster.disable();
|
||||
this.formGroup.get('roster')?.disable();
|
||||
this.checkboxesChanged = false;
|
||||
this.isDisabled = true;
|
||||
this.systemService.updateMakerCheckerPermission(permissionData).subscribe((response: any) => {});
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<br />
|
||||
|
||||
<div class="layout-row-wrap responsive-column">
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }}<span style="color: red">*</span></p>
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }}<span class="red">*</span></p>
|
||||
|
||||
<button mat-raised-button class="AddEventButton flex-20" type="button" color="primary" (click)="addEvent()">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<br />
|
||||
|
||||
<div class="layout-row-wrap responsive-column">
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }} <span style="color: red">*</span></p>
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }} <span class="red">*</span></p>
|
||||
|
||||
<button mat-raised-button class="AddEventButton flex-20" type="button" color="primary" (click)="addEvent()">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
|
||||
@@ -9,7 +9,12 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { JobStep } from './workflow-diagram/workflow-diagram.component';
|
||||
|
||||
export interface JobStep {
|
||||
stepName: string;
|
||||
stepDescription: string;
|
||||
order: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-workflow-jobs',
|
||||
@@ -21,7 +26,7 @@ export class WorkflowJobsComponent implements OnInit {
|
||||
|
||||
jobNameOptions: any = [];
|
||||
jobStepsData: any = [];
|
||||
jobAvailableStepsData: any = [];
|
||||
jobAvailableStepsData: JobStep[] = [];
|
||||
jobStepsDataBase: any = [];
|
||||
jobStepName: String = null;
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill" ="48">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Text' | translate }}</mat-label>
|
||||
<input matInput maxlength="255" required formControlName="text" />
|
||||
<mat-error *ngIf="question.controls.text.hasError('required')">
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill" ="48">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Text' | translate }}</mat-label>
|
||||
<input matInput maxlength="255" required formControlName="text" />
|
||||
<mat-error *ngIf="question.get('text').hasError('required')">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators, FormArray } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import * as _ from 'lodash';
|
||||
@@ -45,12 +45,14 @@ export class ViewRoleComponent implements OnInit {
|
||||
backupform: UntypedFormGroup;
|
||||
/** Temporarily stores Permission data */
|
||||
tempPermissionUIData: {
|
||||
permissions: { code: string }[];
|
||||
}[];
|
||||
[key: string]: {
|
||||
permissions: { code: string; id: number; selected?: boolean }[];
|
||||
};
|
||||
} = {};
|
||||
/** Stores permissions */
|
||||
permissions: {
|
||||
permissions: { code: string; id: number }[];
|
||||
};
|
||||
} = { permissions: [] };
|
||||
|
||||
/**
|
||||
* Retrieves the roledetails data from `resolve`.
|
||||
@@ -121,11 +123,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
* Groups the permissions based on rules
|
||||
*/
|
||||
groupRules() {
|
||||
this.tempPermissionUIData = [
|
||||
{
|
||||
permissions: []
|
||||
}
|
||||
];
|
||||
this.tempPermissionUIData = {};
|
||||
for (const i in this.rolePermissionService.permissionUsageData) {
|
||||
if (this.rolePermissionService.permissionUsageData[i]) {
|
||||
if (this.rolePermissionService.permissionUsageData[i].grouping !== this.currentGrouping) {
|
||||
@@ -135,7 +133,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
}
|
||||
const temp = {
|
||||
code: this.rolePermissionService.permissionUsageData[i].code,
|
||||
id: i,
|
||||
id: +i,
|
||||
selected: this.rolePermissionService.permissionUsageData[i].selected
|
||||
};
|
||||
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||
@@ -177,7 +175,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
name = name || '';
|
||||
// replace '_' with ' '
|
||||
name = name.replace(/_/g, ' ');
|
||||
// for reorts replace read with view
|
||||
// for reports replace read with view
|
||||
if (this.previousGrouping === 'report') {
|
||||
name = name.replace(/READ/g, 'View');
|
||||
}
|
||||
@@ -185,7 +183,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Backups the valued
|
||||
* Backups the values
|
||||
*/
|
||||
backupCheckValues() {
|
||||
this.backupform = _.cloneDeep(this.formGroup) as UntypedFormGroup;
|
||||
@@ -220,7 +218,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
*/
|
||||
submit() {
|
||||
const value = this.formGroup.get('roster').value;
|
||||
const data = {};
|
||||
const data: { [key: string]: boolean } = {};
|
||||
const permissionData = {
|
||||
permissions: {}
|
||||
};
|
||||
@@ -238,8 +236,9 @@ export class ViewRoleComponent implements OnInit {
|
||||
* Selects all the permission of a particular role
|
||||
*/
|
||||
selectAll() {
|
||||
const roster = this.formGroup.get('roster') as FormArray;
|
||||
for (let i = 0; i < this.permissions.permissions.length; i++) {
|
||||
this.formGroup.controls.roster['controls'][this.permissions.permissions[i].id].patchValue({
|
||||
roster.at(this.permissions.permissions[i].id).patchValue({
|
||||
selected: true
|
||||
});
|
||||
}
|
||||
@@ -249,8 +248,9 @@ export class ViewRoleComponent implements OnInit {
|
||||
* Deselects all the permissions of a particular role
|
||||
*/
|
||||
deselectAll() {
|
||||
const roster = this.formGroup.get('roster') as FormArray;
|
||||
for (let i = 0; i < this.permissions.permissions.length; i++) {
|
||||
this.formGroup.controls.roster['controls'][this.permissions.permissions[i].id].patchValue({
|
||||
roster.at(this.permissions.permissions[i].id).patchValue({
|
||||
selected: false
|
||||
});
|
||||
}
|
||||
|
||||
+14
-8
@@ -15,6 +15,12 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
interface OfficeNode {
|
||||
id: number;
|
||||
name: string;
|
||||
loans: any[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-loan-approval',
|
||||
templateUrl: './loan-approval.component.html',
|
||||
@@ -32,7 +38,7 @@ export class LoanApprovalComponent {
|
||||
/** Row Selection Data */
|
||||
selection: SelectionModel<any>;
|
||||
/** Map data */
|
||||
idToNodeMap = {};
|
||||
idToNodeMap: { [key: number]: OfficeNode } = {};
|
||||
/** Grouped Office Data */
|
||||
officesArray: any[];
|
||||
/** List of Requests */
|
||||
@@ -79,15 +85,15 @@ export class LoanApprovalComponent {
|
||||
});
|
||||
this.loans.forEach((loanEle: any) => {
|
||||
if (loanEle.status.pendingApproval) {
|
||||
let tempOffice = {};
|
||||
let tempOffice: OfficeNode | undefined;
|
||||
if (loanEle.clientOfficeId) {
|
||||
tempOffice = this.idToNodeMap[loanEle.clientOfficeId];
|
||||
tempOffice['loans'].push(loanEle);
|
||||
} else {
|
||||
if (loanEle.group) {
|
||||
tempOffice = this.idToNodeMap[loanEle.group.officeId];
|
||||
tempOffice['loans'].push(loanEle);
|
||||
}
|
||||
} else if (loanEle.group?.officeId) {
|
||||
tempOffice = this.idToNodeMap[loanEle.group.officeId];
|
||||
}
|
||||
|
||||
if (tempOffice) {
|
||||
tempOffice.loans.push(loanEle);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+10
-3
@@ -15,6 +15,13 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
interface RescheduleFormData {
|
||||
dateFormat: string;
|
||||
locale: string;
|
||||
approvedOnDate?: string;
|
||||
rejectedOnDate?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-reschedule-loan',
|
||||
templateUrl: './reschedule-loan.component.html',
|
||||
@@ -107,14 +114,14 @@ export class RescheduleLoanComponent {
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const transactionDate = this.dateUtils.formatDate(this.settingsService.businessDate, dateFormat);
|
||||
const locale = this.settingsService.language.code;
|
||||
const formData = {
|
||||
const formData: RescheduleFormData = {
|
||||
dateFormat,
|
||||
locale
|
||||
};
|
||||
if (command === 'approve') {
|
||||
formData['approvedOnDate'] = transactionDate;
|
||||
formData.approvedOnDate = transactionDate;
|
||||
} else {
|
||||
formData['rejectedOnDate'] = transactionDate;
|
||||
formData.rejectedOnDate = transactionDate;
|
||||
}
|
||||
const listSelectedAccounts = this.selection.selected;
|
||||
this.batchRequests = [];
|
||||
|
||||
@@ -6,32 +6,32 @@
|
||||
// `.env.ts` is generated by the `npm run env` command
|
||||
import env from './.env';
|
||||
|
||||
// The `window['env']` object is loaded in the `index.html` file
|
||||
const loadedEnv = window['env'] || {};
|
||||
// The `window.env` object is loaded in the `index.html` file
|
||||
const loadedEnv = window.env || {};
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
version: env.mifos_x.version,
|
||||
hash: env.mifos_x.hash,
|
||||
// For connecting to server running elsewhere update the tenant identifier
|
||||
fineractPlatformTenantId: loadedEnv['fineractPlatformTenantId'] || 'default',
|
||||
fineractPlatformTenantIds: loadedEnv['fineractPlatformTenantIds'] || 'default',
|
||||
fineractPlatformTenantId: loadedEnv.fineractPlatformTenantId || 'default',
|
||||
fineractPlatformTenantIds: loadedEnv.fineractPlatformTenantIds || 'default',
|
||||
// For connecting to others servers running elsewhere update the base API URL
|
||||
baseApiUrls:
|
||||
loadedEnv['fineractApiUrls'] ||
|
||||
loadedEnv.fineractApiUrls ||
|
||||
'https://sandbox.mifos.community,https://demo.mifos.community,https://localhost:8443,' + window.location.origin,
|
||||
// For connecting to server running elsewhere set the base API URL
|
||||
baseApiUrl:
|
||||
loadedEnv['fineractApiUrl'] ||
|
||||
(loadedEnv['fineractApiUrls']?.length > 0 ? loadedEnv['fineractApiUrls'].split(',')[0] : window.location.origin),
|
||||
loadedEnv.fineractApiUrl ||
|
||||
(loadedEnv.fineractApiUrls?.length > 0 ? loadedEnv.fineractApiUrls.split(',')[0] : window.location.origin),
|
||||
allowServerSwitch: env.allow_switching_backend_instance,
|
||||
apiProvider: loadedEnv['apiProvider'] || '/fineract-provider/api',
|
||||
apiVersion: loadedEnv['apiVersion'] || '/v1',
|
||||
apiProvider: loadedEnv.apiProvider || '/fineract-provider/api',
|
||||
apiVersion: loadedEnv.apiVersion || '/v1',
|
||||
serverUrl: '',
|
||||
oauth: {
|
||||
enabled: loadedEnv['oauthServerEnabled'] || false, // For connecting to Mifos X using OAuth2 Authentication change the value to true
|
||||
serverUrl: loadedEnv['oauthServerUrl'] || '',
|
||||
appId: loadedEnv['oauthAppId'] || ''
|
||||
enabled: loadedEnv.oauthServerEnabled || false, // For connecting to Mifos X using OAuth2 Authentication change the value to true
|
||||
serverUrl: loadedEnv.oauthServerUrl || '',
|
||||
appId: loadedEnv.oauthAppId || ''
|
||||
},
|
||||
warningDialog: {
|
||||
title: 'Warning',
|
||||
@@ -39,31 +39,31 @@ export const environment = {
|
||||
'This system is for authorized use only. Unauthorized access will result in possible legal action. By accessing this system, you acknowledge that you are authorized to do so and that all data stored and processed here is confidential.',
|
||||
buttonText: 'Close'
|
||||
},
|
||||
defaultLanguage: loadedEnv['defaultLanguage'] || 'en-US',
|
||||
defaultLanguage: loadedEnv.defaultLanguage || 'en-US',
|
||||
supportedLanguages:
|
||||
loadedEnv['supportedLanguages'] || 'cs-CS,de-DE,en-US,es-MX,fr-FR,it-IT,ko-KO,lt-LT,lv-LV,ne-NE,pt-PT,sw-SW',
|
||||
loadedEnv.supportedLanguages || 'cs-CS,de-DE,en-US,es-MX,fr-FR,it-IT,ko-KO,lt-LT,lv-LV,ne-NE,pt-PT,sw-SW',
|
||||
preloadClients: loadedEnv['preloadClients'] || true,
|
||||
|
||||
defaultCharDelimiter: loadedEnv['defaultCharDelimiter'] || ',',
|
||||
defaultCharDelimiter: loadedEnv.defaultCharDelimiter || ',',
|
||||
|
||||
displayBackEndInfo: loadedEnv['displayBackEndInfo'] || 'true',
|
||||
displayTenantSelector: loadedEnv['displayTenantSelector'] || 'true',
|
||||
displayBackEndInfo: loadedEnv.displayBackEndInfo || 'true',
|
||||
displayTenantSelector: loadedEnv.displayTenantSelector || 'true',
|
||||
// Time in seconds, default 60 seconds
|
||||
waitTimeForNotifications: loadedEnv['waitTimeForNotifications'] || 60,
|
||||
waitTimeForNotifications: loadedEnv.waitTimeForNotifications || 60,
|
||||
// Time in seconds, default 30 seconds
|
||||
waitTimeForCOBCatchUp: loadedEnv['waitTimeForCOBCatchUp'] || 30,
|
||||
waitTimeForCOBCatchUp: loadedEnv.waitTimeForCOBCatchUp || 30,
|
||||
session: {
|
||||
timeout: {
|
||||
idleTimeout: loadedEnv['sessionIdleTimeout'] || 300000 // 5 minutes
|
||||
idleTimeout: loadedEnv.sessionIdleTimeout || 300000 // 5 minutes
|
||||
}
|
||||
},
|
||||
|
||||
vNextApiUrl: window['env']['vNextApiUrl'] || 'https://apis.flexcore.mx',
|
||||
vNextApiProvider: window['env']['vNextApiProvider'] || '/vnext1',
|
||||
vNextApiVersion: window['env']['vNextApiVersion'] || '/v1.0',
|
||||
interbankTransfers: window['env']['interbankTransfers'] || false,
|
||||
vNextApiUrl: window.env?.vNextApiUrl || 'https://apis.flexcore.mx',
|
||||
vNextApiProvider: window.env?.vNextApiProvider || '/vnext1',
|
||||
vNextApiVersion: window.env?.vNextApiVersion || '/v1.0',
|
||||
interbankTransfers: window.env?.interbankTransfers || false,
|
||||
|
||||
minPasswordLength: loadedEnv['minPasswordLength'] || 12
|
||||
minPasswordLength: loadedEnv.minPasswordLength || 12
|
||||
};
|
||||
|
||||
// Server URL
|
||||
|
||||
@@ -580,6 +580,10 @@
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.menu-right-section fa-icon {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.menu-right-section {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
@@ -591,3 +595,19 @@
|
||||
display: contents;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
mifosx-notifications-page td {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.full-width-flex {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
+2
-1
@@ -28,7 +28,8 @@ import '@angular/localize/init';
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
import 'zone.js';
|
||||
// Included with Angular CLI.
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
|
||||
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
interface Window {
|
||||
env?: {
|
||||
[key: string]: any;
|
||||
fineractPlatformTenantId?: string;
|
||||
fineractPlatformTenantIds?: string;
|
||||
fineractApiUrls?: string;
|
||||
fineractApiUrl?: string;
|
||||
allow_switching_backend_instance?: boolean;
|
||||
apiProvider?: string;
|
||||
apiVersion?: string;
|
||||
oauthServerEnabled?: boolean;
|
||||
oauthServerUrl?: string;
|
||||
oauthAppId?: string;
|
||||
defaultLanguage?: string;
|
||||
supportedLanguages?: string;
|
||||
preloadClients?: boolean;
|
||||
defaultCharDelimiter?: string;
|
||||
displayBackEndInfo?: string;
|
||||
displayTenantSelector?: string;
|
||||
waitTimeForNotifications?: number;
|
||||
waitTimeForCOBCatchUp?: number;
|
||||
sessionIdleTimeout?: number;
|
||||
vNextApiUrl?: string;
|
||||
vNextApiProvider?: string;
|
||||
vNextApiVersion?: string;
|
||||
interbankTransfers?: boolean;
|
||||
minPasswordLength?: number;
|
||||
};
|
||||
}
|
||||
Vendored
+7
@@ -11,6 +11,13 @@ interface NodeModule {
|
||||
id: string;
|
||||
}
|
||||
|
||||
// Extend the global Window interface to include `env`
|
||||
interface Window {
|
||||
env: {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
declare module 'chart.js';
|
||||
|
||||
declare module '@ckeditor/ckeditor5-build-classic' {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"target": "ES2022",
|
||||
"typeRoots": [
|
||||
"node_modules/@types",
|
||||
|
||||
Reference in New Issue
Block a user