From a3d86fed4b217bda123f4e700ff7ca72a1529b0c Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 6 Jan 2022 13:40:40 +0300 Subject: [PATCH 01/12] feat: create abstarct menu service --- .../src/lib/services/abstract-menu.service.ts | 60 +++++++++++++++++++ .../src/lib/services/nav-items.service.ts | 48 +-------------- 2 files changed, 63 insertions(+), 45 deletions(-) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts new file mode 100644 index 00000000000..2c3d904a1ba --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts @@ -0,0 +1,60 @@ +import { BehaviorSubject, Observable } from 'rxjs'; +import { NavItem } from '../models/nav-item'; + +export abstract class AbstractMenuService { + protected abstract baseClass; + + protected _items$ = new BehaviorSubject([]); + + get items(): T[] { + return this._items$.value; + } + + get items$(): Observable { + return this._items$.asObservable(); + } + + addItems(newItems: T[]) { + const items = [...this.items]; + newItems.forEach(item => { + const index = items.findIndex(i => i.id === item.id); + const data = new this.baseClass(item); + + if (index > -1) { + items[index] = data; + return; + } + + items.push(data); + }); + items.sort(this.sortItems); + this._items$.next(items); + } + + removeItem(id: string | number) { + const index = this.items.findIndex(item => item.id === id); + + if (index < 0) return; + + const items = [...this.items.slice(0, index), ...this.items.slice(index + 1)]; + this._items$.next(items); + } + + patchItem(id: string | number, item: Partial>) { + const index = this.items.findIndex(i => i.id === id); + + if (index < 0) return; + + const items = [...this.items]; + items[index] = new this.baseClass({ ...items[index], ...item }); + items.sort(this.sortItems); + this._items$.next(items); + } + + private sortItems(a: T, b: T) { + if (!a.order) return 1; + if (!b.order) return -1; + + return a.order - b.order; + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/nav-items.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/nav-items.service.ts index ca361a2940c..6aacdd279b5 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/nav-items.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/nav-items.service.ts @@ -1,50 +1,8 @@ import { Injectable } from '@angular/core'; -import { BehaviorSubject, Observable } from 'rxjs'; import { NavItem } from '../models/nav-item'; +import { AbstractMenuService } from './abstract-menu.service'; @Injectable({ providedIn: 'root' }) -export class NavItemsService { - private _items$ = new BehaviorSubject([]); - - get items(): NavItem[] { - return this._items$.value; - } - - get items$(): Observable { - return this._items$.asObservable(); - } - - addItems(newItems: NavItem[]) { - const items = [...this.items]; - newItems.forEach(item => items.push(new NavItem(item))); - items.sort(sortItems); - this._items$.next(items); - } - - removeItem(id: string | number) { - const index = this.items.findIndex(item => item.id === id); - - if (index < 0) return; - - const items = [...this.items.slice(0, index), ...this.items.slice(index + 1)]; - this._items$.next(items); - } - - patchItem(id: string | number, item: Partial>) { - const index = this.items.findIndex(i => i.id === id); - - if (index < 0) return; - - const items = [...this.items]; - items[index] = new NavItem({ ...items[index], ...item }); - items.sort(sortItems); - this._items$.next(items); - } -} - -function sortItems(a: NavItem, b: NavItem) { - if (!a.order) return 1; - if (!b.order) return -1; - - return a.order - b.order; +export class NavItemsService extends AbstractMenuService { + protected baseClass = NavItem; } From 97b426f8c17bac182fa3a1a846193289bd58e15e Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 6 Jan 2022 13:40:51 +0300 Subject: [PATCH 02/12] feat: create user-menu.service --- .../packages/theme-shared/src/lib/services/index.ts | 1 + .../theme-shared/src/lib/services/user-menu.service.ts | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/user-menu.service.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts index 5b973639172..0f98819137a 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts @@ -2,3 +2,4 @@ export * from './confirmation.service'; export * from './nav-items.service'; export * from './page-alert.service'; export * from './toaster.service'; +export * from './user-menu.service'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/user-menu.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/user-menu.service.ts new file mode 100644 index 00000000000..1d58170084e --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/user-menu.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@angular/core'; +import { UserMenu } from '../models/user-menu'; +import { AbstractMenuService } from './abstract-menu.service'; + +@Injectable({ providedIn: 'root' }) +export class UserMenuService extends AbstractMenuService { + protected baseClass = UserMenu; +} From 3ec9a83acd358fea1f4e533bd8033f771edf46c5 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 6 Jan 2022 13:41:22 +0300 Subject: [PATCH 03/12] feat: add user-menu.provider --- .../theme-basic/src/lib/enums/index.ts | 1 + .../src/lib/enums/user-menu-items.ts | 4 ++ .../theme-basic/src/lib/providers/index.ts | 1 + .../src/lib/providers/user-menu.provider.ts | 59 +++++++++++++++++++ .../theme-basic/src/lib/theme-basic.module.ts | 2 + .../theme-shared/src/lib/models/index.ts | 3 +- .../theme-shared/src/lib/models/user-menu.ts | 3 + 7 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 npm/ng-packs/packages/theme-basic/src/lib/enums/user-menu-items.ts create mode 100644 npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts diff --git a/npm/ng-packs/packages/theme-basic/src/lib/enums/index.ts b/npm/ng-packs/packages/theme-basic/src/lib/enums/index.ts index 07635cbbc8e..3c919aa2710 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/enums/index.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/enums/index.ts @@ -1 +1,2 @@ export * from './components'; +export * from './user-menu-items'; diff --git a/npm/ng-packs/packages/theme-basic/src/lib/enums/user-menu-items.ts b/npm/ng-packs/packages/theme-basic/src/lib/enums/user-menu-items.ts new file mode 100644 index 00000000000..42ab66e8021 --- /dev/null +++ b/npm/ng-packs/packages/theme-basic/src/lib/enums/user-menu-items.ts @@ -0,0 +1,4 @@ +export const enum eUserMenuItems { + MyAccount = 'UserMenu.MyAccount', + Logout = 'UserMenu.Logout', +} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/providers/index.ts b/npm/ng-packs/packages/theme-basic/src/lib/providers/index.ts index 8102d94f623..d3028eab68c 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/providers/index.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/providers/index.ts @@ -1,2 +1,3 @@ export * from './nav-item.provider'; export * from './styles.provider'; +export * from './user-menu.provider'; diff --git a/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts b/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts new file mode 100644 index 00000000000..5c36cc53472 --- /dev/null +++ b/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts @@ -0,0 +1,59 @@ +import { + AuthService, + ConfigStateService, + LocalizationService, + NAVIGATE_TO_MANAGE_PROFILE, +} from '@abp/ng.core'; +import { UserMenuService } from '@abp/ng.theme.shared'; +import { APP_INITIALIZER, Injector } from '@angular/core'; +import { filter } from 'rxjs/operators'; +import { eUserMenuItems } from '../enums/user-menu-items'; + +export const BASIC_THEME_USER_MENU_PROVIDERS = [ + { + provide: APP_INITIALIZER, + useFactory: configureUserMenu, + deps: [Injector], + multi: true, + }, +]; + +export function configureUserMenu(injector: Injector) { + const configState = injector.get(ConfigStateService); + const userMenu = injector.get(UserMenuService); + const localization = injector.get(LocalizationService); + const authService = injector.get(AuthService); + const navigateToManageProfile = injector.get(NAVIGATE_TO_MANAGE_PROFILE); + + return () => { + configState + .getAll$() + .pipe(filter(res => !!res?.localization)) + .subscribe(() => { + userMenu.addItems([ + { + id: eUserMenuItems.MyAccount, + order: 100, + html: ` + ${localization.instant('AbpAccount::MyAccount')} + `, + action: () => navigateToManageProfile(), + }, + { + id: eUserMenuItems.Logout, + order: 101, + html: ` + ${localization.instant('AbpUi::Logout')} + `, + action: () => { + authService.logout().subscribe(); + }, + }, + ]); + }); + }; +} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts b/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts index 17ef89338f5..a8020e50fed 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts @@ -23,6 +23,7 @@ import { ValidationErrorComponent } from './components/validation-error/validati import { LazyStyleHandler } from './handlers/lazy-style.handler'; import { BASIC_THEME_NAV_ITEM_PROVIDERS } from './providers/nav-item.provider'; import { BASIC_THEME_STYLES_PROVIDERS } from './providers/styles.provider'; +import { BASIC_THEME_USER_MENU_PROVIDERS } from './providers/user-menu.provider'; export const LAYOUTS = [ApplicationLayoutComponent, AccountLayoutComponent, EmptyLayoutComponent]; @@ -70,6 +71,7 @@ export class ThemeBasicModule { ngModule: ThemeBasicModule, providers: [ BASIC_THEME_NAV_ITEM_PROVIDERS, + BASIC_THEME_USER_MENU_PROVIDERS, BASIC_THEME_STYLES_PROVIDERS, { provide: VALIDATION_ERROR_TEMPLATE, diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts index d1e2e71c5c6..ca6aa741249 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts @@ -1,5 +1,6 @@ export * from './common'; export * from './confirmation'; +export * from './nav-item'; export * from './statistics'; export * from './toaster'; -export * from './nav-item'; +export * from './user-menu'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts new file mode 100644 index 00000000000..20b92b80824 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts @@ -0,0 +1,3 @@ +import { NavItem } from './nav-item'; + +export class UserMenu extends NavItem {} From b7e172656f41ff9253990148faeb2eea60f69390 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 6 Jan 2022 13:41:38 +0300 Subject: [PATCH 04/12] feat: user user-menu.service into the current-user component --- .../theme-basic/src/lib/components/index.ts | 2 +- .../nav-items/current-user.component.html | 20 +++++++++++++------ .../nav-items/current-user.component.ts | 8 ++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/index.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/index.ts index 7daf7f2c1a9..b5e0d52629c 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/index.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/index.ts @@ -7,6 +7,6 @@ export * from './logo/logo.component'; export * from './nav-items/current-user.component'; export * from './nav-items/languages.component'; export * from './nav-items/nav-items.component'; +export * from './page-alert-container/page-alert-container.component'; export * from './routes/routes.component'; export * from './validation-error/validation-error.component'; -export * from './page-alert-container/page-alert-container.component'; diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html index 64a1bb4d6a3..0a1dec59d01 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html @@ -31,11 +31,19 @@ aria-labelledby="dropdownMenuLink" [class.d-block]="smallScreen && currentUserDropdown.isOpen()" > - {{ 'AbpAccount::MyAccount' | abpLocalization }} - {{ 'AbpUi::Logout' | abpLocalization }} + + + + + diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts index fbfa01882ac..96198458375 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts @@ -5,7 +5,8 @@ import { NAVIGATE_TO_MANAGE_PROFILE, SessionStateService, } from '@abp/ng.core'; -import { Component, Inject } from '@angular/core'; +import { UserMenu, UserMenuService } from '@abp/ng.theme.shared'; +import { Component, Inject, TrackByFunction } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ @@ -16,12 +17,15 @@ export class CurrentUserComponent { currentUser$: Observable = this.configState.getOne$('currentUser'); selectedTenant$ = this.sessionState.getTenant$(); + trackByFn: TrackByFunction = (_, element) => element.id; + get smallScreen(): boolean { return window.innerWidth < 992; } constructor( - @Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile: () => void, + @Inject(NAVIGATE_TO_MANAGE_PROFILE) public readonly navigateToManageProfile: () => void, + public readonly userMenu: UserMenuService, private authService: AuthService, private configState: ConfigStateService, private sessionState: SessionStateService, From 1eb3c103854a89a29f53780fce07a91c5a526a34 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 6 Jan 2022 13:41:46 +0300 Subject: [PATCH 05/12] update yarn.lock --- npm/ng-packs/yarn.lock | 182 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 171 insertions(+), 11 deletions(-) diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index e968d45cbad..983efc03505 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -2,6 +2,120 @@ # yarn lockfile v1 +"@abp/ng.account.core@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.account.core/-/ng.account.core-5.0.1.tgz#ec29ad71cf88c9ac5975e7911e4263efc002d27d" + integrity sha512-h6E8FWE3qJzDObYYtrWEjAqGaoKRhmOERATdndqBElCKWc88BAoO+tCJ67fdi9EGcSyLeYnX2y3fR5QBrThe+g== + dependencies: + tslib "^2.0.0" + +"@abp/ng.account@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.account/-/ng.account-5.0.1.tgz#aa428813454dd065edc97be0080ef04c403f2720" + integrity sha512-VeT2zJjB07gFh/wionYiwRbAY+H1ZHf4ueC0xJLP6oADxRf7IZHxFcujsmpv0eB66Zyy3DZ9j6gkx3Kva5B+Rg== + dependencies: + "@abp/ng.account.core" "~5.0.1" + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.components@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.components/-/ng.components-5.0.1.tgz#9cd10f91d4da45eb435109fe3c75619f866aad63" + integrity sha512-SZR5+dlWydVJw27un+WFGb1Hnis3Dg+1hZXfHmIuAyX/Mr7l0X0JKKVxfWR+4u/A83xjBxYD4Zo6OaXpEn6cCg== + dependencies: + chart.js "^3.5.1" + ng-zorro-antd "^12.0.1" + tslib "^2.0.0" + +"@abp/ng.core@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-5.0.1.tgz#f507075dde476bb32d6b37792bce36443dd2fb83" + integrity sha512-Ta7SqOrrGXeXPM4N2bJuhK9awTHaYSsfE3GTCtOvBn11P/GxfsaUKJ7XFvAd1D/5+3BjF9+LF4EiWYZn1UaWUw== + dependencies: + "@abp/utils" "~5.0.1" + angular-oauth2-oidc "^12.1.0" + just-clone "^3.2.1" + just-compare "^1.4.0" + ts-toolbelt "6.15.4" + tslib "^2.0.0" + +"@abp/ng.feature-management@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-5.0.1.tgz#2cbc54f7ca209cc9397394eebabf69a9e5380613" + integrity sha512-evoX1hmFHdKWCW/H409KmXtcg2B9HKXgZTez9/yXV5+eluVm9HY/U/gtTmgMG3vMAfqAJMXQdOEeG/vo5JozsQ== + dependencies: + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.identity@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-5.0.1.tgz#71e25af3c5fa1f00967b98ec983d013291d76adc" + integrity sha512-AzrGyl88fX+qlZ3DiXqfxG5i4N4Yy6HTiOs6TFNwtEFfNICKXWWOAv6q6w8U50P35WpAytwyTnz9oYeAozn8cg== + dependencies: + "@abp/ng.permission-management" "~5.0.1" + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.permission-management@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-5.0.1.tgz#aa712868055ec71b9367b758d899d783df7f7115" + integrity sha512-8ge0TIrdtshEe/hUmmcSBU8T8onKSIBRR3dAkitPJRfU/FSDVB/qM4pOTjWzgL/Rghem+9y9LTV4UXvM3fw8eQ== + dependencies: + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.schematics@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.schematics/-/ng.schematics-5.0.1.tgz#f80077c7503789738c9238f4e6f57301a648fc9d" + integrity sha512-dRx1T/I+wAhb1oM+7M0qcnCPn6OPeDcm8NtTmolN8iLkCaMPUh5HkylPNnTvxLcUWXiOFqJtn2HBQn7SBD8Vnw== + dependencies: + "@angular-devkit/core" "~11.0.2" + "@angular-devkit/schematics" "~11.0.2" + got "^11.5.2" + jsonc-parser "^2.3.0" + should-quote "^1.0.0" + typescript "~3.9.2" + +"@abp/ng.setting-management@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-5.0.1.tgz#6d32ea9930ac23f56e91306872ce87ab5cc42e54" + integrity sha512-5DhYj14JqT1z2IFnCL4lSOfyK3+ZdJ2y8LOJBROJ9xLnvYUfwFaVcn+V3Iz0kM8v5huWQ+EKgjIZ47qdc/tPCQ== + dependencies: + "@abp/ng.components" "~5.0.1" + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.tenant-management@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-5.0.1.tgz#592da08b9376c00714bd4dd63f37e752c15de912" + integrity sha512-8m9HuStDWZsLCv6g6vK7l9k6wvK0oamgFuZrac9DjIHsruGdpLFdEeUvqhDhsyulMyk83OUEIi1hRgEX2PdQfg== + dependencies: + "@abp/ng.feature-management" "~5.0.1" + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.theme.basic@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-5.0.1.tgz#87d4eec12296c6747b5d9d37781c180334e36fbb" + integrity sha512-kzgc2plB9xPTFye8CVlALzCNL/UAAd+jVhl5wz1meau2l7vvnW5sCI6P64y9gpKipQYMSpRhbYYQSBi4JJGNeA== + dependencies: + "@abp/ng.account.core" "~5.0.1" + "@abp/ng.theme.shared" "~5.0.1" + tslib "^2.0.0" + +"@abp/ng.theme.shared@~5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-5.0.1.tgz#866e7733619c9c6bcb1d36c827369fff0e97c80b" + integrity sha512-XT1BGJiG9sqZJJGZcCN6+WvlbRdZPRBRnc6NvzZTPXGgnnX107N2lanIShulJiVUX68chkBd4yNuM8tM/hLiOg== + dependencies: + "@abp/ng.core" "~5.0.1" + "@fortawesome/fontawesome-free" "^5.15.4" + "@ng-bootstrap/ng-bootstrap" "11.0.0-beta.2" + "@ngx-validate/core" "^0.1.1" + "@swimlane/ngx-datatable" "^19.0.0" + bootstrap "^5.1.1" + tslib "^2.0.0" + "@abp/utils@~5.0.1": version "5.0.1" resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.0.1.tgz#57934383004a21172bf7e08130813c08946894fb" @@ -146,6 +260,17 @@ rxjs "6.6.2" source-map "0.7.3" +"@angular-devkit/core@11.0.7", "@angular-devkit/core@~11.0.2": + version "11.0.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-11.0.7.tgz#05b82be7e11ddc2a7836c777297ee45eee20ff55" + integrity sha512-1GKnIT++YSUHpzzRx9QC0+8yOw4wy+ZpiJVDlroPSeK4FGrTCJqJKenkfRjVFRFOSrzTiJds+IU6kI4+bFbw9g== + dependencies: + ajv "6.12.6" + fast-json-stable-stringify "2.1.0" + magic-string "0.25.7" + rxjs "6.6.3" + source-map "0.7.3" + "@angular-devkit/core@12.2.13": version "12.2.13" resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-12.2.13.tgz#db3929d1bfce71010b37fb7c4e6c33ef80a4f35f" @@ -179,6 +304,15 @@ ora "5.4.1" rxjs "6.6.7" +"@angular-devkit/schematics@~11.0.2": + version "11.0.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-11.0.7.tgz#7cd2398c98d82f8e5bdc3bb5c70e92d6b1d12a12" + integrity sha512-mKkXWmSTlZYjQO4i7xUX+bG1E9h9Ke3GgGQQouA+kth06IPO+VcywLQNsui4qcyLDUjyo8CaX+44aoSXoX3Tgg== + dependencies: + "@angular-devkit/core" "11.0.7" + ora "5.1.0" + rxjs "6.6.3" + "@angular-eslint/eslint-plugin-template@~12.3.0": version "12.3.1" resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-12.3.1.tgz#33260cd5356df5db7e27719443eabcf6c214e32e" @@ -3581,6 +3715,16 @@ ajv@6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@6.12.6, ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@8.6.2: version "8.6.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" @@ -3591,16 +3735,6 @@ ajv@8.6.2: require-from-string "^2.0.2" uri-js "^4.2.2" -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ajv@^8.0.0, ajv@^8.0.1: version "8.8.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" @@ -4551,7 +4685,7 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^2.5.0: +cli-spinners@^2.4.0, cli-spinners@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== @@ -10096,6 +10230,20 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +ora@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.1.0.tgz#b188cf8cd2d4d9b13fd25383bc3e5cba352c94f8" + integrity sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w== + dependencies: + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.4.0" + is-interactive "^1.0.0" + log-symbols "^4.0.0" + mute-stream "0.0.8" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + ora@5.4.1, ora@^5.1.0, ora@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" @@ -11838,6 +11986,13 @@ rxjs@6.6.2: dependencies: tslib "^1.9.0" +rxjs@6.6.3: + version "6.6.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" + integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== + dependencies: + tslib "^1.9.0" + rxjs@6.6.7, rxjs@^6.5.0, rxjs@^6.5.4, rxjs@^6.6.0, rxjs@~6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -13227,6 +13382,11 @@ typescript@4.3.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +typescript@~3.9.2: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + uglify-js@^3.1.4: version "3.14.3" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf" From 3dda81f88da0f3f062035cbbe83a308097641377 Mon Sep 17 00:00:00 2001 From: Mehmet Erim <34455572+mehmet-erim@users.noreply.github.com> Date: Thu, 6 Jan 2022 16:10:57 +0300 Subject: [PATCH 06/12] Update Theming.md --- docs/en/UI/Angular/Theming.md | 38 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/docs/en/UI/Angular/Theming.md b/docs/en/UI/Angular/Theming.md index 21e28953f81..16bae7aac9f 100644 --- a/docs/en/UI/Angular/Theming.md +++ b/docs/en/UI/Angular/Theming.md @@ -204,25 +204,49 @@ constructor(private sessionState: SessionStateService) { } ```` + + ##### User Menu -User menu is a component that can be replaceable. See an example to learn how can you replace it: +`UserMenuService` is used to get the user menu's items and render on the dropdown. You can add/update/remove an item by using the service. + +**Example: Adding/updating/removing an user menu item** ````ts -import { eThemeBasicComponents } from '@abp/ng.theme.basic'; -import { NavItemsService } from '@abp/ng.theme.shared'; +import { eUserMenuItems } from '@abp/ng.theme.basic'; +import { UserMenuService } from '@abp/ng.theme.shared'; import { Component } from '@angular/core'; +import { Router } from '@angular/router'; @Component({/* component metadata */}) export class AppComponent { - constructor(private navItems: NavItemsService) { - this.navItems.patchItem(eThemeBasicComponents.CurrentUser, { component: MyUserMenuComponent }); + constructor(private userMenu: UserMenuService, private router: Router) { + this.userMenu.addItems([ + { + id: 'UserMenu.Reports', + order: 1, + html: `Reports`, + action: () => { + this.router.navigateByUrl('/account/reports'); + }, + }, + ]); + + this.userMenu.patchItem(eUserMenuItems.MyAccount, { + html: `My profile`, + }); + + this.userMenu.removeItem(eUserMenuItems.Logout); } } ```` -[`ConfigStateService`](Config-State-Service.md) service can be used to obtain the `application-configuration` API response (e.g. getting current user or tenant). +In the example above, added a new user menu item labeled "Reports", updated the "My account" item HTML content, and removed the "Logout" item. + +See the result: + +![image](https://user-images.githubusercontent.com/34455572/148387770-5b5e25fb-f855-447c-8ead-c04c69b6d6f7.png) #### Page Alerts -`PageAlertService` service is used to get the current page alerts to render on the layout. See the [Page Alerts](Page-Alerts.md) document to learn more. \ No newline at end of file +`PageAlertService` service is used to get the current page alerts to render on the layout. See the [Page Alerts](Page-Alerts.md) document to learn more. From 570646a6365c6729cdb49121cd8af029e8607b11 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 7 Jan 2022 11:05:34 +0300 Subject: [PATCH 07/12] feat: add text property to UserMenu class --- .../components/nav-items/current-user.component.html | 12 +++++++++++- .../theme-shared/src/lib/models/user-menu.ts | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html index 0a1dec59d01..9adbde2d558 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html @@ -40,7 +40,17 @@ > -
+
+
+ + + + {{ item.text }} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts index 20b92b80824..e3b33cb1f22 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts @@ -1,3 +1,5 @@ import { NavItem } from './nav-item'; -export class UserMenu extends NavItem {} +export class UserMenu extends NavItem { + text?: string; +} From 25e23461e15848f7f372a165fe87db41cb1304f9 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 7 Jan 2022 11:29:44 +0300 Subject: [PATCH 08/12] improve the text template of user menu --- .../nav-items/current-user.component.html | 9 ++- .../src/lib/providers/user-menu.provider.ts | 61 +++++++------------ .../theme-shared/src/lib/models/user-menu.ts | 7 ++- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html index 9adbde2d558..8d76e6cb9cd 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html @@ -48,8 +48,13 @@ - - {{ item.text }} + + {{ item.textTemplate.text | abpLocalization }} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts b/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts index 5c36cc53472..dbf5815d55a 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts @@ -1,12 +1,6 @@ -import { - AuthService, - ConfigStateService, - LocalizationService, - NAVIGATE_TO_MANAGE_PROFILE, -} from '@abp/ng.core'; +import { AuthService, NAVIGATE_TO_MANAGE_PROFILE } from '@abp/ng.core'; import { UserMenuService } from '@abp/ng.theme.shared'; import { APP_INITIALIZER, Injector } from '@angular/core'; -import { filter } from 'rxjs/operators'; import { eUserMenuItems } from '../enums/user-menu-items'; export const BASIC_THEME_USER_MENU_PROVIDERS = [ @@ -19,41 +13,32 @@ export const BASIC_THEME_USER_MENU_PROVIDERS = [ ]; export function configureUserMenu(injector: Injector) { - const configState = injector.get(ConfigStateService); const userMenu = injector.get(UserMenuService); - const localization = injector.get(LocalizationService); const authService = injector.get(AuthService); const navigateToManageProfile = injector.get(NAVIGATE_TO_MANAGE_PROFILE); return () => { - configState - .getAll$() - .pipe(filter(res => !!res?.localization)) - .subscribe(() => { - userMenu.addItems([ - { - id: eUserMenuItems.MyAccount, - order: 100, - html: ` - ${localization.instant('AbpAccount::MyAccount')} - `, - action: () => navigateToManageProfile(), - }, - { - id: eUserMenuItems.Logout, - order: 101, - html: ` - ${localization.instant('AbpUi::Logout')} - `, - action: () => { - authService.logout().subscribe(); - }, - }, - ]); - }); + userMenu.addItems([ + { + id: eUserMenuItems.MyAccount, + order: 100, + textTemplate: { + text: 'AbpAccount::MyAccount', + icon: 'fa fa-cog', + }, + action: () => navigateToManageProfile(), + }, + { + id: eUserMenuItems.Logout, + order: 101, + textTemplate: { + text: 'AbpUi::Logout', + icon: 'fa fa-power-off', + }, + action: () => { + authService.logout().subscribe(); + }, + }, + ]); }; } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts index e3b33cb1f22..c45ea84396e 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts @@ -1,5 +1,10 @@ import { NavItem } from './nav-item'; export class UserMenu extends NavItem { - text?: string; + textTemplate?: UserMenuTextTemplate; +} + +export interface UserMenuTextTemplate { + text: string; + icon?: string; } From 6fa437f6870c216ad08a4594313b7275c6bf12cd Mon Sep 17 00:00:00 2001 From: bnymncoskuner Date: Fri, 7 Jan 2022 14:38:31 +0300 Subject: [PATCH 09/12] feat: add to-injector pipe in core package --- .../packages/core/src/lib/core.module.ts | 3 ++ .../packages/core/src/lib/pipes/index.ts | 1 + .../core/src/lib/pipes/to-injector.pipe.ts | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index c34b4a2fabf..270ab7dcbdb 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -23,6 +23,7 @@ import { LocalizationModule } from './localization.module'; import { ABP } from './models/common'; import { LocalizationPipe } from './pipes/localization.pipe'; import { SortPipe } from './pipes/sort.pipe'; +import { ToInjectorPipe } from './pipes/to-injector.pipe'; import { CookieLanguageProvider } from './providers/cookie-language.provider'; import { LocaleProvider } from './providers/locale.provider'; import { LocalizationService } from './services/localization.service'; @@ -65,6 +66,7 @@ export function storageFactory(): OAuthStorage { RouterOutletComponent, SortPipe, StopPropagationDirective, + ToInjectorPipe, ], imports: [ OAuthModule, @@ -89,6 +91,7 @@ export function storageFactory(): OAuthStorage { RouterOutletComponent, SortPipe, StopPropagationDirective, + ToInjectorPipe, ], providers: [LocalizationPipe], entryComponents: [ diff --git a/npm/ng-packs/packages/core/src/lib/pipes/index.ts b/npm/ng-packs/packages/core/src/lib/pipes/index.ts index eb028eee4f1..31e0a765931 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/index.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/index.ts @@ -1,2 +1,3 @@ export * from './localization.pipe'; export * from './sort.pipe'; +export * from './to-injector.pipe'; diff --git a/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts new file mode 100644 index 00000000000..5a1ac4df29b --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts @@ -0,0 +1,28 @@ +import { InjectionToken, Injector, Pipe, PipeTransform } from '@angular/core'; + +export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken( + 'INJECTOR_PIPE_DATA_TOKEN', +); + +@Pipe({ + name: 'toInjector', +}) +export class ToInjectorPipe implements PipeTransform { + constructor(private injector: Injector) {} + transform( + value: any, + token: InjectionToken = INJECTOR_PIPE_DATA_TOKEN, + name = 'ToInjectorPipe', + ): Injector { + return Injector.create({ + providers: [ + { + provide: token, + useValue: value, + }, + ], + parent: this.injector, + name, + }); + } +} From 80f7dae23b0b17a35f5dfde9bc7d5aa69e1ba5cd Mon Sep 17 00:00:00 2001 From: bnymncoskuner Date: Fri, 7 Jan 2022 14:38:51 +0300 Subject: [PATCH 10/12] feat: use toInjector in nav-items and current-user --- .../src/lib/components/nav-items/current-user.component.html | 1 + .../src/lib/components/nav-items/nav-items.component.html | 1 + 2 files changed, 2 insertions(+) diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html index 8d76e6cb9cd..3484c452a06 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html @@ -37,6 +37,7 @@ diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html index ac571d76808..2b1949a0ebc 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html @@ -5,6 +5,7 @@ From fa229efee1c4fbbf51473a6daf01b3de0fb8c03b Mon Sep 17 00:00:00 2001 From: bnymncoskuner Date: Fri, 7 Jan 2022 14:39:28 +0300 Subject: [PATCH 11/12] docs: update theming with new options of user menu --- docs/en/UI/Angular/Theming.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/en/UI/Angular/Theming.md b/docs/en/UI/Angular/Theming.md index 16bae7aac9f..74cf3b08cbb 100644 --- a/docs/en/UI/Angular/Theming.md +++ b/docs/en/UI/Angular/Theming.md @@ -210,6 +210,9 @@ constructor(private sessionState: SessionStateService) { `UserMenuService` is used to get the user menu's items and render on the dropdown. You can add/update/remove an item by using the service. +You can either pass a `component`, a piece of `html` or a `textTemplate` to render an item. +All of the options are shown below. You can choose either of them. + **Example: Adding/updating/removing an user menu item** ````ts @@ -218,6 +221,21 @@ import { UserMenuService } from '@abp/ng.theme.shared'; import { Component } from '@angular/core'; import { Router } from '@angular/router'; +// make sure that you import this component in a NgModule +@Component({ + selector: 'abp-current-user-test', + template: ` + + + {{ data.textTemplate.text | abpLocalization }} + + `, +}) +export class UserMenuItemComponent { + // you can inject the data through `INJECTOR_PIPE_DATA_TOKEN` token + constructor(@Inject(INJECTOR_PIPE_DATA_TOKEN) public data: UserMenu) {} +} + @Component({/* component metadata */}) export class AppComponent { constructor(private userMenu: UserMenuService, private router: Router) { @@ -225,7 +243,18 @@ export class AppComponent { { id: 'UserMenu.Reports', order: 1, + + // HTML example html: `Reports`, + + // text template example + textTemplate: { + text: 'AbpAccount::MyAccount', + icon: 'fa fa-cog', + }, + // component example + component: UserMenuItemComponent, + action: () => { this.router.navigateByUrl('/account/reports'); }, From 0f52f4ee8f36567fe331335d0068fc4c72109858 Mon Sep 17 00:00:00 2001 From: bnymncoskuner Date: Fri, 7 Jan 2022 14:45:13 +0300 Subject: [PATCH 12/12] docs: update the example in theming --- docs/en/UI/Angular/Theming.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/Theming.md b/docs/en/UI/Angular/Theming.md index 74cf3b08cbb..3b7e3d1afd6 100644 --- a/docs/en/UI/Angular/Theming.md +++ b/docs/en/UI/Angular/Theming.md @@ -241,11 +241,11 @@ export class AppComponent { constructor(private userMenu: UserMenuService, private router: Router) { this.userMenu.addItems([ { - id: 'UserMenu.Reports', + id: 'UserMenu.MyAccount', order: 1, // HTML example - html: `Reports`, + html: `My account`, // text template example textTemplate: { @@ -256,7 +256,7 @@ export class AppComponent { component: UserMenuItemComponent, action: () => { - this.router.navigateByUrl('/account/reports'); + this.router.navigateByUrl('/account/manage'); }, }, ]);