Browse Source

реворк фильтров поиска

master
gsd 3 weeks ago
parent
commit
f7f59f4571
  1. 16
      src/app/app.module.ts
  2. 54
      src/app/entities/search/BanSearchFilter.ts
  3. 11
      src/app/entities/search/MessageSearchFilter.ts
  4. 74
      src/app/entities/search/SearchFilter.ts
  5. 109
      src/app/pages/banlist-page/banlist-page.component.html
  6. 20
      src/app/pages/banlist-page/banlist-page.component.scss
  7. 58
      src/app/pages/banlist-page/banlist-page.component.ts
  8. 88
      src/app/pages/internal-components/abstract-search-table.component.ts
  9. 28
      src/app/pages/internal-components/search-filters/FilterMatChipBanId.ts
  10. 26
      src/app/pages/internal-components/search-filters/FilterMatChipMessage.ts
  11. 28
      src/app/pages/internal-components/search-filters/base/FilterMatChipAccount.ts
  12. 29
      src/app/pages/internal-components/search-filters/base/FilterMatChipDateBegin.ts
  13. 29
      src/app/pages/internal-components/search-filters/base/FilterMatChipDateEnd.ts
  14. 34
      src/app/pages/internal-components/search-filters/base/FilterMatChipServer.ts
  15. 116
      src/app/pages/messages-page/messages-page.component.html
  16. 30
      src/app/pages/messages-page/messages-page.component.ts
  17. 13
      src/app/services/ban.service.ts
  18. 6
      src/app/services/message.service.ts

16
src/app/app.module.ts

@ -42,19 +42,33 @@ import {MatSelectModule} from "@angular/material/select";
import {MatDatepickerModule} from "@angular/material/datepicker"; import {MatDatepickerModule} from "@angular/material/datepicker";
import {MatNativeDateModule} from "@angular/material/core"; import {MatNativeDateModule} from "@angular/material/core";
import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; import {MatProgressSpinnerModule} from "@angular/material/progress-spinner";
import {FilterMatChipAccount} from "./pages/internal-components/search-filters/base/FilterMatChipAccount";
import {FilterMatChipMessage} from "./pages/internal-components/search-filters/FilterMatChipMessage";
import {FilterMatChipServer} from "./pages/internal-components/search-filters/base/FilterMatChipServer";
import {FilterMatChipDateBegin} from "./pages/internal-components/search-filters/base/FilterMatChipDateBegin";
import {FilterMatChipDateEnd} from "./pages/internal-components/search-filters/base/FilterMatChipDateEnd";
import {FilterMatChipBanId} from "./pages/internal-components/search-filters/FilterMatChipBanId";
registerLocaleData(localeRu, "ru") registerLocaleData(localeRu, "ru")
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
//pages
MainPageComponent, MainPageComponent,
ServersPageComponent, ServersPageComponent,
ProfilePageComponent, ProfilePageComponent,
NeedAuthToContinue, NeedAuthToContinue,
RulesPageComponent, RulesPageComponent,
BanlistPageComponent, BanlistPageComponent,
MessagesPageComponent MessagesPageComponent,
//search filters
FilterMatChipAccount,
FilterMatChipMessage,
FilterMatChipServer,
FilterMatChipDateBegin,
FilterMatChipDateEnd,
FilterMatChipBanId
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

54
src/app/entities/search/BanSearchFilter.ts

@ -0,0 +1,54 @@
import {SearchFilter} from "./SearchFilter";
import {MatPaginator} from "@angular/material/paginator";
import {ParamMap} from "@angular/router";
export class BanSearchFilter extends SearchFilter{
ban_ids: number[]|null = null;
active: boolean|null = null;
admin_ids: string[]|null = null;
override createQuery(paginator:MatPaginator|undefined): { [p: string]: any } {
let q:{[param: string]: any} = super.createQuery(paginator);
q["ban_ids"] = this.ban_ids?this.ban_ids.join(","):null;
q["active"] = this.active != null? this.active: null;
q["admin_ids"] = this.admin_ids?this.admin_ids.join(","):null;
return q;
}
override fromQuery(param: ParamMap,paginator:MatPaginator|undefined) {
try {if (param.get("ban_ids")) { // @ts-ignore
this.message = param.get("ban_ids")?.split(",");}}catch (e) {}
try {if (param.get("active")) { // @ts-ignore
this.message = param.get("active");}}catch (e) {}
try {if (param.get("admin_ids")) { // @ts-ignore
this.message = param.get("admin_ids")?.split(",");}}catch (e) {}
super.fromQuery(param, paginator);
}
changeBanIdToSearch(prev: number, name: any) {
if (this.ban_ids == null)
this.ban_ids = [];
this.ban_ids = this.ban_ids.filter(v => v !== prev);
if (this.ban_ids.indexOf(name.target.value) == -1)
this.ban_ids.push(name.target.value);
this.updated = true;
}
addBanIdToSearch(name: number) {
if (this.ban_ids == null)
this.ban_ids = [];
if (this.ban_ids.indexOf(name) == -1)
this.ban_ids.push(name);
this.updated = true;
}
removeBanIdFromSearch(name: number) {
if (this.ban_ids == null) return;
this.ban_ids = this.ban_ids.filter(v => v !== name);
this.updated = true;
}
}

