FR-593: Responsive claim status filter (#501)

* claim status filter

* remove pendingAcceptance status

* more prettier

* warnings count fix
This commit is contained in:
Denis Ezhov 2021-07-01 14:30:40 +03:00 committed by GitHub
parent 7bcb2a2dcc
commit d291c36559
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 143 additions and 30 deletions

View File

@ -7,7 +7,7 @@
"build": "ng build --prod --extraWebpackConfig webpack.extra.js --progress=false",
"test": "ng test",
"test-ci": "ng run dashboard:test-ci",
"lint": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 2075 --cache",
"lint": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 2073 --cache",
"lint-errors": "npm run lint -- --quiet",
"lint-fix": "npm run lint -- --fix",
"e2e": "ng e2e",

View File

@ -1,6 +1,6 @@
import { StatusModificationUnit } from '@dsh/api-codegen/claim-management/swagger-codegen';
import { ClaimStatusesEnum } from '@dsh/app/shared/components/inputs/claim-statuses-field/types/claim-statuses-enum';
export interface ClaimsSearchFiltersSearchParams {
claimID?: number;
claimStatuses?: StatusModificationUnit.StatusEnum[];
claimStatuses?: ClaimStatusesEnum[];
}

View File

@ -1,10 +1,7 @@
<dsh-filters-group>
<dsh-filters-group [formGroup]="form">
<dsh-claim-id-filter
[selected]="initParams?.claimID"
(selectionChange)="claimIDchange($event)"
(selectionChange)="claimIDChange($event)"
></dsh-claim-id-filter>
<dsh-claim-statuses-filter
[selected]="initParams?.claimStatuses"
(selectedChange)="statusesSelectionChange($event)"
></dsh-claim-statuses-filter>
<dsh-claim-statuses-filter formControlName="claimStatuses"></dsh-claim-statuses-filter>
</dsh-filters-group>

View File

@ -1,17 +1,24 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder } from '@ngneat/reactive-forms';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import isEqual from 'lodash-es/isEqual';
import pick from 'lodash-es/pick';
import { ReplaySubject, Subject } from 'rxjs';
import { distinctUntilChanged, scan } from 'rxjs/operators';
import { StatusModificationUnit } from '@dsh/api-codegen/claim-management/swagger-codegen';
import { ClaimStatusesEnum } from '@dsh/app/shared/components/inputs/claim-statuses-field/types/claim-statuses-enum';
import { removeEmptyProperties } from '../../payment-section/operations/operators';
import { ClaimsSearchFiltersSearchParams } from './claims-search-filters-search-params';
@UntilDestroy()
@Component({
selector: 'dsh-claims-search-filters',
templateUrl: 'claims-search-filters.component.html',
})
export class ClaimsSearchFiltersComponent implements OnInit {
form = this.fb.group<{ claimStatuses: ClaimStatusesEnum[] }>({ claimStatuses: null });
private searchParams$: Subject<Partial<ClaimsSearchFiltersSearchParams>> = new ReplaySubject(1);
// eslint-disable-next-line @typescript-eslint/member-ordering
@ -22,20 +29,29 @@ export class ClaimsSearchFiltersComponent implements OnInit {
@Output()
searchParamsChanges = new EventEmitter<ClaimsSearchFiltersSearchParams>();
ngOnInit() {
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.searchParams$
.pipe(
distinctUntilChanged(isEqual),
scan((acc, current) => ({ ...acc, ...current }), this.initParams)
scan((acc, current) => ({ ...acc, ...current }), this.initParams),
removeEmptyProperties,
untilDestroyed(this)
)
.subscribe((v) => this.searchParamsChanges.emit(v));
this.form.valueChanges.pipe(untilDestroyed(this)).subscribe((value) => this.searchParams$.next(value));
this.form.patchValue(pick(this.initParams, ['claimStatuses']));
const { claimID } = this.initParams;
this.claimIDChange(claimID);
}
claimIDchange(claimID: number) {
claimIDChange(claimID: number): void {
this.searchParams$.next({ claimID });
}
statusesSelectionChange(claimStatuses: StatusModificationUnit.StatusEnum[]) {
statusesSelectionChange(claimStatuses: ClaimStatusesEnum[]): void {
this.searchParams$.next({ claimStatuses });
}
}

View File

@ -1,8 +1,11 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { ReactiveFormsModule } from '@angular/forms';
import { TranslocoModule } from '@ngneat/transloco';
import { ClaimStatusesFieldModule } from '@dsh/app/shared/components/inputs/claim-statuses-field';
import { FilterModule } from '@dsh/components/filter';
import { FiltersGroupModule } from '@dsh/components/filters-group';
import { MultiselectFilterModule } from '@dsh/components/filters/multiselect-filter';
import { RadioGroupFilterModule } from '@dsh/components/filters/radio-group-filter';
@ -22,6 +25,9 @@ import { ClaimStatusesFilterComponent } from './components/claim-statuses-filter
FlexModule,
MultiselectFilterModule,
FiltersGroupModule,
FilterModule,
ClaimStatusesFieldModule,
ReactiveFormsModule,
],
exports: [ClaimsSearchFiltersComponent],
})

