1.0.0 #253
| @@ -58,6 +58,8 @@ export class Queries { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|         createdAt | ||||
|         modifiedAt | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
|   | ||||
| @@ -0,0 +1,215 @@ | ||||
| <h1> | ||||
|   {{'view.server.levels.header' | translate}} | ||||
| </h1> | ||||
| <div class="content-wrapper"> | ||||
|   <div class="content"> | ||||
|     <p-table #dt [value]="levels" dataKey="id" editMode="row" [rowHover]="true" [rows]="10" | ||||
|              [rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords" | ||||
|              [lazy]="true" (onLazyLoad)="nextPage($event)"> | ||||
|  | ||||
|       <ng-template pTemplate="caption"> | ||||
|         <div class="table-caption"> | ||||
|           <div class="table-caption-text"> | ||||
|             <ng-container *ngIf="!loading">{{levels.length}} {{'view.server.levels.of' | translate}} | ||||
|               {{dt.totalRecords}} | ||||
|             </ng-container> | ||||
|             {{'view.server.levels.levels' | translate}} | ||||
|           </div> | ||||
|  | ||||
|           <div class="table-caption-btn-wrapper btn-wrapper"> | ||||
|             <button pButton label="{{'admin.auth_users.add' | translate}}" class="icon-btn btn" | ||||
|                     icon="pi pi-user-plus" [disabled]="isEditingNew"> | ||||
|             </button> | ||||
|             <button pButton label="{{'view.server.levels.reset_filters' | translate}}" icon="pi pi-undo" | ||||
|                     class="icon-btn btn"> | ||||
|             </button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="header"> | ||||
|         <tr> | ||||
|           <th pSortableColumn="id"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.levels.headers.id' | translate}}</div> | ||||
|               <p-sortIcon field="id" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="name"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.levels.headers.name' | translate}}</div> | ||||
|               <p-sortIcon field="name" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="color"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.levels.headers.color' | translate}}</div> | ||||
|               <p-sortIcon field="color" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="minXp"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.levels.headers.min_xp' | translate}}</div> | ||||
|               <p-sortIcon field="minXp" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="permissions"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.levels.headers.permissions' | translate}}</div> | ||||
|               <p-sortIcon field="permissions" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'common.created_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'common.modified_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.actions' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|         </tr> | ||||
|  | ||||
|         <tr> | ||||
|           <th class="table-header-small"> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <input type="text" pInputText formControlName="id" | ||||
|                      placeholder="{{'view.server.levels.headers.id' | translate}}"> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <input type="text" pInputText formControlName="name" | ||||
|                      placeholder="{{'view.server.levels.headers.name' | translate}}"> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th></th> | ||||
|           <th></th> | ||||
|           <th></th> | ||||
|           <th class="table-header-small-dropdown"></th> | ||||
|           <th class="table-header-small-dropdown"></th> | ||||
|           <th class="table-header-actions"></th> | ||||
|         </tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="body" let-level let-editing="editing" let-ri="rowIndex"> | ||||
|         <tr [pEditableRow]="level"> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.id}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.id}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|  | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.name}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.name}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|  | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.color}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.color}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|  | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.minXp}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.minXp}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|  | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.permissions}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.permissions}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|  | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{level.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{level.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|  | ||||
|           <td> | ||||
|             <div class="btn-wrapper"> | ||||
|               <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" | ||||
|               ></button> | ||||
|               <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user" | ||||
|                       [routerLink]="[level.id, 'rules']"></button> | ||||
|  | ||||
|               <button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn" | ||||
|                       icon="pi pi-check-circle"></button> | ||||
|               <button *ngIf="editing" pButton pCancelEditableRow class="btn icon-btn danger-icon-btn" | ||||
|                       icon="pi pi-times-circle"></button> | ||||
|             </div> | ||||
|           </td> | ||||
|         </tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="emptymessage"> | ||||
|         <tr></tr> | ||||
|         <tr> | ||||
|           <td colspan="10">{{'view.server.auto_roles.no_entries_found' | translate}}</td> | ||||
|         </tr> | ||||
|         <tr></tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="paginatorleft"> | ||||
|       </ng-template> | ||||
|     </p-table> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @@ -0,0 +1,23 @@ | ||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
|  | ||||
| import { LevelsComponent } from './levels.component'; | ||||
|  | ||||
| describe('LevelsComponent', () => { | ||||
|   let component: LevelsComponent; | ||||
|   let fixture: ComponentFixture<LevelsComponent>; | ||||
|  | ||||
|   beforeEach(async () => { | ||||
|     await TestBed.configureTestingModule({ | ||||
|       declarations: [ LevelsComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|  | ||||
|     fixture = TestBed.createComponent(LevelsComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @@ -0,0 +1,127 @@ | ||||
| import {Component} from '@angular/core'; | ||||
| import {AuthService} from "../../../../../../services/auth/auth.service"; | ||||
| import {SpinnerService} from "../../../../../../services/spinner/spinner.service"; | ||||
| import {ToastService} from "../../../../../../services/toast/toast.service"; | ||||
| import {ConfirmationDialogService} from "../../../../../../services/confirmation-dialog/confirmation-dialog.service"; | ||||
| import {FormBuilder, FormControl, FormGroup} from "@angular/forms"; | ||||
| import {TranslateService} from "@ngx-translate/core"; | ||||
| import {DataService} from "../../../../../../services/data/data.service"; | ||||
| import {SidebarService} from "../../../../../../services/sidebar/sidebar.service"; | ||||
| import {ActivatedRoute} from "@angular/router"; | ||||
| import {Page} from "../../../../../../models/graphql/filter/page.model"; | ||||
| import {Sort, SortDirection} from "../../../../../../models/graphql/filter/sort.model"; | ||||
| import {Level, LevelFilter} from "../../../../../../models/data/level.model"; | ||||
| import {LevelListQuery} from "../../../../../../models/graphql/query.model"; | ||||
| import {Queries} from "../../../../../../models/graphql/queries.model"; | ||||
| import {debounceTime} from "rxjs/operators"; | ||||
| import {LazyLoadEvent} from "primeng/api"; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-levels', | ||||
|   templateUrl: './levels.component.html', | ||||
|   styleUrls: ['./levels.component.scss'] | ||||
| }) | ||||
| export class LevelsComponent { | ||||
|  | ||||
|   levels!: Level[]; | ||||
|   loading = true; | ||||
|  | ||||
|   isEditingNew: boolean = false; | ||||
|  | ||||
|   filterForm!: FormGroup<{ | ||||
|     id: FormControl<number | null>, | ||||
|     name: FormControl<string | null>, | ||||
|     color: FormControl<string | null>, | ||||
|     min_xp: FormControl<number | null>, | ||||
|     permissions: FormControl<number | null>, | ||||
|   }>; | ||||
|  | ||||
|   filter: LevelFilter = {}; | ||||
|   page: Page = { | ||||
|     pageSize: undefined, | ||||
|     pageIndex: undefined | ||||
|   }; | ||||
|   sort: Sort = { | ||||
|     sortColumn: undefined, | ||||
|     sortDirection: undefined | ||||
|   }; | ||||
|  | ||||
|   totalRecords!: number; | ||||
|  | ||||
|   public constructor( | ||||
|     private authService: AuthService, | ||||
|     private spinner: SpinnerService, | ||||
|     private toastService: ToastService, | ||||
|     private confirmDialog: ConfirmationDialogService, | ||||
|     private fb: FormBuilder, | ||||
|     private translate: TranslateService, | ||||
|     private data: DataService, | ||||
|     private sidebar: SidebarService, | ||||
|     private route: ActivatedRoute) { | ||||
|   } | ||||
|  | ||||
|   public ngOnInit(): void { | ||||
|     this.data.getServerFromRoute(this.route); | ||||
|  | ||||
|     this.setFilterForm(); | ||||
|     this.loadNextPage(); | ||||
|   } | ||||
|  | ||||
|   public loadNextPage() { | ||||
|     this.loading = true; | ||||
|     this.data.query<LevelListQuery>(Queries.levelQuery, { | ||||
|         filter: this.filter, page: this.page, sort: this.sort | ||||
|       } | ||||
|     ).subscribe(data => { | ||||
|       this.totalRecords = data.levelCount; | ||||
|       this.levels = data.levels; | ||||
|       this.spinner.hideSpinner(); | ||||
|       this.loading = false; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   public setFilterForm() { | ||||
|     this.filterForm = this.fb.group({ | ||||
|       id: new FormControl<number | null>(null), | ||||
|       name: new FormControl<string | null>(null), | ||||
|       color: new FormControl<string | null>(null), | ||||
|       min_xp: new FormControl<number | null>(null), | ||||
|       permissions: new FormControl<number | null>(null), | ||||
|     }); | ||||
|  | ||||
|     this.filterForm.valueChanges.pipe( | ||||
|       debounceTime(600) | ||||
|     ).subscribe(changes => { | ||||
|       if (changes.id) { | ||||
|         this.filter.id = changes.id; | ||||
|       } else { | ||||
|         this.filter.id = undefined; | ||||
|       } | ||||
|  | ||||
|       if (changes.name) { | ||||
|         this.filter.name = changes.name; | ||||
|       } else { | ||||
|         this.filter.name = undefined; | ||||
|       } | ||||
|  | ||||
|       if (this.page.pageSize) | ||||
|         this.page.pageSize = 10; | ||||
|  | ||||
|       if (this.page.pageIndex) | ||||
|         this.page.pageIndex = 0; | ||||
|  | ||||
|       this.loadNextPage(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   public nextPage(event: LazyLoadEvent) { | ||||
|     this.page.pageSize = event.rows ?? 0; | ||||
|     if (event.first != null && event.rows != null) | ||||
|       this.page.pageIndex = event.first / event.rows; | ||||
|     this.sort.sortColumn = event.sortField ?? undefined; | ||||
|     this.sort.sortDirection = event.sortOrder === 1 ? SortDirection.ASC : event.sortOrder === -1 ? SortDirection.DESC : SortDirection.ASC; | ||||
|  | ||||
|     this.loadNextPage(); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,16 @@ | ||||
| import {NgModule} from "@angular/core"; | ||||
| import {RouterModule, Routes} from "@angular/router"; | ||||
| import {LevelsComponent} from "./components/levels/levels.component"; | ||||
|  | ||||
| const routes: Routes = [ | ||||
|  | ||||
|   {path: '', component: LevelsComponent}, | ||||
| ]; | ||||
|  | ||||
| @NgModule({ | ||||
|   imports: [RouterModule.forChild(routes)], | ||||
|   exports: [RouterModule] | ||||
| }) | ||||
| export class LevelsRoutingModule { | ||||
|  | ||||
| } | ||||
							
								
								
									
										18
									
								
								kdb-web/src/app/modules/view/server/levels/levels.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								kdb-web/src/app/modules/view/server/levels/levels.module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| import {NgModule} from '@angular/core'; | ||||
| import {CommonModule} from '@angular/common'; | ||||
| import {LevelsComponent} from './components/levels/levels.component' | ||||
| import {SharedModule} from "../../../shared/shared.module"; | ||||
| import {LevelsRoutingModule} from "./levels-routing.module"; | ||||
|  | ||||
| @NgModule({ | ||||
|   declarations: [ | ||||
|     LevelsComponent | ||||
|   ], | ||||
|   imports: [ | ||||
|     CommonModule, | ||||
|     LevelsRoutingModule, | ||||
|     SharedModule | ||||
|   ] | ||||
| }) | ||||
| export class LevelsModule { | ||||
| } | ||||
| @@ -1,18 +1,20 @@ | ||||
| import { NgModule } from "@angular/core"; | ||||
| import { RouterModule, Routes } from "@angular/router"; | ||||
| import { ServerDashboardComponent } from "./server-dashboard/server-dashboard.component"; | ||||
| import { ProfileComponent } from "./profile/profile.component"; | ||||
| import { MembersComponent } from "./members/members.component"; | ||||
| import {NgModule} from "@angular/core"; | ||||
| import {RouterModule, Routes} from "@angular/router"; | ||||
| import {ServerDashboardComponent} from "./server-dashboard/server-dashboard.component"; | ||||
| import {ProfileComponent} from "./profile/profile.component"; | ||||
| import {MembersComponent} from "./members/members.component"; | ||||
|  | ||||
| const routes: Routes = [ | ||||
|   { path: '', component: ServerDashboardComponent }, | ||||
|   { path: 'members', component: MembersComponent }, | ||||
|   { path: 'members/:memberId', component: ProfileComponent }, | ||||
|   { path: 'auto-roles', loadChildren: () => import('./auto-role/auto-role.module').then(m => m.AutoRoleModule)}, | ||||
|   {path: '', component: ServerDashboardComponent}, | ||||
|   {path: 'members', component: MembersComponent}, | ||||
|   {path: 'members/:memberId', component: ProfileComponent}, | ||||
|   {path: 'auto-roles', loadChildren: () => import('./auto-role/auto-role.module').then(m => m.AutoRoleModule)}, | ||||
|   {path: 'levels', loadChildren: () => import('./levels/levels.module').then(m => m.LevelsModule)}, | ||||
| ]; | ||||
|  | ||||
| @NgModule({ | ||||
|   imports: [RouterModule.forChild(routes)], | ||||
|   exports: [RouterModule] | ||||
| }) | ||||
| export class ServerRoutingModule { } | ||||
| export class ServerRoutingModule { | ||||
| } | ||||
|   | ||||
| @@ -24,6 +24,7 @@ export class SidebarService { | ||||
|   serverMembers!: MenuItem; | ||||
|   serverAutoRoles!: MenuItem; | ||||
|   serverAutoRoleRules!: MenuItem; | ||||
|   serverLevels!: MenuItem; | ||||
|   serverMenu!: MenuItem; | ||||
|   adminConfig!: MenuItem; | ||||
|   adminUsers!: MenuItem; | ||||
| @@ -66,7 +67,11 @@ export class SidebarService { | ||||
|   } | ||||
|  | ||||
|   async buildMenu(user: UserDTO | null, hasPermission: boolean) { | ||||
|     this.dashboard = { label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", icon: "pi pi-th-large", routerLink: "dashboard" }; | ||||
|     this.dashboard = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", | ||||
|       icon: "pi pi-th-large", | ||||
|       routerLink: "dashboard" | ||||
|     }; | ||||
|     this.serverDashboard = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.dashboard") : "", | ||||
|       icon: "pi pi-th-large", | ||||
| @@ -74,7 +79,7 @@ export class SidebarService { | ||||
|     }; | ||||
|     this.serverProfile = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.profile") : "", | ||||
|       icon: "pi pi-user", | ||||
|       icon: "pi pi-id-card", | ||||
|       routerLink: `server/${this.server$.value?.id}/members/${user?.id}` | ||||
|     }; | ||||
|     this.serverMembers = { | ||||
| @@ -91,14 +96,25 @@ export class SidebarService { | ||||
|       routerLink: `server/${this.server$.value?.id}/auto-roles` | ||||
|     }; | ||||
|  | ||||
|     this.serverLevels = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.levels") : "", | ||||
|       icon: "pi pi-book", | ||||
|       visible: true, | ||||
|       routerLink: `server/${this.server$.value?.id}/levels` | ||||
|     }; | ||||
|  | ||||
|     this.serverMenu = { | ||||
|       label: this.isSidebarOpen ? this.server$.value?.name : "", | ||||
|       icon: "pi pi-server", | ||||
|       visible: false, | ||||
|       expanded: true, | ||||
|       items: [this.serverDashboard, this.serverProfile, this.serverMembers, this.serverAutoRoles] | ||||
|       items: [this.serverDashboard, this.serverProfile, this.serverMembers, this.serverAutoRoles, this.serverLevels] | ||||
|     }; | ||||
|     this.adminConfig = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", | ||||
|       icon: "pi pi-cog", | ||||
|       routerLink: "/admin/settings" | ||||
|     }; | ||||
|     this.adminConfig = { label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", icon: "pi pi-cog", routerLink: "/admin/settings" }; | ||||
|     this.adminUsers = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.auth_user_list") : "", | ||||
|       icon: "pi pi-user-edit", | ||||
| @@ -126,6 +142,7 @@ export class SidebarService { | ||||
|         this.serverMenu.visible = true; | ||||
|         this.serverMembers.visible = !!user?.isModerator; | ||||
|         this.serverAutoRoles.visible = !!user?.isAdmin; | ||||
|         this.serverLevels.visible = !!user?.isAdmin; | ||||
|       } else { | ||||
|         this.serverMenu.visible = false; | ||||
|       } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
|       "dashboard": "Dashboard", | ||||
|       "profile": "Dein Profil", | ||||
|       "members": "Mitglieder", | ||||
|       "levels": "Level", | ||||
|       "auto_roles": "Auto Rollen" | ||||
|     }, | ||||
|     "server_empty": "Kein Server ausgewählt", | ||||
| @@ -281,6 +282,27 @@ | ||||
|             "auto_role_rule_delete_failed_d": "Die Löschung der Auto Rollen Regel {{id}} ist fehlgeschlagen!" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "levels": { | ||||
|         "header": "Level", | ||||
|         "reset_filters": "Filter zurücksetzen", | ||||
|         "of": "von", | ||||
|         "add": "Hinzufügen", | ||||
|         "levels": "Level", | ||||
|         "headers": { | ||||
|           "id": "Id", | ||||
|           "name": "Name", | ||||
|           "color": "Farbe", | ||||
|           "min_xp": "Min. XP", | ||||
|           "permissions": "Rechte" | ||||
|         }, | ||||
|         "no_entries_found": "Keine Einträge gefunden", | ||||
|         "message": { | ||||
|           "level_changed": "Level geändert", | ||||
|           "level_changed_d": "Level {{name}} erfolgreich geändert", | ||||
|           "level_change_failed": "Level Änderung fehlgeschlagen", | ||||
|           "level_change_failed_d": "Level {{name}} konnte nicht geändert werden!" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "user-list": {}, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user