mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 02:25:23 +00:00
MI-9: Enable wallet reports (#137)
This commit is contained in:
parent
e047b1f0c2
commit
4a5ef4595a
8
package-lock.json
generated
8
package-lock.json
generated
@ -25,7 +25,7 @@
|
||||
"@sentry/angular": "^7.56.0",
|
||||
"@sentry/integrations": "^7.56.0",
|
||||
"@sentry/tracing": "^7.56.0",
|
||||
"@vality/ng-core": "^16.2.1-pr-33-42d91a3.0",
|
||||
"@vality/ng-core": "^16.2.1-pr-33-bd23324.0",
|
||||
"@vality/swag-anapi-v2": "2.0.0",
|
||||
"@vality/swag-api-keys-v2": "^0.1.2-be3bbdd.0",
|
||||
"@vality/swag-claim-management": "0.1.1-7a03f9b.0",
|
||||
@ -6866,9 +6866,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/ng-core": {
|
||||
"version": "16.2.1-pr-33-42d91a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-33-42d91a3.0.tgz",
|
||||
"integrity": "sha512-Ags1PPyLkeHEmjRlh3hqgo8jR4dtLpnM9EmjZ3Qa33ayfI8cki+BQANRzaH2VOgjTLcwR54QOTxm012xui2SEQ==",
|
||||
"version": "16.2.1-pr-33-bd23324.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-33-bd23324.0.tgz",
|
||||
"integrity": "sha512-V+aGyvD0oSfmgj8yxPolgweM6Q05XDJsuXdAAIBD1ptrTQNxkjPBTY1op5LzKGI3+Uk0MQ9ctCI5HjJd+BkQRQ==",
|
||||
"dependencies": {
|
||||
"@ng-matero/extensions": "^16.0.0",
|
||||
"@s-libs/js-core": "^16.0.0",
|
||||
|
@ -41,7 +41,7 @@
|
||||
"@sentry/angular": "^7.56.0",
|
||||
"@sentry/integrations": "^7.56.0",
|
||||
"@sentry/tracing": "^7.56.0",
|
||||
"@vality/ng-core": "^16.2.1-pr-33-42d91a3.0",
|
||||
"@vality/ng-core": "^16.2.1-pr-33-bd23324.0",
|
||||
"@vality/swag-anapi-v2": "2.0.0",
|
||||
"@vality/swag-api-keys-v2": "^0.1.2-be3bbdd.0",
|
||||
"@vality/swag-claim-management": "0.1.1-7a03f9b.0",
|
||||
|
@ -76,7 +76,7 @@ export class DialogFiltersComponent implements OnInit {
|
||||
private getInitFormValues(): AdditionalFiltersForm {
|
||||
const {
|
||||
depositID = '',
|
||||
walletID = '',
|
||||
walletID = null,
|
||||
identityID = '',
|
||||
sourceID = '',
|
||||
depositStatus = null,
|
||||
|
@ -0,0 +1,18 @@
|
||||
<div
|
||||
gdColumns="1fr"
|
||||
gdGap="24px"
|
||||
*transloco="let t; scope: 'wallet-section'; read: 'walletSection.reports.reportFiles'"
|
||||
>
|
||||
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="8px">
|
||||
<div class="dsh-title">{{ t('title') }}</div>
|
||||
<button dsh-text-button color="accent" [disabled]="!!(progress$ | async)" (click)="download()">
|
||||
{{ t('downloadAll') }}
|
||||
</button>
|
||||
</div>
|
||||
<div *ngFor="let file of files" gdColumns="auto auto" gdAlignRows="space-between" gdAlignColumns="center center">
|
||||
<div class="dsh-body-1">{{ file.id }}</div>
|
||||
<button dsh-icon-button (click)="download([file.id])" [disabled]="!!(progress$ | async)">
|
||||
<dsh-bi icon="save"></dsh-bi>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,50 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { NotifyLogService, progressTo } from '@vality/ng-core';
|
||||
import { ReportFiles } from '@vality/swag-wallet';
|
||||
import { forkJoin, EMPTY, BehaviorSubject } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
import { DownloadsService } from '@dsh/app/api/wallet';
|
||||
import { multipleDownload } from '@dsh/utils';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'dsh-files',
|
||||
templateUrl: './files.component.html',
|
||||
styles: [],
|
||||
})
|
||||
export class FilesComponent {
|
||||
@Input() id: number;
|
||||
@Input() files: ReportFiles[];
|
||||
|
||||
progress$ = new BehaviorSubject(0);
|
||||
|
||||
constructor(
|
||||
private downloadsService: DownloadsService,
|
||||
private transloco: TranslocoService,
|
||||
private log: NotifyLogService
|
||||
) {}
|
||||
|
||||
download(fileIDs: string[] = this.files.map((f) => f.id)) {
|
||||
forkJoin(
|
||||
fileIDs.map((fileID) =>
|
||||
this.downloadsService.downloadFile({ fileID }).pipe(
|
||||
catchError((err) => {
|
||||
this.log.error(
|
||||
err,
|
||||
this.transloco.translate('reports.errors.downloadReportError', null, 'wallet-section')
|
||||
);
|
||||
return EMPTY;
|
||||
}),
|
||||
progressTo(this.progress$)
|
||||
)
|
||||
)
|
||||
)
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe((files) => {
|
||||
multipleDownload(files.map((f) => f.url));
|
||||
});
|
||||
}
|
||||
}
|
@ -34,19 +34,17 @@
|
||||
>
|
||||
<ng-template let-report>
|
||||
<div fxLayout="column" fxLayoutGap="24px">
|
||||
<div gdColumns="1fr" gdGap="24px">
|
||||
<div gdColumns="1fr" gdColumns.gt-sm="1fr 1fr 1fr" gdGap="24px">
|
||||
<dsh-details-item [title]="t('status')">
|
||||
<dsh-status
|
||||
[color]="reportStatusColor[report.status]"
|
||||
>{{ (reportStatusDict$| async)?.[report.status] }}</dsh-status
|
||||
>
|
||||
</dsh-details-item>
|
||||
<dsh-details-item [title]="t('createdAt')">{{
|
||||
report.createdAt | date : 'dd MMMM yyyy, HH:mm:ss'
|
||||
}}</dsh-details-item>
|
||||
</div>
|
||||
<dsh-details-item [title]="t('period')"
|
||||
<div gdColumns="1fr" gdColumns.gt-sm="1fr 1fr" gdGap="24px">
|
||||
<dsh-details-item [title]="t('status')">
|
||||
<dsh-status
|
||||
[color]="reportStatusColor[report.status]"
|
||||
>{{ (reportStatusDict$| async)?.[report.status] }}</dsh-status
|
||||
>
|
||||
</dsh-details-item>
|
||||
<dsh-details-item [title]="t('createdAt')">{{
|
||||
report.createdAt | date : 'dd MMMM yyyy, HH:mm:ss'
|
||||
}}</dsh-details-item>
|
||||
<dsh-details-item [title]="t('period')" gdColumn="1/-1"
|
||||
>{{ report.fromTime | date : 'dd MMMM yyyy, HH:mm:ss' }} -
|
||||
{{ report.toTime | date : 'dd MMMM yyyy, HH:mm:ss' }}</dsh-details-item
|
||||
>
|
||||
@ -54,7 +52,7 @@
|
||||
|
||||
<ng-container *ngIf="report.status === 'created'">
|
||||
<mat-divider></mat-divider>
|
||||
<dsh-report-files [reportID]="report.id" [files]="report.files"></dsh-report-files>
|
||||
<dsh-files [id]="report.id" [files]="report.files"></dsh-files>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -92,14 +92,13 @@ export class ReportsComponent implements OnInit {
|
||||
.pipe(startWith(this.form.value), distinctUntilChanged(isEqual), untilDestroyed(this))
|
||||
.subscribe((value) => {
|
||||
void this.qp.set(value);
|
||||
if (value.identityID) {
|
||||
this.load();
|
||||
}
|
||||
this.load();
|
||||
});
|
||||
}
|
||||
|
||||
load() {
|
||||
const { dateRange, identityID } = this.form.value;
|
||||
if (!identityID) return;
|
||||
this.fetchReportsService.load({
|
||||
fromTime: dateRange.start.utc().format(),
|
||||
toTime: dateRange.end.utc().format(),
|
||||
|
@ -11,8 +11,6 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { ReportFilesModule } from '@dsh/app/sections/payment-section/reports/report-files';
|
||||
import { ReportPipesModule } from '@dsh/app/sections/payment-section/reports/report-pipes';
|
||||
import { IdentityFilterModule, ApiModelRefsModule } from '@dsh/app/shared';
|
||||
import { AccordionTableModule } from '@dsh/app/shared/components/accordion-table';
|
||||
import { DialogModule } from '@dsh/app/shared/components/dialog';
|
||||
@ -26,11 +24,12 @@ import { BootstrapIconModule, StatusModule } from '@dsh/components/indicators';
|
||||
import { DetailsItemModule } from '@dsh/components/layout';
|
||||
|
||||
import { CreateReportDialogComponent } from './components/create-report-dialog/create-report-dialog.component';
|
||||
import { FilesComponent } from './components/files/files.component';
|
||||
import { ReportsRoutingModule } from './reports-routing.module';
|
||||
import { ReportsComponent } from './reports.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ReportsComponent, CreateReportDialogComponent],
|
||||
declarations: [ReportsComponent, CreateReportDialogComponent, FilesComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ReportsRoutingModule,
|
||||
@ -56,10 +55,8 @@ import { ReportsComponent } from './reports.component';
|
||||
IdentityFieldComponent,
|
||||
BootstrapIconModule,
|
||||
MatDividerModule,
|
||||
ReportFilesModule,
|
||||
ApiModelRefsModule,
|
||||
DetailsItemModule,
|
||||
ReportPipesModule,
|
||||
StatusModule,
|
||||
],
|
||||
})
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { BootstrapIconName } from '@dsh/components/indicators';
|
||||
import { environment } from '@dsh/environments';
|
||||
|
||||
export enum NavbarRouterLink {
|
||||
Wallets = 'wallets',
|
||||
@ -37,15 +36,11 @@ export const toNavbarItemConfig = ({
|
||||
icon: BootstrapIconName.ArrowUpRightCircle,
|
||||
label: withdrawals,
|
||||
},
|
||||
...(environment.production
|
||||
? []
|
||||
: [
|
||||
{
|
||||
routerLink: NavbarRouterLink.Reports,
|
||||
icon: BootstrapIconName.FileText,
|
||||
label: reports,
|
||||
},
|
||||
]),
|
||||
{
|
||||
routerLink: NavbarRouterLink.Reports,
|
||||
icon: BootstrapIconName.FileText,
|
||||
label: reports,
|
||||
},
|
||||
{
|
||||
routerLink: NavbarRouterLink.Integrations,
|
||||
icon: BootstrapIconName.Plug,
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { environment } from '@dsh/environments';
|
||||
|
||||
import { WalletSectionComponent } from './wallet-section.component';
|
||||
|
||||
const WALLET_SECTION_ROUTES: Routes = [
|
||||
@ -26,14 +24,10 @@ const WALLET_SECTION_ROUTES: Routes = [
|
||||
path: 'integrations',
|
||||
loadChildren: () => import('./integrations').then((m) => m.IntegrationsModule),
|
||||
},
|
||||
...(environment.production
|
||||
? []
|
||||
: [
|
||||
{
|
||||
path: 'reports',
|
||||
loadChildren: () => import('./reports').then((m) => m.ReportsModule),
|
||||
},
|
||||
]),
|
||||
{
|
||||
path: 'reports',
|
||||
loadChildren: () => import('./reports').then((m) => m.ReportsModule),
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'wallets',
|
||||
|
@ -2,7 +2,7 @@
|
||||
<dsh-filter
|
||||
[active]="isActive"
|
||||
[label]="t('label')"
|
||||
[activeLabel]="t('label') + ' #' + savedValue"
|
||||
[activeLabel]="t('label', { name: (identity$ | async)?.name || '#' + savedValue })"
|
||||
[content]="content"
|
||||
(save)="save()"
|
||||
(clear)="clear()"
|
||||
|
@ -1,7 +1,10 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { createControlProviders } from '@vality/ng-core';
|
||||
import { Identity } from '@vality/swag-wallet';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { map, share } from 'rxjs/operators';
|
||||
|
||||
import { IdentitiesService } from '@dsh/app/api/wallet';
|
||||
import { FilterSuperclass } from '@dsh/components/filter';
|
||||
|
||||
@Component({
|
||||
@ -10,4 +13,13 @@ import { FilterSuperclass } from '@dsh/components/filter';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: createControlProviders(() => IdentityFilterComponent),
|
||||
})
|
||||
export class IdentityFilterComponent extends FilterSuperclass<Identity['id']> {}
|
||||
export class IdentityFilterComponent extends FilterSuperclass<Identity['id']> {
|
||||
identity$ = combineLatest([this.identitiesService.identities$, this.savedValue$]).pipe(
|
||||
map(([identities, value]) => identities.find((i) => i.id === value)),
|
||||
share()
|
||||
);
|
||||
|
||||
constructor(private identitiesService: IdentitiesService) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@
|
||||
"showAllStatuses": "Show all statuses"
|
||||
},
|
||||
"identityFilter": {
|
||||
"label": "Wallet holder"
|
||||
"label": "Wallet holder: {{name}}"
|
||||
},
|
||||
"inputs": {
|
||||
"identityField": {
|
||||
|
@ -175,7 +175,7 @@
|
||||
"showAllStatuses": "Показать все статусы"
|
||||
},
|
||||
"identityFilter": {
|
||||
"label": "Владелец кошелька"
|
||||
"label": "Владелец кошелька: {{name}}"
|
||||
},
|
||||
"inputs": {
|
||||
"identityField": {
|
||||
|
@ -56,11 +56,16 @@
|
||||
"createdAt": "Created at",
|
||||
"dateRangeDescription": "Reporting period",
|
||||
"errors": {
|
||||
"downloadReportError": "Failed to load documents",
|
||||
"identityNotSpecified": "Wallet holder not specified"
|
||||
},
|
||||
"openCreateReport": "Create report",
|
||||
"period": "Reporting period",
|
||||
"report": "Report",
|
||||
"reportFiles": {
|
||||
"downloadAll": "Download all",
|
||||
"title": "Documents"
|
||||
},
|
||||
"status": "Status"
|
||||
},
|
||||
"walletSection": {
|
||||
|
@ -56,11 +56,16 @@
|
||||
"createdAt": "Дата и время создания",
|
||||
"dateRangeDescription": "Период создания отчетов",
|
||||
"errors": {
|
||||
"downloadReportError": "Не удалось загрузить документы",
|
||||
"identityNotSpecified": "Владелец кошелька не указан"
|
||||
},
|
||||
"openCreateReport": "Создать отчет",
|
||||
"period": "Период отчетности",
|
||||
"report": "Отчет",
|
||||
"reportFiles": {
|
||||
"downloadAll": "Загрузить все",
|
||||
"title": "Документы"
|
||||
},
|
||||
"status": "Статус"
|
||||
},
|
||||
"walletSection": {
|
||||
|
Loading…
Reference in New Issue
Block a user