From 1f2f9caceabb2922576bfce21aa3002d5f3071c8 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Tue, 19 Dec 2023 18:05:51 +0300 Subject: [PATCH 1/3] Add new layout component and define dynamic layouts --- docs/en/UI/Angular/Component-Replacement.md | 134 ++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index 1baf7e18be..eadb2579af 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -77,6 +77,140 @@ export class AppComponent { ![Layout Components](./images/layout-components.png) +### How to Add a New Layout Component + +To add a new layout component, you need to follow these steps: + +#### Step 1: Create a New Angular Component + +First, you need to create a new Angular component. This component should have a 'router-outlet' for dynamic content loading. You can create a new component using the Angular CLI. Run the following command in your terminal: + +```bash +ng generate component new-layout +``` +This command will create a new component named `new-layout`. Now, open the new-layout.component.html file and add a `router-outlet` to it: + +```html + +``` +This 'router-outlet' will act as a placeholder that Angular dynamically fills based on the current router state. + +note: (don't forget: you should add the app in the app.module.ts file) + +#### Step 2: Define a Variable for the Layout Component + +Although this step is optional, it can be useful if you're going to use the layout component's value multiple times. You can define a variable for the layout component like this: + +```javascript +export const eCustomLayout = { + key: 'CustomLayout', + component: 'CustomLayoutComponent', +}; +``` +In this variable, `key` is a unique identifier for the layout component, and `component` is the name of the layout component. +You can use this variable when you need to refer to the layout component. + +#### Step 3: Add the Layout Component to the ABP Replaceable-System + +Next, you need to add the new layout component to the `ReplaceableComponentsService`. This service allows you to replace a component with another one dynamically. + +You can do this by defining a provider for `APP_INITIALIZER` that uses a factory function. In this function, you inject the `ReplaceableComponentsService` and use its `add` method to add the new layout component. + +Here's how you can do it: + +```javascript +export const CUSTOM_LAYOUT_PROVIDERS = [ + { provide: APP_INITIALIZER, useFactory: configureFn, deps: [ReplaceableComponentsService], multi: true }, + +]; +function configureFn() { + const service= inject( ReplaceableComponentsService) + return () =>{ + service.add({ + key: eCustomLayout.component, + component: CustomLayoutComponent, + }) + } +} +``` +In this code, `configureFn` is a factory function that adds the new layout component to the `ReplaceableComponentsService`. The `APP_INITIALIZER` provider runs this function when the application starts. + +note: (don't forget: you should add the CUSTOM_LAYOUT_PROVIDERS in the app.module.ts file) + +#### Step 4: Define the Application's Dynamic Layouts + +Finally, you need to define the application's dynamic layouts. This is a map where the keys are the layout keys and the values are the layout components. + +You can add the new layout to the existing layouts like this: + +```javascript +export const myDynamicLayouts = new Map([...DEFAULT_DYNAMIC_LAYOUTS, [eCustomLayout.key, eCustomLayout.component]]); +``` + +#### Step 5: Pass the Dynamic Layouts to the CoreModule + +The final step is to pass the dynamic layouts to the `CoreModule` using the `forRoot` method. This method allows you to configure the module with a static method. + +Here's how you can do it: + +```javascript +@NgModule({ + declarations: [AppComponent], + imports: [ + // other imports... + CoreModule.forRoot({ + dynamicLayouts: myDynamicLayouts, + environment, + registerLocaleFn: registerLocale(), + }), + // other imports... + NewLayoutComponent + ], + providers: [APP_ROUTE_PROVIDER, CUSTOM_LAYOUT_PROVIDERS], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` +In this code, `myDynamicLayouts` is the map of dynamic layouts you defined earlier. We pass this map to the `CoreModule` using the `forRoot` method. + + +Now that you have defined the new layout, you can use it in the router definition. You do this by adding a new route that uses the new layout. + +Here's how you can do it: + +```javascript +// route.provider.ts +import { eCustomLayout } from './custom-layout/custom-layout.provider'; +import { RoutesService, eLayoutType } from '@abp/ng.core'; +import { APP_INITIALIZER } from '@angular/core'; + +export const APP_ROUTE_PROVIDER = [ + { provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true }, +]; + +function configureRoutes(routes: RoutesService) { + return () => { + routes.add([ + { + path: '/', + name: '::Menu:Home', + iconClass: 'fas fa-home', + order: 1, + layout: eLayoutType.application, + }, + { + path: '/dashboard', + name: '::Menu:Dashboard', + iconClass: 'fas fa-chart-line', + order: 2, + layout: eCustomLayout.key as eLayoutType, + requiredPolicy: 'MyProjectName.Dashboard.Host || MyProjectName.Dashboard.Tenant', + }, + ]); + }; +} +``` + #### How to Replace LogoComponent ![LogoComponent](./images/logo-component.png) From 1de18ccda26c435dec0af8c78fd97d07bbd620d4 Mon Sep 17 00:00:00 2001 From: Masum ULU <49063256+masumulu28@users.noreply.github.com> Date: Tue, 19 Dec 2023 21:06:00 +0300 Subject: [PATCH 2/3] update `configureFn` name to `configureLayoutFn` --- docs/en/UI/Angular/Component-Replacement.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index eadb2579af..48a5d4fa74 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -120,10 +120,10 @@ Here's how you can do it: ```javascript export const CUSTOM_LAYOUT_PROVIDERS = [ - { provide: APP_INITIALIZER, useFactory: configureFn, deps: [ReplaceableComponentsService], multi: true }, + { provide: APP_INITIALIZER, useFactory: configureLayoutFn, deps: [ReplaceableComponentsService], multi: true }, ]; -function configureFn() { +function configureLayoutFn() { const service= inject( ReplaceableComponentsService) return () =>{ service.add({ @@ -133,7 +133,7 @@ function configureFn() { } } ``` -In this code, `configureFn` is a factory function that adds the new layout component to the `ReplaceableComponentsService`. The `APP_INITIALIZER` provider runs this function when the application starts. +In this code, `configureLayoutFn` is a factory function that adds the new layout component to the `ReplaceableComponentsService`. The `APP_INITIALIZER` provider runs this function when the application starts. note: (don't forget: you should add the CUSTOM_LAYOUT_PROVIDERS in the app.module.ts file) From d759d26045c46a499314917def7a3563c457921b Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Fri, 29 Dec 2023 09:14:29 +0300 Subject: [PATCH 3/3] Update Component-Replacement.md --- docs/en/UI/Angular/Component-Replacement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index 48a5d4fa74..d21489d232 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -83,7 +83,7 @@ To add a new layout component, you need to follow these steps: #### Step 1: Create a New Angular Component -First, you need to create a new Angular component. This component should have a 'router-outlet' for dynamic content loading. You can create a new component using the Angular CLI. Run the following command in your terminal: +This component should have a 'router-outlet' for dynamic content loading. You can create a new component using the Angular CLI. Run the following command in your terminal: ```bash ng generate component new-layout