mirror of https://github.com/ghostfolio/ghostfolio
				
				
			
							committed by
							
								 GitHub
								GitHub
							
						
					
				
				 22 changed files with 497 additions and 52 deletions
			
			
		| @ -0,0 +1,3 @@ | |||
| :host { | |||
|   display: block; | |||
| } | |||
| @ -0,0 +1,112 @@ | |||
| import { | |||
|   ChangeDetectionStrategy, | |||
|   ChangeDetectorRef, | |||
|   Component, | |||
|   Inject, | |||
|   OnDestroy, | |||
|   OnInit | |||
| } from '@angular/core'; | |||
| import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; | |||
| import { DataService } from '@ghostfolio/client/services/data.service'; | |||
| import { UserService } from '@ghostfolio/client/services/user/user.service'; | |||
| import { downloadAsFile } from '@ghostfolio/common/helper'; | |||
| import { User } from '@ghostfolio/common/interfaces'; | |||
| import { OrderWithAccount } from '@ghostfolio/common/types'; | |||
| import { AccountType } from '@prisma/client'; | |||
| import { format, parseISO } from 'date-fns'; | |||
| import { Subject } from 'rxjs'; | |||
| import { takeUntil } from 'rxjs/operators'; | |||
| 
 | |||
| import { AccountDetailDialogParams } from './interfaces/interfaces'; | |||
| 
 | |||
| @Component({ | |||
|   host: { class: 'd-flex flex-column h-100' }, | |||
|   selector: 'gf-account-detail-dialog', | |||
|   changeDetection: ChangeDetectionStrategy.OnPush, | |||
|   templateUrl: 'account-detail-dialog.html', | |||
|   styleUrls: ['./account-detail-dialog.component.scss'] | |||
| }) | |||
| export class AccountDetailDialog implements OnDestroy, OnInit { | |||
|   public accountType: AccountType; | |||
|   public name: string; | |||
|   public orders: OrderWithAccount[]; | |||
|   public platformName: string; | |||
|   public user: User; | |||
|   public valueInBaseCurrency: number; | |||
| 
 | |||
|   private unsubscribeSubject = new Subject<void>(); | |||
| 
 | |||
|   public constructor( | |||
|     private changeDetectorRef: ChangeDetectorRef, | |||
|     @Inject(MAT_DIALOG_DATA) public data: AccountDetailDialogParams, | |||
|     private dataService: DataService, | |||
|     public dialogRef: MatDialogRef<AccountDetailDialog>, | |||
|     private userService: UserService | |||
|   ) { | |||
|     this.userService.stateChanged | |||
|       .pipe(takeUntil(this.unsubscribeSubject)) | |||
|       .subscribe((state) => { | |||
|         if (state?.user) { | |||
|           this.user = state.user; | |||
| 
 | |||
|           this.changeDetectorRef.markForCheck(); | |||
|         } | |||
|       }); | |||
|   } | |||
| 
 | |||
|   public ngOnInit(): void { | |||
|     this.dataService | |||
|       .fetchAccount(this.data.accountId) | |||
|       .pipe(takeUntil(this.unsubscribeSubject)) | |||
|       .subscribe(({ accountType, name, Platform, valueInBaseCurrency }) => { | |||
|         this.accountType = accountType; | |||
|         this.name = name; | |||
|         this.platformName = Platform?.name; | |||
|         this.valueInBaseCurrency = valueInBaseCurrency; | |||
| 
 | |||
|         this.changeDetectorRef.markForCheck(); | |||
|       }); | |||
| 
 | |||
|     this.dataService | |||
|       .fetchActivities({ | |||
|         filters: [{ id: this.data.accountId, type: 'ACCOUNT' }] | |||
|       }) | |||
|       .pipe(takeUntil(this.unsubscribeSubject)) | |||
|       .subscribe(({ activities }) => { | |||
|         this.orders = activities; | |||
| 
 | |||
|         this.changeDetectorRef.markForCheck(); | |||
|       }); | |||
|   } | |||
| 
 | |||
|   public onClose(): void { | |||
|     this.dialogRef.close(); | |||
|   } | |||
| 
 | |||
|   public onExport() { | |||
|     this.dataService | |||
|       .fetchExport( | |||
|         this.orders.map((order) => { | |||
|           return order.id; | |||
|         }) | |||
|       ) | |||
|       .pipe(takeUntil(this.unsubscribeSubject)) | |||
|       .subscribe((data) => { | |||
|         downloadAsFile({ | |||
|           content: data, | |||
|           fileName: `ghostfolio-export-${this.name | |||
|             .replace(/\s+/g, '-') | |||
|             .toLowerCase()}-${format( | |||
|             parseISO(data.meta.date), | |||
|             'yyyyMMddHHmm' | |||
|           )}.json`,
 | |||
|           format: 'json' | |||
|         }); | |||
|       }); | |||
|   } | |||
| 
 | |||
|   public ngOnDestroy() { | |||
|     this.unsubscribeSubject.next(); | |||
|     this.unsubscribeSubject.complete(); | |||
|   } | |||
| } | |||
| @ -0,0 +1,65 @@ | |||
| <gf-dialog-header | |||
|   mat-dialog-title | |||
|   position="center" | |||
|   [deviceType]="data.deviceType" | |||
|   [title]="name" | |||
|   (closeButtonClicked)="onClose()" | |||
| ></gf-dialog-header> | |||
| 
 | |||
