Added logic to edit technician config in WI #127
This commit is contained in:
parent
eac367c611
commit
8922524f44
@ -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}")
|
||||
|
@ -74,6 +74,6 @@ class TechnicianPingUrlConfig(TableABC):
|
||||
return str(
|
||||
f"""
|
||||
DELETE FROM `CFG_TechnicianPingUrls`
|
||||
WHERE `URL` = {self._ping_url};
|
||||
WHERE `URL` = '{self._ping_url}';
|
||||
"""
|
||||
)
|
||||
|
@ -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))
|
||||
|
@ -51,4 +51,4 @@
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "~4.9.5"
|
||||
}
|
||||
}
|
||||
}
|
@ -160,6 +160,100 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-divider"></div>
|
||||
<div class="content-row">
|
||||
<div class="content-column">
|
||||
<div class="content-data-name">
|
||||
{{'admin.settings.bot.ping_urls' | translate}}:
|
||||
</div>
|
||||
<div class="content-data-value-row">
|
||||
<p-table #dt [value]="pingUrls" dataKey="id" editMode="row">
|
||||
<ng-template pTemplate="caption">
|
||||
<div class="table-caption">
|
||||
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||
<button pButton class="icon-btn btn"
|
||||
icon="pi pi-plus" (click)="pingUrlsAddNew(dt)">
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template pTemplate="body" let-pingUrl let-editing="editing" let-ri="rowIndex">
|
||||
<tr [pEditableRow]="pingUrl">
|
||||
<td>
|
||||
<p-cellEditor>
|
||||
<ng-template pTemplate="input">
|
||||
<input class="table-edit-input" pInputText type="text" [(ngModel)]="pingUrl.value">
|
||||
</ng-template>
|
||||
<ng-template pTemplate="output">
|
||||
{{pingUrl.value}}
|
||||
</ng-template>
|
||||
</p-cellEditor>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-wrapper">
|
||||
<button *ngIf="!editing" pButton type="button" pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="pingUrlsEditInit(pingUrl, ri)"></button>
|
||||
<button *ngIf="!editing" pButton type="button" class="btn danger-icon-btn" icon="pi pi-trash" (click)="pingUrlsDelete(ri)"></button>
|
||||
|
||||
<button *ngIf="editing" pButton type="button" pSaveEditableRow class="btn icon-btn" icon="pi pi-check" (click)="pingUrlsEditSave(pingUrl, ri)"></button>
|
||||
<button *ngIf="editing" pButton type="button" pCancelEditableRow class="btn danger-icon-btn" icon="pi pi-times"
|
||||
(click)="pingUrlsEditCancel(pingUrl, ri)"></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</p-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-divider"></div>
|
||||
|
||||
<div class="content-row">
|
||||
<div class="content-column">
|
||||
<div class="content-data-name">
|
||||
{{'admin.settings.bot.technicianIds' | translate}}:
|
||||
</div>
|
||||
<div class="content-data-value-row">
|
||||
<p-table #dt [value]="technicianIds" dataKey="id" editMode="row">
|
||||
<ng-template pTemplate="caption">
|
||||
<div class="table-caption">
|
||||
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||
<button pButton class="icon-btn btn"
|
||||
icon="pi pi-plus" (click)="technicianIdsAddNew(dt)">
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template pTemplate="body" let-technicianId let-editing="editing" let-ri="rowIndex">
|
||||
<tr [pEditableRow]="technicianId">
|
||||
<td>
|
||||
<p-cellEditor>
|
||||
<ng-template pTemplate="input">
|
||||
<input class="table-edit-input" pInputText type="text" [(ngModel)]="technicianId.value">
|
||||
</ng-template>
|
||||
<ng-template pTemplate="output">
|
||||
{{technicianId.value}}
|
||||
</ng-template>
|
||||
</p-cellEditor>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-wrapper">
|
||||
<button *ngIf="!editing" pButton type="button" pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="technicianIdsEditInit(technicianId, ri)"></button>
|
||||
<button *ngIf="!editing" pButton type="button" class="btn danger-icon-btn" icon="pi pi-trash" (click)="technicianIdsDelete(ri)"></button>
|
||||
|
||||
<button *ngIf="editing" pButton type="button" pSaveEditableRow class="btn icon-btn" icon="pi pi-check" (click)="technicianIdsEditSave(technicianId, ri)"></button>
|
||||
<button *ngIf="editing" pButton type="button" pCancelEditableRow class="btn danger-icon-btn" icon="pi pi-times"
|
||||
(click)="technicianIdsEditCancel(technicianId, ri)"></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</p-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-divider"></div>
|
||||
|
||||
<div class="content-row">
|
||||
<button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn"
|
||||
(click)="saveTechnicianConfig()" [disabled]="technicianConfigForm.invalid"></button>
|
||||
|
@ -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 = <FormArray>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<TechnicianConfigMutationResult>(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<TechnicianConfigMutationResult>(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];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,4 +25,4 @@
|
||||
"Name": "sh-edraft-dark-theme"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user