diff --git a/packages/stark-core/src/modules/session.ts b/packages/stark-core/src/modules/session.ts index 8a32fa7105..8018024f50 100644 --- a/packages/stark-core/src/modules/session.ts +++ b/packages/stark-core/src/modules/session.ts @@ -1,4 +1,5 @@ export * from "./session/actions"; +export * from "./session/components"; export * from "./session/entities"; export * from "./session/reducers"; export * from "./session/services"; diff --git a/packages/stark-ui/src/modules/session-ui/components.ts b/packages/stark-core/src/modules/session/components.ts similarity index 100% rename from packages/stark-ui/src/modules/session-ui/components.ts rename to packages/stark-core/src/modules/session/components.ts diff --git a/packages/stark-ui/src/modules/session-ui/components/app-container.component.html b/packages/stark-core/src/modules/session/components/app-container.component.html similarity index 100% rename from packages/stark-ui/src/modules/session-ui/components/app-container.component.html rename to packages/stark-core/src/modules/session/components/app-container.component.html diff --git a/packages/stark-ui/src/modules/session-ui/components/app-container.component.ts b/packages/stark-core/src/modules/session/components/app-container.component.ts similarity index 62% rename from packages/stark-ui/src/modules/session-ui/components/app-container.component.ts rename to packages/stark-core/src/modules/session/components/app-container.component.ts index 19b9023972..c4e9871012 100644 --- a/packages/stark-ui/src/modules/session-ui/components/app-container.component.ts +++ b/packages/stark-core/src/modules/session/components/app-container.component.ts @@ -1,22 +1,22 @@ import { Component, Inject, OnInit, ViewEncapsulation } from "@angular/core"; -import { - STARK_LOGGING_SERVICE, - STARK_ROUTING_SERVICE, - starkAppExitStateName, - starkAppInitStateName, - StarkLoggingService, - StarkRoutingService -} from "@nationalbankbelgium/stark-core"; +import { STARK_LOGGING_SERVICE, StarkLoggingService } from "../../logging/services"; +import { STARK_ROUTING_SERVICE, StarkRoutingService } from "../../routing/services"; +import { starkAppExitStateName, starkAppInitStateName } from "../routes"; /** * Name of the component */ const componentName: string = "stark-app-container"; +/** + * Component to coordinate the display of the init/exit states when the application starts or ends and hide the application content. + * For any other state it simply displays the application content hiding any init/exit state. + */ @Component({ selector: "stark-app-container", templateUrl: "./app-container.component.html", encapsulation: ViewEncapsulation.None, + // tslint:disable-next-line: use-host-property-decorator host: { class: componentName } @@ -40,7 +40,7 @@ export class StarkAppContainerComponent implements OnInit { } /** - * Check if the current state is a "session-ui" state (with "starkAppInit" or "starkAppExit" as parent state name) + * Check if the current state is an init or exit state (with "starkAppInit" or "starkAppExit" as parent state name) */ public isAppInitOrExitState(): boolean { return ( diff --git a/packages/stark-core/src/modules/session/routes.ts b/packages/stark-core/src/modules/session/routes.ts index 761c646af2..16d655cb38 100644 --- a/packages/stark-core/src/modules/session/routes.ts +++ b/packages/stark-core/src/modules/session/routes.ts @@ -1,3 +1,10 @@ +import { Location } from "@angular/common"; +import { Transition, StateDeclaration, LazyLoadResult, RawParams } from "@uirouter/core"; +import { loadNgModule, Ng2StateDeclaration, NgModuleToLoad } from "@uirouter/angular"; +import { from, Observable, of } from "rxjs"; +import { map } from "rxjs/operators"; +import { STARK_ROUTING_SERVICE, StarkRoutingService, StarkStateConfigWithParams } from "../routing/services"; + /** * Name of the initialization states of the application */ @@ -42,3 +49,104 @@ export const starkSessionLogoutStateName: string = starkAppExitStateName + ".sta * URL of the SessionLogout state of the application */ export const starkSessionLogoutStateUrl: string = "/starkSessionLogout"; + +/** + * Configuration of the route state of the application + */ +export function resolveTargetRoute( + $location: Location, + $transition$: Transition, + routingService: StarkRoutingService +): Promise { + /** + * Get the corresponding registered state that matches with the given URL. + * If the state is part of a lazy loaded module, then such module is loaded first and then the URL is searched again to get the correct state + */ + function getTargetStateByUrl(targetUrl: string): StarkStateConfigWithParams | undefined { + let targetState: StarkStateConfigWithParams | undefined = routingService.getStateConfigByUrlPath(targetUrl); + + // skip any init/exit state + const initOrExitStateRegex: RegExp = new RegExp("(" + starkAppInitStateName + "|" + starkAppExitStateName + ")"); + + if ( + targetState && + (targetState.state.$$state)().parent && + (targetState.state.$$state)().parent.name.match(initOrExitStateRegex) + ) { + targetState = undefined; + } + + return targetState; + } + + // get the path of the current URL in the browser's navigation bar + const targetUrlPath: string = $location.path(); + const targetRoute: StarkStateConfigWithParams | undefined = getTargetStateByUrl(targetUrlPath); + let finalTargetRoute$: Observable = of(targetRoute); + + // in case the state is part of a module to load lazily, we need to load it and search the url again + if (targetRoute && (targetRoute.state.$$state)().loadChildren) { + // so we call the needed function to lazy load the module + const moduleToLoad: NgModuleToLoad = (targetRoute.state.$$state)().loadChildren; + const lazyLoadNgModule: (transition: Transition, stateObject: StateDeclaration) => Promise = loadNgModule( + moduleToLoad + ); + + // once the module is loaded lazily, we search again for the right state and return the result + finalTargetRoute$ = from(lazyLoadNgModule($transition$, targetRoute.state)).pipe( + map((_lazyLoadResult: LazyLoadResult) => { + return getTargetStateByUrl(targetUrlPath); + }) + ); + } + + return finalTargetRoute$.toPromise(); +} + +/** + * Check if targetRoute is defined and returns the name of the state OR undefined. + * @param targetRoute - returned value of resolveTargetRoute method + */ +export function resolveTargetState(targetRoute?: StarkStateConfigWithParams): Promise { + return of(typeof targetRoute !== "undefined" ? targetRoute.state.name : undefined).toPromise(); +} + +/** + * Check if targetRoute is defined and returns the params of the state OR undefined. + * @param targetRoute - returned value of resolveTargetRoute method + */ +export function resolveTargetStateParams(targetRoute?: StarkStateConfigWithParams): Promise { + return of(typeof targetRoute !== "undefined" ? targetRoute.paramValues : undefined).toPromise(); +} + +/** + * States defined by Session Module + */ +export const SESSION_STATES: Ng2StateDeclaration[] = [ + { + name: starkAppInitStateName, // parent state for any initialization state (used to show/hide the main app component) + abstract: true, + + resolve: [ + { + token: "targetRoute", + deps: [Location, Transition, STARK_ROUTING_SERVICE], + resolveFn: resolveTargetRoute + }, + { + token: "targetState", + deps: ["targetRoute"], + resolveFn: resolveTargetState + }, + { + token: "targetStateParams", + deps: ["targetRoute"], + resolveFn: resolveTargetStateParams + } + ] + }, + { + name: starkAppExitStateName, // parent state for any exit state (used to show/hide the main app component) + abstract: true + } +]; diff --git a/packages/stark-core/src/modules/session/session.module.ts b/packages/stark-core/src/modules/session/session.module.ts index d56e4d6388..c92dbe88f9 100644 --- a/packages/stark-core/src/modules/session/session.module.ts +++ b/packages/stark-core/src/modules/session/session.module.ts @@ -1,12 +1,25 @@ -import { ModuleWithProviders, NgModule, Optional, SkipSelf } from "@angular/core"; +import { ApplicationInitStatus, Inject, ModuleWithProviders, NgModule, Optional, SkipSelf } from "@angular/core"; +import { CommonModule, Location } from "@angular/common"; import { StoreModule } from "@ngrx/store"; +import { UIRouterModule } from "@uirouter/angular"; +import { from } from "rxjs"; import { starkSessionReducers } from "./reducers"; import { StarkSessionConfig, STARK_SESSION_CONFIG } from "./entities"; import { STARK_SESSION_SERVICE, StarkSessionServiceImpl } from "./services"; -import { StarkUserModule } from "../user/user.module"; +import { STARK_ROUTING_SERVICE, StarkRoutingService } from "../routing/services"; +import { SESSION_STATES, starkLoginStateName, starkPreloadingStateName } from "./routes"; +import { StarkAppContainerComponent } from "./components"; @NgModule({ - imports: [StoreModule.forFeature("StarkSession", starkSessionReducers), StarkUserModule] + imports: [ + CommonModule, + StoreModule.forFeature("StarkSession", starkSessionReducers), + UIRouterModule.forChild({ + states: SESSION_STATES + }) + ], + declarations: [StarkAppContainerComponent], + exports: [StarkAppContainerComponent] }) export class StarkSessionModule { /** @@ -20,6 +33,7 @@ export class StarkSessionModule { return { ngModule: StarkSessionModule, providers: [ + Location, { provide: STARK_SESSION_SERVICE, useClass: StarkSessionServiceImpl }, sessionConfig ? { provide: STARK_SESSION_CONFIG, useValue: sessionConfig } : [] ] @@ -30,14 +44,53 @@ export class StarkSessionModule { * Prevents this module from being re-imported * @link https://angular.io/guide/singleton-services#prevent-reimport-of-the-coremodule * @param parentModule - the parent module + * @param routingService - The routing service of the application + * @param sessionConfig - The configuration of the session module + * @param appInitStatus - A class that reflects the state of running {@link APP_INITIALIZER}s */ public constructor( @Optional() @SkipSelf() - parentModule: StarkSessionModule + parentModule: StarkSessionModule, + @Inject(STARK_ROUTING_SERVICE) routingService: StarkRoutingService, + appInitStatus: ApplicationInitStatus, + @Optional() + @Inject(STARK_SESSION_CONFIG) + sessionConfig?: StarkSessionConfig ) { if (parentModule) { throw new Error("StarkSessionModule is already loaded. Import it in the AppModule only"); } + + // this logic cannot be executed in an APP_INITIALIZER factory because the StarkRoutingService uses the StarkLoggingService + // which needs the "logging" state to be already defined in the Store (which NGRX defines internally via APP_INITIALIZER factories :p) + from(appInitStatus.donePromise).subscribe(() => { + if (ENV === "development") { + const loginStateName: string = this.getStateName( + starkLoginStateName, + sessionConfig ? sessionConfig.loginStateName : undefined + ); + routingService.navigateTo(loginStateName); + } else { + const preloadingStateName: string = this.getStateName( + starkPreloadingStateName, + sessionConfig ? sessionConfig.preloadingStateName : undefined + ); + routingService.navigateTo(preloadingStateName); + } + }); + } + + /** + * @ignore + */ + private getStateName(defaultState: string, configState?: string): string { + let finalStateName: string = defaultState; + + if (typeof configState !== "undefined" && configState !== "") { + finalStateName = configState; + } + + return finalStateName; } } diff --git a/packages/stark-core/testing/tsconfig-build.json b/packages/stark-core/testing/tsconfig-build.json index 926cf608cd..7841d4456d 100644 --- a/packages/stark-core/testing/tsconfig-build.json +++ b/packages/stark-core/testing/tsconfig-build.json @@ -30,6 +30,7 @@ "allowEmptyCodegenFiles": false, "annotateForClosureCompiler": true, "skipTemplateCodegen": true, + "enableResourceInlining": true, "flatModuleOutFile": "testing.js", "flatModuleId": "@nationalbankbelgium/stark-core/testing" } diff --git a/packages/stark-ui/src/modules/app-menu/app-menu.module.ts b/packages/stark-ui/src/modules/app-menu/app-menu.module.ts index 3a85dceeec..76366f9922 100644 --- a/packages/stark-ui/src/modules/app-menu/app-menu.module.ts +++ b/packages/stark-ui/src/modules/app-menu/app-menu.module.ts @@ -1,19 +1,17 @@ import { NgModule } from "@angular/core"; -import { StarkAppMenuComponent, StarkAppMenuItemComponent } from "./components"; -import { TranslateModule } from "@ngx-translate/core"; import { CommonModule } from "@angular/common"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { MatDividerModule } from "@angular/material/divider"; import { MatExpansionModule } from "@angular/material/expansion"; import { MatIconModule } from "@angular/material/icon"; import { MatListModule } from "@angular/material/list"; -import { StarkSvgViewBoxModule } from "../svg-view-box/svg-view-box.module"; +import { TranslateModule } from "@ngx-translate/core"; import { UIRouterModule } from "@uirouter/angular"; +import { StarkAppMenuComponent, StarkAppMenuItemComponent } from "./components"; +import { StarkSvgViewBoxModule } from "../svg-view-box/svg-view-box.module"; @NgModule({ declarations: [StarkAppMenuComponent, StarkAppMenuItemComponent], imports: [ - BrowserAnimationsModule, CommonModule, MatListModule, MatDividerModule, diff --git a/packages/stark-ui/src/modules/dropdown/dropdown.module.ts b/packages/stark-ui/src/modules/dropdown/dropdown.module.ts index e4f8269da8..bc63e0f574 100644 --- a/packages/stark-ui/src/modules/dropdown/dropdown.module.ts +++ b/packages/stark-ui/src/modules/dropdown/dropdown.module.ts @@ -1,15 +1,14 @@ import { NgModule } from "@angular/core"; -import { StarkDropdownComponent } from "./components"; -import { TranslateModule } from "@ngx-translate/core"; import { CommonModule } from "@angular/common"; import { FormsModule } from "@angular/forms"; import { MatOptionModule } from "@angular/material/core"; import { MatSelectModule } from "@angular/material/select"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { TranslateModule } from "@ngx-translate/core"; +import { StarkDropdownComponent } from "./components"; @NgModule({ declarations: [StarkDropdownComponent], - imports: [CommonModule, TranslateModule, FormsModule, MatSelectModule, MatOptionModule, BrowserAnimationsModule], + imports: [CommonModule, TranslateModule, FormsModule, MatSelectModule, MatOptionModule], exports: [StarkDropdownComponent] }) export class StarkDropdownModule {} diff --git a/packages/stark-ui/src/modules/pagination/pagination.module.ts b/packages/stark-ui/src/modules/pagination/pagination.module.ts index 21b71c08dc..1b44eb280c 100644 --- a/packages/stark-ui/src/modules/pagination/pagination.module.ts +++ b/packages/stark-ui/src/modules/pagination/pagination.module.ts @@ -1,6 +1,6 @@ import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; import { FormsModule } from "@angular/forms"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { MatIconModule } from "@angular/material/icon"; import { MatInputModule } from "@angular/material/input"; import { MatButtonModule } from "@angular/material/button"; @@ -15,7 +15,7 @@ import { StarkDropdownModule } from "../dropdown/dropdown.module"; declarations: [StarkPaginationComponent], exports: [StarkPaginationComponent], imports: [ - BrowserAnimationsModule, + CommonModule, FormsModule, MatButtonModule, MatIconModule, diff --git a/packages/stark-ui/src/modules/session-ui.ts b/packages/stark-ui/src/modules/session-ui.ts index dcd73085cd..112375eb84 100644 --- a/packages/stark-ui/src/modules/session-ui.ts +++ b/packages/stark-ui/src/modules/session-ui.ts @@ -1,3 +1,2 @@ export * from "./session-ui/session-ui.module"; export * from "./session-ui/pages"; -export * from "./session-ui/components"; diff --git a/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.ts b/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.ts index c4c2b0d1f8..3d4b720217 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.ts @@ -18,7 +18,11 @@ import { const componentName: string = "stark-login-page"; /** - * Login Page smart component + * Login Page smart component. + * **This page is to be used only in the development environment.** + * + * It shows a list of user profiles (provided by mock data or a back-end) that the user can choose and use it to impersonate himself as someone else. + * This makes it easy to run the application with different roles. */ @Component({ selector: "stark-login-page", @@ -29,13 +33,30 @@ const componentName: string = "stark-login-page"; } }) export class StarkLoginPageComponent implements OnInit { + /** + * Target page to navigate to after the user profile is loaded and automatically logged in. + */ @Input() public targetState: string; + + /** + * Params to pass to the target page (if any). + */ @Input() public targetStateParams: RawParams; + /** + * User profiles to be displayed in the list where the user can choose from. + */ public users: StarkUser[]; + /** + * Class constructor + * @param logger - The logger of the application + * @param userService - The user service of the application + * @param sessionService - The session service of the application + * @param routingService - The routing service of the application + */ public constructor( @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, @Inject(STARK_USER_SERVICE) public userService: StarkUserService, diff --git a/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts b/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts index cc0f9ee0c7..0f418afd74 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts @@ -20,7 +20,10 @@ import { const componentName: string = "stark-preloading-page"; /** - * Preloading Page smart component + * Preloading Page smart component. + * + * This page will be shown when the application starts and will fetch the user profile (via the {@link StarkUserService}) to perform the login of the user. + * It will redirect to the target page (via the {@link StarkRoutingService}) as soon as the user profile is loaded and logged in. */ @Component({ selector: "stark-preloading-page", @@ -31,15 +34,40 @@ const componentName: string = "stark-preloading-page"; } }) export class StarkPreloadingPageComponent implements OnInit { + /** + * Target page to navigate to after the user profile is loaded and automatically logged in. + */ @Input() public targetState: string; + + /** + * Params to pass to the target page (if any). + */ @Input() public targetStateParams: RawParams; + /** + * Whether the fetching of the user profile failed + */ public userFetchingFailed: boolean; + + /** + * The current correlation Id of the application (useful when troubleshooting errors). + */ public correlationId: string; + + /** + * @ignore + */ public loginDelay: number = 200; + /** + * Class constructor + * @param logger - The logger of the application + * @param userService - The user service of the application + * @param sessionService - The session service of the application + * @param routingService - The routing service of the application + */ public constructor( @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, @Inject(STARK_USER_SERVICE) public userService: StarkUserService, diff --git a/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.ts b/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.ts index 001bd8c54e..b6295d4b75 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.ts @@ -8,7 +8,10 @@ import { STARK_APP_CONFIG, STARK_LOGGING_SERVICE, StarkApplicationConfig, StarkL const componentName: string = "stark-session-expired-page"; /** - * Session expired page smart component + * Session Expired Page smart component. + * + * This page will be shown when there is no user activity in the application and the session expiration timer has timed out (see {@link StarKApplicationConfig}). + * In this page, the user has the ability to reload again the application clicking the Reload button. */ @Component({ selector: "stark-session-expired-page", @@ -19,6 +22,11 @@ const componentName: string = "stark-session-expired-page"; } }) export class StarkSessionExpiredPageComponent implements OnInit { + /** + * Class constructor + * @param logger - The logger of the application + * @param appConfig - The application configuration + */ public constructor( @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, @Inject(STARK_APP_CONFIG) public appConfig: StarkApplicationConfig diff --git a/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.ts b/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.ts index ec7fb9a6ff..133ef21e98 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.ts @@ -8,7 +8,10 @@ import { STARK_APP_CONFIG, STARK_LOGGING_SERVICE, StarkApplicationConfig, StarkL const componentName: string = "stark-session-logout-page"; /** - * Session logout page smart component + * Session Logout Page smart component. + * + * This page will be shown when the user logs out from the application (i.e. clicking the {@AppLogoComponent} button). + * In this page, the user has the ability to reload and log in again into the application by clicking the Login button. */ @Component({ selector: "stark-session-logout-page", @@ -19,6 +22,11 @@ const componentName: string = "stark-session-logout-page"; } }) export class StarkSessionLogoutPageComponent implements OnInit { + /** + * Class constructor + * @param logger - The logger of the application + * @param appConfig - The application configuration + */ public constructor( @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, @Inject(STARK_APP_CONFIG) public appConfig: StarkApplicationConfig diff --git a/packages/stark-ui/src/modules/session-ui/routes.ts b/packages/stark-ui/src/modules/session-ui/routes.ts index 67d9a3030a..619c6b170f 100644 --- a/packages/stark-ui/src/modules/session-ui/routes.ts +++ b/packages/stark-ui/src/modules/session-ui/routes.ts @@ -1,19 +1,13 @@ -import { Ng2StateDeclaration, RawParams } from "@uirouter/angular"; -import { Location } from "@angular/common"; +import { Ng2StateDeclaration } from "@uirouter/angular"; import { - STARK_ROUTING_SERVICE, - starkAppExitStateName, - starkAppInitStateName, starkLoginStateName, starkLoginStateUrl, starkPreloadingStateName, starkPreloadingStateUrl, - StarkRoutingService, starkSessionExpiredStateName, starkSessionExpiredStateUrl, starkSessionLogoutStateName, - starkSessionLogoutStateUrl, - StarkStateConfigWithParams + starkSessionLogoutStateUrl } from "@nationalbankbelgium/stark-core"; import { StarkLoginPageComponent, @@ -21,84 +15,12 @@ import { StarkSessionExpiredPageComponent, StarkSessionLogoutPageComponent } from "./pages"; -import { of } from "rxjs"; /** - * Configuration of the route state of the application - */ -export function resolveTargetRoute( - $location: Location, - routingService: StarkRoutingService -): Promise { - // get the path of the current URL in the browser's navigation bar - const targetUrlPath: string = $location.path(); - const targetRoute: StarkStateConfigWithParams | undefined = routingService.getStateConfigByUrlPath(targetUrlPath); - - // skip any init/exit state - const initOrExitStateRegex: RegExp = new RegExp("(" + starkAppInitStateName + "|" + starkAppExitStateName + ")"); - - if (targetRoute) { - if ((targetRoute.state.$$state)().parent) { - if (!(targetRoute.state.$$state)().parent.name.match(initOrExitStateRegex)) { - return of(targetRoute).toPromise(); - } else { - return of(undefined).toPromise(); - } - } else { - return of(targetRoute).toPromise(); - } - } else { - return of(undefined).toPromise(); - } -} - -/** - * Check if targetRoute is defined and returns the name of the state OR undefined. - * @param targetRoute - returned value of resolveTargetRoute method - */ -export function resolveTargetState(targetRoute: StarkStateConfigWithParams): Promise { - return of(typeof targetRoute !== "undefined" ? targetRoute.state.name : undefined).toPromise(); -} - -/** - * Check if targetRoute is defined and returns the params of the state OR undefined. - * @param targetRoute - returned value of resolveTargetRoute method - */ -export function resolveTargetStateParams(targetRoute: StarkStateConfigWithParams): Promise { - return of(typeof targetRoute !== "undefined" ? targetRoute.paramValues : undefined).toPromise(); -} - -/** - * States defined by Session-Ui + * States defined by Session-UI Module */ /* tslint:disable:no-duplicate-string */ -export const SESSION_MODULE_STATES: Ng2StateDeclaration[] = [ - { - name: starkAppInitStateName, // parent state for any initialization state (used to show/hide the main app component) - abstract: true, - - resolve: [ - { - token: "targetRoute", - deps: [Location, STARK_ROUTING_SERVICE], - resolveFn: resolveTargetRoute - }, - { - token: "targetState", - deps: ["targetRoute"], - resolveFn: resolveTargetState - }, - { - token: "targetStateParams", - deps: ["targetRoute"], - resolveFn: resolveTargetStateParams - } - ] - }, - { - name: starkAppExitStateName, // parent state for any exit state (used to show/hide the main app component) - abstract: true - }, +export const SESSION_UI_STATES: Ng2StateDeclaration[] = [ { name: starkLoginStateName, // the parent is defined in the state's name (contains a dot) url: starkLoginStateUrl, diff --git a/packages/stark-ui/src/modules/session-ui/session-ui.module.ts b/packages/stark-ui/src/modules/session-ui/session-ui.module.ts index 49473ad87c..71794820bb 100644 --- a/packages/stark-ui/src/modules/session-ui/session-ui.module.ts +++ b/packages/stark-ui/src/modules/session-ui/session-ui.module.ts @@ -1,50 +1,32 @@ -import { ApplicationInitStatus, Inject, ModuleWithProviders, NgModule, Optional, SkipSelf } from "@angular/core"; +import { ModuleWithProviders, NgModule, Optional, SkipSelf } from "@angular/core"; import { UIRouterModule } from "@uirouter/angular"; import { TranslateModule } from "@ngx-translate/core"; -import { CommonModule, Location } from "@angular/common"; +import { CommonModule } from "@angular/common"; import { MatButtonModule } from "@angular/material/button"; -import { SESSION_MODULE_STATES } from "./routes"; -import { from } from "rxjs"; -import { - STARK_ROUTING_SERVICE, - STARK_SESSION_CONFIG, - StarkSessionConfig, - starkLoginStateName, - starkPreloadingStateName, - StarkRoutingService -} from "@nationalbankbelgium/stark-core"; +import { SESSION_UI_STATES } from "./routes"; import { StarkLoginPageComponent, StarkPreloadingPageComponent, StarkSessionExpiredPageComponent, StarkSessionLogoutPageComponent } from "./pages"; -import { StarkAppContainerComponent } from "./components"; @NgModule({ declarations: [ - StarkAppContainerComponent, - StarkLoginPageComponent, - StarkPreloadingPageComponent, - StarkSessionExpiredPageComponent, - StarkSessionLogoutPageComponent - ], - exports: [ - StarkAppContainerComponent, StarkLoginPageComponent, StarkPreloadingPageComponent, StarkSessionExpiredPageComponent, StarkSessionLogoutPageComponent ], + exports: [StarkLoginPageComponent, StarkPreloadingPageComponent, StarkSessionExpiredPageComponent, StarkSessionLogoutPageComponent], imports: [ CommonModule, UIRouterModule.forChild({ - states: SESSION_MODULE_STATES + states: SESSION_UI_STATES }), MatButtonModule, TranslateModule - ], - providers: [Location] + ] }) export class StarkSessionUiModule { /** @@ -63,53 +45,14 @@ export class StarkSessionUiModule { * Prevents this module from being re-imported * @link https://angular.io/guide/singleton-services#prevent-reimport-of-the-coremodule * @param parentModule - The parent module - * @param routingService - The routing service of the application - * @param sessionConfig - The configuration of the session module - * @param appInitStatus - A class that reflects the state of running {@link APP_INITIALIZER}s */ public constructor( @Optional() @SkipSelf() - parentModule: StarkSessionUiModule, - @Inject(STARK_ROUTING_SERVICE) routingService: StarkRoutingService, - appInitStatus: ApplicationInitStatus, - @Optional() - @Inject(STARK_SESSION_CONFIG) - sessionConfig?: StarkSessionConfig + parentModule: StarkSessionUiModule ) { if (parentModule) { throw new Error("StarkSessionUiModule is already loaded. Import it in the AppModule only"); } - - // this logic cannot be executed in an APP_INITIALIZER factory because the StarkRoutingService uses the StarkLoggingService - // which needs the "logging" state to be already defined in the Store (which NGRX defines internally via APP_INITIALIZER factories :p) - from(appInitStatus.donePromise).subscribe(() => { - if (ENV === "development") { - const loginStateName: string = this.getStateName( - starkLoginStateName, - sessionConfig ? sessionConfig.loginStateName : undefined - ); - routingService.navigateTo(loginStateName); - } else { - const preloadingStateName: string = this.getStateName( - starkPreloadingStateName, - sessionConfig ? sessionConfig.preloadingStateName : undefined - ); - routingService.navigateTo(preloadingStateName); - } - }); - } - - /** - * @ignore - */ - private getStateName(defaultState: string, configState?: string): string { - let finalStateName: string = defaultState; - - if (typeof configState !== "undefined" && configState !== "") { - finalStateName = configState; - } - - return finalStateName; } } diff --git a/packages/stark-ui/src/modules/table/table.module.ts b/packages/stark-ui/src/modules/table/table.module.ts index 207291aea6..75cbf7c420 100644 --- a/packages/stark-ui/src/modules/table/table.module.ts +++ b/packages/stark-ui/src/modules/table/table.module.ts @@ -1,6 +1,6 @@ import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; import { FormsModule } from "@angular/forms"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { MatButtonModule } from "@angular/material/button"; import { MatCheckboxModule } from "@angular/material/checkbox"; import { MatDialogModule } from "@angular/material/dialog"; @@ -23,7 +23,7 @@ import { StarkSvgViewBoxModule } from "../svg-view-box/svg-view-box.module"; entryComponents: [StarkTableMultisortDialogComponent], exports: [StarkTableComponent, StarkTableColumnComponent], imports: [ - BrowserAnimationsModule, + CommonModule, FormsModule, MatButtonModule, MatCheckboxModule, diff --git a/packages/stark-ui/src/modules/toast-notification/toast-notification.module.ts b/packages/stark-ui/src/modules/toast-notification/toast-notification.module.ts index b4f187f858..eeaf51a16a 100644 --- a/packages/stark-ui/src/modules/toast-notification/toast-notification.module.ts +++ b/packages/stark-ui/src/modules/toast-notification/toast-notification.module.ts @@ -1,5 +1,5 @@ import { NgModule, ModuleWithProviders, SkipSelf, Optional } from "@angular/core"; -import { BrowserModule } from "@angular/platform-browser"; +import { CommonModule } from "@angular/common"; import { MatSnackBarModule } from "@angular/material/snack-bar"; import { MatIconModule } from "@angular/material/icon"; import { MatButtonModule } from "@angular/material/button"; @@ -13,7 +13,7 @@ import { import { StarkToastNotificationComponent } from "./components"; @NgModule({ declarations: [StarkToastNotificationComponent], - imports: [BrowserModule, MatButtonModule, MatIconModule, MatSnackBarModule, TranslateModule], + imports: [CommonModule, MatButtonModule, MatIconModule, MatSnackBarModule, TranslateModule], exports: [StarkToastNotificationComponent], entryComponents: [StarkToastNotificationComponent] // More infos about entryComponents : https://github.com/angular/material2/issues/3002 }) diff --git a/showcase/src/app/app.component.ts b/showcase/src/app/app.component.ts index 9ceda02a8a..5f429c4dac 100644 --- a/showcase/src/app/app.component.ts +++ b/showcase/src/app/app.component.ts @@ -68,119 +68,119 @@ export class AppComponent implements OnInit { label: "Action bar", isVisible: true, isEnabled: true, - targetState: "demo-action-bar" + targetState: "demo.action-bar" }, { id: "menu-stark-ui-components-logout", label: "App logout", isVisible: true, isEnabled: true, - targetState: "demo-logout" + targetState: "demo.logout" }, { id: "menu-stark-ui-components-menu", label: "App menu", isVisible: true, isEnabled: true, - targetState: "demo-menu" + targetState: "demo.menu" }, { id: "menu-stark-ui-components-sidebar", label: "App sidebar", isVisible: true, isEnabled: true, - targetState: "demo-sidebar" + targetState: "demo.sidebar" }, { id: "menu-stark-ui-components-breadcrumb", label: "Breadcrumb", isVisible: true, isEnabled: true, - targetState: "demo-breadcrumb" + targetState: "demo.breadcrumb" }, { id: "menu-stark-ui-components-button", label: "Button", isVisible: true, isEnabled: true, - targetState: "demo-button" + targetState: "demo.button" }, { id: "menu-stark-ui-components-collapsible", label: "Collapsible", isVisible: true, isEnabled: true, - targetState: "demo-collapsible" + targetState: "demo.collapsible" }, { id: "menu-stark-ui-components-date-picker", label: "Date picker", isVisible: true, isEnabled: true, - targetState: "demo-date-picker" + targetState: "demo.date-picker" }, { id: "menu-stark-ui-components-date-range-picker", label: "Date range picker", isVisible: true, isEnabled: true, - targetState: "demo-date-range-picker" + targetState: "demo.date-range-picker" }, { id: "menu-stark-ui-components-dropdown", label: "Dropdown", isVisible: true, isEnabled: true, - targetState: "demo-dropdown" + targetState: "demo.dropdown" }, { id: "menu-stark-ui-components-example-viewer", label: "Example viewer", isVisible: true, isEnabled: true, - targetState: "demo-example-viewer" + targetState: "demo.example-viewer" }, { id: "menu-stark-ui-components-language-selector", label: "Language selector", isVisible: true, isEnabled: true, - targetState: "demo-language-selector" + targetState: "demo.language-selector" }, { id: "menu-stark-ui-components-pagination", label: "Pagination", isVisible: true, isEnabled: true, - targetState: "demo-pagination" + targetState: "demo.pagination" }, { id: "menu-stark-ui-components-pretty-print", label: "Pretty print", isVisible: true, isEnabled: true, - targetState: "demo-pretty-print" + targetState: "demo.pretty-print" }, { id: "menu-stark-ui-components-slider", label: "Slider", isVisible: true, isEnabled: true, - targetState: "demo-slider" + targetState: "demo.slider" }, { id: "menu-stark-ui-components-table", label: "Table", isVisible: true, isEnabled: true, - targetState: "demo-table" + targetState: "demo.table" }, { id: "menu-stark-ui-components-toast", label: "Toast notification", isVisible: true, isEnabled: true, - targetState: "demo-toast" + targetState: "demo.toast" } ] }, @@ -195,7 +195,7 @@ export class AppComponent implements OnInit { label: "Keyboard directives", isVisible: true, isEnabled: true, - targetState: "demo-keyboard-directives" + targetState: "demo.keyboard-directives" } ] }, @@ -213,7 +213,7 @@ export class AppComponent implements OnInit { menuGroups: [ { id: "test-1", - label: "Getting start", + label: "Getting started", isVisible: true, isEnabled: true }, @@ -233,35 +233,35 @@ export class AppComponent implements OnInit { label: "Card", isVisible: true, isEnabled: true, - targetState: "demo-card" + targetState: "demo.card" }, { id: "menu-style-colors", label: "Colors", isVisible: true, isEnabled: true, - targetState: "demo-colors" + targetState: "demo.colors" }, { id: "menu-style-footer", label: "Footer", isVisible: true, isEnabled: true, - targetState: "stark-footer" + targetState: "demo.stark-footer" }, { id: "menu-style-header", label: "Header", isVisible: true, isEnabled: true, - targetState: "stark-header" + targetState: "demo.stark-header" }, { id: "menu-style-typography", label: "Typography", isVisible: true, isEnabled: true, - targetState: "demo-typography" + targetState: "demo.typography" } ] } diff --git a/showcase/src/app/app.module.ts b/showcase/src/app/app.module.ts index 320369aa1d..8df1587d54 100644 --- a/showcase/src/app/app.module.ts +++ b/showcase/src/app/app.module.ts @@ -1,5 +1,6 @@ import { APP_INITIALIZER, Inject, NgModule, NgModuleFactoryLoader, SystemJsNgModuleLoader } from "@angular/core"; import { BrowserModule, DomSanitizer } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { FormsModule } from "@angular/forms"; import { UIRouter, UIRouterModule } from "@uirouter/angular"; import { NgIdleModule } from "@ng-idle/core"; @@ -9,7 +10,6 @@ import { StoreDevtoolsModule } from "@ngrx/store-devtools"; import { EffectsModule } from "@ngrx/effects"; import { storeFreeze } from "ngrx-store-freeze"; import { storeLogger } from "ngrx-store-logger"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { MatIconModule, MatIconRegistry } from "@angular/material/icon"; import { MatButtonModule } from "@angular/material/button"; import { MatButtonToggleModule } from "@angular/material/button-toggle"; @@ -17,7 +17,6 @@ import { MatCardModule } from "@angular/material/card"; import { MatCheckboxModule } from "@angular/material/checkbox"; import { MatExpansionModule } from "@angular/material/expansion"; import { MatListModule } from "@angular/material/list"; -import { MatSidenavModule } from "@angular/material/sidenav"; import { MatTooltipModule } from "@angular/material/tooltip"; import { DateAdapter } from "@angular/material/core"; import { SharedModule } from "./shared/shared.module"; @@ -57,7 +56,6 @@ import { StarkAppLogoutModule, StarkAppMenuModule, StarkAppSidebarModule, - StarkBreadcrumbModule, StarkDatePickerModule, StarkLanguageSelectorModule, StarkSessionUiModule, @@ -85,8 +83,6 @@ import { APP_STATES } from "./app.routes"; import { AppComponent } from "./app.component"; import { HomeComponent } from "./home"; import { NoContentComponent } from "./no-content"; -import { DemoModule } from "./demo"; -import { NewsModule } from "./news"; /* tslint:disable:no-import-side-effect */ // load PostCSS styles import "../styles/styles.pcss"; @@ -188,7 +184,6 @@ export const metaReducers: MetaReducer[] = ENV !== "production" ? [logger MatExpansionModule, MatIconModule, MatListModule, - MatSidenavModule, MatTooltipModule, StoreModule.forRoot(reducers, { metaReducers @@ -225,8 +220,6 @@ export const metaReducers: MetaReducer[] = ENV !== "production" ? [logger } }), SharedModule, - DemoModule, - NewsModule, StarkAppFooterModule, StarkAppLogoModule, StarkAppLogoutModule, @@ -235,7 +228,6 @@ export const metaReducers: MetaReducer[] = ENV !== "production" ? [logger StarkLanguageSelectorModule, StarkSvgViewBoxModule, StarkDatePickerModule, - StarkBreadcrumbModule, StarkToastNotificationModule.forRoot({ delay: 5000, position: "top right", diff --git a/showcase/src/app/app.routes.ts b/showcase/src/app/app.routes.ts index 621464fa78..f33326aaba 100644 --- a/showcase/src/app/app.routes.ts +++ b/showcase/src/app/app.routes.ts @@ -1,58 +1,33 @@ -import { - DemoActionBarComponent, - DemoBreadcrumbComponent, - DemoButtonComponent, - DemoDatePickerComponent, - DemoDateRangePickerComponent, - DemoDropdownComponent, - DemoCardComponent, - DemoCollapsibleComponent, - DemoColorsComponent, - DemoExampleViewerComponent, - DemoFooterComponent, - DemoHeaderComponent, - DemoKeyboardDirectivesComponent, - DemoLanguageSelectorComponent, - DemoLogoutComponent, - DemoMenuComponent, - DemoPaginationComponent, - DemoPrettyPrintComponent, - DemoSidebarComponent, - DemoSliderComponent, - DemoTableComponent, - DemoToastComponent, - DemoTypographyComponent -} from "./demo"; import { HomeComponent } from "./home"; import { NoContentComponent } from "./no-content"; import { Ng2StateDeclaration } from "@uirouter/angular"; -import { NewsComponent } from "./news"; +import { AppComponent } from "./app.component"; export const APP_STATES: Ng2StateDeclaration[] = [ - { name: "news", url: "/news", component: NewsComponent }, - { name: "home", url: "/", component: HomeComponent }, - { name: "demo-action-bar", url: "/demo/action-bar", component: DemoActionBarComponent }, - { name: "demo-breadcrumb", url: "/demo/breadcrumb", component: DemoBreadcrumbComponent }, - { name: "demo-button", url: "/demo/button", component: DemoButtonComponent }, - { name: "demo-card", url: "/demo/card", component: DemoCardComponent }, - { name: "demo-collapsible", url: "/demo/collapsible", component: DemoCollapsibleComponent }, - { name: "demo-colors", url: "/demo/colors", component: DemoColorsComponent }, - { name: "demo-date-picker", url: "/demo/date-picker", component: DemoDatePickerComponent }, - { name: "demo-date-range-picker", url: "/demo/date-range-picker", component: DemoDateRangePickerComponent }, - { name: "demo-dropdown", url: "/demo/dropdown", component: DemoDropdownComponent }, - { name: "stark-footer", url: "/demo/stark-footer", component: DemoFooterComponent }, - { name: "stark-header", url: "/demo/stark-header", component: DemoHeaderComponent }, - { name: "demo-example-viewer", url: "/demo/example-viewer", component: DemoExampleViewerComponent }, - { name: "demo-keyboard-directives", url: "/demo/keyboard-directives", component: DemoKeyboardDirectivesComponent }, - { name: "demo-language-selector", url: "/demo/language-selector", component: DemoLanguageSelectorComponent }, - { name: "demo-logout", url: "/demo/logout", component: DemoLogoutComponent }, - { name: "demo-menu", url: "/demo/menu", component: DemoMenuComponent }, - { name: "demo-pagination", url: "/demo/pagination", component: DemoPaginationComponent }, - { name: "demo-pretty-print", url: "/demo/pretty-print", component: DemoPrettyPrintComponent }, - { name: "demo-slider", url: "/demo/slider", component: DemoSliderComponent }, - { name: "demo-sidebar", url: "/demo/sidebar", component: DemoSidebarComponent }, - { name: "demo-table", url: "/demo/table", component: DemoTableComponent }, - { name: "demo-toast", url: "/demo/toast", component: DemoToastComponent }, - { name: "demo-typography", url: "/demo/typography", component: DemoTypographyComponent }, - { name: "otherwise", url: "/otherwise", component: NoContentComponent } + { + name: "app", + url: "/", + component: AppComponent + }, + { + name: "home", + url: "", + views: { "@": { component: HomeComponent } }, + parent: "app" + }, + { + name: "news.**", + url: "^/news", // use ^ to avoid double slash "//" in the URL after the domain (https://github.com/angular-ui/ui-router/wiki/URL-Routing#absolute-routes-) + loadChildren: "./news/news.module#NewsModule" // lazy loaded module + }, + { + name: "demo.**", + url: "^/demo", // use ^ to avoid double slash "//" in the URL after the domain (https://github.com/angular-ui/ui-router/wiki/URL-Routing#absolute-routes-) + loadChildren: "./demo/demo.module#DemoModule" // lazy loaded module + }, + { + name: "otherwise", + url: "^/otherwise", // use ^ to avoid double slash "//" in the URL after the domain (https://github.com/angular-ui/ui-router/wiki/URL-Routing#absolute-routes-) + component: NoContentComponent + } ]; diff --git a/showcase/src/app/demo/demo.module.ts b/showcase/src/app/demo/demo.module.ts index ee6f4825b0..1d5528af4d 100644 --- a/showcase/src/app/demo/demo.module.ts +++ b/showcase/src/app/demo/demo.module.ts @@ -14,15 +14,33 @@ import { MatSnackBarModule } from "@angular/material/snack-bar"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; import { TranslateModule } from "@ngx-translate/core"; +import { UIRouterModule } from "@uirouter/angular"; +import { + STARK_DATE_FORMATS, + StarkActionBarModule, + StarkAppLogoutModule, + StarkBreadcrumbModule, + StarkCollapsibleModule, + StarkDatePickerModule, + StarkDateRangePickerModule, + StarkDropdownModule, + StarkKeyboardDirectivesModule, + StarkLanguageSelectorModule, + StarkAppMenuModule, + StarkPaginationModule, + StarkPrettyPrintModule, + StarkSliderModule, + StarkSvgViewBoxModule, + StarkTableModule +} from "@nationalbankbelgium/stark-ui"; import { DemoActionBarComponent } from "./action-bar/demo-action-bar.component"; import { DemoBreadcrumbComponent } from "./breadcrumb/demo-breadcrumb.component"; +import { DemoButtonComponent } from "./button/demo-button.component"; import { DemoCardComponent } from "./card/demo-card.component"; +import { DemoCollapsibleComponent } from "./collapsible/demo-collapsible.component"; import { DemoColorsComponent } from "./colors/demo-colors.component"; -import { DemoButtonComponent } from "./button/demo-button.component"; import { DemoDatePickerComponent } from "./date-picker/demo-date-picker.component"; import { DemoDateRangePickerComponent } from "./date-range-picker/demo-date-range-picker.component"; -import { DemoCollapsibleComponent } from "./collapsible/demo-collapsible.component"; -import { DemoSidebarComponent } from "./sidebar/demo-sidebar.component"; import { DemoDropdownComponent } from "./dropdown/demo-dropdown.component"; import { DemoExampleViewerComponent } from "./example-viewer/demo-example-viewer.component"; import { DemoHeaderComponent } from "./header/demo-header.component"; @@ -33,32 +51,19 @@ import { DemoLogoutComponent } from "./logout/demo-logout.component"; import { DemoMenuComponent } from "./menu/demo-menu.component"; import { DemoPaginationComponent } from "./pagination/demo-pagination.component"; import { DemoPrettyPrintComponent } from "./pretty-print/demo-pretty-print.component"; +import { DemoSidebarComponent } from "./sidebar/demo-sidebar.component"; import { DemoSliderComponent } from "./slider/demo-slider.component"; import { DemoTableComponent } from "./table/demo-table.component"; import { DemoTypographyComponent } from "./typography/demo-typography.component"; import { DemoToastComponent } from "./toast/demo-toast-notification.component"; import { SharedModule } from "../shared/shared.module"; -import { - STARK_DATE_FORMATS, - StarkActionBarModule, - StarkAppLogoutModule, - StarkBreadcrumbModule, - StarkDatePickerModule, - StarkDateRangePickerModule, - StarkDropdownModule, - StarkKeyboardDirectivesModule, - StarkLanguageSelectorModule, - StarkAppMenuModule, - StarkPaginationModule, - StarkPrettyPrintModule, - StarkSliderModule, - StarkSvgViewBoxModule, - StarkTableModule, - StarkCollapsibleModule -} from "@nationalbankbelgium/stark-ui"; +import { DEMO_STATES } from "./routes"; @NgModule({ imports: [ + UIRouterModule.forChild({ + states: DEMO_STATES + }), CommonModule, FormsModule, MatButtonModule, diff --git a/showcase/src/app/demo/routes.ts b/showcase/src/app/demo/routes.ts new file mode 100644 index 0000000000..085cc8e3b1 --- /dev/null +++ b/showcase/src/app/demo/routes.ts @@ -0,0 +1,143 @@ +import { Ng2StateDeclaration } from "@uirouter/angular"; +import { DemoActionBarComponent } from "./action-bar"; +import { DemoBreadcrumbComponent } from "./breadcrumb"; +import { DemoButtonComponent } from "./button"; +import { DemoCardComponent } from "./card"; +import { DemoCollapsibleComponent } from "./collapsible"; +import { DemoColorsComponent } from "./colors"; +import { DemoDatePickerComponent } from "./date-picker"; +import { DemoDateRangePickerComponent } from "./date-range-picker"; +import { DemoDropdownComponent } from "./dropdown"; +import { DemoFooterComponent } from "./footer"; +import { DemoHeaderComponent } from "./header"; +import { DemoExampleViewerComponent } from "./example-viewer"; +import { DemoKeyboardDirectivesComponent } from "./keyboard-directives"; +import { DemoLanguageSelectorComponent } from "./language-selector"; +import { DemoLogoutComponent } from "./logout"; +import { DemoMenuComponent } from "./menu"; +import { DemoPaginationComponent } from "./pagination"; +import { DemoPrettyPrintComponent } from "./pretty-print"; +import { DemoSliderComponent } from "./slider"; +import { DemoSidebarComponent } from "./sidebar"; +import { DemoTableComponent } from "./table"; +import { DemoToastComponent } from "./toast"; +import { DemoTypographyComponent } from "./typography"; + +export const DEMO_STATES: Ng2StateDeclaration[] = [ + { name: "demo", url: "^/demo", abstract: true, parent: "app" }, + { + name: "demo.action-bar", + url: "/action-bar", + views: { "@": { component: DemoActionBarComponent } } + }, + { + name: "demo.breadcrumb", + url: "/breadcrumb", + views: { "@": { component: DemoBreadcrumbComponent } } + }, + { + name: "demo.button", + url: "/button", + views: { "@": { component: DemoButtonComponent } } + }, + { + name: "demo.card", + url: "/card", + views: { "@": { component: DemoCardComponent } } + }, + { + name: "demo.collapsible", + url: "/collapsible", + views: { "@": { component: DemoCollapsibleComponent } } + }, + { + name: "demo.colors", + url: "/colors", + views: { "@": { component: DemoColorsComponent } } + }, + { + name: "demo.date-picker", + url: "/date-picker", + views: { "@": { component: DemoDatePickerComponent } } + }, + { + name: "demo.date-range-picker", + url: "/date-range-picker", + views: { "@": { component: DemoDateRangePickerComponent } } + }, + { + name: "demo.dropdown", + url: "/dropdown", + views: { "@": { component: DemoDropdownComponent } } + }, + { + name: "demo.stark-footer", + url: "/stark-footer", + views: { "@": { component: DemoFooterComponent } } + }, + { + name: "demo.stark-header", + url: "/stark-header", + views: { "@": { component: DemoHeaderComponent } } + }, + { + name: "demo.example-viewer", + url: "/example-viewer", + views: { "@": { component: DemoExampleViewerComponent } } + }, + { + name: "demo.keyboard-directives", + url: "/keyboard-directives", + views: { "@": { component: DemoKeyboardDirectivesComponent } } + }, + { + name: "demo.language-selector", + url: "/language-selector", + views: { "@": { component: DemoLanguageSelectorComponent } } + }, + { + name: "demo.logout", + url: "/logout", + views: { "@": { component: DemoLogoutComponent } } + }, + { + name: "demo.menu", + url: "/menu", + views: { "@": { component: DemoMenuComponent } } + }, + { + name: "demo.pagination", + url: "/pagination", + views: { "@": { component: DemoPaginationComponent } } + }, + { + name: "demo.pretty-print", + url: "/pretty-print", + views: { "@": { component: DemoPrettyPrintComponent } } + }, + { + name: "demo.slider", + url: "/slider", + views: { "@": { component: DemoSliderComponent } } + }, + { + name: "demo.sidebar", + url: "/sidebar", + views: { "@": { component: DemoSidebarComponent } } + }, + { + name: "demo.table", + url: "/table", + views: { "@": { component: DemoTableComponent } } + }, + { + name: "demo.toast", + url: "/toast", + views: { "@": { component: DemoToastComponent } } + }, + { + name: "demo.typography", + url: "/typography", + views: { "@": { component: DemoTypographyComponent } } + } +]; diff --git a/showcase/src/app/in-memory-data/services/in-memory-data.service.ts b/showcase/src/app/in-memory-data/services/in-memory-data.service.ts index b4f6426885..bbc88ee178 100644 --- a/showcase/src/app/in-memory-data/services/in-memory-data.service.ts +++ b/showcase/src/app/in-memory-data/services/in-memory-data.service.ts @@ -12,7 +12,7 @@ import { import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium/stark-core"; const _cloneDeep: Function = require("lodash/cloneDeep"); -const mockData: any = require("../../../../config/json-server/data.json"); +const mockData: object = require("../../../../config/json-server/data.json"); @Injectable() export class InMemoryDataService implements InMemoryDbService { @@ -29,10 +29,11 @@ export class InMemoryDataService implements InMemoryDbService { */ public createDb(_reqInfo?: RequestInfo): {} | Observable<{}> | Promise<{}> { // replace the "uuid" field defined in the mock data by the "id" field expected by the in-memory-db - this.deepReplaceProperty(mockData, "uuid", "id"); + const normalizedMockData: object = _cloneDeep(mockData); // avoid modifying the original mock data + this.deepReplaceProperty(normalizedMockData, "uuid", "id"); // IMPORTANT: cannot mock "logging" and "logout" requests since they are performed via XHR and not via Angular - return mockData; + return normalizedMockData; } /** diff --git a/showcase/src/app/news/news.module.ts b/showcase/src/app/news/news.module.ts index edac5550d6..8b762ddf58 100644 --- a/showcase/src/app/news/news.module.ts +++ b/showcase/src/app/news/news.module.ts @@ -1,13 +1,23 @@ import { NgModule } from "@angular/core"; -import { NewsComponent } from "./news-component"; -import { NewsItemComponent } from "./news-item-component"; +import { CommonModule } from "@angular/common"; +import { UIRouterModule } from "@uirouter/angular"; import { MatIconModule } from "@angular/material/icon"; import { MatCardModule } from "@angular/material/card"; -import { CommonModule } from "@angular/common"; +import { NewsComponent } from "./news-component"; +import { NewsItemComponent } from "./news-item-component"; import { SharedModule } from "../shared"; +import { NEWS_STATES } from "./routes"; @NgModule({ - imports: [MatCardModule, MatIconModule, CommonModule, SharedModule], + imports: [ + UIRouterModule.forChild({ + states: NEWS_STATES + }), + CommonModule, + MatCardModule, + MatIconModule, + SharedModule + ], declarations: [NewsComponent, NewsItemComponent], exports: [NewsComponent, NewsItemComponent] }) diff --git a/showcase/src/app/news/routes.ts b/showcase/src/app/news/routes.ts new file mode 100644 index 0000000000..cc2c19cd78 --- /dev/null +++ b/showcase/src/app/news/routes.ts @@ -0,0 +1,11 @@ +import { Ng2StateDeclaration } from "@uirouter/angular"; +import { NewsComponent } from "./news-component"; + +export const NEWS_STATES: Ng2StateDeclaration[] = [ + { + name: "news", + url: "^/news", + views: { "@": { component: NewsComponent } }, + parent: "app" + } +];