From 2cecca0128ccc6662a8d87c3df08761792947e17 Mon Sep 17 00:00:00 2001 From: Hung Pham Date: Sat, 18 Apr 2026 05:53:29 +0700 Subject: [PATCH] feat(challenge 31): convert to standalone --- .../src/app/app.component.ts | 3 +- .../src/app/app.config.ts | 12 ++++++++ .../src/app/app.module.ts | 11 ------- .../31-module-to-standalone/src/main.ts | 14 ++++----- .../admin/feature/src/index.ts | 2 +- .../feature/src/lib/admin-feature.module.ts | 27 ----------------- .../feature/src/lib/admin-feature.routes.ts | 14 +++++++++ .../lib/create-user/create-user.component.ts | 14 ++------- .../src/lib/dashboard/dashboard.component.ts | 14 ++------- .../admin/shared/src/lib/authorized.guard.ts | 29 ++++++++----------- .../core/providers/src/lib/token.provider.ts | 2 +- .../forbidden/src/index.ts | 2 +- .../forbidden/src/lib/forbidden.component.ts | 5 ++-- .../forbidden/src/lib/forbidden.module.ts | 13 --------- libs/module-to-standalone/home/src/index.ts | 2 +- .../home/src/lib/home.component.ts | 9 +++--- .../home/src/lib/home.module.ts | 13 --------- libs/module-to-standalone/shell/src/index.ts | 2 +- .../shell/src/lib/main-shell.module.ts | 11 ------- .../shell/src/lib/main-shell.routes.ts | 24 +++++---------- .../user/contact/src/index.ts | 2 +- .../contact/src/lib/contact-feature.module.ts | 27 ----------------- .../contact/src/lib/contact-feature.routes.ts | 14 +++++++++ .../create-contact.component.ts | 16 +++------- .../src/lib/dashboard/dashboard.component.ts | 16 +++------- .../user/home/src/index.ts | 2 +- .../user/home/src/lib/home.component.ts | 3 +- .../user/home/src/lib/home.module.ts | 11 ------- .../user/shell/src/index.ts | 2 +- .../shell/src/lib/user-shell.component.ts | 3 +- .../user/shell/src/lib/user-shell.module.ts | 13 --------- .../user/shell/src/lib/user-shell.routes.ts | 17 ++++++----- 32 files changed, 107 insertions(+), 242 deletions(-) create mode 100644 apps/angular/31-module-to-standalone/src/app/app.config.ts delete mode 100644 apps/angular/31-module-to-standalone/src/app/app.module.ts delete mode 100644 libs/module-to-standalone/admin/feature/src/lib/admin-feature.module.ts create mode 100644 libs/module-to-standalone/admin/feature/src/lib/admin-feature.routes.ts delete mode 100644 libs/module-to-standalone/forbidden/src/lib/forbidden.module.ts delete mode 100644 libs/module-to-standalone/home/src/lib/home.module.ts delete mode 100644 libs/module-to-standalone/shell/src/lib/main-shell.module.ts delete mode 100644 libs/module-to-standalone/user/contact/src/lib/contact-feature.module.ts create mode 100644 libs/module-to-standalone/user/contact/src/lib/contact-feature.routes.ts delete mode 100644 libs/module-to-standalone/user/home/src/lib/home.module.ts delete mode 100644 libs/module-to-standalone/user/shell/src/lib/user-shell.module.ts diff --git a/apps/angular/31-module-to-standalone/src/app/app.component.ts b/apps/angular/31-module-to-standalone/src/app/app.component.ts index 986df84b5..c3e2c6927 100644 --- a/apps/angular/31-module-to-standalone/src/app/app.component.ts +++ b/apps/angular/31-module-to-standalone/src/app/app.component.ts @@ -1,7 +1,9 @@ import { Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', + imports: [RouterOutlet, RouterLink], template: `
`, - standalone: false, }) -export class CreateUserComponent {} - -@NgModule({ - imports: [ - RouterModule.forChild([{ path: '', component: CreateUserComponent }]), - ], - declarations: [CreateUserComponent], -}) -export class CreateUserModule {} +export default class CreateUserComponent {} diff --git a/libs/module-to-standalone/admin/feature/src/lib/dashboard/dashboard.component.ts b/libs/module-to-standalone/admin/feature/src/lib/dashboard/dashboard.component.ts index 801efb520..340b792ca 100644 --- a/libs/module-to-standalone/admin/feature/src/lib/dashboard/dashboard.component.ts +++ b/libs/module-to-standalone/admin/feature/src/lib/dashboard/dashboard.component.ts @@ -1,5 +1,4 @@ -import { Component, NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { Component } from '@angular/core'; @Component({ selector: 'lib-dashboard', @@ -12,14 +11,5 @@ import { RouterModule } from '@angular/router'; Create User `, - standalone: false, }) -export class DashboardComponent {} - -@NgModule({ - imports: [ - RouterModule.forChild([{ path: '', component: DashboardComponent }]), - ], - declarations: [DashboardComponent], -}) -export class DashboardModule {} +export default class DashboardComponent {} diff --git a/libs/module-to-standalone/admin/shared/src/lib/authorized.guard.ts b/libs/module-to-standalone/admin/shared/src/lib/authorized.guard.ts index ea1a312ed..215adbae6 100644 --- a/libs/module-to-standalone/admin/shared/src/lib/authorized.guard.ts +++ b/libs/module-to-standalone/admin/shared/src/lib/authorized.guard.ts @@ -1,21 +1,16 @@ -import { CanActivate, Router, UrlTree } from '@angular/router'; +import { CanActivateFn, Router } from '@angular/router'; import { AuthorizationService } from '@angular-challenges/module-to-standalone/core/service'; -import { inject, Injectable } from '@angular/core'; -import { map, Observable } from 'rxjs'; +import { inject } from '@angular/core'; +import { map } from 'rxjs'; -@Injectable({ - providedIn: 'root', -}) -export class IsAuthorizedGuard implements CanActivate { - private authorizationService = inject(AuthorizationService); - private router = inject(Router); +export const isAuthorizedGuard: CanActivateFn = () => { + const authorizationService = inject(AuthorizationService); + const router = inject(Router); - canActivate(): Observable { - return this.authorizationService.isAuthorized$.pipe( - map((isAuthorized) => - isAuthorized ? true : this.router.createUrlTree(['forbidden']), - ), - ); - } -} + return authorizationService.isAuthorized$.pipe( + map((isAuthorized) => { + return isAuthorized ? true : router.createUrlTree(['forbidden']); + }), + ); +}; diff --git a/libs/module-to-standalone/core/providers/src/lib/token.provider.ts b/libs/module-to-standalone/core/providers/src/lib/token.provider.ts index 3f498ee06..132f3fde6 100644 --- a/libs/module-to-standalone/core/providers/src/lib/token.provider.ts +++ b/libs/module-to-standalone/core/providers/src/lib/token.provider.ts @@ -4,7 +4,7 @@ import { makeEnvironmentProviders, } from '@angular/core'; -export const TOKEN = new InjectionToken('token'); +export const TOKEN = new InjectionToken('token'); export const provideToken = (token: string): EnvironmentProviders => { return makeEnvironmentProviders([ diff --git a/libs/module-to-standalone/forbidden/src/index.ts b/libs/module-to-standalone/forbidden/src/index.ts index 672622f64..dd4219cc6 100644 --- a/libs/module-to-standalone/forbidden/src/index.ts +++ b/libs/module-to-standalone/forbidden/src/index.ts @@ -1 +1 @@ -export * from './lib/forbidden.module'; +export { default } from './lib/forbidden.component'; diff --git a/libs/module-to-standalone/forbidden/src/lib/forbidden.component.ts b/libs/module-to-standalone/forbidden/src/lib/forbidden.component.ts index a5e6e2d77..217d8ac85 100644 --- a/libs/module-to-standalone/forbidden/src/lib/forbidden.component.ts +++ b/libs/module-to-standalone/forbidden/src/lib/forbidden.component.ts @@ -1,10 +1,9 @@ import { Component } from '@angular/core'; @Component({ - selector: 'lib-home', + selector: 'lib-forbidden', template: ` Forbidden component `, - standalone: false, }) -export class ForbiddenComponent {} +export default class ForbiddenComponent {} diff --git a/libs/module-to-standalone/forbidden/src/lib/forbidden.module.ts b/libs/module-to-standalone/forbidden/src/lib/forbidden.module.ts deleted file mode 100644 index 0b363bf04..000000000 --- a/libs/module-to-standalone/forbidden/src/lib/forbidden.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; -import { ForbiddenComponent } from './forbidden.component'; - -@NgModule({ - declarations: [ForbiddenComponent], - imports: [ - CommonModule, - RouterModule.forChild([{ path: '', component: ForbiddenComponent }]), - ], -}) -export class ForbiddenModule {} diff --git a/libs/module-to-standalone/home/src/index.ts b/libs/module-to-standalone/home/src/index.ts index fe97ad579..5055b06fe 100644 --- a/libs/module-to-standalone/home/src/index.ts +++ b/libs/module-to-standalone/home/src/index.ts @@ -1 +1 @@ -export * from './lib/home.module'; +export { default } from './lib/home.component'; diff --git a/libs/module-to-standalone/home/src/lib/home.component.ts b/libs/module-to-standalone/home/src/lib/home.component.ts index bf350d47d..4e71351e3 100644 --- a/libs/module-to-standalone/home/src/lib/home.component.ts +++ b/libs/module-to-standalone/home/src/lib/home.component.ts @@ -1,18 +1,20 @@ import { TOKEN } from '@angular-challenges/module-to-standalone/core/providers'; import { AuthorizationService } from '@angular-challenges/module-to-standalone/core/service'; +import { CommonModule } from '@angular/common'; import { Component, inject } from '@angular/core'; @Component({ selector: 'lib-home', + imports: [CommonModule], template: ` Home component
Authorization : - - (isAuthorized: {{ authorizeService.isAuthorized$ | async }}) @@ -20,9 +22,8 @@ import { Component, inject } from '@angular/core';
LoadedToken {{ token }}
`, - standalone: false, }) -export class HomeComponent { +export default class HomeComponent { public authorizeService = inject(AuthorizationService); public token = inject(TOKEN); } diff --git a/libs/module-to-standalone/home/src/lib/home.module.ts b/libs/module-to-standalone/home/src/lib/home.module.ts deleted file mode 100644 index 30ae1ea8a..000000000 --- a/libs/module-to-standalone/home/src/lib/home.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; -import { HomeComponent } from './home.component'; - -@NgModule({ - declarations: [HomeComponent], - imports: [ - RouterModule.forChild([{ path: '', component: HomeComponent }]), - CommonModule, - ], -}) -export class ModuleToStandaloneHomeModule {} diff --git a/libs/module-to-standalone/shell/src/index.ts b/libs/module-to-standalone/shell/src/index.ts index 494d4096f..902420448 100644 --- a/libs/module-to-standalone/shell/src/index.ts +++ b/libs/module-to-standalone/shell/src/index.ts @@ -1 +1 @@ -export * from './lib/main-shell.module'; +export * from './lib/main-shell.routes'; diff --git a/libs/module-to-standalone/shell/src/lib/main-shell.module.ts b/libs/module-to-standalone/shell/src/lib/main-shell.module.ts deleted file mode 100644 index e886da911..000000000 --- a/libs/module-to-standalone/shell/src/lib/main-shell.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { provideToken } from '@angular-challenges/module-to-standalone/core/providers'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; -import { appRoutes } from './main-shell.routes'; - -@NgModule({ - imports: [RouterModule.forRoot(appRoutes)], - exports: [RouterModule], - providers: [provideToken('main-shell-token')], -}) -export class MainShellModule {} diff --git a/libs/module-to-standalone/shell/src/lib/main-shell.routes.ts b/libs/module-to-standalone/shell/src/lib/main-shell.routes.ts index 84f9a8d03..66bd1cb94 100644 --- a/libs/module-to-standalone/shell/src/lib/main-shell.routes.ts +++ b/libs/module-to-standalone/shell/src/lib/main-shell.routes.ts @@ -1,36 +1,28 @@ -import { IsAuthorizedGuard } from '@angular-challenges/module-to-standalone/admin/shared'; +import { isAuthorizedGuard } from '@angular-challenges/module-to-standalone/admin/shared'; import { Route } from '@angular/router'; export const appRoutes: Route[] = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', - loadChildren: () => - import('@angular-challenges/module-to-standalone/home').then( - (m) => m.ModuleToStandaloneHomeModule, - ), + loadComponent: () => + import('@angular-challenges/module-to-standalone/home'), }, { path: 'admin', - canActivate: [IsAuthorizedGuard], + canActivate: [isAuthorizedGuard], loadChildren: () => - import('@angular-challenges/module-to-standalone/admin/feature').then( - (m) => m.AdminFeatureModule, - ), + import('@angular-challenges/module-to-standalone/admin/feature'), }, { path: 'user', loadChildren: () => - import('@angular-challenges/module-to-standalone/user/shell').then( - (m) => m.UserShellModule, - ), + import('@angular-challenges/module-to-standalone/user/shell'), }, { path: 'forbidden', - loadChildren: () => - import('@angular-challenges/module-to-standalone/forbidden').then( - (m) => m.ForbiddenModule, - ), + loadComponent: () => + import('@angular-challenges/module-to-standalone/forbidden'), }, ]; diff --git a/libs/module-to-standalone/user/contact/src/index.ts b/libs/module-to-standalone/user/contact/src/index.ts index 8561ea519..aae753ee9 100644 --- a/libs/module-to-standalone/user/contact/src/index.ts +++ b/libs/module-to-standalone/user/contact/src/index.ts @@ -1 +1 @@ -export * from './lib/contact-feature.module'; +export { default } from './lib/contact-feature.routes'; diff --git a/libs/module-to-standalone/user/contact/src/lib/contact-feature.module.ts b/libs/module-to-standalone/user/contact/src/lib/contact-feature.module.ts deleted file mode 100644 index 09da407c7..000000000 --- a/libs/module-to-standalone/user/contact/src/lib/contact-feature.module.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -@NgModule({ - declarations: [], - imports: [ - CommonModule, - RouterModule.forChild([ - { - path: '', - loadChildren: () => - import('./dashboard/dashboard.component').then( - (m) => m.ContactDashboardModule, - ), - }, - { - path: 'create-contact', - loadChildren: () => - import('./create-contact/create-contact.component').then( - (m) => m.CreateContactModule, - ), - }, - ]), - ], -}) -export class ContactFeatureModule {} diff --git a/libs/module-to-standalone/user/contact/src/lib/contact-feature.routes.ts b/libs/module-to-standalone/user/contact/src/lib/contact-feature.routes.ts new file mode 100644 index 000000000..88d9cb7d1 --- /dev/null +++ b/libs/module-to-standalone/user/contact/src/lib/contact-feature.routes.ts @@ -0,0 +1,14 @@ +import { Route } from '@angular/router'; + +const contactFeatureRoutes: Route[] = [ + { + path: '', + loadComponent: () => import('./dashboard/dashboard.component'), + }, + { + path: 'create-contact', + loadComponent: () => import('./create-contact/create-contact.component'), + }, +]; + +export default contactFeatureRoutes; diff --git a/libs/module-to-standalone/user/contact/src/lib/create-contact/create-contact.component.ts b/libs/module-to-standalone/user/contact/src/lib/create-contact/create-contact.component.ts index 9c5cea9ff..00e26cbe8 100644 --- a/libs/module-to-standalone/user/contact/src/lib/create-contact/create-contact.component.ts +++ b/libs/module-to-standalone/user/contact/src/lib/create-contact/create-contact.component.ts @@ -1,8 +1,9 @@ -import { Component, NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; @Component({ selector: 'lib-create-contact', + imports: [RouterLink], template: ` Create Contact Form @@ -12,14 +13,5 @@ import { RouterModule } from '@angular/router'; Back `, - standalone: false, }) -export class CreateContactComponent {} - -@NgModule({ - imports: [ - RouterModule.forChild([{ path: '', component: CreateContactComponent }]), - ], - declarations: [CreateContactComponent], -}) -export class CreateContactModule {} +export default class CreateContactComponent {} diff --git a/libs/module-to-standalone/user/contact/src/lib/dashboard/dashboard.component.ts b/libs/module-to-standalone/user/contact/src/lib/dashboard/dashboard.component.ts index 8e56b721a..b3f54fc0b 100644 --- a/libs/module-to-standalone/user/contact/src/lib/dashboard/dashboard.component.ts +++ b/libs/module-to-standalone/user/contact/src/lib/dashboard/dashboard.component.ts @@ -1,8 +1,9 @@ -import { Component, NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; @Component({ selector: 'lib-contact-dashboard', + imports: [RouterLink], template: ` Contact Dashboard @@ -12,14 +13,5 @@ import { RouterModule } from '@angular/router'; Create contact `, - standalone: false, }) -export class ContactDashboardComponent {} - -@NgModule({ - imports: [ - RouterModule.forChild([{ path: '', component: ContactDashboardComponent }]), - ], - declarations: [ContactDashboardComponent], -}) -export class ContactDashboardModule {} +export default class ContactDashboardComponent {} diff --git a/libs/module-to-standalone/user/home/src/index.ts b/libs/module-to-standalone/user/home/src/index.ts index fe97ad579..5055b06fe 100644 --- a/libs/module-to-standalone/user/home/src/index.ts +++ b/libs/module-to-standalone/user/home/src/index.ts @@ -1 +1 @@ -export * from './lib/home.module'; +export { default } from './lib/home.component'; diff --git a/libs/module-to-standalone/user/home/src/lib/home.component.ts b/libs/module-to-standalone/user/home/src/lib/home.component.ts index 253c76622..0e99bc79c 100644 --- a/libs/module-to-standalone/user/home/src/lib/home.component.ts +++ b/libs/module-to-standalone/user/home/src/lib/home.component.ts @@ -5,6 +5,5 @@ import { Component } from '@angular/core'; template: ` User Home component `, - standalone: false, }) -export class UserHomeComponent {} +export default class UserHomeComponent {} diff --git a/libs/module-to-standalone/user/home/src/lib/home.module.ts b/libs/module-to-standalone/user/home/src/lib/home.module.ts deleted file mode 100644 index ceeb49511..000000000 --- a/libs/module-to-standalone/user/home/src/lib/home.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; -import { UserHomeComponent } from './home.component'; - -@NgModule({ - declarations: [UserHomeComponent], - imports: [ - RouterModule.forChild([{ path: '', component: UserHomeComponent }]), - ], -}) -export class UserHomeModule {} diff --git a/libs/module-to-standalone/user/shell/src/index.ts b/libs/module-to-standalone/user/shell/src/index.ts index 641fd6817..06fd1285e 100644 --- a/libs/module-to-standalone/user/shell/src/index.ts +++ b/libs/module-to-standalone/user/shell/src/index.ts @@ -1 +1 @@ -export * from './lib/user-shell.module'; +export { default } from './lib/user-shell.routes'; diff --git a/libs/module-to-standalone/user/shell/src/lib/user-shell.component.ts b/libs/module-to-standalone/user/shell/src/lib/user-shell.component.ts index 558c4069f..723f43a0c 100644 --- a/libs/module-to-standalone/user/shell/src/lib/user-shell.component.ts +++ b/libs/module-to-standalone/user/shell/src/lib/user-shell.component.ts @@ -1,8 +1,10 @@ import { TOKEN } from '@angular-challenges/module-to-standalone/core/providers'; import { Component, inject } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; @Component({ selector: 'lib-user-shell', + imports: [RouterOutlet, RouterLink], template: ` -- User Panel --
@@ -27,7 +29,6 @@ import { Component, inject } from '@angular/core'; host: { class: 'flex flex-col p-4 gap-3 border border-blue', }, - standalone: false, }) export class UserShellComponent { public token = inject(TOKEN); diff --git a/libs/module-to-standalone/user/shell/src/lib/user-shell.module.ts b/libs/module-to-standalone/user/shell/src/lib/user-shell.module.ts deleted file mode 100644 index 433d6f77b..000000000 --- a/libs/module-to-standalone/user/shell/src/lib/user-shell.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { provideToken } from '@angular-challenges/module-to-standalone/core/providers'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; -import { UserShellComponent } from './user-shell.component'; -import { userShellRoutes } from './user-shell.routes'; - -@NgModule({ - imports: [CommonModule, RouterModule.forChild(userShellRoutes), RouterModule], - declarations: [UserShellComponent], - providers: [provideToken('user-token')], -}) -export class UserShellModule {} diff --git a/libs/module-to-standalone/user/shell/src/lib/user-shell.routes.ts b/libs/module-to-standalone/user/shell/src/lib/user-shell.routes.ts index b5813e5d5..dab0f3993 100644 --- a/libs/module-to-standalone/user/shell/src/lib/user-shell.routes.ts +++ b/libs/module-to-standalone/user/shell/src/lib/user-shell.routes.ts @@ -1,26 +1,27 @@ +import { provideToken } from '@angular-challenges/module-to-standalone/core/providers'; import { Route } from '@angular/router'; + import { UserShellComponent } from './user-shell.component'; -export const userShellRoutes: Route[] = [ +const userShellRoutes: Route[] = [ { path: '', component: UserShellComponent, + providers: [provideToken('user-token')], children: [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', - loadChildren: () => - import('@angular-challenges/module-to-standalone/user/home').then( - (m) => m.UserHomeModule, - ), + loadComponent: () => + import('@angular-challenges/module-to-standalone/user/home'), }, { path: 'contact', loadChildren: () => - import('@angular-challenges/module-to-standalone/user/contact').then( - (m) => m.ContactFeatureModule, - ), + import('@angular-challenges/module-to-standalone/user/contact'), }, ], }, ]; + +export default userShellRoutes;