mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
Move terminals page to table v2 (#402)
This commit is contained in:
parent
6a76549c59
commit
753ad0d727
8
package-lock.json
generated
8
package-lock.json
generated
@ -26,7 +26,7 @@
|
|||||||
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
||||||
"@vality/machinegun-proto": "1.0.1-3decc8f.0",
|
"@vality/machinegun-proto": "1.0.1-3decc8f.0",
|
||||||
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
||||||
"@vality/ng-core": "^18.4.1-pr-69-2efb51f.0",
|
"@vality/ng-core": "18.4.1-pr-74-55d4acd.0",
|
||||||
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
||||||
"@vality/repairer-proto": "2.0.2-07b73e9.0",
|
"@vality/repairer-proto": "2.0.2-07b73e9.0",
|
||||||
"@vality/scrooge-proto": "0.1.1-9ce7fc6.0",
|
"@vality/scrooge-proto": "0.1.1-9ce7fc6.0",
|
||||||
@ -5969,9 +5969,9 @@
|
|||||||
"integrity": "sha512-XWF7qM/CARRAey0scGVhfGU6jNq+UdlGE2mg3jn4eIFDuIWQJqsT+Bah300RBUrl+XgFsmj95C6HWRfeA5Q8kw=="
|
"integrity": "sha512-XWF7qM/CARRAey0scGVhfGU6jNq+UdlGE2mg3jn4eIFDuIWQJqsT+Bah300RBUrl+XgFsmj95C6HWRfeA5Q8kw=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/ng-core": {
|
"node_modules/@vality/ng-core": {
|
||||||
"version": "18.4.1-pr-69-2efb51f.0",
|
"version": "18.4.1-pr-74-55d4acd.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-18.4.1-pr-69-2efb51f.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-18.4.1-pr-74-55d4acd.0.tgz",
|
||||||
"integrity": "sha512-q01uhPxW88y9/rpPGfOLSPqsCL65ORZGcsxBd/2Rta+5wqLTSMlzz++gm13BmLUPKc8HvaRKDacOEfktVfCG3Q==",
|
"integrity": "sha512-EkGTPth5+HA0MLc+BYLIV5ie7xnwBrXftTxoVJw+5zlcWoLm5V1+10AGz6wmhX4VIunFFZR/p9XUNAhNqvluVw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/material-date-fns-adapter": "^18.2.2",
|
"@angular/material-date-fns-adapter": "^18.2.2",
|
||||||
"@ng-matero/extensions": "^18.2.0",
|
"@ng-matero/extensions": "^18.2.0",
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
||||||
"@vality/machinegun-proto": "1.0.1-3decc8f.0",
|
"@vality/machinegun-proto": "1.0.1-3decc8f.0",
|
||||||
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
||||||
"@vality/ng-core": "^18.4.1-pr-69-2efb51f.0",
|
"@vality/ng-core": "18.4.1-pr-74-55d4acd.0",
|
||||||
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
||||||
"@vality/repairer-proto": "2.0.2-07b73e9.0",
|
"@vality/repairer-proto": "2.0.2-07b73e9.0",
|
||||||
"@vality/scrooge-proto": "0.1.1-9ce7fc6.0",
|
"@vality/scrooge-proto": "0.1.1-9ce7fc6.0",
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
"extends": ["local>valitydev/.github:renovate-config"],
|
"extends": ["local>valitydev/.github:renovate-config"],
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"groupName": "Minor Updates",
|
"groupName": "Minor",
|
||||||
"matchUpdateTypes": ["minor", "patch"]
|
"matchUpdateTypes": ["minor", "patch"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"groupName": "Major Updates",
|
"groupName": "Major",
|
||||||
"matchUpdateTypes": ["major"]
|
"matchUpdateTypes": ["major"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -30,14 +30,20 @@ export class AccountBalancesStoreService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTerminalBalances(id: string | number, providerId?: string | number) {
|
getTerminalBalances(
|
||||||
|
id: string | number,
|
||||||
|
providerId?: string | number,
|
||||||
|
): Observable<AccountBalance[]> {
|
||||||
|
if (isNil(providerId)) {
|
||||||
|
return of([]);
|
||||||
|
}
|
||||||
return this.balances$.pipe(
|
return this.balances$.pipe(
|
||||||
map((balances) =>
|
map((balances) =>
|
||||||
balances.filter(
|
balances.filter(
|
||||||
(b) =>
|
(b) =>
|
||||||
!isNil(providerId) &&
|
|
||||||
b.provider.id === String(providerId) &&
|
b.provider.id === String(providerId) &&
|
||||||
b.terminal.id === String(id),
|
b.terminal.id === String(id) &&
|
||||||
|
b.balance,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -47,10 +47,10 @@ export class DepositDetailsComponent implements OnInit {
|
|||||||
map((c) => ({
|
map((c) => ({
|
||||||
value: formatCurrency(
|
value: formatCurrency(
|
||||||
amount,
|
amount,
|
||||||
c.data.symbolic_code,
|
c.symbolic_code,
|
||||||
'long',
|
'long',
|
||||||
this._locale,
|
this._locale,
|
||||||
c.data.exponent,
|
c.exponent,
|
||||||
),
|
),
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
|
@ -82,7 +82,6 @@ export class DomainObjectsTableComponent implements OnInit {
|
|||||||
{
|
{
|
||||||
field: 'id',
|
field: 'id',
|
||||||
cell: (d) => ({ value: getDomainObjectDetails(d.obj).id }),
|
cell: (d) => ({ value: getDomainObjectDetails(d.obj).id }),
|
||||||
sort: true,
|
|
||||||
sticky: 'start',
|
sticky: 'start',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -91,17 +90,14 @@ export class DomainObjectsTableComponent implements OnInit {
|
|||||||
value: getDomainObjectDetails(d.obj).label,
|
value: getDomainObjectDetails(d.obj).label,
|
||||||
click: () => this.details(d),
|
click: () => this.details(d),
|
||||||
}),
|
}),
|
||||||
sort: true,
|
|
||||||
style: { width: 0 },
|
style: { width: 0 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'description',
|
field: 'description',
|
||||||
cell: (d) => ({ value: getDomainObjectDetails(d.obj).description }),
|
cell: (d) => ({ value: getDomainObjectDetails(d.obj).description }),
|
||||||
sort: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'type',
|
field: 'type',
|
||||||
sort: true,
|
|
||||||
cell: (d) => ({ value: startCase(d.type) }),
|
cell: (d) => ({ value: startCase(d.type) }),
|
||||||
hidden: getValueChanges(this.typesControl).pipe(map((t) => t.length <= 1)),
|
hidden: getValueChanges(this.typesControl).pipe(map((t) => t.length <= 1)),
|
||||||
},
|
},
|
||||||
|
@ -35,10 +35,10 @@ export class PaymentDetailsComponent {
|
|||||||
map((c) => ({
|
map((c) => ({
|
||||||
value: formatCurrency(
|
value: formatCurrency(
|
||||||
amount,
|
amount,
|
||||||
c.data.symbolic_code,
|
c.symbolic_code,
|
||||||
'long',
|
'long',
|
||||||
this._locale,
|
this._locale,
|
||||||
c.data.exponent,
|
c.exponent,
|
||||||
),
|
),
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
<cc-page-layout title="Terminals">
|
<cc-page-layout fullHeight title="Terminals">
|
||||||
<cc-page-layout-actions>
|
<cc-page-layout-actions>
|
||||||
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
||||||
</cc-page-layout-actions>
|
</cc-page-layout-actions>
|
||||||
<v-table
|
<v-table2
|
||||||
[(sort)]="sort"
|
[(sort)]="sort"
|
||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
[data]="data$ | async"
|
[data]="data$ | async"
|
||||||
[filterByColumns]="[]"
|
|
||||||
[progress]="progress$ | async"
|
[progress]="progress$ | async"
|
||||||
name="terminals"
|
name="terminals"
|
||||||
sortOnFront
|
|
||||||
standaloneFilter
|
standaloneFilter
|
||||||
(update)="update()"
|
(update)="update()"
|
||||||
></v-table>
|
></v-table2>
|
||||||
</cc-page-layout>
|
</cc-page-layout>
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
import { Component, DestroyRef } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
import { Sort } from '@angular/material/sort';
|
import { Sort } from '@angular/material/sort';
|
||||||
import { TerminalObject } from '@vality/domain-proto/domain';
|
import { TerminalObject } from '@vality/domain-proto/domain';
|
||||||
import { Column, DialogService } from '@vality/ng-core';
|
import { DialogService, Column2 } from '@vality/ng-core';
|
||||||
import { of } from 'rxjs';
|
import { map } from 'rxjs/operators';
|
||||||
import { map, take } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { DomainStoreService } from '../../api/domain-config';
|
import { DomainStoreService } from '../../api/domain-config';
|
||||||
import { AccountBalancesStoreService } from '../../api/terminal-balance';
|
import { AccountBalancesStoreService } from '../../api/terminal-balance';
|
||||||
import { createPredicateColumn, createCurrenciesColumn } from '../../shared';
|
|
||||||
import { SidenavInfoService } from '../../shared/components/sidenav-info';
|
import { SidenavInfoService } from '../../shared/components/sidenav-info';
|
||||||
|
import { TerminalBalancesCardComponent } from '../../shared/components/terminal-balances-card/terminal-balances-card.component';
|
||||||
import { TerminalDelegatesCardComponent } from '../../shared/components/terminal-delegates-card/terminal-delegates-card.component';
|
import { TerminalDelegatesCardComponent } from '../../shared/components/terminal-delegates-card/terminal-delegates-card.component';
|
||||||
import {
|
import {
|
||||||
DomainObjectCardComponent,
|
DomainObjectCardComponent,
|
||||||
CreateDomainObjectDialogComponent,
|
CreateDomainObjectDialogComponent,
|
||||||
|
getDomainObjectDetails,
|
||||||
} from '../../shared/components/thrift-api-crud';
|
} from '../../shared/components/thrift-api-crud';
|
||||||
|
import {
|
||||||
|
createCurrencyColumn,
|
||||||
|
createPredicateColumn,
|
||||||
|
createDomainObjectColumn,
|
||||||
|
} from '../../shared/utils/table2';
|
||||||
|
|
||||||
import { getTerminalShopWalletDelegates } from './utils/get-terminal-shop-wallet-delegates';
|
import { getTerminalShopWalletDelegates } from './utils/get-terminal-shop-wallet-delegates';
|
||||||
|
|
||||||
@ -23,78 +27,86 @@ import { getTerminalShopWalletDelegates } from './utils/get-terminal-shop-wallet
|
|||||||
templateUrl: './terminals.component.html',
|
templateUrl: './terminals.component.html',
|
||||||
})
|
})
|
||||||
export class TerminalsComponent {
|
export class TerminalsComponent {
|
||||||
columns: Column<TerminalObject>[] = [
|
columns: Column2<TerminalObject>[] = [
|
||||||
{ field: 'ref.id', sortable: true },
|
{ field: 'ref.id', sticky: 'start' },
|
||||||
{
|
{
|
||||||
field: 'data.name',
|
field: 'data.name',
|
||||||
description: 'data.description',
|
cell: (d) => ({
|
||||||
sortable: true,
|
description: getDomainObjectDetails({ terminal: d }).description,
|
||||||
click: (d) => {
|
click: () => {
|
||||||
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
|
this.sidenavInfoService.toggle(DomainObjectCardComponent, {
|
||||||
ref: { terminal: d.ref },
|
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 },
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
createPredicateColumn('payments global allow', (d) => d.data.terms?.payments?.global_allow),
|
createDomainObjectColumn((d) => ({ ref: { provider: d.data.provider_ref } }), {
|
||||||
|
header: 'Provider',
|
||||||
|
}),
|
||||||
|
createPredicateColumn((d) => ({ predicate: d.data.terms?.payments?.global_allow }), {
|
||||||
|
header: 'Payments Global Allow',
|
||||||
|
}),
|
||||||
createPredicateColumn(
|
createPredicateColumn(
|
||||||
'withdrawals global allow',
|
(d) => ({ predicate: d.data.terms?.wallet?.withdrawals?.global_allow }),
|
||||||
(d) => d.data.terms?.wallet?.withdrawals?.global_allow,
|
{
|
||||||
|
header: 'Withdrawals Global Allow',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
field: 'delegates',
|
field: 'delegates',
|
||||||
formatter: (d) =>
|
cell: (d) =>
|
||||||
this.getTerminalShopWalletDelegates(d).pipe(map((r) => r.length || '')),
|
this.getTerminalShopWalletDelegates(d).pipe(
|
||||||
click: (d) => {
|
map((r) => ({
|
||||||
this.sidenavInfoService.toggle(TerminalDelegatesCardComponent, {
|
value: r.length || '',
|
||||||
ref: d.ref,
|
click: () => {
|
||||||
});
|
this.sidenavInfoService.toggle(TerminalDelegatesCardComponent, {
|
||||||
},
|
ref: d.ref,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
createCurrenciesColumn<TerminalObject>(
|
createCurrencyColumn(
|
||||||
'balances',
|
|
||||||
(d) =>
|
(d) =>
|
||||||
this.accountBalancesStoreService
|
this.accountBalancesStoreService
|
||||||
.getTerminalBalances(d.ref.id, d.data.provider_ref.id)
|
.getTerminalBalances(d.ref.id, d.data.provider_ref?.id)
|
||||||
.pipe(
|
.pipe(
|
||||||
map((b) =>
|
map((balances) => ({
|
||||||
b.map((a) => ({
|
values: balances.map((a) => ({
|
||||||
amount: a.balance.amount,
|
amount: a.balance.amount,
|
||||||
symbolicCode: a.balance.currency_code,
|
code: a.balance.currency_code,
|
||||||
})),
|
})),
|
||||||
),
|
isSum: true,
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
sortable: true,
|
header: 'Balances (Summarized)',
|
||||||
tooltip: (d) =>
|
cell: (d) => ({
|
||||||
this.accountBalancesStoreService
|
click: () => {
|
||||||
.getTerminalBalances(d.ref.id, d.data.provider_ref.id)
|
this.toggleBalancesCard(d);
|
||||||
.pipe(
|
},
|
||||||
map((accountBalance) =>
|
}),
|
||||||
accountBalance
|
},
|
||||||
.sort((a, b) => b.balance.amount - a.balance.amount)
|
),
|
||||||
.map((a) => a.account_id)
|
createCurrencyColumn(
|
||||||
.join(', '),
|
(d) =>
|
||||||
),
|
this.accountBalancesStoreService
|
||||||
),
|
.getTerminalBalances(d.ref.id, d.data.provider_ref?.id)
|
||||||
|
.pipe(
|
||||||
|
map((balances) => ({
|
||||||
|
values: balances.map((a) => ({
|
||||||
|
amount: a.balance.amount,
|
||||||
|
code: a.balance.currency_code,
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
{
|
||||||
|
header: 'Balances',
|
||||||
|
cell: (d) => ({
|
||||||
|
click: () => {
|
||||||
|
this.toggleBalancesCard(d);
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@ -105,7 +117,6 @@ export class TerminalsComponent {
|
|||||||
constructor(
|
constructor(
|
||||||
private domainStoreService: DomainStoreService,
|
private domainStoreService: DomainStoreService,
|
||||||
private sidenavInfoService: SidenavInfoService,
|
private sidenavInfoService: SidenavInfoService,
|
||||||
private destroyRef: DestroyRef,
|
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private accountBalancesStoreService: AccountBalancesStoreService,
|
private accountBalancesStoreService: AccountBalancesStoreService,
|
||||||
) {}
|
) {}
|
||||||
@ -120,21 +131,16 @@ export class TerminalsComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getProvider(terminalObj: TerminalObject) {
|
|
||||||
return terminalObj.data.provider_ref
|
|
||||||
? this.domainStoreService
|
|
||||||
.getObjects('provider')
|
|
||||||
.pipe(
|
|
||||||
map((providers) =>
|
|
||||||
providers.find((p) => p.ref.id === terminalObj.data.provider_ref.id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: of(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getTerminalShopWalletDelegates(terminalObj: TerminalObject) {
|
private getTerminalShopWalletDelegates(terminalObj: TerminalObject) {
|
||||||
return this.domainStoreService
|
return this.domainStoreService
|
||||||
.getObjects('routing_rules')
|
.getObjects('routing_rules')
|
||||||
.pipe(map((rules) => getTerminalShopWalletDelegates(rules, terminalObj)));
|
.pipe(map((rules) => getTerminalShopWalletDelegates(rules, terminalObj)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toggleBalancesCard(d: TerminalObject) {
|
||||||
|
this.sidenavInfoService.toggle(TerminalBalancesCardComponent, {
|
||||||
|
terminalId: d.ref.id,
|
||||||
|
providerId: d.data.provider_ref.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
<cc-card title="Terminal #{{ terminalId() }} balances">
|
||||||
|
<v-table2 [(sort)]="sort" [columns]="columns" [data]="balances$ | async"></v-table2>
|
||||||
|
</cc-card>
|
@ -0,0 +1,41 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, input } from '@angular/core';
|
||||||
|
import { toObservable } from '@angular/core/rxjs-interop';
|
||||||
|
import { Sort } from '@angular/material/sort';
|
||||||
|
import { TableModule, Column2 } from '@vality/ng-core';
|
||||||
|
import { AccountBalance } from '@vality/scrooge-proto/internal/account_balance';
|
||||||
|
import { combineLatest } from 'rxjs';
|
||||||
|
import { switchMap, shareReplay } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { AccountBalancesStoreService } from '../../../api/terminal-balance';
|
||||||
|
import { createCurrencyColumn } from '../../utils/table2';
|
||||||
|
import { CardComponent } from '../sidenav-info/components/card/card.component';
|
||||||
|
import { DomainThriftViewerComponent } from '../thrift-api-crud';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'cc-terminal-balances-card',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, CardComponent, DomainThriftViewerComponent, TableModule],
|
||||||
|
templateUrl: './terminal-balances-card.component.html',
|
||||||
|
})
|
||||||
|
export class TerminalBalancesCardComponent {
|
||||||
|
terminalId = input<number>();
|
||||||
|
providerId = input<number>();
|
||||||
|
columns: Column2<AccountBalance>[] = [
|
||||||
|
{ field: 'account_id' },
|
||||||
|
createCurrencyColumn((d) => ({ code: d.balance.currency_code, amount: d.balance.amount }), {
|
||||||
|
header: 'Balance',
|
||||||
|
field: 'balance',
|
||||||
|
}),
|
||||||
|
{ field: 'last_updated', cell: { type: 'datetime' } },
|
||||||
|
];
|
||||||
|
balances$ = combineLatest([toObservable(this.terminalId), toObservable(this.providerId)]).pipe(
|
||||||
|
switchMap(([terminalId, providerId]) =>
|
||||||
|
this.accountBalancesStoreService.getTerminalBalances(terminalId, providerId),
|
||||||
|
),
|
||||||
|
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||||
|
);
|
||||||
|
sort: Sort = { active: 'account_id', direction: 'asc' };
|
||||||
|
|
||||||
|
constructor(private accountBalancesStoreService: AccountBalancesStoreService) {}
|
||||||
|
}
|
@ -112,7 +112,7 @@ export function getDomainObjectValueDetailsFn(key: keyof DomainObject): GetDomai
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getDomainObjectDetails(o: DomainObject): DomainObjectDetails {
|
export function getDomainObjectDetails(o: DomainObject): DomainObjectDetails {
|
||||||
if (!o || !getUnionValue(o)) {
|
if (!o || !getUnionValue(o)?.ref || !getUnionValue(o)?.data) {
|
||||||
return { id: null, label: '', description: '', type: '' };
|
return { id: null, label: '', description: '', type: '' };
|
||||||
}
|
}
|
||||||
const result = getDomainObjectValueDetailsFn(getUnionKey(o))(getUnionValue(o));
|
const result = getDomainObjectValueDetailsFn(getUnionKey(o))(getUnionValue(o));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { toMajorByExponent, toMinorByExponent } from '@vality/ng-core';
|
import { toMajorByExponent, toMinorByExponent } from '@vality/ng-core';
|
||||||
import { map, first } from 'rxjs/operators';
|
import { map, first, shareReplay } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/domain-config';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
@ -8,27 +8,28 @@ import { DomainStoreService } from '@cc/app/api/domain-config';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AmountCurrencyService {
|
export class AmountCurrencyService {
|
||||||
|
currencies$ = this.domainStoreService.getObjects('currency').pipe(
|
||||||
|
map((currencies) => new Map(currencies.map((c) => [c.ref.symbolic_code, c.data]))),
|
||||||
|
shareReplay(1),
|
||||||
|
);
|
||||||
|
|
||||||
constructor(private domainStoreService: DomainStoreService) {}
|
constructor(private domainStoreService: DomainStoreService) {}
|
||||||
|
|
||||||
toMajor(amount: number, symbolicCode: string) {
|
toMajor(amount: number, symbolicCode: string) {
|
||||||
return this.getCurrency(symbolicCode).pipe(
|
return this.getCurrency(symbolicCode).pipe(
|
||||||
first(),
|
first(),
|
||||||
map((currency) => toMajorByExponent(amount, currency?.data?.exponent)),
|
map((currency) => toMajorByExponent(amount, currency?.exponent)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
toMinor(amount: number, symbolicCode: string) {
|
toMinor(amount: number, symbolicCode: string) {
|
||||||
return this.getCurrency(symbolicCode).pipe(
|
return this.getCurrency(symbolicCode).pipe(
|
||||||
first(),
|
first(),
|
||||||
map((currency) => toMinorByExponent(amount, currency?.data?.exponent)),
|
map((currency) => toMinorByExponent(amount, currency?.exponent)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrency(symbolicCode: string) {
|
getCurrency(symbolicCode: string) {
|
||||||
return this.domainStoreService
|
return this.currencies$.pipe(map((currencies) => currencies.get(symbolicCode)));
|
||||||
.getObjects('currency')
|
|
||||||
.pipe(
|
|
||||||
map((currencies) => currencies.find((c) => c.ref.symbolic_code === symbolicCode)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ export function createCurrencyColumn<T extends object>(
|
|||||||
exponent: (d: T) =>
|
exponent: (d: T) =>
|
||||||
getPossiblyAsyncObservable(selectSymbolicCode(d)).pipe(
|
getPossiblyAsyncObservable(selectSymbolicCode(d)).pipe(
|
||||||
switchMap((code) => amountCurrencyService.getCurrency(code)),
|
switchMap((code) => amountCurrencyService.getCurrency(code)),
|
||||||
map((c) => c?.data?.exponent),
|
map((c) => c?.exponent),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
...params,
|
...params,
|
||||||
|
@ -1,28 +1,70 @@
|
|||||||
import { inject } from '@angular/core';
|
import { getCurrencySymbol } from '@angular/common';
|
||||||
import { createColumn } from '@vality/ng-core';
|
import { inject, LOCALE_ID } from '@angular/core';
|
||||||
import isNil from 'lodash-es/isNil';
|
import { createColumn, formatCurrency } from '@vality/ng-core';
|
||||||
import { of, concat, EMPTY } from 'rxjs';
|
import { groupBy, uniq } from 'lodash-es';
|
||||||
import { map } from 'rxjs/operators';
|
import { of, combineLatest } from 'rxjs';
|
||||||
|
import { map, startWith } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { DomainStoreService } from '../../../api/domain-config';
|
||||||
import { AmountCurrencyService } from '../../services';
|
import { AmountCurrencyService } from '../../services';
|
||||||
|
|
||||||
|
interface CurrencyValue {
|
||||||
|
amount: number;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatCurrencyValue(value: CurrencyValue) {
|
||||||
|
const amountCurrencyService = inject(AmountCurrencyService);
|
||||||
|
const locale = inject(LOCALE_ID);
|
||||||
|
return amountCurrencyService.getCurrency(value.code).pipe(
|
||||||
|
map((currencyObj) =>
|
||||||
|
formatCurrency(value.amount, value.code, 'long', locale, currencyObj?.exponent),
|
||||||
|
),
|
||||||
|
startWith(
|
||||||
|
(value.amount === 0 ? '0' : '…') +
|
||||||
|
' ' +
|
||||||
|
getCurrencySymbol(value.code, 'narrow', locale),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatCurrencyValues(values: CurrencyValue[], separator = ' | ') {
|
||||||
|
return combineLatest(values.map(formatCurrencyValue)).pipe(map((v) => v.join(separator)));
|
||||||
|
}
|
||||||
|
|
||||||
export const createCurrencyColumn = createColumn(
|
export const createCurrencyColumn = createColumn(
|
||||||
({ amount, code }: { amount: number; code: string }) => {
|
(currencyValue: CurrencyValue | { values: CurrencyValue[]; isSum?: boolean }) => {
|
||||||
const amountCurrencyService = inject(AmountCurrencyService);
|
const isSum = 'isSum' in currencyValue ? currencyValue.isSum : false;
|
||||||
if (isNil(amount)) {
|
const currencyValues = ('values' in currencyValue ? currencyValue.values : [currencyValue])
|
||||||
|
.filter(Boolean)
|
||||||
|
.sort((a, b) => b.amount - a.amount);
|
||||||
|
if (!currencyValues?.length) {
|
||||||
return of(undefined);
|
return of(undefined);
|
||||||
}
|
}
|
||||||
return concat(
|
const currencyValuesByCode = groupBy(currencyValues, 'code');
|
||||||
amount === 0 ? of(0) : EMPTY,
|
let currencyValuesByCodeList = uniq(currencyValues.map((v) => v.code)).map(
|
||||||
amountCurrencyService.getCurrency(code).pipe(map((c) => c?.data?.exponent)),
|
(code) => currencyValuesByCode[code],
|
||||||
).pipe(
|
);
|
||||||
map((exponent) => ({
|
if (isSum) {
|
||||||
value: amount,
|
currencyValuesByCodeList = currencyValuesByCodeList.map((g) =>
|
||||||
type: 'currency',
|
g.reduce(
|
||||||
params: {
|
(sum, v) => {
|
||||||
code,
|
sum[0].amount += v.amount;
|
||||||
exponent,
|
return sum;
|
||||||
},
|
},
|
||||||
|
[{ code: g[0].code, amount: 0 }],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const domainStoreService = inject(DomainStoreService);
|
||||||
|
return combineLatest([
|
||||||
|
combineLatest(currencyValuesByCodeList.map((g) => formatCurrencyValues(g))),
|
||||||
|
domainStoreService.isLoading$,
|
||||||
|
]).pipe(
|
||||||
|
map(([currencyValueStrings, inProgress]) => ({
|
||||||
|
value: currencyValueStrings[0],
|
||||||
|
description: currencyValueStrings.slice(1).join('; '),
|
||||||
|
inProgress,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { inject } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { Reference } from '@vality/domain-proto/internal/domain';
|
import { Reference } from '@vality/domain-proto/internal/domain';
|
||||||
import { createColumn } from '@vality/ng-core';
|
import { createColumn } from '@vality/ng-core';
|
||||||
import { getUnionKey, getUnionValue } from '@vality/ng-thrift';
|
import { getUnionValue, getUnionKey } from '@vality/ng-thrift';
|
||||||
import { map, startWith } from 'rxjs/operators';
|
import { map, startWith } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '../../../api/domain-config';
|
import { DomainStoreService } from '../../../api/domain-config';
|
||||||
@ -12,12 +12,12 @@ import {
|
|||||||
} from '../../components/thrift-api-crud';
|
} from '../../components/thrift-api-crud';
|
||||||
|
|
||||||
export const createDomainObjectColumn = createColumn(({ ref }: { ref: Reference }) => {
|
export const createDomainObjectColumn = createColumn(({ ref }: { ref: Reference }) => {
|
||||||
|
const sourceObj = {
|
||||||
|
[getUnionKey(ref)]: { ref: getUnionValue(ref), data: {} },
|
||||||
|
};
|
||||||
return inject(DomainStoreService)
|
return inject(DomainStoreService)
|
||||||
.getObject(ref)
|
.getObject(ref)
|
||||||
.pipe(
|
.pipe(
|
||||||
startWith({
|
|
||||||
[getUnionKey(ref)]: { ref: getUnionValue(ref), data: {} },
|
|
||||||
}),
|
|
||||||
map((obj) => ({
|
map((obj) => ({
|
||||||
value: getDomainObjectDetails(obj).label || '',
|
value: getDomainObjectDetails(obj).label || '',
|
||||||
description: getDomainObjectDetails(obj).id || '',
|
description: getDomainObjectDetails(obj).id || '',
|
||||||
@ -25,5 +25,13 @@ export const createDomainObjectColumn = createColumn(({ ref }: { ref: Reference
|
|||||||
inject(SidenavInfoService).toggle(DomainObjectCardComponent, { ref });
|
inject(SidenavInfoService).toggle(DomainObjectCardComponent, { ref });
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
|
startWith({
|
||||||
|
value: getDomainObjectDetails(sourceObj).label || '',
|
||||||
|
description: getDomainObjectDetails(sourceObj).id || '',
|
||||||
|
click: () => {
|
||||||
|
inject(SidenavInfoService).toggle(DomainObjectCardComponent, { ref });
|
||||||
|
},
|
||||||
|
inProgress: true,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -13,18 +13,22 @@ export const createPartyColumn = createColumn(
|
|||||||
? of(params.partyName)
|
? of(params.partyName)
|
||||||
: inject(PartiesStoreService)
|
: inject(PartiesStoreService)
|
||||||
.get(id)
|
.get(id)
|
||||||
.pipe(
|
.pipe(map((party) => party.contact_info.registration_email));
|
||||||
map((party) => party.contact_info.registration_email),
|
const partyCell = {
|
||||||
startWith(''),
|
description: id,
|
||||||
);
|
link: () => {
|
||||||
|
void inject(Router).navigate([`/party/${id}`]);
|
||||||
|
},
|
||||||
|
};
|
||||||
return partyName$.pipe(
|
return partyName$.pipe(
|
||||||
map((partyName) => ({
|
map((partyName) => ({
|
||||||
|
...partyCell,
|
||||||
value: partyName,
|
value: partyName,
|
||||||
description: id,
|
|
||||||
link: () => {
|
|
||||||
void inject(Router).navigate([`/party/${id}`]);
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
|
startWith({
|
||||||
|
...partyCell,
|
||||||
|
inProgress: true,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
{ header: 'Party' },
|
{ header: 'Party' },
|
||||||
|
18
src/app/shared/utils/table2/create-predicate-column.ts
Normal file
18
src/app/shared/utils/table2/create-predicate-column.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Predicate } from '@vality/domain-proto/domain';
|
||||||
|
import { createColumn } from '@vality/ng-core';
|
||||||
|
|
||||||
|
import { formatPredicate } from '../table';
|
||||||
|
|
||||||
|
export const createPredicateColumn = createColumn(
|
||||||
|
({ predicate }: { predicate: Predicate }) => {
|
||||||
|
const value = formatPredicate(predicate);
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
color: {
|
||||||
|
True: 'success',
|
||||||
|
False: 'warn',
|
||||||
|
}[value],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ header: 'Predicate' },
|
||||||
|
);
|
@ -1,7 +1,7 @@
|
|||||||
import { inject } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { createColumn } from '@vality/ng-core';
|
import { createColumn } from '@vality/ng-core';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map, startWith } from 'rxjs/operators';
|
||||||
|
|
||||||
import { PartiesStoreService } from '../../../api/payment-processing';
|
import { PartiesStoreService } from '../../../api/payment-processing';
|
||||||
import { ShopCardComponent } from '../../components/shop-card/shop-card.component';
|
import { ShopCardComponent } from '../../components/shop-card/shop-card.component';
|
||||||
@ -16,14 +16,21 @@ export const createShopColumn = createColumn(
|
|||||||
.get(partyId)
|
.get(partyId)
|
||||||
.pipe(map((party) => party.shops.get(shopId).details.name));
|
.pipe(map((party) => party.shops.get(shopId).details.name));
|
||||||
const sidenavInfoService = inject(SidenavInfoService);
|
const sidenavInfoService = inject(SidenavInfoService);
|
||||||
|
const shopCell = {
|
||||||
|
description: shopId,
|
||||||
|
click: () => {
|
||||||
|
sidenavInfoService.toggle(ShopCardComponent, { id: shopId, partyId });
|
||||||
|
},
|
||||||
|
};
|
||||||
return shopName$.pipe(
|
return shopName$.pipe(
|
||||||
map((shopName) => ({
|
map((shopName) => ({
|
||||||
|
...shopCell,
|
||||||
value: shopName,
|
value: shopName,
|
||||||
description: shopId,
|
|
||||||
click: () => {
|
|
||||||
sidenavInfoService.toggle(ShopCardComponent, { id: shopId, partyId });
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
|
startWith({
|
||||||
|
...shopCell,
|
||||||
|
inProgress: true,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
{ header: 'Shop' },
|
{ header: 'Shop' },
|
||||||
|
@ -4,3 +4,4 @@ export * from './create-wallet-column';
|
|||||||
export * from './create-contract-column';
|
export * from './create-contract-column';
|
||||||
export * from './create-domain-object-column';
|
export * from './create-domain-object-column';
|
||||||
export * from './create-currency-column';
|
export * from './create-currency-column';
|
||||||
|
export * from './create-predicate-column';
|
||||||
|
Loading…
Reference in New Issue
Block a user