Added technician config to frontend #127

This commit is contained in:
Sven Heidemann 2023-08-07 14:59:19 +02:00
parent 33ed4328a1
commit e0896700e7
12 changed files with 351 additions and 157 deletions

View File

@ -1,12 +1,12 @@
{ {
"name": "kdb-web", "name": "kdb-web",
"version": "1.0.dev251", "version": "1.0.dev127_config_in_wi",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "kdb-web", "name": "kdb-web",
"version": "1.0.dev251", "version": "1.0.dev127_config_in_wi",
"dependencies": { "dependencies": {
"@angular/animations": "^15.1.4", "@angular/animations": "^15.1.4",
"@angular/common": "^15.1.4", "@angular/common": "^15.1.4",
@ -21,6 +21,7 @@
"@ngx-translate/core": "^14.0.0", "@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0", "@ngx-translate/http-loader": "^7.0.0",
"@types/socket.io-client": "^3.0.0", "@types/socket.io-client": "^3.0.0",
"primeflex": "^3.3.1",
"primeicons": "^6.0.1", "primeicons": "^6.0.1",
"primeng": "^15.2.0", "primeng": "^15.2.0",
"rxjs": "~7.5.0", "rxjs": "~7.5.0",
@ -9302,6 +9303,11 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/primeflex": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/primeflex/-/primeflex-3.3.1.tgz",
"integrity": "sha512-zaOq3YvcOYytbAmKv3zYc+0VNS9Wg5d37dfxZnveKBFPr7vEIwfV5ydrpiouTft8MVW6qNjfkaQphHSnvgQbpQ=="
},
"node_modules/primeicons": { "node_modules/primeicons": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-6.0.1.tgz", "resolved": "https://registry.npmjs.org/primeicons/-/primeicons-6.0.1.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "kdb-web", "name": "kdb-web",
"version": "1.0.dev268_achievements", "version": "1.0.dev127_config_in_wi",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"update-version": "ts-node-esm update-version.ts", "update-version": "ts-node-esm update-version.ts",
@ -30,6 +30,7 @@
"@ngx-translate/core": "^14.0.0", "@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0", "@ngx-translate/http-loader": "^7.0.0",
"@types/socket.io-client": "^3.0.0", "@types/socket.io-client": "^3.0.0",
"primeflex": "^3.3.1",
"primeicons": "^6.0.1", "primeicons": "^6.0.1",
"primeng": "^15.2.0", "primeng": "^15.2.0",
"rxjs": "~7.5.0", "rxjs": "~7.5.0",

View File

@ -0,0 +1,11 @@
import { DataWithHistory } from "../data/data.model";
export interface TechnicianConfig extends DataWithHistory {
id?: number;
helpCommandReferenceUrl?: string;
waitForRestart?: number;
waitForShutdown?: number;
cacheMaxMessages?: number;
pingURLs?: string[];
technicianIds?: string[];
}

View File

@ -165,4 +165,30 @@ export class Mutations {
} }
} }
`; `;
static updateTechnicianConfig = `
mutation updateTechnicianConfig($id: ID, $helpCommandReferenceUrl: String, $waitForRestart: Int, $waitForShutdown: Int, $cacheMaxMessages: Int, $pingURLs: [String], $technicianIds: [String]) {
technicianConfig {
updateTechnicianConfig(input: {
id: $id,
helpCommandReferenceUrl: $helpCommandReferenceUrl,
waitForRestart: $waitForRestart,
waitForShutdown: $waitForShutdown,
cacheMaxMessages: $cacheMaxMessages,
pingURLs: $pingURLs,
technicianIds: $technicianIds
}) {
id
helpCommandReferenceUrl
waitForRestart
waitForShutdown
cacheMaxMessages
pingURLs
technicianIds
}
}
}
`;
} }

View File

