Browse Source

Merge pull request #11214 from abpframework/feat/user-menu

Angular UI: Created the UserMenuService to get user menu items dynamically
pull/11251/head
Bunyamin Coskuner 5 years ago
committed by GitHub
parent
commit
a2af9e5313
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 67
      docs/en/UI/Angular/Theming.md
  2. 3
      npm/ng-packs/packages/core/src/lib/core.module.ts
  3. 1
      npm/ng-packs/packages/core/src/lib/pipes/index.ts
  4. 28
      npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts
  5. 2
      npm/ng-packs/packages/theme-basic/src/lib/components/index.ts
  6. 36
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html
  7. 8
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts
  8. 1
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html
  9. 1
      npm/ng-packs/packages/theme-basic/src/lib/enums/index.ts
  10. 4
      npm/ng-packs/packages/theme-basic/src/lib/enums/user-menu-items.ts
  11. 1
      npm/ng-packs/packages/theme-basic/src/lib/providers/index.ts
  12. 44
      npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts
  13. 2
      npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts
  14. 3
      npm/ng-packs/packages/theme-shared/src/lib/models/index.ts
  15. 10
      npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts
  16. 60
      npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts
  17. 1
      npm/ng-packs/packages/theme-shared/src/lib/services/index.ts
  18. 48
      npm/ng-packs/packages/theme-shared/src/lib/services/nav-items.service.ts
  19. 8
      npm/ng-packs/packages/theme-shared/src/lib/services/user-menu.service.ts
  20. 182
      npm/ng-packs/yarn.lock

67
docs/en/UI/Angular/Theming.md

@ -204,25 +204,78 @@ 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.
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
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';
// make sure that you import this component in a NgModule
@Component({
selector: 'abp-current-user-test',
template: `
<a class="dropdown-item pointer" (click)="data.action()">
<i *ngIf="data.textTemplate.icon" [class]="data.textTemplate.icon"></i>
{{ data.textTemplate.text | abpLocalization }}
</a>
`,
})
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 navItems: NavItemsService) {
this.navItems.patchItem(eThemeBasicComponents.CurrentUser, { component: MyUserMenuComponent });
constructor(private userMenu: UserMenuService, private router: Router) {
this.userMenu.addItems([
{
id: 'UserMenu.MyAccount',
order: 1,
// HTML example
html: `<a class="dropdown-item pointer">My account</a>`,
// text template example
textTemplate: {
text: 'AbpAccount::MyAccount',
icon: 'fa fa-cog',
},
// component example
component: UserMenuItemComponent,
action: () => {
this.router.navigateByUrl('/account/manage');
},
},
]);
this.userMenu.patchItem(eUserMenuItems.MyAccount, {
html: `<a class="dropdown-item pointer">My profile</a>`,
});
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.
`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.

3
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: [

1
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';

28
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<PipeTransform>(
'INJECTOR_PIPE_DATA_TOKEN',
);
@Pipe({
name: 'toInjector',
})
export class ToInjectorPipe implements PipeTransform {
constructor(private injector: Injector) {}
transform(
value: any,
token: InjectionToken<any> = INJECTOR_PIPE_DATA_TOKEN,
name = 'ToInjectorPipe',
): Injector {
return Injector.create({
providers: [
{
provide: token,
useValue: value,
},
],
parent: this.injector,
name,
});
}
}

2
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';

36
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html

@ -31,11 +31,35 @@
aria-labelledby="dropdownMenuLink"
[class.d-block]="smallScreen && currentUserDropdown.isOpen()"
>
<a class="dropdown-item pointer" (click)="navigateToManageProfile()"
><i class="fa fa-cog me-1"></i>{{ 'AbpAccount::MyAccount' | abpLocalization }}</a
>
<a class="dropdown-item" href="javascript:void(0)" (click)="logout()"
><i class="fa fa-power-off me-1"></i>{{ 'AbpUi::Logout' | abpLocalization }}</a
>
<ng-container *ngFor="let item of userMenu.items$ | async; trackBy: trackByFn">
<ng-container *ngIf="item.visible && item.visible()">
<li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy">
<ng-container
*ngIf="item.component; else htmlTemplate"
[ngComponentOutlet]="item.component"
[ngComponentOutletInjector]="item | toInjector"
></ng-container>
<ng-template #htmlTemplate>
<div
*ngIf="item.html; else textTemplate"
[innerHTML]="item.html"
(click)="item.action ? item.action() : null"
></div>
</ng-template>
<ng-template #textTemplate>
<a
*ngIf="item.textTemplate"
(click)="item.action ? item.action() : null"
class="dropdown-item pointer"
>
<i *ngIf="item.textTemplate.icon" class="me-1 {{ item.textTemplate.icon }}"></i>
{{ item.textTemplate.text | abpLocalization }}</a
>
</ng-template>
</li>
</ng-container>
</ng-container>
</div>
</div>

8
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<CurrentUserDto> = this.configState.getOne$('currentUser');
selectedTenant$ = this.sessionState.getTenant$();
trackByFn: TrackByFunction<UserMenu> = (_, 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,

1
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html

@ -5,6 +5,7 @@
<ng-container
*ngIf="item.component; else htmlTemplate"
[ngComponentOutlet]="item.component"
[ngComponentOutletInjector]="item | toInjector"
></ng-container>
<ng-template #htmlTemplate>

1
npm/ng-packs/packages/theme-basic/src/lib/enums/index.ts

@ -1 +1,2 @@
export * from './components';
export * from './user-menu-items';

4
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',
}

1
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';

44
npm/ng-packs/packages/theme-basic/src/lib/providers/user-menu.provider.ts

@ -0,0 +1,44 @@
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 { 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 userMenu = injector.get(UserMenuService);
const authService = injector.get(AuthService);
const navigateToManageProfile = injector.get(NAVIGATE_TO_MANAGE_PROFILE);
return () => {
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();
},
},
]);
};
}

2
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,

3
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';

10
npm/ng-packs/packages/theme-shared/src/lib/models/user-menu.ts

@ -0,0 +1,10 @@
import { NavItem } from './nav-item';
export class UserMenu extends NavItem {
textTemplate?: UserMenuTextTemplate;
}
export interface UserMenuTextTemplate {
text: string;
icon?: string;
}

60
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<T extends NavItem> {
protected abstract baseClass;
protected _items$ = new BehaviorSubject<T[]>([]);
get items(): T[] {
return this._items$.value;
}
get items$(): Observable<T[]> {
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<Omit<T, 'id'>>) {
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;
}
}

1
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';

48
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<NavItem[]>([]);
get items(): NavItem[] {
return this._items$.value;
}
get items$(): Observable<NavItem[]> {
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<Omit<NavItem, 'id'>>) {
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<NavItem> {
protected baseClass = NavItem;
}

8
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<UserMenu> {
protected baseClass = UserMenu;
}

182
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"

Loading…
Cancel
Save