Browse Source

use report error method of http error reporter instead of store's action

pull/10010/head
mehmet-erim 5 years ago
parent
commit
03bf9389a1
  1. 1
      npm/ng-packs/packages/core/src/lib/actions/index.ts
  2. 6
      npm/ng-packs/packages/core/src/lib/actions/rest.actions.ts
  3. 10
      npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts
  4. 8
      npm/ng-packs/packages/core/src/lib/services/rest.service.ts
  5. 11
      npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts
  6. 16
      npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts
  7. 7
      npm/ng-packs/packages/core/src/lib/utils/environment-utils.ts
  8. 5
      npm/ng-packs/packages/core/src/public-api.ts
  9. 64
      npm/ng-packs/packages/identity/src/lib/actions/identity.actions.ts
  10. 1
      npm/ng-packs/packages/identity/src/lib/actions/index.ts
  11. 6
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html
  12. 51
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts
  13. 6
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  14. 69
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts
  15. 3
      npm/ng-packs/packages/identity/src/lib/identity.module.ts
  16. 12
      npm/ng-packs/packages/identity/src/lib/models/identity.ts
  17. 1
      npm/ng-packs/packages/identity/src/lib/models/index.ts
  18. 82
      npm/ng-packs/packages/identity/src/lib/services/identity-state.service.ts
  19. 1
      npm/ng-packs/packages/identity/src/lib/services/index.ts
  20. 138
      npm/ng-packs/packages/identity/src/lib/states/identity.state.ts
  21. 1
      npm/ng-packs/packages/identity/src/lib/states/index.ts
  22. 3
      npm/ng-packs/packages/identity/src/public-api.ts
  23. 21
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts
  24. 38
      npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts

1
npm/ng-packs/packages/core/src/lib/actions/index.ts

@ -1 +0,0 @@
export * from './rest.actions';

6
npm/ng-packs/packages/core/src/lib/actions/rest.actions.ts

@ -1,6 +0,0 @@
import { HttpErrorResponse } from '@angular/common/http';
export class RestOccurError {
static readonly type = '[Rest] Error';
constructor(public payload: HttpErrorResponse | any) {}
}

10
npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts

