Improve the user table (#16)
This commit is contained in:
parent
3558f52b84
commit
358f0d7eaf
@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Changed the about page for the new license
|
- Changed the about page for the new license
|
||||||
- Optimized the data management for historical data
|
- Optimized the data management for historical data
|
||||||
- Optimized the exchange rate service
|
- Optimized the exchange rate service
|
||||||
|
- Improved the user table in the admin control panel
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ export class AdminService {
|
|||||||
|
|
||||||
public async get(): Promise<AdminData> {
|
public async get(): Promise<AdminData> {
|
||||||
return {
|
return {
|
||||||
analytics: await this.getUserAnalytics(),
|
|
||||||
exchangeRates: [
|
exchangeRates: [
|
||||||
{
|
{
|
||||||
label1: Currency.EUR,
|
label1: Currency.EUR,
|
||||||
@ -64,7 +63,8 @@ export class AdminService {
|
|||||||
],
|
],
|
||||||
lastDataGathering: await this.getLastDataGathering(),
|
lastDataGathering: await this.getLastDataGathering(),
|
||||||
transactionCount: await this.prisma.order.count(),
|
transactionCount: await this.prisma.order.count(),
|
||||||
userCount: await this.prisma.user.count()
|
userCount: await this.prisma.user.count(),
|
||||||
|
users: await this.getUsersWithAnalytics()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,20 +88,27 @@ export class AdminService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getUserAnalytics() {
|
private async getUsersWithAnalytics() {
|
||||||
return await this.prisma.analytics.findMany({
|
return await this.prisma.user.findMany({
|
||||||
orderBy: { updatedAt: 'desc' },
|
orderBy: {
|
||||||
select: {
|
Analytics: {
|
||||||
activityCount: true,
|
updatedAt: 'desc'
|
||||||
updatedAt: true,
|
|
||||||
User: {
|
|
||||||
select: {
|
|
||||||
alias: true,
|
|
||||||
createdAt: true,
|
|
||||||
id: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
_count: {
|
||||||
|
select: { Order: true }
|
||||||
|
},
|
||||||
|
alias: true,
|
||||||
|
Analytics: {
|
||||||
|
select: {
|
||||||
|
activityCount: true,
|
||||||
|
updatedAt: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createdAt: true,
|
||||||
|
id: true
|
||||||
|
},
|
||||||
take: 20
|
take: 20
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
export interface AdminData {
|
export interface AdminData {
|
||||||
analytics: {
|
exchangeRates: { label1: string; label2: string; value: number }[];
|
||||||
|
lastDataGathering: Date | 'IN_PROGRESS';
|
||||||
|
transactionCount: number;
|
||||||
|
userCount: number;
|
||||||
|
users: {
|
||||||
activityCount: number;
|
activityCount: number;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
User: {
|
User: {
|
||||||
@ -7,8 +11,4 @@ export interface AdminData {
|
|||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
}[];
|
}[];
|
||||||
exchangeRates: { label1: string; label2: string; value: number }[];
|
|
||||||
lastDataGathering: Date | 'IN_PROGRESS';
|
|
||||||
transactionCount: number;
|
|
||||||
userCount: number;
|
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,13 @@ import { DataService } from '../../services/data.service';
|
|||||||
styleUrls: ['./admin-page.scss']
|
styleUrls: ['./admin-page.scss']
|
||||||
})
|
})
|
||||||
export class AdminPageComponent implements OnInit {
|
export class AdminPageComponent implements OnInit {
|
||||||
public analytics: AdminData['analytics'];
|
|
||||||
public dataGatheringInProgress: boolean;
|
public dataGatheringInProgress: boolean;
|
||||||
public defaultDateFormat = DEFAULT_DATE_FORMAT;
|
public defaultDateFormat = DEFAULT_DATE_FORMAT;
|
||||||
public exchangeRates: { label1: string; label2: string; value: number }[];
|
public exchangeRates: { label1: string; label2: string; value: number }[];
|
||||||
public lastDataGathering: string;
|
public lastDataGathering: string;
|
||||||
public transactionCount: number;
|
public transactionCount: number;
|
||||||
public userCount: number;
|
public userCount: number;
|
||||||
|
public users: AdminData['users'];
|
||||||
|
|
||||||
private unsubscribeSubject = new Subject<void>();
|
private unsubscribeSubject = new Subject<void>();
|
||||||
|
|
||||||
@ -44,14 +44,14 @@ export class AdminPageComponent implements OnInit {
|
|||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
({
|
({
|
||||||
analytics,
|
|
||||||
exchangeRates,
|
exchangeRates,
|
||||||
lastDataGathering,
|
lastDataGathering,
|
||||||
transactionCount,
|
transactionCount,
|
||||||
userCount
|
userCount,
|
||||||
|
users
|
||||||
}) => {
|
}) => {
|
||||||
this.analytics = analytics;
|
|
||||||
this.exchangeRates = exchangeRates;
|
this.exchangeRates = exchangeRates;
|
||||||
|
this.users = users;
|
||||||
|
|
||||||
if (isValid(parseISO(lastDataGathering?.toString()))) {
|
if (isValid(parseISO(lastDataGathering?.toString()))) {
|
||||||
this.lastDataGathering = formatDistanceToNow(
|
this.lastDataGathering = formatDistanceToNow(
|
||||||
|
@ -67,33 +67,45 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h3 class="mb-3 text-center" i18n>Analytics</h3>
|
<h3 class="mb-3 text-center" i18n>Users</h3>
|
||||||
<mat-card>
|
<mat-card class="px-0">
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<table class="analytics w-100">
|
<table class="users w-100">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="mat-header-row">
|
<tr class="mat-header-row">
|
||||||
<th class="mat-header-cell pl-2 py-2" i18n>User</th>
|
<th class="mat-header-cell pl-2 py-2 text-truncate" i18n>
|
||||||
<th class="mat-header-cell pr-2 py-2" i18n>
|
User
|
||||||
|
</th>
|
||||||
|
<th class="mat-header-cell pr-2 py-2 text-truncate" i18n>
|
||||||
Registration Date
|
Registration Date
|
||||||
</th>
|
</th>
|
||||||
<th class="mat-header-cell pr-2 py-2" i18n>Engagement</th>
|
<th class="mat-header-cell pr-2 py-2 text-truncate" i18n>
|
||||||
<th class="mat-header-cell pr-2 py-2" i18n>Last Activitiy</th>
|
Transactions
|
||||||
|
</th>
|
||||||
|
<th class="mat-header-cell pr-2 py-2 text-truncate" i18n>
|
||||||
|
Engagement
|
||||||
|
</th>
|
||||||
|
<th class="mat-header-cell pr-2 py-2 text-truncate" i18n>
|
||||||
|
Last Activitiy
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let analyticsItem of analytics" class="mat-row">
|
<tr *ngFor="let userItem of users" class="mat-row">
|
||||||
<td class="mat-cell text-truncate pl-2 py-2">
|
<td class="mat-cell pl-2 py-2 text-truncate">
|
||||||
{{ analyticsItem.User.alias || analyticsItem.User.id }}
|
{{ userItem.alias || userItem.id }}
|
||||||
</td>
|
</td>
|
||||||
<td class="mat-cell pr-2 py-2">
|
<td class="mat-cell pr-2 py-2 text-truncate">
|
||||||
{{ analyticsItem.User.createdAt | date: defaultDateFormat }}
|
{{ userItem.createdAt | date: defaultDateFormat }}
|
||||||
</td>
|
</td>
|
||||||
<td class="mat-cell pr-2 py-2">
|
<td class="mat-cell pr-2 py-2 text-truncate">
|
||||||
{{ analyticsItem.activityCount }}
|
{{ userItem._count.Order }}
|
||||||
</td>
|
</td>
|
||||||
<td class="mat-cell pr-2 py-2">
|
<td class="mat-cell pr-2 py-2 text-truncate">
|
||||||
{{ formatDistanceToNow(analyticsItem.updatedAt) }}
|
{{ userItem.Analytics.activityCount }}
|
||||||
|
</td>
|
||||||
|
<td class="mat-cell pr-2 py-2 text-truncate">
|
||||||
|
{{ formatDistanceToNow(userItem.Analytics.updatedAt) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
table {
|
table {
|
||||||
&.analytics {
|
&.users {
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user