From 1baa8cee60036e4e15cc2e103db62fc273c9259e Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 17 Oct 2022 16:50:09 +0200 Subject: [PATCH] Added logic to get servers to dashboard #72 --- .../controller/discord/server_controller.py | 20 ++-- .../src/bot_api/service/discord_service.py | 45 +++++---- kdb-web/src/app/models/discord/server.dto.ts | 6 ++ .../logins/login-select-criterion.dto.ts | 8 -- .../server/get-filtered-servers-result.dto.ts | 7 ++ .../server/server-select-criterion.dto.ts | 5 + .../auth-user/auth-user.component.ts | 2 +- .../dashboard/dashboard.component.html | 15 ++- .../dashboard/dashboard.component.ts | 95 ++++++++++++++++++- kdb-web/src/app/services/data/data.service.ts | 33 ++++++- kdb-web/src/assets/i18n/de.json | 4 +- 11 files changed, 191 insertions(+), 49 deletions(-) create mode 100644 kdb-web/src/app/models/discord/server.dto.ts delete mode 100644 kdb-web/src/app/models/selection/logins/login-select-criterion.dto.ts create mode 100644 kdb-web/src/app/models/selection/server/get-filtered-servers-result.dto.ts create mode 100644 kdb-web/src/app/models/selection/server/server-select-criterion.dto.ts diff --git a/kdb-bot/src/bot_api/controller/discord/server_controller.py b/kdb-bot/src/bot_api/controller/discord/server_controller.py index 35a3fa9c..d2c89b10 100644 --- a/kdb-bot/src/bot_api/controller/discord/server_controller.py +++ b/kdb-bot/src/bot_api/controller/discord/server_controller.py @@ -36,24 +36,24 @@ class ServerController: self._mailer = mailer self._discord_service = discord_service - @Route.get(f'{BasePath}/servers') + @Route.get(f'{BasePath}/get/servers') @Route.authorize(role=AuthRoleEnum.admin) async def get_all_servers(self) -> Response: result = await self._discord_service.get_all_servers() result = result.select(lambda x: x.to_dict()) return jsonify(result) - @Route.get(f'{BasePath}/servers/get/filtered') - @Route.authorize - async def get_all_servers_by_user(self) -> Response: - dto: ServerSelectCriteria = JSONProcessor.process(ServerSelectCriteria, request.get_json(force=True, silent=True)) - result = await self._discord_service.get_filtered_servers_async(dto) - result.result = result.result.select(lambda x: x.to_dict()) - return jsonify(result.to_dict()) - - @Route.get(f'{BasePath}/servers-by-user') + @Route.get(f'{BasePath}/get/servers-by-user') @Route.authorize async def get_all_servers_by_user(self) -> Response: result = await self._discord_service.get_all_servers_by_user() result = result.select(lambda x: x.to_dict()) return jsonify(result) + + @Route.post(f'{BasePath}/get/filtered') + @Route.authorize + async def get_filtered_servers(self) -> Response: + dto: ServerSelectCriteria = JSONProcessor.process(ServerSelectCriteria, request.get_json(force=True, silent=True)) + result = await self._discord_service.get_filtered_servers_async(dto) + result.result = result.result.select(lambda x: x.to_dict()) + return jsonify(result.to_dict()) diff --git a/kdb-bot/src/bot_api/service/discord_service.py b/kdb-bot/src/bot_api/service/discord_service.py index e00e5b84..6f8e5f13 100644 --- a/kdb-bot/src/bot_api/service/discord_service.py +++ b/kdb-bot/src/bot_api/service/discord_service.py @@ -37,29 +37,6 @@ class DiscordService: lambda x: ServerTransformer.to_dto(x, self._bot.get_guild(x.discord_server_id).name, self._bot.get_guild(x.discord_server_id).member_count) ) - async def get_filtered_servers_async(self, criteria: ServerSelectCriteria) -> ServerFilteredResultDTO: - token = self._auth.get_decoded_token_from_request() - if token is None or 'email' not in token or 'role' not in token: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid') - - role = AuthRoleEnum(token['role']) - role = AuthRoleEnum(token['role']) - filtered_result = self._servers.get_filtered_servers(criteria) - servers = filtered_result.result - if role != AuthRoleEnum.admin: - user = await self._auth.find_auth_user_by_email_async(token['email']) - user_from_db = self._users.find_user_by_id(0 if user.user_id is None else user.user_id) - servers = servers.where(lambda x: user_from_db is not None and x.server_id == user_from_db.server.server_id) - - result = servers.select( - lambda x: ServerTransformer.to_dto(x, self._bot.get_guild(x.discord_server_id).name, self._bot.get_guild(x.discord_server_id).member_count) - ) - - return ServerFilteredResultDTO( - List(ServerDTO, result), - servers.total_count - ) - async def get_all_servers_by_user(self) -> List[ServerDTO]: token = self._auth.get_decoded_token_from_request() if token is None or 'email' not in token or 'role' not in token: @@ -76,3 +53,25 @@ class DiscordService: return servers.select( lambda x: ServerTransformer.to_dto(x, self._bot.get_guild(x.discord_server_id).name, self._bot.get_guild(x.discord_server_id).member_count) ) + + async def get_filtered_servers_async(self, criteria: ServerSelectCriteria) -> ServerFilteredResultDTO: + token = self._auth.get_decoded_token_from_request() + if token is None or 'email' not in token or 'role' not in token: + raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid') + + role = AuthRoleEnum(token['role']) + filtered_result = self._servers.get_filtered_servers(criteria) + servers = filtered_result.result + if role != AuthRoleEnum.admin: + user = await self._auth.find_auth_user_by_email_async(token['email']) + user_from_db = self._users.find_user_by_id(0 if user.user_id is None else user.user_id) + servers = servers.where(lambda x: user_from_db is not None and x.server_id == user_from_db.server.server_id) + + result = servers.select( + lambda x: ServerTransformer.to_dto(x, self._bot.get_guild(x.discord_server_id).name, self._bot.get_guild(x.discord_server_id).member_count) + ) + + return ServerFilteredResultDTO( + List(ServerDTO, result), + filtered_result.total_count + ) diff --git a/kdb-web/src/app/models/discord/server.dto.ts b/kdb-web/src/app/models/discord/server.dto.ts new file mode 100644 index 00000000..4cba26ac --- /dev/null +++ b/kdb-web/src/app/models/discord/server.dto.ts @@ -0,0 +1,6 @@ +export interface ServerDTO { + serverId: number; + discordId: number; + name: string; + memberCount: number; +} \ No newline at end of file diff --git a/kdb-web/src/app/models/selection/logins/login-select-criterion.dto.ts b/kdb-web/src/app/models/selection/logins/login-select-criterion.dto.ts deleted file mode 100644 index e1998d60..00000000 --- a/kdb-web/src/app/models/selection/logins/login-select-criterion.dto.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { SelectCriterion } from "../select-criterion.model"; - -export interface LoginSelectCriterion extends SelectCriterion { - timeFrom: string; - timeTo: string; - userName: string; - hostName: string; -} \ No newline at end of file diff --git a/kdb-web/src/app/models/selection/server/get-filtered-servers-result.dto.ts b/kdb-web/src/app/models/selection/server/get-filtered-servers-result.dto.ts new file mode 100644 index 00000000..4dfe801a --- /dev/null +++ b/kdb-web/src/app/models/selection/server/get-filtered-servers-result.dto.ts @@ -0,0 +1,7 @@ +import { AuthUserDTO } from "../../auth/auth-user.dto"; +import { ServerDTO } from "../../discord/server.dto"; + +export interface GetFilteredServersResultDTO { + servers: ServerDTO[]; + totalCount: number; +} \ No newline at end of file diff --git a/kdb-web/src/app/models/selection/server/server-select-criterion.dto.ts b/kdb-web/src/app/models/selection/server/server-select-criterion.dto.ts new file mode 100644 index 00000000..08b9ea59 --- /dev/null +++ b/kdb-web/src/app/models/selection/server/server-select-criterion.dto.ts @@ -0,0 +1,5 @@ +import { SelectCriterion } from "../select-criterion.model"; + +export interface ServerSelectCriterion extends SelectCriterion { + name: string | null; +} \ No newline at end of file diff --git a/kdb-web/src/app/modules/admin/auth-users/components/auth-user/auth-user.component.ts b/kdb-web/src/app/modules/admin/auth-users/components/auth-user/auth-user.component.ts index c972e7f2..a9243563 100644 --- a/kdb-web/src/app/modules/admin/auth-users/components/auth-user/auth-user.component.ts +++ b/kdb-web/src/app/modules/admin/auth-users/components/auth-user/auth-user.component.ts @@ -85,7 +85,7 @@ export class AuthUserComponent implements OnInit { }; this.setFilterForm(); - // this.loadNextPage(); + this.loadNextPage(); } setFilterForm() { diff --git a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.html b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.html index 04e795ec..e4139bac 100644 --- a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.html +++ b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.html @@ -1,3 +1,12 @@ -

