From 28651460f58f818bd7966a6c13163709b45c23da Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 14 Dec 2018 14:30:58 -0700 Subject: [PATCH 1/2] SHIBUI-1031 Integration with endpoints --- .../container/admin-management.component.html | 12 ++--- .../container/admin-management.component.ts | 6 +-- .../user/admin/effect/collection.effect.ts | 2 +- ui/src/app/user/admin/model/admin-entity.ts | 25 +++++++++ ui/src/app/user/admin/model/admin.ts | 16 ++++-- .../user/admin/reducer/collection.reducer.ts | 2 +- .../app/user/admin/service/admin.service.ts | 54 ++++++++----------- 7 files changed, 72 insertions(+), 45 deletions(-) create mode 100644 ui/src/app/user/admin/model/admin-entity.ts diff --git a/ui/src/app/user/admin/container/admin-management.component.html b/ui/src/app/user/admin/container/admin-management.component.html index 7b32aa82f..13d79a1ff 100644 --- a/ui/src/app/user/admin/container/admin-management.component.html +++ b/ui/src/app/user/admin/container/admin-management.component.html @@ -20,16 +20,16 @@ - {{ user.resourceId }} - {{ user.name.first }} {{ user.name.last }} - {{ user.email }} + {{ user.username }} + {{ user.firstName }} {{ user.lastName }} + {{ user.emailAddress }} - + - diff --git a/ui/src/app/user/admin/container/admin-management.component.ts b/ui/src/app/user/admin/container/admin-management.component.ts index 08c69264d..fd3219723 100644 --- a/ui/src/app/user/admin/container/admin-management.component.ts +++ b/ui/src/app/user/admin/container/admin-management.component.ts @@ -7,7 +7,7 @@ import * as fromAdmin from '../reducer'; import { UserService } from '../../../core/service/user.service'; import { LoadAdminRequest, UpdateAdminRequest, RemoveAdminRequest } from '../action/collection.action'; -import { Admin } from '../model/admin'; +import { Admin, Role } from '../model/admin'; @Component({ selector: 'admin-management-page', @@ -18,7 +18,7 @@ import { Admin } from '../model/admin'; export class AdminManagementPageComponent { users$: Observable; - roles$: Observable = of(['SUPER_ADMIN', 'DELEGATED_ADMIN']); + roles$: Observable = of([{name: 'ROLE_ADMIN' }, {name: 'ROLE_USER'}]); constructor( private store: Store @@ -28,7 +28,7 @@ export class AdminManagementPageComponent { this.users$ = this.store.select(fromAdmin.getAllAdmins); } - setUserRole(user: Admin, change: string): void { + setUserRole(user: Admin, change: Role): void { this.store.dispatch(new UpdateAdminRequest({ ...user, role: change diff --git a/ui/src/app/user/admin/effect/collection.effect.ts b/ui/src/app/user/admin/effect/collection.effect.ts index 6120faf5b..4958f1d8e 100644 --- a/ui/src/app/user/admin/effect/collection.effect.ts +++ b/ui/src/app/user/admin/effect/collection.effect.ts @@ -34,7 +34,7 @@ export class AdminCollectionEffects { map(action => action.payload), switchMap(changes => this.adminService.update(changes).pipe( map(user => new UpdateAdminSuccess({ - id: changes.resourceId, + id: changes.username, changes })) )) diff --git a/ui/src/app/user/admin/model/admin-entity.ts b/ui/src/app/user/admin/model/admin-entity.ts new file mode 100644 index 000000000..70a6e93b7 --- /dev/null +++ b/ui/src/app/user/admin/model/admin-entity.ts @@ -0,0 +1,25 @@ +import { Admin, Role } from './admin'; + +export class AdminEntity implements Admin { + + username: string; + firstName: string; + lastName: string; + emailAddress: string; + + roles: Role[]; + + constructor( + properties: Admin + ) { + Object.assign(this, properties); + } + + get role(): Role { + return this.roles[0]; + } + + set role(newRole: Role) { + this.roles[0] = newRole; + } +} diff --git a/ui/src/app/user/admin/model/admin.ts b/ui/src/app/user/admin/model/admin.ts index 5a5a9400a..29a29ccfe 100644 --- a/ui/src/app/user/admin/model/admin.ts +++ b/ui/src/app/user/admin/model/admin.ts @@ -1,9 +1,19 @@ import { User } from '../../../core/model/user'; -export interface Admin extends User { +export interface Admin { createdDate?: string; updatedDate?: string; - resourceId: string; + username: string; + firstName: string; + lastName: string; - email: string; + roles: Role[]; + + role: Role; + + emailAddress: string; +} + +export interface Role { + name: string; } diff --git a/ui/src/app/user/admin/reducer/collection.reducer.ts b/ui/src/app/user/admin/reducer/collection.reducer.ts index 1e884b907..70d8ba9a4 100644 --- a/ui/src/app/user/admin/reducer/collection.reducer.ts +++ b/ui/src/app/user/admin/reducer/collection.reducer.ts @@ -8,7 +8,7 @@ export interface CollectionState extends EntityState { } export const adapter: EntityAdapter = createEntityAdapter({ - selectId: (model: Admin) => model.resourceId + selectId: (model: Admin) => model.username }); export const initialState: CollectionState = adapter.getInitialState({ diff --git a/ui/src/app/user/admin/service/admin.service.ts b/ui/src/app/user/admin/service/admin.service.ts index 77bd39c05..1d050f433 100644 --- a/ui/src/app/user/admin/service/admin.service.ts +++ b/ui/src/app/user/admin/service/admin.service.ts @@ -1,47 +1,39 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { Admin } from '../model/admin'; - -let users = [ - { - resourceId: 'abc', - role: 'SUPER_ADMIN', - email: 'foo@bar.com', - name: { - first: 'Jane', - last: 'Doe' - } - }, - { - resourceId: 'def', - role: 'DELEGATED_ADMIN', - email: 'bar@baz.com', - name: { - first: 'John', - last: 'Doe' - } - } -]; +import { HttpClient } from '@angular/common/http'; +import { map, catchError } from 'rxjs/operators'; +import { AdminEntity } from '../model/admin-entity'; @Injectable() export class AdminService { - constructor() { } + private endpoint = '/admin/users'; + private base = '/api'; + + constructor( + private http: HttpClient + ) { } query(): Observable { - return of([ - ...users - ]); + return this.http.get( + `${this.base}${this.endpoint}`, {} + ).pipe( + map(users => users.map(u => new AdminEntity(u))) + ); } update(user: Admin): Observable { - return of({ - ...users.find(u => u.resourceId === user.resourceId), - ...user - }); + return this.http.put( + `${this.base}${this.endpoint}/${user.username}`, {user} + ); } remove(userId: string): Observable { - users = users.filter(u => u.resourceId !== userId); - return of(true); + return this.http.delete( + `${this.base}${this.endpoint}/${userId}` + ).pipe( + map(response => !!response), + catchError(() => of(false)) + ); } } From c207bd247ee7ec317e5db0fe5661b77c4631a707 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 7 Jan 2019 12:28:14 -0700 Subject: [PATCH 2/2] SHIBUI-1031 Integrated with backend endpoints --- .../app/core/action/configuration.action.ts | 29 +++++++++++++++++++ ui/src/app/core/effect/user.effect.ts | 14 +++++++++ .../app/core/reducer/configuration.reducer.ts | 25 ++++++++++++++++ ui/src/app/core/reducer/index.ts | 11 +++++-- ui/src/app/core/service/user.service.ts | 13 ++++++++- .../container/admin-management.component.html | 4 +-- .../container/admin-management.component.ts | 11 ++++--- ui/src/app/user/admin/model/admin-entity.ts | 12 ++------ ui/src/app/user/admin/model/admin.ts | 10 +------ .../app/user/admin/service/admin.service.ts | 2 +- 10 files changed, 102 insertions(+), 29 deletions(-) create mode 100644 ui/src/app/core/action/configuration.action.ts create mode 100644 ui/src/app/core/reducer/configuration.reducer.ts diff --git a/ui/src/app/core/action/configuration.action.ts b/ui/src/app/core/action/configuration.action.ts new file mode 100644 index 000000000..33c9e4c82 --- /dev/null +++ b/ui/src/app/core/action/configuration.action.ts @@ -0,0 +1,29 @@ +import { Action } from '@ngrx/store'; + +export enum ConfigurationActionTypes { + LOAD_ROLE_REQUEST = '[Config] Load User Role Request', + LOAD_ROLE_SUCCESS = '[Config] Load User Role Success', + LOAD_ROLE_FAIL = '[Config] Load User Role Fail' +} + +export class LoadRoleRequest implements Action { + readonly type = ConfigurationActionTypes.LOAD_ROLE_REQUEST; + + constructor() {} +} +export class LoadRoleSuccess implements Action { + readonly type = ConfigurationActionTypes.LOAD_ROLE_SUCCESS; + + constructor(public payload: string[]) { } +} +export class LoadRoleFail implements Action { + readonly type = ConfigurationActionTypes.LOAD_ROLE_FAIL; + + constructor() { } +} + +export type ConfigurationActionUnion = + | LoadRoleRequest + | LoadRoleSuccess + | LoadRoleFail +; diff --git a/ui/src/app/core/effect/user.effect.ts b/ui/src/app/core/effect/user.effect.ts index 72f3a8aac..42cc412ba 100644 --- a/ui/src/app/core/effect/user.effect.ts +++ b/ui/src/app/core/effect/user.effect.ts @@ -5,6 +5,7 @@ import { of } from 'rxjs'; import { map, tap, catchError, switchMap } from 'rxjs/operators'; import * as user from '../action/user.action'; +import { LoadRoleRequest, LoadRoleFail, LoadRoleSuccess, ConfigurationActionTypes } from '../action/configuration.action'; import { UserService } from '../service/user.service'; @Injectable() @@ -21,6 +22,19 @@ export class UserEffects { ) ) ); + + @Effect() + loadRoles$ = this.actions$.pipe( + ofType(ConfigurationActionTypes.LOAD_ROLE_REQUEST), + switchMap(() => + this.userService.getRoles() + .pipe( + map(roles => new LoadRoleSuccess(roles)), + catchError(error => of(new LoadRoleFail())) + ) + ) + ); + @Effect({dispatch: false}) redirect$ = this.actions$.pipe( ofType(user.REDIRECT), diff --git a/ui/src/app/core/reducer/configuration.reducer.ts b/ui/src/app/core/reducer/configuration.reducer.ts new file mode 100644 index 000000000..8f29e4126 --- /dev/null +++ b/ui/src/app/core/reducer/configuration.reducer.ts @@ -0,0 +1,25 @@ +import { ConfigurationActionUnion, ConfigurationActionTypes } from '../action/configuration.action'; + +export interface ConfigState { + roles: string[]; +} + +export const initialState: ConfigState = { + roles: [] +}; + +export function reducer(state = initialState, action: ConfigurationActionUnion): ConfigState { + switch (action.type) { + case ConfigurationActionTypes.LOAD_ROLE_SUCCESS: { + return { + roles: [...action.payload] + }; + } + default: { + return state; + } + } +} + + +export const getRoles = (state: ConfigState) => state.roles; diff --git a/ui/src/app/core/reducer/index.ts b/ui/src/app/core/reducer/index.ts index 15098e68e..9d9f91dec 100644 --- a/ui/src/app/core/reducer/index.ts +++ b/ui/src/app/core/reducer/index.ts @@ -5,11 +5,13 @@ import { import * as fromUser from './user.reducer'; import * as fromVersion from './version.reducer'; +import * as fromConfig from './configuration.reducer'; import * as fromRoot from '../../app.reducer'; export interface CoreState { user: fromUser.UserState; version: fromVersion.VersionState; + config: fromConfig.ConfigState; } export interface State extends fromRoot.State { @@ -18,19 +20,24 @@ export interface State extends fromRoot.State { export const reducers = { user: fromUser.reducer, - version: fromVersion.reducer + version: fromVersion.reducer, + config: fromConfig.reducer }; export const getCoreFeature = createFeatureSelector('core'); export const getUserStateFn = (state: CoreState) => state.user; export const getVersionStateFn = (state: CoreState) => state.version; +export const getConfigStateFn = (state: CoreState) => state.config; export const getUserState = createSelector(getCoreFeature, getUserStateFn); export const getUser = createSelector(getUserState, fromUser.getUser); export const isFetching = createSelector(getUserState, fromUser.isFetching); export const getUserError = createSelector(getUserState, fromUser.getError); -export const getVersionState = createSelector(getCoreFeature, (state: CoreState) => state.version); +export const getVersionState = createSelector(getCoreFeature, getVersionStateFn); export const getVersionInfo = createSelector(getVersionState, fromVersion.getVersionInfo); export const getVersionLoading = createSelector(getVersionState, fromVersion.getVersionIsLoading); export const getVersionError = createSelector(getVersionState, fromVersion.getVersionError); + +export const getConfigState = createSelector(getCoreFeature, getConfigStateFn); +export const getRoles = createSelector(getConfigState, fromConfig.getRoles); diff --git a/ui/src/app/core/service/user.service.ts b/ui/src/app/core/service/user.service.ts index 6570b4482..dae49d4e3 100644 --- a/ui/src/app/core/service/user.service.ts +++ b/ui/src/app/core/service/user.service.ts @@ -1,11 +1,16 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { User } from '../model/user'; +import { HttpClient } from '@angular/common/http'; @Injectable() export class UserService { - constructor() { } + readonly base = `/api`; + + constructor( + private http: HttpClient + ) { } get(): Observable { const defUser = Object.assign({}, { @@ -18,4 +23,10 @@ export class UserService { }); return of(defUser); } + + getRoles(): Observable { + return this.http.get( + `${this.base}/supportedRoles` + ); + } } /* istanbul ignore next */ diff --git a/ui/src/app/user/admin/container/admin-management.component.html b/ui/src/app/user/admin/container/admin-management.component.html index 13d79a1ff..5cc2e72b1 100644 --- a/ui/src/app/user/admin/container/admin-management.component.html +++ b/ui/src/app/user/admin/container/admin-management.component.html @@ -24,8 +24,8 @@ {{ user.firstName }} {{ user.lastName }} {{ user.emailAddress }} - + diff --git a/ui/src/app/user/admin/container/admin-management.component.ts b/ui/src/app/user/admin/container/admin-management.component.ts index fd3219723..b94a8c396 100644 --- a/ui/src/app/user/admin/container/admin-management.component.ts +++ b/ui/src/app/user/admin/container/admin-management.component.ts @@ -3,11 +3,12 @@ import { Store } from '@ngrx/store'; import { Observable, of } from 'rxjs'; import * as fromRoot from '../../../app.reducer'; +import * as fromCore from '../../../core/reducer'; import * as fromAdmin from '../reducer'; -import { UserService } from '../../../core/service/user.service'; import { LoadAdminRequest, UpdateAdminRequest, RemoveAdminRequest } from '../action/collection.action'; -import { Admin, Role } from '../model/admin'; +import { Admin } from '../model/admin'; +import { LoadRoleRequest } from '../../../core/action/configuration.action'; @Component({ selector: 'admin-management-page', @@ -18,17 +19,19 @@ import { Admin, Role } from '../model/admin'; export class AdminManagementPageComponent { users$: Observable; - roles$: Observable = of([{name: 'ROLE_ADMIN' }, {name: 'ROLE_USER'}]); + roles$: Observable; constructor( private store: Store ) { this.store.dispatch(new LoadAdminRequest()); + this.store.dispatch(new LoadRoleRequest()); this.users$ = this.store.select(fromAdmin.getAllAdmins); + this.roles$ = this.store.select(fromCore.getRoles); } - setUserRole(user: Admin, change: Role): void { + setUserRole(user: Admin, change: string): void { this.store.dispatch(new UpdateAdminRequest({ ...user, role: change diff --git a/ui/src/app/user/admin/model/admin-entity.ts b/ui/src/app/user/admin/model/admin-entity.ts index 70a6e93b7..8993660b2 100644 --- a/ui/src/app/user/admin/model/admin-entity.ts +++ b/ui/src/app/user/admin/model/admin-entity.ts @@ -1,4 +1,4 @@ -import { Admin, Role } from './admin'; +import { Admin } from './admin'; export class AdminEntity implements Admin { @@ -7,19 +7,11 @@ export class AdminEntity implements Admin { lastName: string; emailAddress: string; - roles: Role[]; + role: string; constructor( properties: Admin ) { Object.assign(this, properties); } - - get role(): Role { - return this.roles[0]; - } - - set role(newRole: Role) { - this.roles[0] = newRole; - } } diff --git a/ui/src/app/user/admin/model/admin.ts b/ui/src/app/user/admin/model/admin.ts index 29a29ccfe..b7cd90296 100644 --- a/ui/src/app/user/admin/model/admin.ts +++ b/ui/src/app/user/admin/model/admin.ts @@ -1,5 +1,3 @@ -import { User } from '../../../core/model/user'; - export interface Admin { createdDate?: string; updatedDate?: string; @@ -7,13 +5,7 @@ export interface Admin { firstName: string; lastName: string; - roles: Role[]; - - role: Role; + role: string; emailAddress: string; } - -export interface Role { - name: string; -} diff --git a/ui/src/app/user/admin/service/admin.service.ts b/ui/src/app/user/admin/service/admin.service.ts index 1d050f433..9f97e489d 100644 --- a/ui/src/app/user/admin/service/admin.service.ts +++ b/ui/src/app/user/admin/service/admin.service.ts @@ -24,7 +24,7 @@ export class AdminService { update(user: Admin): Observable { return this.http.put( - `${this.base}${this.endpoint}/${user.username}`, {user} + `${this.base}${this.endpoint}/${user.username}`, {...user} ); }