Просмотр исходного кода

refactor(admin-ui): Remove ngrx and related files

Michael Bromley 7 лет назад
Родитель
Сommit
20e41cb3a3

+ 0 - 3
admin-ui/package.json

@@ -25,7 +25,6 @@
     "@clr/angular": "^0.11.21",
     "@clr/icons": "^0.11.21",
     "@clr/ui": "^0.11.21",
-    "@ngrx/store": "^6.0.1",
     "@webcomponents/custom-elements": "1.0.0",
     "apollo-angular": "^1.1.1",
     "apollo-angular-cache-ngrx": "^1.0.0-beta.0",
@@ -37,8 +36,6 @@
     "core-js": "^2.5.4",
     "graphql": "^0.13.2",
     "graphql-tag": "^2.9.2",
-    "immer": "^1.3.1",
-    "ngrx-store-logger": "^0.2.2",
     "rxjs": "^6.0.0",
     "rxjs-compat": "^6.2.1",
     "zone.js": "^0.8.26"

+ 7 - 4
admin-ui/src/app/core/components/app-shell/app-shell.component.ts

@@ -1,7 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
 import { Observable } from 'rxjs';
-import { StateStore } from '../../../state/state-store.service';
+import { map } from 'rxjs/operators';
+import { DataService } from '../../../data/providers/data.service';
 import { AuthService } from '../../providers/auth/auth.service';
 
 @Component({
@@ -13,12 +14,14 @@ export class AppShellComponent implements OnInit {
 
     userName$: Observable<string>;
 
-    constructor(private store: StateStore,
-                private authService: AuthService,
+    constructor(private authService: AuthService,
+                private dataService: DataService,
                 private router: Router) { }
 
     ngOnInit() {
-        this.userName$ = this.store.select(state => state.user.username);
+        this.userName$ = this.dataService.client.userStatus().single$.pipe(
+            map(data => data.userStatus.username),
+        );
     }
 
     logOut() {

+ 4 - 5
admin-ui/src/app/core/components/breadcrumb/breadcrumb.component.ts

@@ -3,8 +3,7 @@ import { ActivatedRoute, Data, NavigationEnd, Params, PRIMARY_OUTLET, Router } f
 import { flatten } from 'lodash';
 import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subject } from 'rxjs';
 import { filter, map, takeUntil } from 'rxjs/operators';
-
-import { StateStore } from '../../../state/state-store.service';
+import { DataService } from '../../../data/providers/data.service';
 
 export type BreadcrumbString = string;
 export interface BreadcrumbLabelLinkPair {
@@ -12,7 +11,7 @@ export interface BreadcrumbLabelLinkPair {
     link: any[];
 }
 export type BreadcrumbValue = BreadcrumbString | BreadcrumbLabelLinkPair | BreadcrumbLabelLinkPair[];
-export type BreadcrumbFunction = (data: Data, params: Params, store: StateStore) => BreadcrumbValue | Observable<BreadcrumbValue>;
+export type BreadcrumbFunction = (data: Data, params: Params, dataService: DataService) => BreadcrumbValue | Observable<BreadcrumbValue>;
 export type BreadcrumbDefinition = BreadcrumbValue | BreadcrumbFunction | Observable<BreadcrumbValue>;
 
 /**
@@ -36,7 +35,7 @@ export class BreadcrumbComponent implements OnDestroy {
 
     constructor(private router: Router,
                 private route: ActivatedRoute,
-                private store: StateStore) {
+                private dataService: DataService) {
         this.router.events.pipe(
             filter(event => event instanceof NavigationEnd),
             takeUntil(this.destroy$))
@@ -99,7 +98,7 @@ export class BreadcrumbComponent implements OnDestroy {
 
                     if (breadcrumbDef) {
                         if (isBreadcrumbFunction(breadcrumbDef)) {
-                            breadcrumbDef = breadcrumbDef(routeSnapshot.data, routeSnapshot.params, this.store);
+                            breadcrumbDef = breadcrumbDef(routeSnapshot.data, routeSnapshot.params, this.dataService);
                         }
                         const observableValue = isObservable(breadcrumbDef) ? breadcrumbDef : observableOf(breadcrumbDef);
                         breadcrumbParts.push({ value$: observableValue, path: segmentPaths.slice() });

+ 0 - 2
admin-ui/src/app/core/core.module.ts

@@ -1,7 +1,6 @@
 import { NgModule } from '@angular/core';
 import { DataModule } from '../data/data.module';
 import { SharedModule } from '../shared/shared.module';
-import { StateModule } from '../state/state.module';
 import { AppShellComponent } from './components/app-shell/app-shell.component';
 import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';
 import { MainNavComponent } from './components/main-nav/main-nav.component';
@@ -18,7 +17,6 @@ import { OverlayHostService } from './providers/overlay-host/overlay-host.servic
     imports: [
         DataModule,
         SharedModule,
-        StateModule,
     ],
     exports: [
         SharedModule,

+ 1 - 6
admin-ui/src/app/data/providers/interceptor.ts

@@ -4,7 +4,6 @@ import { Injectable } from '@angular/core';
 import { Observable, throwError } from 'rxjs';
 import { catchError, tap } from 'rxjs/operators';
 
-import { ApiActions } from '../../state/api/api-actions';
 import { NotificationService } from '../../core/providers/notification/notification.service';
 import { DataService } from './data.service';
 
@@ -15,26 +14,22 @@ import { DataService } from './data.service';
 @Injectable()
 export class DefaultInterceptor implements HttpInterceptor {
 
-    constructor(private apiActions: ApiActions,
-                private dataService: DataService,
+    constructor(private dataService: DataService,
                 private notification: NotificationService) {}
 
     intercept(req: HttpRequest<any>, next: HttpHandler):
         Observable<HttpEvent<any>> {
-        this.apiActions.startRequest();
         this.dataService.client.startRequest().subscribe();
         return next.handle(req).pipe(
             tap(event => {
                     if (event instanceof HttpResponse) {
                         this.notifyOnGraphQLErrors(event);
-                        this.apiActions.requestCompleted();
                         this.dataService.client.completeRequest().subscribe();
                     }
                 },
                 err => {
                     if (err instanceof HttpErrorResponse) {
                         this.notification.error(err.message);
-                        this.apiActions.requestCompleted();
                         this.dataService.client.completeRequest().subscribe();
                     }
                 }),

+ 0 - 34
admin-ui/src/app/state/action-logger.ts

@@ -1,34 +0,0 @@
-import { ActionReducer } from '@ngrx/store';
-import { storeLogger } from 'ngrx-store-logger';
-
-import { AppState } from './app-state';
-
-/**
- * A meta reducer which logs actions to the console for debugging purposes.
- */
-export function actionLogger(reducer: ActionReducer<AppState>): any {
-    const key = 'vdr_logToConsole';
-    const localSetting = sessionStorage.getItem(key);
-    let logToConsole = localSetting === 'true';
-
-    Object.defineProperty(window, 'vdr_log_actions', {
-        get: () => {
-            return logToConsole ? 'Logging actions enabled' : 'No longer logging actions';
-        },
-        set: (active: any) => {
-            logToConsole = !!active;
-            sessionStorage.setItem(key, logToConsole.toString());
-        },
-    });
-
-    return (state, action) => {
-        if (logToConsole) {
-            return storeLogger({
-                collapsed: true,
-            })(reducer)(state, action);
-        } else {
-            return reducer(state, action);
-        }
-    };
-
-}

+ 0 - 19
admin-ui/src/app/state/api/api-actions.ts

@@ -1,19 +0,0 @@
-import { Injectable } from '@angular/core';
-
-import { StateStore } from '../state-store.service';
-
-import {Actions} from './api-state';
-
-@Injectable()
-export class ApiActions {
-
-    constructor(private store: StateStore) {}
-
-    startRequest(): void {
-        this.store.dispatch(new Actions.StartRequest());
-    }
-
-    requestCompleted(): void {
-        this.store.dispatch(new Actions.RequestCompleted());
-    }
-}

+ 0 - 26
admin-ui/src/app/state/api/api-reducer.ts

@@ -1,26 +0,0 @@
-import produce from 'immer';
-
-import {reducerCaseNever} from '../../common/utilities/common';
-
-import {Actions, ActionType, ApiState, initialApiState} from './api-state';
-
-/**
- * Reducer for user (auth state etc.)
- */
-export function api(state: ApiState = initialApiState, action: Actions): ApiState {
-    return produce(state, draft => {
-        switch (action.type) {
-
-            case ActionType.START_REQUEST:
-                draft.inFlightRequests++;
-                return draft;
-
-            case ActionType.REQUEST_COMPLETED:
-                draft.inFlightRequests--;
-                return draft;
-
-            default:
-                reducerCaseNever(action);
-        }
-    });
-}

+ 0 - 31
admin-ui/src/app/state/api/api-state.ts

@@ -1,31 +0,0 @@
-import { Action } from '@ngrx/store';
-
-export interface ApiState {
-    inFlightRequests: number;
-}
-
-export const initialApiState: ApiState = {
-    inFlightRequests: 0,
-};
-
-export enum ActionType  {
-    START_REQUEST = 'api/START_REQUEST',
-    REQUEST_COMPLETED = 'api/REQUEST_COMPLETED',
-}
-
-export class StartRequest implements Action {
-    readonly type = ActionType.START_REQUEST;
-}
-
-export class RequestCompleted implements Action {
-    readonly type = ActionType.REQUEST_COMPLETED;
-}
-
-export const Actions = {
-    StartRequest,
-    RequestCompleted,
-};
-
-export type Actions =
-    StartRequest |
-    RequestCompleted;

+ 0 - 10
admin-ui/src/app/state/app-state.ts

@@ -1,10 +0,0 @@
-import { NormalizedCacheObject } from 'apollo-cache-inmemory/src/types';
-
-import { ApiState } from './api/api-state';
-import { UserState } from './user/user-state';
-
-export interface AppState {
-    api: ApiState;
-    entities: NormalizedCacheObject;
-    user: UserState;
-}

+ 0 - 24
admin-ui/src/app/state/handle-error.ts

@@ -1,24 +0,0 @@
-import {EMPTY, Observable} from 'rxjs';
-import {catchError} from 'rxjs/operators';
-
-/**
- * An error-handling operator which will execute the onErrorSideEffect() function and then
- * catch the error and complete the stream, so that any further operators are bypassed.
- *
- * Designed to be used with the .let() operator or in the pipable style.
- *
- * @example
- * ```
- * this.dataService.fetchData()
- *  .let(handleError(err => this.store.dispatch(new Actions.FetchError(err)))
- *  .do(data => this.store.dispatch(new Actions.FetchSuccess(data))
- *  .subscribe();
- * ```
- */
-export function handleError<T>(onErrorSideEffect: (err: any) => void): (observable: Observable<T>) => Observable<T> {
-    return (observable: Observable<T>) => observable.pipe(
-        catchError(err => {
-            onErrorSideEffect(err);
-            return EMPTY;
-        }));
-}

+ 0 - 85
admin-ui/src/app/state/state-store.service.ts

@@ -1,85 +0,0 @@
-import { Injectable } from '@angular/core';
-import { Action, Store } from '@ngrx/store';
-import { Observable, Subscription } from 'rxjs';
-import { distinctUntilChanged, take } from 'rxjs/operators';
-
-import { AppState } from './app-state';
-
-/**
- * Wrapper class which wraps the @ngrx/store Store object, and also provides additional
- * convenience methods for accessing data.
- */
-@Injectable()
-export class StateStore {
-
-    observeStateSubscriptions: Subscription[] = [];
-
-    constructor(public _internalStore: Store<AppState>) {
-        // expose the AppStore on the window for debug purposes
-        Object.defineProperty(window, 'vdr_app_state', {
-            get: () => this.getState(),
-        });
-        // allow observing of particular state for debug purposes
-        Object.defineProperty(window, 'vdr_observe_state', {
-            get: () => this.observeState.bind(this),
-        });
-    }
-
-    /**
-     * The store object can be manually set (mainly for testing purposes).
-     */
-    public setStore(store): void {
-        this._internalStore = store;
-    }
-
-    public getState(): AppState {
-        // Hacky typing here because TypeScript does not know that .take().subscribe() is a
-        // synchronous operation, and therefore complains that "state" has not been assigned
-        // when it is returned.
-        let state = {} as any;
-        this._internalStore.pipe(take(1)).subscribe(s => state = s);
-        return state;
-    }
-
-    public select<T>(selector: (state: AppState) => T): Observable<T> {
-        return this._internalStore.select<T>(selector).pipe(
-            distinctUntilChanged());
-    }
-
-    public dispatch(action: Action): void {
-        return this._internalStore.dispatch(action);
-    }
-
-    public subscribe(callback: (_) => any): Subscription {
-        return this._internalStore.subscribe(callback);
-    }
-
-    /**
-     * Allows the creation of ad-hoc subscriptions to the app state, and logs the value whenever that part of the state changes.
-     *
-     * Returns an unsubscribe function.
-     */
-    public observeState(selector: (state: AppState) => any): (() => void) | void  {
-        let hasError = false;
-
-        // tslint:disable:no-console
-        const sub = this.select(selector)
-            .subscribe(
-                value => console.log(`%c ${selector.toString()}:`, 'color: #0d35a9;', value),
-                err => {
-                    console.log(`%c "${selector.toString()}" is an invalid selector function:`, 'color: #f00', err.message);
-                    hasError = true;
-                },
-            );
-        // tslint:enable:no-console
-
-        if (!hasError) {
-            this.observeStateSubscriptions.push(sub);
-            return () => {
-                sub.unsubscribe();
-                const index = this.observeStateSubscriptions.indexOf(sub);
-                this.observeStateSubscriptions.splice(index, 1);
-            };
-        }
-    }
-}

+ 0 - 44
admin-ui/src/app/state/state.module.ts

@@ -1,44 +0,0 @@
-import { InjectionToken, NgModule } from '@angular/core';
-import { Store, StoreModule } from '@ngrx/store';
-import { apolloReducer, NgrxCache, NgrxCacheModule } from 'apollo-angular-cache-ngrx';
-import { InMemoryCache } from 'apollo-cache-inmemory';
-
-import { environment } from '../../environments/environment';
-
-import { actionLogger } from './action-logger';
-import { ApiActions } from './api/api-actions';
-import { api } from './api/api-reducer';
-import { StateStore } from './state-store.service';
-import { UserActions } from './user/user-actions';
-import { user } from './user/user-reducer';
-
-export const APOLLO_NGRX_CACHE = new InjectionToken<InMemoryCache>('APOLLO_NGRX_CACHE');
-
-export function createApolloNgrxCache(ngrxCache: NgrxCache, store: Store<any>): InMemoryCache {
-    return ngrxCache.create();
-}
-
-export const metaReducers = environment.production ? [] : [actionLogger];
-
-@NgModule({
-    imports: [
-        NgrxCacheModule,
-        StoreModule.forRoot({
-            entities: apolloReducer,
-            api,
-            user,
-        }, { metaReducers }),
-        NgrxCacheModule.forRoot('entities'),
-    ],
-    providers: [
-        {
-            provide: APOLLO_NGRX_CACHE,
-            useFactory: createApolloNgrxCache,
-            deps: [NgrxCache, Store],
-        },
-        UserActions,
-        StateStore,
-        ApiActions,
-    ],
-})
-export class StateModule {}

+ 0 - 61
admin-ui/src/app/state/user/user-actions.ts

@@ -1,61 +0,0 @@
-import {Injectable} from '@angular/core';
-import { EMPTY, Observable, of, throwError } from 'rxjs';
-import { catchError, map } from 'rxjs/operators';
-
-import { DataService } from '../../data/providers/data.service';
-import { LocalStorageService } from '../../core/providers/local-storage/local-storage.service';
-import { handleError } from '../handle-error';
-import { StateStore } from '../state-store.service';
-
-import {Actions} from './user-state';
-
-@Injectable()
-export class UserActions {
-
-    constructor(private store: StateStore,
-                private localStorageService: LocalStorageService,
-                private dataService: DataService) {}
-
-    checkAuth(): Observable<boolean> {
-        if (!this.localStorageService.get('authToken')) {
-            return of(false);
-        }
-
-        this.store.dispatch(new Actions.Login());
-
-        return this.dataService.user.checkLoggedIn().pipe(
-            map(result => {
-                this.store.dispatch(new Actions.LoginSuccess({
-                    username: result.identifier,
-                    loginTime: Date.now(),
-                }));
-                return true;
-            }),
-            catchError(err => of(false)),
-        );
-    }
-
-    logIn(username: string, password: string): Observable<any> {
-        this.store.dispatch(new Actions.Login());
-
-        return this.dataService.user.attemptLogin(username, password).pipe(
-            map(result => {
-                this.store.dispatch(new Actions.LoginSuccess({
-                    username,
-                    loginTime: Date.now(),
-                }));
-                this.localStorageService.set('authToken', result.token);
-            }),
-            catchError(err => {
-                this.store.dispatch(new Actions.LoginError(err));
-                return throwError(err);
-            }),
-        );
-    }
-
-    logOut(): void {
-        this.localStorageService.remove('authToken');
-        this.store.dispatch(new Actions.Logout());
-    }
-
-}

+ 0 - 65
admin-ui/src/app/state/user/user-reducer.spec.ts

@@ -1,65 +0,0 @@
-import { user } from './user-reducer';
-import { Actions, UserState } from './user-state';
-
-describe('user reducer', () => {
-
-    it('should handle LOGIN', () => {
-        const state = {} as UserState;
-        const action = new Actions.Login();
-        const newState = user(state, action);
-
-        expect(newState).toEqual({
-            loggingIn: true,
-        } as any);
-    });
-
-    it('should handle LOGIN_SUCCESS', () => {
-        const state = {
-            loggingIn: true,
-            loginTime: -1,
-        } as UserState;
-        const action = new Actions.LoginSuccess({
-            username: 'test',
-            loginTime: 12345,
-        });
-        const newState = user(state, action);
-
-        expect(newState).toEqual({
-            username: 'test',
-            loggingIn: false,
-            isLoggedIn: true,
-            loginTime: 12345,
-        } as any);
-    });
-
-    it('should handle LOGIN_ERROR', () => {
-        const state = {
-            loggingIn: true,
-        } as UserState;
-        const action = new Actions.LoginError({ message: 'an error message' });
-        const newState = user(state, action);
-
-        expect(newState).toEqual({
-            loggingIn: false,
-            isLoggedIn: false,
-        } as any);
-    });
-
-    it('should handle LOGOUT', () => {
-        const state = {
-            username: 'test',
-            isLoggedIn: true,
-            loginTime: 12345,
-        } as UserState;
-        const action = new Actions.Logout();
-        const newState = user(state, action);
-
-        expect(newState).toEqual({
-            username: '',
-            loggingIn: false,
-            isLoggedIn: false,
-            loginTime: -1,
-        } as any);
-    });
-
-});

+ 0 - 41
admin-ui/src/app/state/user/user-reducer.ts

@@ -1,41 +0,0 @@
-import produce from 'immer';
-
-import {reducerCaseNever} from '../../common/utilities/common';
-
-import {Actions, ActionType, initialUserState, UserState} from './user-state';
-
-/**
- * Reducer for user (auth state etc.)
- */
-export function user(state: UserState = initialUserState, action: Actions): UserState {
-    return produce(state, draft => {
-        switch (action.type) {
-
-            case ActionType.LOGIN:
-                draft.loggingIn = true;
-                return;
-
-            case ActionType.LOGIN_SUCCESS:
-                draft.username = action.payload.username;
-                draft.loggingIn = false;
-                draft.isLoggedIn = true;
-                draft.loginTime = action.payload.loginTime;
-                return;
-
-            case ActionType.LOGIN_ERROR:
-                draft.loggingIn = false;
-                draft.isLoggedIn = false;
-                return;
-
-            case ActionType.LOGOUT:
-                draft.username = '';
-                draft.loggingIn = false;
-                draft.isLoggedIn = false;
-                draft.loginTime = -1;
-                return;
-
-            default:
-                reducerCaseNever(action);
-        }
-    });
-}

+ 0 - 60
admin-ui/src/app/state/user/user-state.ts

@@ -1,60 +0,0 @@
-import {Action} from '@ngrx/store';
-
-export interface UserState {
-    username: any;
-    loggingIn: boolean;
-    isLoggedIn: boolean;
-    loginTime: number;
-}
-
-export const initialUserState = {
-    username: '',
-    loggingIn: false,
-    isLoggedIn: false,
-    loginTime: -1,
-};
-
-export enum ActionType  {
-    CHECK_LOGGED_IN = 'user/CHECK_LOGGED_IN',
-    LOGIN = 'user/LOGIN',
-    LOGIN_SUCCESS = 'user/LOGIN_SUCCESS',
-    LOGIN_ERROR = 'user/LOGIN_ERROR',
-    LOGOUT = 'user/LOGOUT',
-}
-
-export class CheckLoggedIn implements Action {
-    readonly type = ActionType.LOGIN;
-}
-
-export class Login implements Action {
-    readonly type = ActionType.LOGIN;
-}
-
-export class LoginSuccess implements Action {
-    readonly type = ActionType.LOGIN_SUCCESS;
-    constructor(public payload: { username: string; loginTime: number }) {}
-}
-
-export class LoginError implements Action {
-    readonly type = ActionType.LOGIN_ERROR;
-    constructor(public payload: any) {}
-}
-
-export class Logout implements Action {
-    readonly type = ActionType.LOGOUT;
-}
-
-export const Actions = {
-    CheckLoggedIn,
-    Login,
-    LoginSuccess,
-    LoginError,
-    Logout,
-};
-
-export type Actions =
-    CheckLoggedIn |
-    Login |
-    LoginSuccess |
-    LoginError |
-    Logout;

+ 0 - 12
admin-ui/yarn.lock

@@ -223,10 +223,6 @@
     call-me-maybe "^1.0.1"
     glob-to-regexp "^0.3.0"
 
-"@ngrx/store@^6.0.1":
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-6.0.1.tgz#02c806ce20c698b997e81f5671e0edc07d32cf86"
-
 "@ngtools/webpack@6.0.8":
   version "6.0.8"
   resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-6.0.8.tgz#a05bce526aee9da62bb230a95fba83fee99d0bca"
@@ -3750,10 +3746,6 @@ immediate@~3.0.5:
   version "3.0.6"
   resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
 
-immer@^1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/immer/-/immer-1.3.1.tgz#3a8c18d9d618c8b7169760a79beec24a1da6a43e"
-
 import-local@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc"
@@ -5063,10 +5055,6 @@ next-tick@1:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
 
-ngrx-store-logger@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/ngrx-store-logger/-/ngrx-store-logger-0.2.2.tgz#c1ed4d5f30710bdb4583ddbe488b96fa44b03bda"
-
 nice-try@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"