dashboard works!

- -
+

+ {{'view.dashboard.header' | translate}} +

+
+
+
    +
  • + {{server.name}} +
  • +
+
+
\ No newline at end of file diff --git a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts index 25d48a7a..0fb3ff19 100644 --- a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts +++ b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts @@ -1,4 +1,14 @@ import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormControl, FormBuilder } from '@angular/forms'; +import { TranslateService } from '@ngx-translate/core'; +import { LazyLoadEvent } from 'primeng/api'; +import { catchError, debounceTime, throwError } from 'rxjs'; +import { ServerDTO } from 'src/app/models/discord/server.dto'; +import { ServerSelectCriterion } from 'src/app/models/selection/server/server-select-criterion.dto'; +import { ConfirmationDialogService } from 'src/app/services/confirmation-dialog/confirmation-dialog.service'; +import { DataService } from 'src/app/services/data/data.service'; +import { SpinnerService } from 'src/app/services/spinner/spinner.service'; +import { ToastService } from 'src/app/services/toast/toast.service'; @Component({ selector: 'app-dashboard', @@ -7,8 +17,89 @@ import { Component, OnInit } from '@angular/core'; }) export class DashboardComponent implements OnInit { - constructor() { } + loading = true; + servers: ServerDTO[] = []; - ngOnInit(): void {} + searchCriterions: ServerSelectCriterion = { + name: null, + pageIndex: 0, + pageSize: 10, + sortColumn: null, + sortDirection: null + }; + totalRecords!: number; + + + filterForm!: FormGroup<{ + name: FormControl, + }>; + + constructor( + private data: DataService, + private spinnerService: SpinnerService, + private toastService: ToastService, + private confirmDialog: ConfirmationDialogService, + private fb: FormBuilder, + private translate: TranslateService + ) { } + + ngOnInit(): void { + this.setFilterForm(); + this.loadNextPage(); + } + + setFilterForm() { + this.filterForm = this.fb.group({ + name: [''], + }); + + this.filterForm.valueChanges.pipe( + debounceTime(600) + ).subscribe(changes => { + if (changes.name) { + this.searchCriterions.name = changes.name; + } else { + this.searchCriterions.name = null; + } + + if (this.searchCriterions.pageSize) + this.searchCriterions.pageSize = 10; + + if (this.searchCriterions.pageSize) + this.searchCriterions.pageIndex = 0; + + this.loadNextPage(); + }); + } + + loadNextPage() { + this.data.getFilteredServers(this.searchCriterions).pipe(catchError(err => { + this.loading = false; + return throwError(() => err); + })).subscribe(list => { + this.totalRecords = list.totalCount; + this.servers = list.servers; + this.loading = false; + }); + } + + nextPage(event: LazyLoadEvent) { + this.searchCriterions.pageSize = event.rows ?? 0; + if (event.first != null && event.rows != null) + this.searchCriterions.pageIndex = event.first / event.rows; + this.searchCriterions.sortColumn = event.sortField ?? null; + this.searchCriterions.sortDirection = event.sortOrder === 1 ? 'asc' : event.sortOrder === -1 ? 'desc' : 'asc'; + + if (event.filters) { + // + "" => convert to string + this.searchCriterions.name = event.filters['name'] ? event.filters['name'] + "" : null; + } + + this.loadNextPage(); + } + + resetFilters() { + this.filterForm.reset(); + } } diff --git a/kdb-web/src/app/services/data/data.service.ts b/kdb-web/src/app/services/data/data.service.ts index 36cccbb5..80a60600 100644 --- a/kdb-web/src/app/services/data/data.service.ts +++ b/kdb-web/src/app/services/data/data.service.ts @@ -1,5 +1,9 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { ServerDTO } from 'src/app/models/discord/server.dto'; +import { GetFilteredServersResultDTO } from 'src/app/models/selection/server/get-filtered-servers-result.dto'; +import { ServerSelectCriterion } from 'src/app/models/selection/server/server-select-criterion.dto'; import { SettingsService } from '../settings/settings.service'; @Injectable({ @@ -11,4 +15,31 @@ export class DataService { private appsettings: SettingsService, private http: HttpClient, ) { } + + + + /* data requests */ + getAllServers(): Observable> { + return this.http.get>(`${this.appsettings.getApiURL()}/api/discord/server/servers`, { + headers: new HttpHeaders({ + 'Content-Type': 'application/json' + }) + }); + } + + getAllServersByUser(): Observable> { + return this.http.get>(`${this.appsettings.getApiURL()}/api/discord/server/servers-by-user`, { + headers: new HttpHeaders({ + 'Content-Type': 'application/json' + }) + }); + } + + getFilteredServers(selectCriterions: ServerSelectCriterion): Observable { + return this.http.post(`${this.appsettings.getApiURL()}/api/discord/server/get/filtered`, selectCriterions, { + headers: new HttpHeaders({ + 'Content-Type': 'application/json' + }) + }); + } } diff --git a/kdb-web/src/assets/i18n/de.json b/kdb-web/src/assets/i18n/de.json index 894bd461..ae0a0f4c 100644 --- a/kdb-web/src/assets/i18n/de.json +++ b/kdb-web/src/assets/i18n/de.json @@ -106,7 +106,9 @@ } }, "view": { - "dashboard": {}, + "dashboard": { + "header": "Dashboard" + }, "user-list": {}, "change-password": { "header": "Passwort ändern",