@ -1,12 +1,12 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { Store } from '@ngxs/store';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { RestOccurError } from '../actions/rest.actions';
import { HttpErrorReporterService } from '../services/http-error-reporter.service';
import { PermissionService } from '../services/permission.service';
import { RoutesService } from '../services/routes.service';
import { findRoute, getRoutePath } from '../utils/route-utils';
import { PermissionService } from '../services/permission.service';
@Injectable({
providedIn: 'root',
@ -15,8 +15,8 @@ export class PermissionGuard implements CanActivate {
constructor(
private router: Router,
private routesService: RoutesService,
private store: Store,
private permissionService: PermissionService,
private httpErrorReporter: HttpErrorReporterService,
) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
@ -32,7 +32,7 @@ export class PermissionGuard implements CanActivate {
return this.permissionService.getGrantedPolicy$(requiredPolicy).pipe(
tap(access => {
if (!access) {
this.store.dispatch(new RestOccurError({ status: 403 }));
this.httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse);
}
}),
);

8
npm/ng-packs/packages/core/src/lib/services/rest.service.ts

@ -1,14 +1,13 @@
import { HttpClient, HttpRequest } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { Store } from '@ngxs/store';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { RestOccurError } from '../actions/rest.actions';
import { ABP } from '../models/common';
import { Rest } from '../models/rest';
import { CORE_OPTIONS } from '../tokens/options.token';
import { isUndefinedOrEmptyString } from '../utils/common-utils';
import { EnvironmentService } from './environment.service';
import { HttpErrorReporterService } from './http-error-reporter.service';
@Injectable({
providedIn: 'root',
@ -18,7 +17,7 @@ export class RestService {
@Inject(CORE_OPTIONS) protected options: ABP.Root,
protected http: HttpClient,
protected environment: EnvironmentService,
protected store: Store,
protected httpErrorReporter: HttpErrorReporterService,
) {}
protected getApiFromStore(apiName: string): string {
@ -26,11 +25,10 @@ export class RestService {
}
handleError(err: any): Observable<any> {
this.store.dispatch(new RestOccurError(err));
this.httpErrorReporter.reportError(err);
return throwError(err);
}
// TODO: Deprecate service or improve interface in v5.0
request<T, R>(
request: HttpRequest<T> | Rest.Request<T>,
config?: Rest.Config,

11
npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts

@ -1,7 +1,6 @@
import { HttpHeaders } from '@angular/common/http';
import { Injector } from '@angular/core';
import { Params, Router } from '@angular/router';
import { Store } from '@ngxs/store';
import {
AuthConfig,
OAuthErrorEvent,
@ -11,21 +10,21 @@ import {
} from 'angular-oauth2-oidc';
import { from, Observable, of, pipe } from 'rxjs';
import { filter, switchMap, tap } from 'rxjs/operators';
import { RestOccurError } from '../actions/rest.actions';
import { LoginParams } from '../models/auth';
import { HttpErrorReporterService } from '../services';
import { ConfigStateService } from '../services/config-state.service';
import { EnvironmentService } from '../services/environment.service';
import { SessionStateService } from '../services/session-state.service';
import { TENANT_KEY } from '../tokens/tenant-key.token';
import { removeRememberMe, setRememberMe } from '../utils/auth-utils';
import { noop } from '../utils/common-utils';
import { TENANT_KEY } from '../tokens/tenant-key.token';
export const oAuthStorage = localStorage;
export abstract class AuthFlowStrategy {
abstract readonly isInternalAuth: boolean;
protected store: Store;
protected httpErrorReporter: HttpErrorReporterService;
protected environment: EnvironmentService;
protected configState: ConfigStateService;
protected oAuthService: OAuthService;
@ -38,10 +37,10 @@ export abstract class AuthFlowStrategy {
abstract logout(queryParams?: Params): Observable<any>;
abstract login(params?: LoginParams | Params): Observable<any>;
private catchError = err => this.store.dispatch(new RestOccurError(err));
private catchError = err => this.httpErrorReporter.reportError(err);
constructor(protected injector: Injector) {
this.store = injector.get(Store);
this.httpErrorReporter = injector.get(HttpErrorReporterService);
this.environment = injector.get(EnvironmentService);
this.configState = injector.get(ConfigStateService);
this.oAuthService = injector.get(OAuthService);

16
npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts

@ -5,9 +5,8 @@ import { RouterModule } from '@angular/router';
import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { Actions, Store } from '@ngxs/store';
import { of } from 'rxjs';
import { RestOccurError } from '../actions';
import { PermissionGuard } from '../guards/permission.guard';
import { PermissionService } from '../services';
import { HttpErrorReporterService, PermissionService } from '../services';
import { RoutesService } from '../services/routes.service';
import { CORE_OPTIONS } from '../tokens';
@ -15,7 +14,7 @@ describe('PermissionGuard', () => {
let spectator: SpectatorService<PermissionGuard>;
let guard: PermissionGuard;
let routes: SpyObject<RoutesService>;
let store: SpyObject<Store>;
let httpErrorReporter: SpyObject<HttpErrorReporterService>;
let permissionService: SpyObject<PermissionService>;
@Component({ template: '' })
@ -61,13 +60,13 @@ describe('PermissionGuard', () => {
spectator = createService();
guard = spectator.service;
routes = spectator.inject(RoutesService);
store = spectator.inject(Store);
httpErrorReporter = spectator.inject(HttpErrorReporterService);
permissionService = spectator.inject(PermissionService);
});
it('should return true when the grantedPolicy is true', done => {
permissionService.getGrantedPolicy$.andReturn(of(true));
const spy = jest.spyOn(store, 'dispatch');
const spy = jest.spyOn(httpErrorReporter, 'reportError');
guard.canActivate({ data: { requiredPolicy: 'test' } } as any, null).subscribe(res => {
expect(res).toBe(true);
expect(spy.mock.calls).toHaveLength(0);
@ -75,13 +74,12 @@ describe('PermissionGuard', () => {
});
});
it('should return false and dispatch RestOccurError when the grantedPolicy is false', done => {
it('should return false and report an error when the grantedPolicy is false', done => {
permissionService.getGrantedPolicy$.andReturn(of(false));
const spy = jest.spyOn(store, 'dispatch');
const spy = jest.spyOn(httpErrorReporter, 'reportError');
guard.canActivate({ data: { requiredPolicy: 'test' } } as any, null).subscribe(res => {
expect(res).toBe(false);
expect(spy.mock.calls[0][0] instanceof RestOccurError).toBeTruthy();
expect((spy.mock.calls[0][0] as RestOccurError).payload).toEqual({
expect(spy.mock.calls[0][0]).toEqual({
status: 403,
});
done();

7
npm/ng-packs/packages/core/src/lib/utils/environment-utils.ts

@ -1,9 +1,8 @@
import { HttpClient } from '@angular/common/http';
import { Injector } from '@angular/core';
import { Store } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { RestOccurError } from '../actions/rest.actions';
import { Environment, RemoteEnv } from '../models/environment';
import { HttpErrorReporterService } from '../services';
import { EnvironmentService } from '../services/environment.service';
import { deepMerge } from './object-utils';
@ -15,12 +14,12 @@ export function getRemoteEnv(injector: Injector, environment: Partial<Environmen
if (!url) return Promise.resolve();
const http = injector.get(HttpClient);
const store = injector.get(Store);
const httpErrorReporter = injector.get(HttpErrorReporterService);
return http
.request<Environment>(method, url, { headers })
.pipe(
catchError(err => store.dispatch(new RestOccurError(err))), // TODO: Condiser get handle function from a provider
catchError(err => httpErrorReporter.reportError(err)), // TODO: Condiser get handle function from a provider
tap(env => environmentService.setState(mergeEnvironments(environment, env, remoteEnv))),
)
.toPromise();

5
npm/ng-packs/packages/core/src/public-api.ts

@ -1,10 +1,5 @@
/*
* Public API Surface of core
*/
// export * from './lib/handlers';
export * from './lib/abstracts';
export * from './lib/actions';
export * from './lib/components';
export * from './lib/constants';
export * from './lib/core.module';

64
npm/ng-packs/packages/identity/src/lib/actions/identity.actions.ts

@ -1,64 +0,0 @@
import { Identity } from '../models/identity';
import { ABP, PagedAndSortedResultRequestDto } from '@abp/ng.core';
import {
GetIdentityUsersInput,
IdentityRoleCreateDto,
IdentityRoleUpdateDto,
IdentityUserCreateDto,
IdentityUserUpdateDto,
} from '../proxy/identity/models';
export class GetRoles {
static readonly type = '[Identity] Get Roles';
constructor(public payload?: PagedAndSortedResultRequestDto) {}
}
export class GetRoleById {
static readonly type = '[Identity] Get Role By Id';
constructor(public payload: string) {}
}
export class DeleteRole {
static readonly type = '[Identity] Delete Role';
constructor(public payload: string) {}
}
export class CreateRole {
static readonly type = '[Identity] Create Role';
constructor(public payload: IdentityRoleCreateDto) {}
}
export class UpdateRole {
static readonly type = '[Identity] Update Role';
constructor(public payload: IdentityRoleUpdateDto & { id: string }) {}
}
export class GetUsers {
static readonly type = '[Identity] Get Users';
constructor(public payload?: GetIdentityUsersInput) {}
}
export class GetUserById {
static readonly type = '[Identity] Get User By Id';
constructor(public payload: string) {}
}
export class DeleteUser {
static readonly type = '[Identity] Delete User';
constructor(public payload: string) {}
}
export class CreateUser {
static readonly type = '[Identity] Create User';
constructor(public payload: IdentityUserCreateDto) {}
}
export class UpdateUser {
static readonly type = '[Identity] Update User';
constructor(public payload: IdentityUserUpdateDto & { id: string }) {}
}
export class GetUserRoles {
static readonly type = '[Identity] Get User Roles';
constructor(public payload: string) {}
}

1
npm/ng-packs/packages/identity/src/lib/actions/index.ts

@ -1 +0,0 @@
export * from './identity.actions';

6
npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html

@ -5,15 +5,15 @@
<h5 class="card-title">{{ 'AbpIdentity::Roles' | abpLocalization }}</h5>
</div>
<div class="text-right col col-md-6">
<abp-page-toolbar [record]="data$ | async"></abp-page-toolbar>
<abp-page-toolbar [record]="data.items"></abp-page-toolbar>
</div>
</div>
</div>
<div class="card-body">
<abp-extensible-table
[data]="data$ | async"
[recordsTotal]="totalCount$ | async"
[data]="data.items"
[recordsTotal]="data.totalCount"
[list]="list"
></abp-extensible-table>
</div>

51
npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts

@ -1,4 +1,4 @@
import { ListService, PagedAndSortedResultRequestDto } from '@abp/ng.core';
import { ListService, PagedAndSortedResultRequestDto, PagedResultDto } from '@abp/ng.core';
import { ePermissionManagementComponents } from '@abp/ng.permission-management';
import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
import {
@ -6,21 +6,12 @@ import {
FormPropData,
generateFormFromProps,
} from '@abp/ng.theme.shared/extensions';
import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
import { Component, Injector, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { finalize, pluck } from 'rxjs/operators';
import {
CreateRole,
DeleteRole,
GetRoleById,
GetRoles,
UpdateRole,
} from '../../actions/identity.actions';
import { finalize } from 'rxjs/operators';
import { eIdentityComponents } from '../../enums/components';
import { IdentityRoleService } from '../../proxy/identity/identity-role.service';
import { IdentityRoleDto } from '../../proxy/identity/models';
import { IdentityState } from '../../states/identity.state';
@Component({
selector: 'abp-roles',
@ -34,11 +25,7 @@ import { IdentityState } from '../../states/identity.state';
],
})
export class RolesComponent implements OnInit {
@Select(IdentityState.getRoles)
data$: Observable<IdentityRoleDto[]>;
@Select(IdentityState.getRolesTotalCount)
totalCount$: Observable<number>;
data: PagedResultDto<IdentityRoleDto> = { items: [], totalCount: 0 };
form: FormGroup;
@ -61,8 +48,8 @@ export class RolesComponent implements OnInit {
constructor(
public readonly list: ListService<PagedAndSortedResultRequestDto>,
protected confirmationService: ConfirmationService,
protected store: Store,
protected injector: Injector,
protected service: IdentityRoleService,
) {}
ngOnInit() {
@ -85,25 +72,21 @@ export class RolesComponent implements OnInit {
}
edit(id: string) {
this.store
.dispatch(new GetRoleById(id))
.pipe(pluck('IdentityState', 'selectedRole'))
.subscribe(selectedRole => {
this.selected = selectedRole;
this.openModal();
});
this.service.get(id).subscribe(res => {
this.selected = res;
this.openModal();
});
}
save() {
if (!this.form.valid) return;
this.modalBusy = true;
this.store
.dispatch(
this.selected.id
? new UpdateRole({ ...this.selected, ...this.form.value, id: this.selected.id })
: new CreateRole(this.form.value),
)
const { id } = this.selected;
(id
? this.service.update(id, { ...this.selected, ...this.form.value })
: this.service.create(this.form.value)
)
.pipe(finalize(() => (this.modalBusy = false)))
.subscribe(() => {
this.isModalVisible = false;
@ -118,13 +101,13 @@ export class RolesComponent implements OnInit {
})
.subscribe((status: Confirmation.Status) => {
if (status === Confirmation.Status.confirm) {
this.store.dispatch(new DeleteRole(id)).subscribe(() => this.list.get());
this.service.delete(id).subscribe(() => this.list.get());
}
});
}
private hookToQuery() {
this.list.hookToQuery(query => this.store.dispatch(new GetRoles(query))).subscribe();
this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res));
}
openPermissionsModal(providerKey: string) {

6
npm/ng-packs/packages/identity/src/lib/components/users/users.component.html

@ -5,7 +5,7 @@
<h5 class="card-title">{{ 'AbpIdentity::Users' | abpLocalization }}</h5>
</div>
<div class="text-right col col-md-6">
<abp-page-toolbar [record]="data$ | async"></abp-page-toolbar>
<abp-page-toolbar [record]="data.items"></abp-page-toolbar>
</div>
</div>
</div>
@ -22,8 +22,8 @@
</div>
<abp-extensible-table
[data]="data$ | async"
[recordsTotal]="totalCount$ | async"
[data]="data.items"
[recordsTotal]="data.totalCount"
[list]="list"
></abp-extensible-table>
</div>

69
npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts

@ -1,4 +1,4 @@
import { ListService } from '@abp/ng.core';
import { ListService, PagedResultDto } from '@abp/ng.core';
import { ePermissionManagementComponents } from '@abp/ng.permission-management';
import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
import {
@ -15,26 +15,14 @@ import {
ViewChild,
} from '@angular/core';
import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { finalize, pluck, switchMap, take } from 'rxjs/operators';
import {
CreateUser,
DeleteUser,
GetUserById,
GetUserRoles,
GetUsers,
UpdateUser,
} from '../../actions/identity.actions';
import { finalize, switchMap, tap } from 'rxjs/operators';
import { eIdentityComponents } from '../../enums/components';
import { Identity } from '../../models/identity';
import { IdentityUserService } from '../../proxy/identity/identity-user.service';
import {
GetIdentityUsersInput,
IdentityRoleDto,
IdentityUserDto,
} from '../../proxy/identity/models';
import { IdentityState } from '../../states/identity.state';
@Component({
selector: 'abp-users',
@ -48,11 +36,7 @@ import { IdentityState } from '../../states/identity.state';
],
})
export class UsersComponent implements OnInit {
@Select(IdentityState.getUsers)
data$: Observable<IdentityUserDto[]>;
@Select(IdentityState.getUsersTotalCount)
totalCount$: Observable<number>;
data: PagedResultDto<IdentityUserDto> = { items: [], totalCount: 0 };
@ViewChild('modalContent', { static: false })
modalContent: TemplateRef<any>;
@ -88,9 +72,8 @@ export class UsersComponent implements OnInit {
constructor(
public readonly list: ListService<GetIdentityUsersInput>,
protected confirmationService: ConfirmationService,
protected userService: IdentityUserService,
protected service: IdentityUserService,
protected fb: FormBuilder,
protected store: Store,
protected injector: Injector,
) {}
@ -102,7 +85,7 @@ export class UsersComponent implements OnInit {
const data = new FormPropData(this.injector, this.selected);
this.form = generateFormFromProps(data);
this.userService.getAssignableRoles().subscribe(({ items }) => {
this.service.getAssignableRoles().subscribe(({ items }) => {
this.roles = items;
this.form.addControl(
'roleNames',
@ -133,16 +116,14 @@ export class UsersComponent implements OnInit {
}
edit(id: string) {
this.store
.dispatch(new GetUserById(id))
this.service
.get(id)
.pipe(
switchMap(() => this.store.dispatch(new GetUserRoles(id))),
pluck('IdentityState'),
take(1),
tap(user => (this.selected = user)),
switchMap(() => this.service.getRoles(id)),
)
.subscribe((state: Identity.State) => {
this.selected = state.selectedUser;
this.selectedUserRoles = state.selectedUserRoles || [];
.subscribe(userRole => {
this.selectedUserRoles = userRole.items || [];
this.openModal();
});
}
@ -156,20 +137,16 @@ export class UsersComponent implements OnInit {
roleNames.filter(role => !!role[Object.keys(role)[0]]).map(role => Object.keys(role)[0]) ||
[];
this.store
.dispatch(
this.selected.id
? new UpdateUser({
...this.selected,
...this.form.value,
id: this.selected.id,
roleNames: mappedRoleNames,
})
: new CreateUser({
...this.form.value,
roleNames: mappedRoleNames,
}),
)
const { id } = this.selected;
(id
? this.service.update(id, {
...this.selected,
...this.form.value,
roleNames: mappedRoleNames,
})
: this.service.create({ ...this.form.value, roleNames: mappedRoleNames })
)
.pipe(finalize(() => (this.modalBusy = false)))
.subscribe(() => {
this.isModalVisible = false;
@ -184,7 +161,7 @@ export class UsersComponent implements OnInit {
})
.subscribe((status: Confirmation.Status) => {
if (status === Confirmation.Status.confirm) {
this.store.dispatch(new DeleteUser(id)).subscribe(() => this.list.get());
this.service.delete(id).subscribe(() => this.list.get());
}
});
}
@ -196,7 +173,7 @@ export class UsersComponent implements OnInit {
}
private hookToQuery() {
this.list.hookToQuery(query => this.store.dispatch(new GetUsers(query))).subscribe();
this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res));
}
openPermissionsModal(providerKey: string) {

3
npm/ng-packs/packages/identity/src/lib/identity.module.ts

@ -5,13 +5,11 @@ import { UiExtensionsModule } from '@abp/ng.theme.shared/extensions';
import { ModuleWithProviders, NgModule, NgModuleFactory } from '@angular/core';
import { NgbDropdownModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxValidateCoreModule } from '@ngx-validate/core';
import { NgxsModule } from '@ngxs/store';
import { RolesComponent } from './components/roles/roles.component';
import { UsersComponent } from './components/users/users.component';
import { IdentityExtensionsGuard } from './guards/extensions.guard';
import { IdentityRoutingModule } from './identity-routing.module';
import { IdentityConfigOptions } from './models/config-options';
import { IdentityState } from './states/identity.state';
import {
IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS,
IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS,
@ -24,7 +22,6 @@ import {
declarations: [RolesComponent, UsersComponent],
exports: [RolesComponent, UsersComponent],
imports: [
NgxsModule.forFeature([IdentityState]),
CoreModule,
IdentityRoutingModule,
NgbNavModule,

12
npm/ng-packs/packages/identity/src/lib/models/identity.ts

@ -1,12 +0,0 @@
import { PagedResultDto } from '@abp/ng.core';
import { IdentityRoleDto, IdentityUserDto } from '../proxy/identity/models';
export namespace Identity {
export interface State {
roles: PagedResultDto<IdentityRoleDto>;
users: PagedResultDto<IdentityUserDto>;
selectedRole: IdentityRoleDto;
selectedUser: IdentityUserDto;
selectedUserRoles: IdentityRoleDto[];
}
}

1
npm/ng-packs/packages/identity/src/lib/models/index.ts

@ -1,2 +1 @@
export * from './config-options';
export * from './identity';

82
npm/ng-packs/packages/identity/src/lib/services/identity-state.service.ts

@ -1,82 +0,0 @@
import { ABP } from '@abp/ng.core';
import { Injectable } from '@angular/core';
import { Store } from '@ngxs/store';
import {
CreateRole,
CreateUser,
DeleteRole,
DeleteUser,
GetRoleById,
GetRoles,
GetUserById,
GetUsers,
UpdateRole,
UpdateUser,
GetUserRoles,
} from '../actions/identity.actions';
import { Identity } from '../models/identity';
import { IdentityState } from '../states/identity.state';
@Injectable({
providedIn: 'root',
})
export class IdentityStateService {
constructor(private store: Store) {}
getRoles() {
return this.store.selectSnapshot(IdentityState.getRoles);
}
getRolesTotalCount() {
return this.store.selectSnapshot(IdentityState.getRolesTotalCount);
}
getUsers() {
return this.store.selectSnapshot(IdentityState.getUsers);
}
getUsersTotalCount() {
return this.store.selectSnapshot(IdentityState.getUsersTotalCount);
}
dispatchGetRoles(...args: ConstructorParameters<typeof GetRoles>) {
return this.store.dispatch(new GetRoles(...args));
}
dispatchGetRoleById(...args: ConstructorParameters<typeof GetRoleById>) {
return this.store.dispatch(new GetRoleById(...args));
}
dispatchDeleteRole(...args: ConstructorParameters<typeof DeleteRole>) {
return this.store.dispatch(new DeleteRole(...args));
}
dispatchCreateRole(...args: ConstructorParameters<typeof CreateRole>) {
return this.store.dispatch(new CreateRole(...args));
}
dispatchUpdateRole(...args: ConstructorParameters<typeof UpdateRole>) {
return this.store.dispatch(new UpdateRole(...args));
}
dispatchGetUsers(...args: ConstructorParameters<typeof GetUsers>) {
return this.store.dispatch(new GetUsers(...args));
}
dispatchGetUserById(...args: ConstructorParameters<typeof GetUserById>) {
return this.store.dispatch(new GetUserById(...args));
}
dispatchDeleteUser(...args: ConstructorParameters<typeof DeleteUser>) {
return this.store.dispatch(new DeleteUser(...args));
}
dispatchCreateUser(...args: ConstructorParameters<typeof CreateUser>) {
return this.store.dispatch(new CreateUser(...args));
}
dispatchUpdateUser(...args: ConstructorParameters<typeof UpdateUser>) {
return this.store.dispatch(new UpdateUser(...args));
}
dispatchGetUserRoles(...args: ConstructorParameters<typeof GetUserRoles>) {
return this.store.dispatch(new GetUserRoles(...args));
}
}

1
npm/ng-packs/packages/identity/src/lib/services/index.ts

@ -1 +0,0 @@
export * from './identity-state.service';

138
npm/ng-packs/packages/identity/src/lib/states/identity.state.ts

@ -1,138 +0,0 @@
import { Injectable } from '@angular/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { pluck, tap } from 'rxjs/operators';
import {
CreateRole,
CreateUser,
DeleteRole,
DeleteUser,
GetRoleById,
GetRoles,
GetUserById,
GetUserRoles,
GetUsers,
UpdateRole,
UpdateUser,
} from '../actions/identity.actions';
import { Identity } from '../models/identity';
import { IdentityRoleService } from '../proxy/identity/identity-role.service';
import { IdentityUserService } from '../proxy/identity/identity-user.service';
import { IdentityRoleDto, IdentityUserDto } from '../proxy/identity/models';
@State<Identity.State>({
name: 'IdentityState',
defaults: { roles: {}, selectedRole: {}, users: {}, selectedUser: {} } as Identity.State,
})
@Injectable()
export class IdentityState {
@Selector()
static getRoles({ roles }: Identity.State): IdentityRoleDto[] {
return roles.items || [];
}
@Selector()
static getRolesTotalCount({ roles }: Identity.State): number {
return roles.totalCount || 0;
}
@Selector()
static getUsers({ users }: Identity.State): IdentityUserDto[] {
return users.items || [];
}
@Selector()
static getUsersTotalCount({ users }: Identity.State): number {
return users.totalCount || 0;
}
constructor(
private identityUserService: IdentityUserService,
private identityRoleService: IdentityRoleService,
) {}
@Action(GetRoles)
getRoles({ patchState }: StateContext<Identity.State>, { payload }: GetRoles) {
return this.identityRoleService.getList(payload).pipe(
tap(roles =>
patchState({
roles,
}),
),
);
}
@Action(GetRoleById)
getRole({ patchState }: StateContext<Identity.State>, { payload }: GetRoleById) {
return this.identityRoleService.get(payload).pipe(
tap(selectedRole =>
patchState({
selectedRole,
}),
),
);
}
@Action(DeleteRole)
deleteRole(_, { payload }: GetRoleById) {
return this.identityRoleService.delete(payload);
}
@Action(CreateRole)
addRole(_, { payload }: CreateRole) {
return this.identityRoleService.create(payload);
}
@Action(UpdateRole)
updateRole({ getState }: StateContext<Identity.State>, { payload }: UpdateRole) {
return this.identityRoleService.update(payload.id, { ...getState().selectedRole, ...payload });
}
@Action(GetUsers)
getUsers({ patchState }: StateContext<Identity.State>, { payload }: GetUsers) {
return this.identityUserService.getList(payload).pipe(
tap(users =>
patchState({
users,
}),
),
);
}
@Action(GetUserById)
getUser({ patchState }: StateContext<Identity.State>, { payload }: GetUserById) {
return this.identityUserService.get(payload).pipe(
tap(selectedUser =>
patchState({
selectedUser,
}),
),
);
}
@Action(DeleteUser)
deleteUser(_, { payload }: GetUserById) {
return this.identityUserService.delete(payload);
}
@Action(CreateUser)
addUser(_, { payload }: CreateUser) {
return this.identityUserService.create(payload);
}
@Action(UpdateUser)
updateUser({ getState }: StateContext<Identity.State>, { payload }: UpdateUser) {
return this.identityUserService.update(payload.id, { ...getState().selectedUser, ...payload });
}
@Action(GetUserRoles)
getUserRoles({ patchState }: StateContext<Identity.State>, { payload }: GetUserRoles) {
return this.identityUserService.getRoles(payload).pipe(
pluck('items'),
tap(selectedUserRoles =>
patchState({
selectedUserRoles,
}),
),
);
}
}

1
npm/ng-packs/packages/identity/src/lib/states/index.ts

@ -1 +0,0 @@
export * from './identity.state';

3
npm/ng-packs/packages/identity/src/public-api.ts

@ -1,4 +1,3 @@
export * from './lib/actions';
export * from './lib/components';
export * from './lib/enums';
export * from './lib/guards';
@ -6,6 +5,4 @@ export * from './lib/identity.module';
export * from './lib/models';
export * from './lib/proxy/identity';
export * from './lib/proxy/users';
export * from './lib/services';
export * from './lib/states';
export * from './lib/tokens';

21
npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts

@ -1,4 +1,9 @@
import { AuthService, LocalizationParam, RestOccurError, RouterEvents } from '@abp/ng.core';
import {
AuthService,
HttpErrorReporterService,
LocalizationParam,
RouterEvents,
} from '@abp/ng.core';
import { HttpErrorResponse } from '@angular/common/http';
import {
ApplicationRef,
@ -11,9 +16,8 @@ import {
RendererFactory2,
} from '@angular/core';
import { NavigationError, ResolveEnd } from '@angular/router';
import { Actions, ofActionSuccessful } from '@ngxs/store';
import { Observable, of, Subject, throwError } from 'rxjs';
import { catchError, filter, map, switchMap } from 'rxjs/operators';
import { catchError, filter, switchMap } from 'rxjs/operators';
import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component';
import { ErrorScreenErrorCodes, HttpErrorConfig } from '../models/common';
import { Confirmation } from '../models/confirmation';
@ -75,7 +79,7 @@ export class ErrorHandler {
);
constructor(
protected actions: Actions,
protected httpErrorReporter: HttpErrorReporterService,
protected routerEvents: RouterEvents,
protected confirmationService: ConfirmationService,
protected cfRes: ComponentFactoryResolver,
@ -106,13 +110,8 @@ export class ErrorHandler {
}
protected listenToRestError() {
this.actions
.pipe(
ofActionSuccessful(RestOccurError),
map(action => action.payload),
filter(this.filterRestErrors),
switchMap(this.executeErrorHandler),
)
this.httpErrorReporter.reporter$
.pipe(filter(this.filterRestErrors), switchMap(this.executeErrorHandler))
.subscribe();
}

38
npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts

@ -1,10 +1,9 @@
import { RestOccurError } from '@abp/ng.core';
import { HttpErrorReporterService } from '@abp/ng.core';
import { CoreTestingModule } from '@abp/ng.core/testing';
import { APP_BASE_HREF } from '@angular/common';
import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Component, NgModule } from '@angular/core';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { NgxsModule, Store } from '@ngxs/store';
import { OAuthService } from 'angular-oauth2-oidc';
import { of } from 'rxjs';
import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component';
@ -22,7 +21,7 @@ class MockModule {}
let spectator: SpectatorService<ErrorHandler>;
let service: ErrorHandler;
let store: Store;
let httpErrorReporter: HttpErrorReporterService;
const errorConfirmation: jest.Mock = jest.fn(() => of(null));
const CONFIRMATION_BUTTONS = {
hideCancelBtn: true,
@ -31,7 +30,7 @@ const CONFIRMATION_BUTTONS = {
describe('ErrorHandler', () => {
const createService = createServiceFactory({
service: ErrorHandler,
imports: [NgxsModule.forRoot([]), CoreTestingModule.withConfig(), MockModule],
imports: [CoreTestingModule.withConfig(), MockModule],
mocks: [OAuthService],
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
@ -51,8 +50,7 @@ describe('ErrorHandler', () => {
beforeEach(() => {
spectator = createService();
service = spectator.service;
store = spectator.inject(Store);
store.selectSnapshot = jest.fn(() => '/x');
httpErrorReporter = spectator.inject(HttpErrorReporterService);
});
afterEach(() => {
@ -77,7 +75,7 @@ describe('ErrorHandler', () => {
expect(selectHtmlErrorWrapper()).toBeNull();
store.dispatch(new RestOccurError(error));
httpErrorReporter.reportError(error);
expect(createComponent).toHaveBeenCalledWith(params);
});
@ -99,7 +97,7 @@ describe('ErrorHandler', () => {
expect(selectHtmlErrorWrapper()).toBeNull();
store.dispatch(new RestOccurError(error));
httpErrorReporter.reportError(error);
expect(createComponent).toHaveBeenCalledWith(params);
});
@ -121,13 +119,13 @@ describe('ErrorHandler', () => {
expect(selectHtmlErrorWrapper()).toBeNull();
store.dispatch(new RestOccurError(error));
httpErrorReporter.reportError(error);
expect(createComponent).toHaveBeenCalledWith(params);
});
test('should call error method of ConfirmationService when not found error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 404 })));
httpErrorReporter.reportError(new HttpErrorResponse({ status: 404 }));
expect(errorConfirmation).toHaveBeenCalledWith(
{
@ -143,7 +141,7 @@ describe('ErrorHandler', () => {
});
test('should call error method of ConfirmationService when default error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 412 })));
httpErrorReporter.reportError(new HttpErrorResponse({ status: 412 }));
expect(errorConfirmation).toHaveBeenCalledWith(
{
@ -159,7 +157,7 @@ describe('ErrorHandler', () => {
});
test('should call error method of ConfirmationService when authenticated error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 401 })));
httpErrorReporter.reportError(new HttpErrorResponse({ status: 401 }));
expect(errorConfirmation).toHaveBeenCalledWith(
{
@ -178,7 +176,7 @@ describe('ErrorHandler', () => {
const headers: HttpHeaders = new HttpHeaders({
_AbpErrorFormat: '_AbpErrorFormat',
});
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 401, headers })));
httpErrorReporter.reportError(new HttpErrorResponse({ status: 401, headers }));
expect(errorConfirmation).toHaveBeenCalledWith(
{
@ -193,14 +191,12 @@ describe('ErrorHandler', () => {
test('should call error method of ConfirmationService when error occurs with _AbpErrorFormat header', () => {
let headers: HttpHeaders = new HttpHeaders();
headers = headers.append('_AbpErrorFormat', '_AbpErrorFormat');
store.dispatch(
new RestOccurError(
new HttpErrorResponse({
error: { error: { message: 'test message', details: 'test detail' } },
status: 412,
headers,
}),
),
httpErrorReporter.reportError(
new HttpErrorResponse({
error: { error: { message: 'test message', details: 'test detail' } },
status: 412,
headers,
}),
);
expect(errorConfirmation).toHaveBeenCalledWith(

Loading…
Cancel
Save