1.0.0 #253

Merged
edraft merged 262 commits from 1.0.0 into master 2023-03-27 09:30:50 +02:00
11 changed files with 97 additions and 43 deletions
Showing only changes of commit 7d67b08ce6 - Show all commits

View File

@ -86,6 +86,17 @@ class User(TableABC):
def server(self) -> Optional[Server]:
return self._server
@property
@ServiceProviderABC.inject
def left_server(
self,
services: ServiceProviderABC,
) -> bool:
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
ujs: UserJoinedServerRepositoryABC = services.get_service(UserJoinedServerRepositoryABC)
return ujs.find_active_user_joined_server_by_user_id(self.id) is None
@staticmethod
def get_select_all_string() -> str:
return str(

View File

@ -31,7 +31,9 @@ class ServerFilter(FilterABC):
query = query.where(lambda x: x.id == self._id)
if self._discord_id is not None:
query = query.where(lambda x: x.discord_id == self._discord_id)
query = query.where(
lambda x: x.discord_id == self._discord_id or str(self._discord_id) in str(x.discord_id)
)
if self._name is not None:

View File

@ -73,7 +73,7 @@ class UserFilter(FilterABC):
def filter(self, query: List[User]) -> List[User]:
if self._id is not None:
query = query.where(lambda x: x.id == self._id or str(self._id) in str(x.id))
query = query.where(lambda x: x.id == self._id)
if self._discord_id is not None:
query = query.where(

View File

@ -91,5 +91,6 @@ class UserQuery(DataQueryABC):
def resolve_server(user: User, *_):
return user.server
def resolve_left_server(self, user: User, *_):
return self._ujs.find_active_user_joined_server_by_user_id(user.id) is None
@staticmethod
def resolve_left_server(user: User, *_):
return user.left_server

View File

@ -24,5 +24,5 @@ export interface UserDTO {
modifiedAt: string;
isTechnician: boolean;
isAdmin: boolean;
IsModerator: boolean;
isModerator: boolean;
}

View File

@ -61,6 +61,13 @@
</div>
</th>
<th class="table-header-actions" pSortableColumn="leftServer">
<div class="table-header-label">
<div class="table-header-text">{{'view.server.members.headers.left_server' | translate}}</div>
<p-sortIcon field="leftServer" class="table-header-icon"></p-sortIcon>
</div>
</th>
<th class="table-header-small-dropdown" pSortableColumn="level.name">
<div class="table-header-label">
<div class="table-header-text">{{'view.server.members.headers.level' | translate}}</div>
@ -92,6 +99,11 @@
</th>
<th></th>
<th></th>
<th>
<form [formGroup]="filterForm">
<p-dropdown formControlName="leftServer" [options]="leftServerOptions" placeholder="{{'view.server.members.headers.left_server' | translate}}"></p-dropdown>
</form>
</th>
<th>
<form [formGroup]="filterForm">
<p-dropdown formControlName="level" [options]="levels" placeholder="{{'view.server.members.headers.level' | translate}}"></p-dropdown>
@ -153,6 +165,16 @@
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
{{!member.leftServer | bool}}
</ng-template>
<ng-template pTemplate="output">
{{!member.leftServer | bool}}
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
@ -167,6 +189,7 @@
<div class="btn-wrapper">
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
(click)="onRowEditInit(dt, member, ri)"></button>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user" [routerLink]="member.id"></button>
<button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn"
icon="pi pi-check-circle" (click)="onRowEditSave(dt, member, ri)"></button>

View File

@ -29,6 +29,10 @@ export class MembersComponent {
members!: User[];
// levelsFilter!: MenuItem[];
levels!: MenuItem[];
leftServerOptions = [
{label: this.translate.instant('common.bool_as_string.true'), value: false},
{label: this.translate.instant('common.bool_as_string.false'), value: true},
];
loading = true;
clonedUsers: { [s: string]: User; } = {};
@ -60,12 +64,11 @@ export class MembersComponent {
id: FormControl<number | null>,
discordId: FormControl<number | null>,
name: FormControl<string | null>,
leftServer: FormControl<boolean | null>,
level: FormControl<number | null>
}>;
filter: UserFilter = {
leftServer: false
};
filter: UserFilter = {};
page: Page = {
pageSize: undefined,
pageIndex: undefined
@ -86,7 +89,7 @@ export class MembersComponent {
private translate: TranslateService,
private data: DataService,
private sidebar: SidebarService,
private route: ActivatedRoute,
private route: ActivatedRoute
) {
}
@ -110,12 +113,26 @@ export class MembersComponent {
this.loadNextPage();
}
loadNextPage() {
this.loading = true;
this.data.query<UserListQuery>(Queries.usersQuery, {
filter: this.filter, page: this.page, sort: this.sort
}
).subscribe(data => {
this.totalRecords = data.userCount;
this.members = data.users;
this.spinner.hideSpinner();
this.loading = false;
});
}
setFilterForm() {
this.filterForm = this.fb.group({
id: new FormControl<number | null>(null),
discordId: new FormControl<number | null>(null),
name: [""],
level: new FormControl<number | null>(null)
leftServer: new FormControl<boolean | null>(null),
level: new FormControl<number | null>(null),
});
this.filterForm.valueChanges.pipe(
@ -139,6 +156,12 @@ export class MembersComponent {
this.filter.name = undefined;
}
if (changes.leftServer !== undefined && changes.leftServer !== null) {
this.filter.leftServer = changes.leftServer;
} else {
this.filter.leftServer = undefined;
}
if (changes.level) {
this.filter.level = {
id: changes.level
@ -157,25 +180,12 @@ export class MembersComponent {
});
}
loadNextPage() {
this.loading = true;
this.data.query<UserListQuery>(Queries.usersQuery, {
filter: this.filter, page: this.page, sort: this.sort
}
).subscribe(data => {
this.totalRecords = data.userCount;
this.members = data.users;
this.spinner.hideSpinner();
this.loading = false;
});
}
nextPage(event: LazyLoadEvent) {
this.page.pageSize = event.rows ?? 0;
if (event.first != null && event.rows != null)
this.page.pageIndex = event.first / event.rows;
this.sort.sortColumn = event.sortField ?? undefined;
this.sort.sortDirection = event.sortOrder === 1 ? SortDirection.ASC : event.sortOrder === -1 ? SortDirection.DESC: SortDirection.ASC;
this.sort.sortDirection = event.sortOrder === 1 ? SortDirection.ASC : event.sortOrder === -1 ? SortDirection.DESC : SortDirection.ASC;
this.loadNextPage();
}

View File

@ -5,6 +5,11 @@ import { UserListQuery } from "../../../../models/graphql/query.model";
import { SpinnerService } from "../../../../services/spinner/spinner.service";
import { DataService } from "../../../../services/data/data.service";
import { User } from "../../../../models/data/user.model";
import { UserDTO } from "../../../../models/auth/auth-user.dto";
import { AuthService } from "src/app/services/auth/auth.service";
import { SidebarService } from "../../../../services/sidebar/sidebar.service";
import { ToastService } from "src/app/services/toast/toast.service";
import { TranslateService } from "@ngx-translate/core";
@Component({
selector: "app-profile",
@ -19,11 +24,15 @@ export class ProfileComponent implements OnInit {
private route: ActivatedRoute,
private router: Router,
private spinner: SpinnerService,
private data: DataService
private sidebar: SidebarService,
private data: DataService,
private auth: AuthService,
private toast: ToastService,
private translate: TranslateService
) {
}
ngOnInit() {
async ngOnInit() {
this.data.getServerFromRoute(this.route);
this.spinner.showSpinner();
@ -33,10 +42,18 @@ export class ProfileComponent implements OnInit {
return;
}
let authUser = await this.auth.getLoggedInUser();
let user: UserDTO | null = authUser?.users?.find(u => u.server == this.sidebar.server$.value?.id) ?? null;
if (!user || user?.id != this.route.snapshot.params["memberId"] && !user?.isModerator) {
this.toast.error(this.translate.instant("view.server.profile.permission_denied"), this.translate.instant("view.server.profile.permission_denied_d"));
this.router.navigate(["/server", this.sidebar.server$.value?.id]);
return;
}
this.data.query<User>(Queries.singleUserQuery, {
filter: {
id: this.route.snapshot.params["memberId"],
leftServer: false
id: this.route.snapshot.params["memberId"]
}
},
function(data: UserListQuery) {
@ -44,7 +61,6 @@ export class ProfileComponent implements OnInit {
}
).subscribe(user => {
this.user = user;
console.log(this.user);
this.spinner.hideSpinner();
});
}

View File

@ -44,18 +44,6 @@ export class DataService {
});
}
// query(query: string, variables: object = {}): Observable<QueryResult> {
// return this.http.post<QueryResult>(`${this.appsettings.getApiURL()}/api/graphql`,
// JSON.stringify({
// query, variables
// }), {
// headers: new HttpHeaders({
// "Content-Type": "application/json"
// })
// }
// );
// }
public query<T>(query: string, variables?: Variables, f?: Function): Observable<T> {
return this.http
.post<{ data: T }>(`${this.appsettings.getApiURL()}/api/graphql`, {

View File

@ -114,7 +114,7 @@ export class SidebarService {
if (this.server$.value) {
this.serverMenu.visible = true;
this.serverMembers.visible = !!user?.isAdmin;
this.serverMembers.visible = !!user?.isModerator;
} else {
this.serverMenu.visible = false;
}

View File

@ -182,7 +182,9 @@
"time": "Zeit",
"joined_at": "Beigetreten am",
"leaved_at": "Verlassen am"
}
},
"permission_denied": "Zugriff Verweigert!",
"permission_denied_d": "Du musst Moderator sein, um andere Profile sehen zu können!"
},
"members": {
"header": "Mitglieder",
@ -196,6 +198,7 @@
"name": "Name",
"xp": "XP",
"ontime": "Ontime",
"left_server": "Aktiv",
"level": "Level",
"actions": "Aktionen"
},