Browse Source

Add checkbox for selecting activities

pull/1531/head
yksolanki9 3 years ago
parent
commit
456f87cf17
  1. 29
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts
  2. 17
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html
  3. 2
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts
  4. 4
      apps/client/src/app/services/import-activities.service.ts
  5. 24
      libs/ui/src/lib/activities-table/activities-table.component.html
  6. 61
      libs/ui/src/lib/activities-table/activities-table.component.ts
  7. 2
      libs/ui/src/lib/activities-table/activities-table.module.ts

29
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts

@ -7,9 +7,14 @@ import {
} from '@angular/core'; } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import {
Activities,
Activity
} from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service'; import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service';
import { isArray } from 'lodash'; import { isArray } from 'lodash';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { ImportActivitiesDialogParams } from './interfaces/interfaces'; import { ImportActivitiesDialogParams } from './interfaces/interfaces';
@ -20,8 +25,10 @@ import { ImportActivitiesDialogParams } from './interfaces/interfaces';
templateUrl: 'import-activities-dialog.html' templateUrl: 'import-activities-dialog.html'
}) })
export class ImportActivitiesDialog implements OnDestroy { export class ImportActivitiesDialog implements OnDestroy {
public activities: Activity[] | CreateOrderDto[] = [];
public details: any[] = []; public details: any[] = [];
public errorMessages: string[] = []; public errorMessages: string[] = [];
public importComplete = false;
private unsubscribeSubject = new Subject<void>(); private unsubscribeSubject = new Subject<void>();
@ -93,7 +100,7 @@ export class ImportActivitiesDialog implements OnDestroy {
return; return;
} else if (file.name.endsWith('.csv')) { } else if (file.name.endsWith('.csv')) {
try { try {
await this.importActivitiesService.importCsv({ this.activities = await this.importActivitiesService.importCsv({
fileContent, fileContent,
userAccounts: this.data.user.accounts userAccounts: this.data.user.accounts
}); });
@ -163,14 +170,18 @@ export class ImportActivitiesDialog implements OnDestroy {
} }
private handleImportSuccess() { private handleImportSuccess() {
this.snackBar.open( this.importComplete = true;
'✅ ' + $localize`Import has been completed`,
undefined,
{
duration: 3000
}
);
this.dialogRef.close(); //Needed to trigger onPush change detection strategy
this.changeDetectorRef.markForCheck();
// this.snackBar.open(
// '✅ ' + $localize`Import has been completed`,
// undefined,
// {
// duration: 3000
// }
// );
// this.dialogRef.close();
} }
} }

17
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html

@ -6,7 +6,22 @@
></gf-dialog-header> ></gf-dialog-header>
<div class="flex-grow-1" mat-dialog-content> <div class="flex-grow-1" mat-dialog-content>
<ng-container *ngIf="errorMessages.length === 0"> <ng-container *ngIf="importComplete">
<gf-activities-table
[activities]="activities"
[baseCurrency]="data?.user?.settings?.baseCurrency"
[deviceType]="data.deviceType"
[hasPermissionToCreateActivity]="false"
[hasPermissionToExportActivities]="true"
[hasPermissionToFilter]="false"
[hasPermissionToImportActivities]="false"
[hasPermissionToOpenDetails]="false"
[locale]="data?.user?.settings?.locale"
[showActions]="false"
[showSymbolColumn]="false"
></gf-activities-table>
</ng-container>
<ng-container *ngIf="errorMessages.length === 0 && !importComplete">
<div class="d-flex justify-content-center flex-column"> <div class="d-flex justify-content-center flex-column">
<button <button
class="py-3" class="py-3"

2
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts

@ -3,6 +3,7 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module';
import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module';
import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module';
@ -12,6 +13,7 @@ import { ImportActivitiesDialog } from './import-activities-dialog.component';
declarations: [ImportActivitiesDialog], declarations: [ImportActivitiesDialog],
imports: [ imports: [
CommonModule, CommonModule,
GfActivitiesTableModule,
GfDialogFooterModule, GfDialogFooterModule,
GfDialogHeaderModule, GfDialogHeaderModule,
MatButtonModule, MatButtonModule,

4
apps/client/src/app/services/import-activities.service.ts

@ -52,7 +52,9 @@ export class ImportActivitiesService {
}); });
} }
await this.importJson({ content: activities }); return activities;
// await this.importJson({ content: activities });
} }
public importJson({ content }: { content: CreateOrderDto[] }): Promise<void> { public importJson({ content }: { content: CreateOrderDto[] }): Promise<void> {

24
libs/ui/src/lib/activities-table/activities-table.component.html

@ -15,6 +15,24 @@
matSortDirection="desc" matSortDirection="desc"
[dataSource]="dataSource" [dataSource]="dataSource"
> >
<ng-container matColumnDef="select">
<th *matHeaderCellDef class="px-1" mat-header-cell>
<mat-checkbox
[checked]="selectedRows.hasValue() && areAllRowsSelected()"
[indeterminate]="selectedRows.hasValue() && !areAllRowsSelected()"
(change)="$event ? toggleAll() : null"
></mat-checkbox>
</th>
<td *matCellDef="let element" class="px-1" mat-cell>
<mat-checkbox
[checked]="selectedRows.isSelected(element)"
(change)="$event ? selectedRows.toggle(element) : null"
(click)="$event.stopPropagation()"
></mat-checkbox>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell></td>
</ng-container>
<ng-container matColumnDef="count"> <ng-container matColumnDef="count">
<th <th
*matHeaderCellDef *matHeaderCellDef
@ -122,7 +140,7 @@
class="d-none d-lg-table-cell px-1" class="d-none d-lg-table-cell px-1"
mat-cell mat-cell
> >
{{ element.SymbolProfile.currency }} {{ baseCurrency }}
</td> </td>
<td *matFooterCellDef class="d-none d-lg-table-cell px-1" mat-footer-cell> <td *matFooterCellDef class="d-none d-lg-table-cell px-1" mat-footer-cell>
{{ baseCurrency }} {{ baseCurrency }}
@ -238,7 +256,9 @@
<gf-value <gf-value
[isCurrency]="true" [isCurrency]="true"
[locale]="locale" [locale]="locale"
[value]="isLoading ? undefined : element.value" [value]="
isLoading ? undefined : element.unitPrice * element.quantity
"
></gf-value> ></gf-value>
</div> </div>
</td> </td>

61
libs/ui/src/lib/activities-table/activities-table.component.ts

@ -8,6 +8,7 @@ import {
Output, Output,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { SelectionModel } from '@angular/cdk/collections';
import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
@ -57,6 +58,7 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
public allFilters: Filter[]; public allFilters: Filter[];
public dataSource: MatTableDataSource<Activity> = new MatTableDataSource(); public dataSource: MatTableDataSource<Activity> = new MatTableDataSource();
public selectedRows = new SelectionModel<Activity>(true, []);
public defaultDateFormat: string; public defaultDateFormat: string;
public displayedColumns = []; public displayedColumns = [];
public endOfToday = endOfToday(); public endOfToday = endOfToday();
@ -83,8 +85,24 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
}); });
} }
public areAllRowsSelected() {
const numSelectedRows = this.selectedRows.selected.length;
const numTotalRows = this.dataSource.data.length;
return numSelectedRows === numTotalRows;
}
public toggleAll() {
this.areAllRowsSelected()
? this.selectedRows.clear()
: this.dataSource.data.forEach((row) => this.selectedRows.select(row));
this.selectedActivities.emit(this.selectedRows.selected);
}
public ngOnChanges() { public ngOnChanges() {
console.log('INSIDE LIIB', this.activities);
this.displayedColumns = [ this.displayedColumns = [
'select',
'count', 'count',
'date', 'date',
'type', 'type',
@ -219,13 +237,18 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
}; };
} }
fieldValueMap[activity.SymbolProfile.currency] = { if (activity.SymbolProfile?.currency) {
id: activity.SymbolProfile.currency, fieldValueMap[activity.SymbolProfile.currency] = {
label: activity.SymbolProfile.currency, id: activity.SymbolProfile.currency,
type: 'TAG' label: activity.SymbolProfile.currency,
}; type: 'TAG'
};
}
if (!isUUID(activity.SymbolProfile.symbol)) { if (
activity.SymbolProfile?.symbol &&
!isUUID(activity.SymbolProfile.symbol)
) {
fieldValueMap[activity.SymbolProfile.symbol] = { fieldValueMap[activity.SymbolProfile.symbol] = {
id: activity.SymbolProfile.symbol, id: activity.SymbolProfile.symbol,
label: activity.SymbolProfile.symbol, label: activity.SymbolProfile.symbol,
@ -233,17 +256,21 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
}; };
} }
fieldValueMap[activity.type] = { if (activity?.type) {
id: activity.type, fieldValueMap[activity.type] = {
label: activity.type, id: activity.type,
type: 'TAG' label: activity.type,
}; type: 'TAG'
};
fieldValueMap[format(activity.date, 'yyyy')] = { }
id: format(activity.date, 'yyyy'),
label: format(activity.date, 'yyyy'), // if (typeof activity?.date) {
type: 'TAG' // fieldValueMap[format(activity.date, 'yyyy')] = {
}; // id: format(activity.date, 'yyyy'),
// label: format(activity.date, 'yyyy'),
// type: 'TAG'
// };
// }
return Object.values(fieldValueMap); return Object.values(fieldValueMap);
} }

2
libs/ui/src/lib/activities-table/activities-table.module.ts

@ -1,6 +1,7 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { MatPaginatorModule } from '@angular/material/paginator'; import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort'; import { MatSortModule } from '@angular/material/sort';
@ -26,6 +27,7 @@ import { ActivitiesTableComponent } from './activities-table.component';
GfSymbolModule, GfSymbolModule,
GfValueModule, GfValueModule,
MatButtonModule, MatButtonModule,
MatCheckboxModule,
MatMenuModule, MatMenuModule,
MatPaginatorModule, MatPaginatorModule,
MatSortModule, MatSortModule,

Loading…
Cancel
Save