| <div class="flex-grow-1" mat-dialog-content> | |||
|   <div class="container p-0"> | |||
|     <div class="row"> | |||
|       <div class="col-12 d-flex justify-content-center mb-3"> | |||
|         <gf-value | |||
|           size="large" | |||
|           [currency]="user?.settings?.baseCurrency" | |||
|           [locale]="user?.settings?.locale" | |||
|           [value]="valueInBaseCurrency" | |||
|         ></gf-value> | |||
|       </div> | |||
|     </div> | |||
| 
 | |||
|     <div class="row"> | |||
|       <div class="col-6 mb-3"> | |||
|         <gf-value | |||
|           label="Account Type" | |||
|           size="medium" | |||
|           [value]="accountType" | |||
|         ></gf-value> | |||
|       </div> | |||
|       <div class="col-6 mb-3"> | |||
|         <gf-value | |||
|           label="Platform" | |||
|           size="medium" | |||
|           [value]="platformName" | |||
|         ></gf-value> | |||
|       </div> | |||
|     </div> | |||
| 
 | |||
|     <div *ngIf="orders?.length > 0" class="row"> | |||
|       <div class="col mb-3"> | |||
|         <div class="h5 mb-0" i18n>Activities</div> | |||
|         <gf-activities-table | |||
|           [activities]="orders" | |||
|           [baseCurrency]="user?.settings?.baseCurrency" | |||
|           [deviceType]="data.deviceType" | |||
|           [hasPermissionToCreateActivity]="false" | |||
|           [hasPermissionToExportActivities]="!hasImpersonationId" | |||
|           [hasPermissionToFilter]="false" | |||
|           [hasPermissionToImportActivities]="false" | |||
|           [hasPermissionToOpenDetails]="false" | |||
|           [locale]="user?.settings?.locale" | |||
|           [showActions]="false" | |||
|           [showSymbolColumn]="false" | |||
|           (export)="onExport()" | |||
|         ></gf-activities-table> | |||
|       </div> | |||
|     </div> | |||
|   </div> | |||
| </div> | |||
| 
 | |||
| <gf-dialog-footer | |||
|   mat-dialog-actions | |||
|   [deviceType]="data.deviceType" | |||
|   (closeButtonClicked)="onClose()" | |||
| ></gf-dialog-footer> | |||
| @ -0,0 +1,29 @@ | |||
| import { CommonModule } from '@angular/common'; | |||
| import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; | |||
| import { MatButtonModule } from '@angular/material/button'; | |||
| import { MatDialogModule } from '@angular/material/dialog'; | |||
| import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; | |||
| import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; | |||
| import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; | |||
| import { GfValueModule } from '@ghostfolio/ui/value'; | |||
| import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; | |||
| 
 | |||
| import { AccountDetailDialog } from './account-detail-dialog.component'; | |||
| 
 | |||
| @NgModule({ | |||
|   declarations: [AccountDetailDialog], | |||
|   exports: [], | |||
|   imports: [ | |||
|     CommonModule, | |||
|     GfActivitiesTableModule, | |||
|     GfDialogFooterModule, | |||
|     GfDialogHeaderModule, | |||
|     GfValueModule, | |||
|     MatButtonModule, | |||
|     MatDialogModule, | |||
|     NgxSkeletonLoaderModule | |||
|   ], | |||
|   providers: [], | |||
|   schemas: [CUSTOM_ELEMENTS_SCHEMA] | |||
| }) | |||
| export class GfAccountDetailDialogModule {} | |||
| @ -0,0 +1,5 @@ | |||
| export interface AccountDetailDialogParams { | |||
|   accountId: string; | |||
|   deviceType: string; | |||
|   hasImpersonationId: boolean; | |||
| } | |||
					Loading…
					
					
				
		Reference in new issue