View File

@ -1,13 +1,13 @@
<dsh-multiselect-filter
<dsh-filter
*transloco="let t; scope: 'claim-status-filter'; read: 'claimStatusFilter'"
[active]="isActive"
[label]="t('label')"
[selected]="selected"
[searchInputLabel]="t('label')"
(selectedChange)="this.selectedChange.emit($event)"
[activeLabel]="t('label') | listLabel: (labels$ | async)"
[content]="content"
(save)="save()"
(clear)="clear()"
>
<dsh-multiselect-filter-option *ngFor="let status of statuses" [value]="status">
<span *transloco="let filterStatuses; scope: 'claim-status-filter'; read: 'claimStatusFilter.statuses'">{{
filterStatuses(status)
}}</span>
</dsh-multiselect-filter-option>
</dsh-multiselect-filter>
</dsh-filter>
<ng-template #content>
<dsh-claim-statuses-field [formControl]="formControl"></dsh-claim-statuses-field>
</ng-template>

View File

@ -1,15 +1,31 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { ChangeDetectionStrategy, Component, Injector } from '@angular/core';
import { provideValueAccessor } from '@s-libs/ng-core';
import { combineLatest } from 'rxjs';
import { share, switchMap } from 'rxjs/operators';
import { StatusModificationUnit } from '@dsh/api-codegen/claim-management/swagger-codegen';
import { ClaimStatusesLabelPipe } from '@dsh/app/shared/components/inputs/claim-statuses-field';
import { ClaimStatusesEnum } from '@dsh/app/shared/components/inputs/claim-statuses-field/types/claim-statuses-enum';
import { FilterSuperclass } from '@dsh/components/filter';
@Component({
selector: 'dsh-claim-statuses-filter',
templateUrl: 'claim-statuses-filter.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [provideValueAccessor(ClaimStatusesFilterComponent), ClaimStatusesLabelPipe],
})
export class ClaimStatusesFilterComponent {
@Input() selected?: StatusModificationUnit.StatusEnum;
@Output() selectedChange = new EventEmitter<StatusModificationUnit.StatusEnum>();
export class ClaimStatusesFilterComponent extends FilterSuperclass<ClaimStatusesEnum[]> {
labels$ = this.savedValue$.pipe(
switchMap((types) => combineLatest((types || []).map((type) => this.claimStatusesLabelPipe.transform(type)))),
share()
);
statuses = Object.values(StatusModificationUnit.StatusEnum).filter((i) => i !== 'pendingAcceptance');
constructor(injector: Injector, private claimStatusesLabelPipe: ClaimStatusesLabelPipe) {
super(injector);
}
save(): void {
if (this.formControl.value?.length === Object.keys(ClaimStatusesEnum).length)
this.formControl.patchValue(this.createEmpty());
this.savedValue = this.formControl.value;
}
}

View File

@ -0,0 +1 @@
<dsh-multi-select-field [formControl]="formControl" [options]="options$ | async" noSearch></dsh-multi-select-field>

View File

@ -0,0 +1,23 @@
import { Component, Injector, OnChanges } from '@angular/core';
import { provideValueAccessor, WrappedFormControlSuperclass } from '@s-libs/ng-core';
import { valuesToOptions } from '@dsh/components/form-controls/utils/values-to-options';
import { ClaimStatusesLabelPipe } from './pipes/claim-statuses-label.pipe';
import { ClaimStatusesEnum } from './types/claim-statuses-enum';
@Component({
selector: 'dsh-claim-statuses-field',
templateUrl: 'claim-statuses-field.component.html',
providers: [provideValueAccessor(ClaimStatusesFieldComponent), ClaimStatusesLabelPipe],
})
export class ClaimStatusesFieldComponent
extends WrappedFormControlSuperclass<ClaimStatusesEnum[]>
implements OnChanges
{
options$ = valuesToOptions(Object.values(ClaimStatusesEnum), (v) => this.claimStatusesLabelPipe.transform(v));
constructor(injector: Injector, private claimStatusesLabelPipe: ClaimStatusesLabelPipe) {
super(injector);
}
}

View File

@ -0,0 +1,17 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { TranslocoModule } from '@ngneat/transloco';
import { MultiselectFilterModule } from '@dsh/components/filters/multiselect-filter';
import { MultiSelectFieldModule } from '@dsh/components/form-controls/multi-select-field';
import { ClaimStatusesFieldComponent } from './claim-statuses-field.component';
import { ClaimStatusesLabelPipe } from './pipes/claim-statuses-label.pipe';
@NgModule({
imports: [MultiselectFilterModule, CommonModule, TranslocoModule, MultiSelectFieldModule, ReactiveFormsModule],
declarations: [ClaimStatusesFieldComponent, ClaimStatusesLabelPipe],
exports: [ClaimStatusesFieldComponent, ClaimStatusesLabelPipe],
})
export class ClaimStatusesFieldModule {}

View File

@ -0,0 +1,3 @@
export * from './claim-statuses-field.component';
export * from './claim-statuses-field.module';
export * from './pipes/claim-statuses-label.pipe';

View File

@ -0,0 +1,17 @@
import { Pipe, PipeTransform } from '@angular/core';
import { TranslocoService } from '@ngneat/transloco';
import { Observable, of } from 'rxjs';
import { StatusModificationUnit } from '@dsh/api-codegen/claim-management';
import { OPTION_LABELS } from '../types/option-labels';
@Pipe({ name: 'claimStatusesLabelPipe' })
export class ClaimStatusesLabelPipe implements PipeTransform {
constructor(private translocoService: TranslocoService) {}
transform(value: StatusModificationUnit.StatusEnum): Observable<string> {
if (!value) return of('');
return this.translocoService.selectTranslate(`statuses.${OPTION_LABELS[value]}`, {}, 'claim-status-filter');
}
}

View File

@ -0,0 +1,7 @@
export enum ClaimStatusesEnum {
Pending = 'pending',
Review = 'review',
Accepted = 'accepted',
Denied = 'denied',
Revoked = 'revoked',
}

View File

@ -0,0 +1,9 @@
import { ClaimStatusesEnum } from '@dsh/app/shared/components/inputs/claim-statuses-field/types/claim-statuses-enum';
export const OPTION_LABELS: { [N in ClaimStatusesEnum]: string } = {
pending: 'pending',
review: 'review',
accepted: 'accepted',
denied: 'denied',
revoked: 'revoked',
};

View File

@ -3,6 +3,7 @@
"statuses": {
"pending": "В ожидании",
"review": "На рассмотрении",
"pendingAcceptance": "В ожидании одобрения",
"revoked": "Отозвана",
"denied": "Отклонена",
"accepted": "Одобрена"