From d91fcede09e87894a948459f2b57a5895b156463 Mon Sep 17 00:00:00 2001 From: Ilkay Ilknur Date: Fri, 30 Apr 2021 16:49:55 +0300 Subject: [PATCH 1/9] global feature attributes added and base types updated. --- .../Admin/Tags/EntityTagAdminAppService.cs | 7 ++++--- .../CmsKit/Admin/Tags/TagAdminAppService.cs | 5 +++-- .../Public/Blogs/BlogPostPublicAppService.cs | 8 ++++---- .../Comments/CommentPublicAppService.cs | 19 +++++++++---------- .../Public/Pages/PagePublicAppService.cs | 3 +++ .../Public/Ratings/RatingPublicAppService.cs | 10 ++++++---- .../Reactions/ReactionPublicAppService.cs | 7 +++++-- 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs index 0095063e2b..221b32a245 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs @@ -1,10 +1,11 @@ -using System.Linq; -using System.Linq; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Tags; namespace Volo.CmsKit.Admin.Tags { + [RequiresGlobalFeature(typeof(TagsFeature))] public class EntityTagAdminAppService : CmsKitAdminAppServiceBase, IEntityTagAdminAppService { protected ITagDefinitionStore TagDefinitionStore { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs index da30721267..2977aab185 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs @@ -5,14 +5,15 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; -using Volo.Abp.Domain.Repositories; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; using Volo.CmsKit.Tags; namespace Volo.CmsKit.Admin.Tags { [Authorize(CmsKitAdminPermissions.Tags.Default)] + [RequiresGlobalFeature(typeof(TagsFeature))] public class TagAdminAppService : CmsKitAppServiceBase, ITagAdminAppService { protected ITagRepository Repository { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index 550d0cf9a8..6ae4a785d6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -1,14 +1,14 @@ using JetBrains.Annotations; -using System; using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; -using Volo.Abp.BlobStoring; -using Volo.Abp.Content; +using Volo.Abp.GlobalFeatures; using Volo.CmsKit.Blogs; +using Volo.CmsKit.GlobalFeatures; namespace Volo.CmsKit.Public.Blogs { + [RequiresGlobalFeature(typeof(BlogsFeature))] public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPublicAppService { protected IBlogRepository BlogRepository { get; } @@ -36,7 +36,7 @@ namespace Volo.CmsKit.Public.Blogs { var blog = await BlogRepository.GetBySlugAsync(blogSlug); - var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id,input.MaxResultCount, input.SkipCount, input.Sorting); + var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.MaxResultCount, input.SkipCount, input.Sorting); return new PagedResultDto( await BlogPostRepository.GetCountAsync(blogId: blog.Id), diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs index e3c9e8781c..f3341a8e7e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs @@ -1,22 +1,21 @@ -using System; +using Microsoft.AspNetCore.Authorization; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Options; -using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; using Volo.Abp.Authorization; using Volo.Abp.EventBus.Distributed; -using Volo.Abp.Uow; +using Volo.Abp.GlobalFeatures; using Volo.Abp.Users; using Volo.CmsKit.Comments; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Users; namespace Volo.CmsKit.Public.Comments { - public class CommentPublicAppService : ApplicationService, ICommentPublicAppService + [RequiresGlobalFeature(typeof(CommentsFeature))] + public class CommentPublicAppService : CmsKitPublicAppServiceBase, ICommentPublicAppService { protected ICommentRepository CommentRepository { get; } protected ICmsUserLookupService CmsUserLookupService { get; } @@ -50,7 +49,7 @@ namespace Volo.CmsKit.Public.Comments { var user = await CmsUserLookupService.GetByIdAsync(CurrentUser.GetId()); - if(input.RepliedCommentId.HasValue) + if (input.RepliedCommentId.HasValue) { await CommentRepository.GetAsync(input.RepliedCommentId.Value); } @@ -111,8 +110,8 @@ namespace Volo.CmsKit.Public.Comments //TODO: I think this method can be optimized if you use dictionaries instead of straight search var parentComments = comments - .Where(c=> c.Comment.RepliedCommentId == null) - .Select(c=> ObjectMapper.Map(c.Comment)) + .Where(c => c.Comment.RepliedCommentId == null) + .Select(c => ObjectMapper.Map(c.Comment)) .ToList(); foreach (var parentComment in parentComments) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs index 778b00d6c6..31fe76599f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs @@ -1,8 +1,11 @@ using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Pages; namespace Volo.CmsKit.Public.Pages { + [RequiresGlobalFeature(typeof(PagesFeature))] public class PagePublicAppService : CmsKitPublicAppServiceBase, IPagePublicAppService { protected IPageRepository PageRepository { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs index f3a9925d72..6fa4677710 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs @@ -1,15 +1,17 @@ -using System.Collections.Generic; +using Microsoft.AspNetCore.Authorization; +using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Volo.Abp.Application.Services; using Volo.Abp.Authorization; +using Volo.Abp.GlobalFeatures; using Volo.Abp.Users; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Ratings; using Volo.CmsKit.Users; namespace Volo.CmsKit.Public.Ratings { - public class RatingPublicAppService : ApplicationService, IRatingPublicAppService + [RequiresGlobalFeature(typeof(RatingsFeature))] + public class RatingPublicAppService : CmsKitPublicAppServiceBase, IRatingPublicAppService { protected IRatingRepository RatingRepository { get; } public ICmsUserLookupService CmsUserLookupService { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Reactions/ReactionPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Reactions/ReactionPublicAppService.cs index ae8e725655..4f9746ef9f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Reactions/ReactionPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Reactions/ReactionPublicAppService.cs @@ -1,13 +1,16 @@ -using System.Collections.Generic; +using Microsoft.AspNetCore.Authorization; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; +using Volo.Abp.GlobalFeatures; using Volo.Abp.Users; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Reactions; namespace Volo.CmsKit.Public.Reactions { + [RequiresGlobalFeature(typeof(ReactionsFeature))] public class ReactionPublicAppService : CmsKitPublicAppServiceBase, IReactionPublicAppService { protected IReactionDefinitionStore ReactionDefinitionStore { get; } From 72c2020f37600fffdbfb4c06611b62fadbc5e8dd Mon Sep 17 00:00:00 2001 From: Ilkay Ilknur Date: Tue, 4 May 2021 17:32:42 +0300 Subject: [PATCH 2/9] json document has been added. --- docs/en/JSON.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docs/en/JSON.md diff --git a/docs/en/JSON.md b/docs/en/JSON.md new file mode 100644 index 0000000000..fa847ebbb6 --- /dev/null +++ b/docs/en/JSON.md @@ -0,0 +1,51 @@ +# JSON +The ABP Framework provides an abstraction to work with JSON. Having such an abstraction has some benefits; + +* You can write library independent code. Therefore, you can change the underlying library with the minimum effort and code change. +* You can easily change the underlying JSON library (System.Text.Json, Newtonsoft.Json, etc.) by configuring the options. +* You can use the predefined converters defined in the ABP without worrying about the underlying library's internal details. + +> The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package. Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). + +## IJsonSerializer + +You can inject `IJsonSerializer` and use it for JSON operations. Here is the available operations in the `IJsonSerializer` interface. + +```csharp +public interface IJsonSerializer +{ + string Serialize(object obj, bool camelCase = true, bool indented = false); + T Deserialize(string jsonString, bool camelCase = true); + object Deserialize(Type type, string jsonString, bool camelCase = true); +} +``` +Usage Example: + +```csharp +public class ProductManager +{ + public IJsonSerializer JsonSerializer { get; } + + public ProductManager(IJsonSerializer jsonSerializer) + { + JsonSerializer = jsonSerializer; + } + + public void SendRequest(Product product) + { + var json= JsonSerializer.Serialize(product); + // Left blank intentionally for demo purposes... + } +} +``` + +## Configuration + +`AbpJsonOptions` type provides options for the JSON operations in the ABP Framework. + +Properties: +* **DefaultDateTimeFormat(`string`)**: Default `DateTime` format. +* **UseHybridSerializer(`bool`)**: True by default. Boolean field indicating whether the ABP Framework uses the hybrid approach or not. If the field is true, it will try to use `System.Json.Text` to handle JSON if it can otherwise use the `Newtonsoft.Json.` +* **Providers(`ITypeList`)**: List of JSON serializer providers implementing the `IJsonSerializerProvider` interface. You can create and add custom serializers to the list, and the ABP Framework uses them automatically. When the `Serialize` or `Deserialize` method is called on the `IJsonSerializer` interface, the ABP Framework calls the `CanHandle` methods of the given providers in reverse order and uses the first provider that returns `true` to do the JSON operation. + + From 0132d95a2ab297f20ef29a856f7ae4a0931f3924 Mon Sep 17 00:00:00 2001 From: Ilkay Ilknur Date: Tue, 4 May 2021 17:32:57 +0300 Subject: [PATCH 3/9] JSON document added to the navigation --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 03c8ff2c4c..6c1755b033 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -320,6 +320,10 @@ } ] }, + { + "text": "JSON", + "path": "JSON.md" + }, { "text": "Features", "path": "Features.md" From 939e891ae816551f26abdf47756085b082908e10 Mon Sep 17 00:00:00 2001 From: Ilkay Ilknur Date: Fri, 7 May 2021 12:32:17 +0300 Subject: [PATCH 4/9] duplicate statement removed. --- docs/en/JSON.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/en/JSON.md b/docs/en/JSON.md index fa847ebbb6..33ef889711 100644 --- a/docs/en/JSON.md +++ b/docs/en/JSON.md @@ -2,7 +2,6 @@ The ABP Framework provides an abstraction to work with JSON. Having such an abstraction has some benefits; * You can write library independent code. Therefore, you can change the underlying library with the minimum effort and code change. -* You can easily change the underlying JSON library (System.Text.Json, Newtonsoft.Json, etc.) by configuring the options. * You can use the predefined converters defined in the ABP without worrying about the underlying library's internal details. > The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package. Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). @@ -48,4 +47,3 @@ Properties: * **UseHybridSerializer(`bool`)**: True by default. Boolean field indicating whether the ABP Framework uses the hybrid approach or not. If the field is true, it will try to use `System.Json.Text` to handle JSON if it can otherwise use the `Newtonsoft.Json.` * **Providers(`ITypeList`)**: List of JSON serializer providers implementing the `IJsonSerializerProvider` interface. You can create and add custom serializers to the list, and the ABP Framework uses them automatically. When the `Serialize` or `Deserialize` method is called on the `IJsonSerializer` interface, the ABP Framework calls the `CanHandle` methods of the given providers in reverse order and uses the first provider that returns `true` to do the JSON operation. - From 8553bd39b6dd3787f2a1772984b6eb3bd57461c0 Mon Sep 17 00:00:00 2001 From: Ilkay Ilknur Date: Fri, 7 May 2021 13:14:29 +0300 Subject: [PATCH 5/9] AbpSystemTextJsonSerializerOptions description added. --- docs/en/JSON.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/en/JSON.md b/docs/en/JSON.md index 33ef889711..29e93007af 100644 --- a/docs/en/JSON.md +++ b/docs/en/JSON.md @@ -40,6 +40,8 @@ public class ProductManager ## Configuration +### AbpJsonOptions + `AbpJsonOptions` type provides options for the JSON operations in the ABP Framework. Properties: @@ -47,3 +49,12 @@ Properties: * **UseHybridSerializer(`bool`)**: True by default. Boolean field indicating whether the ABP Framework uses the hybrid approach or not. If the field is true, it will try to use `System.Json.Text` to handle JSON if it can otherwise use the `Newtonsoft.Json.` * **Providers(`ITypeList`)**: List of JSON serializer providers implementing the `IJsonSerializerProvider` interface. You can create and add custom serializers to the list, and the ABP Framework uses them automatically. When the `Serialize` or `Deserialize` method is called on the `IJsonSerializer` interface, the ABP Framework calls the `CanHandle` methods of the given providers in reverse order and uses the first provider that returns `true` to do the JSON operation. +### AbpSystemTextJsonSerializerOptions + +`AbpSystemTextJsonSerializerOptions` provides options for `System.Text.Json` usage. + +Properties: + +- **JsonSerializerOptions(`System.Text.Json.JsonSerializerOptions`)**: Global options for System.Text.Json library operations. See [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) for reference. +- **UnsupportedTypes(`ITypeList`)**: List of the unsupported types. You can add types of the unsupported types to the list and, the hybrid JSON serializer automatically uses the `Newtonsoft.Json` library instead of `System.Text.Json`. + From 917aff08a5e74579a50a48bdd606629f3cdeadc7 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 17 May 2021 13:18:53 +0300 Subject: [PATCH 6/9] docs: resolve example nav items component problems --- docs/en/UI/Angular/Component-Replacement.md | 125 +++++++++----------- 1 file changed, 55 insertions(+), 70 deletions(-) diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index 0010a30a2f..1b757c7c23 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -84,11 +84,10 @@ export class AppComponent { Run the following command in `angular` folder to create a new component called `LogoComponent`. ```bash -yarn ng generate component logo --inlineTemplate --inlineStyle --entryComponent - -# You don't need the --entryComponent option in Angular 9 +yarn ng generate component logo --inlineTemplate --inlineStyle ``` + Open the generated `logo.component.ts` in `src/app/logo` folder and replace its content with the following: ```js @@ -115,7 +114,7 @@ Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService -import { LogoComponent } from './logo/logo.component'; // imported NavItemsComponent +import { LogoComponent } from './logo/logo.component'; // imported LogoComponent import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents //... @@ -151,36 +150,18 @@ yarn ng generate component routes Open the generated `routes.component.ts` in `src/app/routes` folder and replace its content with the following: ```js -import { ABP } from '@abp/ng.core'; -import { - Component, - HostBinding, - Inject, - Renderer2, - TrackByFunction, - AfterViewInit, -} from '@angular/core'; -import { fromEvent } from 'rxjs'; -import { debounceTime } from 'rxjs/operators'; +import { Component, HostBinding } from '@angular/core'; @Component({ selector: 'app-routes', templateUrl: 'routes.component.html', }) -export class RoutesComponent implements AfterViewInit { +export class RoutesComponent { @HostBinding('class.mx-auto') marginAuto = true; - smallScreen = window.innerWidth < 992; - - constructor(private renderer: Renderer2) {} - - ngAfterViewInit() { - fromEvent(window, 'resize') - .pipe(debounceTime(150)) - .subscribe(() => { - this.smallScreen = window.innerWidth < 992; - }); + get smallScreen() { + return window.innerWidth < 992; } } ``` @@ -310,7 +291,7 @@ Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService -import { RoutesComponent } from './routes/routes.component'; // imported NavItemsComponent +import { RoutesComponent } from './routes/routes.component'; // imported RoutesComponent import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents //... @@ -347,51 +328,51 @@ Open the generated `nav-items.component.ts` in `src/app/nav-items` folder and re ```js import { - ApplicationConfiguration, AuthService, - ConfigState, + ConfigStateService, + CurrentUserDto, + LanguageInfo, + NAVIGATE_TO_MANAGE_PROFILE, SessionStateService, - SetLanguage, } from '@abp/ng.core'; -import { Component, AfterViewInit } from '@angular/core'; -import { Navigate, RouterState } from '@ngxs/router-plugin'; -import { Select, Store } from '@ngxs/store'; -import { Observable, fromEvent } from 'rxjs'; -import { map, debounceTime } from 'rxjs/operators'; +import { Component, Inject } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; import snq from 'snq'; @Component({ selector: 'app-nav-items', templateUrl: 'nav-items.component.html', }) -export class NavItemsComponent implements AfterViewInit { - @Select(ConfigState.getOne('currentUser')) - currentUser$: Observable; +export class NavItemsComponent { + currentUser$: Observable = this.configState.getOne$('currentUser'); + selectedTenant$ = this.sessionState.getTenant$(); - @Select(ConfigState.getDeep('localization.languages')) - languages$: Observable; + languages$: Observable = this.configState.getDeep$('localization.languages'); - smallScreen = window.innerWidth < 992; + get smallScreen(): boolean { + return window.innerWidth < 992; + } get defaultLanguage$(): Observable { return this.languages$.pipe( map( languages => snq( - () => languages.find(lang => lang.cultureName === this.selectedLangCulture).displayName, + () => languages.find(lang => lang.cultureName === this.selectedLangCulture).displayName ), - '', - ), + '' + ) ); } - get dropdownLanguages$(): Observable { + get dropdownLanguages$(): Observable { return this.languages$.pipe( map( languages => snq(() => languages.filter(lang => lang.cultureName !== this.selectedLangCulture)), - [], - ), + [] + ) ); } @@ -399,28 +380,23 @@ export class NavItemsComponent implements AfterViewInit { return this.sessionState.getLanguage(); } - constructor(private store: Store, private authService: AuthService, private sessionState: SessionStateService) {} + constructor( + @Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile, + private configState: ConfigStateService, + private authService: AuthService, + private sessionState: SessionStateService + ) {} - ngAfterViewInit() { - fromEvent(window, 'resize') - .pipe(debounceTime(150)) - .subscribe(() => { - this.smallScreen = window.innerWidth < 992; - }); + onChangeLang(cultureName: string) { + this.sessionState.setLanguage(cultureName); } - onChangeLang(cultureName: string) { - this.store.dispatch(new SetLanguage(cultureName)); + navigateToLogin() { + this.authService.navigateToLogin(); } logout() { - this.authService.logout().subscribe(() => { - this.store.dispatch( - new Navigate(['/'], null, { - state: { redirectUrl: this.store.selectSnapshot(RouterState).state.url }, - }), - ); - }); + this.authService.logout().subscribe(); } } ``` @@ -445,8 +421,14 @@ Open the generated `nav-items.component.html` in `src/app/nav-items` folder and ```html