This commit is contained in:
Ildar Galeev 2020-12-09 18:51:52 +03:00 committed by GitHub
parent d395e48906
commit 31c21cf147
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 74 additions and 67 deletions

View File

@ -1,4 +1,5 @@
<div class="operations-container" fxLayout="column" fxLayoutGap="24px">
<div class="cc-headline">Operations</div>
<div fxLayout="column" fxLayoutGap="24px">
<nav mat-tab-nav-bar>
<a

View File

@ -12,7 +12,7 @@ export class ChargebacksMainSearchFiltersService {
private getShops$ = new ReplaySubject<string>();
form = this.fb.group({
from_time: [moment().subtract(1, 'month').startOf('d'), Validators.required],
from_time: [moment().subtract(1, 'y').startOf('d'), Validators.required],
to_time: [moment().endOf('d'), Validators.required],
invoice_id: '',
shop_ids: '',

View File

@ -4,11 +4,6 @@
<td mat-cell *matCellDef="let claim">{{ claim.id }}</td>
</ng-container>
<ng-container matColumnDef="source">
<th mat-header-cell *matHeaderCellDef>Source</th>
<td mat-cell *matCellDef="let claim">{{ claim | ccClaimSource }}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef>Status</th>
<td mat-cell *matCellDef="let claim">

View File

@ -14,14 +14,7 @@ export class ClaimsTableComponent {
@Input()
claims: Claim[];
displayedColumns: string[] = [
'claimID',
'source',
'status',
'createdAt',
'updatedAt',
'actions',
];
displayedColumns: string[] = ['claimID', 'status', 'createdAt', 'updatedAt', 'actions'];
constructor(private router: Router) {}

View File

@ -1,6 +1,6 @@
<div fxLayout="column" fxLayoutGap="24px">
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
<div class="cc-headline">Party claims</div>
<div class="cc-headline">Merchant's claims</div>
<button mat-button color="primary" (click)="createClaim()">CREATE</button>
</div>
<div fxLayout="column" fxLayoutGap="24px">

View File

@ -9,7 +9,7 @@ import { SearchFormValue } from '@cc/app/shared/components';
import { ClaimManagementService } from '../../thrift-services/damsel/claim-management.service';
import { Claim } from '../../thrift-services/damsel/gen-model/claim_management';
const SEARCH_LIMIT = 20;
const SEARCH_LIMIT = 10;
@Injectable()
export class PartyClaimsService extends PartialFetcher<Claim, SearchFormValue> {

View File

@ -3,7 +3,7 @@
<cc-payments-searcher
*ngIf="searchType"
[type]="searchType"
[initSearchParams]="initsearchParams$ | async"
[initSearchParams]="initSearchParams$ | async"
(searchParamsChanged$)="searchParamsUpdated($event)"
(paymentEventFired$)="paymentEventFired($event)"
></cc-payments-searcher>

View File

@ -19,7 +19,7 @@ import { PartyPaymentsService } from './party-payments.service';
})
export class PartyPaymentsComponent {
searchType: SearcherType;
initsearchParams$ = this.partyPaymentsService.data$;
initSearchParams$ = this.partyPaymentsService.data$;
constructor(
private route: ActivatedRoute,

View File

@ -1,4 +1,4 @@
<div fxLayout="column" fxLayoutGap="24px">
<div class="cc-headline">Party shops</div>
<div class="cc-headline">Merchant's shops</div>
<cc-shops-table [shops]="shops$ | async"></cc-shops-table>
</div>

View File

@ -1,5 +1,7 @@
<div class="party-container" fxLayout="column" fxLayoutGap="24px">
<h3 class="cc-subheading-1 cc-party-header">Party #{{ partyID$ | async }}</h3>
<h3 class="cc-subheading-1 cc-party-header">
{{ merchantEmail$ | async }} (#{{ partyID$ | async }})
</h3>
<div fxLayout="column" fxLayoutGap="24px">
<nav mat-tab-nav-bar>

View File

@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { filter, map, pluck, shareReplay, startWith } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { catchError, filter, map, pluck, shareReplay, startWith, switchMap } from 'rxjs/operators';
import {
AppAuthGuardService,
@ -11,13 +12,14 @@ import {
PartyRole,
} from '@cc/app/shared/services';
import { DeanonimusService, getMaxSearchHitParty } from '../../thrift-services/deanonimus';
@Component({
templateUrl: 'party.component.html',
styleUrls: ['party.component.scss'],
})
export class PartyComponent {
links = this.getLinks();
partyID$ = this.route.params.pipe(pluck('partyID'), shareReplay(1));
activeLinkByFragment$ = this.router.events.pipe(
filter((e) => e instanceof NavigationEnd),
startWith(undefined),
@ -25,11 +27,27 @@ export class PartyComponent {
shareReplay(1)
);
partyID$: Observable<string>;
merchantEmail$: Observable<string>;
constructor(
private route: ActivatedRoute,
private router: Router,
private appAuthGuardService: AppAuthGuardService
) {}
private appAuthGuardService: AppAuthGuardService,
private deanonimusService: DeanonimusService
) {
this.partyID$ = this.route.params.pipe(pluck('partyID'), shareReplay(1));
this.merchantEmail$ = this.partyID$.pipe(
switchMap((partyID) => this.deanonimusService.searchParty(partyID)),
map(getMaxSearchHitParty),
pluck('email'),
catchError((err) => {
console.error(err);
return of('--/--');
}),
shareReplay(1)
);
}
private getLinks() {
const links = [

View File

@ -4,11 +4,19 @@ import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatTabsModule } from '@angular/material/tabs';
import { DeanonimusModule } from '../../thrift-services/deanonimus';
import { PartyRouting } from './party-routing.module';
import { PartyComponent } from './party.component';
@NgModule({
imports: [PartyRouting, CommonModule, MatTabsModule, FlexModule, MatButtonModule],
imports: [
PartyRouting,
CommonModule,
MatTabsModule,
FlexModule,
MatButtonModule,
DeanonimusModule,
],
declarations: [PartyComponent],
})
export class PartyModule {}

View File

@ -10,7 +10,7 @@ import { Claim } from '../../thrift-services/damsel/gen-model/claim_management';
@Injectable()
export class SearchClaimsService extends PartialFetcher<Claim, SearchFormValue> {
private readonly searchLimit = 20;
private readonly searchLimit = 10;
claims$: Observable<Claim[]> = this.searchResult$;

View File

@ -10,10 +10,6 @@
<div class="mat-caption party-id">{{ claim.party_id }}</div>
</td>
</ng-container>
<ng-container matColumnDef="source">
<th mat-header-cell *matHeaderCellDef>Source</th>
<td mat-cell *matCellDef="let claim">{{ claim.metadata | ccClaimSource }}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef>Status</th>
<td mat-cell *matCellDef="let claim">

View File

@ -12,7 +12,7 @@ export class SearchTableComponent {
@Input()
claims: Claim[];
displayedColumns = ['claimID', 'party', 'source', 'status', 'updatedAt', 'actions'];
displayedColumns = ['claimID', 'party', 'status', 'updatedAt', 'actions'];
constructor(private router: Router) {}

View File

@ -26,7 +26,7 @@ export class SearchPartiesComponent {
searchParamsUpdated($event: PartiesSearchFiltersParams) {
this.partiesService.preserve($event);
this.fetchPartiesService.searchParties($event);
this.fetchPartiesService.searchParties($event.text);
}
partyMenuItemSelected(event: PartyMenuItemEvent) {

View File

@ -1,5 +1,4 @@
<div fxLayout="column" fxLayoutGap="24px">
<div class="cc-headline">Payments</div>
<cc-payments-searcher
[type]="searchType"
[initSearchParams]="initsearchParams$ | async"

View File

@ -46,7 +46,7 @@ export class MerchantSearcherComponent extends CustomFormControl implements OnIn
if (v === '') {
this.formControl.patchValue(v);
} else {
this.fetchMarchantsService.searchParties({ text: v });
this.fetchMarchantsService.searchParties(v);
}
});
@ -72,7 +72,7 @@ export class MerchantSearcherComponent extends CustomFormControl implements OnIn
const { value } = this.formControl;
if (value && value !== '') {
this.searchControl.patchValue(value);
this.fetchMarchantsService.searchParties({ text: value });
this.fetchMarchantsService.searchParties(value);
}
}
}

View File

@ -15,7 +15,7 @@ export class PaymentsMainSearchFiltersService {
private getShops$ = new ReplaySubject<string>();
form = this.fb.group({
fromTime: [moment().subtract(1, 'month').startOf('d'), Validators.required],
fromTime: [moment().subtract(1, 'year').startOf('d'), Validators.required],
toTime: [moment().endOf('d'), Validators.required],
invoiceID: '',
partyID: '',

View File

@ -1,11 +1,10 @@
import { NgModule } from '@angular/core';
import { ClaimSourcePipe } from './claim-source.pipe';
import { ClaimStatusPipe } from './claim-status.pipe';
import { PartyModificationNamePipe } from './party-modification-name.pipe';
import { ShopNamePipe } from './shop-name.pipe';
const pipes = [ClaimSourcePipe, ClaimStatusPipe, PartyModificationNamePipe, ShopNamePipe];
const pipes = [ClaimStatusPipe, PartyModificationNamePipe, ShopNamePipe];
@NgModule({
declarations: pipes,

View File

@ -1,10 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'ccClaimSource',
})
export class ClaimSourcePipe implements PipeTransform {
transform(value: any): string {
return 'Unknown';
}
}

View File

@ -1,35 +1,33 @@
import { Injectable } from '@angular/core';
import { progress } from '@rbkmoney/partial-fetcher/dist/progress';
import { merge, of, Subject } from 'rxjs';
import { catchError, filter, map, switchMap } from 'rxjs/operators';
import { Observable, of, Subject } from 'rxjs';
import { catchError, map, shareReplay, switchMap } from 'rxjs/operators';
import { PartiesSearchFiltersParams } from '../../sections/search-parties/parties-search-filters';
import { DeanonimusService } from '../../thrift-services/deanonimus';
import { SearchHit } from '../../thrift-services/deanonimus/gen-model/deanonimus';
import { Party } from '../../thrift-services/deanonimus/gen-model/deanonimus';
@Injectable()
export class FetchPartiesService {
private searchParties$: Subject<PartiesSearchFiltersParams> = new Subject();
private hasError$: Subject<any> = new Subject();
private searchParties$: Subject<string> = new Subject();
parties$ = this.searchParties$.pipe(
switchMap((params) =>
this.deanonimusService.searchParty(params).pipe(
catchError((_) => {
this.hasError$.next();
return of('error');
parties$: Observable<Party[]> = this.searchParties$.pipe(
switchMap((text) =>
this.deanonimusService.searchParty(text).pipe(
map((hits) => hits.map((hit) => hit.party)),
catchError((err) => {
console.error(err);
return of([]);
})
)
),
filter((r) => r !== 'error'),
map((hits: SearchHit[]) => hits.map((hit) => hit.party))
shareReplay(1)
);
inProgress$ = progress(this.searchParties$, merge(this.parties$, this.hasError$));
inProgress$: Observable<boolean> = progress(this.searchParties$, this.parties$);
constructor(private deanonimusService: DeanonimusService) {}
searchParties(params: PartiesSearchFiltersParams) {
this.searchParties$.next(params);
searchParties(text: string) {
this.searchParties$.next(text);
}
}

View File

@ -12,6 +12,6 @@ export class DeanonimusService extends ThriftService {
super(zone, keycloakTokenInfoService, '/deanonimus', Deanonimus);
}
searchParty = (params: { text: string }): Observable<SearchHit[]> =>
this.toObservableAction('searchParty')(params.text);
searchParty = (text: string): Observable<SearchHit[]> =>
this.toObservableAction('searchParty')(text);
}

View File

@ -1,2 +1,3 @@
export * from './deanonimus.module';
export * from './deanonimus.service';
export * from './utils';

View File

@ -0,0 +1,6 @@
import maxBy from 'lodash-es/maxBy';
import { Party, SearchHit } from '../gen-model/deanonimus';
export const getMaxSearchHitParty = (searchHits: SearchHit[]): Party =>
maxBy(searchHits, (searchHit) => searchHit.score)?.party;

View File

@ -0,0 +1 @@
export * from './get-max-search-hit-party';