mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
IMP-63: Support new wallet modifications and others (#231)
This commit is contained in:
parent
99a65e917b
commit
12628346bc
14
package-lock.json
generated
14
package-lock.json
generated
@ -30,7 +30,7 @@
|
||||
"@vality/dominant-cache-proto": "2.0.1-99f38c9.0",
|
||||
"@vality/fistful-proto": "2.0.1-4ff4ea3.0",
|
||||
"@vality/magista-proto": "2.0.1-cf0eff8.0",
|
||||
"@vality/ng-core": "0.7.1-pr-26-5b97f36.0",
|
||||
"@vality/ng-core": "15.0.0",
|
||||
"@vality/payout-manager-proto": "2.0.1-b079679.0",
|
||||
"@vality/repairer-proto": "2.0.1-8f7973d.0",
|
||||
"@vality/thrift-ts": "2.4.1-8ad5123.0",
|
||||
@ -6602,9 +6602,9 @@
|
||||
"integrity": "sha512-59ncaJpt7tXFLOq9KrDu4OgrDQr9vTQ3j30T0hjN+ZIsPBsE+lld/pGKASWLLQfwvTtvp9laAuKgQGX9GuvIiQ=="
|
||||
},
|
||||
"node_modules/@vality/ng-core": {
|
||||
"version": "0.7.1-pr-26-5b97f36.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-0.7.1-pr-26-5b97f36.0.tgz",
|
||||
"integrity": "sha512-d95e80Y6yrPSGmfqVQWmREPEH8TVEDqaobphcroa9a+FHzjexh14+mDh3jxcgYlsuLMI4j1+yBXMDwTqCWXMcw==",
|
||||
"version": "15.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-15.0.0.tgz",
|
||||
"integrity": "sha512-7ux9yH80Bu7QnONFzmY8BSlxCZojvervVuecZdLAhvCo0/W6/NysOjzt3skSsi4S9I0vEtfaJ2kYpFqfqLjuJA==",
|
||||
"dependencies": {
|
||||
"@ng-matero/extensions": "^15.0.0",
|
||||
"@s-libs/js-core": "^15.2.0",
|
||||
@ -27589,9 +27589,9 @@
|
||||
"integrity": "sha512-59ncaJpt7tXFLOq9KrDu4OgrDQr9vTQ3j30T0hjN+ZIsPBsE+lld/pGKASWLLQfwvTtvp9laAuKgQGX9GuvIiQ=="
|
||||
},
|
||||
"@vality/ng-core": {
|
||||
"version": "0.7.1-pr-26-5b97f36.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-0.7.1-pr-26-5b97f36.0.tgz",
|
||||
"integrity": "sha512-d95e80Y6yrPSGmfqVQWmREPEH8TVEDqaobphcroa9a+FHzjexh14+mDh3jxcgYlsuLMI4j1+yBXMDwTqCWXMcw==",
|
||||
"version": "15.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-15.0.0.tgz",
|
||||
"integrity": "sha512-7ux9yH80Bu7QnONFzmY8BSlxCZojvervVuecZdLAhvCo0/W6/NysOjzt3skSsi4S9I0vEtfaJ2kYpFqfqLjuJA==",
|
||||
"requires": {
|
||||
"@ng-matero/extensions": "^15.0.0",
|
||||
"@s-libs/js-core": "^15.2.0",
|
||||
|
@ -39,7 +39,7 @@
|
||||
"@vality/dominant-cache-proto": "2.0.1-99f38c9.0",
|
||||
"@vality/fistful-proto": "2.0.1-4ff4ea3.0",
|
||||
"@vality/magista-proto": "2.0.1-cf0eff8.0",
|
||||
"@vality/ng-core": "0.7.1-pr-26-5b97f36.0",
|
||||
"@vality/ng-core": "15.0.0",
|
||||
"@vality/payout-manager-proto": "2.0.1-b079679.0",
|
||||
"@vality/repairer-proto": "2.0.1-8f7973d.0",
|
||||
"@vality/thrift-ts": "2.4.1-8ad5123.0",
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ClaimStatus as ClaimStatusUnion } from '@vality/domain-proto/claim_management';
|
||||
import { ClaimStatus } from '@vality/domain-proto/claim_management';
|
||||
|
||||
import { enumerate } from '@cc/utils';
|
||||
|
||||
export const CLAIM_STATUSES = enumerate<keyof ClaimStatusUnion>()(
|
||||
export const CLAIM_STATUSES = enumerate<keyof ClaimStatus>()(
|
||||
'pending',
|
||||
'review',
|
||||
'pending_acceptance',
|
||||
@ -10,13 +10,3 @@ export const CLAIM_STATUSES = enumerate<keyof ClaimStatusUnion>()(
|
||||
'denied',
|
||||
'revoked'
|
||||
);
|
||||
|
||||
/** @deprecated use CLAIM_STATUS - it checks for the occurrence of all elements */
|
||||
export enum ClaimStatus {
|
||||
Pending = 'pending',
|
||||
Review = 'review',
|
||||
Denied = 'denied',
|
||||
Revoked = 'revoked',
|
||||
Accepted = 'accepted',
|
||||
PendingAcceptance = 'pending_acceptance',
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import { AppAuthGuardService } from '@cc/app/shared/services';
|
||||
|
||||
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 PAYMENTS_ROUTING_CONFIG } from './sections/payments/routing-config';
|
||||
import { ROUTING_CONFIG as PAYOUTS_ROUTING_CONFIG } from './sections/payouts/payouts/routing-config';
|
||||
import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing/routing-config';
|
||||
import { ROUTING_CONFIG as CLAIMS_ROUTING_CONFIG } from './sections/search-claims/routing-config';
|
||||
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
||||
import { ROUTING_CONFIG as SOURCES_ROUTING_CONFIG } from './sections/sources/routing-config';
|
||||
import { ROUTING_CONFIG as WALLETS_ROUTING_CONFIG } from './sections/wallets/routing-config';
|
||||
|
@ -28,8 +28,8 @@ import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { CoreModule } from './core/core.module';
|
||||
import icons from './icons.json';
|
||||
import { ClaimsModule } from './sections/claims/claims.module';
|
||||
import { PayoutsModule } from './sections/payouts';
|
||||
import { SearchClaimsModule } from './sections/search-claims/search-claims.module';
|
||||
import { SearchPartiesModule } from './sections/search-parties/search-parties.module';
|
||||
import { SectionsModule } from './sections/sections.module';
|
||||
import {
|
||||
@ -68,7 +68,7 @@ export let AppInjector: Injector;
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
SearchPartiesModule,
|
||||
SearchClaimsModule,
|
||||
ClaimsModule,
|
||||
KeycloakTokenInfoModule,
|
||||
PayoutsModule,
|
||||
SectionsModule,
|
||||
|
@ -1,20 +1,26 @@
|
||||
<cc-page-layout *ngIf="claim$ | async as claim" description="#{{ claim.id }}" title="Claim">
|
||||
<cc-page-layout-actions>
|
||||
<cc-page-layout
|
||||
[path]="[
|
||||
{ label: 'Merchants', link: '/parties' },
|
||||
{
|
||||
label: (party$ | async)?.contact_info?.email,
|
||||
tooltip: (party$ | async)?.id,
|
||||
link: ['/party', (party$ | async)?.id]
|
||||
},
|
||||
{
|
||||
label: 'Merchant claims',
|
||||
link: '/claims',
|
||||
queryParams: { party_id: '"' + (party$ | async)?.id + '"' }
|
||||
}
|
||||
]"
|
||||
description="#{{ (claim$ | async)?.id }}"
|
||||
title="Claim"
|
||||
>
|
||||
<cc-page-layout-actions *ngIf="claim$ | async as claim">
|
||||
<cc-status [color]="statusColor[claim.status | ccUnionKey]">{{
|
||||
claim.status | ccUnionKey | keyTitle | titlecase
|
||||
}}</cc-status>
|
||||
</cc-page-layout-actions>
|
||||
|
||||
<div gdColumns="1fr" gdGap="16px">
|
||||
<div *ngIf="party$ | async as party" fxLayoutAlign="space-between center">
|
||||
<span class="mat-h3 mat-secondary-text">
|
||||
<a class="mat-secondary-text" routerLink="/claims">Claims</a> / Claim details
|
||||
</span>
|
||||
<span class="mat-h3 mat-secondary-text">
|
||||
{{ party.contact_info.email }} (#{{ party.id }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="claim$ | async as claim" gdColumns="1fr" gdGap="24px">
|
||||
<h2 class="mat-headline-5">Changeset</h2>
|
||||
<div *ngIf="isLoading$ | async; else timeline" fxLayoutAlign="center">
|
||||
@ -78,6 +84,13 @@
|
||||
(claimChanged)="reloadClaim()"
|
||||
></cc-modification-unit-timeline-item>
|
||||
</ng-container>
|
||||
<cc-modification-unit-timeline-item
|
||||
*ngSwitchDefault
|
||||
[claim]="claim"
|
||||
[modificationUnit]="modificationUnit"
|
||||
isChangeable
|
||||
(claimChanged)="reloadClaim()"
|
||||
></cc-modification-unit-timeline-item>
|
||||
</ng-container>
|
||||
</cc-timeline>
|
||||
</ng-template>
|
||||
|
@ -1,22 +1,18 @@
|
||||
import { Modification } from '@vality/domain-proto/claim_management';
|
||||
import isObject from 'lodash-es/isObject';
|
||||
|
||||
import { getUnionKey } from '../../../../utils';
|
||||
import { MODIFICATIONS_NAME_TREE } from './types/modifications-name-tree';
|
||||
|
||||
export function getModificationName(modification: Modification) {
|
||||
let value: unknown = modification;
|
||||
let name: unknown = MODIFICATIONS_NAME_TREE;
|
||||
while (value) {
|
||||
if (typeof value === 'object') {
|
||||
const key = Object.keys(value).find((k) => Object.keys(name).includes(k));
|
||||
value = value[key];
|
||||
name = name[key];
|
||||
}
|
||||
if (!name) {
|
||||
console.error('Unknown modification:', modification);
|
||||
return 'Unknown Modification';
|
||||
}
|
||||
if (typeof name === 'string') {
|
||||
return name + ' Modification';
|
||||
}
|
||||
let currentValue: unknown = modification;
|
||||
let currentName: unknown = MODIFICATIONS_NAME_TREE;
|
||||
while (isObject(currentName) && isObject(currentValue)) {
|
||||
const key = Object.keys(currentValue).find((k) => Object.keys(currentName).includes(k));
|
||||
currentValue = currentValue?.[key];
|
||||
currentName = currentName?.[key];
|
||||
}
|
||||
return typeof currentName === 'string'
|
||||
? `${currentName} Modification`
|
||||
: getUnionKey(modification);
|
||||
}
|
||||
|
@ -1,85 +1,8 @@
|
||||
import {
|
||||
CashRegisterModificationUnit,
|
||||
ClaimModification,
|
||||
CommentModificationUnit,
|
||||
ContractAdjustmentModificationUnit,
|
||||
ContractModificationUnit,
|
||||
ContractorModificationUnit,
|
||||
DocumentModificationUnit,
|
||||
FileModificationUnit,
|
||||
Modification,
|
||||
PartyModification,
|
||||
PayoutToolModificationUnit,
|
||||
ShopModificationUnit,
|
||||
StatusModificationUnit,
|
||||
WalletModificationUnit,
|
||||
WalletModification,
|
||||
IdentityModification,
|
||||
} from '@vality/domain-proto/claim_management';
|
||||
import { Overwrite } from 'utility-types';
|
||||
import { Modification } from '@vality/domain-proto/claim_management';
|
||||
|
||||
type OverwriteAll<T extends object, U extends { [N in keyof T]-?: unknown }> = U;
|
||||
type ModificationsNameTree<T> = { [N in keyof T]?: ModificationsNameTree<T[N]> | string };
|
||||
|
||||
type ModificationsName<T extends object> = {
|
||||
[P in keyof T]-?: string;
|
||||
};
|
||||
type ModificationUnitsName<
|
||||
T extends { modification: object },
|
||||
O extends { [N in keyof T['modification']]?: unknown } = Record<never, never>
|
||||
> = {
|
||||
modification: Overwrite<ModificationsName<T['modification']>, O>;
|
||||
};
|
||||
|
||||
type ModificationsNameTree = OverwriteAll<
|
||||
Modification,
|
||||
{
|
||||
claim_modification: OverwriteAll<
|
||||
ClaimModification,
|
||||
{
|
||||
document_modification: ModificationUnitsName<DocumentModificationUnit>;
|
||||
file_modification: ModificationUnitsName<FileModificationUnit>;
|
||||
comment_modification: ModificationUnitsName<CommentModificationUnit>;
|
||||
status_modification: ModificationUnitsName<StatusModificationUnit>;
|
||||
external_info_modification: string;
|
||||
}
|
||||
>;
|
||||
party_modification: OverwriteAll<
|
||||
PartyModification,
|
||||
{
|
||||
contractor_modification: ModificationUnitsName<ContractorModificationUnit>;
|
||||
contract_modification: ModificationUnitsName<
|
||||
ContractModificationUnit,
|
||||
{
|
||||
adjustment_modification: ModificationUnitsName<ContractAdjustmentModificationUnit>;
|
||||
payout_tool_modification: ModificationUnitsName<PayoutToolModificationUnit>;
|
||||
}
|
||||
>;
|
||||
shop_modification: ModificationUnitsName<
|
||||
ShopModificationUnit,
|
||||
{
|
||||
cash_register_modification_unit: ModificationUnitsName<CashRegisterModificationUnit>;
|
||||
}
|
||||
>;
|
||||
wallet_modification: ModificationUnitsName<WalletModificationUnit>;
|
||||
}
|
||||
>;
|
||||
identity_modification: OverwriteAll<
|
||||
IdentityModification,
|
||||
{
|
||||
creation: string;
|
||||
}
|
||||
>;
|
||||
wallet_modification: OverwriteAll<
|
||||
WalletModification,
|
||||
{
|
||||
creation: string;
|
||||
account_creation: string;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>;
|
||||
|
||||
export const MODIFICATIONS_NAME_TREE: ModificationsNameTree = {
|
||||
export const MODIFICATIONS_NAME_TREE: ModificationsNameTree<Modification> = {
|
||||
claim_modification: {
|
||||
document_modification: {
|
||||
modification: {
|
||||
@ -154,16 +77,19 @@ export const MODIFICATIONS_NAME_TREE: ModificationsNameTree = {
|
||||
},
|
||||
wallet_modification: {
|
||||
modification: {
|
||||
creation: 'Wallet Creation',
|
||||
account_creation: 'Wallet Account Creation',
|
||||
creation: 'Old Wallet Creation',
|
||||
account_creation: 'Old Wallet Account Creation',
|
||||
},
|
||||
},
|
||||
},
|
||||
identity_modification: {
|
||||
modification: {
|
||||
creation: 'Identity Creation',
|
||||
},
|
||||
},
|
||||
wallet_modification: {
|
||||
modification: {
|
||||
creation: 'Wallet Creation',
|
||||
account_creation: 'Wallet Account Creation',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -3,15 +3,15 @@ import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppAuthGuardService } from '@cc/app/shared/services';
|
||||
|
||||
import { ClaimsComponent } from './claims.component';
|
||||
import { ROUTING_CONFIG } from './routing-config';
|
||||
import { SearchClaimsComponent } from './search-claims.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: 'claims',
|
||||
component: SearchClaimsComponent,
|
||||
component: ClaimsComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: ROUTING_CONFIG,
|
||||
},
|
||||
@ -19,4 +19,4 @@ import { SearchClaimsComponent } from './search-claims.component';
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class SearchClaimsComponentRouting {}
|
||||
export class ClaimsComponentRouting {}
|
@ -0,0 +1,10 @@
|
||||
<v-table
|
||||
[columns]="columns"
|
||||
[data]="data"
|
||||
[hasMore]="hasMore"
|
||||
[progress]="isLoading"
|
||||
(more)="more.emit()"
|
||||
(update)="update.emit($event)"
|
||||
>
|
||||
<v-table-actions><ng-content></ng-content></v-table-actions>
|
||||
</v-table>
|
@ -0,0 +1,72 @@
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Claim, ClaimStatus } from '@vality/domain-proto/claim_management';
|
||||
import { Column, LoadOptions, TagColumn } from '@vality/ng-core';
|
||||
import startCase from 'lodash-es/startCase';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { getUnionKey } from '../../../../utils';
|
||||
import { PartiesStoreService } from '../../../api/payment-processing';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claims-table',
|
||||
templateUrl: './claims-table.component.html',
|
||||
styleUrls: ['./claims-table.component.scss'],
|
||||
})
|
||||
export class ClaimsTableComponent {
|
||||
@Input() data!: Claim[];
|
||||
@Input() isLoading?: boolean | null;
|
||||
@Input() hasMore?: boolean | null;
|
||||
|
||||
@Output() update = new EventEmitter<LoadOptions>();
|
||||
@Output() more = new EventEmitter<void>();
|
||||
|
||||
columns: Column<Claim>[] = [
|
||||
{ field: 'id', pinned: 'left' },
|
||||
{
|
||||
field: 'party',
|
||||
description: 'party_id',
|
||||
formatter: (claim) =>
|
||||
this.partiesStoreService.get(claim.party_id).pipe(map((p) => p.contact_info.email)),
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
type: 'tag',
|
||||
formatter: (claim) => getUnionKey(claim.status),
|
||||
typeParameters: {
|
||||
label: (claim) => startCase(getUnionKey(claim.status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
review: { color: 'pending' },
|
||||
pending_acceptance: { color: 'pending' },
|
||||
accepted: { color: 'success' },
|
||||
denied: { color: 'warn' },
|
||||
},
|
||||
},
|
||||
} as TagColumn<Claim, keyof ClaimStatus>,
|
||||
'revision',
|
||||
{ field: 'created_at', type: 'datetime' },
|
||||
{ field: 'updated_at', type: 'datetime' },
|
||||
{
|
||||
field: 'operation',
|
||||
header: '',
|
||||
type: 'menu',
|
||||
pinned: 'right',
|
||||
width: '0',
|
||||
typeParameters: {
|
||||
items: [
|
||||
{
|
||||
label: 'Details',
|
||||
click: (claim) => this.navigateToClaim(claim.party_id, claim.id),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
constructor(private router: Router, private partiesStoreService: PartiesStoreService) {}
|
||||
|
||||
navigateToClaim(partyId: string, claimID: number) {
|
||||
void this.router.navigate([`/party/${partyId}/claim/${claimID}`]);
|
||||
}
|
||||
}
|
35
src/app/sections/claims/claims.component.html
Normal file
35
src/app/sections/claims/claims.component.html
Normal file
@ -0,0 +1,35 @@
|
||||
<cc-page-layout title="Claims">
|
||||
<cc-page-layout-actions
|
||||
><v-more-filters-button [filters]="filters"></v-more-filters-button
|
||||
></cc-page-layout-actions>
|
||||
<v-filters #filters [active]="active">
|
||||
<ng-template [formGroup]="filtersForm">
|
||||
<mat-form-field>
|
||||
<input
|
||||
autocomplete="off"
|
||||
formControlName="claim_id"
|
||||
matInput
|
||||
placeholder="Claim ID"
|
||||
type="number"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-select formControlName="statuses" multiple placeholder="Claim statuses">
|
||||
<mat-option *ngFor="let status of claimStatuses" [value]="status">{{
|
||||
status | keyTitle | titlecase
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<cc-merchant-field formControlName="party_id"></cc-merchant-field>
|
||||
</ng-template>
|
||||
</v-filters>
|
||||
<cc-claims-table
|
||||
[data]="claims$ | async"
|
||||
[hasMore]="hasMore$ | async"
|
||||
[isLoading]="isLoading$ | async"
|
||||
(more)="more()"
|
||||
(update)="load($event)"
|
||||
>
|
||||
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
||||
</cc-claims-table>
|
||||
</cc-page-layout>
|
64
src/app/sections/claims/claims.component.ts
Normal file
64
src/app/sections/claims/claims.component.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { NonNullableFormBuilder } from '@angular/forms';
|
||||
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { PartyID } from '@vality/domain-proto/domain';
|
||||
import { DialogService, LoadOptions, QueryParamsService, clean } from '@vality/ng-core';
|
||||
import { debounceTime } from 'rxjs';
|
||||
import { startWith } from 'rxjs/operators';
|
||||
|
||||
import { CLAIM_STATUSES } from '../../api/claim-management';
|
||||
import { CreateClaimDialogComponent } from './components/create-claim-dialog/create-claim-dialog.component';
|
||||
import { FetchClaimsService } from './fetch-claims.service';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
templateUrl: './claims.component.html',
|
||||
})
|
||||
export class ClaimsComponent implements OnInit {
|
||||
isLoading$ = this.fetchClaimsService.isLoading$;
|
||||
claims$ = this.fetchClaimsService.result$;
|
||||
hasMore$ = this.fetchClaimsService.hasMore$;
|
||||
claimStatuses = CLAIM_STATUSES;
|
||||
filtersForm = this.fb.group({
|
||||
party_id: undefined as string,
|
||||
claim_id: undefined as number,
|
||||
statuses: [[] as string[]],
|
||||
});
|
||||
active = 0;
|
||||
|
||||
private selectedPartyId: PartyID;
|
||||
|
||||
constructor(
|
||||
private fetchClaimsService: FetchClaimsService,
|
||||
private dialogService: DialogService,
|
||||
private fb: NonNullableFormBuilder,
|
||||
private qp: QueryParamsService<ClaimsComponent['filtersForm']['value']>
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.filtersForm.patchValue(this.qp.params);
|
||||
this.filtersForm.valueChanges
|
||||
.pipe(startWith(null), debounceTime(500), untilDestroyed(this))
|
||||
.subscribe(() => {
|
||||
this.load();
|
||||
});
|
||||
}
|
||||
|
||||
load(options?: LoadOptions): void {
|
||||
const filters = clean(this.filtersForm.value);
|
||||
void this.qp.set(filters);
|
||||
this.fetchClaimsService.load(
|
||||
{ ...filters, statuses: filters.statuses?.map((status) => ({ [status]: {} })) || [] },
|
||||
options
|
||||
);
|
||||
this.active = Object.keys(filters).length;
|
||||
}
|
||||
|
||||
more(): void {
|
||||
this.fetchClaimsService.more();
|
||||
}
|
||||
|
||||
create() {
|
||||
this.dialogService.open(CreateClaimDialogComponent, { partyId: this.selectedPartyId });
|
||||
}
|
||||
}
|
@ -14,25 +14,22 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { ActionsModule, DialogModule } from '@vality/ng-core';
|
||||
import { ActionsModule, DialogModule, TableModule, FiltersModule } from '@vality/ng-core';
|
||||
|
||||
import { ClaimSearchFormModule, PageLayoutModule } from '@cc/app/shared/components';
|
||||
import { PageLayoutModule } from '@cc/app/shared/components';
|
||||
import { MerchantFieldModule } from '@cc/app/shared/components/merchant-field';
|
||||
import { ApiModelPipesModule, ThriftPipesModule } from '@cc/app/shared/pipes';
|
||||
import { EmptySearchResultModule } from '@cc/components/empty-search-result';
|
||||
import { TableModule } from '@cc/components/table';
|
||||
|
||||
import { ClaimsComponentRouting } from './claims-routing.module';
|
||||
import { ClaimsTableComponent } from './claims-table/claims-table.component';
|
||||
import { ClaimsComponent } from './claims.component';
|
||||
import { CreateClaimDialogComponent } from './components/create-claim-dialog/create-claim-dialog.component';
|
||||
import { SearchClaimsComponentRouting } from './search-claims-routing.module';
|
||||
import { SearchClaimsComponent } from './search-claims.component';
|
||||
import { SearchClaimsService } from './search-claims.service';
|
||||
import { ClaimMailPipePipe } from './search-table/claim-mail-pipe.pipe';
|
||||
import { SearchTableComponent } from './search-table/search-table.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
SearchClaimsComponentRouting,
|
||||
ClaimsComponentRouting,
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatDialogModule,
|
||||
@ -47,7 +44,6 @@ import { SearchTableComponent } from './search-table/search-table.component';
|
||||
ReactiveFormsModule,
|
||||
FlexLayoutModule,
|
||||
MatExpansionModule,
|
||||
ClaimSearchFormModule,
|
||||
EmptySearchResultModule,
|
||||
ApiModelPipesModule,
|
||||
ThriftPipesModule,
|
||||
@ -56,13 +52,9 @@ import { SearchTableComponent } from './search-table/search-table.component';
|
||||
DialogModule,
|
||||
MerchantFieldModule,
|
||||
PageLayoutModule,
|
||||
TableModule,
|
||||
FiltersModule,
|
||||
],
|
||||
declarations: [
|
||||
SearchClaimsComponent,
|
||||
SearchTableComponent,
|
||||
ClaimMailPipePipe,
|
||||
CreateClaimDialogComponent,
|
||||
],
|
||||
providers: [SearchClaimsService],
|
||||
declarations: [ClaimsComponent, ClaimsTableComponent, CreateClaimDialogComponent],
|
||||
})
|
||||
export class SearchClaimsModule {}
|
||||
export class ClaimsModule {}
|
@ -1,37 +1,42 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Claim, ClaimSearchQuery } from '@vality/domain-proto/claim_management';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { FetchSuperclass, FetchResult, FetchOptions, NotifyLogService } from '@vality/ng-core';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, catchError } from 'rxjs/operators';
|
||||
|
||||
import { ClaimManagementService } from '@cc/app/api/claim-management';
|
||||
import { FetchResult, PartialFetcher } from '@cc/app/shared/services';
|
||||
|
||||
@Injectable()
|
||||
export class SearchClaimsService extends PartialFetcher<
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FetchClaimsService extends FetchSuperclass<
|
||||
Claim,
|
||||
Omit<ClaimSearchQuery, 'continuation_token' | 'limit'>
|
||||
> {
|
||||
private readonly searchLimit = 10;
|
||||
|
||||
constructor(private claimManagementService: ClaimManagementService) {
|
||||
constructor(
|
||||
private claimManagementService: ClaimManagementService,
|
||||
private log: NotifyLogService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected fetch(
|
||||
params: Omit<ClaimSearchQuery, 'continuation_token' | 'limit'>,
|
||||
continuationToken: string
|
||||
{ size, continuationToken }: FetchOptions
|
||||
): Observable<FetchResult<Claim>> {
|
||||
return this.claimManagementService
|
||||
.SearchClaims({
|
||||
...params,
|
||||
continuation_token: continuationToken,
|
||||
limit: this.searchLimit,
|
||||
} as ClaimSearchQuery)
|
||||
limit: size,
|
||||
})
|
||||
.pipe(
|
||||
map((r) => ({
|
||||
result: r.result,
|
||||
continuationToken: r.continuation_token,
|
||||
}))
|
||||
})),
|
||||
catchError((err) => {
|
||||
this.log.errorOperation(err, 'receive', 'claims');
|
||||
return of({ result: [] });
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -48,14 +48,13 @@ export class PaymentsTableComponent {
|
||||
{
|
||||
field: 'status',
|
||||
type: 'tag',
|
||||
formatter: (data) => startCase(getUnionKey(data.status)),
|
||||
formatter: (data) => getUnionKey(data.status),
|
||||
typeParameters: {
|
||||
value: (data) => getUnionKey(data.status),
|
||||
label: (data) => startCase(getUnionKey(data.status)),
|
||||
tags: {
|
||||
pending: { color: 'pending' },
|
||||
processed: { color: 'pending' },
|
||||
captured: { color: 'success' },
|
||||
cancelled: {},
|
||||
refunded: { color: 'success' },
|
||||
failed: { color: 'warn' },
|
||||
charged_back: { color: 'success' },
|
||||
@ -86,7 +85,7 @@ export class PaymentsTableComponent {
|
||||
field: 'menu',
|
||||
header: '',
|
||||
pinned: 'right',
|
||||
maxWidth: 0,
|
||||
width: '0',
|
||||
type: 'menu',
|
||||
typeParameters: {
|
||||
items: [
|
||||
|
@ -1,25 +0,0 @@
|
||||
<cc-page-layout title="Claims">
|
||||
<cc-page-layout-actions>
|
||||
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
||||
</cc-page-layout-actions>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<cc-claim-search-form (valueChanges)="search($event)"></cc-claim-search-form>
|
||||
</mat-card-content>
|
||||
<mat-card-footer *ngIf="doAction$ | async">
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</mat-card-footer>
|
||||
</mat-card>
|
||||
<ng-container *ngIf="claims$ | async as claims">
|
||||
<cc-empty-search-result *ngIf="claims.length === 0"></cc-empty-search-result>
|
||||
<mat-card *ngIf="claims.length > 0" fxLayout="column" fxLayoutGap="18px">
|
||||
<cc-search-table [claims]="claims"></cc-search-table>
|
||||
<cc-show-more-button
|
||||
*ngIf="hasMore$ | async"
|
||||
[inProgress]="doAction$ | async"
|
||||
(click)="fetchMore()"
|
||||
>
|
||||
</cc-show-more-button>
|
||||
</mat-card>
|
||||
</ng-container>
|
||||
</cc-page-layout>
|
@ -1,46 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { PartyID } from '@vality/domain-proto/domain';
|
||||
import { DialogService, cleanPrimitiveProps, clean } from '@vality/ng-core';
|
||||
|
||||
import { ClaimSearchForm } from '@cc/app/shared/components';
|
||||
|
||||
import { CreateClaimDialogComponent } from './components/create-claim-dialog/create-claim-dialog.component';
|
||||
import { SearchClaimsService } from './search-claims.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './search-claims.component.html',
|
||||
})
|
||||
export class SearchClaimsComponent implements OnInit {
|
||||
doAction$ = this.searchClaimService.doAction$;
|
||||
claims$ = this.searchClaimService.searchResult$;
|
||||
hasMore$ = this.searchClaimService.hasMore$;
|
||||
private selectedPartyId: PartyID;
|
||||
|
||||
constructor(
|
||||
private searchClaimService: SearchClaimsService,
|
||||
private snackBar: MatSnackBar,
|
||||
private dialogService: DialogService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.searchClaimService.errors$.subscribe((e) =>
|
||||
this.snackBar.open(`An error occurred while search claims (${String(e)})`, 'OK')
|
||||
);
|
||||
}
|
||||
|
||||
search(v: ClaimSearchForm): void {
|
||||
this.selectedPartyId = v?.party_id;
|
||||
this.searchClaimService.search(
|
||||
cleanPrimitiveProps({ ...v, statuses: clean(v.statuses?.map((s) => ({ [s]: {} }))) })
|
||||
);
|
||||
}
|
||||
|
||||
fetchMore(): void {
|
||||
this.searchClaimService.fetchMore();
|
||||
}
|
||||
|
||||
create() {
|
||||
this.dialogService.open(CreateClaimDialogComponent, { partyId: this.selectedPartyId });
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { Claim } from '@vality/domain-proto/claim_management';
|
||||
|
||||
@Pipe({
|
||||
name: 'ccClaimMail',
|
||||
})
|
||||
export class ClaimMailPipePipe implements PipeTransform {
|
||||
transform(value: Claim): string {
|
||||
let res = 'Unknown';
|
||||
|
||||
const changeSet = value.changeset;
|
||||
if (changeSet.length > 0) {
|
||||
const modificationUnit = changeSet[0];
|
||||
res = modificationUnit.user_info.email;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<table [dataSource]="claims" mat-table>
|
||||
<ng-container matColumnDef="claimID">
|
||||
<th *matHeaderCellDef fxHide.sm fxHide.xs mat-header-cell>Claim ID</th>
|
||||
<td *matCellDef="let claim" fxHide.sm fxHide.xs mat-cell>{{ claim.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="party">
|
||||
<th *matHeaderCellDef mat-header-cell>Party</th>
|
||||
<td *matCellDef="let claim" mat-cell>
|
||||
<div>{{ claim | ccClaimMail }}</div>
|
||||
<div class="mat-caption party-id">{{ claim.party_id }}</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="status">
|
||||
<th *matHeaderCellDef mat-header-cell>Status</th>
|
||||
<td *matCellDef="let claim" mat-cell>
|
||||
{{ claim.status | ccClaimStatusThrift | ccClaimStatus }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="revision">
|
||||
<th *matHeaderCellDef mat-header-cell>Revision</th>
|
||||
<td *matCellDef="let claim" mat-cell>
|
||||
{{ claim.revision }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="updatedAt">
|
||||
<th *matHeaderCellDef fxHide.sm fxHide.xs mat-header-cell>Updated At</th>
|
||||
<td *matCellDef="let claim" fxHide.sm fxHide.xs mat-cell>
|
||||
{{ claim.updated_at | date : 'dd.MM.yyyy HH:mm:ss' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="createdAt">
|
||||
<th *matHeaderCellDef fxHide.sm fxHide.xs mat-header-cell>Created At</th>
|
||||
<td *matCellDef="let claim" fxHide.sm fxHide.xs mat-cell>
|
||||
{{ claim.created_at | date : 'dd.MM.yyyy HH:mm:ss' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<th *matHeaderCellDef class="action-cell" mat-header-cell></th>
|
||||
<td *matCellDef="let claim" class="action-cell" mat-cell>
|
||||
<button [matMenuTriggerFor]="menu" mat-icon-button>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="navigateToClaim(claim.party_id, claim.id)">
|
||||
Details
|
||||
</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
|
||||
<tr *matRowDef="let claim; columns: displayedColumns" mat-row></tr>
|
||||
</table>
|
@ -1,29 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Claim } from '@vality/domain-proto/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-search-table',
|
||||
templateUrl: './search-table.component.html',
|
||||
styleUrls: ['./search-table.component.scss'],
|
||||
})
|
||||
export class SearchTableComponent {
|
||||
@Input()
|
||||
claims: Claim[];
|
||||
|
||||
displayedColumns = [
|
||||
'claimID',
|
||||
'party',
|
||||
'status',
|
||||
'revision',
|
||||
'updatedAt',
|
||||
'createdAt',
|
||||
'actions',
|
||||
];
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
||||
navigateToClaim(partyId: string, claimID: number) {
|
||||
void this.router.navigate([`/party/${partyId}/claim/${claimID}`]);
|
||||
}
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
<v-dialog title="Create Source">
|
||||
<cc-metadata-form
|
||||
<cc-fistful-thrift-form
|
||||
[formControl]="control"
|
||||
[metadata]="metadata$ | async"
|
||||
namespace="source"
|
||||
type="SourceParams"
|
||||
></cc-metadata-form>
|
||||
></cc-fistful-thrift-form>
|
||||
<v-dialog-actions>
|
||||
<button [disabled]="control.invalid" color="primary" mat-raised-button (click)="create()">
|
||||
Create
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { Component, Injector } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { ThriftAstMetadata } from '@vality/fistful-proto';
|
||||
import { DialogSuperclass } from '@vality/ng-core';
|
||||
import { from } from 'rxjs';
|
||||
|
||||
import { FistfulAdminService } from '../../../api/fistful-admin';
|
||||
import { NotificationService } from '../../../shared/services/notification';
|
||||
@ -14,9 +12,6 @@ import { NotificationErrorService } from '../../../shared/services/notification-
|
||||
})
|
||||
export class CreateSourceComponent extends DialogSuperclass<void> {
|
||||
control = new FormControl();
|
||||
metadata$ = from(
|
||||
import('@vality/fistful-proto/metadata.json').then((m) => m.default as ThriftAstMetadata[])
|
||||
);
|
||||
|
||||
constructor(
|
||||
injector: Injector,
|
||||
|
@ -10,6 +10,7 @@ import { ActionsModule, DialogModule, TableModule } from '@vality/ng-core';
|
||||
|
||||
import { EmptySearchResultModule } from '../../../components/empty-search-result';
|
||||
import { PageLayoutModule } from '../../shared';
|
||||
import { FistfulThriftFormComponent } from '../../shared/components/fistful-thrift-form';
|
||||
import { MetadataFormModule } from '../../shared/components/metadata-form';
|
||||
import { CreateSourceComponent } from './create-source/create-source.component';
|
||||
import { SourcesRoutingModule } from './sources-routing.module';
|
||||
@ -31,6 +32,7 @@ import { SourcesComponent } from './sources.component';
|
||||
MetadataFormModule,
|
||||
ReactiveFormsModule,
|
||||
PageLayoutModule,
|
||||
FistfulThriftFormComponent,
|
||||
],
|
||||
declarations: [SourcesComponent, CreateSourceComponent],
|
||||
})
|
||||
|
@ -1,23 +0,0 @@
|
||||
<form [formGroup]="form" fxLayout="row" fxLayout.xs="column" fxLayoutGap="16px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-select formControlName="statuses" multiple placeholder="Claim statuses">
|
||||
<mat-option *ngFor="let status of claimStatuses" [value]="status">{{
|
||||
status | ccClaimStatus
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
autocomplete="off"
|
||||
formControlName="claim_id"
|
||||
matInput
|
||||
placeholder="Claim ID"
|
||||
type="number"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<cc-merchant-field
|
||||
*ngIf="!hideMerchantSearch"
|
||||
formControlName="party_id"
|
||||
fxFlex
|
||||
></cc-merchant-field>
|
||||
</form>
|
@ -1,57 +0,0 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
} from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { coerceBoolean } from 'coerce-property';
|
||||
import { debounceTime, map, take } from 'rxjs/operators';
|
||||
|
||||
import { CLAIM_STATUSES } from '@cc/app/api/claim-management';
|
||||
import { removeEmptyProperties } from '@cc/utils/remove-empty-properties';
|
||||
|
||||
import { ClaimSearchForm } from './claim-search-form';
|
||||
import { queryParamsToFormValue } from './query-params-to-form-value';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'cc-claim-search-form',
|
||||
templateUrl: 'claim-search-form.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ClaimSearchFormComponent implements OnInit {
|
||||
@Input() @coerceBoolean hideMerchantSearch = false;
|
||||
@Output() valueChanges = new EventEmitter<ClaimSearchForm>();
|
||||
|
||||
form = this.fb.group<ClaimSearchForm>({
|
||||
statuses: null,
|
||||
claim_id: null,
|
||||
party_id: null,
|
||||
});
|
||||
|
||||
claimStatuses = CLAIM_STATUSES;
|
||||
|
||||
constructor(private route: ActivatedRoute, private router: Router, private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.form.valueChanges
|
||||
.pipe(debounceTime(600), map(removeEmptyProperties), untilDestroyed(this))
|
||||
.subscribe((value) => {
|
||||
void this.router.navigate([location.pathname], { queryParams: value });
|
||||
this.valueChanges.emit(value as never);
|
||||
});
|
||||
this.route.queryParams
|
||||
.pipe(
|
||||
take(1),
|
||||
map(queryParamsToFormValue),
|
||||
map(removeEmptyProperties),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe((v) => this.form.patchValue(v));
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
|
||||
import { MerchantFieldModule } from '@cc/app/shared/components/merchant-field';
|
||||
|
||||
import { ApiModelPipesModule } from '../../pipes';
|
||||
import { ClaimSearchFormComponent } from './claim-search-form.component';
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FlexLayoutModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
ReactiveFormsModule,
|
||||
ApiModelPipesModule,
|
||||
MerchantFieldModule,
|
||||
],
|
||||
declarations: [ClaimSearchFormComponent],
|
||||
exports: [ClaimSearchFormComponent],
|
||||
})
|
||||
export class ClaimSearchFormModule {}
|
@ -1,8 +0,0 @@
|
||||
import { ClaimID, ClaimStatus } from '@vality/domain-proto/claim_management';
|
||||
import { PartyID } from '@vality/domain-proto/domain';
|
||||
|
||||
export interface ClaimSearchForm {
|
||||
claim_id: ClaimID;
|
||||
statuses: (keyof ClaimStatus)[];
|
||||
party_id: PartyID;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export * from './claim-search-form.module';
|
||||
export * from './claim-search-form.component';
|
||||
export * from './claim-search-form';
|
@ -1,13 +0,0 @@
|
||||
import { Params } from '@angular/router';
|
||||
import pickBy from 'lodash-es/pickBy';
|
||||
|
||||
import { wrapValuesToArray } from '@cc/utils/wrap-values-to-array';
|
||||
|
||||
const statusesAndPrimitives = (v, k) =>
|
||||
k === 'statuses' && (typeof v === 'string' || typeof v === 'number');
|
||||
|
||||
export const queryParamsToFormValue = (params: Params) => ({
|
||||
...params,
|
||||
// Query param ?statuses=accepted will be present as { statuses: 'accepted' } in form. Selector value must be an array in multiple-selection mode.
|
||||
...wrapValuesToArray(pickBy(params, statusesAndPrimitives)),
|
||||
});
|
@ -0,0 +1,7 @@
|
||||
<cc-metadata-form
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
[metadata]="metadata$ | async"
|
||||
[namespace]="namespace"
|
||||
[type]="type"
|
||||
></cc-metadata-form>
|
@ -0,0 +1,31 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { ThriftAstMetadata } from '@vality/fistful-proto';
|
||||
import { FormControlSuperclass, createControlProviders } from '@vality/ng-core';
|
||||
import { from, of } from 'rxjs';
|
||||
import short from 'short-uuid';
|
||||
|
||||
import { MetadataFormModule, isTypeWithAliases, MetadataFormExtension } from '../metadata-form';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'cc-fistful-thrift-form',
|
||||
templateUrl: './fistful-thrift-form.component.html',
|
||||
providers: createControlProviders(() => FistfulThriftFormComponent),
|
||||
imports: [CommonModule, ReactiveFormsModule, MetadataFormModule],
|
||||
})
|
||||
export class FistfulThriftFormComponent extends FormControlSuperclass<unknown> {
|
||||
@Input() namespace: string;
|
||||
@Input() type: string;
|
||||
|
||||
metadata$ = from(
|
||||
import('@vality/fistful-proto/metadata.json').then((m) => m.default as ThriftAstMetadata[])
|
||||
);
|
||||
extensions: MetadataFormExtension[] = [
|
||||
{
|
||||
determinant: (data) => of(isTypeWithAliases(data, 'SourceID', 'fistful')),
|
||||
extension: () => of({ generate: () => of(short().uuid()), isIdentifier: true }),
|
||||
},
|
||||
];
|
||||
}
|
1
src/app/shared/components/fistful-thrift-form/index.ts
Normal file
1
src/app/shared/components/fistful-thrift-form/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './fistful-thrift-form.component';
|
@ -1,4 +1,3 @@
|
||||
export * from './claim-search-form';
|
||||
export * from './party-modification-creator';
|
||||
export * from './party-modification-forms';
|
||||
export * from './status';
|
||||
|
@ -3,9 +3,11 @@
|
||||
class="mat-headline-4 mat-no-margin"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="start center"
|
||||
fxLayoutGap="8px"
|
||||
fxLayoutGap="4px"
|
||||
>
|
||||
<mat-icon *ngIf="isBackAvailable" class="back" (click)="back()">arrow_back</mat-icon>
|
||||
<button *ngIf="isBackAvailable" mat-icon-button (click)="back()">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
<div>
|
||||
{{ title }}
|
||||
<span class="mat-secondary-text">{{ description }}</span>
|
||||
@ -15,6 +17,22 @@
|
||||
<ng-content select="cc-page-layout-actions"></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="path?.length" class="mat-h3 mat-secondary-text" fxLayout fxLayoutGap="4px">
|
||||
<ng-container *ngFor="let pathPart of path; let idx = index">
|
||||
<div [matTooltip]="pathPart.tooltip">
|
||||
<a
|
||||
*ngIf="pathPart.link; else onlyLabel"
|
||||
[queryParams]="pathPart?.queryParams"
|
||||
[routerLink]="pathPart.link"
|
||||
class="mat-secondary-text"
|
||||
>{{ pathPart.label }}</a
|
||||
>
|
||||
<ng-template #onlyLabel>{{ pathPart.label }}</ng-template>
|
||||
</div>
|
||||
<div *ngIf="idx !== path.length - 1">/</div></ng-container
|
||||
>
|
||||
</div>
|
||||
|
||||
<div *ngIf="progress; else content" fxLayout fxLayoutAlign="center center">
|
||||
<mat-spinner diameter="64"></mat-spinner>
|
||||
</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Location } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { Params } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-page-layout',
|
||||
@ -11,9 +12,16 @@ export class PageLayoutComponent {
|
||||
@Input() title!: string;
|
||||
@Input() description?: string;
|
||||
@Input() progress?: boolean;
|
||||
@Input() path?: {
|
||||
label: string;
|
||||
link?: unknown[] | string | null | undefined;
|
||||
queryParams?: Params | null;
|
||||
tooltip?: string;
|
||||
}[];
|
||||
|
||||
// 1 and 2 is default history length
|
||||
isBackAvailable = window.history.length > 2;
|
||||
isBackAvailable =
|
||||
window.history.length > 2 && window.location.pathname.split('/').slice(1).length > 1;
|
||||
|
||||
constructor(private location: Location) {}
|
||||
|
||||
|
@ -1,14 +1,26 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
import { FlexModule, GridModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterLink } from '@angular/router';
|
||||
|
||||
import { PageLayoutActionsComponent } from './components/page-layout-actions/page-layout-actions.component';
|
||||
import { PageLayoutComponent } from './page-layout.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, FlexModule, MatIconModule, MatProgressSpinnerModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FlexModule,
|
||||
MatIconModule,
|
||||
MatProgressSpinnerModule,
|
||||
GridModule,
|
||||
RouterLink,
|
||||
MatButtonModule,
|
||||
MatTooltipModule,
|
||||
],
|
||||
declarations: [PageLayoutComponent, PageLayoutActionsComponent],
|
||||
exports: [PageLayoutComponent, PageLayoutActionsComponent],
|
||||
})
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { ClaimStatus as UnionClaimStatus } from '@vality/domain-proto/claim_management';
|
||||
|
||||
import { extractClaimStatus } from '../../utils';
|
||||
|
||||
@Pipe({
|
||||
name: 'ccClaimStatusThrift',
|
||||
})
|
||||
export class ClaimStatusThriftPipe implements PipeTransform {
|
||||
transform(value: UnionClaimStatus): string {
|
||||
return extractClaimStatus(value);
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ClaimStatusThriftPipe } from './claim-status-thrift.pipe';
|
||||
import { KeyTitlePipe } from './key-title.pipe';
|
||||
import { MapUnionPipe } from './map-union.pipe';
|
||||
import { ThriftInt64Pipe } from './thrift-int64.pipe';
|
||||
@ -9,7 +8,6 @@ import { UnionKeyPipe } from './union-key.pipe';
|
||||
import { UnionValuePipe } from './union-value.pipe';
|
||||
|
||||
const PIPES = [
|
||||
ClaimStatusThriftPipe,
|
||||
MapUnionPipe,
|
||||
ThriftInt64Pipe,
|
||||
ThriftViewPipe,
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { ClaimStatus as UnionClaimStatus } from '@vality/domain-proto/claim_management';
|
||||
|
||||
import { ClaimStatus } from '@cc/app/api/claim-management';
|
||||
import { getUnionKey } from '@cc/utils/get-union-key';
|
||||
|
||||
export const CLAIM_STATUS_BY_UNION_CLAIM_STATUS: {
|
||||
[name in keyof UnionClaimStatus]-?: ClaimStatus;
|
||||
} = {
|
||||
accepted: ClaimStatus.Accepted,
|
||||
denied: ClaimStatus.Denied,
|
||||
revoked: ClaimStatus.Revoked,
|
||||
pending: ClaimStatus.Pending,
|
||||
review: ClaimStatus.Review,
|
||||
pending_acceptance: ClaimStatus.PendingAcceptance,
|
||||
};
|
||||
|
||||
export const extractClaimStatus = (status: UnionClaimStatus): ClaimStatus =>
|
||||
CLAIM_STATUS_BY_UNION_CLAIM_STATUS[getUnionKey(status)];
|
@ -1,4 +1,3 @@
|
||||
export * from './extract-claim-status';
|
||||
export * from './component-changes';
|
||||
export * from './polling-conditions';
|
||||
export * from './deposit-status';
|
||||
|
@ -1,16 +1,12 @@
|
||||
@use '@angular/material' as mat;
|
||||
@use '@vality/ng-core' as v;
|
||||
@import './all-component-themes';
|
||||
|
||||
@include v.core();
|
||||
|
||||
$app-theme: v.create-light-theme();
|
||||
|
||||
@include v.core();
|
||||
@include v.all-component-themes($app-theme);
|
||||
@include all-component-themes($app-theme);
|
||||
|
||||
@include v.typography-hierarchy($app-theme);
|
||||
|
||||
@include v.app($app-theme);
|
||||
|
||||
.cc-code {
|
||||
|
Loading…
Reference in New Issue
Block a user