Browse Source

Integrate total items

pull/2729/head
Thomas Kaul 2 years ago
parent
commit
8d30dd711e
  1. 1
      apps/api/src/app/order/interfaces/activities.interface.ts
  2. 4
      apps/api/src/app/order/order.controller.ts
  3. 17
      apps/api/src/app/order/order.service.ts
  4. 55
      apps/api/src/app/portfolio/portfolio.service.ts
  5. 9
      apps/client/src/app/pages/portfolio/activities/activities-page.component.ts
  6. 1
      apps/client/src/app/pages/portfolio/activities/activities-page.html
  7. 4
      apps/client/src/app/services/data.service.ts
  8. 4
      libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.html
  9. 6
      libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.scss
  10. 2
      libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts

1
apps/api/src/app/order/interfaces/activities.interface.ts

@ -2,6 +2,7 @@ import { OrderWithAccount } from '@ghostfolio/common/types';
export interface Activities { export interface Activities {
activities: Activity[]; activities: Activity[];
count: number;
} }
export interface Activity extends OrderWithAccount { export interface Activity extends OrderWithAccount {

4
apps/api/src/app/order/order.controller.ts

@ -105,7 +105,7 @@ export class OrderController {
await this.impersonationService.validateImpersonationId(impersonationId); await this.impersonationService.validateImpersonationId(impersonationId);
const userCurrency = this.request.user.Settings.settings.baseCurrency; const userCurrency = this.request.user.Settings.settings.baseCurrency;
const activities = await this.orderService.getOrders({ const { activities, count } = await this.orderService.getOrders({
filters, filters,
sortColumn, sortColumn,
sortDirection, sortDirection,
@ -117,7 +117,7 @@ export class OrderController {
withExcludedAccounts: true withExcludedAccounts: true
}); });
return { activities }; return { activities, count };
} }
@Post() @Post()

17
apps/api/src/app/order/order.service.ts

@ -25,7 +25,7 @@ import { endOfToday, isAfter } from 'date-fns';
import { groupBy } from 'lodash'; import { groupBy } from 'lodash';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { Activity } from './interfaces/activities.interface'; import { Activities, Activity } from './interfaces/activities.interface';
@Injectable() @Injectable()
export class OrderService { export class OrderService {
@ -249,7 +249,7 @@ export class OrderService {
userCurrency: string; userCurrency: string;
userId: string; userId: string;
withExcludedAccounts?: boolean; withExcludedAccounts?: boolean;
}): Promise<Activity[]> { }): Promise<Activities> {
let orderBy: Prisma.Enumerable<Prisma.OrderOrderByWithRelationInput> = [ let orderBy: Prisma.Enumerable<Prisma.OrderOrderByWithRelationInput> = [
{ date: 'asc' } { date: 'asc' }
]; ];
@ -328,8 +328,8 @@ export class OrderService {
}); });
} }
return ( const [orders, count] = await Promise.all([
await this.orders({ this.orders({
orderBy, orderBy,
skip, skip,
take, take,
@ -345,8 +345,11 @@ export class OrderService {
SymbolProfile: true, SymbolProfile: true,
tags: true tags: true
} }
}) }),
) this.prismaService.order.count({ where })
]);
const activities = orders
.filter((order) => { .filter((order) => {
return ( return (
withExcludedAccounts || withExcludedAccounts ||
@ -372,6 +375,8 @@ export class OrderService {
) )
}; };
}); });
return { activities, count };
} }
public async updateOrder({ public async updateOrder({

55
apps/api/src/app/portfolio/portfolio.service.ts

@ -225,7 +225,7 @@ export class PortfolioService {
}): Promise<InvestmentItem[]> { }): Promise<InvestmentItem[]> {
const userId = await this.getUserId(impersonationId, this.request.user.id); const userId = await this.getUserId(impersonationId, this.request.user.id);
const activities = await this.orderService.getOrders({ const { activities } = await this.orderService.getOrders({
filters, filters,
userId, userId,
types: ['DIVIDEND'], types: ['DIVIDEND'],
@ -679,13 +679,13 @@ export class PortfolioService {
const user = await this.userService.user({ id: userId }); const user = await this.userService.user({ id: userId });
const userCurrency = this.getUserCurrency(user); const userCurrency = this.getUserCurrency(user);
const orders = ( const { activities } = await this.orderService.getOrders({
await this.orderService.getOrders({ userCurrency,
userCurrency, userId,
userId, withExcludedAccounts: true
withExcludedAccounts: true });
})
).filter(({ SymbolProfile }) => { const orders = activities.filter(({ SymbolProfile }) => {
return ( return (
SymbolProfile.dataSource === aDataSource && SymbolProfile.dataSource === aDataSource &&
SymbolProfile.symbol === aSymbol SymbolProfile.symbol === aSymbol
@ -1639,18 +1639,18 @@ export class PortfolioService {
userId userId
}); });
const activities = await this.orderService.getOrders({ const { activities } = await this.orderService.getOrders({
userCurrency, userCurrency,
userId userId
}); });
const excludedActivities = ( let { activities: excludedActivities } = await this.orderService.getOrders({
await this.orderService.getOrders({ userCurrency,
userCurrency, userId,
userId, withExcludedAccounts: true
withExcludedAccounts: true });
})
).filter(({ Account: account }) => { excludedActivities = excludedActivities.filter(({ Account: account }) => {
return account?.isExcluded ?? false; return account?.isExcluded ?? false;
}); });
@ -1830,7 +1830,7 @@ export class PortfolioService {
const userCurrency = const userCurrency =
this.request.user?.Settings?.settings.baseCurrency ?? DEFAULT_CURRENCY; this.request.user?.Settings?.settings.baseCurrency ?? DEFAULT_CURRENCY;
const orders = await this.orderService.getOrders({ const { activities, count } = await this.orderService.getOrders({
filters, filters,
includeDrafts, includeDrafts,
userCurrency, userCurrency,
@ -1839,11 +1839,11 @@ export class PortfolioService {
types: ['BUY', 'SELL'] types: ['BUY', 'SELL']
}); });
if (orders.length <= 0) { if (count <= 0) {
return { transactionPoints: [], orders: [], portfolioOrders: [] }; return { transactionPoints: [], orders: [], portfolioOrders: [] };
} }
const portfolioOrders: PortfolioOrder[] = orders.map((order) => ({ const portfolioOrders: PortfolioOrder[] = activities.map((order) => ({
currency: order.SymbolProfile.currency, currency: order.SymbolProfile.currency,
dataSource: order.SymbolProfile.dataSource, dataSource: order.SymbolProfile.dataSource,
date: format(order.date, DATE_FORMAT), date: format(order.date, DATE_FORMAT),
@ -1877,8 +1877,8 @@ export class PortfolioService {
portfolioCalculator.computeTransactionPoints(); portfolioCalculator.computeTransactionPoints();
return { return {
orders,
portfolioOrders, portfolioOrders,
orders: activities,
transactionPoints: portfolioCalculator.getTransactionPoints() transactionPoints: portfolioCalculator.getTransactionPoints()
}; };
} }
@ -1913,13 +1913,14 @@ export class PortfolioService {
userId: string; userId: string;
withExcludedAccounts?: boolean; withExcludedAccounts?: boolean;
}) { }) {
const ordersOfTypeItemOrLiability = await this.orderService.getOrders({ const { activities: ordersOfTypeItemOrLiability } =
filters, await this.orderService.getOrders({
userCurrency, filters,
userId, userCurrency,
withExcludedAccounts, userId,
types: ['ITEM', 'LIABILITY'] withExcludedAccounts,
}); types: ['ITEM', 'LIABILITY']
});
const accounts: PortfolioDetails['accounts'] = {}; const accounts: PortfolioDetails['accounts'] = {};
const platforms: PortfolioDetails['platforms'] = {}; const platforms: PortfolioDetails['platforms'] = {};

9
apps/client/src/app/pages/portfolio/activities/activities-page.component.ts

@ -44,6 +44,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
public routeQueryParams: Subscription; public routeQueryParams: Subscription;
public sortColumn = 'date'; public sortColumn = 'date';
public sortDirection: Prisma.SortOrder = 'desc'; public sortDirection: Prisma.SortOrder = 'desc';
public totalItems: number;
public user: User; public user: User;
private unsubscribeSubject = new Subject<void>(); private unsubscribeSubject = new Subject<void>();
@ -120,13 +121,11 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
take: this.pageSize take: this.pageSize
}) })
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ activities }) => { .subscribe(({ activities, count }) => {
this.dataSource = new MatTableDataSource(activities); this.dataSource = new MatTableDataSource(activities);
this.totalItems = count;
if ( if (this.hasPermissionToCreateActivity && count <= 0) {
this.hasPermissionToCreateActivity &&
this.activities?.length <= 0
) {
this.router.navigate([], { queryParams: { createDialog: true } }); this.router.navigate([], { queryParams: { createDialog: true } });
} }

1
apps/client/src/app/pages/portfolio/activities/activities-page.html

@ -13,6 +13,7 @@
[pageIndex]="pageIndex" [pageIndex]="pageIndex"
[pageSize]="pageSize" [pageSize]="pageSize"
[showActions]="!hasImpersonationId && hasPermissionToDeleteActivity && !user.settings.isRestrictedView" [showActions]="!hasImpersonationId && hasPermissionToDeleteActivity && !user.settings.isRestrictedView"
[totalItems]="totalItems"
(activityDeleted)="onDeleteActivity($event)" (activityDeleted)="onDeleteActivity($event)"
(activityToClone)="onCloneActivity($event)" (activityToClone)="onCloneActivity($event)"
(activityToUpdate)="onUpdateActivity($event)" (activityToUpdate)="onUpdateActivity($event)"

4
apps/client/src/app/services/data.service.ts

@ -180,12 +180,12 @@ export class DataService {
} }
return this.http.get<any>('/api/v1/order', { params }).pipe( return this.http.get<any>('/api/v1/order', { params }).pipe(
map(({ activities }) => { map(({ activities, count }) => {
for (const activity of activities) { for (const activity of activities) {
activity.createdAt = parseISO(activity.createdAt); activity.createdAt = parseISO(activity.createdAt);
activity.date = parseISO(activity.date); activity.date = parseISO(activity.date);
} }
return { activities }; return { activities, count };
}) })
); );
} }

4
libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.html

@ -469,9 +469,9 @@
</div> </div>
<mat-paginator <mat-paginator
[length]="length" [length]="totalItems"
[ngClass]="{ [ngClass]="{
'd-none': isLoading && dataSource?.data.length === 0 'd-none': (isLoading && totalItems === 0) || totalItems <= pageSize
}" }"
[pageSize]="pageSize" [pageSize]="pageSize"
(page)="onChangePage($event)" (page)="onChangePage($event)"

6
libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.scss

@ -6,10 +6,4 @@
.activities { .activities {
overflow-x: auto; overflow-x: auto;
} }
::ng-deep {
.mat-mdc-paginator-range-label {
display: none;
}
}
} }

2
libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts

@ -37,7 +37,6 @@ export class ActivitiesTableLazyComponent
@Input() hasPermissionToCreateActivity: boolean; @Input() hasPermissionToCreateActivity: boolean;
@Input() hasPermissionToExportActivities: boolean; @Input() hasPermissionToExportActivities: boolean;
@Input() hasPermissionToOpenDetails = true; @Input() hasPermissionToOpenDetails = true;
@Input() length = Number.MAX_SAFE_INTEGER;
@Input() locale: string; @Input() locale: string;
@Input() pageIndex: number; @Input() pageIndex: number;
@Input() pageSize = DEFAULT_PAGE_SIZE; @Input() pageSize = DEFAULT_PAGE_SIZE;
@ -45,6 +44,7 @@ export class ActivitiesTableLazyComponent
@Input() showCheckbox = false; @Input() showCheckbox = false;
@Input() showFooter = true; @Input() showFooter = true;
@Input() showNameColumn = true; @Input() showNameColumn = true;
@Input() totalItems = Number.MAX_SAFE_INTEGER;
@Output() activityDeleted = new EventEmitter<string>(); @Output() activityDeleted = new EventEmitter<string>();
@Output() activityToClone = new EventEmitter<OrderWithAccount>(); @Output() activityToClone = new EventEmitter<OrderWithAccount>();

Loading…
Cancel
Save