Merge pull request 'Als Nutzer des WI möchte ich nicht, dass Tabellen mit vielen Daten so lange laden #300' (#312) from #300 into support

Reviewed-on: sh-edraft.de/kd_discord_bot#312
Reviewed-by: edraft-dev <dev.sven.heidemann@sh-edraft.de>
Closes #300
This commit is contained in:
Sven Heidemann 2023-04-14 23:25:39 +02:00
commit 400e54a501
14 changed files with 147 additions and 32 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "kdb-web", "name": "kdb-web",
"version": "1.0.5", "version": "1.0.7",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"update-version": "ts-node-esm update-version.ts", "update-version": "ts-node-esm update-version.ts",

View File

@ -23,17 +23,6 @@ export interface User extends DataWithHistory {
userJoinedGameServerCount?: number; userJoinedGameServerCount?: number;
userJoinedGameServers?: UserJoinedGameServer[]; userJoinedGameServers?: UserJoinedGameServer[];
// history?: UserHistory[];
}
export interface UserHistory extends History {
id?: number;
discordId?: number;
xp?: number;
level?: number;
server?: number;
leftServer?: boolean;
} }
export interface UserFilter { export interface UserFilter {

View File

@ -62,6 +62,17 @@ export class Queries {
} }
createdAt createdAt
modifiedAt modifiedAt
}
}
}
`;
static levelWithHistoryQuery = `
query LevelHistory($serverId: ID, $id: ID) {
servers(filter: {id: $serverId}) {
levelCount
levels(filter: {id: $id}) {
id
history { history {
id id
@ -94,6 +105,29 @@ export class Queries {
name name
} }
leftServer leftServer
createdAt
modifiedAt
}
}
}
`;
static userProfile = `
query UserProfile($serverId: ID, $userId: ID, $page: Page, $sort: Sort) {
servers(filter: {id: $serverId}) {
userCount
users(filter: {id: $userId}, page: $page, sort: $sort) {
id
discordId
name
xp
ontime
level {
id
name
}
leftServer
server { server {
id id
name name
@ -124,9 +158,17 @@ export class Queries {
joinedOn joinedOn
leavedOn leavedOn
} }
}
}
}
`;
createdAt static userQueryWithHistory = `
modifiedAt query UsersWithHistory($serverId: ID, $id: ID) {
servers(filter: {id: $serverId}) {
userCount
users(filter: {id: $id}) {
id
history { history {
id id
@ -159,6 +201,17 @@ export class Queries {
createdAt createdAt
modifiedAt modifiedAt
}
}
}
`;
static autoRolesWithHistoryQuery = `
query AutoRoleWithHistoryQuery($serverId: ID, $id: ID) {
servers(filter: {id: $serverId}) {
autoRoleCount
autoRoles(filter: {id: $id}) {
id
history { history {
id id
@ -191,6 +244,19 @@ export class Queries {
createdAt createdAt
modifiedAt modifiedAt
}
}
}
}
`;
static autoRoleRulesHistoryQuery = `
query AutoRoleRuleHistoryQuery($serverId: ID, $autoRoleId: ID, $id: ID) {
servers(filter: {id: $serverId}) {
autoRoles(filter: {id: $autoRoleId}) {
autoRoleRuleCount
autoRoleRules(filter: {id: $id}) {
id
history { history {
id id

View File

@ -1,5 +1,16 @@
import { Component, Input, OnInit } from "@angular/core"; import { Component, Input, OnInit } from "@angular/core";
import { History } from "../../../../models/data/data.model"; import { History } from "../../../../models/data/data.model";
import { UserListQuery } from "../../../../models/graphql/query.model";
import { Server } from "../../../../models/data/server.model";
import { DataService } from "../../../../services/data/data.service";
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 } from "@angular/forms";
import { TranslateService } from "@ngx-translate/core";
import { ActivatedRoute } from "@angular/router";
import { SidebarService } from "../../../../services/sidebar/sidebar.service";
@Component({ @Component({
selector: "app-history-btn", selector: "app-history-btn",
@ -8,19 +19,62 @@ import { History } from "../../../../models/data/data.model";
}) })
export class HistoryBtnComponent implements OnInit { export class HistoryBtnComponent implements OnInit {
@Input() history: History[] = []; @Input() id: number = 0;
@Input() query: string = "";
@Input() translationKey: string = ""; @Input() translationKey: string = "";
public showSidebar: boolean = false; public history: History[] = [];
public constructor() { public showSidebar: boolean = false;
private server: Server = {};
public constructor(
private authService: AuthService,
private spinner: SpinnerService,
private toastService: ToastService,
private confirmDialog: ConfirmationDialogService,
private fb: FormBuilder,
private translate: TranslateService,
private data: DataService,
private route: ActivatedRoute,
private sidebar: SidebarService
) {
} }
public ngOnInit(): void { public ngOnInit(): void {
this.server = this.sidebar.server$.value ?? {};
}
private findVal(object: any, key: string) {
var value;
Object.keys(object).some((k: string) => {
if (k === key) {
value = object[k];
return true;
}
if (object[k] && typeof object[k] === "object") {
value = this.findVal(object[k], key);
return value !== undefined;
}
return null;
});
return value;
} }
public openHistory(): void { public openHistory(): void {
this.showSidebar = true; this.showSidebar = true;
this.data.query<UserListQuery>(this.query, {
serverId: this.server.id, id: this.id
},
(x: { servers: Server[] }) => {
return x.servers[0];
}
).subscribe(data => {
this.history = this.findVal(data, "history") ?? [];
this.spinner.hideSpinner();
});
let oldHistory: Partial<History> = {}; let oldHistory: Partial<History> = {};
for (const history of this.history) { for (const history of this.history) {
const attributes = Object.keys(history).map((key) => { const attributes = Object.keys(history).map((key) => {

View File

@ -160,7 +160,7 @@
<td> <td>
<div class="btn-wrapper"> <div class="btn-wrapper">
<app-history-btn *ngIf="!isEditingNew" [history] ="autoRoleRule.history" translationKey="view.server.auto_roles.rules.header"></app-history-btn> <app-history-btn *ngIf="!isEditingNew" [id] ="autoRoleRule.id" [query]="query" translationKey="view.server.auto_roles.rules.header"></app-history-btn>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="onRowEditInit(dt, autoRoleRule, ri)"></button> <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="onRowEditInit(dt, autoRoleRule, ri)"></button>
<button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash" <button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"
(click)="deleteAutoRoleRule(autoRoleRule)"></button> (click)="deleteAutoRoleRule(autoRoleRule)"></button>

View File

@ -1,4 +1,4 @@
import { Component, OnDestroy, OnInit } from "@angular/core"; import { Component, OnDestroy, OnInit, Query } from "@angular/core";
import { DataService } from "../../../../../../services/data/data.service"; import { DataService } from "../../../../../../services/data/data.service";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute, Router } from "@angular/router";
import { AutoRoleRule, AutoRoleRuleFilter } from "../../../../../../models/data/auto_role.model"; import { AutoRoleRule, AutoRoleRuleFilter } from "../../../../../../models/data/auto_role.model";
@ -66,6 +66,8 @@ export class AutoRolesRulesComponent implements OnInit, OnDestroy {
private unsubscriber = new Subject<void>(); private unsubscriber = new Subject<void>();
private server: Server = {}; private server: Server = {};
query: string = Queries.autoRoleRulesHistoryQuery;
constructor( constructor(
private authService: AuthService, private authService: AuthService,
private spinner: SpinnerService, private spinner: SpinnerService,

View File

@ -126,7 +126,8 @@
<td> <td>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<p-dropdown [options]="channels" optionValue="value.id" [(ngModel)]="autoRole.channelId" placeholder="{{'view.server.auto_roles.headers.channel_id' | translate}}"></p-dropdown> <p-dropdown [options]="channels" optionValue="value.id" [(ngModel)]="autoRole.channelId"
placeholder="{{'view.server.auto_roles.headers.channel_id' | translate}}"></p-dropdown>
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{autoRole.channelId}} {{autoRole.channelId}}
@ -193,7 +194,7 @@
<div class="btn-wrapper"> <div class="btn-wrapper">
<!-- <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"--> <!-- <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"-->
<!-- (click)="onRowEditInit(dt, autoRole, ri)"></button>--> <!-- (click)="onRowEditInit(dt, autoRole, ri)"></button>-->
<app-history-btn *ngIf="!isEditingNew" [history] ="autoRole.history" translationKey="view.server.auto_roles.header"></app-history-btn> <app-history-btn *ngIf="!isEditingNew" [id]="autoRole.id" [query]="query" translationKey="view.server.auto_roles.header"></app-history-btn>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-sliders-h" [routerLink]="[autoRole.id, 'rules']"></button> <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-sliders-h" [routerLink]="[autoRole.id, 'rules']"></button>
<button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash" <button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"
(click)="deleteAutoRole(autoRole)"></button> (click)="deleteAutoRole(autoRole)"></button>

View File

@ -63,6 +63,8 @@ export class AutoRolesComponent implements OnInit, OnDestroy {
private unsubscriber = new Subject<void>(); private unsubscriber = new Subject<void>();
private server: Server = {}; private server: Server = {};
query: string = Queries.autoRolesWithHistoryQuery;
constructor( constructor(
private authService: AuthService, private authService: AuthService,
private spinner: SpinnerService, private spinner: SpinnerService,

View File

@ -184,7 +184,7 @@
</td> </td>
<td> <td>
<div class="btn-wrapper"> <div class="btn-wrapper">
<app-history-btn *ngIf="!isEditingNew" [history] ="level.history" translationKey="view.server.levels.header"></app-history-btn> <app-history-btn *ngIf="!isEditingNew" [id]="level.id" [query]="query" translationKey="view.server.levels.header"></app-history-btn>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
(click)="onRowEditInit(dt, level, ri)" [disabled]="!user || user.isModerator && !user.isAdmin"></button> (click)="onRowEditInit(dt, level, ri)" [disabled]="!user || user.isModerator && !user.isAdmin"></button>
<button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash" <button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"

View File

@ -61,6 +61,8 @@ export class LevelsComponent implements OnInit, OnDestroy {
private server: Server = {}; private server: Server = {};
public user: UserDTO | null = null; public user: UserDTO | null = null;
query: string = Queries.levelWithHistoryQuery;
public constructor( public constructor(
private authService: AuthService, private authService: AuthService,
private spinner: SpinnerService, private spinner: SpinnerService,

View File

@ -224,7 +224,7 @@
</td> </td>
<td> <td>
<div class="btn-wrapper"> <div class="btn-wrapper">
<app-history-btn *ngIf="!isEditingNew" [history] ="member.history" translationKey="view.server.members.header"></app-history-btn> <app-history-btn *ngIf="!isEditingNew" [id]="member.id" [query]="query" translationKey="view.server.members.header"></app-history-btn>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
(click)="onRowEditInit(dt, member, ri)"></button> (click)="onRowEditInit(dt, member, ri)"></button>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user" <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user"

View File

@ -81,6 +81,7 @@ export class MembersComponent implements OnInit, OnDestroy {
totalRecords!: number; totalRecords!: number;
private unsubscriber = new Subject<void>(); private unsubscriber = new Subject<void>();
private server: Server = {}; private server: Server = {};
query = Queries.userQueryWithHistory;
constructor( constructor(
private authService: AuthService, private authService: AuthService,

View File

@ -55,11 +55,9 @@ export class ProfileComponent implements OnInit, OnDestroy {
return; return;
} }
this.data.query<UserListQuery>(Queries.usersQuery, { this.data.query<UserListQuery>(Queries.userProfile, {
serverId: this.server.id, serverId: this.server.id,
filter: { userId: params["memberId"]
id: params["memberId"]
}
}, },
(x: { servers: Server[] }) => { (x: { servers: Server[] }) => {
return x.servers[0]; return x.servers[0];

View File

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