Feature/improve platform managment in admin control (#1939)
* Refactoring, fix tab style, add account count * Update changelog
This commit is contained in:
parent
606f6159c4
commit
5249257dd8
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Improved the management of platforms in the admin control panel
|
||||||
- Improved the language localization for German (`de`)
|
- Improved the language localization for German (`de`)
|
||||||
|
|
||||||
## 1.266.0 - 2023-05-06
|
## 1.266.0 - 2023-05-06
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { BenchmarkModule } from '@ghostfolio/api/app/benchmark/benchmark.module';
|
import { BenchmarkModule } from '@ghostfolio/api/app/benchmark/benchmark.module';
|
||||||
|
import { PlatformModule } from '@ghostfolio/api/app/platform/platform.module';
|
||||||
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
|
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
|
||||||
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
|
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
|
||||||
import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering/data-gathering.module';
|
import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering/data-gathering.module';
|
||||||
@ -26,6 +27,7 @@ import { InfoService } from './info.service';
|
|||||||
secret: process.env.JWT_SECRET_KEY,
|
secret: process.env.JWT_SECRET_KEY,
|
||||||
signOptions: { expiresIn: '30 days' }
|
signOptions: { expiresIn: '30 days' }
|
||||||
}),
|
}),
|
||||||
|
PlatformModule,
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
PropertyModule,
|
PropertyModule,
|
||||||
RedisCacheModule,
|
RedisCacheModule,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { BenchmarkService } from '@ghostfolio/api/app/benchmark/benchmark.service';
|
import { BenchmarkService } from '@ghostfolio/api/app/benchmark/benchmark.service';
|
||||||
|
import { PlatformService } from '@ghostfolio/api/app/platform/platform.service';
|
||||||
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
|
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
|
||||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||||
@ -38,6 +39,7 @@ export class InfoService {
|
|||||||
private readonly configurationService: ConfigurationService,
|
private readonly configurationService: ConfigurationService,
|
||||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||||
private readonly jwtService: JwtService,
|
private readonly jwtService: JwtService,
|
||||||
|
private readonly platformService: PlatformService,
|
||||||
private readonly prismaService: PrismaService,
|
private readonly prismaService: PrismaService,
|
||||||
private readonly propertyService: PropertyService,
|
private readonly propertyService: PropertyService,
|
||||||
private readonly redisCacheService: RedisCacheService,
|
private readonly redisCacheService: RedisCacheService,
|
||||||
@ -47,9 +49,12 @@ export class InfoService {
|
|||||||
public async get(): Promise<InfoItem> {
|
public async get(): Promise<InfoItem> {
|
||||||
const info: Partial<InfoItem> = {};
|
const info: Partial<InfoItem> = {};
|
||||||
let isReadOnlyMode: boolean;
|
let isReadOnlyMode: boolean;
|
||||||
const platforms = await this.prismaService.platform.findMany({
|
const platforms = (
|
||||||
orderBy: { name: 'asc' },
|
await this.platformService.getPlatforms({
|
||||||
select: { id: true, name: true }
|
orderBy: { name: 'asc' }
|
||||||
|
})
|
||||||
|
).map(({ id, name }) => {
|
||||||
|
return { id, name };
|
||||||
});
|
});
|
||||||
let systemMessage: string;
|
let systemMessage: string;
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ export class PlatformController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getPlatforms(): Promise<Platform[]> {
|
public async getPlatforms() {
|
||||||
return this.platformService.getPlatforms();
|
return this.platformService.getPlatformsWithAccountCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
@ -6,10 +6,6 @@ import { Platform, Prisma } from '@prisma/client';
|
|||||||
export class PlatformService {
|
export class PlatformService {
|
||||||
public constructor(private readonly prismaService: PrismaService) {}
|
public constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
public async getPlatforms(): Promise<Platform[]> {
|
|
||||||
return this.prismaService.platform.findMany();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getPlatform(
|
public async getPlatform(
|
||||||
platformWhereUniqueInput: Prisma.PlatformWhereUniqueInput
|
platformWhereUniqueInput: Prisma.PlatformWhereUniqueInput
|
||||||
): Promise<Platform> {
|
): Promise<Platform> {
|
||||||
@ -18,6 +14,48 @@ export class PlatformService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getPlatforms({
|
||||||
|
cursor,
|
||||||
|
orderBy,
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
|
where
|
||||||
|
}: {
|
||||||
|
cursor?: Prisma.PlatformWhereUniqueInput;
|
||||||
|
orderBy?: Prisma.PlatformOrderByWithRelationInput;
|
||||||
|
skip?: number;
|
||||||
|
take?: number;
|
||||||
|
where?: Prisma.PlatformWhereInput;
|
||||||
|
} = {}) {
|
||||||
|
return this.prismaService.platform.findMany({
|
||||||
|
cursor,
|
||||||
|
orderBy,
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
|
where
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getPlatformsWithAccountCount() {
|
||||||
|
const platformsWithAccountCount =
|
||||||
|
await this.prismaService.platform.findMany({
|
||||||
|
include: {
|
||||||
|
_count: {
|
||||||
|
select: { Account: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return platformsWithAccountCount.map(({ _count, id, name, url }) => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
accountCount: _count.Account
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async createPlatform(data: Prisma.PlatformCreateInput) {
|
public async createPlatform(data: Prisma.PlatformCreateInput) {
|
||||||
return this.prismaService.platform.create({
|
return this.prismaService.platform.create({
|
||||||
data
|
data
|
||||||
|
@ -43,6 +43,20 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="accounts">
|
||||||
|
<th
|
||||||
|
*matHeaderCellDef
|
||||||
|
class="px-1"
|
||||||
|
mat-header-cell
|
||||||
|
mat-sort-header="accountCount"
|
||||||
|
>
|
||||||
|
<ng-container i18n>Accounts</ng-container>
|
||||||
|
</th>
|
||||||
|
<td *matCellDef="let element" class="px-1" mat-cell>
|
||||||
|
{{ element.accountCount }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<th
|
<th
|
||||||
*matHeaderCellDef
|
*matHeaderCellDef
|
@ -22,16 +22,17 @@ import { Subject, takeUntil } from 'rxjs';
|
|||||||
import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog/create-or-update-account-platform.component';
|
import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog/create-or-update-account-platform.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'gf-platform-overview',
|
host: { class: 'page' },
|
||||||
styleUrls: ['./platform.component.scss'],
|
selector: 'gf-admin-platform',
|
||||||
templateUrl: './platform.component.html'
|
styleUrls: ['./admin-platform.component.scss'],
|
||||||
|
templateUrl: './admin-platform.component.html'
|
||||||
})
|
})
|
||||||
export class AdminPlatformComponent implements OnInit, OnDestroy {
|
export class AdminPlatformComponent implements OnInit, OnDestroy {
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
|
||||||
public dataSource: MatTableDataSource<Platform> = new MatTableDataSource();
|
public dataSource: MatTableDataSource<Platform> = new MatTableDataSource();
|
||||||
public deviceType: string;
|
public deviceType: string;
|
||||||
public displayedColumns = ['name', 'url', 'actions'];
|
public displayedColumns = ['name', 'url', 'accounts', 'actions'];
|
||||||
public hasPermissionToCreatePlatform: boolean;
|
public hasPermissionToCreatePlatform: boolean;
|
||||||
public hasPermissionToDeletePlatform: boolean;
|
public hasPermissionToDeletePlatform: boolean;
|
||||||
public platforms: PlatformModel[];
|
public platforms: PlatformModel[];
|
@ -3,8 +3,8 @@ import { RouterModule, Routes } from '@angular/router';
|
|||||||
import { AdminJobsComponent } from '@ghostfolio/client/components/admin-jobs/admin-jobs.component';
|
import { AdminJobsComponent } from '@ghostfolio/client/components/admin-jobs/admin-jobs.component';
|
||||||
import { AdminMarketDataComponent } from '@ghostfolio/client/components/admin-market-data/admin-market-data.component';
|
import { AdminMarketDataComponent } from '@ghostfolio/client/components/admin-market-data/admin-market-data.component';
|
||||||
import { AdminOverviewComponent } from '@ghostfolio/client/components/admin-overview/admin-overview.component';
|
import { AdminOverviewComponent } from '@ghostfolio/client/components/admin-overview/admin-overview.component';
|
||||||
|
import { AdminPlatformComponent } from '@ghostfolio/client/components/admin-platform/platform.component';
|
||||||
import { AdminUsersComponent } from '@ghostfolio/client/components/admin-users/admin-users.component';
|
import { AdminUsersComponent } from '@ghostfolio/client/components/admin-users/admin-users.component';
|
||||||
import { AdminPlatformComponent } from '@ghostfolio/client/components/platform/platform.component';
|
|
||||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
||||||
|
|
||||||
import { AdminPageComponent } from './admin-page.component';
|
import { AdminPageComponent } from './admin-page.component';
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<a
|
<a
|
||||||
#rla="routerLinkActive"
|
#rla="routerLinkActive"
|
||||||
*ngFor="let tab of tabs"
|
*ngFor="let tab of tabs"
|
||||||
|
class="px-3"
|
||||||
mat-tab-link
|
mat-tab-link
|
||||||
routerLinkActive
|
routerLinkActive
|
||||||
[active]="rla.isActive"
|
[active]="rla.isActive"
|
||||||
|
@ -4,8 +4,8 @@ import { MatTabsModule } from '@angular/material/tabs';
|
|||||||
import { GfAdminJobsModule } from '@ghostfolio/client/components/admin-jobs/admin-jobs.module';
|
import { GfAdminJobsModule } from '@ghostfolio/client/components/admin-jobs/admin-jobs.module';
|
||||||
import { GfAdminMarketDataModule } from '@ghostfolio/client/components/admin-market-data/admin-market-data.module';
|
import { GfAdminMarketDataModule } from '@ghostfolio/client/components/admin-market-data/admin-market-data.module';
|
||||||
import { GfAdminOverviewModule } from '@ghostfolio/client/components/admin-overview/admin-overview.module';
|
import { GfAdminOverviewModule } from '@ghostfolio/client/components/admin-overview/admin-overview.module';
|
||||||
|
import { GfAdminPlatformModule } from '@ghostfolio/client/components/admin-platform/admin-platform.module';
|
||||||
import { GfAdminUsersModule } from '@ghostfolio/client/components/admin-users/admin-users.module';
|
import { GfAdminUsersModule } from '@ghostfolio/client/components/admin-users/admin-users.module';
|
||||||
import { GfAdminPlatformModule } from '@ghostfolio/client/components/platform/platform.module';
|
|
||||||
import { CacheService } from '@ghostfolio/client/services/cache.service';
|
import { CacheService } from '@ghostfolio/client/services/cache.service';
|
||||||
|
|
||||||
import { AdminPageRoutingModule } from './admin-page-routing.module';
|
import { AdminPageRoutingModule } from './admin-page-routing.module';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user