diff options
Diffstat (limited to 'client/src/app/menu')
-rw-r--r-- | client/src/app/menu/index.ts | 2 | ||||
-rw-r--r-- | client/src/app/menu/menu-admin.component.html | 35 | ||||
-rw-r--r-- | client/src/app/menu/menu-admin.component.ts | 33 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.html | 48 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.scss | 131 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.ts | 97 |
6 files changed, 346 insertions, 0 deletions
diff --git a/client/src/app/menu/index.ts b/client/src/app/menu/index.ts new file mode 100644 index 000000000..c905ed20a --- /dev/null +++ b/client/src/app/menu/index.ts | |||
@@ -0,0 +1,2 @@ | |||
1 | export * from './menu.component' | ||
2 | export * from './menu-admin.component' | ||
diff --git a/client/src/app/menu/menu-admin.component.html b/client/src/app/menu/menu-admin.component.html new file mode 100644 index 000000000..9857b2e3e --- /dev/null +++ b/client/src/app/menu/menu-admin.component.html | |||
@@ -0,0 +1,35 @@ | |||
1 | <menu> | ||
2 | <div class="panel-block"> | ||
3 | <a *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active"> | ||
4 | <span class="hidden-xs glyphicon glyphicon-user"></span> | ||
5 | List users | ||
6 | </a> | ||
7 | |||
8 | <a *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active"> | ||
9 | <span class="hidden-xs glyphicon glyphicon-cloud"></span> | ||
10 | Manage follows | ||
11 | </a> | ||
12 | |||
13 | <a *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active"> | ||
14 | <span class="hidden-xs glyphicon glyphicon-alert"></span> | ||
15 | Video abuses | ||
16 | </a> | ||
17 | |||
18 | <a *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active"> | ||
19 | <span class="hidden-xs glyphicon glyphicon-eye-close"></span> | ||
20 | Video blacklist | ||
21 | </a> | ||
22 | |||
23 | <a *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active"> | ||
24 | <span class="hidden-xs glyphicon glyphicon-tasks"></span> | ||
25 | Jobs | ||
26 | </a> | ||
27 | </div> | ||
28 | |||
29 | <div class="panel-block"> | ||
30 | <a routerLink="/videos/list" routerLinkActive="active"> | ||
31 | <span class="hidden-xs glyphicon glyphicon-cog"></span> | ||
32 | Quit admin. | ||
33 | </a> | ||
34 | </div> | ||
35 | </menu> | ||
diff --git a/client/src/app/menu/menu-admin.component.ts b/client/src/app/menu/menu-admin.component.ts new file mode 100644 index 000000000..1babf5eb6 --- /dev/null +++ b/client/src/app/menu/menu-admin.component.ts | |||
@@ -0,0 +1,33 @@ | |||
1 | import { Component } from '@angular/core' | ||
2 | |||
3 | import { AuthService } from '../core/auth/auth.service' | ||
4 | import { UserRight } from '../../../../shared' | ||
5 | |||
6 | @Component({ | ||
7 | selector: 'my-menu-admin', | ||
8 | templateUrl: './menu-admin.component.html', | ||
9 | styleUrls: [ './menu.component.scss' ] | ||
10 | }) | ||
11 | export class MenuAdminComponent { | ||
12 | constructor (private auth: AuthService) {} | ||
13 | |||
14 | hasUsersRight () { | ||
15 | return this.auth.getUser().hasRight(UserRight.MANAGE_USERS) | ||
16 | } | ||
17 | |||
18 | hasServerFollowRight () { | ||
19 | return this.auth.getUser().hasRight(UserRight.MANAGE_SERVER_FOLLOW) | ||
20 | } | ||
21 | |||
22 | hasVideoAbusesRight () { | ||
23 | return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES) | ||
24 | } | ||
25 | |||
26 | hasVideoBlacklistRight () { | ||
27 | return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) | ||
28 | } | ||
29 | |||
30 | hasJobsRight () { | ||
31 | return this.auth.getUser().hasRight(UserRight.MANAGE_JOBS) | ||
32 | } | ||
33 | } | ||
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html new file mode 100644 index 000000000..bb0caaef5 --- /dev/null +++ b/client/src/app/menu/menu.component.html | |||
@@ -0,0 +1,48 @@ | |||
1 | <menu> | ||
2 | <div *ngIf="isLoggedIn" class="logged-in-block"> | ||
3 | <div class="logged-in-info"> | ||
4 | <div class="logged-in-username">{{ user.username }}</div> | ||
5 | <div class="logged-in-email">{{ user.email }}</div> | ||
6 | </div> | ||
7 | |||
8 | <div class="logged-in-more" dropdown placement="right" container="body"> | ||
9 | <span class="glyphicon glyphicon-option-vertical" dropdownToggle></span> | ||
10 | |||
11 | <ul *dropdownMenu class="dropdown-menu"> | ||
12 | <li> | ||
13 | <a (click)="logout($event)" class="dropdown-item" title="Log out" href="#"> | ||
14 | Log out | ||
15 | </a> | ||
16 | </li> | ||
17 | </ul> | ||
18 | </div> | ||
19 | </div> | ||
20 | |||
21 | <div *ngIf="!isLoggedIn" class="button-block"> | ||
22 | <a routerLink="/login"class="login-button">Login</a> | ||
23 | <a *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a> | ||
24 | </div> | ||
25 | |||
26 | <div class="panel-block"> | ||
27 | <div class="block-title">Videos</div> | ||
28 | |||
29 | <a routerLink="/videos/list" routerLinkActive="active"> | ||
30 | <span class="icon icon-videos-trending"></span> | ||
31 | Trending | ||
32 | </a> | ||
33 | |||
34 | <a routerLink="/videos/list" routerLinkActive="active"> | ||
35 | <span class="icon icon-videos-recently-added"></span> | ||
36 | Recently added | ||
37 | </a> | ||
38 | </div> | ||
39 | |||
40 | <div *ngIf="userHasAdminAccess" class="panel-block"> | ||
41 | <div class="block-title">More</div> | ||
42 | |||
43 | <a [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> | ||
44 | <span class="icon icon-administration"></span> | ||
45 | Administration | ||
46 | </a> | ||
47 | </div> | ||
48 | </menu> | ||
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss new file mode 100644 index 000000000..8a4910605 --- /dev/null +++ b/client/src/app/menu/menu.component.scss | |||
@@ -0,0 +1,131 @@ | |||
1 | menu { | ||
2 | background-color: $black-background; | ||
3 | margin: 0; | ||
4 | padding: 0; | ||
5 | height: 100%; | ||
6 | white-space: nowrap; | ||
7 | text-overflow: ellipsis; | ||
8 | overflow: hidden; | ||
9 | z-index: 1000; | ||
10 | color: $menu-color; | ||
11 | |||
12 | @media screen and (max-width: 550px) { | ||
13 | font-size: 90%; | ||
14 | } | ||
15 | |||
16 | .logged-in-block { | ||
17 | height: 100px; | ||
18 | background-color: rgba(255, 255, 255, 0.15); | ||
19 | display: flex; | ||
20 | align-items: center; | ||
21 | justify-content: center; | ||
22 | margin-bottom: 35px; | ||
23 | |||
24 | .logged-in-info { | ||
25 | flex-grow: 1; | ||
26 | margin-left: 40px; | ||
27 | |||
28 | .logged-in-username { | ||
29 | font-size: 16px; | ||
30 | font-weight: $font-semibold; | ||
31 | } | ||
32 | |||
33 | .logged-in-email { | ||
34 | font-size: 13px; | ||
35 | color: #C6C6C6; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | .logged-in-more { | ||
40 | margin-right: 20px; | ||
41 | |||
42 | .glyphicon { | ||
43 | cursor: pointer; | ||
44 | font-size: 18px; | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | .button-block { | ||
50 | margin: 30px 25px 35px 25px; | ||
51 | |||
52 | .login-button, .create-account-button { | ||
53 | font-weight: $font-semibold; | ||
54 | font-size: 15px; | ||
55 | height: $button-height; | ||
56 | line-height: $button-height; | ||
57 | width: 190px; | ||
58 | border-radius: 3px; | ||
59 | text-align: center; | ||
60 | |||
61 | &.login-button { | ||
62 | background-color: $orange-color; | ||
63 | margin-bottom: 10px; | ||
64 | } | ||
65 | |||
66 | &.create-account-button { | ||
67 | background-color: rgba(255, 255, 255, 0.25); | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | .block-title { | ||
73 | text-transform: uppercase; | ||
74 | font-weight: $font-bold; // Bold | ||
75 | font-size: 13px; | ||
76 | margin-bottom: 25px; | ||
77 | } | ||
78 | |||
79 | .panel-block { | ||
80 | margin-bottom: 45px; | ||
81 | margin-left: 26px; | ||
82 | |||
83 | a { | ||
84 | display: flex; | ||
85 | |||
86 | .icon { | ||
87 | width: 22px; | ||
88 | height: 22px; | ||
89 | display: inline-block; | ||
90 | margin-right: 18px; | ||
91 | background-size: contain; | ||
92 | |||
93 | &.icon-videos-trending { | ||
94 | position: relative; | ||
95 | top: -2px; | ||
96 | background-image: url('../../assets/menu/trending.svg'); | ||
97 | } | ||
98 | |||
99 | &.icon-videos-recently-added { | ||
100 | width: 23px; | ||
101 | height: 23px; | ||
102 | position: relative; | ||
103 | top: -1px; | ||
104 | background-image: url('../../assets/menu/recently-added.svg'); | ||
105 | } | ||
106 | |||
107 | &.icon-administration { | ||
108 | width: 23px; | ||
109 | height: 23px; | ||
110 | |||
111 | background-image: url('../../assets/menu/administration.svg'); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | a { | ||
118 | color: $menu-color; | ||
119 | height: 22px; | ||
120 | line-height: 22px; | ||
121 | display: block; | ||
122 | font-size: 16px; | ||
123 | cursor: pointer; | ||
124 | margin-bottom: 15px; | ||
125 | |||
126 | &:hover, &:focus { | ||
127 | text-decoration: none !important; | ||
128 | outline: none !important; | ||
129 | } | ||
130 | } | ||
131 | } | ||
diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts new file mode 100644 index 000000000..4c35bb3a5 --- /dev/null +++ b/client/src/app/menu/menu.component.ts | |||
@@ -0,0 +1,97 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | ||
2 | import { Router } from '@angular/router' | ||
3 | import { UserRight } from '../../../../shared/models/users/user-right.enum' | ||
4 | import { AuthService, AuthStatus, ServerService } from '../core' | ||
5 | import { User } from '../shared/users/user.model' | ||
6 | |||
7 | @Component({ | ||
8 | selector: 'my-menu', | ||
9 | templateUrl: './menu.component.html', | ||
10 | styleUrls: [ './menu.component.scss' ] | ||
11 | }) | ||
12 | export class MenuComponent implements OnInit { | ||
13 | user: User | ||
14 | isLoggedIn: boolean | ||
15 | userHasAdminAccess = false | ||
16 | |||
17 | private routesPerRight = { | ||
18 | [UserRight.MANAGE_USERS]: '/admin/users', | ||
19 | [UserRight.MANAGE_SERVER_FOLLOW]: '/admin/friends', | ||
20 | [UserRight.MANAGE_VIDEO_ABUSES]: '/admin/video-abuses', | ||
21 | [UserRight.MANAGE_VIDEO_BLACKLIST]: '/admin/video-blacklist' | ||
22 | } | ||
23 | |||
24 | constructor ( | ||
25 | private authService: AuthService, | ||
26 | private serverService: ServerService, | ||
27 | private router: Router | ||
28 | ) {} | ||
29 | |||
30 | ngOnInit () { | ||
31 | this.isLoggedIn = this.authService.isLoggedIn() | ||
32 | if (this.isLoggedIn === true) this.user = this.authService.getUser() | ||
33 | this.computeIsUserHasAdminAccess() | ||
34 | |||
35 | this.authService.loginChangedSource.subscribe( | ||
36 | status => { | ||
37 | if (status === AuthStatus.LoggedIn) { | ||
38 | this.isLoggedIn = true | ||
39 | this.user = this.authService.getUser() | ||
40 | this.computeIsUserHasAdminAccess() | ||
41 | console.log('Logged in.') | ||
42 | } else if (status === AuthStatus.LoggedOut) { | ||
43 | this.isLoggedIn = false | ||
44 | this.user = undefined | ||
45 | this.computeIsUserHasAdminAccess() | ||
46 | console.log('Logged out.') | ||
47 | } else { | ||
48 | console.error('Unknown auth status: ' + status) | ||
49 | } | ||
50 | } | ||
51 | ) | ||
52 | } | ||
53 | |||
54 | isRegistrationAllowed () { | ||
55 | return this.serverService.getConfig().signup.allowed | ||
56 | } | ||
57 | |||
58 | getFirstAdminRightAvailable () { | ||
59 | const user = this.authService.getUser() | ||
60 | if (!user) return undefined | ||
61 | |||
62 | const adminRights = [ | ||
63 | UserRight.MANAGE_USERS, | ||
64 | UserRight.MANAGE_SERVER_FOLLOW, | ||
65 | UserRight.MANAGE_VIDEO_ABUSES, | ||
66 | UserRight.MANAGE_VIDEO_BLACKLIST | ||
67 | ] | ||
68 | |||
69 | for (const adminRight of adminRights) { | ||
70 | if (user.hasRight(adminRight)) { | ||
71 | return adminRight | ||
72 | } | ||
73 | } | ||
74 | |||
75 | return undefined | ||
76 | } | ||
77 | |||
78 | getFirstAdminRouteAvailable () { | ||
79 | const right = this.getFirstAdminRightAvailable() | ||
80 | |||
81 | return this.routesPerRight[right] | ||
82 | } | ||
83 | |||
84 | logout (event: Event) { | ||
85 | event.preventDefault() | ||
86 | |||
87 | this.authService.logout() | ||
88 | // Redirect to home page | ||
89 | this.router.navigate(['/videos/list']) | ||
90 | } | ||
91 | |||
92 | private computeIsUserHasAdminAccess () { | ||
93 | const right = this.getFirstAdminRightAvailable() | ||
94 | |||
95 | this.userHasAdminAccess = right !== undefined | ||
96 | } | ||
97 | } | ||