diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-11-15 10:10:41 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-11-27 19:40:51 +0100 |
commit | 51548b31815c6f96f314ae96588a9adca150519d (patch) | |
tree | b3298447b7ac128823016fdec92d083e07d9432e /client/src/app/+admin/follows | |
parent | 350e31d6b64e4973dfa5e9f7b46841cb09aeb1ad (diff) | |
download | PeerTube-51548b31815c6f96f314ae96588a9adca150519d.tar.gz PeerTube-51548b31815c6f96f314ae96588a9adca150519d.tar.zst PeerTube-51548b31815c6f96f314ae96588a9adca150519d.zip |
Add follow tabs
Following
Follow
Followers
Diffstat (limited to 'client/src/app/+admin/follows')
18 files changed, 466 insertions, 0 deletions
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html new file mode 100644 index 000000000..24d75d2b3 --- /dev/null +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html | |||
@@ -0,0 +1,16 @@ | |||
1 | <div class="row"> | ||
2 | <div class="content-padding"> | ||
3 | <h3>Followers list</h3> | ||
4 | |||
5 | <p-dataTable | ||
6 | [value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" | ||
7 | sortField="createdAt" (onLazyLoad)="loadLazy($event)" | ||
8 | > | ||
9 | <p-column field="id" header="ID"></p-column> | ||
10 | <p-column field="host" header="Host"></p-column> | ||
11 | <p-column field="email" header="Email"></p-column> | ||
12 | <p-column field="score" header="Score"></p-column> | ||
13 | <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> | ||
14 | </p-dataTable> | ||
15 | </div> | ||
16 | </div> | ||
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.scss b/client/src/app/+admin/follows/followers-list/followers-list.component.scss new file mode 100644 index 000000000..0a0f621c6 --- /dev/null +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.scss | |||
@@ -0,0 +1,3 @@ | |||
1 | .btn { | ||
2 | margin-top: 10px; | ||
3 | } | ||
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts new file mode 100644 index 000000000..208a0c648 --- /dev/null +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts | |||
@@ -0,0 +1,41 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | ||
2 | |||
3 | import { NotificationsService } from 'angular2-notifications' | ||
4 | import { SortMeta } from 'primeng/primeng' | ||
5 | |||
6 | import { ConfirmService } from '../../../core' | ||
7 | import { RestTable, RestPagination } from '../../../shared' | ||
8 | import { Pod } from '../../../../../../shared' | ||
9 | import { FollowService } from '../shared' | ||
10 | |||
11 | @Component({ | ||
12 | selector: 'my-followers-list', | ||
13 | templateUrl: './followers-list.component.html', | ||
14 | styleUrls: [ './followers-list.component.scss' ] | ||
15 | }) | ||
16 | export class FollowersListComponent extends RestTable { | ||
17 | followers: Pod[] = [] | ||
18 | totalRecords = 0 | ||
19 | rowsPerPage = 10 | ||
20 | sort: SortMeta = { field: 'createdAt', order: 1 } | ||
21 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } | ||
22 | |||
23 | constructor ( | ||
24 | private notificationsService: NotificationsService, | ||
25 | private followService: FollowService | ||
26 | ) { | ||
27 | super() | ||
28 | } | ||
29 | |||
30 | protected loadData () { | ||
31 | this.followService.getFollowers(this.pagination, this.sort) | ||
32 | .subscribe( | ||
33 | resultList => { | ||
34 | this.followers = resultList.data | ||
35 | this.totalRecords = resultList.total | ||
36 | }, | ||
37 | |||
38 | err => this.notificationsService.error('Error', err.message) | ||
39 | ) | ||
40 | } | ||
41 | } | ||
diff --git a/client/src/app/+admin/follows/followers-list/index.ts b/client/src/app/+admin/follows/followers-list/index.ts new file mode 100644 index 000000000..15390cfbe --- /dev/null +++ b/client/src/app/+admin/follows/followers-list/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './followers-list.component' | |||
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.html b/client/src/app/+admin/follows/following-add/following-add.component.html new file mode 100644 index 000000000..111f6a8de --- /dev/null +++ b/client/src/app/+admin/follows/following-add/following-add.component.html | |||
@@ -0,0 +1,35 @@ | |||
1 | <div class="row"> | ||
2 | <div class="content-padding"> | ||
3 | |||
4 | <h3>Add following</h3> | ||
5 | |||
6 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | ||
7 | |||
8 | <form (ngSubmit)="addFollowing()" [formGroup]="form"> | ||
9 | <div class="form-group" *ngFor="let host of hosts; let id = index; trackBy:customTrackBy"> | ||
10 | <label [for]="'host-' + id">Host (so without "http://")</label> | ||
11 | |||
12 | <div class="input-group"> | ||
13 | <input | ||
14 | type="text" class="form-control" placeholder="example.com" | ||
15 | [id]="'host-' + id" [formControlName]="'host-' + id" | ||
16 | /> | ||
17 | <span class="input-group-btn"> | ||
18 | <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button> | ||
19 | <button *ngIf="displayRemoveField(id)" (click)="removeField(id)" class="btn btn-default" type="button">-</button> | ||
20 | </span> | ||
21 | </div> | ||
22 | |||
23 | <div [hidden]="form.controls['host-' + id].valid || form.controls['host-' + id].pristine" class="alert alert-warning"> | ||
24 | It should be a valid host. | ||
25 | </div> | ||
26 | </div> | ||
27 | |||
28 | <div *ngIf="canMakeFriends() === false" class="alert alert-warning"> | ||
29 | It seems that you are not on a HTTPS pod. Your webserver need to have TLS activated in order to follow servers. | ||
30 | </div> | ||
31 | |||
32 | <input type="submit" value="Add following" class="btn btn-default" [disabled]="!isFormValid()"> | ||
33 | </form> | ||
34 | </div> | ||
35 | </div> | ||
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.scss b/client/src/app/+admin/follows/following-add/following-add.component.scss new file mode 100644 index 000000000..5fde51636 --- /dev/null +++ b/client/src/app/+admin/follows/following-add/following-add.component.scss | |||
@@ -0,0 +1,7 @@ | |||
1 | table { | ||
2 | margin-bottom: 40px; | ||
3 | } | ||
4 | |||
5 | .input-group-btn button { | ||
6 | width: 35px; | ||
7 | } | ||
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.ts b/client/src/app/+admin/follows/following-add/following-add.component.ts new file mode 100644 index 000000000..d95d6afa9 --- /dev/null +++ b/client/src/app/+admin/follows/following-add/following-add.component.ts | |||
@@ -0,0 +1,121 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | ||
2 | import { FormControl, FormGroup } from '@angular/forms' | ||
3 | import { Router } from '@angular/router' | ||
4 | |||
5 | import { NotificationsService } from 'angular2-notifications' | ||
6 | |||
7 | import { ConfirmService } from '../../../core' | ||
8 | import { validateHost } from '../../../shared' | ||
9 | import { FollowService } from '../shared' | ||
10 | |||
11 | @Component({ | ||
12 | selector: 'my-following-add', | ||
13 | templateUrl: './following-add.component.html', | ||
14 | styleUrls: [ './following-add.component.scss' ] | ||
15 | }) | ||
16 | export class FollowingAddComponent implements OnInit { | ||
17 | form: FormGroup | ||
18 | hosts: string[] = [ ] | ||
19 | error: string = null | ||
20 | |||
21 | constructor ( | ||
22 | private router: Router, | ||
23 | private notificationsService: NotificationsService, | ||
24 | private confirmService: ConfirmService, | ||
25 | private followService: FollowService | ||
26 | ) {} | ||
27 | |||
28 | ngOnInit () { | ||
29 | this.form = new FormGroup({}) | ||
30 | this.addField() | ||
31 | } | ||
32 | |||
33 | addField () { | ||
34 | this.form.addControl(`host-${this.hosts.length}`, new FormControl('', [ validateHost ])) | ||
35 | this.hosts.push('') | ||
36 | } | ||
37 | |||
38 | canMakeFriends () { | ||
39 | return window.location.protocol === 'https:' | ||
40 | } | ||
41 | |||
42 | customTrackBy (index: number, obj: any): any { | ||
43 | return index | ||
44 | } | ||
45 | |||
46 | displayAddField (index: number) { | ||
47 | return index === (this.hosts.length - 1) | ||
48 | } | ||
49 | |||
50 | displayRemoveField (index: number) { | ||
51 | return (index !== 0 || this.hosts.length > 1) && index !== (this.hosts.length - 1) | ||
52 | } | ||
53 | |||
54 | isFormValid () { | ||
55 | // Do not check the last input | ||
56 | for (let i = 0; i < this.hosts.length - 1; i++) { | ||
57 | if (!this.form.controls[`host-${i}`].valid) return false | ||
58 | } | ||
59 | |||
60 | const lastIndex = this.hosts.length - 1 | ||
61 | // If the last input (which is not the first) is empty, it's ok | ||
62 | if (this.hosts[lastIndex] === '' && lastIndex !== 0) { | ||
63 | return true | ||
64 | } else { | ||
65 | return this.form.controls[`host-${lastIndex}`].valid | ||
66 | } | ||
67 | } | ||
68 | |||
69 | removeField (index: number) { | ||
70 | // Remove the last control | ||
71 | this.form.removeControl(`host-${this.hosts.length - 1}`) | ||
72 | this.hosts.splice(index, 1) | ||
73 | } | ||
74 | |||
75 | addFollowing () { | ||
76 | this.error = '' | ||
77 | |||
78 | const notEmptyHosts = this.getNotEmptyHosts() | ||
79 | if (notEmptyHosts.length === 0) { | ||
80 | this.error = 'You need to specify at least 1 host.' | ||
81 | return | ||
82 | } | ||
83 | |||
84 | if (!this.isHostsUnique(notEmptyHosts)) { | ||
85 | this.error = 'Hosts need to be unique.' | ||
86 | return | ||
87 | } | ||
88 | |||
89 | const confirmMessage = 'Are you sure to make friends with:<br /> - ' + notEmptyHosts.join('<br /> - ') | ||
90 | this.confirmService.confirm(confirmMessage, 'Follow new server(s)').subscribe( | ||
91 | res => { | ||
92 | if (res === false) return | ||
93 | |||
94 | this.followService.follow(notEmptyHosts).subscribe( | ||
95 | status => { | ||
96 | this.notificationsService.success('Success', 'Follow request(s) sent!') | ||
97 | // Wait requests between pods | ||
98 | setTimeout(() => this.router.navigate([ '/admin/friends/list' ]), 1000) | ||
99 | }, | ||
100 | |||
101 | err => this.notificationsService.error('Error', err.message) | ||
102 | ) | ||
103 | } | ||
104 | ) | ||
105 | } | ||
106 | |||
107 | private getNotEmptyHosts () { | ||
108 | const notEmptyHosts = [] | ||
109 | |||
110 | Object.keys(this.form.value).forEach((hostKey) => { | ||
111 | const host = this.form.value[hostKey] | ||
112 | if (host !== '') notEmptyHosts.push(host) | ||
113 | }) | ||
114 | |||
115 | return notEmptyHosts | ||
116 | } | ||
117 | |||
118 | private isHostsUnique (hosts: string[]) { | ||
119 | return hosts.every(host => hosts.indexOf(host) === hosts.lastIndexOf(host)) | ||
120 | } | ||
121 | } | ||
diff --git a/client/src/app/+admin/follows/following-add/index.ts b/client/src/app/+admin/follows/following-add/index.ts new file mode 100644 index 000000000..1b1897ffa --- /dev/null +++ b/client/src/app/+admin/follows/following-add/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './following-add.component' | |||
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html new file mode 100644 index 000000000..fbcebfaa7 --- /dev/null +++ b/client/src/app/+admin/follows/following-list/following-list.component.html | |||
@@ -0,0 +1,16 @@ | |||
1 | <div class="row"> | ||
2 | <div class="content-padding"> | ||
3 | <h3>Following list</h3> | ||
4 | |||
5 | <p-dataTable | ||
6 | [value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" | ||
7 | sortField="createdAt" (onLazyLoad)="loadLazy($event)" | ||
8 | > | ||
9 | <p-column field="id" header="ID"></p-column> | ||
10 | <p-column field="host" header="Host"></p-column> | ||
11 | <p-column field="email" header="Email"></p-column> | ||
12 | <p-column field="score" header="Score"></p-column> | ||
13 | <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> | ||
14 | </p-dataTable> | ||
15 | </div> | ||
16 | </div> | ||
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts new file mode 100644 index 000000000..7d2c5084b --- /dev/null +++ b/client/src/app/+admin/follows/following-list/following-list.component.ts | |||
@@ -0,0 +1,40 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | ||
2 | |||
3 | import { NotificationsService } from 'angular2-notifications' | ||
4 | import { SortMeta } from 'primeng/primeng' | ||
5 | |||
6 | import { ConfirmService } from '../../../core' | ||
7 | import { RestTable, RestPagination } from '../../../shared' | ||
8 | import { Pod } from '../../../../../../shared' | ||
9 | import { FollowService } from '../shared' | ||
10 | |||
11 | @Component({ | ||
12 | selector: 'my-followers-list', | ||
13 | templateUrl: './following-list.component.html' | ||
14 | }) | ||
15 | export class FollowingListComponent extends RestTable { | ||
16 | following: Pod[] = [] | ||
17 | totalRecords = 0 | ||
18 | rowsPerPage = 10 | ||
19 | sort: SortMeta = { field: 'createdAt', order: 1 } | ||
20 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } | ||
21 | |||
22 | constructor ( | ||
23 | private notificationsService: NotificationsService, | ||
24 | private followService: FollowService | ||
25 | ) { | ||
26 | super() | ||
27 | } | ||
28 | |||
29 | protected loadData () { | ||
30 | this.followService.getFollowing(this.pagination, this.sort) | ||
31 | .subscribe( | ||
32 | resultList => { | ||
33 | this.following = resultList.data | ||
34 | this.totalRecords = resultList.total | ||
35 | }, | ||
36 | |||
37 | err => this.notificationsService.error('Error', err.message) | ||
38 | ) | ||
39 | } | ||
40 | } | ||
diff --git a/client/src/app/+admin/follows/following-list/index.ts b/client/src/app/+admin/follows/following-list/index.ts new file mode 100644 index 000000000..a70d46a7e --- /dev/null +++ b/client/src/app/+admin/follows/following-list/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './following-list.component' | |||
diff --git a/client/src/app/+admin/follows/follows.component.html b/client/src/app/+admin/follows/follows.component.html new file mode 100644 index 000000000..b67bc9736 --- /dev/null +++ b/client/src/app/+admin/follows/follows.component.html | |||
@@ -0,0 +1,11 @@ | |||
1 | <div class="follows-menu"> | ||
2 | <tabset #followsMenuTabs> | ||
3 | <tab *ngFor="let link of links"> | ||
4 | <ng-template tabHeading> | ||
5 | <a class="tab-link" [routerLink]="link.path">{{ link.title }}</a> | ||
6 | </ng-template> | ||
7 | </tab> | ||
8 | </tabset> | ||
9 | </div> | ||
10 | |||
11 | <router-outlet></router-outlet> | ||
diff --git a/client/src/app/+admin/follows/follows.component.scss b/client/src/app/+admin/follows/follows.component.scss new file mode 100644 index 000000000..d8ab41975 --- /dev/null +++ b/client/src/app/+admin/follows/follows.component.scss | |||
@@ -0,0 +1,21 @@ | |||
1 | .follows-menu { | ||
2 | margin-top: 20px; | ||
3 | } | ||
4 | |||
5 | tabset /deep/ { | ||
6 | .nav-link { | ||
7 | padding: 0; | ||
8 | } | ||
9 | |||
10 | .tab-link { | ||
11 | display: block; | ||
12 | text-align: center; | ||
13 | height: 40px; | ||
14 | width: 120px; | ||
15 | line-height: 40px; | ||
16 | |||
17 | &:hover, &:active, &:focus { | ||
18 | text-decoration: none !important; | ||
19 | } | ||
20 | } | ||
21 | } | ||
diff --git a/client/src/app/+admin/follows/follows.component.ts b/client/src/app/+admin/follows/follows.component.ts new file mode 100644 index 000000000..97422a41b --- /dev/null +++ b/client/src/app/+admin/follows/follows.component.ts | |||
@@ -0,0 +1,43 @@ | |||
1 | import { AfterViewInit, Component, ViewChild } from '@angular/core' | ||
2 | import { TabsetComponent } from 'ngx-bootstrap/tabs' | ||
3 | |||
4 | @Component({ | ||
5 | templateUrl: './follows.component.html', | ||
6 | styleUrls: [ './follows.component.scss' ] | ||
7 | }) | ||
8 | export class FollowsComponent implements AfterViewInit { | ||
9 | @ViewChild('followsMenuTabs') followsMenuTabs: TabsetComponent | ||
10 | |||
11 | links = [ | ||
12 | { | ||
13 | path: 'following-list', | ||
14 | title: 'Following' | ||
15 | }, | ||
16 | { | ||
17 | path: 'following-add', | ||
18 | title: 'Follow' | ||
19 | }, | ||
20 | { | ||
21 | path: 'followers-list', | ||
22 | title: 'Followers' | ||
23 | } | ||
24 | ] | ||
25 | |||
26 | ngAfterViewInit () { | ||
27 | // Avoid issue with change detector | ||
28 | setTimeout(() => this.updateActiveTab()) | ||
29 | } | ||
30 | |||
31 | private updateActiveTab () { | ||
32 | const url = window.location.pathname | ||
33 | |||
34 | for (let i = 0; i < this.links.length; i++) { | ||
35 | const path = this.links[i].path | ||
36 | |||
37 | if (url.endsWith(path) === true) { | ||
38 | this.followsMenuTabs.tabs[i].active = true | ||
39 | return | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | } | ||
diff --git a/client/src/app/+admin/follows/follows.routes.ts b/client/src/app/+admin/follows/follows.routes.ts new file mode 100644 index 000000000..b7d44f75b --- /dev/null +++ b/client/src/app/+admin/follows/follows.routes.ts | |||
@@ -0,0 +1,53 @@ | |||
1 | import { Routes } from '@angular/router' | ||
2 | |||
3 | import { UserRightGuard } from '../../core' | ||
4 | import { FollowsComponent } from './follows.component' | ||
5 | import { FollowingAddComponent } from './following-add' | ||
6 | import { FollowersListComponent } from './followers-list' | ||
7 | import { UserRight } from '../../../../../shared' | ||
8 | import { FollowingListComponent } from './following-list/following-list.component' | ||
9 | |||
10 | export const FollowsRoutes: Routes = [ | ||
11 | { | ||
12 | path: 'follows', | ||
13 | component: FollowsComponent, | ||
14 | canActivate: [ UserRightGuard ], | ||
15 | data: { | ||
16 | userRight: UserRight.MANAGE_APPLICATION_FOLLOW | ||
17 | }, | ||
18 | children: [ | ||
19 | { | ||
20 | path: '', | ||
21 | redirectTo: 'following-list', | ||
22 | pathMatch: 'full' | ||
23 | }, | ||
24 | { | ||
25 | path: 'following-list', | ||
26 | component: FollowingListComponent, | ||
27 | data: { | ||
28 | meta: { | ||
29 | title: 'Following list' | ||
30 | } | ||
31 | } | ||
32 | }, | ||
33 | { | ||
34 | path: 'followers-list', | ||
35 | component: FollowersListComponent, | ||
36 | data: { | ||
37 | meta: { | ||
38 | title: 'Followers list' | ||
39 | } | ||
40 | } | ||
41 | }, | ||
42 | { | ||
43 | path: 'following-add', | ||
44 | component: FollowingAddComponent, | ||
45 | data: { | ||
46 | meta: { | ||
47 | title: 'Add follow' | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | ] | ||
52 | } | ||
53 | ] | ||
diff --git a/client/src/app/+admin/follows/index.ts b/client/src/app/+admin/follows/index.ts new file mode 100644 index 000000000..7849a06e7 --- /dev/null +++ b/client/src/app/+admin/follows/index.ts | |||
@@ -0,0 +1,6 @@ | |||
1 | export * from './following-add' | ||
2 | export * from './followers-list' | ||
3 | export * from './following-list' | ||
4 | export * from './shared' | ||
5 | export * from './follows.component' | ||
6 | export * from './follows.routes' | ||
diff --git a/client/src/app/+admin/follows/shared/follow.service.ts b/client/src/app/+admin/follows/shared/follow.service.ts new file mode 100644 index 000000000..622c33cea --- /dev/null +++ b/client/src/app/+admin/follows/shared/follow.service.ts | |||
@@ -0,0 +1,49 @@ | |||
1 | import { Injectable } from '@angular/core' | ||
2 | import { HttpClient, HttpParams } from '@angular/common/http' | ||
3 | import { Observable } from 'rxjs/Observable' | ||
4 | import 'rxjs/add/operator/catch' | ||
5 | import 'rxjs/add/operator/map' | ||
6 | |||
7 | import { SortMeta } from 'primeng/primeng' | ||
8 | |||
9 | import { RestExtractor, RestPagination, RestService } from '../../../shared' | ||
10 | import { Pod, ResultList } from '../../../../../../shared' | ||
11 | |||
12 | @Injectable() | ||
13 | export class FollowService { | ||
14 | private static BASE_APPLICATION_URL = API_URL + '/api/v1/application' | ||
15 | |||
16 | constructor ( | ||
17 | private authHttp: HttpClient, | ||
18 | private restService: RestService, | ||
19 | private restExtractor: RestExtractor | ||
20 | ) {} | ||
21 | |||
22 | getFollowing (pagination: RestPagination, sort: SortMeta): Observable<ResultList<Pod>> { | ||
23 | let params = new HttpParams() | ||
24 | params = this.restService.addRestGetParams(params, pagination, sort) | ||
25 | |||
26 | return this.authHttp.get<ResultList<Account>>(FollowService.BASE_APPLICATION_URL + '/following', { params }) | ||
27 | .map(res => this.restExtractor.convertResultListDateToHuman(res)) | ||
28 | .catch(res => this.restExtractor.handleError(res)) | ||
29 | } | ||
30 | |||
31 | getFollowers (pagination: RestPagination, sort: SortMeta): Observable<ResultList<Pod>> { | ||
32 | let params = new HttpParams() | ||
33 | params = this.restService.addRestGetParams(params, pagination, sort) | ||
34 | |||
35 | return this.authHttp.get<ResultList<Account>>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) | ||
36 | .map(res => this.restExtractor.convertResultListDateToHuman(res)) | ||
37 | .catch(res => this.restExtractor.handleError(res)) | ||
38 | } | ||
39 | |||
40 | follow (notEmptyHosts: String[]) { | ||
41 | const body = { | ||
42 | hosts: notEmptyHosts | ||
43 | } | ||
44 | |||
45 | return this.authHttp.post(FollowService.BASE_APPLICATION_URL + '/follow', body) | ||
46 | .map(this.restExtractor.extractDataBool) | ||
47 | .catch(res => this.restExtractor.handleError(res)) | ||
48 | } | ||
49 | } | ||
diff --git a/client/src/app/+admin/follows/shared/index.ts b/client/src/app/+admin/follows/shared/index.ts new file mode 100644 index 000000000..78d456def --- /dev/null +++ b/client/src/app/+admin/follows/shared/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './follow.service' | |||