AutoRole #134 #222

Merged
edraft merged 8 commits from #134 into 1.0.0 2023-02-21 09:54:35 +01:00
20 changed files with 209 additions and 54 deletions
Showing only changes of commit a2dcbbc465 - Show all commits

View File

@ -32,7 +32,8 @@
"cpl-discord==2022.12.2"
],
"DevDependencies": [
"cpl-cli==2022.12.1.post3"
"cpl-cli==2022.12.1.post3",
"pygount==1.5.1"
],
"PythonVersion": ">=3.10.4",
"PythonPath": {},

@ -1 +1 @@
Subproject commit e3019156c058a93c092932dad75db39576bc55a7
Subproject commit 7986144705052ff38472a5d3f0776cb6c1752a55

@ -1 +1 @@
Subproject commit 81021418c21d45cee54478ab5fd69f9ce7261644
Subproject commit c712f856ebe30c71ac0b144045599ed2f91a1cba

View File

@ -63,7 +63,7 @@ class Query(QueryABC):
self.set_field("guilds", self._resolve_guilds)
def _resolve_guilds(self, *_, filter=None):
if filter is None and "id" not in filter:
if filter is None or "id" not in filter:
return self._bot.guilds
return self._bot.guilds.where(lambda g: g.id == int(filter["id"]))

View File