11
src/app/entities/search/MessageSearchFilter.ts

@ -17,4 +17,15 @@ export class MessageSearchFilter extends SearchFilter {
this.message = param.get("message");}}catch (e) {} this.message = param.get("message");}}catch (e) {}
super.fromQuery(param, paginator); super.fromQuery(param, paginator);
} }
addMessageToSearch(name: any) {
this.message = name;
this.updated = true;
}
removeMessageFromSearch() {
this.message = null;
this.updated = true;
}
} }

74
src/app/entities/search/SearchFilter.ts

@ -11,7 +11,7 @@ export class SearchFilter implements ISearchFilter {
createQuery(paginator:MatPaginator|undefined):{[param: string]: any} { createQuery(paginator:MatPaginator|undefined):{[param: string]: any} {
let q: {[param: string]: any} = {}; let q: {[param: string]: any} = {};
q["accounts"] = this.accounts?this.accounts.join(","):null; q["accounts"] = this.accounts && this.accounts.length>0?this.accounts.join(","):null;
q["begin"] = this.begin?this.begin.getTime():null; q["begin"] = this.begin?this.begin.getTime():null;
q["end"] = this.end?this.end.getTime():null; q["end"] = this.end?this.end.getTime():null;
q["serverId"] = this.serverId; q["serverId"] = this.serverId;
@ -40,4 +40,76 @@ export class SearchFilter implements ISearchFilter {
try {if (param.get("size") && paginator) { // @ts-ignore try {if (param.get("size") && paginator) { // @ts-ignore
paginator.pageSize = param.get("size")*1;}}catch (e) {} paginator.pageSize = param.get("size")*1;}}catch (e) {}
} }
//accounts
changeAccountToSearch(prev: string, name: any) {
//tak nado
if (this.accounts == null)
this.accounts = [];
this.accounts = this.accounts.filter(v => v !== prev);
if (this.accounts.indexOf(name.target.value) == -1)
this.accounts.push(name.target.value);
this.updated = true;
}
addAccountToSearch(name: string) {
if (this.accounts == null)
this.accounts = [];
if (this.accounts.indexOf(name) == -1)
this.accounts.push(name);
this.updated = true;
}
removeAccountFromSearch(name: string) {
if (this.accounts == null) return;
this.accounts = this.accounts.filter(v => v !== name);
this.updated = true;
}
//begindate
addBeginTimeToSearch(custom_date: any = null) {
if (custom_date == null) {
const d: Date = new Date();
d.setUTCHours(0, 0, 0, 0);
this.begin = d;
}
else this.begin = new Date(custom_date);
this.updated = true;
}
removeBeginTimeFromSearch() {
this.begin = null;
this.updated = true;
}
//enddate
addEndTimeToSearch(custom_date: number|null = null) {
if (custom_date == null) {
const d: Date = new Date();
d.setUTCHours(23, 59, 59, 999);
this.end = d;
}
else this.end = new Date(custom_date);
this.updated = true;
}
removeEndTimeFromSearch() {
this.end = null;
this.updated = true;
}
//server
addServerToSearch(server_id: string|null = null) {
this.serverId = server_id == null ? "%" : server_id;
if (server_id != null) {
this.updated = true;
}
}
removeServerFromSearch() {
this.serverId = null;
this.updated = true;
}
} }

109
src/app/pages/banlist-page/banlist-page.component.html

