From d7712432171cbc7251b363f57ff25cdb8752be60 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 14 Aug 2023 11:58:36 +0200 Subject: [PATCH] Added logic to edit technician config in WI #127 --- .../service/data_integrity_service.py | 2 +- .../model/technician_ping_url_config.py | 2 +- .../mutations/technician_config_mutation.py | 29 +++- kdb-web/package.json | 2 +- .../settings/settings.component.html | 94 ++++++++++++ .../components/settings/settings.component.ts | 142 ++++++++++++++---- kdb-web/src/assets/config.json | 2 +- 7 files changed, 234 insertions(+), 39 deletions(-) diff --git a/kdb-bot/src/bot_core/service/data_integrity_service.py b/kdb-bot/src/bot_core/service/data_integrity_service.py index 78b64e73..923cf4cb 100644 --- a/kdb-bot/src/bot_core/service/data_integrity_service.py +++ b/kdb-bot/src/bot_core/service/data_integrity_service.py @@ -174,7 +174,7 @@ class DataIntegrityService: self._logger.warn(__name__, f"User not found in database: {u.id}") self._logger.debug(__name__, f"Add user: {u.id}") - self._users.add_user(User(u.id, 0, server)) + self._users.add_user(User(u.id, 0, 0, 0, server)) self._db_context.save_changes() self._logger.debug(__name__, f"Added User: {u.id}") diff --git a/kdb-bot/src/bot_data/model/technician_ping_url_config.py b/kdb-bot/src/bot_data/model/technician_ping_url_config.py index 75d51c29..31983624 100644 --- a/kdb-bot/src/bot_data/model/technician_ping_url_config.py +++ b/kdb-bot/src/bot_data/model/technician_ping_url_config.py @@ -74,6 +74,6 @@ class TechnicianPingUrlConfig(TableABC): return str( f""" DELETE FROM `CFG_TechnicianPingUrls` - WHERE `URL` = {self._ping_url}; + WHERE `URL` = '{self._ping_url}'; """ ) diff --git a/kdb-bot/src/bot_graphql/mutations/technician_config_mutation.py b/kdb-bot/src/bot_graphql/mutations/technician_config_mutation.py index ed89ee48..da3b7651 100644 --- a/kdb-bot/src/bot_graphql/mutations/technician_config_mutation.py +++ b/kdb-bot/src/bot_graphql/mutations/technician_config_mutation.py @@ -1,6 +1,8 @@ from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List +from bot_api.logging.api_logger import ApiLogger from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC from bot_data.model.technician_config import TechnicianConfig @@ -13,6 +15,7 @@ from bot_graphql.abc.query_abc import QueryABC class TechnicianConfigMutation(QueryABC): def __init__( self, + logger: ApiLogger, bot: DiscordBotServiceABC, servers: ServerRepositoryABC, technician_configs: TechnicianConfigRepositoryABC, @@ -20,6 +23,7 @@ class TechnicianConfigMutation(QueryABC): ): QueryABC.__init__(self, "TechnicianConfigMutation") + self._logger = logger self._bot = bot self._servers = servers self._technician_configs = technician_configs @@ -45,9 +49,13 @@ class TechnicianConfigMutation(QueryABC): technician_config.cache_max_messages = ( input["cacheMaxMessages"] if "cacheMaxMessages" in input else technician_config.cache_max_messages ) - technician_config.ping_urls = input["pingURLs"] if "pingURLs" in input else technician_config.ping_urls + technician_config.ping_urls = ( + List(str, input["pingURLs"]) if "pingURLs" in input else technician_config.ping_urls + ) technician_config.technician_ids = ( - input["technicianIds"] if "technicianIds" in input else technician_config.technician_ids + List(int).extend([int(x) for x in input["technicianIds"]]) + if "technicianIds" in input + else technician_config.technician_ids ) self._technician_configs.update_technician_config(technician_config) @@ -76,14 +84,19 @@ class TechnicianConfigMutation(QueryABC): def _update_technician_ids(self, new_config: TechnicianConfig): old_config = self._technician_configs.get_technician_config() - for url in old_config.technician_ids: - if url in new_config.technician_ids: + for technician_id in old_config.technician_ids: + if technician_id in new_config.technician_ids: continue - self._technician_configs.delete_technician_id_config(TechnicianIdConfig(url)) + self._technician_configs.delete_technician_id_config(TechnicianIdConfig(technician_id)) - for url in new_config.technician_ids: - if url in old_config.technician_ids: + for technician_id in new_config.technician_ids: + user = self._bot.get_user(technician_id) + if user is None: + raise ValueError(f"Invalid technicianId") + + for technician_id in new_config.technician_ids: + if technician_id in old_config.technician_ids: continue - self._technician_configs.add_technician_id_config(TechnicianIdConfig(url)) + self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id)) diff --git a/kdb-web/package.json b/kdb-web/package.json index e9e0874b..d6381d85 100644 --- a/kdb-web/package.json +++ b/kdb-web/package.json @@ -51,4 +51,4 @@ "tslib": "^2.4.1", "typescript": "~4.9.5" } -} +} \ No newline at end of file diff --git a/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.html b/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.html index a710fa79..76707043 100644 --- a/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.html +++ b/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.html @@ -160,6 +160,100 @@ + +
+
+
+
+ {{'admin.settings.bot.ping_urls' | translate}}: +
+
+ + +
+
+ +
+
+
+ + + + + + + + + {{pingUrl.value}} + + + + +
+ + + + + +
+ + +
+
+
+
+
+
+ +
+
+
+ {{'admin.settings.bot.technicianIds' | translate}}: +
+
+ + +
+
+ +
+
+
+ + + + + + + + + {{technicianId.value}} + + + + +
+ + + + + +
+ + +
+
+
+
+
+
+
diff --git a/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.ts b/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.ts index d6030c26..c0cb39b8 100644 --- a/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.ts +++ b/kdb-web/src/app/modules/admin/settings/components/settings/settings.component.ts @@ -14,12 +14,20 @@ import { TechnicianConfig } from "../../../../../models/config/technician-config import { TechnicianConfigQuery } from "../../../../../models/graphql/query.model"; import { Queries } from "../../../../../models/graphql/queries.model"; import { DataService } from "../../../../../services/data/data.service"; -import { LevelMutationResult, TechnicianConfigMutationResult } from "../../../../../models/graphql/result.model"; +import { TechnicianConfigMutationResult } from "../../../../../models/graphql/result.model"; import { Mutations } from "../../../../../models/graphql/mutations.model"; import { AuthService } from "../../../../../services/auth/auth.service"; -import { ConfirmationDialogService } from "../../../../../services/confirmation-dialog/confirmation-dialog.service"; -import { SidebarService } from "../../../../../services/sidebar/sidebar.service"; -import { ActivatedRoute } from "@angular/router"; +import { Table } from "primeng/table"; + +type PingUrl = { + id: number; + value: string; +}; + +type TechnicianId = { + id: number; + value: string; +}; @Component({ selector: "app-settings", @@ -33,9 +41,12 @@ export class SettingsComponent implements OnInit { helpCommandReferenceUrl: [null, [Validators.required]], waitForRestart: [null, [Validators.required]], waitForShutdown: [null, [Validators.required]], - cacheMaxMessages: [null, [Validators.required]], - pingUrls: this.formBuilder.array([]) + cacheMaxMessages: [null, [Validators.required]] }); + pingUrls: PingUrl[] = []; + clonedPingUrls: { [s: number]: PingUrl } = {}; + technicianIds: TechnicianId[] = []; + clonedTechnicianIds: { [s: number]: TechnicianId } = {}; data: SettingsDTO = { webVersion: "", apiVersion: "", @@ -71,7 +82,7 @@ export class SettingsComponent implements OnInit { private toastService: ToastService, private translate: TranslateService, private authService: AuthService, - private spinner: SpinnerService, + private spinner: SpinnerService ) { } @@ -107,12 +118,18 @@ export class SettingsComponent implements OnInit { helpCommandReferenceUrl: [this.config.helpCommandReferenceUrl, [Validators.required]], waitForRestart: [this.config.waitForRestart, [Validators.required]], waitForShutdown: [this.config.waitForShutdown, [Validators.required]], - cacheMaxMessages: [this.config.cacheMaxMessages, [Validators.required]], - pingUrls: this.formBuilder.array([]) + cacheMaxMessages: [this.config.cacheMaxMessages, [Validators.required]] }); - const pingUrls = this.technicianConfigForm.controls["pingUrls"]; + let id = 0; for (const url of this.config.pingURLs ?? []) { - pingUrls.push(new FormControl(url, [Validators.required])); + this.pingUrls.push({ id: id, value: url }); + id++; + } + + id = 0; + for (const technicianId of this.config.technicianIds ?? []) { + this.technicianIds.push({ id: id, value: technicianId }); + id++; } } @@ -165,22 +182,93 @@ export class SettingsComponent implements OnInit { saveTechnicianConfig() { this.spinner.showSpinner(); - this.dataService.mutation(Mutations.updateTechnicianConfig, { - helpCommandReferenceUrl: this.config.helpCommandReferenceUrl, - waitForRestart: this.config.waitForRestart, - waitForShutdown: this.config.waitForShutdown, - cacheMaxMessages: this.config.cacheMaxMessages, - pingURLs: this.config.pingURLs, - technicianIds: this.config.technicianIds, - } - ).pipe(catchError(err => { - this.spinner.hideSpinner(); - this.toastService.error(this.translate.instant("admin.settings.message.technician_config_create_failed"), this.translate.instant("admin.settings.message.technician_config_create_failed_d")); - return throwError(err); - })).subscribe(result => { - this.spinner.hideSpinner(); - this.toastService.success(this.translate.instant("admin.settings.message.technician_config_create"), this.translate.instant("admin.settings.message.technician_config_create_d")); - }); + this.dataService.mutation(Mutations.updateTechnicianConfig, { + helpCommandReferenceUrl: this.config.helpCommandReferenceUrl, + waitForRestart: this.config.waitForRestart, + waitForShutdown: this.config.waitForShutdown, + cacheMaxMessages: this.config.cacheMaxMessages, + pingURLs: this.pingUrls.filter(value => value.value).map(value => { + return value.value; + }), + technicianIds: this.technicianIds.filter(value => value.value).map(value => { + return value.value; + }) + } + ).pipe(catchError(err => { + this.spinner.hideSpinner(); + this.toastService.error(this.translate.instant("admin.settings.message.technician_config_create_failed"), this.translate.instant("admin.settings.message.technician_config_create_failed_d")); + return throwError(err); + })).subscribe(result => { + this.spinner.hideSpinner(); + this.toastService.success(this.translate.instant("admin.settings.message.technician_config_create"), this.translate.instant("admin.settings.message.technician_config_create_d")); + }); + } + + pingUrlsAddNew(table: Table) { + const id = Math.max.apply(Math, this.pingUrls.map(url => { + return url.id ?? 0; + })) + 1; + const newItem = { id: id, value: "" }; + this.pingUrls.push(newItem); + + table.initRowEdit(newItem); + const index = this.pingUrls.findIndex(l => l.id == newItem.id); + this.pingUrlsEditInit(newItem, index); + } + + pingUrlsEditInit(url: PingUrl, index: number) { + this.clonedPingUrls[index] = { ...url }; + } + + pingUrlsDelete(index: number) { + this.pingUrls.splice(index, 1); + } + + pingUrlsEditSave(url: PingUrl, index: number) { + if (!url.value || this.pingUrls[index] == this.clonedPingUrls[index]) { + return; + } + + delete this.clonedPingUrls[index]; + } + + pingUrlsEditCancel(url: PingUrl, index: number) { + this.pingUrls[index] = this.clonedPingUrls[index]; + delete this.clonedPingUrls[index]; + } + + + technicianIdsAddNew(table: Table) { + const id = Math.max.apply(Math, this.technicianIds.map(url => { + return url.id ?? 0; + })) + 1; + const newItem = { id: id, value: "" }; + this.technicianIds.push(newItem); + + table.initRowEdit(newItem); + const index = this.technicianIds.findIndex(l => l.id == newItem.id); + this.technicianIdsEditInit(newItem, index); + } + + technicianIdsEditInit(url: PingUrl, index: number) { + this.clonedTechnicianIds[index] = { ...url }; + } + + technicianIdsDelete(index: number) { + this.technicianIds.splice(index, 1); + } + + technicianIdsEditSave(url: PingUrl, index: number) { + if (!url.value || this.technicianIds[index] == this.clonedTechnicianIds[index]) { + return; + } + + delete this.clonedTechnicianIds[index]; + } + + technicianIdsEditCancel(url: PingUrl, index: number) { + this.technicianIds[index] = this.clonedTechnicianIds[index]; + delete this.clonedTechnicianIds[index]; } } diff --git a/kdb-web/src/assets/config.json b/kdb-web/src/assets/config.json index 9d35b928..581bbcb8 100644 --- a/kdb-web/src/assets/config.json +++ b/kdb-web/src/assets/config.json @@ -25,4 +25,4 @@ "Name": "sh-edraft-dark-theme" } ] -} +} \ No newline at end of file