1.0.0 #253
| @@ -45,6 +45,10 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|     def user(self) -> User: | ||||
|         return self._user | ||||
|  | ||||
|     @property | ||||
|     def time(self) -> float: | ||||
|         return round((self.leaved_on - self.joined_on).total_seconds() / 3600, 2) | ||||
|  | ||||
|     @property | ||||
|     def joined_on(self) -> datetime: | ||||
|         return self._joined_on | ||||
|   | ||||
| @@ -3,6 +3,7 @@ type UserJoinedVoiceChannel implements TableQuery { | ||||
|     channelId: String | ||||
|     channelName: String | ||||
|     user: User | ||||
|     time: Float | ||||
|     joinedOn: String | ||||
|     leavedOn: String | ||||
|  | ||||
|   | ||||
| @@ -37,12 +37,12 @@ class UserMutation(QueryABC): | ||||
|         user = self._users.get_user_by_id(input["id"]) | ||||
|         self._can_user_mutate_data(user.server, UserRoleEnum.moderator) | ||||
|  | ||||
|         user.xp = input["xp"] if "xp" in input else user.xp | ||||
|  | ||||
|         if "levelId" in input: | ||||
|             level = self._levels.get_level_by_id(input["levelId"]) | ||||
|             user.xp = level.min_xp | ||||
|  | ||||
|         user.xp = input["xp"] if "xp" in input else user.xp | ||||
|  | ||||
|         self._users.update_user(user) | ||||
|         self._db.save_changes() | ||||
|         self._level_service.set_level(user) | ||||
|   | ||||
| @@ -14,6 +14,7 @@ class UserJoinedVoiceChannelQuery(DataQueryABC): | ||||
|         self.set_field("channelId", self.resolve_channel_id) | ||||
|         self.set_field("channelName", self.resolve_channel_name) | ||||
|         self.set_field("user", self.resolve_user) | ||||
|         self.set_field("time", self.resolve_time) | ||||
|         self.set_field("joinedOn", self.resolve_joined_on) | ||||
|         self.set_field("leavedOn", self.resolve_leaved_on) | ||||
|  | ||||
| @@ -33,6 +34,10 @@ class UserJoinedVoiceChannelQuery(DataQueryABC): | ||||
|     def resolve_user(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.user | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_time(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.time | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_joined_on(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.joined_on | ||||
|   | ||||
| @@ -72,10 +72,8 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||
|             join = self._user_joins_vc.get_active_user_joined_voice_channel_by_user_id(user.id) | ||||
|             join.leaved_on = datetime.now() | ||||
|  | ||||
|             # ontime as hours | ||||
|             ontime = round((join.leaved_on - join.joined_on).total_seconds() / 3600, 2) | ||||
|             old_xp = user.xp | ||||
|             user.xp += round(ontime * settings.xp_per_ontime_hour) | ||||
|             user.xp += round(join.time * settings.xp_per_ontime_hour) | ||||
|  | ||||
|             self._user_joins_vc.update_user_joined_voice_channel(join) | ||||
|             self._users.update_user(user) | ||||
| @@ -83,7 +81,7 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||
|  | ||||
|             self._logger.debug( | ||||
|                 __name__, | ||||
|                 f"User {user} leaved_on {join.leaved_on}. Ontime: {ontime}h | xp: from {old_xp} to {user.xp}", | ||||
|                 f"User {user} leaved_on {join.leaved_on}. Ontime: {join.time}h | xp: from {old_xp} to {user.xp}", | ||||
|             ) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Ontime validation failed", e) | ||||
|   | ||||
| @@ -50,4 +50,4 @@ | ||||
|         "tslib": "^2.4.1", | ||||
|         "typescript": "~4.9.5" | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,6 +1,8 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { Level, LevelFilter } from "./level.model"; | ||||
| import { Server, ServerFilter } from "./server.model"; | ||||
| import { UserJoinedServer } from "./user_joined_server.model"; | ||||
| import { UserJoinedVoiceChannel } from "./user_joined_voice_channel.model"; | ||||
|  | ||||
| export interface User extends Data { | ||||
|   id?: number; | ||||
| @@ -14,10 +16,10 @@ export interface User extends Data { | ||||
|   leftServer?: boolean; | ||||
|  | ||||
|   joinedServerCount?: number; | ||||
|   joinedServers?: []; | ||||
|   joinedServers?: UserJoinedServer[]; | ||||
|  | ||||
|   joinedVoiceChannelCount?: number; | ||||
|   joinedVoiceChannels?: []; | ||||
|   joinedVoiceChannels?: UserJoinedVoiceChannel[]; | ||||
|  | ||||
|   userJoinedGameServerCount?: number; | ||||
|   userJoinedGameServers?: []; | ||||
|   | ||||
							
								
								
									
										9
									
								
								kdb-web/src/app/models/data/user_joined_server.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								kdb-web/src/app/models/data/user_joined_server.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { User } from "./user.model"; | ||||
|  | ||||
| export interface UserJoinedServer extends Data { | ||||
|   id: number; | ||||
|   user: User; | ||||
|   joinedOn: string; | ||||
|   leavedOn: string; | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { User } from "./user.model"; | ||||
|  | ||||
| export interface UserJoinedVoiceChannel extends Data { | ||||
|   id: number; | ||||
|   channelId: string; | ||||
|   channelName: string; | ||||
|   user: User; | ||||
|   time: number; | ||||
|   joinedOn: string; | ||||
|   leavedOn: string; | ||||
| } | ||||
| @@ -78,4 +78,53 @@ export class Queries { | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
|  | ||||
|   static singleUserQuery = ` | ||||
|     query singleUserQuery($filter: UserFilter) { | ||||
|       users(filter: $filter) { | ||||
|         id | ||||
|         discordId | ||||
|         name | ||||
|         xp | ||||
|         ontime | ||||
|         level { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|         leftServer | ||||
|         server { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|  | ||||
|         joinedServerCount | ||||
|         joinedServers { | ||||
|           id | ||||
|           joinedOn | ||||
|           leavedOn | ||||
|         } | ||||
|  | ||||
|         joinedVoiceChannelCount | ||||
|         joinedVoiceChannels { | ||||
|           id | ||||
|           channelId | ||||
|           channelName | ||||
|           time | ||||
|           joinedOn | ||||
|           leavedOn | ||||
|         } | ||||
|  | ||||
|         userJoinedGameServerCount | ||||
|         userJoinedGameServers { | ||||
|           id | ||||
|           gameServer | ||||
|           joinedOn | ||||
|           leavedOn | ||||
|         } | ||||
|  | ||||
|         createdAt | ||||
|         modifiedAt | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
| } | ||||
|   | ||||
| @@ -70,6 +70,18 @@ | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th class="table-header-small-dropdown"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'common.created_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th class="table-header-small-dropdown"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'common.modified_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th class="table-header-actions"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'admin.auth_users.headers.actions' | translate}}</div> | ||||
| @@ -177,7 +189,7 @@ | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{user.createdAt}} | ||||
|                 {{user.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{user.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
| @@ -187,7 +199,7 @@ | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{user.modifiedAt}} | ||||
|                 {{user.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{user.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|   | ||||
| @@ -10,11 +10,15 @@ export class BoolPipe implements PipeTransform { | ||||
|     private translate: TranslateService | ||||
|   ) {} | ||||
|  | ||||
|   transform(value: boolean): string { | ||||
|     if (value === true) { | ||||
|   transform(value?: boolean): string { | ||||
|     if (value === undefined || value === null) { | ||||
|       return ''; | ||||
|     } | ||||
|  | ||||
|     if (value) { | ||||
|       return this.translate.instant('common.bool_as_string.true'); | ||||
|     } | ||||
|    | ||||
|  | ||||
|     return this.translate.instant('common.bool_as_string.false'); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ import { LazyLoadEvent, MenuItem } from "primeng/api"; | ||||
| import { Table } from "primeng/table"; | ||||
| import { User, UserFilter } from "../../../../models/data/user.model"; | ||||
| import { Queries } from "../../../../models/graphql/queries.model"; | ||||
| import { LevelListQuery, Query, UserListQuery } from "../../../../models/graphql/query.model"; | ||||
| import { LevelListQuery, UserListQuery } from "../../../../models/graphql/query.model"; | ||||
| import { DataService } from "../../../../services/data/data.service"; | ||||
| import { Page } from "../../../../models/graphql/filter/page.model"; | ||||
| import { Sort, SortDirection } from "../../../../models/graphql/filter/sort.model"; | ||||
| @@ -18,8 +18,7 @@ import { SidebarService } from "../../../../services/sidebar/sidebar.service"; | ||||
| import { Mutations } from "../../../../models/graphql/mutations.model"; | ||||
| import { throwError } from "rxjs"; | ||||
| import { UpdateUserMutationResult } from "../../../../models/graphql/result.model"; | ||||
| import { Server } from "../../../../models/data/server.model"; | ||||
| import { ActivatedRoute, Router } from "@angular/router"; | ||||
| import { ActivatedRoute } from "@angular/router"; | ||||
|  | ||||
| @Component({ | ||||
|   selector: "app-members", | ||||
| @@ -88,30 +87,11 @@ export class MembersComponent { | ||||
|     private data: DataService, | ||||
|     private sidebar: SidebarService, | ||||
|     private route: ActivatedRoute, | ||||
|     private router: Router, | ||||
|   ) { | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|  | ||||
|     this.spinner.showSpinner(); | ||||
|     if (!this.route.snapshot.params["serverId"]) { | ||||
|       this.spinner.hideSpinner(); | ||||
|       this.router.navigate(['/dashboard']); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     this.data.query<Server>(Queries.serversQuery, { | ||||
|         filter: { id: this.route.snapshot.params["serverId"] } | ||||
|       }, | ||||
|       function(data: Query) { | ||||
|         return data.servers.length > 0 ? data.servers[0] : null; | ||||
|       } | ||||
|     ).subscribe(server => { | ||||
|       this.sidebar.setServer(server); | ||||
|       this.spinner.hideSpinner(); | ||||
|     }); | ||||
|  | ||||
|     this.data.getServerFromRoute(this.route); | ||||
|  | ||||
|     this.spinner.showSpinner(); | ||||
|     this.data.query<LevelListQuery>(Queries.levelQuery, { | ||||
|   | ||||
| @@ -1 +1,115 @@ | ||||
| <p>profile works!</p> | ||||
| <h1> | ||||
|   {{'view.server.profile.header' | translate}} | ||||
| </h1> | ||||
| <div class="content-wrapper"> | ||||
|   <div class="content-header"> | ||||
|     <h2> | ||||
|       {{user.name}} | ||||
|     </h2> | ||||
|   </div> | ||||
|  | ||||
|   <div class="content"> | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.id' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.id}}</div> | ||||
|       </div> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.discord_id' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.discordId}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.name' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.name}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.xp' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.xp}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.ontime' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.ontime}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.level' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.level?.name}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'view.server.profile.left_server' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.leftServer | bool}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'common.created_at' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.createdAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-row"> | ||||
|       <div class="content-column"> | ||||
|         <div class="content-data-name">{{'common.modified_at' | translate}}:</div> | ||||
|         <div class="content-data-value">{{user.modifiedAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-divider"></div> | ||||
|     <div class="content-row"> | ||||
|       <h3>{{'view.server.profile.joined_voice_channel.header' | translate}}</h3> | ||||
|     </div> | ||||
|  | ||||
|     <div *ngFor="let join of user.joinedVoiceChannels;"> | ||||
|       <div class="content-row"> | ||||
|         <div class="content-column"> | ||||
|           <div class="content-data-name">{{'view.server.profile.joined_voice_channel.time' | translate}}:</div> | ||||
|           <div class="content-data-value">{{join.time}} {{'general.hours' | translate}}</div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="content-column"> | ||||
|           <div class="content-data-name">{{'view.server.profile.joined_voice_channel.joined_at' | translate}}:</div> | ||||
|           <div class="content-data-value">{{join.joinedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="content-column"> | ||||
|           <div class="content-data-name">{{'view.server.profile.joined_voice_channel.leaved_at' | translate}}:</div> | ||||
|           <div class="content-data-value">{{join.leavedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="content-divider"></div> | ||||
|     <div class="content-row"> | ||||
|       <h3>{{'view.server.profile.joined_server.header' | translate}}</h3> | ||||
|     </div> | ||||
|  | ||||
|     <div *ngFor="let join of user.joinedServers;"> | ||||
|       <div class="content-row"> | ||||
|         <div class="content-column"> | ||||
|           <div class="content-data-name">{{'view.server.profile.joined_server.joined_at' | translate}}:</div> | ||||
|           <div class="content-data-value">{{join.joinedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="content-column"> | ||||
|           <div class="content-data-name">{{'view.server.profile.joined_server.leaved_at' | translate}}:</div> | ||||
|           <div class="content-data-value">{{join.leavedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| import { Component, OnInit } from "@angular/core"; | ||||
| import { ActivatedRoute, Router } from "@angular/router"; | ||||
| import { Server } from "../../../../models/data/server.model"; | ||||
| import { Queries } from "../../../../models/graphql/queries.model"; | ||||
| import { Query } from "../../../../models/graphql/query.model"; | ||||
| import { UserListQuery } from "../../../../models/graphql/query.model"; | ||||
| import { SpinnerService } from "../../../../services/spinner/spinner.service"; | ||||
| import { DataService } from "../../../../services/data/data.service"; | ||||
| import { SidebarService } from "../../../../services/sidebar/sidebar.service"; | ||||
| import { User } from "../../../../models/data/user.model"; | ||||
|  | ||||
| @Component({ | ||||
|   selector: "app-profile", | ||||
| @@ -14,31 +13,38 @@ import { SidebarService } from "../../../../services/sidebar/sidebar.service"; | ||||
| }) | ||||
| export class ProfileComponent implements OnInit { | ||||
|  | ||||
|   user!: User; | ||||
|  | ||||
|   constructor( | ||||
|     private route: ActivatedRoute, | ||||
|     private router: Router, | ||||
|     private spinner: SpinnerService, | ||||
|     private data: DataService, | ||||
|     private sidebar: SidebarService | ||||
|     private data: DataService | ||||
|   ) { | ||||
|   } | ||||
|  | ||||
|   ngOnInit() { | ||||
|     this.data.getServerFromRoute(this.route); | ||||
|  | ||||
|     this.spinner.showSpinner(); | ||||
|     if (!this.route.snapshot.params["serverId"]) { | ||||
|     if (!this.route.snapshot.params["memberId"]) { | ||||
|       this.spinner.hideSpinner(); | ||||
|       this.router.navigate(['/dashboard']); | ||||
|       this.router.navigate(["/dashboard"]); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     this.data.query<Server>(Queries.serversQuery, { | ||||
|         filter: { id: this.route.snapshot.params["serverId"] } | ||||
|     this.data.query<User>(Queries.singleUserQuery, { | ||||
|         filter: { | ||||
|           id: this.route.snapshot.params["memberId"], | ||||
|           leftServer: false | ||||
|         } | ||||
|       }, | ||||
|       function(data: Query) { | ||||
|         return data.servers.length > 0 ? data.servers[0] : null; | ||||
|       function(data: UserListQuery) { | ||||
|         return data.users.length > 0 ? data.users[0] : null; | ||||
|       } | ||||
|     ).subscribe(server => { | ||||
|       this.sidebar.setServer(server); | ||||
|     ).subscribe(user => { | ||||
|       this.user = user; | ||||
|       console.log(this.user); | ||||
|       this.spinner.hideSpinner(); | ||||
|     }); | ||||
|   } | ||||
|   | ||||
| @@ -3,8 +3,6 @@ import { ActivatedRoute, Router } from "@angular/router"; | ||||
| import { Server } from "src/app/models/data/server.model"; | ||||
| import { DataService } from "src/app/services/data/data.service"; | ||||
| import { SpinnerService } from "src/app/services/spinner/spinner.service"; | ||||
| import { Queries } from "../../../../models/graphql/queries.model"; | ||||
| import { Query } from "../../../../models/graphql/query.model"; | ||||
| import { SidebarService } from "../../../../services/sidebar/sidebar.service"; | ||||
|  | ||||
| @Component({ | ||||
| @@ -27,23 +25,13 @@ export class ServerDashboardComponent implements OnInit { | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.spinner.showSpinner(); | ||||
|     if (!this.route.snapshot.params["serverId"]) { | ||||
|       this.spinner.hideSpinner(); | ||||
|       this.router.navigate(['/dashboard']); | ||||
|       return; | ||||
|     } | ||||
|     this.data.getServerFromRoute(this.route); | ||||
|  | ||||
|     this.data.query<Server>(Queries.serversQuery, { | ||||
|         filter: { id: this.route.snapshot.params["serverId"] } | ||||
|       }, | ||||
|       function(data: Query) { | ||||
|         return data.servers.length > 0 ? data.servers[0] : null; | ||||
|     this.sidebar.server$.subscribe(server => { | ||||
|       if (!server) { | ||||
|         return; | ||||
|       } | ||||
|     ).subscribe(server => { | ||||
|       this.server = server; | ||||
|       this.sidebar.setServer(server); | ||||
|       this.spinner.hideSpinner(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -6,8 +6,8 @@ import { MembersComponent } from "./members/members.component"; | ||||
|  | ||||
| const routes: Routes = [ | ||||
|   { path: '', component: ServerDashboardComponent }, | ||||
|   { path: 'profile', component: ProfileComponent }, | ||||
|   { path: 'members', component: MembersComponent }, | ||||
|   { path: 'members/:memberId', component: ProfileComponent }, | ||||
| ]; | ||||
|  | ||||
| @NgModule({ | ||||
|   | ||||
| @@ -3,6 +3,12 @@ import { Injectable } from "@angular/core"; | ||||
| import { SettingsService } from "../settings/settings.service"; | ||||
| import { map, Observable } from "rxjs"; | ||||
| import { Variables } from "../../models/graphql/variables.model"; | ||||
| import { ActivatedRoute, Router } from "@angular/router"; | ||||
| import { Server } from "../../models/data/server.model"; | ||||
| import { Queries } from "../../models/graphql/queries.model"; | ||||
| import { Query } from "../../models/graphql/query.model"; | ||||
| import { SidebarService } from "../sidebar/sidebar.service"; | ||||
| import { SpinnerService } from "../spinner/spinner.service"; | ||||
|  | ||||
| @Injectable({ | ||||
|   providedIn: "root" | ||||
| @@ -11,10 +17,33 @@ export class DataService { | ||||
|  | ||||
|   constructor( | ||||
|     private appsettings: SettingsService, | ||||
|     private http: HttpClient | ||||
|     private http: HttpClient, | ||||
|     private sidebar: SidebarService, | ||||
|     private spinner: SpinnerService, | ||||
|     private router: Router, | ||||
|   ) { | ||||
|   } | ||||
|  | ||||
|   public getServerFromRoute(route: ActivatedRoute) { | ||||
|     this.spinner.showSpinner(); | ||||
|     if (!route.snapshot.params["serverId"]) { | ||||
|       this.spinner.hideSpinner(); | ||||
|       this.router.navigate(['/dashboard']); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     this.query<Server>(Queries.serversQuery, { | ||||
|         filter: { id: route.snapshot.params["serverId"] } | ||||
|       }, | ||||
|       function(data: Query) { | ||||
|         return data.servers.length > 0 ? data.servers[0] : null; | ||||
|       } | ||||
|     ).subscribe(server => { | ||||
|       this.sidebar.setServer(server); | ||||
|       this.spinner.hideSpinner(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   // query(query: string, variables: object = {}): Observable<QueryResult> { | ||||
|   //   return this.http.post<QueryResult>(`${this.appsettings.getApiURL()}/api/graphql`, | ||||
|   //     JSON.stringify({ | ||||
|   | ||||
| @@ -59,20 +59,28 @@ export class SidebarService { | ||||
|         { label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", icon: "pi pi-th-large", routerLink: "dashboard" } | ||||
|       ]; | ||||
|  | ||||
|       let authUser = await this.authService.getLoggedInUser(); | ||||
|       let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server$.value?.id) ?? null; | ||||
|       const serverMenu = { | ||||
|         label: this.isSidebarOpen ? this.server$.value?.name : "", icon: "pi pi-server", items: [ | ||||
|           { label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.dashboard") : "", icon: "pi pi-th-large", routerLink: `server/${this.server$.value?.id}` }, | ||||
|           { label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.profile") : "", icon: "pi pi-user", routerLink: `server/${this.server$.value?.id}/profile` } | ||||
|           { | ||||
|             label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.profile") : "", | ||||
|             icon: "pi pi-user", | ||||
|             routerLink: `server/${this.server$.value?.id}/members/${user?.id}` | ||||
|           } | ||||
|           // { label: this.isSidebarOpen ? this.translateService.instant("sidebar.members") : "", icon: "pi pi-users", routerLink: "server/members" } | ||||
|         ] | ||||
|       }; | ||||
|       if (this.server$.value) { | ||||
|         let authUser = await this.authService.getLoggedInUser(); | ||||
|         let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server$.value?.id) ?? null; | ||||
|  | ||||
|       if (this.server$.value) { | ||||
|         if (user?.isAdmin) { | ||||
|           serverMenu.items.push( | ||||
|             { label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.members") : "", icon: "pi pi-users", routerLink: `server/${this.server$.value?.id}/members` } | ||||
|             { | ||||
|               label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.members") : "", | ||||
|               icon: "pi pi-users", | ||||
|               routerLink: `server/${this.server$.value?.id}/members` | ||||
|             } | ||||
|           ); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -23,4 +23,4 @@ | ||||
|             "Name": "sh-edraft-dark-theme" | ||||
|         } | ||||
|     ] | ||||
| } | ||||
| } | ||||
| @@ -69,9 +69,7 @@ | ||||
|         "active": "Aktiv", | ||||
|         "role": "Rolle", | ||||
|         "password": "Passwort", | ||||
|         "actions": "Aktionen", | ||||
|         "created_at": "Erstellt am", | ||||
|         "modified_at": "Bearbeitet am" | ||||
|         "actions": "Aktionen" | ||||
|       }, | ||||
|       "no_entries_found": "Keine Einträge gefunden", | ||||
|       "message": { | ||||
| @@ -162,6 +160,28 @@ | ||||
|       "dashboard": { | ||||
|         "header": "Server dashboard" | ||||
|       }, | ||||
|       "profile": { | ||||
|         "header": "Dein Profil", | ||||
|         "id": "Id", | ||||
|         "discord_id": "Discord Id", | ||||
|         "name": "Name", | ||||
|         "xp": "XP", | ||||
|         "ontime": "Ontime", | ||||
|         "level": "Level", | ||||
|         "left_server": "Hat Server verlassen", | ||||
|         "joined_voice_channel": { | ||||
|           "header": "Sprachkanal-beitritte", | ||||
|           "time": "Zeit", | ||||
|           "joined_at": "Beigetreten am", | ||||
|           "leaved_at": "Verlassen am" | ||||
|         }, | ||||
|         "joined_server": { | ||||
|           "header": "Server-beitritte", | ||||
|           "time": "Zeit", | ||||
|           "joined_at": "Beigetreten am", | ||||
|           "leaved_at": "Verlassen am" | ||||
|         } | ||||
|       }, | ||||
|       "members": { | ||||
|         "header": "Mitglieder", | ||||
|         "of": "von", | ||||
| @@ -233,9 +253,12 @@ | ||||
|   }, | ||||
|   "general": { | ||||
|     "days": "Tage", | ||||
|     "minutes": "Minuten" | ||||
|     "minutes": "Minuten", | ||||
|     "hours": "Stunden" | ||||
|   }, | ||||
|   "common": { | ||||
|     "created_at": "Erstellt am", | ||||
|     "modified_at": "Bearbeitet am", | ||||
|     "bool_as_string": { | ||||
|       "true": "Ja", | ||||
|       "false": "Nein" | ||||
|   | ||||
| @@ -122,7 +122,7 @@ header { | ||||
|                         display: flex; | ||||
|                         flex-direction: row; | ||||
|                         flex: 1; | ||||
|                         margin: 1.5px 0; | ||||
|                         margin: 5px 0; | ||||
|                     } | ||||
|  | ||||
|                     .content-column { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user