Browse Source

remove profile state

pull/10010/head
mehmet-erim 5 years ago
parent
commit
0dbc88c3ab
  1. 10
      npm/ng-packs/packages/account/src/lib/services/manage-profile.state.service.ts
  2. 24
      npm/ng-packs/packages/core/src/lib/actions/config.actions.ts
  3. 3
      npm/ng-packs/packages/core/src/lib/actions/index.ts
  4. 15
      npm/ng-packs/packages/core/src/lib/actions/profile.actions.ts
  5. 5
      npm/ng-packs/packages/core/src/lib/core.module.ts
  6. 44
      npm/ng-packs/packages/core/src/lib/models/profile.ts
  7. 7
      npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts
  8. 1
      npm/ng-packs/packages/core/src/lib/services/index.ts
  9. 11
      npm/ng-packs/packages/core/src/lib/services/localization.service.ts
  10. 28
      npm/ng-packs/packages/core/src/lib/services/profile-state.service.ts
  11. 71
      npm/ng-packs/packages/core/src/lib/services/profile.service.ts
  12. 1
      npm/ng-packs/packages/core/src/lib/states/index.ts
  13. 47
      npm/ng-packs/packages/core/src/lib/states/profile.state.ts
  14. 57
      npm/ng-packs/packages/core/src/lib/tests/profile-state.service.spec.ts
  15. 74
      npm/ng-packs/packages/core/src/lib/tests/profile.state.spec.ts
  16. 1
      npm/ng-packs/packages/core/src/public-api.ts

10
npm/ng-packs/packages/account/src/lib/services/manage-profile.state.service.ts

