Skip to content

Commit aab891a

Browse files
committed
refactor: move app-initializers into their respective modules
1 parent 39e9649 commit aab891a

File tree

10 files changed

+170
-119
lines changed

10 files changed

+170
-119
lines changed

src/app/app-initializers.ts

Lines changed: 0 additions & 72 deletions
This file was deleted.

src/app/app.module.ts

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,8 @@
1717

1818
import { BrowserModule } from "@angular/platform-browser";
1919
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
20-
import {
21-
APP_INITIALIZER,
22-
ErrorHandler,
23-
Inject,
24-
LOCALE_ID,
25-
NgModule,
26-
} from "@angular/core";
20+
import { LOCALE_ID, NgModule } from "@angular/core";
2721
import { HttpClientModule } from "@angular/common/http";
28-
import * as Sentry from "@sentry/angular";
2922

3023
import { AppComponent } from "./app.component";
3124
import { allRoutes } from "./app.routing";
@@ -40,8 +33,6 @@ import {
4033
import { environment } from "../environments/environment";
4134
import { AnalyticsService } from "./core/analytics/analytics.service";
4235
import { ConfigurableEnumModule } from "./core/basic-datatypes/configurable-enum/configurable-enum.module";
43-
import { MatPaginatorIntl } from "@angular/material/paginator";
44-
import { TranslatableMatPaginator } from "./core/language/TranslatableMatPaginator";
4536
import { FaIconLibrary } from "@fortawesome/angular-fontawesome";
4637
import { fas } from "@fortawesome/free-solid-svg-icons";
4738
import { far } from "@fortawesome/free-regular-svg-icons";
@@ -81,20 +72,20 @@ import { HistoricalDataModule } from "./features/historical-data/historical-data
8172
import { MatchingEntitiesModule } from "./features/matching-entities/matching-entities.module";
8273
import { ProgressDashboardWidgetModule } from "./features/dashboard-widgets/progress-dashboard-widget/progress-dashboard-widget.module";
8374
import { ReportingModule } from "./features/reporting/reporting.module";
84-
import { Router, RouterModule } from "@angular/router";
75+
import { RouterModule } from "@angular/router";
8576
import { TodosModule } from "./features/todos/todos.module";
86-
import moment from "moment";
87-
import { getLocaleFirstDayOfWeek } from "@angular/common";
8877
import { waitForChangeTo } from "./core/session/session-states/session-utils";
8978
import { LoginState } from "./core/session/session-states/login-state.enum";
90-
import { appInitializers } from "./app-initializers";
79+
import { APP_INITIALIZER_PROPAGATE_CONFIG_UPDATES } from "./core/config/config.app-initializer";
9180
import { ImportModule } from "./core/import/import.module";
9281
import { ShortcutDashboardWidgetModule } from "./features/dashboard-widgets/shortcut-dashboard-widget/shortcut-dashboard-widget.module";
9382
import { EntityCountDashboardWidgetModule } from "./features/dashboard-widgets/entity-count-dashboard-widget/entity-count-dashboard-widget.module";
9483
import { BirthdayDashboardWidgetModule } from "./features/dashboard-widgets/birthday-dashboard-widget/birthday-dashboard-widget.module";
9584
import { MarkdownPageModule } from "./features/markdown-page/markdown-page.module";
9685
import { LoginStateSubject } from "./core/session/session-type";
9786
import { AdminModule } from "./core/admin/admin.module";
87+
import { Logging } from "./core/logging/logging.service";
88+
import { APP_INITIALIZER_DEMO_DATA } from "./core/demo-data/demo-data.app-initializer";
9889

9990
/**
10091
* Main entry point of the application.
@@ -147,23 +138,7 @@ import { AdminModule } from "./core/admin/admin.module";
147138
MatDialogModule,
148139
],
149140
providers: [
150-
/* Sentry setup */
151-
{
152-
provide: ErrorHandler,
153-
useValue: Sentry.createErrorHandler(),
154-
},
155-
{
156-
provide: Sentry.TraceService,
157-
deps: [Router],
158-
},
159-
{
160-
provide: APP_INITIALIZER,
161-
useFactory: () => () => {},
162-
deps: [Sentry.TraceService],
163-
multi: true,
164-
},
165-
166-
{ provide: MatPaginatorIntl, useValue: TranslatableMatPaginator() },
141+
...Logging.getAngularTracingProviders(),
167142
{ provide: ComponentRegistry, useValue: componentRegistry },
168143
{ provide: EntityRegistry, useValue: entityRegistry },
169144
{ provide: WINDOW_TOKEN, useValue: window },
@@ -190,17 +165,13 @@ import { AdminModule } from "./core/admin/admin.module";
190165
}),
191166
deps: [LoginStateSubject],
192167
},
193-
appInitializers,
168+
APP_INITIALIZER_PROPAGATE_CONFIG_UPDATES,
169+
APP_INITIALIZER_DEMO_DATA,
194170
],
195171
bootstrap: [AppComponent],
196172
})
197173
export class AppModule {
198-
constructor(icons: FaIconLibrary, @Inject(LOCALE_ID) locale: string) {
174+
constructor(icons: FaIconLibrary) {
199175
icons.addIconPacks(fas, far);
200-
moment.updateLocale(moment.locale(), {
201-
week: {
202-
dow: getLocaleFirstDayOfWeek(locale),
203-
},
204-
});
205176
}
206177
}

src/app/core/analytics/analytics.service.spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ import {
99
import { RouterTestingModule } from "@angular/router/testing";
1010
import { ConfigService } from "../config/config.service";
1111
import { UsageAnalyticsConfig } from "./usage-analytics-config";
12-
import { Subject } from "rxjs";
12+
import { BehaviorSubject, Subject } from "rxjs";
1313
import { Config } from "../config/config";
1414
import { SiteSettingsService } from "../site-settings/site-settings.service";
15+
import { LoginStateSubject } from "../session/session-type";
16+
import { SessionSubject } from "../session/auth/session-info";
17+
import { LoginState } from "../session/session-states/login-state.enum";
1518

1619
describe("AnalyticsService", () => {
1720
let service: AnalyticsService;
@@ -47,6 +50,11 @@ describe("AnalyticsService", () => {
4750
provide: SiteSettingsService,
4851
useValue: { siteName: siteNameSubject },
4952
},
53+
{
54+
provide: LoginStateSubject,
55+
useValue: new BehaviorSubject(LoginState.LOGGED_IN),
56+
},
57+
{ provide: SessionSubject, useValue: new BehaviorSubject(undefined) },
5058
],
5159
});
5260
service = TestBed.inject(AnalyticsService);

src/app/core/analytics/analytics.service.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import {
77
} from "./usage-analytics-config";
88
import { Angulartics2, Angulartics2Matomo } from "angulartics2";
99
import md5 from "md5";
10+
import { LoginState } from "../session/session-states/login-state.enum";
11+
import { LoginStateSubject } from "../session/session-type";
12+
import { SessionSubject } from "../session/auth/session-info";
1013

1114
/**
1215
* Track usage analytics data and report it to a backend server like Matomo.
@@ -23,7 +26,25 @@ export class AnalyticsService {
2326
private angulartics2: Angulartics2,
2427
private angulartics2Matomo: Angulartics2Matomo,
2528
private configService: ConfigService,
26-
) {}
29+
loginState: LoginStateSubject,
30+
private sessionInfo: SessionSubject,
31+
) {
32+
if (environment.production) {
33+
this.init();
34+
}
35+
36+
// update the user context for remote error logging and tracking and load config initially
37+
loginState.subscribe((s: LoginState) => this.updateSessionInfo(s));
38+
}
39+
40+
private updateSessionInfo(newState: LoginState): void {
41+
if (newState === LoginState.LOGGED_IN) {
42+
const username = this.sessionInfo.value?.name;
43+
this.setUser(username);
44+
} else {
45+
this.setUser(undefined);
46+
}
47+
}
2748

2849
/**
2950
* Sets a unique user hash which is always for the same user but does not expose the username.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { APP_INITIALIZER } from "@angular/core";
2+
import { ConfigService } from "./config.service";
3+
import { RouterService } from "./dynamic-routing/router.service";
4+
import { EntityConfigService } from "../entity/entity-config.service";
5+
import { Router } from "@angular/router";
6+
7+
export const APP_INITIALIZER_PROPAGATE_CONFIG_UPDATES = {
8+
provide: APP_INITIALIZER,
9+
useFactory:
10+
(
11+
configService: ConfigService,
12+
routerService: RouterService,
13+
entityConfigService: EntityConfigService,
14+
router: Router,
15+
) =>
16+
async () => {
17+
// Re-trigger services that depend on the config when something changes
18+
configService.configUpdates.subscribe(() => {
19+
routerService.initRouting();
20+
entityConfigService.setupEntitiesFromConfig();
21+
const url = location.href.replace(location.origin, "");
22+
router.navigateByUrl(url, { skipLocationChange: true });
23+
});
24+
},
25+
deps: [ConfigService, RouterService, EntityConfigService, Router],
26+
multi: true,
27+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {
2+
APP_INITIALIZER,
3+
Injector,
4+
ɵcreateInjector as createInjector,
5+
} from "@angular/core";
6+
import { environment } from "../../../environments/environment";
7+
8+
/**
9+
* Provide this in the app module to run the demo data generation with lazy-loading
10+
* (no download of module code if not in demo mode).
11+
*/
12+
export const APP_INITIALIZER_DEMO_DATA = {
13+
provide: APP_INITIALIZER,
14+
useFactory: (injector: Injector) => async () => {
15+
if (environment.demo_mode) {
16+
const m = await import("./demo-data.module");
17+
await createInjector(m.DemoDataModule, injector)
18+
.get(m.DemoDataModule)
19+
.publishDemoData();
20+
}
21+
},
22+
deps: [Injector],
23+
multi: true,
24+
};

src/app/core/import/import-entity-type/import-entity-type.stories.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ import { applicationConfig, Meta, StoryFn } from "@storybook/angular";
22
import { StorybookBaseModule } from "../../../utils/storybook-base.module";
33
import { ImportEntityTypeComponent } from "./import-entity-type.component";
44
import { importProvidersFrom } from "@angular/core";
5-
import { appInitializers } from "../../../app-initializers";
5+
import { APP_INITIALIZER_PROPAGATE_CONFIG_UPDATES } from "../../config/config.app-initializer";
66

77
export default {
88
title: "Features/Import/2 Select Entity Type",
99
component: ImportEntityTypeComponent,
1010
decorators: [
1111
applicationConfig({
12-
providers: [importProvidersFrom(StorybookBaseModule), appInitializers],
12+
providers: [
13+
importProvidersFrom(StorybookBaseModule),
14+
APP_INITIALIZER_PROPAGATE_CONFIG_UPDATES,
15+
],
1316
}),
1417
],
1518
} as Meta;

src/app/core/language/language.module.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
import { NgModule } from "@angular/core";
1+
import { Inject, LOCALE_ID, NgModule } from "@angular/core";
22
import { LanguageService } from "./language.service";
33
import { HTTP_INTERCEPTORS } from "@angular/common/http";
44
import { AcceptLanguageInterceptor } from "./accept-language.interceptor";
5+
import moment from "moment/moment";
6+
import { getLocaleFirstDayOfWeek } from "@angular/common";
7+
import { MatPaginatorIntl } from "@angular/material/paginator";
8+
import { TranslatableMatPaginator } from "./TranslatableMatPaginator";
59

610
/**
711
* Module that aids in the management and choice of translations/languages
@@ -19,10 +23,20 @@ import { AcceptLanguageInterceptor } from "./accept-language.interceptor";
1923
useClass: AcceptLanguageInterceptor,
2024
multi: true,
2125
},
26+
{ provide: MatPaginatorIntl, useValue: TranslatableMatPaginator() },
2227
],
2328
})
2429
export class LanguageModule {
25-
constructor(translationService: LanguageService) {
30+
constructor(
31+
translationService: LanguageService,
32+
@Inject(LOCALE_ID) locale: string,
33+
) {
2634
translationService.initDefaultLanguage();
35+
36+
moment.updateLocale(moment.locale(), {
37+
week: {
38+
dow: getLocaleFirstDayOfWeek(locale),
39+
},
40+
});
2741
}
2842
}

0 commit comments

Comments
 (0)