diff options
5 files changed, 183 insertions, 0 deletions
diff --git a/client/src/app/+about/about-instance/about-instance.component.html b/client/src/app/+about/about-instance/about-instance.component.html index 25d416740..f05f33d36 100644 --- a/client/src/app/+about/about-instance/about-instance.component.html +++ b/client/src/app/+about/about-instance/about-instance.component.html | |||
@@ -94,6 +94,13 @@ | |||
94 | <label i18n>Features found on this instance</label> | 94 | <label i18n>Features found on this instance</label> |
95 | <my-instance-features-table></my-instance-features-table> | 95 | <my-instance-features-table></my-instance-features-table> |
96 | </div> | 96 | </div> |
97 | |||
98 | <div class="col"> | ||
99 | <div i18n class="middle-title"> | ||
100 | Statistics | ||
101 | </div> | ||
102 | <my-instance-statistics></my-instance-statistics> | ||
103 | </div> | ||
97 | </div> | 104 | </div> |
98 | 105 | ||
99 | <my-contact-admin-modal #contactAdminModal></my-contact-admin-modal> | 106 | <my-contact-admin-modal #contactAdminModal></my-contact-admin-modal> |
diff --git a/client/src/app/shared/instance/instance-statistics.component.html b/client/src/app/shared/instance/instance-statistics.component.html new file mode 100644 index 000000000..181c57b57 --- /dev/null +++ b/client/src/app/shared/instance/instance-statistics.component.html | |||
@@ -0,0 +1,101 @@ | |||
1 | <p i18n *ngIf="null === serverStats">Loading instance statistics...</p> | ||
2 | |||
3 | <section *ngIf="null !== serverStats"> | ||
4 | <h5 i18n>Local</h5> | ||
5 | |||
6 | <div class="row"> | ||
7 | <div class="col-6 col-lg-4 col-xl-3"> | ||
8 | <div class="card stat"> | ||
9 | <div class="card-body"> | ||
10 | <p class="stat-value">{{ serverStats.totalUsers }}</p> | ||
11 | <p class="stat-label" i18n>users</p> | ||
12 | </div> | ||
13 | <i class="glyphicon glyphicon-user icon-bottom"></i> | ||
14 | </div> | ||
15 | </div> | ||
16 | |||
17 | <div class="col-6 col-lg-4 col-xl-3"> | ||
18 | <div class="card stat"> | ||
19 | <div class="card-body"> | ||
20 | <p class="stat-value">{{ serverStats.totalLocalVideos }}</p> | ||
21 | <p class="stat-label" i18n>videos</p> | ||
22 | </div> | ||
23 | <i class="glyphicon glyphicon-facetime-video"></i> | ||
24 | </div> | ||
25 | </div> | ||
26 | |||
27 | <div class="col-6 col-lg-4 col-xl-3"> | ||
28 | <div class="card stat"> | ||
29 | <div class="card-body"> | ||
30 | <p class="stat-value">{{ serverStats.totalLocalVideoViews }}</p> | ||
31 | <p class="stat-label" i18n>videos views</p> | ||
32 | </div> | ||
33 | <i class="glyphicon glyphicon-eye-open"></i> | ||
34 | </div> | ||
35 | </div> | ||
36 | |||
37 | <div class="col-6 col-lg-4 col-xl-3"> | ||
38 | <div class="card stat"> | ||
39 | <div class="card-body"> | ||
40 | <p class="stat-value">{{ serverStats.totalLocalVideoComments }}</p> | ||
41 | <p class="stat-label" i18n>videos comments</p> | ||
42 | </div> | ||
43 | <i class="glyphicon glyphicon-comment"></i> | ||
44 | </div> | ||
45 | </div> | ||
46 | |||
47 | <div class="col-6 col-lg-4 col-xl-3"> | ||
48 | <div class="card stat"> | ||
49 | <div class="card-body"> | ||
50 | <p class="stat-value">{{ serverStats.totalLocalVideoFilesSize | bytes:1 }}</p> | ||
51 | <p class="stat-label" i18n>of hosted video</p> | ||
52 | </div> | ||
53 | <i class="glyphicon glyphicon-hdd"></i> | ||
54 | </div> | ||
55 | </div> | ||
56 | </div> | ||
57 | |||
58 | <h5 i18n>Federation</h5> | ||
59 | |||
60 | <div class="row"> | ||
61 | <div class="col-6 col-lg-4 col-xl-3"> | ||
62 | <div class="card stat"> | ||
63 | <div class="card-body"> | ||
64 | <p class="stat-value">{{ serverStats.totalVideos }}</p> | ||
65 | <p class="stat-label" i18n>videos</p> | ||
66 | </div> | ||
67 | <i class="glyphicon glyphicon-facetime-video"></i> | ||
68 | </div> | ||
69 | </div> | ||
70 | |||
71 | <div class="col-6 col-lg-4 col-xl-3"> | ||
72 | <div class="card stat"> | ||
73 | <div class="card-body"> | ||
74 | <p class="stat-value">{{ serverStats.totalVideoComments }}</p> | ||
75 | <p class="stat-label" i18n>videos comments</p> | ||
76 | </div> | ||
77 | <i class="glyphicon glyphicon-comment"></i> | ||
78 | </div> | ||
79 | </div> | ||
80 | |||
81 | <div class="col-6 col-lg-4 col-xl-3"> | ||
82 | <div class="card stat"> | ||
83 | <div class="card-body"> | ||
84 | <p class="stat-value">{{ serverStats.totalInstanceFollowers }}</p> | ||
85 | <p class="stat-label" i18n>followers</p> | ||
86 | </div> | ||
87 | <i class="glyphicon glyphicon-retweet"></i> | ||
88 | </div> | ||
89 | </div> | ||
90 | |||
91 | <div class="col-6 col-lg-4 col-xl-3"> | ||
92 | <div class="card stat"> | ||
93 | <div class="card-body"> | ||
94 | <p class="stat-value">{{ serverStats.totalInstanceFollowing }}</p> | ||
95 | <p class="stat-label" i18n>following</p> | ||
96 | </div> | ||
97 | <i class="glyphicon glyphicon-retweet"></i> | ||
98 | </div> | ||
99 | </div> | ||
100 | </div> | ||
101 | </section> | ||
diff --git a/client/src/app/shared/instance/instance-statistics.component.scss b/client/src/app/shared/instance/instance-statistics.component.scss new file mode 100644 index 000000000..63f8911f6 --- /dev/null +++ b/client/src/app/shared/instance/instance-statistics.component.scss | |||
@@ -0,0 +1,35 @@ | |||
1 | .stat { | ||
2 | text-align: center; | ||
3 | margin-bottom: 1em; | ||
4 | overflow: hidden; | ||
5 | |||
6 | .stat-value { | ||
7 | font-size: 2.25em; | ||
8 | line-height: 1em; | ||
9 | margin: 0; | ||
10 | } | ||
11 | |||
12 | .stat-label { | ||
13 | font-size: 1.15em; | ||
14 | margin: 0; | ||
15 | } | ||
16 | |||
17 | .glyphicon { | ||
18 | opacity: 0.12; | ||
19 | position: absolute; | ||
20 | left: 16px; | ||
21 | top: -24px; | ||
22 | |||
23 | &.icon-bottom { | ||
24 | top: 4px; | ||
25 | } | ||
26 | |||
27 | &::before { | ||
28 | font-size: 8em; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | .card-body { | ||
33 | z-index: 2; | ||
34 | } | ||
35 | } | ||
diff --git a/client/src/app/shared/instance/instance-statistics.component.ts b/client/src/app/shared/instance/instance-statistics.component.ts new file mode 100644 index 000000000..8ec728f05 --- /dev/null +++ b/client/src/app/shared/instance/instance-statistics.component.ts | |||
@@ -0,0 +1,37 @@ | |||
1 | import { map } from 'rxjs/operators' | ||
2 | import { HttpClient } from '@angular/common/http' | ||
3 | import { Component, OnInit } from '@angular/core' | ||
4 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
5 | import { ServerStats } from '@shared/models/server' | ||
6 | import { environment } from '../../../environments/environment' | ||
7 | |||
8 | @Component({ | ||
9 | selector: 'my-instance-statistics', | ||
10 | templateUrl: './instance-statistics.component.html', | ||
11 | styleUrls: [ './instance-statistics.component.scss' ] | ||
12 | }) | ||
13 | export class InstanceStatisticsComponent implements OnInit { | ||
14 | private static BASE_STATS_URL = environment.apiUrl + '/api/v1/server/stats' | ||
15 | |||
16 | serverStats: ServerStats = null | ||
17 | |||
18 | constructor ( | ||
19 | private http: HttpClient, | ||
20 | private i18n: I18n | ||
21 | ) { | ||
22 | } | ||
23 | |||
24 | ngOnInit () { | ||
25 | this.getStats() | ||
26 | .subscribe( | ||
27 | res => { | ||
28 | this.serverStats = res | ||
29 | } | ||
30 | ) | ||
31 | } | ||
32 | |||
33 | getStats () { | ||
34 | return this.http | ||
35 | .get<ServerStats>(InstanceStatisticsComponent.BASE_STATS_URL) | ||
36 | } | ||
37 | } | ||
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 65e0f21a4..f6991a66d 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -61,6 +61,7 @@ import { | |||
61 | } from '@ng-bootstrap/ng-bootstrap' | 61 | } from '@ng-bootstrap/ng-bootstrap' |
62 | import { RemoteSubscribeComponent, SubscribeButtonComponent, UserSubscriptionService } from '@app/shared/user-subscription' | 62 | import { RemoteSubscribeComponent, SubscribeButtonComponent, UserSubscriptionService } from '@app/shared/user-subscription' |
63 | import { InstanceFeaturesTableComponent } from '@app/shared/instance/instance-features-table.component' | 63 | import { InstanceFeaturesTableComponent } from '@app/shared/instance/instance-features-table.component' |
64 | import { InstanceStatisticsComponent } from '@app/shared/instance/instance-statistics.component' | ||
64 | import { OverviewService } from '@app/shared/overview' | 65 | import { OverviewService } from '@app/shared/overview' |
65 | import { UserBanModalComponent } from '@app/shared/moderation' | 66 | import { UserBanModalComponent } from '@app/shared/moderation' |
66 | import { UserModerationDropdownComponent } from '@app/shared/moderation/user-moderation-dropdown.component' | 67 | import { UserModerationDropdownComponent } from '@app/shared/moderation/user-moderation-dropdown.component' |
@@ -157,6 +158,7 @@ import { FeatureBooleanComponent } from '@app/shared/instance/feature-boolean.co | |||
157 | SubscribeButtonComponent, | 158 | SubscribeButtonComponent, |
158 | RemoteSubscribeComponent, | 159 | RemoteSubscribeComponent, |
159 | InstanceFeaturesTableComponent, | 160 | InstanceFeaturesTableComponent, |
161 | InstanceStatisticsComponent, | ||
160 | FeatureBooleanComponent, | 162 | FeatureBooleanComponent, |
161 | UserBanModalComponent, | 163 | UserBanModalComponent, |
162 | UserModerationDropdownComponent, | 164 | UserModerationDropdownComponent, |
@@ -224,6 +226,7 @@ import { FeatureBooleanComponent } from '@app/shared/instance/feature-boolean.co | |||
224 | SubscribeButtonComponent, | 226 | SubscribeButtonComponent, |
225 | RemoteSubscribeComponent, | 227 | RemoteSubscribeComponent, |
226 | InstanceFeaturesTableComponent, | 228 | InstanceFeaturesTableComponent, |
229 | InstanceStatisticsComponent, | ||
227 | UserBanModalComponent, | 230 | UserBanModalComponent, |
228 | UserModerationDropdownComponent, | 231 | UserModerationDropdownComponent, |
229 | TopMenuDropdownComponent, | 232 | TopMenuDropdownComponent, |