@ -1,25 +1,102 @@
<div class="content-in-center-header" style="flex-direction: column;"> <div class="content-in-center-header" style="flex-direction: column;">
<h1>Бан лист</h1> <h1>Бан лист</h1>
<h3>Скоро и ты сюда попадешь браток {{total==0?'':'как и остальные ' + total + ' карликов'}}</h3> <h3>Скоро и ты сюда попадешь браток {{getCount()==undefined?'':'как и остальные ' + getCount() + ' карликов'}}</h3>
</div> </div>
<div class="content-in-center"> <div class="content-in-center">
<div class="content-in-border"> <div class="content-in-border">
<app-need-auth-to-continue *ngIf="authService.steamdata == null && loading == null"></app-need-auth-to-continue> <app-need-auth-to-continue *ngIf="!authService.isAuth()"></app-need-auth-to-continue>
<div *ngIf="loading == false"> <div *ngIf="authService.isAuth">
<mat-accordion> <div style="padding-bottom: 10px;">
<mat-expansion-panel *ngFor="let ban of bans"> <mat-chip-list>
<mat-expansion-panel-header> <mat-chip [matMenuTriggerFor]="addFilter">Искать по...</mat-chip>
<mat-panel-title> <mat-menu #addFilter>
<p>#{{ban.id}} {{ban.player_name}}</p> <button mat-menu-item (click)="filter.addAccountToSearch('')">Профилю</button>
</mat-panel-title> <button mat-menu-item [matMenuTriggerFor]="timeSelect">Времени</button>
<mat-panel-description> </mat-menu>
<p>{{ban.timestamp | date:'dd/MM/YYYY hh:mm:ss'}}</p> <mat-menu #timeSelect>
</mat-panel-description> <button mat-menu-item (click)="filter.addEndTimeToSearch()">До ...</button>
</mat-expansion-panel-header> <button mat-menu-item (click)="filter.addBeginTimeToSearch()">После ...</button>
<p>А хуй знает я еще не приудмал</p> </mat-menu>
</mat-expansion-panel>
</mat-accordion> <mat-chip *ngIf="filter.updated" (click)="updateData()">Обновить</mat-chip>
<app-filter-mat-chip-account
[filter]="filter"
></app-filter-mat-chip-account>
<app-filter-mat-chip-date-begin
[filter]="filter">
</app-filter-mat-chip-date-begin>
<app-filter-mat-chip-date-end
[filter]="filter">
</app-filter-mat-chip-date-end>
<app-filter-mat-chip-banid
[filter]="filter">
</app-filter-mat-chip-banid>
</mat-chip-list>
</div>
<div>
<div class="loading-shade"
*ngIf="loading || err">
<mat-spinner *ngIf="loading"></mat-spinner>
<div class="err" *ngIf="err">
Слишком много запросов или сервер не отвечает, обнови страницу.
<br>
<button mat-button (click)="err=false; loading=false">Закрыть</button>
</div>
</div>
<table mat-table [dataSource]="dataSource" style="width: 100%">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> ID бана </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="banIdMenu"> {{row.id}}
<mat-menu #banIdMenu><button mat-menu-item (click)="filter.addBanIdToSearch(row.id)">Искать по ид</button></mat-menu></td>
</ng-container>
<ng-container matColumnDef="player_name">
<th mat-header-cell *matHeaderCellDef> Имя игрока </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="accountMenu"> {{row.player_name}}
<mat-menu #accountMenu>
<button mat-menu-item (click)="filter.addAccountToSearch(row.player_name)">Добавить в поиск</button>
<button mat-menu-item (click)="searchPlayer(row.account_id)">Открыть профиль</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef> Время </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="dateMenu"> {{row.timestamp | date:"HH:mm dd/MM/yyyy"}}
<mat-menu #dateMenu>
<button mat-menu-item (click)="filter.addEndTimeToSearch(row.timestamp)">Искать до {{row.timestamp | date:"HH:mm:ss dd/MM/yyyy"}}</button>
<button mat-menu-item (click)="filter.addBeginTimeToSearch(row.timestamp)">Искать после {{row.timestamp | date:"HH:mm:ss dd/MM/yyyy"}}</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="reason">
<th mat-header-cell *matHeaderCellDef> Причина </th>
<td mat-cell *matCellDef="let row"> {{row.ban_reason}}</td>
</ng-container>
<ng-container matColumnDef="admin_name">
<th mat-header-cell *matHeaderCellDef> Модератор </th>
<td mat-cell *matCellDef="let row"> {{row.banned_by}}</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef> Действие </th>
<td mat-cell *matCellDef="let row"> пук</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<!-- Row shown when there is no matching data. -->
<div *ngIf="!loading">
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">Бан лист пуст</td>
</tr>
</div>
</table>
<mat-paginator
[pageSizeOptions]="[5, 10, 25, 100]"
[pageSize]="10"
(page)="updateData()"
></mat-paginator>
</div>
</div> </div>
</div> </div>
</div> </div>

20
src/app/pages/banlist-page/banlist-page.component.scss

@ -0,0 +1,20 @@
.loading-shade {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.15);
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
}
.err {
max-width: 360px;
text-align: center;
background: white;
border-radius: 15px;
border: 0px solid black;
}

58
src/app/pages/banlist-page/banlist-page.component.ts

