Skip to content

Commit 3732f16

Browse files
thetaPCbrandyscarneyShaneK
authored
feat(angular): update to Angular 20 (#1828)
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Co-authored-by: ShaneK <shane@shanessite.net>
1 parent 778ff0d commit 3732f16

File tree

15 files changed

+8849
-9736
lines changed

15 files changed

+8849
-9736
lines changed

.eslintrc.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
}
4343
],
4444
"@angular-eslint/component-class-suffix": "off",
45-
"@angular-eslint/no-host-metadata-property": "error",
4645
"@angular-eslint/no-inputs-metadata-property": "error",
4746
"@angular-eslint/no-output-rename": "error",
4847
"@angular-eslint/use-lifecycle-interface": "error",

package-lock.json

Lines changed: 8749 additions & 9637 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
},
1919
"private": true,
2020
"dependencies": {
21-
"@angular/common": "^19.1.6",
22-
"@angular/core": "^19.1.6",
23-
"@angular/forms": "^19.1.6",
24-
"@angular/platform-browser": "^19.1.6",
25-
"@angular/platform-browser-dynamic": "^19.1.6",
26-
"@angular/pwa": "^19.1.7",
27-
"@angular/router": "^19.1.6",
28-
"@angular/service-worker": "^19.1.6",
21+
"@angular/common": "^20.0.0",
22+
"@angular/core": "^20.0.0",
23+
"@angular/forms": "^20.0.0",
24+
"@angular/platform-browser": "^20.0.0",
25+
"@angular/platform-browser-dynamic": "^20.0.0",
26+
"@angular/pwa": "^20.0.0",
27+
"@angular/router": "^20.0.0",
28+
"@angular/service-worker": "^20.0.0",
2929
"@awesome-cordova-plugins/core": "6.3.0",
3030
"@awesome-cordova-plugins/in-app-browser": "6.3.0",
3131
"@capacitor/android": "^6.0.0",
@@ -51,49 +51,48 @@
5151
},
5252
"devDependencies": {
5353
"@angular-devkit/architect": "^0.1901.7",
54-
"@angular-devkit/build-angular": "^19.1.7",
55-
"@angular-devkit/core": "^19.1.7",
56-
"@angular-devkit/schematics": "^19.1.0",
57-
"@angular-eslint/builder": "^18.0.0",
58-
"@angular-eslint/eslint-plugin": "^18.0.0",
59-
"@angular-eslint/eslint-plugin-template": "^18.0.0",
60-
"@angular-eslint/schematics": "^19.1.0",
61-
"@angular-eslint/template-parser": "^18.0.0",
62-
"@angular/cli": "^19.1.7",
63-
"@angular/compiler": "^19.1.6",
64-
"@angular/compiler-cli": "^19.1.6",
65-
"@angular/language-service": "^19.1.6",
54+
"@angular-devkit/build-angular": "^20.0.0",
55+
"@angular-devkit/core": "^20.0.0",
56+
"@angular-devkit/schematics": "^20.0.0",
57+
"@angular-eslint/builder": "^20.0.0",
58+
"@angular-eslint/eslint-plugin": "^20.0.0",
59+
"@angular-eslint/eslint-plugin-template": "^20.0.0",
60+
"@angular-eslint/schematics": "^20.0.0",
61+
"@angular-eslint/template-parser": "^20.0.0",
62+
"@angular/cli": "^20.0.0",
63+
"@angular/compiler": "^20.0.0",
64+
"@angular/compiler-cli": "^20.0.0",
65+
"@angular/language-service": "^20.0.0",
6666
"@capacitor/cli": "^6.0.0",
6767
"@ionic/angular-toolkit": "12.1.1",
6868
"@ionic/cli": "7.2.0",
6969
"@ionic/storage": "^3.0.6",
70-
"@types/jasmine": "~3.6.0",
70+
"@types/jasmine": "~5.1.0",
7171
"@types/leaflet": "^1.9.17",
7272
"@types/node": "^12.11.1",
7373
"@typescript-eslint/eslint-plugin": "^8.24.1",
7474
"@typescript-eslint/parser": "^8.24.1",
7575
"cordova-res": "0.15.4",
7676
"eslint": "^9.20.0",
77-
"jasmine-core": "~3.8.0",
77+
"jasmine-core": "~5.7.0",
7878
"jasmine-spec-reporter": "~5.0.0",
79-
"karma": "~6.3.7",
80-
"karma-chrome-launcher": "~3.1.0",
79+
"karma": "~6.4.0",
80+
"karma-chrome-launcher": "~3.2.0",
8181
"karma-coverage-istanbul-reporter": "~3.0.2",
82-
"karma-jasmine": "~4.0.0",
83-
"karma-jasmine-html-reporter": "^1.5.0",
82+
"karma-jasmine": "~5.1.0",
83+
"karma-jasmine-html-reporter": "~2.1.0",
8484
"puppeteer": "^11.0.0",
8585
"stylelint": "15.3.0",
8686
"stylelint-config-standard-scss": "7.0.1",
8787
"stylelint-order": "6.0.3",
8888
"ts-node": "8.5.0",
89-
"typescript": "~5.7.3"
89+
"typescript": "~5.8.0"
9090
},
9191
"browserslist": [
92-
"Chrome >=79",
93-
"ChromeAndroid >=79",
94-
"Firefox >=70",
95-
"Edge >=79",
96-
"Safari >=14",
97-
"iOS >=14"
92+
"Chrome >=107",
93+
"Firefox >=106",
94+
"Edge >=107",
95+
"Safari >=16.1",
96+
"iOS >=16.1"
9897
]
9998
}

