Upgrading to Angular 20:

Replaced checked in package-lock.json by regenerated one.
Ran ng update @angular/core@20 @angular/cli@20
Ran npm install @angular-builders/jest@^20.0.0 @fortawesome/angular-fontawesome@^3.0.0 @swimlane/ngx-graph@^11
Ran npm install ngx-mat-select-search@^8.0.2.
Ran ng update @angular/material@20.
Updated all eslint and typescript to the latest versions.
Removed @angular-devkit/schematics.
Updated fontawesome.
Updated rxjs and tslib.
Moved required node version from 16 to 20.
Updated jest-preset-angular.
Set preserveWhitespaces to false.
Corrected two type declarations in two typescript files to make ng serve run without errors.
Removed unused angular-devkit/schematics from view-user.component.ts .
Updated list of supported browsers.
Upgraded prettier.
Ran prettier . --write the first time.
Ran prettier . --write the second time.
Ran ng generate @angular/core:inject with defaults, excepted a handful of files.
Fixed remaining eslint problems.
Added dist directory to ignores in eslint.config.js.
Let prettier fix formatting, almost everything is just line breaks.
Made htmlhint ignore @if and @for Angular constructs.
Updated node version in Github workflow to 22.12.0 (build.yml).
Updated .env.ts.
Updated Angular datetime format strings from YYYY-MM-DD to yyyy-MM-dd.
Merged changes from dev into angular20 branch.
This commit is contained in:
Felix van Hove
2025-12-08 11:01:01 +01:00
parent f1b4ec2cf2
commit 7fd1486c08
1516 changed files with 39367 additions and 36037 deletions
@@ -1,15 +1,27 @@
<nav class="breadcrumb-wrapper">
<ul class="breadcrumb">
<span #breadcrumb class="breadcrumb-title">{{ getTranslate(breadcrumbs[breadcrumbs?.length - 1].label) }}</span>
<span *ngIf="breadcrumbs.length - 1 !== 0" class="separator">
<li *ngFor="let breadcrumb of breadcrumbs; let last = last" class="breadcrumb-label">
<span *ngIf="!last" class="breadcrumb-link">
<a *ngIf="breadcrumb.url" [routerLink]="breadcrumb.url">{{ getTranslate(breadcrumb.label) }}</a>
<span *ngIf="!breadcrumb.url">{{ getTranslate(breadcrumb.label) }}</span>
</span>
<span *ngIf="last">{{ getTranslate(breadcrumb.label) }}</span>
</li>
</span>
@if (breadcrumbs.length - 1 !== 0) {
<span class="separator">
@for (breadcrumb of breadcrumbs; track breadcrumb; let last = $last) {
<li class="breadcrumb-label">
@if (!last) {
<span class="breadcrumb-link">
@if (breadcrumb.url) {
<a [routerLink]="breadcrumb.url">{{ getTranslate(breadcrumb.label) }}</a>
}
@if (!breadcrumb.url) {
<span>{{ getTranslate(breadcrumb.label) }}</span>
}
</span>
}
@if (last) {
<span>{{ getTranslate(breadcrumb.label) }}</span>
}
</li>
}
</span>
}
</ul>
</nav>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd, Data, RouterLink } from '@angular/router';
/** rxjs Imports */
@@ -55,6 +55,12 @@ const routeAddBreadcrumbLink = 'addBreadcrumbLink';
]
})
export class BreadcrumbComponent implements AfterViewInit {
private activatedRoute = inject(ActivatedRoute);
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
private translateService = inject(TranslateService);
/** Array of breadcrumbs. */
breadcrumbs: Breadcrumb[];
/* Reference of breadcrumb */
@@ -69,13 +75,7 @@ export class BreadcrumbComponent implements AfterViewInit {
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private activatedRoute: ActivatedRoute,
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService,
private translateService: TranslateService
) {
constructor() {
this.generateBreadcrumbs();
}
+5 -3
View File
@@ -20,9 +20,11 @@
<!-- Toolbar -->
<mifosx-toolbar [sidenav]="sidenav" (collapse)="toggleCollapse($event)"></mifosx-toolbar>
<!-- Progress Bar -->
<div *ngIf="progressBarMode !== 'none'">
<div class="loading"></div>
</div>
@if (progressBarMode !== 'none') {
<div>
<div class="loading"></div>
</div>
}
<!-- Breadcrumb -->
<mifosx-breadcrumb></mifosx-breadcrumb>
+6 -13
View File
@@ -1,6 +1,6 @@
/** Angular Imports */
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { ChangeDetectorRef, Component, OnDestroy, OnInit, inject } from '@angular/core';
/** rxjs Imports */
import { Observable, Subscription } from 'rxjs';
@@ -9,7 +9,7 @@ import { map } from 'rxjs/operators';
/** Custom Services */
import { ProgressBarService } from '../progress-bar/progress-bar.service';
import { MatSidenavContainer, MatSidenav, MatSidenavContent } from '@angular/material/sidenav';
import { NgClass, NgIf, AsyncPipe } from '@angular/common';
import { NgClass, AsyncPipe } from '@angular/common';
import { SidenavComponent } from './sidenav/sidenav.component';
import { ToolbarComponent } from './toolbar/toolbar.component';
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
@@ -39,6 +39,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ShellComponent implements OnInit, OnDestroy {
private breakpointObserver = inject(BreakpointObserver);
private progressBarService = inject(ProgressBarService);
private cdr = inject(ChangeDetectorRef);
/** Subscription to breakpoint observer for handset. */
isHandset$: Observable<boolean> = this.breakpointObserver
.observe(Breakpoints.Handset)
@@ -50,17 +54,6 @@ export class ShellComponent implements OnInit, OnDestroy {
/** Subscription to progress bar. */
progressBar$: Subscription;
/**
* @param {BreakpointObserver} breakpointObserver Breakpoint Observer to detect screen size.
* @param {ProgressBarService} progressBarService Progress Bar Service.
* @param {ChangeDetectorRef} cdr Change Detector Ref.
*/
constructor(
private breakpointObserver: BreakpointObserver,
private progressBarService: ProgressBarService,
private cdr: ChangeDetectorRef
) {}
/**
* Subscribes to progress bar to update its mode.
*/
@@ -40,16 +40,18 @@
</div>
</div>
<div class="icon-menu">
<div class="icon-menu-item" *ngFor="let activity of mappedActivities">
<button
mat-raised-button
[matTooltipPosition]="tooltipPosition"
[matTooltip]="activity.toolTip"
[routerLink]="[activity.path]"
>
<fa-icon [icon]="activity.icon" size="lg"></fa-icon>
</button>
</div>
@for (activity of mappedActivities; track activity) {
<div class="icon-menu-item">
<button
mat-raised-button
[matTooltipPosition]="tooltipPosition"
[matTooltip]="activity.toolTip"
[routerLink]="[activity.path]"
>
<fa-icon [icon]="activity.icon" size="lg"></fa-icon>
</button>
</div>
}
</div>
<div class="nav-item-sep">
+11 -11
View File
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, Input, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, Input, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router, RouterLink, RouterLinkActive } from '@angular/router';
@@ -14,7 +14,7 @@ import { ConfigurationWizardService } from '../../../configuration-wizard/config
/** Custom Imports */
import { frequentActivities } from './frequent-activities';
import { SettingsService } from 'app/settings/settings.service';
import { NgClass, NgFor } from '@angular/common';
import { NgClass } from '@angular/common';
import { MatIconButton, MatButton } from '@angular/material/button';
import { MatTooltip } from '@angular/material/tooltip';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
@@ -50,6 +50,14 @@ import { AuthService } from 'app/zitadel/auth.service';
]
})
export class SidenavComponent implements OnInit, AfterViewInit {
private router = inject(Router);
dialog = inject(MatDialog);
private authenticationService = inject(AuthenticationService);
private settingsService = inject(SettingsService);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
private authService = inject(AuthService);
/** True if sidenav is in collapsed state. */
@Input() sidenavCollapsed: boolean;
/** Tooltip position */
@@ -80,15 +88,7 @@ export class SidenavComponent implements OnInit, AfterViewInit {
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private router: Router,
public dialog: MatDialog,
private authenticationService: AuthenticationService,
private settingsService: SettingsService,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService,
private authService: AuthService
) {
constructor() {
this.userActivity = JSON.parse(localStorage.getItem('mifosXLocation'));
}
@@ -1,25 +1,31 @@
<mat-toolbar class="layout-row" color="primary" id="mifosx-toolbar">
<button
mat-icon-button
*ngIf="!sidenavCollapsed"
(click)="toggleSidenav()"
matTooltip="{{ 'tooltips.Toggle Hide/Open' | translate }}"
tabindex="0"
>
<fa-icon icon="bars" size="lg"></fa-icon>
</button>
@if (!sidenavCollapsed) {
<button
mat-icon-button
(click)="toggleSidenav()"
matTooltip="{{ 'tooltips.Toggle Hide/Open' | translate }}"
tabindex="0"
>
<fa-icon icon="bars" size="lg"></fa-icon>
</button>
}
<button
mat-icon-button
*ngIf="sidenav.opened"
(click)="toggleSidenavCollapse()"
matTooltip="{{ 'tooltips.Toggle Collapse' | translate }}"
class="hide-lt-md"
tabindex="0"
>
<fa-icon *ngIf="!sidenavCollapsed" icon="chevron-left"></fa-icon>
<fa-icon *ngIf="sidenavCollapsed" icon="chevron-right"></fa-icon>
</button>
@if (sidenav.opened) {
<button
mat-icon-button
(click)="toggleSidenavCollapse()"
matTooltip="{{ 'tooltips.Toggle Collapse' | translate }}"
class="hide-lt-md"
tabindex="0"
>
@if (!sidenavCollapsed) {
<fa-icon icon="chevron-left"></fa-icon>
}
@if (sidenavCollapsed) {
<fa-icon icon="chevron-right"></fa-icon>
}
</button>
}
<div class="tab-nav-bar">
<a
+11 -20
View File
@@ -10,7 +10,8 @@ import {
ElementRef,
TemplateRef,
AfterContentChecked,
ChangeDetectorRef
ChangeDetectorRef,
inject
} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSidenav } from '@angular/material/sidenav';
@@ -69,6 +70,15 @@ import { AuthService } from 'app/zitadel/auth.service';
]
})
export class ToolbarComponent implements OnInit, AfterViewInit, AfterContentChecked {
private breakpointObserver = inject(BreakpointObserver);
private router = inject(Router);
private authenticationService = inject(AuthenticationService);
private popoverService = inject(PopoverService);
private configurationWizardService = inject(ConfigurationWizardService);
private dialog = inject(MatDialog);
private changeDetector = inject(ChangeDetectorRef);
private authService = inject(AuthService);
/* Reference of institution */
@ViewChild('institution') institution: ElementRef<any>;
/* Template for popover on institution */
@@ -92,25 +102,6 @@ export class ToolbarComponent implements OnInit, AfterViewInit, AfterContentChec
/** Sidenav collapse event. */
@Output() collapse = new EventEmitter<boolean>();
/**
* @param {BreakpointObserver} breakpointObserver Breakpoint observer to detect screen size.
* @param {Router} router Router for navigation.
* @param {AuthenticationService} authenticationService Authentication service.
* @param {MatDialog} dialog MatDialog.
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private breakpointObserver: BreakpointObserver,
private router: Router,
private authenticationService: AuthenticationService,
private popoverService: PopoverService,
private configurationWizardService: ConfigurationWizardService,
private dialog: MatDialog,
private changeDetector: ChangeDetectorRef,
private authService: AuthService
) {}
/**
* Subscribes to breakpoint for handset.
*/