Tab text translation issue solved (#2376)
Co-authored-by: jc-on-fire <147938885+jc-on-fire@users.noreply.github.com>
This commit is contained in:
co-authored by
jc-on-fire
parent
27b6e72976
commit
3607148784
Generated
+695
-108
File diff suppressed because it is too large
Load Diff
+37
-144
@@ -1,4 +1,3 @@
|
|||||||
/** Angular Imports */
|
|
||||||
import { Component, OnInit, HostListener, HostBinding } from '@angular/core';
|
import { Component, OnInit, HostListener, HostBinding } from '@angular/core';
|
||||||
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
|
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
@@ -6,8 +5,8 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
|
||||||
/** rxjs Imports */
|
/** rxjs Imports */
|
||||||
import { merge } from 'rxjs';
|
import { merge, of } from 'rxjs';
|
||||||
import { filter, map, mergeMap } from 'rxjs/operators';
|
import { filter, map, switchMap, catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
/** Translation Imports */
|
/** Translation Imports */
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
@@ -35,35 +34,6 @@ import { ThemingService } from './shared/theme-toggle/theming.service';
|
|||||||
/** Initialize Logger */
|
/** Initialize Logger */
|
||||||
const log = new Logger('MifosX');
|
const log = new Logger('MifosX');
|
||||||
|
|
||||||
import { registerLocaleData } from '@angular/common';
|
|
||||||
import localeCS from '@angular/common/locales/cs';
|
|
||||||
import localeEN from '@angular/common/locales/en';
|
|
||||||
import localeES from '@angular/common/locales/es';
|
|
||||||
import localeDE from '@angular/common/locales/de';
|
|
||||||
import localeFR from '@angular/common/locales/fr';
|
|
||||||
import localeIT from '@angular/common/locales/it';
|
|
||||||
import localeKO from '@angular/common/locales/ko';
|
|
||||||
import localeLT from '@angular/common/locales/lt';
|
|
||||||
import localeLV from '@angular/common/locales/lv';
|
|
||||||
import localeNE from '@angular/common/locales/ne';
|
|
||||||
import localePT from '@angular/common/locales/pt';
|
|
||||||
import localeSW from '@angular/common/locales/sw';
|
|
||||||
registerLocaleData(localeCS);
|
|
||||||
registerLocaleData(localeEN);
|
|
||||||
registerLocaleData(localeES);
|
|
||||||
registerLocaleData(localeDE);
|
|
||||||
registerLocaleData(localeFR);
|
|
||||||
registerLocaleData(localeIT);
|
|
||||||
registerLocaleData(localeKO);
|
|
||||||
registerLocaleData(localeLT);
|
|
||||||
registerLocaleData(localeLV);
|
|
||||||
registerLocaleData(localeNE);
|
|
||||||
registerLocaleData(localePT);
|
|
||||||
registerLocaleData(localeSW);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main web app component.
|
|
||||||
*/
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-web-app',
|
selector: 'mifosx-web-app',
|
||||||
templateUrl: './web-app.component.html',
|
templateUrl: './web-app.component.html',
|
||||||
@@ -72,34 +42,19 @@ registerLocaleData(localeSW);
|
|||||||
trigger('opacityScale', [
|
trigger('opacityScale', [
|
||||||
transition(':enter', [
|
transition(':enter', [
|
||||||
style({ opacity: 0, transform: 'scale(.95)' }),
|
style({ opacity: 0, transform: 'scale(.95)' }),
|
||||||
animate('100ms ease-out', style({ opacity: 1, transform: 'scale(1)' }))]),
|
animate('100ms ease-out', style({ opacity: 1, transform: 'scale(1)' })),
|
||||||
|
]),
|
||||||
transition(':leave', [
|
transition(':leave', [
|
||||||
style({ opacity: 1, transform: 'scale(1)' }),
|
style({ opacity: 1, transform: 'scale(1)' }),
|
||||||
animate('75ms ease-in', style({ opacity: 0, transform: 'scale(.95)' }))])
|
animate('75ms ease-in', style({ opacity: 0, transform: 'scale(.95)' })),
|
||||||
|
]),
|
||||||
])
|
]),
|
||||||
|
],
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class WebAppComponent implements OnInit {
|
export class WebAppComponent implements OnInit {
|
||||||
buttonConfig: KeyboardShortcutsConfiguration;
|
buttonConfig: KeyboardShortcutsConfiguration;
|
||||||
|
|
||||||
i18nService: I18nService;
|
i18nService: I18nService;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Router} router Router for navigation.
|
|
||||||
* @param {ActivatedRoute} activatedRoute Activated Route.
|
|
||||||
* @param {Title} titleService Title Service.
|
|
||||||
* @param {TranslateService} translateService Translate Service.
|
|
||||||
* @param {ThemeStorageService} themeStorageService Theme Storage Service.
|
|
||||||
* @param {MatSnackBar} snackBar Material Snackbar for notifications.
|
|
||||||
* @param {AlertService} alertService Alert Service.
|
|
||||||
* @param {SettingsService} settingsService Settings Service.
|
|
||||||
* @param {AuthenticationService} authenticationService Authentication service.
|
|
||||||
* @param {Dates} dateUtils Dates service.
|
|
||||||
* @param {IdleTimeoutService} idle Idle timeout service.
|
|
||||||
* @param {MatDialog} dialog Dialog component.
|
|
||||||
*/
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
@@ -118,17 +73,6 @@ export class WebAppComponent implements OnInit {
|
|||||||
|
|
||||||
@HostBinding('class') public cssClass: string;
|
@HostBinding('class') public cssClass: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Initial Setup:
|
|
||||||
*
|
|
||||||
* 1) Logger
|
|
||||||
*
|
|
||||||
* 2) Language and Translations
|
|
||||||
*
|
|
||||||
* 3) Page Title
|
|
||||||
*
|
|
||||||
* 4) Alerts
|
|
||||||
*/
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.themingService.theme.subscribe((value: string) => {
|
this.themingService.theme.subscribe((value: string) => {
|
||||||
this.cssClass = value;
|
this.cssClass = value;
|
||||||
@@ -136,93 +80,53 @@ export class WebAppComponent implements OnInit {
|
|||||||
this.themingService.setInitialDarkMode();
|
this.themingService.setInitialDarkMode();
|
||||||
this.themingService.setDarkMode(this.settingsService.themeDarkEnabled === 'true');
|
this.themingService.setDarkMode(this.settingsService.themeDarkEnabled === 'true');
|
||||||
|
|
||||||
// Setup logger
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
Logger.enableProductionMode();
|
Logger.enableProductionMode();
|
||||||
}
|
}
|
||||||
log.debug('init');
|
log.debug('init');
|
||||||
|
|
||||||
// Setup translations
|
|
||||||
this.translateService.addLangs(environment.supportedLanguages.split(','));
|
this.translateService.addLangs(environment.supportedLanguages.split(','));
|
||||||
if (this.settingsService.language) {
|
this.translateService.use(this.settingsService.languageCode || environment.defaultLanguage);
|
||||||
this.translateService.use(this.settingsService.languageCode);
|
|
||||||
} else {
|
|
||||||
this.translateService.use(environment.defaultLanguage);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.i18nService = new I18nService(this.translateService);
|
this.i18nService = new I18nService(this.translateService);
|
||||||
|
|
||||||
// Change page title on navigation or language change, based on route data
|
this.router.events
|
||||||
const onNavigationEnd = this.router.events.pipe(filter((event) => event instanceof NavigationEnd));
|
.pipe(
|
||||||
merge(this.translateService.onLangChange, onNavigationEnd)
|
filter((event) => event instanceof NavigationEnd),
|
||||||
.pipe(
|
map(() => {
|
||||||
map(() => {
|
let route = this.activatedRoute;
|
||||||
let route = this.activatedRoute;
|
while (route.firstChild) {
|
||||||
while (route.firstChild) {
|
route = route.firstChild;
|
||||||
route = route.firstChild;
|
}
|
||||||
}
|
return route;
|
||||||
return route;
|
}),
|
||||||
}),
|
switchMap((route) => route.data.pipe(catchError(() => of({ title: 'APP_NAME' })))),
|
||||||
filter((route) => route.outlet === 'primary'),
|
switchMap((data) => {
|
||||||
mergeMap((route) => route.data)
|
const rawTitle = data['title'] || 'APP_NAME';
|
||||||
)
|
return this.translateService.get(`labels.titles.${rawTitle}`);
|
||||||
.subscribe((event) => {
|
})
|
||||||
let title = event['title'];
|
)
|
||||||
if (!title) {
|
.subscribe((translatedTitle) => {
|
||||||
title = 'APP_NAME';
|
this.titleService.setTitle(translatedTitle);
|
||||||
}
|
});
|
||||||
this.i18nService.translate(title).subscribe((titleTranslated: any) => {
|
|
||||||
this.titleService.setTitle(titleTranslated);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stores top 100 user activites as local storage object.
|
|
||||||
let activities: string[] = [];
|
|
||||||
if (localStorage.getItem('mifosXLocation')) {
|
|
||||||
const activitiesArray: string[] = JSON.parse(localStorage.getItem('mifosXLocation'));
|
|
||||||
const length = activitiesArray.length;
|
|
||||||
activities = length > 100 ? activitiesArray.slice(length - 100) : activitiesArray;
|
|
||||||
}
|
|
||||||
// Store route URLs array in local storage on navigation end.
|
|
||||||
onNavigationEnd.subscribe(() => {
|
|
||||||
activities.push(this.router.url);
|
|
||||||
localStorage.setItem('mifosXLocation', JSON.stringify(activities));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Setup alerts
|
|
||||||
this.alertService.alertEvent.subscribe((alertEvent: Alert) => {
|
this.alertService.alertEvent.subscribe((alertEvent: Alert) => {
|
||||||
this.snackBar.open(`${alertEvent.message}`, 'Close', {
|
this.snackBar.open(`${alertEvent.message}`, 'Close', {
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
horizontalPosition: 'right',
|
horizontalPosition: 'right',
|
||||||
verticalPosition: 'top'
|
verticalPosition: 'top',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.buttonConfig = new KeyboardShortcutsConfiguration();
|
this.buttonConfig = new KeyboardShortcutsConfiguration();
|
||||||
|
|
||||||
// initialize language and date format if they are null.
|
|
||||||
if (!localStorage.getItem('mifosXLanguage')) {
|
|
||||||
this.settingsService.setDefaultLanguage();
|
|
||||||
}
|
|
||||||
if (!localStorage.getItem('mifosXDateFormat')) {
|
|
||||||
this.settingsService.setDateFormat('dd MMMM yyyy');
|
|
||||||
}
|
|
||||||
// Set default max date picker as Today
|
|
||||||
this.settingsService.setBusinessDate(this.dateUtils.formatDate(new Date(), SettingsService.businessDateFormat));
|
|
||||||
// Set the server list from the env var FINERACT_API_URLS
|
|
||||||
this.settingsService.setServers(environment.baseApiUrls.split(','));
|
|
||||||
// Set the Tenant Identifier(s) list from the env var
|
|
||||||
if (!localStorage.getItem('mifosXTenantIdentifier')) {
|
|
||||||
this.settingsService.setTenantIdentifier(environment.fineractPlatformTenantId || 'default');
|
|
||||||
}
|
|
||||||
this.settingsService.setTenantIdentifiers(environment.fineractPlatformTenantIds.split(','));
|
|
||||||
|
|
||||||
// Subscribe to session timeout If IdleTimeout is higher than 0 (zero)
|
|
||||||
if (environment.session.timeout.idleTimeout > 0) {
|
if (environment.session.timeout.idleTimeout > 0) {
|
||||||
this.idle.$onSessionTimeout.subscribe(() => {
|
this.idle.$onSessionTimeout.subscribe(() => {
|
||||||
if (this.authenticationService.getUserLoggedIn()) {
|
if (this.authenticationService.getUserLoggedIn()) {
|
||||||
this.alertService.alert({
|
this.alertService.alert({
|
||||||
type: 'Session timeout',
|
type: 'Session timeout',
|
||||||
message: this.translateService.instant('labels.text.Session timed out')
|
message: this.translateService.instant('labels.text.Session timed out'),
|
||||||
});
|
});
|
||||||
this.dialog.open(SessionTimeoutDialogComponent);
|
this.dialog.open(SessionTimeoutDialogComponent);
|
||||||
this.logout();
|
this.logout();
|
||||||
@@ -239,14 +143,13 @@ export class WebAppComponent implements OnInit {
|
|||||||
window.open('https://mifosforge.jira.com/wiki/spaces/docs/pages/52035622/User+Manual', '_blank');
|
window.open('https://mifosforge.jira.com/wiki/spaces/docs/pages/52035622/User+Manual', '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monitor all keyboard events and excute keyboard shortcuts
|
|
||||||
@HostListener('window:keydown', ['$event'])
|
@HostListener('window:keydown', ['$event'])
|
||||||
onKeydownHandler(event: KeyboardEvent) {
|
onKeydownHandler(event: KeyboardEvent) {
|
||||||
const routeD = this.buttonConfig.buttonCombinations.find(
|
const routeD = this.buttonConfig.buttonCombinations.find(
|
||||||
(x) =>
|
(x) =>
|
||||||
x.ctrlKey === event.ctrlKey && x.shiftKey === event.shiftKey && x.altKey === event.altKey && x.key === event.key
|
x.ctrlKey === event.ctrlKey && x.shiftKey === event.shiftKey && x.altKey === event.altKey && x.key === event.key
|
||||||
);
|
);
|
||||||
if (!(routeD === undefined)) {
|
if (routeD) {
|
||||||
switch (routeD.id) {
|
switch (routeD.id) {
|
||||||
case 'logout':
|
case 'logout':
|
||||||
this.logout();
|
this.logout();
|
||||||
@@ -255,25 +158,15 @@ export class WebAppComponent implements OnInit {
|
|||||||
this.help();
|
this.help();
|
||||||
break;
|
break;
|
||||||
case 'runReport':
|
case 'runReport':
|
||||||
document.getElementById('runReport').click();
|
document.getElementById('runReport')?.click();
|
||||||
break;
|
break;
|
||||||
case 'cancel':
|
case 'cancel':
|
||||||
const cancelButtons = document.querySelectorAll('button');
|
const cancelButtons = Array.from(document.querySelectorAll('button')).filter((el) => el.textContent?.trim() === 'Cancel');
|
||||||
const filteredcancelButtons = Array.prototype.filter.call(cancelButtons, function (el: any) {
|
cancelButtons[0]?.click();
|
||||||
return el.textContent.trim() === 'Cancel';
|
|
||||||
});
|
|
||||||
if (filteredcancelButtons.length > 0) {
|
|
||||||
filteredcancelButtons[0].click();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'submit':
|
case 'submit':
|
||||||
const submitButton = document.querySelectorAll('button');
|
const submitButtons = Array.from(document.querySelectorAll('button')).filter((el) => el.textContent?.trim() === 'Submit');
|
||||||
const filteredSubmitButton = Array.prototype.filter.call(submitButton, function (el: any) {
|
submitButtons[0]?.click();
|
||||||
return el.textContent.trim() === 'Submit';
|
|
||||||
});
|
|
||||||
if (filteredSubmitButton.length > 0) {
|
|
||||||
filteredSubmitButton[0].click();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.router.navigate([routeD.route], { relativeTo: this.activatedRoute });
|
this.router.navigate([routeD.route], { relativeTo: this.activatedRoute });
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
export default {
|
export default {
|
||||||
'mifos_x': {
|
'mifos_x': {
|
||||||
'version': '250330',
|
'version': '250403',
|
||||||
'hash': 'f4f480ac'
|
'hash': '66449454'
|
||||||
},
|
},
|
||||||
'allow_switching_backend_instance': true
|
'allow_switching_backend_instance': true
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user