mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
Moving to table2 with lazy column (#405)
This commit is contained in:
parent
753ad0d727
commit
9e3b6d5ae8
8
package-lock.json
generated
8
package-lock.json
generated
@ -26,7 +26,7 @@
|
||||
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
||||
"@vality/machinegun-proto": "1.0.1-3decc8f.0",
|
||||
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
||||
"@vality/ng-core": "18.4.1-pr-74-55d4acd.0",
|
||||
"@vality/ng-core": "18.4.1-pr-78-9131f9a.0",
|
||||
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
||||
"@vality/repairer-proto": "2.0.2-07b73e9.0",
|
||||
"@vality/scrooge-proto": "0.1.1-9ce7fc6.0",
|
||||
@ -5969,9 +5969,9 @@
|
||||
"integrity": "sha512-XWF7qM/CARRAey0scGVhfGU6jNq+UdlGE2mg3jn4eIFDuIWQJqsT+Bah300RBUrl+XgFsmj95C6HWRfeA5Q8kw=="
|
||||
},
|
||||
"node_modules/@vality/ng-core": {
|
||||
"version": "18.4.1-pr-74-55d4acd.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-18.4.1-pr-74-55d4acd.0.tgz",
|
||||
"integrity": "sha512-EkGTPth5+HA0MLc+BYLIV5ie7xnwBrXftTxoVJw+5zlcWoLm5V1+10AGz6wmhX4VIunFFZR/p9XUNAhNqvluVw==",
|
||||
"version": "18.4.1-pr-78-9131f9a.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-18.4.1-pr-78-9131f9a.0.tgz",
|
||||
"integrity": "sha512-qmTGnGe+pBWlIQ+cX64pt2aLWdoLM6M2Apc180dQQrLca4VBHB4Oh8yo7vvv/sxws1DLXEzWutgNzi9/bRdtZQ==",
|
||||
"dependencies": {
|
||||
"@angular/material-date-fns-adapter": "^18.2.2",
|
||||
"@ng-matero/extensions": "^18.2.0",
|
||||
|
@ -35,7 +35,7 @@
|
||||
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
||||
"@vality/machinegun-proto": "1.0.1-3decc8f.0",
|
||||
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
||||
"@vality/ng-core": "18.4.1-pr-74-55d4acd.0",
|
||||
"@vality/ng-core": "18.4.1-pr-78-9131f9a.0",
|
||||
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
||||
"@vality/repairer-proto": "2.0.2-07b73e9.0",
|
||||
"@vality/scrooge-proto": "0.1.1-9ce7fc6.0",
|
||||
|
@ -12,8 +12,8 @@ import { environment } from '../environments/environment';
|
||||
import { ROUTING_CONFIG as CLAIMS_ROUTING_CONFIG } from './sections/claims/routing-config';
|
||||
import { ROUTING_CONFIG as DEPOSITS_ROUTING_CONFIG } from './sections/deposits/routing-config';
|
||||
import { ROUTING_CONFIG as DOMAIN_ROUTING_CONFIG } from './sections/domain/routing-config';
|
||||
import { ROUTING_CONFIG as MACHINES_ROUTING_CONFIG } from './sections/machines/routing-config';
|
||||
import { ROUTING_CONFIG as PAYMENTS_ROUTING_CONFIG } from './sections/payments/routing-config';
|
||||
import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing/routing-config';
|
||||
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
||||
import { SHOPS_ROUTING_CONFIG } from './sections/shops';
|
||||
import { ROUTING_CONFIG as SOURCES_ROUTING_CONFIG } from './sections/sources/routing-config';
|
||||
@ -73,7 +73,7 @@ export class AppComponent {
|
||||
{
|
||||
label: 'Machines',
|
||||
url: '/machines',
|
||||
services: REPAIRING_ROUTING_CONFIG.services,
|
||||
services: MACHINES_ROUTING_CONFIG.services,
|
||||
},
|
||||
{
|
||||
label: 'Sources',
|
||||
|
@ -1,4 +1,4 @@
|
||||
<cc-page-layout title="Chargebacks">
|
||||
<cc-page-layout fullHeight title="Chargebacks">
|
||||
<cc-page-layout-actions>
|
||||
<v-more-filters-button [filters]="filters"></v-more-filters-button>
|
||||
</cc-page-layout-actions>
|
||||
@ -47,14 +47,6 @@
|
||||
(more)="more()"
|
||||
(update)="reload($event)"
|
||||
>
|
||||
<button
|
||||
[disabled]="!selected.length"
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
(click)="changeStatuses()"
|
||||
>
|
||||
Change statuses
|
||||
</button>
|
||||
<button color="primary" mat-raised-button (click)="create()">Create by file</button>
|
||||
</cc-chargebacks-table>
|
||||
</cc-page-layout>
|
||||
|
@ -29,7 +29,6 @@ import {
|
||||
CHARGEBACK_CATEGORIES,
|
||||
} from '@cc/app/api/fistful-stat';
|
||||
|
||||
import { ChangeChargebacksStatusDialogComponent } from '../../shared/components/change-chargebacks-status-dialog';
|
||||
import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../../tokens';
|
||||
|
||||
import { CreateChargebacksByFileDialogComponent } from './components/create-chargebacks-by-file-dialog/create-chargebacks-by-file-dialog.component';
|
||||
@ -46,7 +45,7 @@ type FormValue = {
|
||||
@Component({
|
||||
selector: 'cc-chargebacks',
|
||||
templateUrl: './chargebacks.component.html',
|
||||
styles: [],
|
||||
providers: [FetchChargebacksService],
|
||||
})
|
||||
export class ChargebacksComponent implements OnInit {
|
||||
filtersForm = new FormGroup(
|
||||
@ -141,17 +140,4 @@ export class ChargebacksComponent implements OnInit {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
changeStatuses() {
|
||||
this.dialog
|
||||
.open(ChangeChargebacksStatusDialogComponent, { chargebacks: this.selected })
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((res) => res.status === DialogResponseStatus.Success),
|
||||
takeUntilDestroyed(this.dr),
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import {
|
||||
} from '@vality/ng-core';
|
||||
import { ThriftPipesModule } from '@vality/ng-thrift';
|
||||
|
||||
import { ChargebacksTableComponent } from '@cc/app/shared/components/chargebacks-table';
|
||||
|
||||
import { UploadCsvComponent } from '../../../components/upload-csv';
|
||||
import { PageLayoutModule, ShopFieldModule } from '../../shared';
|
||||
import { MerchantFieldModule } from '../../shared/components/merchant-field';
|
||||
@ -31,15 +33,10 @@ import {
|
||||
|
||||
import { ChargebacksRoutingModule } from './chargebacks-routing.module';
|
||||
import { ChargebacksComponent } from './chargebacks.component';
|
||||
import { ChargebacksTableComponent } from './components/chargebacks-table/chargebacks-table.component';
|
||||
import { CreateChargebacksByFileDialogComponent } from './components/create-chargebacks-by-file-dialog/create-chargebacks-by-file-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ChargebacksComponent,
|
||||
ChargebacksTableComponent,
|
||||
CreateChargebacksByFileDialogComponent,
|
||||
],
|
||||
declarations: [ChargebacksComponent, CreateChargebacksByFileDialogComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ChargebacksRoutingModule,
|
||||
@ -67,6 +64,7 @@ import { CreateChargebacksByFileDialogComponent } from './components/create-char
|
||||
MatInputModule,
|
||||
MatCheckboxModule,
|
||||
UploadCsvComponent,
|
||||
ChargebacksTableComponent,
|
||||
],
|
||||
})
|
||||
export class ChargebacksModule {}
|
||||
|
@ -1,144 +0,0 @@
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { InvoicePaymentChargebackStatus } from '@vality/magista-proto/internal/proto/domain';
|
||||
import { StatChargeback } from '@vality/magista-proto/magista';
|
||||
import { LoadOptions, Column, TagColumn } from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
|
||||
import { AmountCurrencyService } from '../../../../shared/services';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-chargebacks-table',
|
||||
templateUrl: './chargebacks-table.component.html',
|
||||
styles: [],
|
||||
})
|
||||
export class ChargebacksTableComponent {
|
||||
@Input() data!: StatChargeback[];
|
||||
@Input() isLoading?: boolean | null;
|
||||
@Input() hasMore?: boolean | null;
|
||||
@Input() selected?: StatChargeback[];
|
||||
|
||||
@Output() selectedChange = new EventEmitter<StatChargeback[]>();
|
||||
@Output() update = new EventEmitter<LoadOptions>();
|
||||
@Output() more = new EventEmitter<void>();
|
||||
|
||||
columns: Column<StatChargeback>[] = [
|
||||
{ field: 'chargeback_id', header: 'Id' },
|
||||
{
|
||||
field: 'chargeback_reason',
|
||||
header: 'Reason',
|
||||
formatter: (data) => startCase(getUnionKey(data.chargeback_reason.category)),
|
||||
description: (data) => data.chargeback_reason.code,
|
||||
},
|
||||
{
|
||||
field: 'chargeback_status',
|
||||
type: 'tag',
|
||||
header: 'Status',
|
||||
formatter: (data) => getUnionKey(data.chargeback_status),
|
||||
typeParameters: {
|
||||
label: (data) => startCase(getUnionKey(data.chargeback_status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
accepted: { color: 'success' },
|
||||
rejected: { color: 'warn' },
|
||||
cancelled: { color: 'neutral' },
|
||||
},
|
||||
},
|
||||
} as TagColumn<StatChargeback, keyof InvoicePaymentChargebackStatus>,
|
||||
{
|
||||
field: 'amount',
|
||||
type: 'currency',
|
||||
formatter: (data) =>
|
||||
this.amountCurrencyService.toMajor(data.amount, data.currency_code.symbolic_code),
|
||||
typeParameters: {
|
||||
currencyCode: (data) => data.currency_code.symbolic_code,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'levy_amount',
|
||||
type: 'currency',
|
||||
formatter: (data) =>
|
||||
this.amountCurrencyService.toMajor(
|
||||
data.levy_amount,
|
||||
data.levy_currency_code.symbolic_code,
|
||||
),
|
||||
typeParameters: {
|
||||
currencyCode: (data) => data.levy_currency_code.symbolic_code,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'fee',
|
||||
type: 'currency',
|
||||
formatter: (data) =>
|
||||
this.amountCurrencyService.toMajor(data.fee, data.currency_code.symbolic_code),
|
||||
typeParameters: {
|
||||
currencyCode: (data) => data.currency_code.symbolic_code,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'provider_fee',
|
||||
type: 'currency',
|
||||
formatter: (data) =>
|
||||
this.amountCurrencyService.toMajor(
|
||||
data.provider_fee,
|
||||
data.currency_code.symbolic_code,
|
||||
),
|
||||
typeParameters: {
|
||||
currencyCode: (data) => data.currency_code.symbolic_code,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'external_fee',
|
||||
type: 'currency',
|
||||
formatter: (data) =>
|
||||
this.amountCurrencyService.toMajor(
|
||||
data.external_fee,
|
||||
data.currency_code.symbolic_code,
|
||||
),
|
||||
typeParameters: {
|
||||
currencyCode: (data) => data.currency_code.symbolic_code,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'stage',
|
||||
formatter: (data) => getUnionKey(data.stage),
|
||||
},
|
||||
{
|
||||
field: 'invoice_id',
|
||||
header: 'Invoice Id (Payment Id)',
|
||||
description: 'payment_id',
|
||||
link: (data) =>
|
||||
`/party/${data.party_id}/invoice/${data.invoice_id}/payment/${data.payment_id}`,
|
||||
},
|
||||
{
|
||||
field: 'created_at',
|
||||
type: 'datetime',
|
||||
},
|
||||
{
|
||||
field: 'party_id',
|
||||
header: 'Party',
|
||||
},
|
||||
{
|
||||
field: 'shop_id',
|
||||
header: 'Shop',
|
||||
},
|
||||
{
|
||||
field: 'external_id',
|
||||
hide: true,
|
||||
},
|
||||
{
|
||||
field: 'content.type',
|
||||
description: 'content.data',
|
||||
header: 'Content',
|
||||
hide: true,
|
||||
},
|
||||
// createOperationColumn<StatChargeback>([
|
||||
// {
|
||||
// label: 'Change status',
|
||||
// click: (data) => undefined,
|
||||
// },
|
||||
// ]),
|
||||
];
|
||||
|
||||
constructor(private amountCurrencyService: AmountCurrencyService) {}
|
||||
}
|
@ -6,9 +6,7 @@ import { map, catchError } from 'rxjs/operators';
|
||||
|
||||
import { MerchantStatisticsService } from '../../api/magista';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
@Injectable()
|
||||
export class FetchChargebacksService extends FetchSuperclass<
|
||||
StatChargeback,
|
||||
ChargebackSearchQuery
|
||||
|
@ -1,5 +1,5 @@
|
||||
<v-table
|
||||
[columns]="columns()"
|
||||
<v-table2
|
||||
[columns]="columns"
|
||||
[data]="data"
|
||||
[hasMore]="hasMore"
|
||||
[progress]="isLoading"
|
||||
@ -7,4 +7,4 @@
|
||||
(update)="update.emit($event)"
|
||||
>
|
||||
<v-table-actions><ng-content></ng-content></v-table-actions>
|
||||
</v-table>
|
||||
</v-table2>
|
||||
|
@ -1,20 +1,11 @@
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
booleanAttribute,
|
||||
input,
|
||||
computed,
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Claim, ClaimStatus } from '@vality/domain-proto/claim_management';
|
||||
import { Column, LoadOptions, TagColumn, createOperationColumn } from '@vality/ng-core';
|
||||
import { Component, Input, Output, EventEmitter, booleanAttribute, input } from '@angular/core';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
import { Claim } from '@vality/domain-proto/claim_management';
|
||||
import { Column2, LoadOptions, createMenuColumn } from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import isObject from 'lodash-es/isObject';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
|
||||
import { createPartyColumn } from '../../../shared';
|
||||
import { createPartyColumn } from '@cc/app/shared/utils/table2';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claims-table',
|
||||
@ -30,48 +21,33 @@ export class ClaimsTableComponent {
|
||||
@Output() update = new EventEmitter<LoadOptions>();
|
||||
@Output() more = new EventEmitter<void>();
|
||||
|
||||
columns = computed<Column<Claim>[]>(() =>
|
||||
this.sourceColumns.filter(
|
||||
(c) => (isObject(c) && c?.field !== 'party_id') || !this.noParty(),
|
||||
),
|
||||
);
|
||||
private sourceColumns: Column<Claim>[] = [
|
||||
{ field: 'id', link: (d) => this.getClaimLink(d.party_id, d.id) },
|
||||
createPartyColumn('party_id'),
|
||||
columns: Column2<Claim>[] = [
|
||||
{ field: 'id', cell: (d) => ({ link: () => `/party/${d.party_id}/claim/${d.id}` }) },
|
||||
createPartyColumn((d) => ({ id: d.party_id }), { hidden: toObservable(this.noParty) }),
|
||||
{
|
||||
field: 'status',
|
||||
type: 'tag',
|
||||
formatter: (claim) => getUnionKey(claim.status),
|
||||
typeParameters: {
|
||||
label: (claim) => startCase(getUnionKey(claim.status)),
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
review: { color: 'pending' },
|
||||
pending_acceptance: { color: 'pending' },
|
||||
accepted: { color: 'success' },
|
||||
denied: { color: 'warn' },
|
||||
revoked: { color: 'neutral' },
|
||||
pending: 'pending',
|
||||
review: 'pending',
|
||||
pending_acceptance: 'pending',
|
||||
accepted: 'success',
|
||||
denied: 'warn',
|
||||
revoked: 'neutral',
|
||||
},
|
||||
}),
|
||||
},
|
||||
} as TagColumn<Claim, keyof ClaimStatus>,
|
||||
'revision',
|
||||
{ field: 'created_at', type: 'datetime' },
|
||||
{ field: 'updated_at', type: 'datetime' },
|
||||
createOperationColumn<Claim>([
|
||||
{ field: 'revision' },
|
||||
{ field: 'created_at', cell: { type: 'datetime' } },
|
||||
{ field: 'updated_at', cell: { type: 'datetime' } },
|
||||
createMenuColumn((d) => ({
|
||||
items: [
|
||||
{
|
||||
label: 'Details',
|
||||
click: (claim) => this.navigateToClaim(claim.party_id, claim.id),
|
||||
link: () => `/party/${d.party_id}/claim/${d.id}`,
|
||||
},
|
||||
]),
|
||||
],
|
||||
})),
|
||||
];
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
||||
navigateToClaim(partyId: string, claimID: number) {
|
||||
void this.router.navigate([this.getClaimLink(partyId, claimID)]);
|
||||
}
|
||||
|
||||
private getClaimLink(partyId: string, claimID: number): string {
|
||||
return `/party/${partyId}/claim/${claimID}`;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<cc-page-layout title="Claims">
|
||||
<cc-page-layout fullHeight title="Claims">
|
||||
<cc-page-layout-actions
|
||||
><v-more-filters-button [filters]="filters"></v-more-filters-button
|
||||
></cc-page-layout-actions>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div style="display: flex; flex-direction: column; gap: 24px">
|
||||
<h1 class="mat-headline-5">Reverts</h1>
|
||||
<v-table
|
||||
<v-table2
|
||||
[columns]="columns"
|
||||
[data]="reverts$ | async"
|
||||
[hasMore]="hasMore$ | async"
|
||||
@ -18,5 +18,5 @@
|
||||
Create revert
|
||||
</button>
|
||||
</v-table-actions>
|
||||
</v-table>
|
||||
</v-table2>
|
||||
</div>
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { DepositStatus, StatDeposit, StatDepositRevert } from '@vality/fistful-proto/fistful_stat';
|
||||
import { DialogService, Column, UpdateOptions } from '@vality/ng-core';
|
||||
import { DialogService, UpdateOptions, Column2 } from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
import { createCurrencyColumn } from '@cc/app/shared/utils';
|
||||
import { createCurrencyColumn } from '@cc/app/shared/utils/table2';
|
||||
|
||||
import { CreateRevertDialogComponent } from './create-revert-dialog/create-revert-dialog.component';
|
||||
import { FetchRevertsService } from './services/fetch-reverts/fetch-reverts.service';
|
||||
@ -23,27 +23,29 @@ export class RevertsComponent implements OnInit {
|
||||
reverts$ = this.fetchRevertsService.result$;
|
||||
hasMore$ = this.fetchRevertsService.hasMore$;
|
||||
isLoading$ = this.fetchRevertsService.isLoading$;
|
||||
columns: Column<StatDepositRevert>[] = [
|
||||
columns: Column2<StatDepositRevert>[] = [
|
||||
{ field: 'id' },
|
||||
{
|
||||
field: 'status',
|
||||
type: 'tag',
|
||||
formatter: (d) => getUnionKey(d.status),
|
||||
typeParameters: {
|
||||
label: (d) => startCase(getUnionKey(d.status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
succeeded: { color: 'success' },
|
||||
failed: { color: 'warn' },
|
||||
},
|
||||
},
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.status)),
|
||||
color: (
|
||||
{
|
||||
pending: 'pending',
|
||||
succeeded: 'success',
|
||||
failed: 'warn',
|
||||
} as const
|
||||
)[getUnionKey(d.status)],
|
||||
}),
|
||||
},
|
||||
createCurrencyColumn(
|
||||
'amount',
|
||||
(d) => d.body.amount,
|
||||
(d) => d.body.currency.symbolic_code,
|
||||
(d) => ({
|
||||
amount: d.body.amount,
|
||||
code: d.body.currency.symbolic_code,
|
||||
}),
|
||||
{ header: 'Amount' },
|
||||
),
|
||||
{ field: 'created_at', type: 'datetime' },
|
||||
{ field: 'created_at', cell: { type: 'datetime' } },
|
||||
];
|
||||
|
||||
constructor(
|
||||
|
@ -1,4 +1,4 @@
|
||||
<cc-page-layout title="Deposits">
|
||||
<cc-page-layout fullHeight title="Deposits">
|
||||
<cc-page-layout-actions>
|
||||
<v-more-filters-button [filters]="filters"></v-more-filters-button>
|
||||
</cc-page-layout-actions>
|
||||
@ -22,7 +22,7 @@
|
||||
<cc-merchant-field formControlName="party_id"></cc-merchant-field>
|
||||
</ng-template>
|
||||
</v-filters>
|
||||
<v-table
|
||||
<v-table2
|
||||
[columns]="columns"
|
||||
[data]="deposits$ | async"
|
||||
[hasMore]="hasMore$ | async"
|
||||
@ -31,10 +31,8 @@
|
||||
(update)="reload($event)"
|
||||
>
|
||||
<v-table-actions>
|
||||
<button color="primary" mat-raised-button (click)="createByFile()">
|
||||
Create by file
|
||||
</button>
|
||||
<button mat-raised-button (click)="createByFile()">Create by file</button>
|
||||
<button color="primary" mat-raised-button (click)="createDeposit()">Create</button>
|
||||
</v-table-actions>
|
||||
</v-table>
|
||||
</v-table2>
|
||||
</cc-page-layout>
|
||||
|
@ -2,10 +2,9 @@ import { ChangeDetectionStrategy, Component, OnInit, Inject, DestroyRef } from '
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { NonNullableFormBuilder } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { StatDeposit, RevertStatus } from '@vality/fistful-proto/fistful_stat';
|
||||
import { fistful_stat } from '@vality/fistful-proto';
|
||||
import { StatDeposit } from '@vality/fistful-proto/fistful_stat';
|
||||
import {
|
||||
Column,
|
||||
createOperationColumn,
|
||||
UpdateOptions,
|
||||
createDateRangeToToday,
|
||||
QueryParamsService,
|
||||
@ -17,26 +16,24 @@ import {
|
||||
debounceTimeWithFirst,
|
||||
getValueChanges,
|
||||
countChanged,
|
||||
Column2,
|
||||
getEnumKey,
|
||||
createMenuColumn,
|
||||
} from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import { endOfDay } from 'date-fns';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
import { filter, map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { createCurrencyColumn } from '@cc/app/shared/utils/table2';
|
||||
|
||||
import { QueryDsl } from '../../api/fistful-stat';
|
||||
import { createCurrencyColumn } from '../../shared';
|
||||
import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../../tokens';
|
||||
|
||||
import { CreateDepositDialogComponent } from './components/create-deposit-dialog/create-deposit-dialog.component';
|
||||
import { CreateDepositsByFileDialogComponent } from './components/create-deposits-by-file-dialog/create-deposits-by-file-dialog.component';
|
||||
import { FetchDepositsService } from './services/fetch-deposits/fetch-deposits.service';
|
||||
|
||||
const REVERT_STATUS: { [N in RevertStatus]: string } = {
|
||||
0: 'none',
|
||||
1: 'partial',
|
||||
2: 'full',
|
||||
};
|
||||
|
||||
@Component({
|
||||
templateUrl: 'deposits.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
@ -56,30 +53,31 @@ export class DepositsComponent implements OnInit {
|
||||
deposits$ = this.fetchDepositsService.result$;
|
||||
hasMore$ = this.fetchDepositsService.hasMore$;
|
||||
isLoading$ = this.fetchDepositsService.isLoading$;
|
||||
columns: Column<StatDeposit>[] = [
|
||||
columns: Column2<StatDeposit>[] = [
|
||||
{
|
||||
field: 'id',
|
||||
formatter: (d) => d.description || `#${d.id}`,
|
||||
link: (d) => `/deposits/${d.id}`,
|
||||
description: 'id',
|
||||
maxWidth: 'max(300px, 30vw)',
|
||||
cell: (d) => ({
|
||||
value: d.description || `#${d.id}`,
|
||||
link: () => `/deposits/${d.id}`,
|
||||
description: d.id,
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
type: 'tag',
|
||||
formatter: (d) => getUnionKey(d.status),
|
||||
typeParameters: {
|
||||
label: (d) => startCase(getUnionKey(d.status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
succeeded: { color: 'success' },
|
||||
failed: { color: 'warn' },
|
||||
},
|
||||
},
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.status)),
|
||||
color: (
|
||||
{
|
||||
pending: 'pending',
|
||||
succeeded: 'success',
|
||||
failed: 'warn',
|
||||
} as const
|
||||
)[getUnionKey(d.status)],
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'created_at',
|
||||
type: 'datetime',
|
||||
cell: { type: 'datetime' },
|
||||
},
|
||||
{
|
||||
field: 'destination_id',
|
||||
@ -87,36 +85,33 @@ export class DepositsComponent implements OnInit {
|
||||
{
|
||||
field: 'identity_id',
|
||||
},
|
||||
createCurrencyColumn(
|
||||
'amount',
|
||||
(d) => d.amount,
|
||||
(d) => d.currency_symbolic_code,
|
||||
),
|
||||
createCurrencyColumn(
|
||||
'fee',
|
||||
(d) => d.fee,
|
||||
(d) => d.currency_symbolic_code,
|
||||
{ hide: true },
|
||||
),
|
||||
{
|
||||
field: 'source_id',
|
||||
hide: true,
|
||||
},
|
||||
createCurrencyColumn((d) => ({ amount: d.amount, code: d.currency_symbolic_code }), {
|
||||
header: 'Amount',
|
||||
}),
|
||||
createCurrencyColumn((d) => ({ amount: d.fee, code: d.currency_symbolic_code }), {
|
||||
header: 'Fee',
|
||||
}),
|
||||
{
|
||||
field: 'revert_status',
|
||||
type: 'tag',
|
||||
formatter: (d) => REVERT_STATUS[d.revert_status],
|
||||
typeParameters: {
|
||||
label: (d) => startCase(REVERT_STATUS[d.revert_status]),
|
||||
tags: {},
|
||||
cell: (d) => ({
|
||||
value: startCase(getEnumKey(fistful_stat.RevertStatus, d.revert_status)),
|
||||
color: (
|
||||
{
|
||||
none: 'neutral',
|
||||
partial: 'pending',
|
||||
full: 'success',
|
||||
} as const
|
||||
)[getEnumKey(fistful_stat.RevertStatus, d.revert_status)],
|
||||
}),
|
||||
},
|
||||
},
|
||||
createOperationColumn([
|
||||
createMenuColumn((d) => ({
|
||||
items: [
|
||||
{
|
||||
label: 'Details',
|
||||
click: (d) => this.router.navigate([`/deposits/${d.id}`]),
|
||||
click: () => this.router.navigate([`/deposits/${d.id}`]),
|
||||
},
|
||||
]),
|
||||
],
|
||||
})),
|
||||
];
|
||||
depositStatuses: QueryDsl['query']['deposits']['status'][] = ['Pending', 'Succeeded', 'Failed'];
|
||||
active$ = getValueChanges(this.filtersForm).pipe(
|
||||
|
@ -13,7 +13,6 @@ import {
|
||||
getValueChanges,
|
||||
Column2,
|
||||
createMenuColumn,
|
||||
TABLE_WRAPPER_STYLE,
|
||||
} from '@vality/ng-core';
|
||||
import sortBy from 'lodash-es/sortBy';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
@ -51,7 +50,6 @@ interface DomainObjectData {
|
||||
ActionsModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
host: { style: TABLE_WRAPPER_STYLE },
|
||||
})
|
||||
export class DomainObjectsTableComponent implements OnInit {
|
||||
@Output() selectedChange = new EventEmitter<string[]>();
|
||||
|
@ -0,0 +1,36 @@
|
||||
import { Component, input } from '@angular/core';
|
||||
import { Column2, getEnumKey, TableModule } from '@vality/ng-core';
|
||||
import { repairer } from '@vality/repairer-proto';
|
||||
import { StatusHistory } from '@vality/repairer-proto/repairer';
|
||||
import { startCase } from 'lodash-es';
|
||||
|
||||
import { SidenavInfoModule } from '@cc/app/shared/components/sidenav-info';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
template: `<cc-card title="Machine #{{ id() }} Status History"
|
||||
><v-table2 [columns]="columns" [data]="history()"></v-table2
|
||||
></cc-card>`,
|
||||
imports: [TableModule, SidenavInfoModule],
|
||||
})
|
||||
export class MachineStatusHistoryCardComponent {
|
||||
history = input<StatusHistory[]>([]);
|
||||
id = input<string>('');
|
||||
|
||||
columns: Column2<StatusHistory>[] = [
|
||||
{ field: 'changed_at', cell: { type: 'datetime' } },
|
||||
{
|
||||
field: 'status',
|
||||
cell: (d) => ({
|
||||
value: startCase(getEnumKey(repairer.RepairStatus, d.status)),
|
||||
color: (
|
||||
{
|
||||
failed: 'warn',
|
||||
in_progress: 'pending',
|
||||
repaired: 'success',
|
||||
} as const
|
||||
)[getEnumKey(repairer.RepairStatus, d.status)],
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
@ -3,7 +3,7 @@ import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppAuthGuardService } from '../../shared/services';
|
||||
|
||||
import { RepairingComponent } from './repairing.component';
|
||||
import { MachinesComponent } from './machines.component';
|
||||
import { ROUTING_CONFIG } from './routing-config';
|
||||
|
||||
@NgModule({
|
||||
@ -11,7 +11,7 @@ import { ROUTING_CONFIG } from './routing-config';
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: RepairingComponent,
|
||||
component: MachinesComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: ROUTING_CONFIG,
|
||||
},
|
||||
@ -19,4 +19,4 @@ import { ROUTING_CONFIG } from './routing-config';
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class RepairingRoutingModule {}
|
||||
export class MachinesRoutingModule {}
|
@ -1,4 +1,4 @@
|
||||
<cc-page-layout title="Machines">
|
||||
<cc-page-layout fullHeight title="Machines">
|
||||
<cc-page-layout-actions>
|
||||
<v-more-filters-button [filters]="filters"></v-more-filters-button>
|
||||
</cc-page-layout-actions>
|
||||
@ -33,7 +33,7 @@
|
||||
</ng-template>
|
||||
</v-filters>
|
||||
|
||||
<v-table
|
||||
<v-table2
|
||||
[columns]="columns"
|
||||
[data]="machines$ | async"
|
||||
[hasMore]="hasMore$ | async"
|
||||
@ -61,5 +61,5 @@
|
||||
Simple repair
|
||||
</button>
|
||||
</v-table-actions>
|
||||
</v-table>
|
||||
</v-table2>
|
||||
</cc-page-layout>
|
@ -5,7 +5,6 @@ import {
|
||||
DialogResponseStatus,
|
||||
DialogService,
|
||||
clean,
|
||||
Column,
|
||||
ConfirmDialogComponent,
|
||||
QueryParamsService,
|
||||
NotifyLogService,
|
||||
@ -18,6 +17,7 @@ import {
|
||||
debounceTimeWithFirst,
|
||||
FetchOptions,
|
||||
getEnumKey,
|
||||
Column2,
|
||||
} from '@vality/ng-core';
|
||||
import { repairer } from '@vality/repairer-proto';
|
||||
import { Namespace, ProviderID, RepairStatus, Machine } from '@vality/repairer-proto/repairer';
|
||||
@ -27,10 +27,13 @@ import startCase from 'lodash-es/startCase';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { filter, switchMap, map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { SidenavInfoService } from '@cc/app/shared/components/sidenav-info';
|
||||
import { createDomainObjectColumn } from '@cc/app/shared/utils/table2';
|
||||
|
||||
import { RepairManagementService } from '../../api/repairer';
|
||||
import { createProviderColumn } from '../../shared/utils/table/create-provider-column';
|
||||
import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../../tokens';
|
||||
|
||||
import { MachineStatusHistoryCardComponent } from './components/machine-status-history-card.component';
|
||||
import { RepairByScenarioDialogComponent } from './components/repair-by-scenario-dialog/repair-by-scenario-dialog.component';
|
||||
import { MachinesService } from './services/machines.service';
|
||||
|
||||
@ -44,11 +47,11 @@ interface Filters {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cc-repairing',
|
||||
templateUrl: './repairing.component.html',
|
||||
selector: 'cc-machines',
|
||||
templateUrl: './machines.component.html',
|
||||
providers: [MachinesService],
|
||||
})
|
||||
export class RepairingComponent implements OnInit {
|
||||
export class MachinesComponent implements OnInit {
|
||||
machines$ = this.machinesService.result$;
|
||||
inProgress$ = this.machinesService.isLoading$;
|
||||
hasMore$ = this.machinesService.hasMore$;
|
||||
@ -62,28 +65,36 @@ export class RepairingComponent implements OnInit {
|
||||
});
|
||||
selected$ = new BehaviorSubject<Machine[]>([]);
|
||||
status = repairer.RepairStatus;
|
||||
columns: Column<Machine>[] = [
|
||||
{ field: 'id' },
|
||||
columns: Column2<Machine>[] = [
|
||||
{ field: 'id', sticky: 'start' },
|
||||
{ header: 'Namespace', field: 'ns' },
|
||||
{ field: 'created_at', type: 'datetime' },
|
||||
createProviderColumn((d) => Number(d.provider_id)),
|
||||
{ field: 'created_at', cell: { type: 'datetime' } },
|
||||
createDomainObjectColumn((d) => ({ ref: { terminal: { id: Number(d.provider_id) } } }), {
|
||||
header: 'Terminal',
|
||||
}),
|
||||
{
|
||||
field: 'status',
|
||||
formatter: (d) => getEnumKey(repairer.RepairStatus, d.status),
|
||||
type: 'tag',
|
||||
typeParameters: {
|
||||
label: (d) => startCase(getEnumKey(repairer.RepairStatus, d.status)),
|
||||
tags: {
|
||||
failed: { color: 'warn' },
|
||||
in_progress: { color: 'pending' },
|
||||
repaired: { color: 'success' },
|
||||
},
|
||||
},
|
||||
cell: (d) => ({
|
||||
value: startCase(getEnumKey(repairer.RepairStatus, d.status)),
|
||||
color: (
|
||||
{
|
||||
failed: 'warn',
|
||||
in_progress: 'pending',
|
||||
repaired: 'success',
|
||||
} as const
|
||||
)[getEnumKey(repairer.RepairStatus, d.status)],
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'history',
|
||||
formatter: (data) => (data.history?.length ? String(data.history.length) : ''),
|
||||
tooltip: 'history',
|
||||
cell: (d) => ({
|
||||
value: d.history?.length ? String(d.history.length) : '',
|
||||
click: () => {
|
||||
this.sidenavInfoService.toggle(MachineStatusHistoryCardComponent, {
|
||||
history: d.history,
|
||||
});
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'error_message',
|
||||
@ -106,6 +117,7 @@ export class RepairingComponent implements OnInit {
|
||||
private destroyRef: DestroyRef,
|
||||
@Inject(DATE_RANGE_DAYS) private dateRangeDays: number,
|
||||
@Inject(DEBOUNCE_TIME_MS) private debounceTimeMs: number,
|
||||
private sidenavInfoService: SidenavInfoService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
@ -28,13 +28,13 @@ import { ThriftFormModule } from '@cc/app/shared/components/metadata-form';
|
||||
import { DomainObjectFieldComponent } from '@cc/app/shared/components/thrift-api-crud';
|
||||
|
||||
import { RepairByScenarioDialogComponent } from './components/repair-by-scenario-dialog/repair-by-scenario-dialog.component';
|
||||
import { RepairingRoutingModule } from './repairing-routing.module';
|
||||
import { RepairingComponent } from './repairing.component';
|
||||
import { MachinesRoutingModule } from './machines-routing.module';
|
||||
import { MachinesComponent } from './machines.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
RepairingRoutingModule,
|
||||
MachinesRoutingModule,
|
||||
TableModule,
|
||||
MatCardModule,
|
||||
ReactiveFormsModule,
|
||||
@ -59,6 +59,6 @@ import { RepairingComponent } from './repairing.component';
|
||||
ThriftPipesModule,
|
||||
FiltersModule,
|
||||
],
|
||||
declarations: [RepairingComponent, RepairByScenarioDialogComponent],
|
||||
declarations: [MachinesComponent, RepairByScenarioDialogComponent],
|
||||
})
|
||||
export class RepairingModule {}
|
||||
export class MachinesModule {}
|
@ -1,4 +1,4 @@
|
||||
<cc-page-layout title="Shops">
|
||||
<cc-page-layout fullHeight title="Shops">
|
||||
<cc-shops-table
|
||||
[progress]="progress$ | async"
|
||||
[shops]="shopsParty$ | async"
|
||||
|
@ -1,3 +1,3 @@
|
||||
<cc-sub-page-layout [links]="links" [tags]="tags$ | async"
|
||||
><router-outlet></router-outlet
|
||||
></cc-sub-page-layout>
|
||||
<cc-sub-page-layout [links]="links">
|
||||
<router-outlet></router-outlet>
|
||||
</cc-sub-page-layout>
|
||||
|
@ -1,10 +1,12 @@
|
||||
<cc-page-layout [progress]="isLoading$ | async" title="Chargebacks">
|
||||
<cc-page-layout-actions>
|
||||
<cc-page-layout [progress]="isLoading$ | async" fullHeight title="Chargebacks">
|
||||
<cc-chargebacks-table
|
||||
[data]="chargebacks$ | async"
|
||||
[hasMore]="fetchChargebacksService.hasMore$ | async"
|
||||
[isLoading]="isLoading$ | async"
|
||||
onePayment
|
||||
(more)="fetchChargebacksService.more()"
|
||||
(update)="update()"
|
||||
>
|
||||
<button color="primary" mat-raised-button (click)="createChargeback()">Create</button>
|
||||
</cc-page-layout-actions>
|
||||
<cc-chargebacks
|
||||
[chargebacks]="chargebacks$ | async"
|
||||
[invoiceId]="(payment$ | async).invoice_id"
|
||||
[paymentId]="(payment$ | async).id"
|
||||
></cc-chargebacks>
|
||||
</cc-chargebacks-table>
|
||||
</cc-page-layout>
|
||||
|
@ -1,49 +1,42 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, DestroyRef } from '@angular/core';
|
||||
import { Component, DestroyRef, OnInit } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { DialogResponseStatus, DialogService } from '@vality/ng-core';
|
||||
import { merge, defer, Subject } from 'rxjs';
|
||||
import { map, switchMap, shareReplay } from 'rxjs/operators';
|
||||
import { first } from 'rxjs';
|
||||
|
||||
import { FetchChargebacksService } from '@cc/app/sections/chargebacks/fetch-chargebacks.service';
|
||||
import { ChargebacksTableComponent } from '@cc/app/shared/components/chargebacks-table';
|
||||
|
||||
import { InvoicingService } from '../../../../api/payment-processing';
|
||||
import { PageLayoutModule } from '../../../../shared';
|
||||
import { ChargebacksComponent } from '../../../../shared/components/chargebacks/chargebacks.component';
|
||||
import { CreateChargebackDialogComponent } from '../../create-chargeback-dialog/create-chargeback-dialog.component';
|
||||
import { PaymentDetailsService } from '../../payment-details.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-payment-chargebacks',
|
||||
standalone: true,
|
||||
imports: [CommonModule, PageLayoutModule, MatButton, ChargebacksComponent],
|
||||
imports: [CommonModule, PageLayoutModule, MatButton, ChargebacksTableComponent],
|
||||
templateUrl: './payment-chargebacks.component.html',
|
||||
styles: ``,
|
||||
providers: [FetchChargebacksService],
|
||||
})
|
||||
export class PaymentChargebacksComponent {
|
||||
export class PaymentChargebacksComponent implements OnInit {
|
||||
payment$ = this.paymentDetailsService.payment$;
|
||||
isLoading$ = this.paymentDetailsService.isLoading$;
|
||||
chargebacks$ = merge(
|
||||
this.route.params,
|
||||
defer(() => this.updateChargebacks$),
|
||||
).pipe(
|
||||
map(() => this.route.snapshot.params as Record<'invoiceID' | 'paymentID', string>),
|
||||
switchMap(({ invoiceID, paymentID }) =>
|
||||
this.invoicingService.GetPayment(invoiceID, paymentID),
|
||||
),
|
||||
map(({ chargebacks }) => chargebacks),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
private updateChargebacks$ = new Subject<void>();
|
||||
chargebacks$ = this.fetchChargebacksService.result$;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private invoicingService: InvoicingService,
|
||||
private dialogService: DialogService,
|
||||
private dr: DestroyRef,
|
||||
private paymentDetailsService: PaymentDetailsService,
|
||||
protected fetchChargebacksService: FetchChargebacksService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.update();
|
||||
}
|
||||
|
||||
createChargeback() {
|
||||
this.dialogService
|
||||
.open(
|
||||
@ -54,8 +47,21 @@ export class PaymentChargebacksComponent {
|
||||
.pipe(takeUntilDestroyed(this.dr))
|
||||
.subscribe(({ status }) => {
|
||||
if (status === DialogResponseStatus.Success) {
|
||||
this.updateChargebacks$.next();
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
update() {
|
||||
this.payment$.pipe(first(), takeUntilDestroyed(this.dr)).subscribe((p) => {
|
||||
this.fetchChargebacksService.load({
|
||||
common_search_query_params: {
|
||||
from_time: new Date(0).toISOString(),
|
||||
to_time: new Date().toISOString(),
|
||||
},
|
||||
payment_id: p.id,
|
||||
invoice_ids: [p.invoice_id],
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { InvoicePaymentChargeback } from '@vality/domain-proto/domain';
|
||||
import { InvoicePaymentChargebackParams } from '@vality/domain-proto/payment_processing';
|
||||
import { DialogSuperclass, NotifyLogService } from '@vality/ng-core';
|
||||
import { from } from 'rxjs';
|
||||
import { DialogSuperclass, getImportValue, NotifyLogService } from '@vality/ng-core';
|
||||
import { ThriftAstMetadata } from '@vality/ng-thrift';
|
||||
import short from 'short-uuid';
|
||||
|
||||
import { InvoicingService } from '@cc/app/api/payment-processing';
|
||||
@ -20,7 +20,7 @@ export class CreateChargebackDialogComponent extends DialogSuperclass<
|
||||
InvoicePaymentChargeback
|
||||
> {
|
||||
form = new FormControl<Partial<InvoicePaymentChargebackParams>>({ id: short().generate() });
|
||||
metadata$ = from(import('@vality/domain-proto/metadata.json').then((m) => m.default));
|
||||
metadata$ = getImportValue<ThriftAstMetadata[]>(import('@vality/domain-proto/metadata.json'));
|
||||
extensions$ = this.domainMetadataFormExtensionsService.extensions$;
|
||||
|
||||
constructor(
|
||||
|
@ -5,7 +5,6 @@
|
||||
{ label: 'Refunds', url: 'refunds' },
|
||||
{ label: 'Chargebacks', url: 'chargebacks' }
|
||||
]"
|
||||
[tags]="tags$ | async"
|
||||
id="{{
|
||||
(payment$ | async) ? (payment$ | async)?.invoice_id + '.' + (payment$ | async)?.id : ''
|
||||
}}"
|
||||
|
@ -12,7 +12,6 @@ import { StatusModule, PageLayoutModule, SubPageLayoutComponent } from '@cc/app/
|
||||
import { DetailsItemModule } from '@cc/components/details-item';
|
||||
import { HeadlineModule } from '@cc/components/headline';
|
||||
|
||||
import { ChargebacksComponent } from '../../shared/components/chargebacks/chargebacks.component';
|
||||
import { JsonViewerModule } from '../../shared/components/json-viewer';
|
||||
import { ThriftFormModule } from '../../shared/components/metadata-form';
|
||||
import { MagistaThriftViewerComponent } from '../../shared/components/thrift-api-crud';
|
||||
@ -34,7 +33,6 @@ import { RefundsTableModule } from './refunds-table';
|
||||
MatProgressSpinnerModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
ChargebacksComponent,
|
||||
ActionsModule,
|
||||
DialogModule,
|
||||
ThriftFormModule,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { StatPayment } from '@vality/magista-proto/magista';
|
||||
import { LoadOptions, Column2, createMenuColumn, TABLE_WRAPPER_STYLE } from '@vality/ng-core';
|
||||
import { LoadOptions, Column2, createMenuColumn } from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
|
||||
@ -18,7 +18,6 @@ import {
|
||||
@Component({
|
||||
selector: 'cc-payments-table',
|
||||
templateUrl: './payments-table.component.html',
|
||||
host: { style: TABLE_WRAPPER_STYLE },
|
||||
})
|
||||
export class PaymentsTableComponent {
|
||||
@Input() data!: StatPayment[];
|
||||
|
@ -34,7 +34,7 @@ const ROUTES: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'machines',
|
||||
loadChildren: () => import('./repairing/repairing.module').then((m) => m.RepairingModule),
|
||||
loadChildren: () => import('./machines/machines.module').then((m) => m.MachinesModule),
|
||||
},
|
||||
{
|
||||
path: 'payments',
|
||||
|
@ -1,9 +1,7 @@
|
||||
<cc-page-layout title="Shops">
|
||||
<cc-page-layout-actions></cc-page-layout-actions>
|
||||
<cc-page-layout fullHeight title="Shops">
|
||||
<cc-shops-table
|
||||
[progress]="progress$ | async"
|
||||
[shops]="shopsParty$ | async"
|
||||
noSort
|
||||
(filterChange)="filterChange$.next($event)"
|
||||
(update)="update()"
|
||||
></cc-shops-table>
|
||||
|
@ -2,7 +2,14 @@ import { Component } from '@angular/core';
|
||||
import { SearchShopHit } from '@vality/deanonimus-proto/deanonimus';
|
||||
import { Column, progressTo, NotifyLogService } from '@vality/ng-core';
|
||||
import { BehaviorSubject, defer, of, combineLatest, Subject, Observable } from 'rxjs';
|
||||
import { switchMap, shareReplay, catchError, map } from 'rxjs/operators';
|
||||
import {
|
||||
switchMap,
|
||||
shareReplay,
|
||||
catchError,
|
||||
map,
|
||||
debounceTime,
|
||||
distinctUntilChanged,
|
||||
} from 'rxjs/operators';
|
||||
|
||||
import { DeanonimusService } from '../../api/deanonimus';
|
||||
import { ShopParty } from '../../shared/components/shops-table';
|
||||
@ -14,7 +21,7 @@ import { ShopParty } from '../../shared/components/shops-table';
|
||||
export class ShopsComponent {
|
||||
filterChange$ = new Subject<string>();
|
||||
shopsParty$: Observable<ShopParty[]> = combineLatest([
|
||||
this.filterChange$,
|
||||
this.filterChange$.pipe(distinctUntilChanged(), debounceTime(500)),
|
||||
defer(() => this.updateShops$),
|
||||
]).pipe(
|
||||
switchMap(([search]) =>
|
||||
|
@ -1,13 +1,12 @@
|
||||
<cc-page-layout title="Sources">
|
||||
<cc-page-layout fullHeight title="Sources">
|
||||
<cc-page-layout-actions>
|
||||
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
||||
</cc-page-layout-actions>
|
||||
<v-table
|
||||
<v-table2
|
||||
[(sort)]="sort"
|
||||
[columns]="columns"
|
||||
[data]="sources$ | async"
|
||||
[progress]="!!(progress$ | async)"
|
||||
[sort]="{ direction: 'asc', active: 'name' }"
|
||||
noActions
|
||||
sortOnFront
|
||||
></v-table>
|
||||
standaloneFilter
|
||||
></v-table2>
|
||||
</cc-page-layout>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { Source } from '@vality/fistful-proto/internal/source';
|
||||
import { DialogService, Column } from '@vality/ng-core';
|
||||
import { DialogService, Column2 } from '@vality/ng-core';
|
||||
|
||||
import { CreateSourceComponent } from './create-source/create-source.component';
|
||||
import { FetchSourcesService } from './fetch-sources.service';
|
||||
@ -11,13 +12,14 @@ import { FetchSourcesService } from './fetch-sources.service';
|
||||
export class SourcesComponent {
|
||||
sources$ = this.fetchSourcesService.sources$;
|
||||
progress$ = this.fetchSourcesService.progress$;
|
||||
columns: Column<Source>[] = [
|
||||
columns: Column2<Source>[] = [
|
||||
{ field: 'id' },
|
||||
{ field: 'name', sortable: true },
|
||||
'identity',
|
||||
{ field: 'currency_symbolic_code', sortable: true },
|
||||
{ field: 'created_at', type: 'datetime' },
|
||||
{ field: 'name' },
|
||||
{ field: 'identity' },
|
||||
{ field: 'currency_symbolic_code' },
|
||||
{ field: 'created_at', cell: { type: 'datetime' } },
|
||||
];
|
||||
sort: Sort = { direction: 'asc', active: 'name' };
|
||||
|
||||
constructor(
|
||||
private fetchSourcesService: FetchSourcesService,
|
||||
|
@ -1,6 +1,7 @@
|
||||
<cc-page-layout title="Wallets">
|
||||
<cc-page-layout fullHeight title="Wallets">
|
||||
<cc-page-layout-actions>
|
||||
<v-more-filters-button *ngIf="filters" [filters]="filters"></v-more-filters-button>
|
||||
@if (!(party$ | async)) {
|
||||
<v-switch-button
|
||||
[formControl]="isFilterControl"
|
||||
[states]="[
|
||||
@ -8,13 +9,10 @@
|
||||
{ label: 'filters', icon: 'manage_search' }
|
||||
]"
|
||||
></v-switch-button>
|
||||
}
|
||||
</cc-page-layout-actions>
|
||||
<v-filters
|
||||
*ngIf="isFilterControl.value"
|
||||
[active]="active$ | async"
|
||||
merge
|
||||
(clear)="filtersForm.reset()"
|
||||
>
|
||||
@if (isFilterTable$ | async) {
|
||||
<v-filters [active]="active$ | async" merge (clear)="filtersForm.reset()">
|
||||
<ng-template [formGroup]="filtersForm">
|
||||
<cc-merchant-field
|
||||
*ngIf="!(party$ | async)"
|
||||
@ -28,26 +26,28 @@
|
||||
<cc-currency-field formControlName="currency_code"></cc-currency-field>
|
||||
</ng-template>
|
||||
</v-filters>
|
||||
}
|
||||
|
||||
<v-table
|
||||
*ngIf="isFilterControl.value"
|
||||
[columns]="filterColumns$ | async"
|
||||
@if (isFilterTable$ | async) {
|
||||
<v-table2
|
||||
[columns]="filterColumns"
|
||||
[data]="filterWallets$ | async"
|
||||
[hasMore]="filterHasMore$ | async"
|
||||
[progress]="filtersLoading$ | async"
|
||||
name="filterWallets"
|
||||
(more)="filterMore()"
|
||||
(update)="filterSearch($event)"
|
||||
></v-table>
|
||||
<v-table
|
||||
*ngIf="!isFilterControl.value"
|
||||
></v-table2>
|
||||
} @else {
|
||||
<v-table2
|
||||
[columns]="fullTextSearchColumns"
|
||||
[data]="fullTextSearchWallets$ | async"
|
||||
[progress]="fullTextSearchLoading$ | async"
|
||||
externalFilter
|
||||
name="ftsWallets"
|
||||
noActions
|
||||
standaloneFilter
|
||||
(filterChange)="fullTextSearch($event)"
|
||||
(update)="fullTextSearchReload()"
|
||||
></v-table>
|
||||
></v-table2>
|
||||
}
|
||||
</cc-page-layout>
|
||||
|
@ -1,12 +1,4 @@
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Inject,
|
||||
ViewChild,
|
||||
DestroyRef,
|
||||
Injector,
|
||||
runInInjectionContext,
|
||||
} from '@angular/core';
|
||||
import { Component, OnInit, Inject, ViewChild, DestroyRef } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { FormControl, NonNullableFormBuilder } from '@angular/forms';
|
||||
import { SearchWalletHit } from '@vality/deanonimus-proto/internal/deanonimus';
|
||||
@ -15,17 +7,17 @@ import { AccountBalance } from '@vality/fistful-proto/internal/account';
|
||||
import { StatWallet } from '@vality/fistful-proto/internal/fistful_stat';
|
||||
import {
|
||||
clean,
|
||||
Column,
|
||||
QueryParamsService,
|
||||
NotifyLogService,
|
||||
FiltersComponent,
|
||||
UpdateOptions,
|
||||
getValueChanges,
|
||||
countChanged,
|
||||
debounceTimeWithFirst,
|
||||
Column2,
|
||||
DebounceTime,
|
||||
} from '@vality/ng-core';
|
||||
import isNil from 'lodash-es/isNil';
|
||||
import { of } from 'rxjs';
|
||||
import { combineLatest, of } from 'rxjs';
|
||||
import { map, shareReplay, catchError, take } from 'rxjs/operators';
|
||||
import { MemoizeExpiring } from 'typescript-memoize';
|
||||
|
||||
@ -33,7 +25,7 @@ import { WalletParams } from '@cc/app/api/fistful-stat/query-dsl/types/wallet';
|
||||
import { ManagementService } from '@cc/app/api/wallet';
|
||||
|
||||
import { IdentityManagementService } from '../../api/identity';
|
||||
import { createCurrencyColumn, createPartyColumn } from '../../shared';
|
||||
import { createCurrencyColumn, createPartyColumn } from '../../shared/utils/table2';
|
||||
import { DEBOUNCE_TIME_MS } from '../../tokens';
|
||||
import { PartyStoreService } from '../party';
|
||||
|
||||
@ -55,81 +47,81 @@ export class WalletsComponent implements OnInit {
|
||||
fullTextSearchWallets$ = this.fetchWalletsTextService.result$;
|
||||
fullTextSearchLoading$ = this.fetchWalletsTextService.isLoading$;
|
||||
|
||||
filterColumns$ = this.partyStoreService.party$.pipe(
|
||||
map((party) =>
|
||||
runInInjectionContext(this.injector, () => [
|
||||
filterColumns: Column2<StatWallet>[] = [
|
||||
{ field: 'id' },
|
||||
{ field: 'name' },
|
||||
'currency_symbolic_code',
|
||||
'identity_id',
|
||||
{ field: 'created_at', type: 'datetime' },
|
||||
createCurrencyColumn<StatWallet>(
|
||||
'balance',
|
||||
(d) => this.getBalance(d.id).pipe(map((b) => b.current)),
|
||||
(d) => this.getBalance(d.id).pipe(map((b) => b.currency.symbolic_code)),
|
||||
{ lazy: true },
|
||||
{ field: 'currency_symbolic_code' },
|
||||
{ field: 'identity_id' },
|
||||
{ field: 'created_at', cell: { type: 'datetime' } },
|
||||
createCurrencyColumn(
|
||||
(d) =>
|
||||
this.getBalance(d.id).pipe(
|
||||
map((b) => ({ amount: b.current, code: b.currency.symbolic_code })),
|
||||
),
|
||||
createCurrencyColumn<StatWallet>(
|
||||
'hold',
|
||||
(d) => this.getBalance(d.id).pipe(map((b) => b.current - b.expected_min)),
|
||||
(d) => this.getBalance(d.id).pipe(map((b) => b.currency.symbolic_code)),
|
||||
{ lazy: true },
|
||||
{ header: 'Balance', isLazyCell: true },
|
||||
),
|
||||
createCurrencyColumn<StatWallet>(
|
||||
'expected_min',
|
||||
(d) => this.getBalance(d.id).pipe(map((b) => b.expected_min)),
|
||||
(d) => this.getBalance(d.id).pipe(map((b) => b.currency.symbolic_code)),
|
||||
{ lazy: true },
|
||||
createCurrencyColumn(
|
||||
(d) =>
|
||||
this.getBalance(d.id).pipe(
|
||||
map((b) => ({
|
||||
amount: b.current - b.expected_min,
|
||||
code: b.currency.symbolic_code,
|
||||
})),
|
||||
),
|
||||
{ header: 'Hold', isLazyCell: true },
|
||||
),
|
||||
createCurrencyColumn(
|
||||
(d) =>
|
||||
this.getBalance(d.id).pipe(
|
||||
map((b) => ({ amount: b.expected_min, code: b.currency.symbolic_code })),
|
||||
),
|
||||
{ header: 'Expected Min', isLazyCell: true },
|
||||
),
|
||||
{
|
||||
field: 'contract_id',
|
||||
formatter: (d) =>
|
||||
lazyCell: (d) =>
|
||||
this.getIdentity(d.identity_id).pipe(
|
||||
map((identity) => identity.contract_id),
|
||||
map((identity) => ({ value: identity.contract_id })),
|
||||
),
|
||||
lazy: true,
|
||||
},
|
||||
...(party
|
||||
? []
|
||||
: [
|
||||
createPartyColumn<StatWallet>(
|
||||
'party',
|
||||
createPartyColumn(
|
||||
(d) =>
|
||||
this.getIdentity(d.identity_id).pipe(
|
||||
map((identity) => identity.party_id),
|
||||
map((identity) => ({ id: identity.party_id })),
|
||||
),
|
||||
undefined,
|
||||
{ lazy: true },
|
||||
{ hidden: this.partyStoreService.party$.pipe(map((p) => !p)) },
|
||||
),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
);
|
||||
fullTextSearchColumns: Column<SearchWalletHit>[] = [
|
||||
];
|
||||
fullTextSearchColumns: Column2<SearchWalletHit>[] = [
|
||||
{ field: 'wallet.id' },
|
||||
{ field: 'wallet.name' },
|
||||
createPartyColumn<SearchWalletHit>(
|
||||
'party',
|
||||
(d) => d.party.id,
|
||||
(d) => d.party.email,
|
||||
createPartyColumn((d) => ({
|
||||
id: d.party.id,
|
||||
partyName: d.party.email,
|
||||
})),
|
||||
createCurrencyColumn(
|
||||
(d) =>
|
||||
this.getBalance(d.wallet.id).pipe(
|
||||
map((b) => ({ amount: b.current, code: b.currency.symbolic_code })),
|
||||
),
|
||||
createCurrencyColumn<SearchWalletHit>(
|
||||
'balance',
|
||||
(d) => this.getBalance(d.wallet.id).pipe(map((b) => b.current)),
|
||||
(d) => this.getBalance(d.wallet.id).pipe(map((b) => b.currency.symbolic_code)),
|
||||
{ lazy: true },
|
||||
{ header: 'Balance', isLazyCell: true },
|
||||
),
|
||||
createCurrencyColumn<SearchWalletHit>(
|
||||
'hold',
|
||||
(d) => this.getBalance(d.wallet.id).pipe(map((b) => b.current - b.expected_min)),
|
||||
(d) => this.getBalance(d.wallet.id).pipe(map((b) => b.currency.symbolic_code)),
|
||||
{ lazy: true },
|
||||
createCurrencyColumn(
|
||||
(d) =>
|
||||
this.getBalance(d.wallet.id).pipe(
|
||||
map((b) => ({
|
||||
amount: b.current - b.expected_min,
|
||||
code: b.currency.symbolic_code,
|
||||
})),
|
||||
),
|
||||
createCurrencyColumn<SearchWalletHit>(
|
||||
'expected_min',
|
||||
(d) => this.getBalance(d.wallet.id).pipe(map((b) => b.expected_min)),
|
||||
(d) => this.getBalance(d.wallet.id).pipe(map((b) => b.currency.symbolic_code)),
|
||||
{ lazy: true },
|
||||
{ header: 'Hold', isLazyCell: true },
|
||||
),
|
||||
createCurrencyColumn(
|
||||
(d) =>
|
||||
this.getBalance(d.wallet.id).pipe(
|
||||
map((b) => ({ amount: b.expected_min, code: b.currency.symbolic_code })),
|
||||
),
|
||||
{ header: 'Expected Min', isLazyCell: true },
|
||||
),
|
||||
];
|
||||
filtersForm = this.fb.group({
|
||||
@ -145,6 +137,10 @@ export class WalletsComponent implements OnInit {
|
||||
@ViewChild(FiltersComponent) filters!: FiltersComponent;
|
||||
typeQp = this.qp.createNamespace<{ isFilter: boolean }>('type');
|
||||
party$ = this.partyStoreService.party$;
|
||||
isFilterTable$ = combineLatest([getValueChanges(this.isFilterControl), this.party$]).pipe(
|
||||
map(([isFilterControl, party]) => isFilterControl || !!party),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
|
||||
private initFilters = this.filtersForm.value;
|
||||
|
||||
@ -154,12 +150,10 @@ export class WalletsComponent implements OnInit {
|
||||
private qp: QueryParamsService<WalletParams>,
|
||||
private fb: NonNullableFormBuilder,
|
||||
private walletManagementService: ManagementService,
|
||||
private log: NotifyLogService,
|
||||
@Inject(DEBOUNCE_TIME_MS) private debounceTimeMs: number,
|
||||
private destroyRef: DestroyRef,
|
||||
private identityManagementService: IdentityManagementService,
|
||||
private partyStoreService: PartyStoreService,
|
||||
private injector: Injector,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -198,6 +192,7 @@ export class WalletsComponent implements OnInit {
|
||||
this.fetchWalletsService.more();
|
||||
}
|
||||
|
||||
@DebounceTime()
|
||||
fullTextSearch(text: string) {
|
||||
this.fetchWalletsTextService.load(text);
|
||||
}
|
||||
|
@ -13,8 +13,10 @@ import {
|
||||
NotifyLogService,
|
||||
EnumKeysPipe,
|
||||
EnumKeyPipe,
|
||||
getImportValue,
|
||||
} from '@vality/ng-core';
|
||||
import { from, BehaviorSubject } from 'rxjs';
|
||||
import { ThriftAstMetadata } from '@vality/ng-thrift';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { InvoicingService } from '@cc/app/api/payment-processing';
|
||||
import { DomainMetadataFormExtensionsService } from '@cc/app/shared/services';
|
||||
@ -57,7 +59,7 @@ export class ChangeChargebacksStatusDialogComponent
|
||||
>
|
||||
implements OnInit
|
||||
{
|
||||
metadata$ = from(import('@vality/domain-proto/metadata.json').then((m) => m.default));
|
||||
metadata$ = getImportValue<ThriftAstMetadata[]>(import('@vality/domain-proto/metadata.json'));
|
||||
extensions$ = this.domainMetadataFormExtensionsService.extensions$;
|
||||
control = new FormControl();
|
||||
actionControl = new FormControl<Action>(null, Validators.required);
|
||||
|
@ -1,15 +1,17 @@
|
||||
<v-table
|
||||
<v-table2
|
||||
[(rowSelected)]="selected"
|
||||
[columns]="columns"
|
||||
[data]="data"
|
||||
[hasMore]="hasMore"
|
||||
[progress]="isLoading"
|
||||
[rowSelected]="selected"
|
||||
rowSelectable
|
||||
(more)="more.emit()"
|
||||
(rowSelectedChange)="selectedChange.emit($event)"
|
||||
(update)="update.emit($event)"
|
||||
>
|
||||
<v-table-actions>
|
||||
<button [disabled]="!selected().length" mat-raised-button (click)="changeStatuses()">
|
||||
Change statuses
|
||||
</button>
|
||||
<ng-content></ng-content>
|
||||
</v-table-actions>
|
||||
</v-table>
|
||||
</v-table2>
|
@ -0,0 +1,155 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
booleanAttribute,
|
||||
input,
|
||||
DestroyRef,
|
||||
model,
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { StatChargeback } from '@vality/magista-proto/magista';
|
||||
import {
|
||||
LoadOptions,
|
||||
Column2,
|
||||
TableModule,
|
||||
DialogService,
|
||||
createMenuColumn,
|
||||
DialogResponseStatus,
|
||||
} from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
import { filter } from 'rxjs';
|
||||
|
||||
import { createCurrencyColumn, createPartyColumn, createShopColumn } from '../../utils/table2';
|
||||
import { ChangeChargebacksStatusDialogComponent } from '../change-chargebacks-status-dialog';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'cc-chargebacks-table',
|
||||
templateUrl: './chargebacks-table.component.html',
|
||||
imports: [CommonModule, TableModule, MatButtonModule],
|
||||
})
|
||||
export class ChargebacksTableComponent {
|
||||
@Input() data!: StatChargeback[];
|
||||
@Input() isLoading?: boolean | null;
|
||||
@Input() hasMore?: boolean | null;
|
||||
selected = model<StatChargeback[]>([]);
|
||||
onePayment = input(false, { transform: booleanAttribute });
|
||||
|
||||
@Output() selectedChange = new EventEmitter<StatChargeback[]>();
|
||||
@Output() update = new EventEmitter<LoadOptions>();
|
||||
@Output() more = new EventEmitter<void>();
|
||||
|
||||
columns: Column2<StatChargeback>[] = [
|
||||
{ field: 'chargeback_id', header: 'Id' },
|
||||
{
|
||||
field: 'chargeback_reason',
|
||||
header: 'Reason',
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.chargeback_reason.category)),
|
||||
description: d.chargeback_reason.code,
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'chargeback_status',
|
||||
header: 'Status',
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.chargeback_status)),
|
||||
color: (
|
||||
{
|
||||
pending: 'pending',
|
||||
accepted: 'success',
|
||||
rejected: 'warn',
|
||||
cancelled: 'neutral',
|
||||
} as const
|
||||
)[getUnionKey(d.chargeback_status)],
|
||||
}),
|
||||
},
|
||||
createCurrencyColumn((d) => ({ amount: d.amount, code: d.currency_code.symbolic_code }), {
|
||||
header: 'Amount',
|
||||
}),
|
||||
createCurrencyColumn(
|
||||
(d) => ({ amount: d.levy_amount, code: d.levy_currency_code.symbolic_code }),
|
||||
{ header: 'Levy Amount' },
|
||||
),
|
||||
createCurrencyColumn((d) => ({ amount: d.fee, code: d.currency_code.symbolic_code }), {
|
||||
header: 'Fee',
|
||||
}),
|
||||
createCurrencyColumn(
|
||||
(d) => ({ amount: d.provider_fee, code: d.currency_code.symbolic_code }),
|
||||
{ header: 'Provider Fee' },
|
||||
),
|
||||
createCurrencyColumn(
|
||||
(d) => ({ amount: d.external_fee, code: d.currency_code.symbolic_code }),
|
||||
{ header: 'External Fee' },
|
||||
),
|
||||
{
|
||||
field: 'stage',
|
||||
cell: (d) => ({ value: startCase(getUnionKey(d.stage)) }),
|
||||
},
|
||||
{
|
||||
field: 'invoice_id',
|
||||
header: {
|
||||
value: 'Invoice Id',
|
||||
description: 'Payment Id',
|
||||
},
|
||||
cell: (d) => ({
|
||||
description: d.payment_id,
|
||||
link: () => `/party/${d.party_id}/invoice/${d.invoice_id}/payment/${d.payment_id}`,
|
||||
}),
|
||||
hidden: toObservable(this.onePayment),
|
||||
},
|
||||
{
|
||||
field: 'created_at',
|
||||
cell: { type: 'datetime' },
|
||||
},
|
||||
createPartyColumn((d) => ({ id: d.party_id }), { hidden: toObservable(this.onePayment) }),
|
||||
createShopColumn((d) => ({ shopId: d.shop_id, partyId: d.party_id }), {
|
||||
hidden: toObservable(this.onePayment),
|
||||
}),
|
||||
createMenuColumn((d) => ({
|
||||
items: [
|
||||
{
|
||||
label: 'Change status',
|
||||
click: () => {
|
||||
this.changeStatus(d);
|
||||
},
|
||||
},
|
||||
],
|
||||
})),
|
||||
];
|
||||
|
||||
constructor(
|
||||
private dialogService: DialogService,
|
||||
private dr: DestroyRef,
|
||||
) {}
|
||||
|
||||
changeStatus(chargeback: StatChargeback) {
|
||||
this.dialogService.open(ChangeChargebacksStatusDialogComponent, {
|
||||
chargebacks: [
|
||||
{
|
||||
payment_id: chargeback.payment_id,
|
||||
invoice_id: chargeback.invoice_id,
|
||||
chargeback_id: chargeback.chargeback_id,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
changeStatuses() {
|
||||
this.dialogService
|
||||
.open(ChangeChargebacksStatusDialogComponent, { chargebacks: this.selected() })
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((res) => res.status === DialogResponseStatus.Success),
|
||||
takeUntilDestroyed(this.dr),
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.update.emit();
|
||||
});
|
||||
}
|
||||
}
|
1
src/app/shared/components/chargebacks-table/index.ts
Normal file
1
src/app/shared/components/chargebacks-table/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './chargebacks-table.component';
|
@ -1 +0,0 @@
|
||||
<v-table [columns]="columns" [data]="chargebacks"></v-table>
|
@ -1,84 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { InvoicePaymentChargeback } from '@vality/domain-proto/payment_processing';
|
||||
import { DialogService, Column, TableModule, createOperationColumn } from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
|
||||
import { createCurrencyColumn } from '@cc/app/shared';
|
||||
import { DetailsDialogComponent } from '@cc/app/shared/components/details-dialog/details-dialog.component';
|
||||
|
||||
import { ChangeChargebacksStatusDialogComponent } from '../change-chargebacks-status-dialog';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'cc-chargebacks',
|
||||
templateUrl: './chargebacks.component.html',
|
||||
imports: [CommonModule, TableModule],
|
||||
})
|
||||
export class ChargebacksComponent {
|
||||
@Input() chargebacks: InvoicePaymentChargeback[];
|
||||
@Input() paymentId: string;
|
||||
@Input() invoiceId: string;
|
||||
|
||||
columns: Column<InvoicePaymentChargeback>[] = [
|
||||
'chargeback.id',
|
||||
{
|
||||
field: 'status',
|
||||
type: 'tag',
|
||||
formatter: (d) => getUnionKey(d.chargeback.status),
|
||||
typeParameters: {
|
||||
label: (d) => startCase(getUnionKey(d.chargeback.status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
accepted: { color: 'success' },
|
||||
rejected: { color: 'warn' },
|
||||
cancelled: { color: 'neutral' },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ field: 'chargeback.created_at', type: 'datetime' },
|
||||
createCurrencyColumn(
|
||||
'body',
|
||||
(d) => d.chargeback.body.amount,
|
||||
(d) => d.chargeback.body.currency.symbolic_code,
|
||||
),
|
||||
createCurrencyColumn(
|
||||
'levy',
|
||||
(d) => d.chargeback.levy.amount,
|
||||
(d) => d.chargeback.levy.currency.symbolic_code,
|
||||
),
|
||||
{ field: 'stage', formatter: (d) => getUnionKey(d.chargeback.stage) },
|
||||
createOperationColumn([
|
||||
{
|
||||
label: 'Details',
|
||||
click: (d) => this.showDetails(d),
|
||||
},
|
||||
{
|
||||
label: 'Change status',
|
||||
click: (d) => this.changeStatus(d.chargeback.id),
|
||||
},
|
||||
]),
|
||||
];
|
||||
|
||||
constructor(private dialogService: DialogService) {}
|
||||
|
||||
changeStatus(id: string) {
|
||||
this.dialogService.open(ChangeChargebacksStatusDialogComponent, {
|
||||
chargebacks: [
|
||||
{
|
||||
payment_id: this.paymentId,
|
||||
invoice_id: this.invoiceId,
|
||||
chargeback_id: id,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
showDetails(chargeback: InvoicePaymentChargeback) {
|
||||
this.dialogService.open(DetailsDialogComponent, {
|
||||
title: 'Chargeback details',
|
||||
json: chargeback,
|
||||
});
|
||||
}
|
||||
}
|
@ -4,44 +4,44 @@
|
||||
(extensionResult$ | async)?.type || (extensionResult$ | async)?.template;
|
||||
else defaultFields
|
||||
"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
></cc-extension-field>
|
||||
<ng-template #defaultFields>
|
||||
<cc-primitive-field
|
||||
*ngSwitchCase="'primitive'"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
></cc-primitive-field>
|
||||
<cc-complex-form
|
||||
*ngSwitchCase="'complex'"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
></cc-complex-form>
|
||||
<ng-container *ngSwitchCase="'object'" [ngSwitch]="data.objectType">
|
||||
<cc-struct-form
|
||||
*ngSwitchCase="'struct'"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
></cc-struct-form>
|
||||
<cc-union-field
|
||||
*ngSwitchCase="'union'"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
></cc-union-field>
|
||||
<cc-enum-field
|
||||
*ngSwitchCase="'enum'"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[formControl]="control"
|
||||
></cc-enum-field>
|
||||
<cc-typedef-form
|
||||
*ngSwitchCase="'typedef'"
|
||||
[data]="data"
|
||||
[data]="$any(data)"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
></cc-typedef-form>
|
||||
|
@ -16,4 +16,9 @@ $offset: 24px;
|
||||
min-height: 48px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
::ng-deep & > *:last-child {
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import { CardComponent } from '../sidenav-info/components/card/card.component';
|
||||
import { DomainThriftViewerComponent } from '../thrift-api-crud';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-contract-card',
|
||||
selector: 'cc-shop-contract-card',
|
||||
standalone: true,
|
||||
imports: [CommonModule, CardComponent, DomainThriftViewerComponent],
|
||||
templateUrl: './shop-contract-card.component.html',
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
Option,
|
||||
NotifyLogService,
|
||||
progressTo,
|
||||
SelectFieldComponent,
|
||||
} from '@vality/ng-core';
|
||||
import {
|
||||
BehaviorSubject,
|
||||
@ -47,8 +48,8 @@ export class ShopFieldComponent
|
||||
{
|
||||
@Input() label: string;
|
||||
@Input({ transform: booleanAttribute }) required: boolean;
|
||||
@Input() size?: string;
|
||||
@Input() appearance?: string;
|
||||
@Input() size?: SelectFieldComponent['size'];
|
||||
@Input() appearance?: SelectFieldComponent['appearance'];
|
||||
@Input() hint?: string;
|
||||
@Input({ transform: booleanAttribute }) multiple = false;
|
||||
partyId = input<PartyID>();
|
||||
|
@ -1,14 +1,11 @@
|
||||
<v-table
|
||||
<v-table2
|
||||
[(sort)]="sort"
|
||||
[columns]="columns$ | async"
|
||||
[columns]="columns"
|
||||
[data]="shops()"
|
||||
[externalFilter]="filterChange.observed"
|
||||
[progress]="progress"
|
||||
[size]="100"
|
||||
name="shops"
|
||||
noActions
|
||||
sortOnFront
|
||||
standaloneFilter
|
||||
(filterChange)="filterChange.emit($event)"
|
||||
(update)="update.emit()"
|
||||
></v-table>
|
||||
></v-table2>
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
EventEmitter,
|
||||
Input,
|
||||
booleanAttribute,
|
||||
OnChanges,
|
||||
input,
|
||||
Injector,
|
||||
} from '@angular/core';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
@ -16,18 +16,17 @@ import { Shop, Party, PartyID, RoutingRulesetRef } from '@vality/domain-proto/do
|
||||
import {
|
||||
InputFieldModule,
|
||||
TableModule,
|
||||
Column,
|
||||
createOperationColumn,
|
||||
DialogService,
|
||||
NotifyLogService,
|
||||
ConfirmDialogComponent,
|
||||
DialogResponseStatus,
|
||||
ComponentChanges,
|
||||
Column2,
|
||||
createMenuColumn,
|
||||
} from '@vality/ng-core';
|
||||
import { getUnionKey } from '@vality/ng-thrift';
|
||||
import isNil from 'lodash-es/isNil';
|
||||
import { isNil } from 'lodash-es';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
import { map, switchMap, Subject, defer, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap, combineLatest, of } from 'rxjs';
|
||||
import { filter, shareReplay, startWith, take, first } from 'rxjs/operators';
|
||||
import { MemoizeExpiring } from 'typescript-memoize';
|
||||
|
||||
@ -38,6 +37,7 @@ import {
|
||||
DelegateWithPaymentInstitution,
|
||||
} from '../../../sections/routing-rules/party-delegate-rulesets';
|
||||
import { RoutingRulesType } from '../../../sections/routing-rules/types/routing-rules-type';
|
||||
import { createPartyColumn } from '../../utils/table2';
|
||||
import { ShopCardComponent } from '../shop-card/shop-card.component';
|
||||
import { ShopContractCardComponent } from '../shop-contract-card/shop-contract-card.component';
|
||||
import { SidenavInfoService } from '../sidenav-info';
|
||||
@ -68,100 +68,70 @@ export interface ShopParty {
|
||||
templateUrl: './shops-table.component.html',
|
||||
providers: [PartyDelegateRulesetsService],
|
||||
})
|
||||
export class ShopsTableComponent implements OnChanges {
|
||||
export class ShopsTableComponent {
|
||||
shops = input<ShopParty[]>([]);
|
||||
@Input({ transform: booleanAttribute }) changed!: boolean;
|
||||
@Input() progress: number | boolean = false;
|
||||
@Output() update = new EventEmitter<void>();
|
||||
@Output() filterChange = new EventEmitter<string>();
|
||||
|
||||
@Input({ transform: booleanAttribute }) noSort: boolean = false;
|
||||
@Input({ transform: booleanAttribute }) noPartyColumn: boolean = false;
|
||||
noPartyColumn = input(false, { transform: booleanAttribute });
|
||||
|
||||
columns$ = combineLatest([
|
||||
toObservable(this.shops).pipe(
|
||||
startWith(null),
|
||||
map((shops) =>
|
||||
shops?.length ? Array.from(new Set(shops.map((s) => s.party.id))) : [],
|
||||
),
|
||||
switchMap((parties) =>
|
||||
parties?.length
|
||||
? combineLatest(
|
||||
parties.map((id) =>
|
||||
this.partyDelegateRulesetsService.getDelegatesWithPaymentInstitution(
|
||||
RoutingRulesType.Payment,
|
||||
id,
|
||||
),
|
||||
),
|
||||
).pipe(map((rules) => new Map(rules.map((r, idx) => [parties[idx], r]))))
|
||||
: of(new Map<string, DelegateWithPaymentInstitution[]>()),
|
||||
),
|
||||
map((delegatesWithPaymentInstitutionByParty) => ({
|
||||
delegatesWithPaymentInstitutionByParty,
|
||||
rulesetIds: Array.from(
|
||||
Array.from(delegatesWithPaymentInstitutionByParty.values()).reduce((acc, d) => {
|
||||
d?.map((v) => v?.partyDelegate?.ruleset?.id).forEach((v) => acc.add(v));
|
||||
return acc;
|
||||
}, new Set<number>([])),
|
||||
),
|
||||
})),
|
||||
),
|
||||
defer(() => this.updateColumns$).pipe(startWith(null)),
|
||||
]).pipe(
|
||||
map(([delegatesByParty]): Column<ShopParty>[] => [
|
||||
columns: Column2<ShopParty>[] = [
|
||||
{
|
||||
field: 'shop.id',
|
||||
sortable: !this.noSort,
|
||||
},
|
||||
{
|
||||
field: 'shop.details.name',
|
||||
description: 'shop.details.description',
|
||||
click: (d) => {
|
||||
cell: (d) => ({
|
||||
description: d.shop.details.description,
|
||||
click: () => {
|
||||
this.sidenavInfoService.toggle(ShopCardComponent, {
|
||||
partyId: d.party.id,
|
||||
id: d.shop.id,
|
||||
});
|
||||
},
|
||||
sortable: !this.noSort,
|
||||
}),
|
||||
},
|
||||
...(this.noPartyColumn
|
||||
? []
|
||||
: [
|
||||
createPartyColumn(
|
||||
(d) => ({
|
||||
id: d.party.id,
|
||||
partyName: d.party.email,
|
||||
}),
|
||||
{
|
||||
field: 'party.email',
|
||||
header: 'Party',
|
||||
description: 'party.id',
|
||||
link: (d) => `/party/${d.party.id}`,
|
||||
hidden: toObservable(this.noPartyColumn),
|
||||
},
|
||||
]),
|
||||
),
|
||||
{
|
||||
field: 'shop.contract_id',
|
||||
header: 'Contract',
|
||||
click: (d) => {
|
||||
cell: (d) => ({
|
||||
click: () => {
|
||||
this.sidenavInfoService.toggle(ShopContractCardComponent, {
|
||||
partyId: d.party.id,
|
||||
id: d.shop.id,
|
||||
});
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'terms',
|
||||
formatter: (d) =>
|
||||
lazyCell: (d) =>
|
||||
this.getTerms(d.party.id, d.shop.id).pipe(
|
||||
map((terms) => getDomainObjectDetails(terms).label),
|
||||
),
|
||||
description: (d) =>
|
||||
this.getTerms(d.party.id, d.shop.id).pipe(
|
||||
map((terms) => getDomainObjectDetails(terms).id),
|
||||
),
|
||||
lazy: true,
|
||||
click: (d) => {
|
||||
map((terms) => getDomainObjectDetails(terms)),
|
||||
map((details) => ({
|
||||
value: details.label,
|
||||
description: details.description,
|
||||
click: () => {
|
||||
this.getTerms(d.party.id, d.shop.id).subscribe((terms) => {
|
||||
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
|
||||
ref: { term_set_hierarchy: terms.term_set_hierarchy.ref },
|
||||
ref: {
|
||||
term_set_hierarchy: terms.term_set_hierarchy.ref,
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
})),
|
||||
),
|
||||
},
|
||||
{
|
||||
field: 'shop.location.url',
|
||||
@ -172,68 +142,66 @@ export class ShopsTableComponent implements OnChanges {
|
||||
},
|
||||
{
|
||||
field: 'shop.blocking',
|
||||
type: 'tag',
|
||||
formatter: ({ shop }) => getUnionKey(shop.blocking),
|
||||
typeParameters: {
|
||||
label: ({ shop }) => startCase(getUnionKey(shop.blocking)),
|
||||
tags: {
|
||||
blocked: { color: 'warn' },
|
||||
unblocked: { color: 'success' },
|
||||
},
|
||||
},
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.shop.blocking)),
|
||||
color: (
|
||||
{
|
||||
blocked: 'warn',
|
||||
unblocked: 'success',
|
||||
} as const
|
||||
)[getUnionKey(d.shop.blocking)],
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'shop.suspension',
|
||||
type: 'tag',
|
||||
formatter: ({ shop }) => getUnionKey(shop.suspension),
|
||||
typeParameters: {
|
||||
label: ({ shop }) => startCase(getUnionKey(shop.suspension)),
|
||||
tags: {
|
||||
suspended: { color: 'warn' },
|
||||
active: { color: 'success' },
|
||||
},
|
||||
},
|
||||
},
|
||||
createOperationColumn<ShopParty>([
|
||||
...delegatesByParty.rulesetIds.map((id) => ({
|
||||
label: `Routing rules #${id}`,
|
||||
click: ({ shop, party }) =>
|
||||
this.openRoutingRules(
|
||||
delegatesByParty.delegatesWithPaymentInstitutionByParty
|
||||
.get(party.id)
|
||||
.find((d) => d?.partyDelegate?.ruleset?.id === id)?.partyDelegate
|
||||
?.ruleset?.id,
|
||||
shop.id,
|
||||
party.id,
|
||||
),
|
||||
disabled: ({ party }) =>
|
||||
isNil(
|
||||
delegatesByParty.delegatesWithPaymentInstitutionByParty
|
||||
.get(party.id)
|
||||
.find((d) => d?.partyDelegate?.ruleset?.id === id)?.partyDelegate
|
||||
?.ruleset?.id,
|
||||
),
|
||||
})),
|
||||
cell: (d) => ({
|
||||
value: startCase(getUnionKey(d.shop.suspension)),
|
||||
color: (
|
||||
{
|
||||
label: ({ shop }) =>
|
||||
getUnionKey(shop.suspension) === 'suspended' ? 'Activate' : 'Suspend',
|
||||
click: (d) => {
|
||||
suspended: 'warn',
|
||||
active: 'success',
|
||||
} as const
|
||||
)[getUnionKey(d.shop.suspension)],
|
||||
}),
|
||||
},
|
||||
createMenuColumn((d) =>
|
||||
this.getDelegatesByParty().pipe(
|
||||
map((delegatesByParty) => ({
|
||||
items: [
|
||||
...delegatesByParty.rulesetIds.map((id) => {
|
||||
const rulesetId =
|
||||
delegatesByParty.delegatesWithPaymentInstitutionByParty
|
||||
?.get?.(d.party.id)
|
||||
?.find?.((v) => v?.partyDelegate?.ruleset?.id === id)
|
||||
?.partyDelegate?.ruleset?.id;
|
||||
return {
|
||||
label: `Routing rules #${id}`,
|
||||
click: () =>
|
||||
this.openRoutingRules(rulesetId, d.shop.id, d.party.id),
|
||||
disabled: isNil(rulesetId),
|
||||
};
|
||||
}),
|
||||
{
|
||||
label:
|
||||
getUnionKey(d.shop.suspension) === 'suspended'
|
||||
? 'Activate'
|
||||
: 'Suspend',
|
||||
click: () => {
|
||||
this.toggleSuspension(d);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: ({ shop }) =>
|
||||
getUnionKey(shop.blocking) === 'blocked' ? 'Unblock' : 'Block',
|
||||
click: (d) => {
|
||||
label: getUnionKey(d.shop.blocking) === 'blocked' ? 'Unblock' : 'Block',
|
||||
click: () => {
|
||||
this.toggleBlocking(d);
|
||||
},
|
||||
},
|
||||
]),
|
||||
]),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
],
|
||||
})),
|
||||
),
|
||||
),
|
||||
];
|
||||
sort: Sort = { active: 'shop.details.name', direction: 'asc' };
|
||||
private updateColumns$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private sidenavInfoService: SidenavInfoService,
|
||||
@ -243,17 +211,9 @@ export class ShopsTableComponent implements OnChanges {
|
||||
private router: Router,
|
||||
private partyDelegateRulesetsService: PartyDelegateRulesetsService,
|
||||
private domainStoreService: DomainStoreService,
|
||||
private injector: Injector,
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: ComponentChanges<ShopsTableComponent>) {
|
||||
if (changes.noSort || changes.noPartyColumn) {
|
||||
if (this.noSort) {
|
||||
this.sort = { active: '', direction: '' };
|
||||
}
|
||||
this.updateColumns$.next();
|
||||
}
|
||||
}
|
||||
|
||||
toggleBlocking({ party, shop }: ShopParty) {
|
||||
this.dialogService
|
||||
.open(ConfirmDialogComponent, {
|
||||
@ -369,4 +329,34 @@ export class ShopsTableComponent implements OnChanges {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private getDelegatesByParty() {
|
||||
return toObservable(this.shops, { injector: this.injector }).pipe(
|
||||
startWith(null),
|
||||
map((shops) =>
|
||||
shops?.length ? Array.from(new Set(shops.map((s) => s.party.id))) : [],
|
||||
),
|
||||
switchMap((parties) =>
|
||||
parties?.length
|
||||
? combineLatest(
|
||||
parties.map((id) =>
|
||||
this.partyDelegateRulesetsService.getDelegatesWithPaymentInstitution(
|
||||
RoutingRulesType.Payment,
|
||||
id,
|
||||
),
|
||||
),
|
||||
).pipe(map((rules) => new Map(rules.map((r, idx) => [parties[idx], r]))))
|
||||
: of(new Map<string, DelegateWithPaymentInstitution[]>()),
|
||||
),
|
||||
map((delegatesWithPaymentInstitutionByParty) => ({
|
||||
delegatesWithPaymentInstitutionByParty,
|
||||
rulesetIds: Array.from(
|
||||
Array.from(delegatesWithPaymentInstitutionByParty.values()).reduce((acc, d) => {
|
||||
d?.map((v) => v?.partyDelegate?.ruleset?.id).forEach((v) => acc.add(v));
|
||||
return acc;
|
||||
}, new Set<number>([])),
|
||||
),
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, Input, booleanAttribute } from '@angular/core';
|
||||
import { ThriftAstMetadata } from '@vality/domain-proto';
|
||||
import { getImportValue } from '@vality/ng-core';
|
||||
import { getImportValue, UnionEnum } from '@vality/ng-core';
|
||||
import { ValueType } from '@vality/thrift-ts';
|
||||
|
||||
import { ThriftViewerModule, ViewerKind } from '../../../thrift-viewer';
|
||||
@ -15,7 +15,7 @@ import { DomainMetadataViewExtensionsService } from './services/domain-metadata-
|
||||
imports: [CommonModule, ThriftViewerModule],
|
||||
})
|
||||
export class DomainThriftViewerComponent<T> {
|
||||
@Input() kind: ViewerKind = ViewerKind.Component;
|
||||
@Input() kind: UnionEnum<ViewerKind> = ViewerKind.Component;
|
||||
@Input() value: T;
|
||||
@Input() compared?: T;
|
||||
@Input() type: ValueType;
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
FormControlSuperclass,
|
||||
} from '@vality/ng-core';
|
||||
import { toJson } from '@vality/ng-thrift';
|
||||
import { ValueType } from '@vality/thrift-ts';
|
||||
import { merge, defer, of, Subject } from 'rxjs';
|
||||
import { map, filter, shareReplay } from 'rxjs/operators';
|
||||
|
||||
@ -32,7 +33,7 @@ export class ThriftEditorComponent<T> extends FormControlSuperclass<T> {
|
||||
|
||||
@Input() metadata: ThriftAstMetadata[];
|
||||
@Input() namespace: string;
|
||||
@Input() type: string;
|
||||
@Input() type: ValueType;
|
||||
@Input() extensions: MetadataFormExtension[];
|
||||
@Input({ transform: booleanAttribute }) noChangeKind = false;
|
||||
@Input({ transform: booleanAttribute }) noToolbar = false;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, Input, OnChanges, Output, EventEmitter, booleanAttribute } from '@angular/core';
|
||||
import { ThriftAstMetadata } from '@vality/domain-proto';
|
||||
import { ComponentChanges } from '@vality/ng-core';
|
||||
import { ComponentChanges, UnionEnum } from '@vality/ng-core';
|
||||
import { toJson } from '@vality/ng-thrift';
|
||||
import { ValueType } from '@vality/thrift-ts';
|
||||
import { DiffEditorModel } from 'ngx-monaco-editor-v2';
|
||||
@ -19,7 +19,7 @@ export enum ViewerKind {
|
||||
styleUrls: ['./thrift-viewer.component.scss'],
|
||||
})
|
||||
export class ThriftViewerComponent<T> implements OnChanges {
|
||||
@Input() kind: ViewerKind = ViewerKind.Component;
|
||||
@Input() kind: UnionEnum<ViewerKind> = ViewerKind.Component;
|
||||
@Input() value: T;
|
||||
@Input() compared?: T;
|
||||
@Input({ transform: booleanAttribute }) progress: boolean = false;
|
||||
@ -62,6 +62,6 @@ export class ThriftViewerComponent<T> implements OnChanges {
|
||||
this.kind = ViewerKind.Editor;
|
||||
break;
|
||||
}
|
||||
this.changeKind.emit(this.kind);
|
||||
this.changeKind.emit(this.kind as ViewerKind);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import {
|
||||
createControlProviders,
|
||||
debounceTimeWithFirst,
|
||||
progressTo,
|
||||
SelectFieldComponent,
|
||||
} from '@vality/ng-core';
|
||||
import { BehaviorSubject, Observable, of, ReplaySubject, Subject, concat, forkJoin } from 'rxjs';
|
||||
import { catchError, map, switchMap, tap, distinctUntilChanged } from 'rxjs/operators';
|
||||
@ -34,8 +35,8 @@ export class WalletFieldComponent
|
||||
{
|
||||
@Input() label: string;
|
||||
@Input({ transform: booleanAttribute }) required: boolean;
|
||||
@Input() size?: string;
|
||||
@Input() appearance?: string;
|
||||
@Input() size?: SelectFieldComponent['size'];
|
||||
@Input() appearance?: SelectFieldComponent['appearance'];
|
||||
@Input() hint?: string;
|
||||
@Input({ transform: booleanAttribute }) multiple = false;
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
import { Column, PossiblyAsync, getPossiblyAsyncObservable } from '@vality/ng-core';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { createDomainObjectColumn } from './create-domain-object-column';
|
||||
|
||||
export function createProviderColumn<T extends object>(
|
||||
selectTerminalId: (d: T) => PossiblyAsync<number>,
|
||||
): Column<T> {
|
||||
return createDomainObjectColumn('provider', (d) =>
|
||||
getPossiblyAsyncObservable(selectTerminalId(d)).pipe(map((id) => ({ id }))),
|
||||
);
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { createColumn } from '@vality/ng-core';
|
||||
import { of } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
@ -16,9 +15,7 @@ export const createPartyColumn = createColumn(
|
||||
.pipe(map((party) => party.contact_info.registration_email));
|
||||
const partyCell = {
|
||||
description: id,
|
||||
link: () => {
|
||||
void inject(Router).navigate([`/party/${id}`]);
|
||||
},
|
||||
link: () => `/party/${id}`,
|
||||
};
|
||||
return partyName$.pipe(
|
||||
map((partyName) => ({
|
||||
|
Loading…
Reference in New Issue
Block a user