@ -2,35 +2,63 @@ import { Component, OnInit } from '@angular/core';
import {AuthService} from "../../services/auth.service"; import {AuthService} from "../../services/auth.service";
import {BanService} from "../../services/ban.service"; import {BanService} from "../../services/ban.service";
import {Ban} from "../../entities/ban/Ban"; import {Ban} from "../../entities/ban/Ban";
import {AbstractSearchTable} from "../internal-components/abstract-search-table.component";
import {BanSearchFilter} from "../../entities/search/BanSearchFilter";
import {ServerService} from "../../services/server.service";
import {PlayerService} from "../../services/player.service";
import {ActivatedRoute, Router} from "@angular/router";
import {MatTableDataSource} from "@angular/material/table";
@Component({ @Component({
selector: 'app-banlist-page', selector: 'app-banlist-page',
templateUrl: './banlist-page.component.html', templateUrl: './banlist-page.component.html',
styleUrls: ['./banlist-page.component.scss'] styleUrls: ['./banlist-page.component.scss']
}) })
export class BanlistPageComponent implements OnInit { export class BanlistPageComponent extends AbstractSearchTable<Ban, BanSearchFilter>{
loading: boolean | null = null;
bans: Ban[] = [];
total: number = 0;
constructor(public authService: AuthService, displayedColumns: string[] = ['id', 'player_name', 'date', 'reason', 'admin_name', 'action'];
constructor(public override authService: AuthService,
protected override serverService: ServerService,
protected override playerService: PlayerService,
protected override router: Router,
protected override route: ActivatedRoute,
private banService: BanService) { private banService: BanService) {
super(authService, serverService, playerService, route, router);
super.filter = new BanSearchFilter();
} }
ngOnInit(): void { private getBanList(): boolean {
if (this.authService.isAuth()) { this.filter.updated = false;
this.loading = true;
this.banService.getBanList(this.filter, this.paginator).subscribe(
(res) => {
this.dataSource = new MatTableDataSource<Ban>(res.data);
this.err = false;
}, (e) => this.err = true, () => this.loading = false
)
return true;
}
override updateData() {
super.updateData();
this.getBanList(); this.getBanList();
} }
addAdminIdToSearch(name: string) {
if (this.filter.admin_ids == null)
this.filter.admin_ids = [];
if (this.filter.admin_ids.indexOf(name) == -1)
this.filter.admin_ids.push(name);
this.filter.updated = true;
} }
getBanList() { removeAdminIdFromSearch(name: string) {
this.loading = true; if (this.filter.admin_ids == null) return;
this.banService.getBanList().subscribe( this.filter.admin_ids = this.filter.admin_ids.filter(v => v !== name);
(res) => { this.filter.updated = true;
this.bans = res.data;
this.total = res.count;
}, () => {}, () => this.loading = false
)
} }
getCount() {
return this.paginator?.length;
}
} }

88
src/app/pages/internal-components/abstract-search-table.component.ts

@ -7,6 +7,8 @@ import {MatSort} from "@angular/material/sort";
import {SearchFilter} from "../../entities/search/SearchFilter"; import {SearchFilter} from "../../entities/search/SearchFilter";
import {ServerService} from "../../services/server.service"; import {ServerService} from "../../services/server.service";
import {ActivatedRoute, Router} from "@angular/router"; import {ActivatedRoute, Router} from "@angular/router";
import {AuthService} from "../../services/auth.service";
import {PlayerService} from "../../services/player.service";
@Component({template: ''}) @Component({template: ''})
export abstract class AbstractSearchTable<T,U extends SearchFilter> implements AfterViewInit { export abstract class AbstractSearchTable<T,U extends SearchFilter> implements AfterViewInit {
@ -20,7 +22,9 @@ export abstract class AbstractSearchTable<T,U extends SearchFilter> implements A
err: boolean = false; err: boolean = false;
protected constructor(protected serverService: ServerService, protected constructor(protected authService: AuthService,
protected serverService: ServerService,
protected playerService: PlayerService,
protected route: ActivatedRoute, protected route: ActivatedRoute,
protected router: Router) { protected router: Router) {
this.filter = new SearchFilter() as U; this.filter = new SearchFilter() as U;
@ -49,79 +53,17 @@ export abstract class AbstractSearchTable<T,U extends SearchFilter> implements A
) )
} }
changeAccountToSearch(prev: string, name: any) { searchPlayer(account_id: number) {
this.removeAccountFromSearch(prev); if (!this.authService.isAuth()) {
this.addAccountToSearch(name.target.value); return;
this.filter.updated = true;
} }
addAccountToSearch(name: string) { this.playerService.searchProfile(`[U:1:${account_id}]`).subscribe(
if (this.filter.accounts == null) (res) => {
this.filter.accounts = []; if (res.steam64 != null)
if (this.filter.accounts.indexOf(name) == -1) this.router.navigate(['profile', res.steam64])
this.filter.accounts.push(name); },
this.filter.updated = true; (err) => {}
} )
removeAccountFromSearch(name: string) {
if (this.filter.accounts == null) return;
this.filter.accounts = this.filter.accounts.filter(v => v !== name);
this.filter.updated = true;
}
addServerToSearch(server_id: string|null = null) {
this.filter.serverId = server_id == null ? "%" : server_id;
if (server_id != null) {
this.filter.updated = true;
}
}
removeServerFromSearch() {
this.filter.serverId = null;
this.filter.updated = true;
}
getServerName(server_id: string|null) {
try {
// @ts-ignore
return this.serverList.filter(s => s.server_id == server_id).pop().name;
} catch (e) {
return "Выбрать сервер";
}
}
addBeginTimeToSearch(custom_date: any = null) {
if (custom_date == null) {
const d: Date = new Date();
d.setUTCHours(0, 0, 0, 0);
this.filter.begin = d;
}
else this.filter.begin = new Date(custom_date);
this.filter.updated = true;
}
removeBeginTimeFromSearch() {
this.filter.begin = null;
this.filter.updated = true;
}
addEndTimeToSearch(custom_date: number|null = null) {
if (custom_date == null) {
const d: Date = new Date();
d.setUTCHours(23, 59, 59, 999);
this.filter.end = d;
}
else this.filter.end = new Date(custom_date);
this.filter.updated = true;
}
removeEndTimeFromSearch() {
this.filter.end = null;
this.filter.updated = true;
}
filterChanges(event:any) {
this.filter.updated = true;
} }
} }

