mirror of https://github.com/ghostfolio/ghostfolio
FabioAzevedo0619
2 years ago
committed by
GitHub
24 changed files with 678 additions and 16 deletions
@ -0,0 +1,9 @@ |
|||||
|
import { IsString } from 'class-validator'; |
||||
|
|
||||
|
export class CreatePlatformDto { |
||||
|
@IsString() |
||||
|
name: string; |
||||
|
|
||||
|
@IsString() |
||||
|
url: string; |
||||
|
} |
@ -0,0 +1,113 @@ |
|||||
|
import { |
||||
|
Body, |
||||
|
Controller, |
||||
|
Delete, |
||||
|
Get, |
||||
|
HttpException, |
||||
|
Inject, |
||||
|
Param, |
||||
|
Post, |
||||
|
Put, |
||||
|
UseGuards |
||||
|
} from '@nestjs/common'; |
||||
|
import { PlatformService } from './platform.service'; |
||||
|
import { AuthGuard } from '@nestjs/passport'; |
||||
|
import { Platform } from '@prisma/client'; |
||||
|
import { CreatePlatformDto } from './create-platform.dto'; |
||||
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
||||
|
import { RequestWithUser } from '@ghostfolio/common/types'; |
||||
|
import { REQUEST } from '@nestjs/core'; |
||||
|
import { getReasonPhrase, StatusCodes } from 'http-status-codes'; |
||||
|
import { UpdatePlatformDto } from './update-platform.dto'; |
||||
|
|
||||
|
@Controller('platform') |
||||
|
export class PlatformController { |
||||
|
public constructor( |
||||
|
private readonly platformService: PlatformService, |
||||
|
@Inject(REQUEST) private readonly request: RequestWithUser |
||||
|
) {} |
||||
|
|
||||
|
@Get() |
||||
|
@UseGuards(AuthGuard('jwt')) |
||||
|
public async getPlatforms(): Promise<Platform[]> { |
||||
|
return this.platformService.getPlatforms(); |
||||
|
} |
||||
|
|
||||
|
@Post() |
||||
|
@UseGuards(AuthGuard('jwt')) |
||||
|
public async createPlatform( |
||||
|
@Body() data: CreatePlatformDto |
||||
|
): Promise<Platform> { |
||||
|
if ( |
||||
|
!hasPermission(this.request.user.permissions, permissions.createPlatform) |
||||
|
) { |
||||
|
throw new HttpException( |
||||
|
getReasonPhrase(StatusCodes.FORBIDDEN), |
||||
|
StatusCodes.FORBIDDEN |
||||
|
); |
||||
|
} |
||||
|
return this.platformService.createPlatform(data); |
||||
|
} |
||||
|
|
||||
|
@Put(':id') |
||||
|
@UseGuards(AuthGuard('jwt')) |
||||
|
public async updatePlatform( |
||||
|
@Param('id') id: string, |
||||
|
@Body() data: UpdatePlatformDto |
||||
|
) { |
||||
|
if ( |
||||
|
!hasPermission(this.request.user.permissions, permissions.updatePlatform) |
||||
|
) { |
||||
|
throw new HttpException( |
||||
|
getReasonPhrase(StatusCodes.FORBIDDEN), |
||||
|
StatusCodes.FORBIDDEN |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
const originalPlatform = await this.platformService.getPlatform({ |
||||
|
id |
||||
|
}); |
||||
|
|
||||
|
if (!originalPlatform) { |
||||
|
throw new HttpException( |
||||
|
getReasonPhrase(StatusCodes.FORBIDDEN), |
||||
|
StatusCodes.FORBIDDEN |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return this.platformService.updatePlatform({ |
||||
|
data: { |
||||
|
...data |
||||
|
}, |
||||
|
where: { |
||||
|
id |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
@Delete(':id') |
||||
|
@UseGuards(AuthGuard('jwt')) |
||||
|
public async deletePlatform(@Param('id') id: string) { |
||||
|
if ( |
||||
|
!hasPermission(this.request.user.permissions, permissions.deletePlatform) |
||||
|
) { |
||||
|
throw new HttpException( |
||||
|
getReasonPhrase(StatusCodes.FORBIDDEN), |
||||
|
StatusCodes.FORBIDDEN |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
const originalPlatform = await this.platformService.getPlatform({ |
||||
|
id |
||||
|
}); |
||||
|
|
||||
|
if (!originalPlatform) { |
||||
|
throw new HttpException( |
||||
|
getReasonPhrase(StatusCodes.FORBIDDEN), |
||||
|
StatusCodes.FORBIDDEN |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return this.platformService.deletePlatform({ id }); |
||||
|
} |
||||
|
} |
@ -1,9 +1,11 @@ |
|||||
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; |
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; |
||||
import { Module } from '@nestjs/common'; |
import { Module } from '@nestjs/common'; |
||||
|
|
||||
|
import { PlatformController } from './platform.controller'; |
||||
import { PlatformService } from './platform.service'; |
import { PlatformService } from './platform.service'; |
||||
|
|
||||
@Module({ |
@Module({ |
||||
|
controllers: [PlatformController], |
||||
exports: [PlatformService], |
exports: [PlatformService], |
||||
imports: [PrismaModule], |
imports: [PrismaModule], |
||||
providers: [PlatformService] |
providers: [PlatformService] |
@ -0,0 +1,45 @@ |
|||||
|
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; |
||||
|
import { Injectable } from '@nestjs/common'; |
||||
|
import { Platform, Prisma } from '@prisma/client'; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class PlatformService { |
||||
|
public constructor(private readonly prismaService: PrismaService) {} |
||||
|
|
||||
|
public async getPlatforms(): Promise<Platform[]> { |
||||
|
return this.prismaService.platform.findMany(); |
||||
|
} |
||||
|
|
||||
|
public async getPlatform( |
||||
|
platformWhereUniqueInput: Prisma.PlatformWhereUniqueInput |
||||
|
): Promise<Platform> { |
||||
|
return this.prismaService.platform.findUnique({ |
||||
|
where: platformWhereUniqueInput |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public async createPlatform(data: Prisma.PlatformCreateInput) { |
||||
|
return this.prismaService.platform.create({ |
||||
|
data |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public async updatePlatform({ |
||||
|
data, |
||||
|
where |
||||
|
}: { |
||||
|
data: Prisma.PlatformUpdateInput; |
||||
|
where: Prisma.PlatformWhereUniqueInput; |
||||
|
}): Promise<Platform> { |
||||
|
return this.prismaService.platform.update({ |
||||
|
data, |
||||
|
where |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public async deletePlatform( |
||||
|
where: Prisma.PlatformWhereUniqueInput |
||||
|
): Promise<Platform> { |
||||
|
return this.prismaService.platform.delete({ where }); |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
import { IsString } from 'class-validator'; |
||||
|
|
||||
|
export class UpdatePlatformDto { |
||||
|
@IsString() |
||||
|
id: string; |
||||
|
|
||||
|
@IsString() |
||||
|
name: string; |
||||
|
|
||||
|
@IsString() |
||||
|
url: string; |
||||
|
} |
@ -1,11 +0,0 @@ |
|||||
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; |
|
||||
import { Injectable } from '@nestjs/common'; |
|
||||
|
|
||||
@Injectable() |
|
||||
export class PlatformService { |
|
||||
public constructor(private readonly prismaService: PrismaService) {} |
|
||||
|
|
||||
public async get() { |
|
||||
return this.prismaService.platform.findMany(); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,30 @@ |
|||||
|
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; |
||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; |
||||
|
import { Subject } from 'rxjs'; |
||||
|
|
||||
|
import { CreateOrUpdatePlatformDialogParams } from './interfaces/interfaces'; |
||||
|
|
||||
|
@Component({ |
||||
|
host: { class: 'h-100' }, |
||||
|
selector: 'gf-create-or-update-platform-dialog', |
||||
|
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
|
styleUrls: ['./create-or-update-platform-dialog.scss'], |
||||
|
templateUrl: 'create-or-update-platform-dialog.html' |
||||
|
}) |
||||
|
export class CreateOrUpdatePlatformDialog { |
||||
|
private unsubscribeSubject = new Subject<void>(); |
||||
|
|
||||
|
public constructor( |
||||
|
public dialogRef: MatDialogRef<CreateOrUpdatePlatformDialog>, |
||||
|
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdatePlatformDialogParams |
||||
|
) {} |
||||
|
|
||||
|
public onCancel() { |
||||
|
this.dialogRef.close(); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.unsubscribeSubject.next(); |
||||
|
this.unsubscribeSubject.complete(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
<form #addPlatformForm="ngForm" class="d-flex flex-column h-100"> |
||||
|
<h1 *ngIf="data.platform.id" i18n mat-dialog-title>Update platform</h1> |
||||
|
<h1 *ngIf="!data.platform.id" i18n mat-dialog-title>Add platform</h1> |
||||
|
<div class="flex-grow-1 py-3" mat-dialog-content> |
||||
|
<div> |
||||
|
<mat-form-field appearance="outline" class="w-100"> |
||||
|
<mat-label i18n>Name</mat-label> |
||||
|
<input matInput name="name" required [(ngModel)]="data.platform.name" /> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<div> |
||||
|
<mat-form-field appearance="outline" class="w-100"> |
||||
|
<mat-label i18n>Url</mat-label> |
||||
|
<input matInput name="url" required [(ngModel)]="data.platform.url" /> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="justify-content-end" mat-dialog-actions> |
||||
|
<button i18n mat-button (click)="onCancel()">Cancel</button> |
||||
|
<button |
||||
|
color="primary" |
||||
|
mat-flat-button |
||||
|
[disabled]="!addPlatformForm.form.valid" |
||||
|
[mat-dialog-close]="data" |
||||
|
> |
||||
|
<ng-container i18n>Save</ng-container> |
||||
|
</button> |
||||
|
</div> |
||||
|
</form> |
@ -0,0 +1,22 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; |
||||
|
import { CreateOrUpdatePlatformDialog } from './create-or-update-account-platform.component'; |
||||
|
import { CommonModule } from '@angular/common'; |
||||
|
import { MatButtonModule } from '@angular/material/button'; |
||||
|
import { MatDialogModule } from '@angular/material/dialog'; |
||||
|
import { MatFormFieldModule } from '@angular/material/form-field'; |
||||
|
import { MatInputModule } from '@angular/material/input'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [CreateOrUpdatePlatformDialog], |
||||
|
imports: [ |
||||
|
CommonModule, |
||||
|
FormsModule, |
||||
|
MatButtonModule, |
||||
|
MatDialogModule, |
||||
|
MatFormFieldModule, |
||||
|
MatInputModule, |
||||
|
ReactiveFormsModule |
||||
|
] |
||||
|
}) |
||||
|
export class GfCreateOrUpdatePlatformDialogModule {} |
@ -0,0 +1,7 @@ |
|||||
|
:host { |
||||
|
display: block; |
||||
|
|
||||
|
.mat-mdc-dialog-content { |
||||
|
max-height: unset; |
||||
|
} |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
import { Platform } from '@prisma/client'; |
||||
|
|
||||
|
export interface CreateOrUpdatePlatformDialogParams { |
||||
|
platform: Platform; |
||||
|
} |
@ -0,0 +1,92 @@ |
|||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col"> |
||||
|
<table |
||||
|
class="gf-table w-100" |
||||
|
mat-table |
||||
|
matSort |
||||
|
matSortActive="name" |
||||
|
matSortDirection="asc" |
||||
|
[dataSource]="dataSource" |
||||
|
> |
||||
|
<ng-container matColumnDef="name"> |
||||
|
<th |
||||
|
*matHeaderCellDef |
||||
|
class="px-1" |
||||
|
mat-header-cell |
||||
|
mat-sort-header="name" |
||||
|
> |
||||
|
<ng-container i18n>Name</ng-container> |
||||
|
</th> |
||||
|
<td *matCellDef="let element" class="px-1" mat-cell> |
||||
|
<gf-symbol-icon |
||||
|
*ngIf="element.url" |
||||
|
class="d-inline mr-1" |
||||
|
[tooltip]="element.name" |
||||
|
[url]="element.url" |
||||
|
></gf-symbol-icon> |
||||
|
<span>{{ element.name }}</span> |
||||
|
</td></ng-container |
||||
|
> |
||||
|
|
||||
|
<ng-container matColumnDef="url"> |
||||
|
<th |
||||
|
*matHeaderCellDef |
||||
|
class="px-1" |
||||
|
mat-header-cell |
||||
|
mat-sort-header="url" |
||||
|
> |
||||
|
<ng-container i18n>Url</ng-container> |
||||
|
</th> |
||||
|
<td *matCellDef="let element" class="px-1" mat-cell> |
||||
|
{{ element.url }} |
||||
|
</td> |
||||
|
</ng-container> |
||||
|
|
||||
|
<ng-container matColumnDef="actions"> |
||||
|
<th |
||||
|
*matHeaderCellDef |
||||
|
class="px-1 text-center" |
||||
|
i18n |
||||
|
mat-header-cell |
||||
|
></th> |
||||
|
<td *matCellDef="let element" class="px-1 text-center" mat-cell> |
||||
|
<button |
||||
|
class="mx-1 no-min-width px-2" |
||||
|
mat-button |
||||
|
[matMenuTriggerFor]="platformMenu" |
||||
|
(click)="$event.stopPropagation()" |
||||
|
> |
||||
|
<ion-icon name="ellipsis-vertical"></ion-icon> |
||||
|
</button> |
||||
|
<mat-menu #platformMenu="matMenu" xPosition="before"> |
||||
|
<button mat-menu-item (click)="onUpdatePlatform(element)"> |
||||
|
<ion-icon class="mr-2" name="create-outline"></ion-icon> |
||||
|
<span i18n>Edit</span> |
||||
|
</button> |
||||
|
<button mat-menu-item (click)="onDeletePlatform(element.id)"> |
||||
|
<ion-icon class="mr-2" name="trash-outline"></ion-icon> |
||||
|
<span i18n>Delete</span> |
||||
|
</button> |
||||
|
</mat-menu> |
||||
|
</td> |
||||
|
</ng-container> |
||||
|
|
||||
|
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr> |
||||
|
<tr *matRowDef="let row; columns: displayedColumns" mat-row></tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div *ngIf="hasPermissionToCreatePlatform" class="fab-container"> |
||||
|
<a |
||||
|
class="align-items-center d-flex justify-content-center" |
||||
|
color="primary" |
||||
|
mat-fab |
||||
|
[queryParams]="{ createDialog: true }" |
||||
|
[routerLink]="[]" |
||||
|
> |
||||
|
<ion-icon name="add-outline" size="large"></ion-icon> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,12 @@ |
|||||
|
@import 'apps/client/src/styles/ghostfolio-style'; |
||||
|
|
||||
|
:host { |
||||
|
display: block; |
||||
|
|
||||
|
.fab-container { |
||||
|
position: fixed; |
||||
|
right: 2rem; |
||||
|
bottom: 4rem; |
||||
|
z-index: 999; |
||||
|
} |
||||
|
} |
@ -0,0 +1,222 @@ |
|||||
|
import { |
||||
|
ChangeDetectorRef, |
||||
|
Component, |
||||
|
OnDestroy, |
||||
|
OnInit, |
||||
|
ViewChild |
||||
|
} from '@angular/core'; |
||||
|
import { MatSort } from '@angular/material/sort'; |
||||
|
import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto'; |
||||
|
import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto'; |
||||
|
import { get } from 'lodash'; |
||||
|
import { MatTableDataSource } from '@angular/material/table'; |
||||
|
import { ActivatedRoute, Router } from '@angular/router'; |
||||
|
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
||||
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
||||
|
import { Platform, Platform as PlatformModel } from '@prisma/client'; |
||||
|
import { Subject, takeUntil } from 'rxjs'; |
||||
|
import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog/create-or-update-account-platform.component'; |
||||
|
import { MatDialog } from '@angular/material/dialog'; |
||||
|
import { DeviceDetectorService } from 'ngx-device-detector'; |
||||
|
import { AdminService } from '@ghostfolio/client/services/admin.service'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'gf-platform-overview', |
||||
|
styleUrls: ['./platform.component.scss'], |
||||
|
templateUrl: './platform.component.html' |
||||
|
}) |
||||
|
export class AdminPlatformComponent implements OnInit, OnDestroy { |
||||
|
@ViewChild(MatSort) sort: MatSort; |
||||
|
|
||||
|
public dataSource: MatTableDataSource<Platform> = new MatTableDataSource(); |
||||
|
public deviceType: string; |
||||
|
public displayedColumns = ['name', 'url', 'actions']; |
||||
|
public hasPermissionToCreatePlatform: boolean; |
||||
|
public hasPermissionToDeletePlatform: boolean; |
||||
|
public platforms: PlatformModel[]; |
||||
|
|
||||
|
private unsubscribeSubject = new Subject<void>(); |
||||
|
|
||||
|
public constructor( |
||||
|
private adminService: AdminService, |
||||
|
private changeDetectorRef: ChangeDetectorRef, |
||||
|
private deviceService: DeviceDetectorService, |
||||
|
private dialog: MatDialog, |
||||
|
private route: ActivatedRoute, |
||||
|
private router: Router, |
||||
|
private userService: UserService |
||||
|
) { |
||||
|
this.route.queryParams |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe((params) => { |
||||
|
if (params['createDialog'] && this.hasPermissionToCreatePlatform) { |
||||
|
this.openCreatePlatformDialog(); |
||||
|
} else if (params['editDialog']) { |
||||
|
if (this.platforms) { |
||||
|
const platform = this.platforms.find(({ id }) => { |
||||
|
return id === params['platformId']; |
||||
|
}); |
||||
|
|
||||
|
this.openUpdatePlatformDialog(platform); |
||||
|
} else { |
||||
|
this.router.navigate(['.'], { relativeTo: this.route }); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
||||
|
|
||||
|
this.userService.stateChanged |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe((state) => { |
||||
|
if (state?.user) { |
||||
|
const user = state.user; |
||||
|
|
||||
|
this.hasPermissionToCreatePlatform = hasPermission( |
||||
|
user.permissions, |
||||
|
permissions.createPlatform |
||||
|
); |
||||
|
this.hasPermissionToDeletePlatform = hasPermission( |
||||
|
user.permissions, |
||||
|
permissions.deletePlatform |
||||
|
); |
||||
|
|
||||
|
this.changeDetectorRef.markForCheck(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
this.fetchPlatforms(); |
||||
|
} |
||||
|
|
||||
|
public onDeletePlatform(aId: string) { |
||||
|
const confirmation = confirm( |
||||
|
$localize`Do you really want to delete this platform?` |
||||
|
); |
||||
|
|
||||
|
if (confirmation) { |
||||
|
this.deletePlatform(aId); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public onUpdatePlatform(aPlatform: PlatformModel) { |
||||
|
this.router.navigate([], { |
||||
|
queryParams: { platformId: aPlatform.id, editDialog: true } |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.unsubscribeSubject.next(); |
||||
|
this.unsubscribeSubject.complete(); |
||||
|
} |
||||
|
|
||||
|
private deletePlatform(aId: string) { |
||||
|
this.adminService |
||||
|
.deletePlatform(aId) |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe({ |
||||
|
next: () => { |
||||
|
this.userService |
||||
|
.get(true) |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe(); |
||||
|
|
||||
|
this.fetchPlatforms(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private fetchPlatforms() { |
||||
|
this.adminService |
||||
|
.fetchPlatforms() |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe((platforms) => { |
||||
|
this.platforms = platforms; |
||||
|
this.dataSource = new MatTableDataSource(platforms); |
||||
|
this.dataSource.sort = this.sort; |
||||
|
this.dataSource.sortingDataAccessor = get; |
||||
|
|
||||
|
this.changeDetectorRef.markForCheck(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private openCreatePlatformDialog() { |
||||
|
const dialogRef = this.dialog.open(CreateOrUpdatePlatformDialog, { |
||||
|
data: { |
||||
|
platform: { |
||||
|
name: null, |
||||
|
url: null |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', |
||||
|
width: this.deviceType === 'mobile' ? '100vw' : '50rem' |
||||
|
}); |
||||
|
|
||||
|
dialogRef |
||||
|
.afterClosed() |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe((data) => { |
||||
|
const platform: CreatePlatformDto = data?.platform; |
||||
|
|
||||
|
if (platform) { |
||||
|
this.adminService |
||||
|
.postPlatform(platform) |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe({ |
||||
|
next: () => { |
||||
|
this.userService |
||||
|
.get(true) |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe(); |
||||
|
|
||||
|
this.fetchPlatforms(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
this.router.navigate(['.'], { relativeTo: this.route }); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private openUpdatePlatformDialog({ id, name, url }) { |
||||
|
const dialogRef = this.dialog.open(CreateOrUpdatePlatformDialog, { |
||||
|
data: { |
||||
|
platform: { |
||||
|
id, |
||||
|
name, |
||||
|
url |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', |
||||
|
width: this.deviceType === 'mobile' ? '100vw' : '50rem' |
||||
|
}); |
||||
|
|
||||
|
dialogRef |
||||
|
.afterClosed() |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe((data) => { |
||||
|
const platform: UpdatePlatformDto = data?.platform; |
||||
|
|
||||
|
if (platform) { |
||||
|
this.adminService |
||||
|
.putPlatform(platform) |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe({ |
||||
|
next: () => { |
||||
|
this.userService |
||||
|
.get(true) |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe(); |
||||
|
|
||||
|
this.fetchPlatforms(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
this.router.navigate(['.'], { relativeTo: this.route }); |
||||
|
}); |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
||||
|
import { AdminPlatformComponent } from './platform.component'; |
||||
|
import { CommonModule } from '@angular/common'; |
||||
|
import { RouterModule } from '@angular/router'; |
||||
|
import { MatButtonModule } from '@angular/material/button'; |
||||
|
import { MatSortModule } from '@angular/material/sort'; |
||||
|
import { MatTableModule } from '@angular/material/table'; |
||||
|
import { GfCreateOrUpdatePlatformDialogModule } from './create-or-update-platform-dialog/create-or-update-platform-dialog.module'; |
||||
|
import { MatMenuModule } from '@angular/material/menu'; |
||||
|
import { GfSymbolIconModule } from '@ghostfolio/client/components/symbol-icon/symbol-icon.module'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [AdminPlatformComponent], |
||||
|
imports: [ |
||||
|
CommonModule, |
||||
|
GfCreateOrUpdatePlatformDialogModule, |
||||
|
GfSymbolIconModule, |
||||
|
MatButtonModule, |
||||
|
MatMenuModule, |
||||
|
MatSortModule, |
||||
|
MatTableModule, |
||||
|
RouterModule |
||||
|
], |
||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA] |
||||
|
}) |
||||
|
export class GfAdminPlatformModule {} |
Loading…
Reference in new issue