@ -1,5 +1,22 @@
export class Queries { export class Queries {
static technicianConfigQuery = `
query technicianConfigQuery {
technicianConfig {
id
helpCommandReferenceUrl
waitForRestart
waitForShutdown
cacheMaxMessages
pingURLs
technicianIds
createdAt
modifiedAt
}
}
`;
static guildsQuery = ` static guildsQuery = `
query GuildsQuery($id: ID) { query GuildsQuery($id: ID) {
guilds(filter: {id: $id}) { guilds(filter: {id: $id}) {

View File

@ -4,12 +4,17 @@ import { AutoRole, AutoRoleRule } from "../data/auto_role.model";
import { Guild } from "../data/discord.model"; import { Guild } from "../data/discord.model";
import { Level } from "../data/level.model"; import { Level } from "../data/level.model";
import { Achievement, AchievementAttribute } from "../data/achievement.model"; import { Achievement, AchievementAttribute } from "../data/achievement.model";
import { TechnicianConfig } from "../config/technician-config.model";
export interface Query { export interface Query {
serverCount: number; serverCount: number;
servers: Server[]; servers: Server[];
} }
export interface TechnicianConfigQuery {
technicianConfig: TechnicianConfig;
}
export interface SingleDiscordQuery { export interface SingleDiscordQuery {
guilds: Guild[]; guilds: Guild[];
} }

View File

@ -3,6 +3,7 @@ import { AutoRole, AutoRoleRule } from "../data/auto_role.model";
import { Level } from "../data/level.model"; import { Level } from "../data/level.model";
import { Server } from "../data/server.model"; import { Server } from "../data/server.model";
import { Achievement } from "../data/achievement.model"; import { Achievement } from "../data/achievement.model";
import { TechnicianConfig } from "../config/technician-config.model";
export interface GraphQLResult { export interface GraphQLResult {
data: { data: {
@ -47,6 +48,12 @@ export interface LevelMutationResult {
}; };
} }
export interface TechnicianConfigMutationResult {
technicianConfig: {
updateTechnicianConfig?: TechnicianConfig
};
}
export interface AchievementMutationResult { export interface AchievementMutationResult {
achievement: { achievement: {
createAchievement?: Achievement createAchievement?: Achievement

View File

@ -1,125 +1,168 @@
<h1> <h1>
{{'admin.settings.header' | translate}} {{'admin.settings.header' | translate}}
</h1> </h1>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content-header"> <div class="content-header">
<h2> <h2>
{{'admin.settings.website.header' | translate}} {{'admin.settings.website.header' | translate}}
</h2> </h2>
</div>
<div class="content">
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.frontend_version' | translate}}:</div>
<div class="content-data-value">{{data.webVersion}}</div>
</div>
</div> </div>
<div class="content"> <div class="content-row">
<div class="content-row"> <div class="content-column">
<div class="content-column"> <div class="content-data-name">{{'admin.settings.website.backend_version' | translate}}:</div>
<div class="content-data-name">{{'admin.settings.website.frontend_version' | translate}}:</div> <div class="content-data-value">{{data.apiVersion}}</div>
<div class="content-data-value">{{data.webVersion}}</div> </div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.backend_version' | translate}}:</div>
<div class="content-data-value">{{data.apiVersion}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.config_path' | translate}}:</div>
<div class="content-data-value">{{data.configPath}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.frontend_base_url' | translate}}:</div>
<div class="content-data-value">{{data.webBaseURL}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.backend_base_url' | translate}}:</div>
<div class="content-data-value">{{data.apiBaseURL}}</div>
</div>
</div>
<div class="content-divider"></div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.token_expire_time' | translate}}:</div>
<div class="content-data-value">{{data.tokenExpireTime}} {{'general.minutes' | translate}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.refresh_token_expire_time' | translate}}:</div>
<div class="content-data-value">{{data.refreshTokenExpireTime}} {{'general.days' | translate}}</div>
</div>
</div>
</div> </div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.config_path' | translate}}:</div>
<div class="content-data-value">{{data.configPath}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.frontend_base_url' | translate}}:</div>
<div class="content-data-value">{{data.webBaseURL}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.backend_base_url' | translate}}:</div>
<div class="content-data-value">{{data.apiBaseURL}}</div>
</div>
</div>
<div class="content-divider"></div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.token_expire_time' | translate}}:</div>
<div class="content-data-value">{{data.tokenExpireTime}} {{'general.minutes' | translate}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.website.refresh_token_expire_time' | translate}}:</div>
<div class="content-data-value">{{data.refreshTokenExpireTime}} {{'general.days' | translate}}</div>
</div>
</div>
</div>
</div> </div>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content-header"> <div class="content-header">
<h2> <h2>
{{'admin.settings.email.header' | translate}} {{'admin.settings.email.header' | translate}}
</h2> </h2>
</div>
<div class="content">
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.user' | translate}}:</div>
<div class="content-data-value">{{data.mailUser}}</div>
</div>
</div> </div>
<div class="content"> <div class="content-row">
<div class="content-row"> <div class="content-column">
<div class="content-column"> <div class="content-data-name">{{'admin.settings.email.host' | translate}}:</div>
<div class="content-data-name">{{'admin.settings.email.user' | translate}}:</div> <div class="content-data-value">{{data.mailHost}}</div>
<div class="content-data-value">{{data.mailUser}}</div> </div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.host' | translate}}:</div>
<div class="content-data-value">{{data.mailHost}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.port' | translate}}:</div>
<div class="content-data-value">{{data.mailPort}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.transceiver' | translate}}:</div>
<div class="content-data-value">{{data.mailTransceiver}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.email_address' | translate}}:</div>
<div class="content-data-value">{{data.mailTransceiverAddress}}</div>
</div>
</div>
<div class="content-row">
<form [formGroup]="testMailForm" class="content-column">
<div class="content-data-name">
<div class="input-field content-input-field">
<input type="email" pInputText formControlName="mail" placeholder="{{'common.email' | translate}}" autocomplete="email">
</div>
</div>
<div class="content-data-value">
<div class="login-form-submit">
<button pButton icon="pi pi-save" label="{{'common.email' | translate}}" class="btn login-form-submit-btn"
(click)="testMail()" [disabled]="testMailForm.invalid"></button>
</div>
</div>
</form>
</div>
</div> </div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.port' | translate}}:</div>
<div class="content-data-value">{{data.mailPort}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.transceiver' | translate}}:</div>
<div class="content-data-value">{{data.mailTransceiver}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.email.email_address' | translate}}:</div>
<div class="content-data-value">{{data.mailTransceiverAddress}}</div>
</div>
</div>
<div class="content-row">
<form [formGroup]="testMailForm" class="content-column">
<div class="content-data-name">
<div class="input-field content-input-field">
<input type="email" pInputText formControlName="mail" placeholder="{{'common.email' | translate}}" autocomplete="email">
</div>
</div>
<div class="content-data-value">
<div class="login-form-submit">
<button pButton icon="pi pi-send" label="{{'common.email' | translate}}" class="btn login-form-submit-btn"
(click)="testMail()" [disabled]="testMailForm.invalid"></button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="content-wrapper">
<div class="content-header">
<h2>
{{'admin.settings.bot.header' | translate}}
</h2>
</div>
<div class="content">
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.bot.help_url' | translate}}:</div>
<input class="content-data-value" type="text" pInputText [(ngModel)]="config.helpCommandReferenceUrl" placeholder="{{'admin.settings.bot.help_url' | translate}}">
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.bot.wait_for_restart' | translate}}:</div>
<input class="content-data-value" type="number" pInputText [(ngModel)]="config.waitForRestart" placeholder="{{'admin.settings.bot.wait_for_restart' | translate}}">
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.bot.wait_for_shutdown' | translate}}:</div>
<input class="content-data-value" type="number" pInputText [(ngModel)]="config.waitForShutdown" placeholder="{{'admin.settings.bot.wait_for_shutdown' | translate}}">
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'admin.settings.bot.cache_max_messages' | translate}}:</div>
<input class="content-data-value" type="number" pInputText [(ngModel)]="config.cacheMaxMessages" placeholder="{{'admin.settings.bot.cache_max_messages' | translate}}">
</div>
</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>
</div>
</div>
</div> </div>

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms";
import { TranslateService } from "@ngx-translate/core"; import { TranslateService } from "@ngx-translate/core";
import { catchError } from "rxjs/operators"; import { catchError } from "rxjs/operators";
import { SettingsDTO } from "src/app/models/config/settings.dto"; import { SettingsDTO } from "src/app/models/config/settings.dto";
@ -9,66 +9,111 @@ import { GuiService } from "src/app/services/gui/gui.service";
import { SettingsService } from "src/app/services/settings/settings.service"; import { SettingsService } from "src/app/services/settings/settings.service";
import { SpinnerService } from "src/app/services/spinner/spinner.service"; import { SpinnerService } from "src/app/services/spinner/spinner.service";
import { ToastService } from "src/app/services/toast/toast.service"; import { ToastService } from "src/app/services/toast/toast.service";
import { throwError } from "rxjs"; import { forkJoin, throwError } from "rxjs";
import { TechnicianConfig } from "../../../../../models/config/technician-config.model";
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 { 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";
@Component({ @Component({
selector: 'app-settings', selector: "app-settings",
templateUrl: './settings.component.html', templateUrl: "./settings.component.html",
styleUrls: ['./settings.component.scss'] styleUrls: ["./settings.component.scss"]
}) })
export class SettingsComponent implements OnInit { export class SettingsComponent implements OnInit {
testMailForm!: FormGroup; testMailForm!: FormGroup;
technicianConfigForm: FormGroup = this.formBuilder.group({
helpCommandReferenceUrl: [null, [Validators.required]],
waitForRestart: [null, [Validators.required]],
waitForShutdown: [null, [Validators.required]],
cacheMaxMessages: [null, [Validators.required]],
pingUrls: this.formBuilder.array([])
});
data: SettingsDTO = { data: SettingsDTO = {
webVersion: '', webVersion: "",
apiVersion: '', apiVersion: "",
configPath: '', configPath: "",
webBaseURL: '', webBaseURL: "",
apiBaseURL: '', apiBaseURL: "",
tokenExpireTime: 0, tokenExpireTime: 0,
refreshTokenExpireTime: 0, refreshTokenExpireTime: 0,
mailUser: '', mailUser: "",
mailPort: 0, mailPort: 0,
mailHost: '', mailHost: "",
mailTransceiver: '', mailTransceiver: "",
mailTransceiverAddress: '', mailTransceiverAddress: ""
};
config: TechnicianConfig = {
helpCommandReferenceUrl: "",
waitForRestart: 0,
waitForShutdown: 0,
cacheMaxMessages: 0,
pingURLs: [],
technicianIds: []
}; };
constructor( constructor(
private dataService: DataService,
private settingsService: SettingsService, private settingsService: SettingsService,
private spinnerService: SpinnerService, private spinnerService: SpinnerService,
private guiService: GuiService, private guiService: GuiService,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private toastService: ToastService, private toastService: ToastService,
private translate: TranslateService private translate: TranslateService,
) { } private authService: AuthService,
private spinner: SpinnerService,
) {
}
ngOnInit(): void { ngOnInit(): void {
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
this.initForms(); this.initForms();
this.guiService.getSettings() forkJoin([
.pipe(catchError(error => { this.guiService.getSettings().pipe(catchError(error => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
return throwError(() => error); return throwError(() => error);
})) })),
.subscribe(settings => { this.dataService.query<TechnicianConfigQuery>(Queries.technicianConfigQuery)
this.spinnerService.hideSpinner(); ]).subscribe(data => {
this.data = settings; this.data = data[0];
this.data.webVersion = this.settingsService.getWebVersion()?.getVersionString() ?? '0.0.0'; this.data.webVersion = this.settingsService.getWebVersion()?.getVersionString() ?? "0.0.0";
this.data.apiBaseURL = this.settingsService.getApiURL(); this.data.apiBaseURL = this.settingsService.getApiURL();
if (!this.data.apiBaseURL.endsWith('/')) { if (!this.data.apiBaseURL.endsWith("/")) {
this.data.apiBaseURL += '/'; this.data.apiBaseURL += "/";
} }
});
this.config = data[1].technicianConfig;
this.initForms();
this.spinnerService.hideSpinner();
});
} }
initForms(): void { initForms(): void {
this.testMailForm = this.formBuilder.group({ this.testMailForm = this.formBuilder.group({
mail: [null, [Validators.required, Validators.email]], mail: [null, [Validators.required, Validators.email]]
}); });
this.technicianConfigForm = this.formBuilder.group({
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([])
});
const pingUrls = <FormArray>this.technicianConfigForm.controls["pingUrls"];
for (const url of this.config.pingURLs ?? []) {
pingUrls.push(new FormControl(url, [Validators.required]));
}
} }
testMail(): void { testMail(): void {
@ -82,27 +127,27 @@ export class SettingsComponent implements OnInit {
this.guiService.sendTestMail(mail) this.guiService.sendTestMail(mail)
.pipe(catchError(error => { .pipe(catchError(error => {
let header = this.translate.instant('admin.settings.message.error'); let header = this.translate.instant("admin.settings.message.error");
let message = this.translate.instant('admin.settings.message.could_not_send_mail'); let message = this.translate.instant("admin.settings.message.could_not_send_mail");
if (error.error !== null) { if (error.error !== null) {
const err: ErrorDTO = error.error; const err: ErrorDTO = error.error;
if (err.errorCode === ServiceErrorCode.ConnectionFailed) { if (err.errorCode === ServiceErrorCode.ConnectionFailed) {
header = this.translate.instant('admin.settings.message.connection_failed'); header = this.translate.instant("admin.settings.message.connection_failed");
message = this.translate.instant('admin.settings.message.connection_to_mail_failed'); message = this.translate.instant("admin.settings.message.connection_to_mail_failed");
error.error = null; error.error = null;
} }
if (err.errorCode === ServiceErrorCode.InvalidUser) { if (err.errorCode === ServiceErrorCode.InvalidUser) {
header = this.translate.instant('admin.settings.message.connection_failed'); header = this.translate.instant("admin.settings.message.connection_failed");
message = this.translate.instant('admin.settings.message.mail_login_failed'); message = this.translate.instant("admin.settings.message.mail_login_failed");
error.error = null; error.error = null;
} }
if (err.errorCode === ServiceErrorCode.MailError) { if (err.errorCode === ServiceErrorCode.MailError) {
header = this.translate.instant('admin.settings.message.send_failed'); header = this.translate.instant("admin.settings.message.send_failed");
message = this.translate.instant('admin.settings.message.test_mail_not_send'); message = this.translate.instant("admin.settings.message.test_mail_not_send");
error.error = null; error.error = null;
} }
} }
@ -113,9 +158,29 @@ export class SettingsComponent implements OnInit {
})) }))
.subscribe(res => { .subscribe(res => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
this.toastService.success(this.translate.instant('admin.settings.message.success'), this.translate.instant('admin.settings.message.send_mail')); this.toastService.success(this.translate.instant("admin.settings.message.success"), this.translate.instant("admin.settings.message.send_mail"));
this.testMailForm.reset(); this.testMailForm.reset();
}); });
} }
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"));
});
}
} }

View File

@ -24,6 +24,7 @@ import { InputNumberModule } from "primeng/inputnumber";
import { ImageModule } from "primeng/image"; import { ImageModule } from "primeng/image";
import { SidebarModule } from "primeng/sidebar"; import { SidebarModule } from "primeng/sidebar";
import { HistoryBtnComponent } from './components/history-btn/history-btn.component'; import { HistoryBtnComponent } from './components/history-btn/history-btn.component';
import { DataViewModule, DataViewLayoutOptions } from 'primeng/dataview';
@NgModule({ @NgModule({
@ -56,6 +57,7 @@ import { HistoryBtnComponent } from './components/history-btn/history-btn.compon
InputNumberModule, InputNumberModule,
ImageModule, ImageModule,
SidebarModule, SidebarModule,
DataViewModule,
], ],
exports: [ exports: [
ButtonModule, ButtonModule,
@ -82,7 +84,9 @@ import { HistoryBtnComponent } from './components/history-btn/history-btn.compon
InputNumberModule, InputNumberModule,
ImageModule, ImageModule,
SidebarModule, SidebarModule,
HistoryBtnComponent HistoryBtnComponent,
DataViewModule,
DataViewLayoutOptions
] ]
}) })
export class SharedModule { } export class SharedModule { }

View File

@ -5,7 +5,7 @@
"WebVersion": { "WebVersion": {
"Major": "1", "Major": "1",
"Minor": "0", "Minor": "0",
"Micro": "dev268_achievements" "Micro": "dev127_config_in_wi"
}, },
"Themes": [ "Themes": [
{ {

View File

@ -177,6 +177,14 @@ header {
font-size: 18px; font-size: 18px;
} }
.content-data-value-row {
display: flex;
flex: 1;
flex-direction: column;
font-size: 18px;
}
.content-divider { .content-divider {
margin: 5px 0; margin: 5px 0;
} }
@ -477,6 +485,7 @@ footer {
.right { .right {
width: 50%; width: 50%;
text-align: right; text-align: right;
.p-button-label { .p-button-label {
font-weight: unset !important; font-weight: unset !important;
} }