28
src/app/pages/internal-components/search-filters/FilterMatChipBanId.ts

@ -0,0 +1,28 @@
import {Component, Input} from "@angular/core";
import {BanSearchFilter} from "../../../entities/search/BanSearchFilter";
@Component({
selector: "app-filter-mat-chip-banid",
template: `
<div *ngIf="filter && filter.ban_ids != null">
<mat-chip
*ngFor="let acId of filter.ban_ids"
(removed)="filter.removeBanIdFromSearch(acId)"
[matMenuTriggerFor]="profileSearch">Ид: {{acId}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #profileSearch>
<mat-form-field appearance="fill" (click)="$event.stopPropagation()">
<mat-label>Ид бана без #</mat-label>
<input matInput placeholder="228" type="number" [ngModel]="acId" (change)="filter.changeBanIdToSearch(acId, $event)">
</mat-form-field>
</mat-menu>
</mat-chip>
</div>`
})
export class FilterMatChipBanId {
@Input("filter")
filter: BanSearchFilter|undefined;
}

26
src/app/pages/internal-components/search-filters/FilterMatChipMessage.ts

@ -0,0 +1,26 @@
import {Component, Input} from "@angular/core";
import {SearchFilter} from "../../../entities/search/SearchFilter";
import {MessageSearchFilter} from "../../../entities/search/MessageSearchFilter";
@Component({
selector: "app-filter-mat-chip-message",
template: `
<mat-chip
*ngIf="filter && filter.message!=null"
(removed)="filter.removeMessageFromSearch()" [matMenuTriggerFor]="contentSearch">Сообщение содержит: {{filter.message}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #contentSearch>
<mat-form-field appearance="fill" (click)="$event.stopPropagation()">
<mat-label>Сообщение содержит...</mat-label>
<input matInput placeholder="люблю россию и путина" [ngModel]="filter.message" (ngModelChange)="filter.addMessageToSearch($event)">
</mat-form-field>
</mat-menu>
</mat-chip>
`
})
export class FilterMatChipMessage {
@Input("filter")
filter: MessageSearchFilter|undefined;
}

28
src/app/pages/internal-components/search-filters/base/FilterMatChipAccount.ts

@ -0,0 +1,28 @@
import {Component, Input} from "@angular/core";
import {SearchFilter} from "../../../../entities/search/SearchFilter";
@Component({
selector: "app-filter-mat-chip-account",
template: `
<div *ngIf="filter && filter.accounts != null">
<mat-chip
*ngFor="let acId of filter.accounts"
(removed)="filter.removeAccountFromSearch(acId)"
[matMenuTriggerFor]="profileSearch">Профиль: {{acId}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #profileSearch>
<mat-form-field appearance="fill" (click)="$event.stopPropagation()">
<mat-label>Ссылка, имя, все что угодно</mat-label>
<input matInput placeholder="отдыхаем" [ngModel]="acId" (change)="filter.changeAccountToSearch(acId, $event)">
</mat-form-field>
</mat-menu>
</mat-chip>
</div>`
})
export class FilterMatChipAccount {
@Input("filter")
filter: SearchFilter|undefined;
}

29
src/app/pages/internal-components/search-filters/base/FilterMatChipDateBegin.ts

@ -0,0 +1,29 @@
import {Component, Input} from "@angular/core";
import {SearchFilter} from "../../../../entities/search/SearchFilter";
@Component({
selector: "app-filter-mat-chip-date-begin",
template: `
<mat-chip
*ngIf="filter && filter.begin!=null"
(removed)="filter.removeBeginTimeFromSearch()"
[matMenuTriggerFor]="dateBeginSelect">
Дата после {{filter.begin | date:"HH:mm dd/MM/yyyy"}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #dateBeginSelect>
<mat-form-field appearance="fill"
(click)="$event.stopPropagation()">
<mat-label>Дата после</mat-label>
<input matInput type="datetime-local"
[(ngModel)]="filter.begin"
(ngModelChange)="filter.addBeginTimeToSearch($event)">
</mat-form-field>
</mat-menu>
</mat-chip>`
})//todo mb abstract
export class FilterMatChipDateBegin {
@Input("filter")
filter: SearchFilter|undefined;
}

29
src/app/pages/internal-components/search-filters/base/FilterMatChipDateEnd.ts