@ -14,4 +14,30 @@ export class Mutations {
}
}
`;
static createAutoRole = `
mutation updateAutoRole($serverId: ID, $channelId: String, $messageId: String) {
autoRole {
createAutoRole(input: { serverId: $serverId, channelId: $channelId, messageId: $messageId }) {
id
channelId
channelName
messageId
}
}
}
`;
static deleteAutoRole = `
mutation updateAutoRole($id: ID) {
autoRole {
deleteAutoRole(id: $id) {
id
channelId
channelName
messageId
}
}
}
`;
}

View File

@ -166,6 +166,10 @@ export class Queries {
messageId
autoRoleRuleCount
server {
id
}
createdAt
modifiedAt
}

View File

@ -2,6 +2,7 @@ import { Server } from "../data/server.model";
import { User } from "../data/user.model";
import { AutoRole } from "../data/auto_role.model";
import { Guild } from "../data/discord.model";
import { Level } from "../data/level.model";
export interface Query {
serverCount: number;
@ -19,7 +20,7 @@ export interface UserListQuery {
export interface LevelListQuery {
levelCount: number;
levels: User[];
levels: Level[];
}
export interface AutoRoleQuery {

View File

@ -1,4 +1,10 @@
import { User } from "../data/user.model";
import { AutoRole } from "../data/auto_role.model";
export interface GraphQLResult {
data: any;
errors?: [];
}
export interface QueryResult {
data: any;
@ -9,3 +15,10 @@ export interface UpdateUserMutationResult {
updateUser: User
};
}
export interface AutoRoleMutationResult {
autoRole: {
createAutoRole?: AutoRole
updateAutoRole?: AutoRole
deleteAutoRole?: AutoRole
};
}

View File

@ -20,6 +20,7 @@ import { IpAddressPipe } from './pipes/ip-address.pipe';
import { BoolPipe } from './pipes/bool.pipe';
import { PanelMenuModule } from 'primeng/panelmenu';
import { PanelModule } from "primeng/panel";
import { InputNumberModule } from 'primeng/inputnumber';
@ -49,6 +50,7 @@ import { PanelModule } from "primeng/panel";
DynamicDialogModule,
PanelMenuModule,
PanelModule,
InputNumberModule,
],
exports: [
ButtonModule,
@ -72,6 +74,7 @@ import { PanelModule } from "primeng/panel";
AuthRolePipe,
IpAddressPipe,
BoolPipe,
InputNumberModule,
]
})
export class SharedModule { }

View File

@ -1,10 +1,22 @@
import { Component } from '@angular/core';
import { Component, OnInit } from "@angular/core";
import { DataService } from "../../../../../../services/data/data.service";
import { ActivatedRoute } from "@angular/router";
@Component({
selector: 'app-auto-roles-rules',
templateUrl: './auto-roles-rules.component.html',
styleUrls: ['./auto-roles-rules.component.scss']
selector: "app-auto-roles-rules",
templateUrl: "./auto-roles-rules.component.html",
styleUrls: ["./auto-roles-rules.component.scss"]
})
export class AutoRolesRulesComponent {
export class AutoRolesRulesComponent implements OnInit {
constructor(
private data: DataService,
private route: ActivatedRoute,
) {
}
ngOnInit(): void {
this.data.getServerFromRoute(this.route);
}
}

View File

@ -18,7 +18,7 @@
<div class="table-caption-btn-wrapper btn-wrapper">
<button pButton label="{{'admin.auth_users.add' | translate}}" class="icon-btn btn"
icon="pi pi-user-plus" (click)="addUser(dt)" [disabled]="isEditingNew">
icon="pi pi-user-plus" (click)="addAutoRole(dt)" [disabled]="isEditingNew">
</button>
<button pButton label="{{'view.server.auto_roles.reset_filters' | translate}}" icon="pi pi-undo"
class="icon-btn btn" (click)="resetFilters()">
@ -126,8 +126,7 @@
<td>
<p-cellEditor>
<ng-template pTemplate="input">
{{autoRole.channelId}}
<p-dropdown [options]="channels" [(ngModel)]="autoRole.channelName" placeholder="{{'view.server.members.headers.level' | 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 pTemplate="output">
{{autoRole.channelId}}
@ -149,7 +148,7 @@
<td>
<p-cellEditor>
<ng-template pTemplate="input">
{{autoRole.messageId}}
<input pInputText class="table-edit-input" [(ngModel)]="autoRole.messageId">
</ng-template>
<ng-template pTemplate="output">
{{autoRole.messageId}}
@ -192,14 +191,16 @@
<td>
<div class="btn-wrapper">
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
(click)="onRowEditInit(dt, autoRole, ri)"></button>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user" [routerLink]="[autoRole.id, 'rules']"></button>
<!-- <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"-->
<!-- (click)="onRowEditInit(dt, autoRole, ri)"></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"
(click)="deleteAutoRole(autoRole)"></button>
<button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn"
icon="pi pi-check-circle" (click)="onRowEditSave(dt, autoRole, ri)"></button>
<button *ngIf="editing" pButton pCancelEditableRow class="btn icon-btn danger-icon-btn"
icon="pi pi-times-circle" (click)="onRowEditCancel(autoRole, ri)"></button>
icon="pi pi-times-circle" (click)="onRowEditCancel(ri)"></button>
</div>
</td>
</tr>

View File

@ -16,7 +16,7 @@ import { AutoRoleQuery, SingleDiscordQuery } from "../../../../../../models/grap
import { Queries } from "../../../../../../models/graphql/queries.model";
import { catchError, debounceTime } from "rxjs/operators";
import { Table } from "primeng/table";
import { UpdateUserMutationResult } from "../../../../../../models/graphql/result.model";
import { AutoRoleMutationResult } from "../../../../../../models/graphql/result.model";
import { Mutations } from "../../../../../../models/graphql/mutations.model";
import { throwError } from "rxjs";
import { AutoRole, AutoRoleFilter } from "../../../../../../models/data/auto_role.model";
@ -87,7 +87,9 @@ export class AutoRolesComponent implements OnInit {
this.guild = data.guilds[0];
this.channels = this.guild.channels
.filter(x => x.type === ChannelType.text)
.map(x => {return {value: x.name, label: x.id}});
.map(x => {
return { label: x.name, value: x };
});
this.spinner.hideSpinner();
});
@ -167,48 +169,39 @@ export class AutoRolesComponent implements OnInit {
this.filterForm.reset();
}
onRowEditInit(table: Table, user: User, index: number) {
this.clonedUsers[index] = { ...user };
onRowEditInit(table: Table, autoRole: AutoRole, index: number) {
this.clonedUsers[index] = { ...autoRole };
}
onRowEditSave(table: Table, newUser: User, index: number) {
// const oldUser = this.clonedUsers[index];
// delete this.clonedUsers[index];
// if (JSON.stringify(oldUser) === JSON.stringify(newUser) && !this.isEditingNew) {
// console.log(1, oldUser, newUser, JSON.stringify(oldUser) === JSON.stringify(newUser), !this.isEditingNew);
// return;
// }
if (this.isEditingNew && JSON.stringify(newUser) === JSON.stringify(this.newAutoRoleTemplate)) {
onRowEditSave(table: Table, newAutoRole: AutoRole, index: number) {
if (this.isEditingNew && JSON.stringify(newAutoRole) === JSON.stringify(this.newAutoRoleTemplate)) {
this.isEditingNew = false;
this.auto_roles.splice(index, 1);
return;
}
if (!newUser.id || !newUser.xp && !newUser.level?.id) {
if (!newAutoRole.id || !newAutoRole.channelId && !newAutoRole.messageId) {
return;
}
this.spinner.showSpinner();
this.data.mutation<UpdateUserMutationResult>(Mutations.updateUser, {
id: newUser.id,
xp: newUser.xp,
levelId: newUser.level?.id
this.data.mutation<AutoRoleMutationResult>(Mutations.createAutoRole, {
serverId: this.sidebar.server$.value?.id,
channelId: newAutoRole.channelId,
messageId: newAutoRole.messageId
}
).pipe(catchError(err => {
this.spinner.hideSpinner();
this.toastService.error(this.translate.instant("view.server.members.message.user_change_failed"), this.translate.instant("view.server.members.message.user_change_failed_d", { name: newUser.name }));
this.toastService.error(this.translate.instant("view.server.auto_roles.message.auto_role_create_failed"), this.translate.instant("view.server.auto_roles.message.auto_role_create_failed_d"));
return throwError(err);
})).subscribe(_ => {
})).subscribe(result => {
this.spinner.hideSpinner();
this.toastService.success(this.translate.instant("view.server.members.message.user_changed"), this.translate.instant("view.server.members.message.user_changed_d", { name: newUser.name }));
this.toastService.success(this.translate.instant("view.server.auto_roles.message.auto_role_created"), this.translate.instant("view.server.auto_roles.message.auto_role_create_d", { id: result.autoRole.createAutoRole?.id }));
this.loadNextPage();
});
}
onRowEditCancel(user: User, index: number) {
onRowEditCancel(index: number) {
if (this.isEditingNew) {
this.auto_roles.splice(index, 1);
delete this.clonedUsers[index];
@ -220,7 +213,29 @@ export class AutoRolesComponent implements OnInit {
delete this.clonedUsers[index];
}
addUser(table: Table) {
deleteAutoRole(autoRole: AutoRole) {
this.confirmDialog.confirmDialog(
this.translate.instant("view.server.auto_roles.message.auto_role_delete"), this.translate.instant("view.server.auto_roles.message.auto_role_delete_q", { id: autoRole.id }),
() => {
this.spinner.showSpinner();
this.data.mutation<AutoRoleMutationResult>(Mutations.deleteAutoRole, {
id: autoRole.id
}
).pipe(catchError(err => {
this.spinner.hideSpinner();
this.toastService.error(this.translate.instant("view.server.auto_roles.message.auto_role_delete_failed"), this.translate.instant("view.server.auto_roles.message.auto_role_delete_failed_d", { id: autoRole.id }));
return throwError(err);
})).subscribe(_ => {
this.spinner.hideSpinner();
this.toastService.success(this.translate.instant("view.server.auto_roles.message.auto_role_deleted"), this.translate.instant("view.server.auto_roles.message.auto_role_deleted_d", { id: autoRole.id }));
this.loadNextPage();
});
});
}
addAutoRole(table: Table) {
const newAutoRole = JSON.parse(JSON.stringify(this.newAutoRoleTemplate));
newAutoRole.id = Math.max.apply(Math, this.auto_roles.map(u => {
return u.id ?? 0;

View File

@ -163,7 +163,8 @@
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<input class="table-edit-input" pInputText type="number" min="0" [(ngModel)]="member.xp">
<p-inputNumber class="table-edit-input" styleClass="input-number" [(ngModel)]="member.xp" mode="decimal" [min]="0" [useGrouping]="false" [showButtons]="true"
inputId="minmax-buttons"></p-inputNumber>
</ng-template>
<ng-template pTemplate="output">
{{member.xp}}

View File

@ -9,6 +9,7 @@ import { Queries } from "../../models/graphql/queries.model";
import { Query } from "../../models/graphql/query.model";
import { SidebarService } from "../sidebar/sidebar.service";
import { SpinnerService } from "../spinner/spinner.service";
import { GraphQLResult } from "../../models/graphql/result.model";
@Injectable({
providedIn: "root"
@ -20,7 +21,7 @@ export class DataService {
private http: HttpClient,
private sidebar: SidebarService,
private spinner: SpinnerService,
private router: Router,
private router: Router
) {
}
@ -28,7 +29,7 @@ export class DataService {
this.spinner.showSpinner();
if (!route.snapshot.params["serverId"]) {
this.spinner.hideSpinner();
this.router.navigate(['/dashboard']);
this.router.navigate(["/dashboard"]);
return;
}
@ -46,21 +47,31 @@ export class DataService {
public query<T>(query: string, variables?: Variables, f?: Function): Observable<T> {
return this.http
.post<{ data: T }>(`${this.appsettings.getApiURL()}/api/graphql`, {
.post<GraphQLResult>(`${this.appsettings.getApiURL()}/api/graphql`, {
query: query,
variables: variables
})
.pipe(map((d) => d.data))
.pipe(map(d => {
if (d.errors && d.errors.length > 0) {
throw new Error(d.errors.toString());
}
return d.data;
}))
.pipe(map((d) => f ? f(d) : d));
}
public mutation<T>(query: string, variables?: object, f?: Function): Observable<T> {
return this.http
.post<{ data: T }>(`${this.appsettings.getApiURL()}/api/graphql`, {
.post<GraphQLResult>(`${this.appsettings.getApiURL()}/api/graphql`, {
query: query,
variables: variables
})
.pipe(map((d) => d.data))
.pipe(map(d => {
if (d.errors && d.errors.length > 0) {
throw new Error(d.errors.toString());
}
return d.data;
}))
.pipe(map((d) => f ? f(d) : d));
}

View File

@ -236,10 +236,16 @@
},
"no_entries_found": "Keine Einträge gefunden",
"message": {
"user_changed": "Benutzer geändert",
"user_changed_d": "Benutzer {{name}} erfolgreich geändert",
"user_change_failed": "Benutzer änderung fehlgeschlagen",
"user_change_failed_d": "Benutzer {{name}} konnte nicht geändert werden!"
"auto_role_create": "Auto Rolle erstellt",
"auto_role_create_d": "Auto Rolle {{id}} erfolgreich erstellt",
"auto_role_create_failed": "Auto Rolle Erstellung fehlgeschlagen",
"auto_role_create_failed_d": "Die Erstellung der Auto Rolle ist fehlgeschlagen!",
"auto_role_delete": "Auto Rolle löschen",
"auto_role_delete_q": "Sind Sie sich sicher, dass Sie die Auto Rolle {{id}} löschen möchten?",
"auto_role_deleted": "Auto Rolle gelöscht",
"auto_role_deleted_d": "Auto Rolle {{id}} erfolgreich gelöscht",
"auto_role_delete_failed": "Auto Rolle Löschung fehlgeschlagen",
"auto_role_delete_failed_d": "Die Löschung der Auto Rolle {{id}} ist fehlgeschlagen!"
}
}
},

View File

@ -97,6 +97,11 @@ p-table {
}
}
.p-dropdown,
.p-inputnumber {
width: 100% !important;
}
.pi-sort-alt:before {
content: "\e915" !important;
}

View File

@ -580,4 +580,18 @@
background-color: $primaryBackgroundColor !important;
color: $primaryHeaderColor !important;
}
.input-number {
span {
.p-button {
background-color: $primaryHeaderColor !important;
border: 1px solid $primaryHeaderColor !important;
&:hover {
background-color: $secondaryHeaderColor !important;
border: 1px solid $secondaryHeaderColor !important;
}
}
}
}
}

View File

@ -580,4 +580,18 @@
background-color: $primaryBackgroundColor !important;
color: $primaryHeaderColor !important;
}
.input-number {
span {
.p-button {
background-color: $primaryHeaderColor !important;
border: 1px solid $primaryHeaderColor !important;
&:hover {
background-color: $secondaryHeaderColor !important;
border: 1px solid $secondaryHeaderColor !important;
}
}
}
}
}

View File

@ -582,4 +582,18 @@
background-color: $primaryBackgroundColor !important;
color: $primaryHeaderColor !important;
}
.input-number {
span {
.p-button {
background-color: $primaryHeaderColor !important;
border: 1px solid $primaryHeaderColor !important;
&:hover {
background-color: $secondaryHeaderColor !important;
border: 1px solid $secondaryHeaderColor !important;
}
}
}
}
}

View File

@ -580,4 +580,18 @@
background-color: $primaryBackgroundColor !important;
color: $primaryHeaderColor !important;
}
.input-number {
span {
.p-button {
background-color: $primaryHeaderColor !important;
border: 1px solid $primaryHeaderColor !important;
&:hover {
background-color: $secondaryHeaderColor !important;
border: 1px solid $secondaryHeaderColor !important;
}
}
}
}
}