Skip to content

Commit

Permalink
Merge pull request #18 from vklachkov/filter-search
Browse files Browse the repository at this point in the history
Поиск и фильтры на стороне бэка
  • Loading branch information
vklachkov authored Sep 25, 2024
2 parents 05434b6 + b55d610 commit 40230e7
Show file tree
Hide file tree
Showing 18 changed files with 356 additions and 134 deletions.
24 changes: 24 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@angular/platform-browser": "^18.1.0",
"@angular/platform-browser-dynamic": "^18.1.0",
"@angular/router": "^18.1.0",
"@ngneat/bind-query-params": "^6.0.0",
"ng-zorro-antd": "^18.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { FormsModule } from '@angular/forms';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import {
FilterOutline,
LogoutOutline,
StarOutline,
StarFill,
Expand All @@ -26,7 +25,8 @@ import {
RocketOutline,
DownloadOutline,
RollbackOutline,
SaveOutline
SaveOutline,
SettingOutline
} from '@ant-design/icons-angular/icons';
import { unauthorizedInterceptor } from './interceptors/unauthorized.interceptor';
import { NzModalService } from 'ng-zorro-antd/modal';
Expand All @@ -38,7 +38,6 @@ export const appConfig: ApplicationConfig = {
provideExperimentalZonelessChangeDetection(),
provideRouter(routes),
provideNzIcons([
FilterOutline,
LogoutOutline,
StarOutline,
StarFill,
Expand All @@ -56,7 +55,8 @@ export const appConfig: ApplicationConfig = {
RocketOutline,
DownloadOutline,
RollbackOutline,
SaveOutline
SaveOutline,
SettingOutline
]),
provideNzI18n(ru_RU),
importProvidersFrom(FormsModule),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { Router } from '@angular/router';
import { NzButtonComponent } from 'ng-zorro-antd/button';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { BaseComponent } from '../base/base.component';
import { ROOT_ROUTE_PATHS } from '../../app.routes';
import { NavigationService } from '../../services/navigation.service';

@Component({
selector: 'app-main-button',
Expand All @@ -14,9 +14,9 @@ import { ROOT_ROUTE_PATHS } from '../../app.routes';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MainButtonComponent extends BaseComponent {
private readonly router: Router = inject(Router);
private readonly navigationService: NavigationService = inject(NavigationService);

goToMain(): void {
this.router.navigate([ROOT_ROUTE_PATHS.Index]);
this.navigationService.back(ROOT_ROUTE_PATHS.Index);
}
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,30 @@
<!-- <a title="" [routerLink]="[participantPath, participant.id]"> -->
<!-- <nz-card class="participant" [nzBodyStyle]="{'padding': '0'}"> -->
<a title="" class="participant" [routerLink]="[participantPath, participant.id]">
<!-- <nz-avatar [nzSize]="72" [nzSrc]="participant.info.photo_url"></nz-avatar> -->

<!-- <div class="participant-info"> -->
<h3 class="participant__title">{{ participant.info.name }} "{{ participant.code }}"</h3>

<p nz-typograpy class="participant__text">
г. {{ participant.info.city }},
{{ participant.info.edu_org }},
{{ participant.info.responsible_adult_name }}
</p>


@switch (status) {
@case (ParticipantStatus.InTeam) {
<p class="participant__status in-team">
Находится в команде "{{ participant.jury?.name ?? '' }}"
</p>
}
@case (ParticipantStatus.NotRated) {
<p class="participant__status not-rated">
Без оценок
</p>
}
@case (ParticipantStatus.PartiallyRated) {
<p class="participant__status partially-rated">
Частично оценен
</p>
}
@case (ParticipantStatus.FullRated) {
<p class="participant__status full-rated">
Полностью оценен
</p>
}
}
<!-- </div> -->
</a>
<!-- </nz-card> -->
<!-- </a> -->
<a title="" class="participant" [routerLink]="[participantPath, participant.id]">
<h3 class="participant__title">
{{ participant.info.name }} (№{{ participant.id + 1 }}, {{ participant.code }})
</h3>

<p nz-typograpy class="participant__text">{{ text }}</p>

@switch (status) {
@case (ParticipantStatus.InTeam) {
<p class="participant__status in-team">
Находится в команде "{{ participant.jury?.name ?? '' }}"
</p>
}
@case (ParticipantStatus.NotRated) {
<p class="participant__status not-rated">
Без оценок
</p>
}
@case (ParticipantStatus.PartiallyRated) {
<p class="participant__status partially-rated">
Частично оценен
</p>
}
@case (ParticipantStatus.FullRated) {
<p class="participant__status full-rated">
Полностью оценен
</p>
}
}
</a>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { NzAvatarModule } from 'ng-zorro-antd/avatar';
Expand All @@ -15,14 +15,16 @@ import { ORGANIZER_ROOT_PATHS } from '../../app.routes';
styleUrl: './participant-card.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ParticipantCardComponent implements OnInit, OnChanges {
export class ParticipantCardComponent implements OnInit {
@Input({ required: true }) participant!: Participant;

status: ParticipantStatus | null = null;
ParticipantStatus = ParticipantStatus;

participantPath: string = ORGANIZER_ROOT_PATHS.Participant;

text: string = '';

private getStatus(): ParticipantStatus | null {
if (this.participant.jury?.id) {
return ParticipantStatus.InTeam;
Expand All @@ -43,13 +45,17 @@ export class ParticipantCardComponent implements OnInit, OnChanges {
return null;
}

ngOnChanges(): void {
// Виртуал скролл не переставляет элементы в списке, а подменяет одно на другое, поэтому при каждой такой подмене
// нужно переиницилизировать статус
this.status = this.getStatus();
private buildText(): void {
const text: string[] = [`г. ${this.participant.info.city}`, this.participant.info.edu_org];
if (this.participant.info.responsible_adult_name) {
text.push(this.participant.info.responsible_adult_name);
}

this.text = text.join(', ');
}

ngOnInit(): void {
this.status = this.getStatus();
this.buildText();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { BaseComponent } from '../base/base.component';
import { NzSpinComponent } from 'ng-zorro-antd/spin';
import { NzOptionComponent, NzSelectComponent } from 'ng-zorro-antd/select';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NzTableComponent, NzTableModule } from 'ng-zorro-antd/table';
import { NzTableModule } from 'ng-zorro-antd/table';
import { CommonModule } from '@angular/common';
import { JuryRate, Participant, Rates } from '../../models/api/participant.interface';
import { JuryRate, Participant } from '../../models/api/participant.interface';
import { Adult } from '../../models/api/adult.interface';
import { delay, switchMap, takeUntil } from 'rxjs';
import { debounceTime, switchMap, takeUntil } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { OrganizerService } from '../../services/organizer.service';
import { NzTypographyComponent } from 'ng-zorro-antd/typography';
Expand Down Expand Up @@ -72,7 +72,7 @@ export class ParticipantRatesTabComponent extends BaseComponent implements OnIni
private initTeamControlSubscription(): void {
this.teamControl.valueChanges
.pipe(
delay(200),
debounceTime(200),
switchMap((value: number | null) => {
this.isSettingCommandLoading = true;
this.cdr.markForCheck();
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/app/models/api/filter-options.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const enum FilterOptions {
Order = 'order',
Sort = 'sort',
Search = 'search'
}
4 changes: 4 additions & 0 deletions frontend/src/app/models/api/order.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum Order {
ASC = 'asc',
DESC = 'desc'
}
8 changes: 5 additions & 3 deletions frontend/src/app/models/api/sort.enum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const enum Sort {
ASC = 'asc',
DESC = 'desc'
export enum Sort {
Id = 'id',
Name = 'name',
District = 'district',
City = 'city'
}
8 changes: 8 additions & 0 deletions frontend/src/app/models/participants-query.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Order } from './api/order.enum';
import { Sort } from './api/sort.enum';

export interface ParticipantsQuery {
order: Order;
sort: Sort;
search?: string | null;
}
3 changes: 1 addition & 2 deletions frontend/src/app/pages/jury/jury.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { LocalStorageService } from '../../services/local-storage.service';
import { LogoutButtonComponent } from '../../components/logout-button/logout-button.component';
import { HeaderComponent } from "../../components/header/header.component";
import { ApplicationsGroupComponent } from "../../components/applications-group/applications-group.component";
import { Sort } from '../../models/api/sort.enum';

@Component({
selector: 'app-jury-page',
Expand Down Expand Up @@ -55,7 +54,7 @@ export class JuryPage extends BaseComponent implements OnInit {

private loadParticipants(): void {
this.isParticipantsLoading = true;
this.juryService.getParticipants(Sort.ASC)
this.juryService.getParticipants()
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (data: AnonymousParticipant[]) => {
Expand Down
45 changes: 36 additions & 9 deletions frontend/src/app/pages/organizer/organizer.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,53 @@
</ng-template>

<button
class="filter__show-options"
nz-button
nz-popover
nzPopoverTrigger="click"
nzPopoverPlacement="bottom"
[nzPopoverContent]="contentTemplate"
[nzPopoverOverlayStyle]="{'width': '34em'}"
[(nzPopoverVisible)]="filterVisible"
(nzPopoverVisibleChange)="changeFilterVisible($event)"
>
<span nz-icon nzType="filter" nzTheme="outline"></span>
Фильтр
<span nz-icon nzType="setting" nzTheme="outline"></span>
</button>

<ng-template #contentTemplate>
<nz-radio-group class="filter__options" formControlName="status">
<label nz-radio [nzValue]="null">Все</label>
<label nz-radio [nzValue]="ParticipantStatus.NotRated">Без оценок</label>
<label nz-radio [nzValue]="ParticipantStatus.PartiallyRated">Частично оценненые</label>
<label nz-radio [nzValue]="ParticipantStatus.FullRated">Полностью оценненые</label>
<label nz-radio [nzValue]="ParticipantStatus.InTeam">В команде</label>
</nz-radio-group>
<div class="filter__options">
<div class="filter__options-item">
<p nz-typography class="filter__options-item-title">Статус</p>

<nz-radio-group class="filter__options-group" formControlName="status">
<label nz-radio [nzValue]="null">Все</label>
<label nz-radio [nzValue]="ParticipantStatus.NotRated">Без оценок</label>
<label nz-radio [nzValue]="ParticipantStatus.PartiallyRated">Частично оценненые</label>
<label nz-radio [nzValue]="ParticipantStatus.FullRated">Полностью оценненые</label>
<label nz-radio [nzValue]="ParticipantStatus.InTeam">В команде</label>
</nz-radio-group>
</div>

<div class="filter__options-item">
<p nz-typography class="filter__options-item-title">Сортировка</p>

<nz-radio-group class="filter__options-group" formControlName="sort">
<label nz-radio [nzValue]="Sort.Id">Номер</label>
<label nz-radio [nzValue]="Sort.Name">Имя</label>
<label nz-radio [nzValue]="Sort.City">Город</label>
<label nz-radio [nzValue]="Sort.District">Район</label>
</nz-radio-group>
</div>

<div class="filter__options-item">
<p nz-typography class="filter__options-item-title">Порядок</p>

<nz-radio-group class="filter__options-group" formControlName="order">
<label nz-radio [nzValue]="Order.ASC">{{ ascSortLabel }}</label>
<label nz-radio [nzValue]="Order.DESC">{{ descSortLabel }}</label>
</nz-radio-group>
</div>
</div>
</ng-template>
</form>

Expand Down
Loading

0 comments on commit 40230e7

Please sign in to comment.