@ -1,9 +1,9 @@
import { InternalStore, ProfileDto } from '@abp/ng.core';
import { Injectable } from '@angular/core';
import { InternalStore, Profile } from '@abp/ng.core';
import { Observable } from 'rxjs';
export interface ManageProfileState {
profile: Profile.Response;
profile: ProfileDto;
}
@Injectable({ providedIn: 'root' })
@ -14,15 +14,15 @@ export class ManageProfileStateService {
return this.store.sliceUpdate;
}
getProfile$(): Observable<Profile.Response> {
getProfile$(): Observable<ProfileDto> {
return this.store.sliceState(state => state.profile);
}
getProfile(): Profile.Response {
getProfile(): ProfileDto {
return this.store.state.profile;
}
setProfile(profile: Profile.Response) {
setProfile(profile: ProfileDto) {
this.store.patch({ profile });
}
}

24
npm/ng-packs/packages/core/src/lib/actions/config.actions.ts

@ -1,24 +0,0 @@
import { Config } from '../models/config';
/**
* @deprecated Use ConfigStateService. To be deleted in v5.0.
*/
export class GetAppConfiguration {
static readonly type = '[Config] Get App Configuration';
}
/**
* @deprecated Use EnvironmentService instead. To be deleted in v5.0.
*/
export class SetEnvironment {
static readonly type = '[Config] Set Environment';
constructor(public environment: Config.Environment) {}
}
/**
* @deprecated Use EnvironmentService instead. To be deleted in v5.0.
*/
export class PatchConfigState {
static readonly type = '[Config] Set State';
constructor(public state: Config.State) {}
}

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

@ -1,4 +1 @@
export { GetAppConfiguration, SetEnvironment } from './config.actions';
export * from './loader.actions';
export * from './profile.actions';
export * from './rest.actions';

15
npm/ng-packs/packages/core/src/lib/actions/profile.actions.ts

@ -1,15 +0,0 @@
import { Profile } from '../models';
export class GetProfile {
static readonly type = '[Profile] Get';
}
export class UpdateProfile {
static readonly type = '[Profile] Update';
constructor(public payload: Profile.Response) {}
}
export class ChangePassword {
static readonly type = '[Profile] Change Password';
constructor(public payload: Profile.ChangePasswordRequest) {}
}

5
npm/ng-packs/packages/core/src/lib/core.module.ts

@ -3,7 +3,6 @@ import { HttpClientModule, HttpClientXsrfModule, HTTP_INTERCEPTORS } from '@angu
import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { NgxsModule } from '@ngxs/store';
import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import { AbstractNgModelComponent } from './abstracts/ng-model.component';
import { DynamicLayoutComponent } from './components/dynamic-layout.component';
@ -27,13 +26,12 @@ import { LocalizationPipe } from './pipes/localization.pipe';
import { SortPipe } from './pipes/sort.pipe';
import { LocaleProvider } from './providers/locale.provider';
import { LocalizationService } from './services/localization.service';
import { ProfileState } from './states/profile.state';
import { oAuthStorage } from './strategies/auth-flow.strategy';
import { coreOptionsFactory, CORE_OPTIONS } from './tokens/options.token';
import { TENANT_KEY } from './tokens/tenant-key.token';
import { noop } from './utils/common-utils';
import './utils/date-extensions';
import { getInitialData, localeInitializer } from './utils/initial-utils';
import { TENANT_KEY } from './tokens/tenant-key.token';
export function storageFactory(): OAuthStorage {
return oAuthStorage;
@ -111,7 +109,6 @@ export class BaseCoreModule {}
imports: [
BaseCoreModule,
LocalizationModule,
NgxsModule.forFeature([ProfileState]),
OAuthModule.forRoot(),
HttpClientXsrfModule.withOptions({
cookieName: 'XSRF-TOKEN',

44
npm/ng-packs/packages/core/src/lib/models/profile.ts

@ -1,28 +1,26 @@
import { ExtensibleObject } from './dtos';
export namespace Profile {
export interface State {
profile: Response;
}
export interface ChangePasswordInput {
currentPassword: string;
newPassword: string;
}
export interface Response extends Partial<ExtensibleObject> {
userName: string;
email: string;
name: string;
surname: string;
phoneNumber: string;
/**
* Following 4 fields are added as optional (for backward compatibility) on 17.08.2020
* Also, this interface extends `ExtensibleObject` as partial for extraProperties field.
*/
isExternal?: boolean;
hasPassword?: boolean;
emailConfirmed?: boolean;
phoneNumberConfirmed?: boolean;
}
export interface ProfileDto extends ExtensibleObject {
userName: string;
email: string;
name: string;
surname: string;
phoneNumber: string;
isExternal?: boolean;
hasPassword?: boolean;
emailConfirmed?: boolean;
phoneNumberConfirmed?: boolean;
}
export interface ChangePasswordRequest {
currentPassword: string;
newPassword: string;
}
export interface UpdateProfileDto extends ExtensibleObject {
userName: string;
email: string;
name: string;
surname: string;
phoneNumber: string;
}

7
npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts

@ -1,5 +1,5 @@
import { Injectable, Pipe, PipeTransform } from '@angular/core';
import { Config } from '../models';
import { LocalizationWithDefault } from '../models/localization';
import { LocalizationService } from '../services/localization.service';
@Injectable()
@ -9,10 +9,7 @@ import { LocalizationService } from '../services/localization.service';
export class LocalizationPipe implements PipeTransform {
constructor(private localization: LocalizationService) {}
transform(
value: string | Config.LocalizationWithDefault = '',
...interpolateParams: string[]
): string {
transform(value: string | LocalizationWithDefault = '', ...interpolateParams: string[]): string {
return this.localization.instant(
value,
...interpolateParams.reduce(

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

@ -10,7 +10,6 @@ export * from './list.service';
export * from './localization.service';
export * from './multi-tenancy.service';
export * from './permission.service';
export * from './profile-state.service';
export * from './profile.service';
export * from './replaceable-components.service';
export * from './resource-wait.service';

11
npm/ng-packs/packages/core/src/lib/services/localization.service.ts

@ -3,7 +3,7 @@ import { Injectable, Injector, isDevMode, Optional, SkipSelf } from '@angular/co
import { from, Observable, Subject } from 'rxjs';
import { filter, map, mapTo, switchMap } from 'rxjs/operators';
import { ABP } from '../models/common';
import { Config } from '../models/config';
import { LocalizationWithDefault } from '../models/localization';
import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models';
import { CORE_OPTIONS } from '../tokens/options.token';
import { createLocalizer, createLocalizerWithFallback } from '../utils/localization-utils';
@ -67,10 +67,7 @@ export class LocalizationService {
* @param key Localizaton key to replace with localized text
* @param interpolateParams Values to interpolate
*/
get(
key: string | Config.LocalizationWithDefault,
...interpolateParams: string[]
): Observable<string> {
get(key: string | LocalizationWithDefault, ...interpolateParams: string[]): Observable<string> {
return this.configState
.getAll$()
.pipe(map(state => getLocalization(state, key, ...interpolateParams)));
@ -89,7 +86,7 @@ export class LocalizationService {
* @param key Localization key to replace with localized text
* @param interpolateParams Values to intepolate.
*/
instant(key: string | Config.LocalizationWithDefault, ...interpolateParams: string[]): string {
instant(key: string | LocalizationWithDefault, ...interpolateParams: string[]): string {
return getLocalization(this.configState.getAll(), key, ...interpolateParams);
}
@ -124,7 +121,7 @@ export class LocalizationService {
function getLocalization(
state: ApplicationConfigurationDto,
key: string | Config.LocalizationWithDefault,
key: string | LocalizationWithDefault,
...interpolateParams: string[]
) {
if (!key) key = '';

28
npm/ng-packs/packages/core/src/lib/services/profile-state.service.ts

@ -1,28 +0,0 @@
import { Injectable } from '@angular/core';
import { Store } from '@ngxs/store';
import { ProfileState } from '../states';
import { Profile } from '../models';
import { GetProfile, UpdateProfile, ChangePassword } from '../actions';
@Injectable({
providedIn: 'root',
})
export class ProfileStateService {
constructor(private store: Store) {}
getProfile() {
return this.store.selectSnapshot(ProfileState.getProfile);
}
dispatchGetProfile() {
return this.store.dispatch(new GetProfile());
}
dispatchUpdateProfile(...args: ConstructorParameters<typeof UpdateProfile>) {
return this.store.dispatch(new UpdateProfile(...args));
}
dispatchChangePassword(...args: ConstructorParameters<typeof ChangePassword>) {
return this.store.dispatch(new ChangePassword(...args));
}
}

71
npm/ng-packs/packages/core/src/lib/services/profile.service.ts

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { ChangePasswordInput, ProfileDto, UpdateProfileDto } from '../models/profile';
import { RestService } from './rest.service';
import { Profile, Rest } from '../models';
@Injectable({
providedIn: 'root',
@ -9,42 +8,34 @@ import { Profile, Rest } from '../models';
export class ProfileService {
apiName = 'AbpIdentity';
constructor(private rest: RestService) {}
get(): Observable<Profile.Response> {
const request: Rest.Request<null> = {
method: 'GET',
url: '/api/identity/my-profile',
};
return this.rest.request<null, Profile.Response>(request, { apiName: this.apiName });
}
update(body: Profile.Response): Observable<Profile.Response> {
const request: Rest.Request<Profile.Response> = {
method: 'PUT',
url: '/api/identity/my-profile',
body,
};
return this.rest.request<Profile.Response, Profile.Response>(request, {
apiName: this.apiName,
});
}
changePassword(
body: Profile.ChangePasswordRequest,
skipHandleError: boolean = false,
): Observable<null> {
const request: Rest.Request<Profile.ChangePasswordRequest> = {
method: 'POST',
url: '/api/identity/my-profile/change-password',
body,
};
return this.rest.request<Profile.ChangePasswordRequest, null>(request, {
skipHandleError,
apiName: this.apiName,
});
}
changePassword = (input: ChangePasswordInput, skipHandleError = false) =>
this.restService.request<ChangePasswordInput, void>(
{
method: 'POST',
url: '/api/identity/my-profile/change-password',
body: input,
},
{ apiName: this.apiName, skipHandleError },
);
get = () =>
this.restService.request<null, ProfileDto>(
{
method: 'GET',
url: '/api/identity/my-profile',
},
{ apiName: this.apiName },
);
update = (input: UpdateProfileDto) =>
this.restService.request<UpdateProfileDto, ProfileDto>(
{
method: 'PUT',
url: '/api/identity/my-profile',
body: input,
},
{ apiName: this.apiName },
);
constructor(private restService: RestService) {}
}

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

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

47
npm/ng-packs/packages/core/src/lib/states/profile.state.ts

@ -1,47 +0,0 @@
import { Injectable } from '@angular/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { tap } from 'rxjs/operators';
import { ChangePassword, GetProfile, UpdateProfile } from '../actions/profile.actions';
import { Profile } from '../models/profile';
import { ProfileService } from '../services/profile.service';
@State<Profile.State>({
name: 'ProfileState',
defaults: {} as Profile.State,
})
@Injectable()
export class ProfileState {
@Selector()
static getProfile({ profile }: Profile.State): Profile.Response {
return profile;
}
constructor(private profileService: ProfileService) {}
@Action(GetProfile)
getProfile({ patchState }: StateContext<Profile.State>) {
return this.profileService.get().pipe(
tap(profile =>
patchState({
profile,
}),
),
);
}
@Action(UpdateProfile)
updateProfile({ patchState }: StateContext<Profile.State>, { payload }: UpdateProfile) {
return this.profileService.update(payload).pipe(
tap(profile =>
patchState({
profile,
}),
),
);
}
@Action(ChangePassword)
changePassword(_, { payload }: ChangePassword) {
return this.profileService.changePassword(payload, true);
}
}

57
npm/ng-packs/packages/core/src/lib/tests/profile-state.service.spec.ts

@ -1,57 +0,0 @@
import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { ProfileStateService } from '../services/profile-state.service';
import { ProfileState } from '../states/profile.state';
import { Store } from '@ngxs/store';
import * as ProfileActions from '../actions';
describe('ProfileStateService', () => {
let service: ProfileStateService;
let spectator: SpectatorService<ProfileStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: ProfileStateService, mocks: [Store] });
beforeEach(() => {
spectator = createService();
service = spectator.service;
store = spectator.inject(Store);
});
test('should have the all ProfileState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm;
ProfileState.toString()
.match(reg)
.forEach(fnName => {
expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = ProfileState[fnName].name !== 'memoized';
if (isDynamicSelector) {
ProfileState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(ProfileState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(ProfileState[fnName]);
}
});
});
test('should have a dispatch method for every ProfileState action', () => {
const reg = /(?<=dispatch)(\w+)(?=\()/gm;
ProfileStateService.toString()
.match(reg)
.forEach(fnName => {
expect(ProfileActions[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'dispatch');
spy.mockClear();
const params = Array.from(new Array(ProfileActions[fnName].length));
service[`dispatch${fnName}`](...params);
expect(spy).toHaveBeenCalledWith(new ProfileActions[fnName](...params));
});
});
});

74
npm/ng-packs/packages/core/src/lib/tests/profile.state.spec.ts

@ -1,74 +0,0 @@
import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { Session } from '../models/session';
import { ProfileService } from '../services';
import { ProfileState } from '../states';
import { GetAppConfiguration } from '../actions/config.actions';
import { of } from 'rxjs';
import { Profile } from '../models/profile';
export class DummyClass {}
export const PROFILE_STATE_DATA = {
profile: { userName: 'admin', email: 'info@abp.io', name: 'Admin' },
} as Profile.State;
describe('ProfileState', () => {
let spectator: SpectatorService<DummyClass>;
let state: ProfileState;
let profileService: SpyObject<ProfileService>;
let patchedData;
const patchState = jest.fn(data => (patchedData = data));
const createService = createServiceFactory({
service: DummyClass,
mocks: [ProfileService],
});
beforeEach(() => {
spectator = createService();
profileService = spectator.inject(ProfileService);
state = new ProfileState(profileService);
});
describe('#getProfile', () => {
it('should return the current language', () => {
expect(ProfileState.getProfile(PROFILE_STATE_DATA)).toEqual(PROFILE_STATE_DATA.profile);
});
});
describe('#GetProfile', () => {
it('should call the profile service get method and update the state', () => {
const mockData = { userName: 'test', email: 'test@abp.io' };
const spy = jest.spyOn(profileService, 'get');
spy.mockReturnValue(of(mockData as any));
state.getProfile({ patchState } as any).subscribe();
expect(patchedData).toEqual({ profile: mockData });
});
});
describe('#UpdateProfile', () => {
it('should call the profile service update method and update the state', () => {
const mockData = { userName: 'test2', email: 'test@abp.io' };
const spy = jest.spyOn(profileService, 'update');
spy.mockReturnValue(of(mockData as any));
state.updateProfile({ patchState } as any, { payload: mockData as any }).subscribe();
expect(patchedData).toEqual({ profile: mockData });
});
});
describe('#ChangePassword', () => {
it('should call the profile service changePassword method', () => {
const mockData = { currentPassword: 'test123', newPassword: 'test123' };
const spy = jest.spyOn(profileService, 'changePassword');
spy.mockReturnValue(of(null));
state.changePassword(null, { payload: mockData }).subscribe();
expect(spy).toHaveBeenCalledWith(mockData, true);
});
});
});

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

@ -24,7 +24,6 @@ export * from './lib/proxy/volo/abp/http/modeling';
export * from './lib/proxy/volo/abp/localization';
export * from './lib/proxy/volo/abp/models';
export * from './lib/services';
export * from './lib/states';
export * from './lib/strategies';
export * from './lib/tokens';
export * from './lib/utils';

Loading…
Cancel
Save