IMP-216: Show terminal balances (#348)

This commit is contained in:
Rinat Arsaev 2024-04-04 17:44:41 +09:00 committed by GitHub
parent b185890065
commit 4214fd6f45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 153 additions and 45 deletions

6
package-lock.json generated
View File

@ -28,6 +28,7 @@
"@vality/ng-core": "17.2.1-pr-60-8d151ad.0",
"@vality/payout-manager-proto": "2.0.1-eb4091a.0",
"@vality/repairer-proto": "2.0.2-07b73e9.0",
"@vality/scrooge-proto": "0.1.0",
"@vality/thrift-ts": "2.4.1-8ad5123.0",
"@vality/woody": "0.1.3",
"date-fns": "^3.3.1",
@ -6502,6 +6503,11 @@
"resolved": "https://registry.npmjs.org/@vality/repairer-proto/-/repairer-proto-2.0.2-07b73e9.0.tgz",
"integrity": "sha512-PwWTzgIrqTKqZVRW235ZPIoQz+Rvf0RavVhTrPwMxRDvkZLcRd7WN6O6rIYNcz84BZXJ5r4YnyN0kWCaLvGdqw=="
},
"node_modules/@vality/scrooge-proto": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@vality/scrooge-proto/-/scrooge-proto-0.1.0.tgz",
"integrity": "sha512-yZkzqVUBpkNtM8lT1HT5yRiZ5tVh+nxVj+gP7NUQB36FIfP0ZSJWxZIdedvulWApiYXbn1M/oDsyhnc62iz2Mw=="
},
"node_modules/@vality/thrift-ts": {
"version": "2.4.1-8ad5123.0",
"resolved": "https://registry.npmjs.org/@vality/thrift-ts/-/thrift-ts-2.4.1-8ad5123.0.tgz",

View File

@ -36,6 +36,7 @@
"@vality/ng-core": "17.2.1-pr-60-8d151ad.0",
"@vality/payout-manager-proto": "2.0.1-eb4091a.0",
"@vality/repairer-proto": "2.0.2-07b73e9.0",
"@vality/scrooge-proto": "0.1.0",
"@vality/thrift-ts": "2.4.1-8ad5123.0",
"@vality/woody": "0.1.3",
"date-fns": "^3.3.1",

View File

@ -0,0 +1,2 @@
export * from './terminal-balance.service';
export * from './stores/terminal-balances-store.service';

View File

@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { TerminalBalance } from '@vality/scrooge-proto/internal/terminal_balance';
import { of, Observable } from 'rxjs';
import { shareReplay, map, catchError, startWith } from 'rxjs/operators';
import { TerminalBalanceService } from '../terminal-balance.service';
@Injectable({
providedIn: 'root',
})
export class TerminalBalancesStoreService {
balances$: Observable<TerminalBalance[]> = this.terminalBalanceService
.GetTerminalBalances()
.pipe(
map((b) => b.balances),
startWith([]),
catchError(() => {
console.error('Terminal balances are not loaded');
return of([]);
}),
shareReplay({ refCount: true, bufferSize: 1 }),
);
constructor(private terminalBalanceService: TerminalBalanceService) {}
getTerminalBalance(id: string | number) {
return this.balances$.pipe(
map((balances) => balances.find((b) => b.terminal.id === String(id))),
);
}
}

View File

@ -0,0 +1,42 @@
import { Injectable } from '@angular/core';
import { getImportValue } from '@vality/ng-core';
import {
terminal_balance_TerminalServiceCodegenClient,
ThriftAstMetadata,
terminal_balance_TerminalService,
} from '@vality/scrooge-proto';
import { combineLatest, map, Observable, switchMap } from 'rxjs';
import { environment } from '../../../environments/environment';
import { ConfigService } from '../../core/config.service';
import { KeycloakTokenInfoService, toWachterHeaders } from '../../shared/services';
@Injectable({ providedIn: 'root' })
export class TerminalBalanceService {
private client$: Observable<terminal_balance_TerminalServiceCodegenClient>;
constructor(
private keycloakTokenInfoService: KeycloakTokenInfoService,
configService: ConfigService,
) {
const headers$ = this.keycloakTokenInfoService.info$.pipe(map(toWachterHeaders('Scrooge')));
const metadata$ = getImportValue<ThriftAstMetadata[]>(
import('@vality/scrooge-proto/metadata.json'),
);
this.client$ = combineLatest([metadata$, headers$]).pipe(
switchMap(([metadata, headers]) =>
terminal_balance_TerminalService({
metadata,
headers,
logging: environment.logging.requests,
...configService.config.api.wachter,
}),
),
);
}
// eslint-disable-next-line @typescript-eslint/naming-convention
GetTerminalBalances() {
return this.client$.pipe(switchMap((c) => c.GetTerminalBalances()));
}
}

View File

@ -4,7 +4,7 @@
</cc-page-layout-actions>
<v-table
[(sort)]="sort"
[columns]="columns"
[columns]="columns$ | async"
[data]="data$ | async"
[filterByColumns]="[]"
[progress]="progress$ | async"

View File

@ -7,7 +7,8 @@ import { of } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { DomainStoreService } from '../../api/domain-config';
import { createPredicateColumn } from '../../shared';
import { TerminalBalancesStoreService } from '../../api/terminal-balance';
import { createPredicateColumn, createCurrencyColumn } from '../../shared';
import { SidenavInfoService } from '../../shared/components/sidenav-info';
import { TerminalDelegatesCardComponent } from '../../shared/components/terminal-delegates-card/terminal-delegates-card.component';
import {
@ -22,51 +23,75 @@ import { getTerminalShopWalletDelegates } from './utils/get-terminal-shop-wallet
templateUrl: './terminals.component.html',
})
export class TerminalsComponent {
columns: Column<TerminalObject>[] = [
{ field: 'ref.id', sortable: true },
{
field: 'data.name',
description: 'data.description',
sortable: true,
click: (d) => {
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
ref: { terminal: d.ref },
});
},
},
{
field: 'data.provider_ref.id',
description: 'data.provider_ref.id',
header: 'Provider',
formatter: (d) => this.getProvider(d).pipe(map((p) => p?.data?.name || '')),
sortable: true,
click: (d) => {
this.getProvider(d)
.pipe(take(1), takeUntilDestroyed(this.destroyRef))
.subscribe((provider) => {
if (!provider) {
return;
}
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
ref: { provider: provider.ref },
});
columns$ = this.terminalBalancesStoreService.balances$.pipe(
map((balances): Column<TerminalObject>[] => [
{ field: 'ref.id', sortable: true },
{
field: 'data.name',
description: 'data.description',
sortable: true,
click: (d) => {
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
ref: { terminal: d.ref },
});
},
},
},
createPredicateColumn('payments global allow', (d) => d.data.terms?.payments?.global_allow),
createPredicateColumn(
'withdrawals global allow',
(d) => d.data.terms?.wallet?.withdrawals?.global_allow,
),
{
field: 'delegates',
formatter: (d) =>
this.getTerminalShopWalletDelegates(d).pipe(map((r) => r.length || '')),
click: (d) => {
this.sidenavInfoService.toggle(TerminalDelegatesCardComponent, { ref: d.ref });
{
field: 'data.provider_ref.id',
description: 'data.provider_ref.id',
header: 'Provider',
formatter: (d) => this.getProvider(d).pipe(map((p) => p?.data?.name || '')),
sortable: true,
click: (d) => {
this.getProvider(d)
.pipe(take(1), takeUntilDestroyed(this.destroyRef))
.subscribe((provider) => {
if (!provider) {
return;
}
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
ref: { provider: provider.ref },
});
});
},
},
},
];
createPredicateColumn(
'payments global allow',
(d) => d.data.terms?.payments?.global_allow,
),
createPredicateColumn(
'withdrawals global allow',
(d) => d.data.terms?.wallet?.withdrawals?.global_allow,
),
{
field: 'delegates',
formatter: (d) =>
this.getTerminalShopWalletDelegates(d).pipe(map((r) => r.length || '')),
click: (d) => {
this.sidenavInfoService.toggle(TerminalDelegatesCardComponent, { ref: d.ref });
},
},
...(balances?.length
? [
createCurrencyColumn<TerminalObject>(
'balance',
(d) =>
this.terminalBalancesStoreService
.getTerminalBalance(d.ref.id)
.pipe(
map((b) =>
b?.balance?.amount ? Number(b.balance.amount) : undefined,
),
),
(d) =>
this.terminalBalancesStoreService
.getTerminalBalance(d.ref.id)
.pipe(map((b) => b?.balance?.currency_code)),
),
]
: []),
]),
);
data$ = this.domainStoreService.getObjects('terminal');
progress$ = this.domainStoreService.isLoading$;
sort: Sort = { active: 'data.name', direction: 'asc' };
@ -76,6 +101,7 @@ export class TerminalsComponent {
private sidenavInfoService: SidenavInfoService,
private destroyRef: DestroyRef,
private dialogService: DialogService,
private terminalBalancesStoreService: TerminalBalancesStoreService,
) {}
update() {

View File

@ -8,7 +8,7 @@
></cc-fistful-thrift-form>
<v-dialog-actions>
<button
[disabled]="control.invalid || (progress$ | async)"
[disabled]="control.invalid || !!(progress$ | async)"
color="primary"
mat-button
(click)="createAdjustment()"