Skip to content

Commit

Permalink
refactor: move most of flow instance to service
Browse files Browse the repository at this point in the history
BREAKING CHANGE: most of flow instance is created in service
  • Loading branch information
ElonH committed May 25, 2020
1 parent 83d32bf commit 1bc2a36
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 239 deletions.
2 changes: 1 addition & 1 deletion src/app/@dataflow/extra/current-user-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export abstract class CurrentUserFlow extends SupersetFlow<
}

public static setLogin(name: string) {
localStorage.setItem('loginUser', JSON.stringify(name));
localStorage.setItem('loginUser', name);
}
public static getLogin(): string {
return localStorage.getItem('loginUser');
Expand Down
8 changes: 6 additions & 2 deletions src/app/@dataflow/rclone/connection-flow.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CombErr, SupersetFlow } from '../core';
import { IRcloneServer } from '../extra';
import { NoopAuthFlowSupNode } from '.';
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

export abstract class ConnectionFlow extends SupersetFlow<
Expand All @@ -11,7 +11,11 @@ export abstract class ConnectionFlow extends SupersetFlow<
> {
// public prerequest$: Observable<CombErr<NoopAuthFlowOutNode>>;
protected request(pre: CombErr<NoopAuthFlowSupNode>): Observable<CombErr<IRcloneServer>> {
throw new Error('Method not implemented.');
if (pre[1].length !== 0) return of([{} as any, pre[1]]);
const data: IRcloneServer = { url: pre[0].url };
if (pre[0].user) data.user = pre[0].user;
if (pre[0].password) data.password = pre[0].password;
return of([data, []]);
}
protected generateSuperset(
current: CombErr<IRcloneServer>,
Expand Down
4 changes: 2 additions & 2 deletions src/app/@dataflow/rclone/list-remotes-flow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PostFlow } from './post-flow';
import { NoopAuthFlowSupNode } from './noop-auth-flow';
import { CurrentUserFlowOutNode } from '../extra';
import { IRcloneServer } from '../extra';
import { CombErr, AjaxFlowInteralNode } from '../core';

export interface ListRemotesOutNode {
Expand All @@ -9,7 +9,7 @@ export interface ListRemotesOutNode {

export interface ListRemotesSupNode extends ListRemotesOutNode, NoopAuthFlowSupNode {}

export abstract class ListRemotesFlow extends PostFlow<CurrentUserFlowOutNode, ListRemotesOutNode> {
export abstract class ListRemotesFlow extends PostFlow<IRcloneServer, ListRemotesOutNode> {
// public prerequest$: Observable<CombErr<IRcloneServer>>;
protected cmd: string = 'config/listremotes';
protected params: object = {};
Expand Down
15 changes: 14 additions & 1 deletion src/app/@dataflow/rclone/operations-list-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,21 @@ export abstract class OperationsListFlow extends PostFlow<
OperationsListFlowParmsNode
> {
// public prerequest$: Observable<CombErr<OperationsListFlowInNode>>;
// protected params: OperationsListFlowParmsNode | ((pre: CombErr<OperationsListFlowInNode>) => OperationsListFlowParmsNode);
protected cmd: string = 'operations/list';
protected params = function (
pre: CombErr<OperationsListFlowInNode>
): OperationsListFlowParmsNode {
if (pre[1].length !== 0) return {} as any;
if (!pre[0].remote) throw new Error('not provide remote');
return {
fs: `${pre[0].remote}:`,
remote: pre[0].path ? pre[0].path : '',
// opt: {
// showOrigIDs: false, // TODO: depends on remote type(local, not support)
// showHash: false,
// },
};
};
protected cacheSupport: boolean = true;
protected reconstructAjaxResult(x: AjaxFlowInteralNode): CombErr<OperationsListFlowOutNode> {
if (x[1].length !== 0) return [{}, x[1]] as any;
Expand Down
8 changes: 4 additions & 4 deletions src/app/pages/dashboard/core-stats.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Injectable } from '@angular/core';
import { UsersService } from '../users.service';
import { CoreStatsFlow } from 'src/app/@dataflow/rclone';
import { interval } from 'rxjs';
import { withLatestFrom, map } from 'rxjs/operators';
import { map, combineLatest } from 'rxjs/operators';
import { CombErr } from 'src/app/@dataflow/core';
import { IRcloneServer } from 'src/app/@dataflow/extra';
import { ConnectionService } from '../connection.service';

@Injectable({
providedIn: 'root',
Expand All @@ -13,11 +13,11 @@ export class CoreStatsService {
public coreStatsFlow$: CoreStatsFlow;
readonly period = 3;

constructor(private userService: UsersService) {
constructor(connnectService: ConnectionService) {
const outer = this;
this.coreStatsFlow$ = new (class extends CoreStatsFlow {
public prerequest$ = interval(outer.period * 1000).pipe(
withLatestFrom(outer.userService.currentUserFlow$.getOutput()),
combineLatest(connnectService.listCmd$.verify(this.cmd)),
map(([_, x]): CombErr<IRcloneServer> => x)
);
})();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export class ListViewComponent implements OnInit, OnDestroy {
if (x[1].length !== 0) return;
this.data = x[0].list;
});
this.listService.listTrigger.next(1);

this.configuration = { ...DefaultConfig };
this.configuration.searchEnabled = true;
Expand Down
79 changes: 49 additions & 30 deletions src/app/pages/manager/fileMode/operations-list.service.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,79 @@
import { Injectable } from '@angular/core';
import {
OperationsListFlow,
OperationsListFlowParmsNode,
OperationsListFlowInNode,
OperationsListFlowOutNode,
OperationsListFlowOutItemNode,
} from 'src/app/@dataflow/rclone';
import { CombErr } from 'src/app/@dataflow/core';
import { Observable, Subject } from 'rxjs';
import { NavigationService } from '../navigation.service';
import { UsersService } from '../../users.service';
import { withLatestFrom, map, filter } from 'rxjs/operators';
import { withLatestFrom, map, combineLatest } from 'rxjs/operators';
import { RemotesService } from '../remotes.service';
import { ConnectionService } from '../../connection.service';
import { NavigationFLowOutNode } from 'src/app/@dataflow/extra';

@Injectable({
providedIn: 'root',
})
export class OperationsListService {
listFlow$: OperationsListFlow;
list$: Observable<OperationsListFlowOutNode>;
listTrigger = new Subject<number>();
detail1$: Observable<CombErr<OperationsListFlowOutItemNode>>;
private listTrigger = new Subject<number>();
private detailtrigger = new Subject<string>();

constructor(private navService: NavigationService, private usersService: UsersService) {
refreshList() {
this.listTrigger.next(1);
}

getDetail(path: string) {
this.detailtrigger.next(path);
}

constructor(
private remotesService: RemotesService,
private navService: NavigationService,
private cmdService: ConnectionService
) {
const outer = this;
this.listFlow$ = new (class extends OperationsListFlow {
public prerequest$ = outer.listTrigger.pipe(
withLatestFrom(
combineLatest(
outer.navService.navFlow$.getOutput(),
outer.usersService.currentUserFlow$.getOutput()
outer.remotesService.remotes$.getOutput()
),
map(
([_, navNode, userNode]): CombErr<OperationsListFlowInNode> => {
if (navNode[1].length !== 0 || userNode[1].length !== 0)
return [{}, [].concat(navNode[1], userNode[1])] as any;
return [{ ...userNode[0], ...navNode[0] }, []];
([, navNode, remotesNode]): CombErr<NavigationFLowOutNode> => {
if (navNode[1].length !== 0 || remotesNode[1].length !== 0)
return [{}, [].concat(navNode[1], remotesNode[1])] as CombErr<any>;
// check if remote exist
if (remotesNode[0].remotes.findIndex((x) => x === navNode[0].remote) !== -1)
return navNode;
return [{}, [new Error(`remote ${navNode[0].remote} not exist!`)]] as CombErr<any>;
}
),
withLatestFrom(outer.cmdService.listCmd$.verify(this.cmd)),
map(
([x, y]): CombErr<OperationsListFlowInNode> => [
{ ...x[0], ...y[0] },
[].concat(x[1], y[1]),
]
)
);
protected params = function (
pre: CombErr<OperationsListFlowInNode>
): OperationsListFlowParmsNode {
if (pre[1].length !== 0) return {} as any;
if (!pre[0].remote) throw new Error('not provide remote');
return {
fs: `${pre[0].remote}:`,
remote: pre[0].path ? pre[0].path : '',
// opt: {
// showOrigIDs: false, // TODO: depends on remote type(local, not support)
// showHash: false,
// },
};
};
})();
this.listFlow$.deploy();
this.list$ = this.listFlow$.getOutput().pipe(
filter((node) => node[1].length === 0),
map((node) => node[0])

this.detail1$ = this.detailtrigger.pipe(
combineLatest(this.listFlow$.getOutput(), this.navService.navFlow$.getOutput()),
map(
([path, dataNode]): CombErr<OperationsListFlowOutItemNode> => {
if (dataNode[1].length !== 0) return [{}, dataNode[1]] as any;
const idx = dataNode[0].list.findIndex((x) => x.Path === path);
if (idx !== -1) return [{ ...dataNode[0].list[idx] }, []];
return [{}, [new Error(`path ${path} not exist`)]] as any;
}
)
);

this.listTrigger.next(1);
}
}
28 changes: 5 additions & 23 deletions src/app/pages/manager/homeMode/homeMode.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { UsersService } from '../../users.service';
import { ListRemotesFlow } from 'src/app/@dataflow/rclone';
import { Subject } from 'rxjs';
import { Router, ActivatedRoute } from '@angular/router';
import { OperationsListService } from '../fileMode/operations-list.service';
import { RemotesService } from '../remotes.service';
import { NavigationService } from '../navigation.service';

@Component({
selector: 'manager-homeMode',
Expand All @@ -18,33 +15,18 @@ import { OperationsListService } from '../fileMode/operations-list.service';
styleUrls: ['./homeMode.component.scss'],
})
export class HomeModeComponent implements OnInit {
constructor(
private usersService: UsersService,
private listService: OperationsListService,
private route: ActivatedRoute,
private router: Router
) {}
constructor(private remotesService: RemotesService, private navService: NavigationService) {}

remotesFlow$: ListRemotesFlow;
remotesTrigger = new Subject<number>();
remotes: string[] = [];

click(remote: string) {
this.router.navigate(['.'], { relativeTo: this.route, queryParams: { remote: remote } });
this.listService.listTrigger.next(1);
this.navService.navigate(remote);
}

ngOnInit() {
const outer = this;
this.remotesFlow$ = new (class extends ListRemotesFlow {
public prerequest$ = outer.usersService.currentUserFlow$.getOutput();
})();
this.remotesFlow$.deploy();

this.remotesFlow$.getOutput().subscribe((x) => {
this.remotesService.remotes$.getOutput().subscribe((x) => {
if (x[1].length !== 0) return;
this.remotes = x[0].remotes;
});
this.remotesTrigger.next(1);
}
}
23 changes: 19 additions & 4 deletions src/app/pages/manager/navigation.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ActivatedRoute, Router } from '@angular/router';
import { map } from 'rxjs/operators';
import { CombErr } from 'src/app/@dataflow/core';
import { NavigationFlow, NavigationFLowOutNode } from 'src/app/@dataflow/extra';
Expand All @@ -8,13 +8,28 @@ import { NavigationFlow, NavigationFLowOutNode } from 'src/app/@dataflow/extra';
providedIn: 'root',
})
export class NavigationService {
navFlow$: NavigationFlow;
public navFlow$: NavigationFlow;

constructor(private route: ActivatedRoute) {
private readonly managerPath = ['pages', 'manager'];
navigate(remote: string = undefined, path: string = undefined) {
if (!remote) this.router.navigate(this.managerPath);
else if (!path) this.router.navigate(this.managerPath, { queryParams: { remote: remote } });
else this.router.navigate(this.managerPath, { queryParams: { remote: remote, path: path } });
}

constructor(private route: ActivatedRoute, private router: Router) {
const outer = this;
this.navFlow$ = new (class extends NavigationFlow {
public prerequest$ = outer.route.queryParams.pipe(
map((x): CombErr<NavigationFLowOutNode> => [{ remote: x['remote'], path: x['path'] }, []])
map(
(x): CombErr<NavigationFLowOutNode> => {
let remote = x['remote'];
if (remote && remote === '') remote = undefined;
let path = x['path'];
if (path && path === '') path = undefined;
return [{ remote: remote, path: path }, []];
}
)
);
})();
this.navFlow$.deploy();
Expand Down
16 changes: 16 additions & 0 deletions src/app/pages/manager/remotes.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* tslint:disable:no-unused-variable */

import { TestBed, async, inject } from '@angular/core/testing';
import { RemotesService } from './remotes.service';

describe('Service: Remotes', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [RemotesService],
});
});

it('should ...', inject([RemotesService], (service: RemotesService) => {
expect(service).toBeTruthy();
}));
});
31 changes: 31 additions & 0 deletions src/app/pages/manager/remotes.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { ConnectionService } from '../connection.service';
import { Subject } from 'rxjs';
import { ListRemotesFlow } from 'src/app/@dataflow/rclone';
import { combineLatest, map } from 'rxjs/operators';

@Injectable({
providedIn: 'root',
})
export class RemotesService {
private trigger = new Subject<number>();
public remotes$: ListRemotesFlow;

public refresh() {
this.trigger.next(1);
}

constructor(connectService: ConnectionService) {
const outer = this;
this.remotes$ = new (class extends ListRemotesFlow {
public prerequest$ = outer.trigger.pipe(
combineLatest(connectService.listCmd$.verify(this.cmd)),
map(([, y]) => {
return y;
})
);
})();
this.remotes$.deploy();
this.trigger.next(1);
}
}
Loading

0 comments on commit 1bc2a36

Please sign in to comment.