@ -0,0 +1,29 @@
import {Component, Input} from "@angular/core";
import {SearchFilter} from "../../../../entities/search/SearchFilter";
@Component(
{ selector: "app-filter-mat-chip-date-end",
template: `
<mat-chip
*ngIf="filter && filter.end!=null"
(removed)="filter.removeEndTimeFromSearch()"
[matMenuTriggerFor]="dateEndSelect">
Дата до {{filter.end | date:"HH:mm dd/MM/yyyy"}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #dateEndSelect>
<mat-form-field appearance="fill"
(click)="$event.stopPropagation()">
<mat-label>Дата после</mat-label>
<input matInput type="datetime-local"
[(ngModel)]="filter.end"
(ngModelChange)="filter.addEndTimeToSearch($event)">
</mat-form-field>
</mat-menu>
</mat-chip>`}
)
export class FilterMatChipDateEnd {
@Input("filter")
filter: SearchFilter|undefined;
}

34
src/app/pages/internal-components/search-filters/base/FilterMatChipServer.ts

@ -0,0 +1,34 @@
import {Component, Input} from "@angular/core";
import {SearchFilter} from "../../../../entities/search/SearchFilter";
@Component({
selector: "app-filter-mat-chip-server",
template: `
<mat-chip *ngIf="filter && filter.serverId!=null"
(removed)="filter.removeServerFromSearch()" [matMenuTriggerFor]="serverSelect">
{{getServerName?getServerName(filter.serverId):filter.serverId}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #serverSelect>
<button mat-menu-item *ngFor="let server of serverList" (click)="filter.addServerToSearch(server.server_id)">{{server.name}}</button>
</mat-menu>
</mat-chip>
`
})
export class FilterMatChipServer {
@Input("filter")
filter: SearchFilter|undefined;
@Input("serverList")
serverList:{name: string, server_id: string }[] = []
getServerName(server_id: string|null) {
try {
// @ts-ignore
return this.serverList.filter(s => s.server_id == server_id).pop().name;
} catch (e) {
return "Выбрать сервер";
}
}
}

116
src/app/pages/messages-page/messages-page.component.html