src/app/app.component.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ describe('AppComponent', () => {
1414

1515
beforeEach(async () => {
1616
menuSpy = jasmine.createSpyObj('MenuController', ['toggle', 'enable']);
17-
userDataSpy = jasmine.createSpyObj('UserData', ['isLoggedIn', 'logout']);
17+
userDataSpy = jasmine.createSpyObj('UserService', ['isLoggedIn', 'logout']);
18+
userDataSpy.isLoggedIn.and.returnValue(Promise.resolve(false));
1819
swUpdateSpy = jasmine.createSpyObj('SwUpdate', [
1920
'available',
2021
'activateUpdate',
2122
]);
23+
swUpdateSpy.versionUpdates = {
24+
subscribe: jasmine.createSpy('subscribe').and.returnValue({ unsubscribe: () => {} })
25+
};
2226

2327
await TestBed.configureTestingModule({
2428
imports: [AppComponent],

src/app/app.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export class AppComponent implements OnInit {
100100
dark = false;
101101

102102
constructor() {
103-
this.initializeApp();
104103
addIcons({
105104
calendarOutline,
106105
peopleOutline,
@@ -117,6 +116,7 @@ export class AppComponent implements OnInit {
117116
}
118117

119118
async ngOnInit() {
119+
this.initializeApp();
120120
await this.storage.create();
121121
this.checkLoginStatus();
122122
this.listenForLoginEvents();

src/app/pages/map/map.ts

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { DOCUMENT } from '@angular/common';
1+
22
import {
33
AfterViewInit,
44
Component,
5+
DOCUMENT,
6+
DestroyRef,
57
ElementRef,
6-
OnDestroy,
78
ViewChild,
8-
inject,
9+
inject
910
} from '@angular/core';
11+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
1012
import {
1113
IonButtons,
1214
IonContent,
@@ -15,10 +17,10 @@ import {
1517
IonTitle,
1618
IonToolbar,
1719
} from '@ionic/angular/standalone';
18-
import { LocationService } from '../../providers/location.service';
19-
import { Location } from '../../interfaces/conference.interfaces';
2020
import * as L from 'leaflet';
21-
import { Subscription, firstValueFrom } from 'rxjs';
21+
import { firstValueFrom } from 'rxjs';
22+
import { Location } from '../../interfaces/conference.interfaces';
23+
import { LocationService } from '../../providers/location.service';
2224

2325
@Component({
2426
selector: 'page-map',
@@ -47,37 +49,39 @@ import { Subscription, firstValueFrom } from 'rxjs';
4749
],
4850
standalone: true,
4951
})
50-
export class MapPage implements AfterViewInit, OnDestroy {
52+
export class MapPage implements AfterViewInit {
5153
private doc = inject(DOCUMENT);
5254
private locationService = inject(LocationService);
55+
private destroyRef = inject(DestroyRef);
5356
private map: L.Map | null = null;
5457
private markers: L.Marker[] = [];
55-
private subscription: Subscription;
5658

5759
@ViewChild('mapCanvas', { static: true }) mapElement!: ElementRef;
5860

5961
ngAfterViewInit() {
60-
this.locationService.loadLocations().subscribe(() => {
61-
this.initializeMap();
62-
});
62+
this.locationService.loadLocations()
63+
.pipe(takeUntilDestroyed(this.destroyRef))
64+
.subscribe(() => {
65+
this.initializeMap();
66+
});
6367

6468
// Subscribe to location changes
65-
this.subscription = this.locationService.getLocations().subscribe(() => {
69+
this.locationService.getLocations()
70+
.pipe(takeUntilDestroyed(this.destroyRef))
71+
.subscribe(() => {
72+
if (this.map) {
73+
this.initializeMap();
74+
}
75+
});
76+
77+
// Clean up map on destroy
78+
this.destroyRef.onDestroy(() => {
6679
if (this.map) {
67-
this.initializeMap();
80+
this.map.remove();
6881
}
6982
});
7083
}
7184

72-
ngOnDestroy() {
73-
if (this.subscription) {
74-
this.subscription.unsubscribe();
75-
}
76-
if (this.map) {
77-
this.map.remove();
78-
}
79-
}
80-
8185
private async initializeMap() {
8286
const mapEle = this.mapElement.nativeElement;
8387

src/app/pages/schedule/schedule.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, OnInit, ViewChild } from '@angular/core';
1+
import { Component, OnInit, ViewChild, inject } from '@angular/core';
22
import { Router, RouterLink } from '@angular/router';
33

44
import { addIcons } from 'ionicons';
@@ -89,6 +89,16 @@ import { ScheduleFilterPage } from '../schedule-filter/schedule-filter';
8989
]
9090
})
9191
export class SchedulePage implements OnInit {
92+
alertCtrl = inject(AlertController);
93+
confService = inject(ConferenceService);
94+
loadingCtrl = inject(LoadingController);
95+
modalCtrl = inject(ModalController);
96+
router = inject(Router);
97+
routerOutlet = inject(IonRouterOutlet);
98+
toastCtrl = inject(ToastController);
99+
user = inject(UserService);
100+
config = inject(Config);
101+
92102
// Gets a reference to the list element
93103
@ViewChild('scheduleList', { static: true }) scheduleList: IonList;
94104

@@ -102,17 +112,7 @@ export class SchedulePage implements OnInit {
102112
confDate: string;
103113
showSearchbar: boolean;
104114

105-
constructor(
106-
public alertCtrl: AlertController,
107-
public confService: ConferenceService,
108-
public loadingCtrl: LoadingController,
109-
public modalCtrl: ModalController,
110-
public router: Router,
111-
public routerOutlet: IonRouterOutlet,
112-
public toastCtrl: ToastController,
113-
public user: UserService,
114-
public config: Config
115-
) {
115+
constructor() {
116116
addIcons({
117117
search,
118118
options,
@@ -126,7 +126,6 @@ export class SchedulePage implements OnInit {
126126

127127
ngOnInit() {
128128
this.updateSchedule();
129-
130129
this.ios = this.config.get('mode') === 'ios';
131130
}
132131

src/app/pages/signup/signup.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component } from '@angular/core';
1+
import { Component, inject } from '@angular/core';
22
import { FormsModule, NgForm } from '@angular/forms';
33
import { Router } from '@angular/router';
44
import {
@@ -37,11 +37,12 @@ import { UserOptions } from '../../interfaces/user-options';
3737
]
3838
})
3939
export class SignupPage {
40+
router = inject(Router);
41+
userService = inject(UserService);
42+
4043
signup: UserOptions = { username: '', password: '' };
4144
submitted = false;
4245

43-
constructor(public router: Router, public userService: UserService) {}
44-
4546
onSignup(form: NgForm) {
4647
this.submitted = true;
4748

src/app/pages/support/support.html

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,7 @@
99

1010
<ion-content>
1111
<div class="support-logo">
12-
<img
13-
ngSrc="assets/img/appicon.svg"
14-
alt="Ionic Logo"
15-
width="200"
16-
height="200"
17-
priority
18-
/>
12+
<img src="assets/img/appicon.svg" alt="Ionic Logo" />
1913
</div>
2014

2115
<div class="support-form">

src/app/pages/support/support.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.support-logo {
22
min-height: 200px;
33

4+
padding: 20px 0;
5+
46
text-align: center;
57
}
68

0 commit comments

Comments
 (0)