@ -11,95 +11,33 @@
<mat-chip-list> <mat-chip-list>
<mat-chip [matMenuTriggerFor]="addFilter">Искать по...</mat-chip> <mat-chip [matMenuTriggerFor]="addFilter">Искать по...</mat-chip>
<mat-menu #addFilter> <mat-menu #addFilter>
<button mat-menu-item (click)="addAccountToSearch('')">Профилю</button> <button mat-menu-item (click)="filter.addAccountToSearch('')">Профилю</button>
<button mat-menu-item [matMenuTriggerFor]="timeSelect">Времени</button> <button mat-menu-item [matMenuTriggerFor]="timeSelect">Времени</button>
<button mat-menu-item (click)="addServerToSearch()">Серверу</button> <button mat-menu-item (click)="filter.addServerToSearch()">Серверу</button>
<button mat-menu-item (click)="addMessageToSearch('')">Содержимому</button> <button mat-menu-item (click)="filter.addMessageToSearch('')">Содержимому</button>
</mat-menu> </mat-menu>
<mat-menu #timeSelect> <mat-menu #timeSelect>
<button mat-menu-item (click)="addEndTimeToSearch()">До ...</button> <button mat-menu-item (click)="filter.addEndTimeToSearch()">До ...</button>
<button mat-menu-item (click)="addBeginTimeToSearch()">После ...</button> <button mat-menu-item (click)="filter.addBeginTimeToSearch()">После ...</button>
</mat-menu> </mat-menu>
<mat-chip *ngIf="filter.updated" (click)="updateData()">Обновить</mat-chip> <mat-chip *ngIf="filter.updated" (click)="updateData()">Обновить</mat-chip>
<div *ngIf="filter.accounts != null"> <app-filter-mat-chip-account
<mat-chip [filter]="filter"
*ngFor="let acId of filter.accounts" ></app-filter-mat-chip-account>
(removed)="removeAccountFromSearch(acId)" <app-filter-mat-chip-message
[matMenuTriggerFor]="profileSearch">Профиль: {{acId}} [filter]="filter">
<button matChipRemove> </app-filter-mat-chip-message>
<mat-icon>cancel</mat-icon> <app-filter-mat-chip-server
</button> [filter]="filter"
<mat-menu #profileSearch> [serverList]="serverList">
<mat-form-field appearance="fill" (click)="$event.stopPropagation()"> </app-filter-mat-chip-server>
<mat-label>Ссылка, имя, все что угодно</mat-label> <app-filter-mat-chip-date-begin
<input matInput placeholder="отдыхаем" [ngModel]="acId" (change)="changeAccountToSearch(acId, $event)"> [filter]="filter">
</mat-form-field> </app-filter-mat-chip-date-begin>
</mat-menu> <app-filter-mat-chip-date-end
</mat-chip> [filter]="filter">
</div> </app-filter-mat-chip-date-end>
<mat-chip
*ngIf="filter.message!=null"
(removed)="removeMessageFromSearch()" [matMenuTriggerFor]="contentSearch">Сообщение содержит: {{filter.message}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #contentSearch>
<mat-form-field appearance="fill" (click)="$event.stopPropagation()">
<mat-label>Сообщение содержит...</mat-label>
<input matInput placeholder="люблю россию и путина" [ngModel]="filter.message" (ngModelChange)="addMessageToSearch($event)">
</mat-form-field>
</mat-menu>
</mat-chip>
<mat-chip *ngIf="filter.serverId!=null"
(removed)="removeServerFromSearch()" [matMenuTriggerFor]="serverSelect">
{{getServerName(filter.serverId)}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #serverSelect>
<button mat-menu-item *ngFor="let server of serverList" (click)="addServerToSearch(server.server_id)">{{server.name}}</button>
</mat-menu>
</mat-chip>
<mat-chip
*ngIf="filter.begin!=null"
(removed)="removeBeginTimeFromSearch()"
[matMenuTriggerFor]="dateBeginSelect">
Дата после {{filter.begin | date:"HH:mm dd/MM/yyyy"}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #dateBeginSelect>
<mat-form-field appearance="fill"
(click)="$event.stopPropagation()">
<mat-label>Дата после</mat-label>
<input matInput type="datetime-local"
[(ngModel)]="filter.begin"
(ngModelChange)="addBeginTimeToSearch($event)">
</mat-form-field>
</mat-menu>
</mat-chip>
<mat-chip
*ngIf="filter.end!=null"
(removed)="removeEndTimeFromSearch()"
[matMenuTriggerFor]="dateEndSelect">
Дата до {{filter.end | date:"HH:mm dd/MM/yyyy"}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
<mat-menu #dateEndSelect>
<mat-form-field appearance="fill"
(click)="$event.stopPropagation()">
<mat-label>Дата после</mat-label>
<input matInput type="datetime-local"
[(ngModel)]="filter.end"
(ngModelChange)="addEndTimeToSearch($event)">
</mat-form-field>
</mat-menu>
</mat-chip>
</mat-chip-list> </mat-chip-list>
</div> </div>
@ -109,6 +47,8 @@
<mat-spinner *ngIf="loading"></mat-spinner> <mat-spinner *ngIf="loading"></mat-spinner>
<div class="err" *ngIf="err"> <div class="err" *ngIf="err">
Слишком много запросов или сервер не отвечает, обнови страницу. Слишком много запросов или сервер не отвечает, обнови страницу.
<br>
<button mat-button (click)="err=false; loading=false">Закрыть</button>
</div> </div>
</div> </div>
<table mat-table [dataSource]="dataSource" style="width: 100%"> <table mat-table [dataSource]="dataSource" style="width: 100%">
@ -116,7 +56,7 @@
<th mat-header-cell *matHeaderCellDef> Игрок </th> <th mat-header-cell *matHeaderCellDef> Игрок </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="accountMenu"> {{row.account_name}} <td mat-cell *matCellDef="let row" [matMenuTriggerFor]="accountMenu"> {{row.account_name}}
<mat-menu #accountMenu> <mat-menu #accountMenu>
<button mat-menu-item (click)="addAccountToSearch(row.account_name)">Добавить в поиск</button> <button mat-menu-item (click)="filter.addAccountToSearch(row.account_name)">Добавить в поиск</button>
<button mat-menu-item (click)="searchPlayer(row.account_id)">Открыть профиль</button> <button mat-menu-item (click)="searchPlayer(row.account_id)">Открыть профиль</button>
</mat-menu></td> </mat-menu></td>
</ng-container> </ng-container>
@ -125,8 +65,8 @@
<th mat-header-cell *matHeaderCellDef> Дата </th> <th mat-header-cell *matHeaderCellDef> Дата </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="dateMenu"> {{row.utime*1000 | date:"HH:mm:ss dd/MM/yyyy"}} <td mat-cell *matCellDef="let row" [matMenuTriggerFor]="dateMenu"> {{row.utime*1000 | date:"HH:mm:ss dd/MM/yyyy"}}
<mat-menu #dateMenu> <mat-menu #dateMenu>
<button mat-menu-item (click)="addEndTimeToSearch(row.utime*1000)">Искать до {{row.utime*1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button> <button mat-menu-item (click)="filter.addEndTimeToSearch(row.utime*1000)">Искать до {{row.utime*1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button>
<button mat-menu-item (click)="addBeginTimeToSearch(row.utime*1000)">Искать после {{row.utime*1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button> <button mat-menu-item (click)="filter.addBeginTimeToSearch(row.utime*1000)">Искать после {{row.utime*1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button>
</mat-menu> </mat-menu>
</td> </td>
</ng-container> </ng-container>
@ -135,7 +75,7 @@
<th mat-header-cell *matHeaderCellDef> Сообщение </th> <th mat-header-cell *matHeaderCellDef> Сообщение </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="messageMenu"> {{row.message}} <td mat-cell *matCellDef="let row" [matMenuTriggerFor]="messageMenu"> {{row.message}}
<mat-menu #messageMenu> <mat-menu #messageMenu>
<button mat-menu-item (click)="addMessageToSearch(row.message)">Добавить в поиск</button> <button mat-menu-item (click)="filter.addMessageToSearch(row.message)">Добавить в поиск</button>
</mat-menu></td> </mat-menu></td>
</ng-container> </ng-container>
@ -143,7 +83,7 @@
<th mat-header-cell *matHeaderCellDef> Сервер </th> <th mat-header-cell *matHeaderCellDef> Сервер </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="serverMenu"> {{row.serverName}} <td mat-cell *matCellDef="let row" [matMenuTriggerFor]="serverMenu"> {{row.serverName}}
<mat-menu #serverMenu> <mat-menu #serverMenu>
<button mat-menu-item (click)="addServerToSearch(row.server_id)">Добавить в поиск</button> <button mat-menu-item (click)="filter.addServerToSearch(row.server_id)">Добавить в поиск</button>
</mat-menu> </mat-menu>
</td> </td>
</ng-container> </ng-container>

30
src/app/pages/messages-page/messages-page.component.ts

@ -21,13 +21,13 @@ export class MessagesPageComponent extends AbstractSearchTable<Message, MessageS
displayedColumns: string[] = ['account_name', 'date', 'message', 'serverName']; displayedColumns: string[] = ['account_name', 'date', 'message', 'serverName'];
constructor(public authService: AuthService, constructor(public override authService: AuthService,
private messageService: MessageService, private messageService: MessageService,
protected override serverService: ServerService, protected override serverService: ServerService,
private playerService: PlayerService, protected override playerService: PlayerService,
protected override router: Router, protected override router: Router,
protected override route: ActivatedRoute) { protected override route: ActivatedRoute) {
super(serverService, route, router); super(authService, serverService, playerService, route, router);
super.filter = new MessageSearchFilter(); super.filter = new MessageSearchFilter();
} }
@ -47,28 +47,4 @@ export class MessagesPageComponent extends AbstractSearchTable<Message, MessageS
super.updateData(); super.updateData();
this.getMessages(); this.getMessages();
} }
addMessageToSearch(name: any) {
this.filter.message = name;
this.filter.updated = true;
}
removeMessageFromSearch() {
this.filter.message = null;
this.filter.updated = true;
}
searchPlayer(account_id: number) {
if (!this.authService.isAuth()) {
return;
}
this.playerService.searchProfile(`[U:1:${account_id}]`).subscribe(
(res) => {
if (res.steam64 != null)
this.router.navigate(['profile', res.steam64])
},
(err) => {}
)
}
} }

13
src/app/services/ban.service.ts

@ -3,6 +3,9 @@ import {HttpClient} from "@angular/common/http";
import {ShityPaginator} from "../entities/ShityPaginator"; import {ShityPaginator} from "../entities/ShityPaginator";
import {Ban} from "../entities/ban/Ban"; import {Ban} from "../entities/ban/Ban";
import {map, Observable} from "rxjs"; import {map, Observable} from "rxjs";
import {BanSearchFilter} from "../entities/search/BanSearchFilter";
import {MatPaginator} from "@angular/material/paginator";
import {PagingAndSortingPaginator} from "../entities/PagingAndSortingPaginator";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -11,9 +14,11 @@ export class BanService {
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
getBanList(): Observable<ShityPaginator<Ban>> { getBanList(filters: BanSearchFilter, paginator: MatPaginator | undefined) {
return this.http.get("api/web/banlist").pipe( return this.http.post(`api/web/banlist`,
map((res) => ShityPaginator.newObj().fromData(res, "bans")) filters,
) {params: {size: paginator?paginator.pageSize:20, page: paginator?paginator.pageIndex:0}}).pipe(
map((res) => PagingAndSortingPaginator<Ban>.newObj().fromData(res).updatePaginator(paginator))
);
} }
} }

6
src/app/services/message.service.ts

@ -4,7 +4,7 @@ import {MatPaginator} from "@angular/material/paginator";
import {map} from "rxjs"; import {map} from "rxjs";
import {PagingAndSortingPaginator} from "../entities/PagingAndSortingPaginator"; import {PagingAndSortingPaginator} from "../entities/PagingAndSortingPaginator";
import {Message} from "../entities/profile/Message"; import {Message} from "../entities/profile/Message";
import {SearchFilter} from "../entities/search/SearchFilter"; import {MessageSearchFilter} from "../entities/search/MessageSearchFilter";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -13,12 +13,12 @@ export class MessageService {
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
getMessages(filters: SearchFilter, paginator: MatPaginator | undefined) { getMessages(filters: MessageSearchFilter, paginator: MatPaginator | undefined) {
return this.http.post( return this.http.post(
`/api/profile/messages/pages`, `/api/profile/messages/pages`,
filters, filters,
{params: {size: paginator?paginator.pageSize:20, page: paginator?paginator.pageIndex:0}}).pipe( {params: {size: paginator?paginator.pageSize:20, page: paginator?paginator.pageIndex:0}}).pipe(
(map((res) => PagingAndSortingPaginator<Message>.newObj().fromData(res).updatePaginator(paginator))) map((res) => PagingAndSortingPaginator<Message>.newObj().fromData(res).updatePaginator(paginator))
); );
} }
} }

Loading…
Cancel
Save