|
|
|
@ -10,12 +10,13 @@ import { |
|
|
|
ChangeDetectionStrategy, |
|
|
|
ChangeDetectorRef, |
|
|
|
Component, |
|
|
|
DestroyRef, |
|
|
|
DOCUMENT, |
|
|
|
HostBinding, |
|
|
|
Inject, |
|
|
|
OnDestroy, |
|
|
|
inject, |
|
|
|
OnInit |
|
|
|
} from '@angular/core'; |
|
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
|
import { MatDialog } from '@angular/material/dialog'; |
|
|
|
import { Title } from '@angular/platform-browser'; |
|
|
|
import { |
|
|
|
@ -30,15 +31,13 @@ import { DataSource } from '@prisma/client'; |
|
|
|
import { addIcons } from 'ionicons'; |
|
|
|
import { openOutline } from 'ionicons/icons'; |
|
|
|
import { DeviceDetectorService } from 'ngx-device-detector'; |
|
|
|
import { Subject } from 'rxjs'; |
|
|
|
import { filter, takeUntil } from 'rxjs/operators'; |
|
|
|
import { filter } from 'rxjs/operators'; |
|
|
|
|
|
|
|
import { GfFooterComponent } from './components/footer/footer.component'; |
|
|
|
import { GfHeaderComponent } from './components/header/header.component'; |
|
|
|
import { GfHoldingDetailDialogComponent } from './components/holding-detail-dialog/holding-detail-dialog.component'; |
|
|
|
import { HoldingDetailDialogParams } from './components/holding-detail-dialog/interfaces/interfaces'; |
|
|
|
import { GfAppQueryParams } from './interfaces/interfaces'; |
|
|
|
import { ImpersonationStorageService } from './services/impersonation-storage.service'; |
|
|
|
import { TokenStorageService } from './services/token-storage.service'; |
|
|
|
import { UserService } from './services/user/user.service'; |
|
|
|
|
|
|
|
@Component({ |
|
|
|
@ -48,11 +47,7 @@ import { UserService } from './services/user/user.service'; |
|
|
|
styleUrls: ['./app.component.scss'], |
|
|
|
templateUrl: './app.component.html' |
|
|
|
}) |
|
|
|
export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
@HostBinding('class.has-info-message') get getHasMessage() { |
|
|
|
return this.hasInfoMessage; |
|
|
|
} |
|
|
|
|
|
|
|
export class GfAppComponent implements OnInit { |
|
|
|
public canCreateAccount: boolean; |
|
|
|
public currentRoute: string; |
|
|
|
public currentSubRoute: string; |
|
|
|
@ -67,52 +62,54 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
public pageTitle: string; |
|
|
|
public routerLinkRegister = publicRoutes.register.routerLink; |
|
|
|
public showFooter = false; |
|
|
|
public user: User; |
|
|
|
|
|
|
|
private unsubscribeSubject = new Subject<void>(); |
|
|
|
|
|
|
|
public constructor( |
|
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
|
private dataService: DataService, |
|
|
|
private deviceService: DeviceDetectorService, |
|
|
|
private dialog: MatDialog, |
|
|
|
@Inject(DOCUMENT) private document: Document, |
|
|
|
private impersonationStorageService: ImpersonationStorageService, |
|
|
|
private notificationService: NotificationService, |
|
|
|
private route: ActivatedRoute, |
|
|
|
private router: Router, |
|
|
|
private title: Title, |
|
|
|
private tokenStorageService: TokenStorageService, |
|
|
|
private userService: UserService |
|
|
|
) { |
|
|
|
public user: User | undefined; |
|
|
|
|
|
|
|
private readonly changeDetectorRef = inject(ChangeDetectorRef); |
|
|
|
private readonly dataService = inject(DataService); |
|
|
|
private readonly destroyRef = inject(DestroyRef); |
|
|
|
private readonly deviceService = inject(DeviceDetectorService); |
|
|
|
private readonly dialog = inject(MatDialog); |
|
|
|
private readonly document = inject(DOCUMENT); |
|
|
|
private readonly impersonationStorageService = inject( |
|
|
|
ImpersonationStorageService |
|
|
|
); |
|
|
|
private readonly notificationService = inject(NotificationService); |
|
|
|
private readonly route = inject(ActivatedRoute); |
|
|
|
private readonly router = inject(Router); |
|
|
|
private readonly title = inject(Title); |
|
|
|
private readonly userService = inject(UserService); |
|
|
|
|
|
|
|
public constructor() { |
|
|
|
this.initializeTheme(); |
|
|
|
this.user = undefined; |
|
|
|
|
|
|
|
this.route.queryParams |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.subscribe((params) => { |
|
|
|
if ( |
|
|
|
params['dataSource'] && |
|
|
|
params['holdingDetailDialog'] && |
|
|
|
params['symbol'] |
|
|
|
) { |
|
|
|
this.openHoldingDetailDialog({ |
|
|
|
dataSource: params['dataSource'], |
|
|
|
symbol: params['symbol'] |
|
|
|
}); |
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
.subscribe( |
|
|
|
({ dataSource, holdingDetailDialog, symbol }: GfAppQueryParams) => { |
|
|
|
if (dataSource && holdingDetailDialog && symbol) { |
|
|
|
this.openHoldingDetailDialog({ |
|
|
|
dataSource, |
|
|
|
symbol |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
); |
|
|
|
|
|
|
|
addIcons({ openOutline }); |
|
|
|
} |
|
|
|
|
|
|
|
@HostBinding('class.has-info-message') get getHasMessage() { |
|
|
|
return this.hasInfoMessage; |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnInit() { |
|
|
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
|
|
|
this.info = this.dataService.fetchInfo(); |
|
|
|
|
|
|
|
this.impersonationStorageService |
|
|
|
.onChangeHasImpersonation() |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
.subscribe((impersonationId) => { |
|
|
|
this.hasImpersonationId = !!impersonationId; |
|
|
|
}); |
|
|
|
@ -131,7 +128,7 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
!this.currentSubRoute) || |
|
|
|
(this.currentRoute === internalRoutes.home.path && |
|
|
|
this.currentSubRoute === |
|
|
|
internalRoutes.home.subRoutes.holdings.path) || |
|
|
|
internalRoutes.home.subRoutes?.holdings.path) || |
|
|
|
(this.currentRoute === internalRoutes.portfolio.path && |
|
|
|
!this.currentSubRoute)) && |
|
|
|
this.user?.settings?.viewMode !== 'ZEN' |
|
|
|
@ -144,18 +141,18 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
if ( |
|
|
|
(this.currentRoute === internalRoutes.home.path && |
|
|
|
this.currentSubRoute === |
|
|
|
internalRoutes.home.subRoutes.holdings.path) || |
|
|
|
internalRoutes.home.subRoutes?.holdings.path) || |
|
|
|
(this.currentRoute === internalRoutes.portfolio.path && |
|
|
|
!this.currentSubRoute) || |
|
|
|
(this.currentRoute === internalRoutes.portfolio.path && |
|
|
|
this.currentSubRoute === |
|
|
|
internalRoutes.portfolio.subRoutes.activities.path) || |
|
|
|
internalRoutes.portfolio.subRoutes?.activities.path) || |
|
|
|
(this.currentRoute === internalRoutes.portfolio.path && |
|
|
|
this.currentSubRoute === |
|
|
|
internalRoutes.portfolio.subRoutes.allocations.path) || |
|
|
|
internalRoutes.portfolio.subRoutes?.allocations.path) || |
|
|
|
(this.currentRoute === internalRoutes.zen.path && |
|
|
|
this.currentSubRoute === |
|
|
|
internalRoutes.home.subRoutes.holdings.path) |
|
|
|
internalRoutes.home.subRoutes?.holdings.path) |
|
|
|
) { |
|
|
|
this.hasPermissionToChangeFilters = true; |
|
|
|
} else { |
|
|
|
@ -201,7 +198,7 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
}); |
|
|
|
|
|
|
|
this.userService.stateChanged |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
.subscribe((state) => { |
|
|
|
this.user = state.user; |
|
|
|
|
|
|
|
@ -226,31 +223,31 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
} |
|
|
|
|
|
|
|
public onClickSystemMessage() { |
|
|
|
if (this.user.systemMessage.routerLink) { |
|
|
|
this.router.navigate(this.user.systemMessage.routerLink); |
|
|
|
const systemMessage = this.user?.systemMessage; |
|
|
|
|
|
|
|
if (!systemMessage) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (systemMessage.routerLink) { |
|
|
|
void this.router.navigate(systemMessage.routerLink); |
|
|
|
} else { |
|
|
|
this.notificationService.alert({ |
|
|
|
title: this.user.systemMessage.message |
|
|
|
title: systemMessage.message |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public onCreateAccount() { |
|
|
|
this.tokenStorageService.signOut(); |
|
|
|
this.userService.signOut(); |
|
|
|
} |
|
|
|
|
|
|
|
public onSignOut() { |
|
|
|
this.tokenStorageService.signOut(); |
|
|
|
this.userService.remove(); |
|
|
|
this.userService.signOut(); |
|
|
|
|
|
|
|
document.location.href = `/${document.documentElement.lang}`; |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnDestroy() { |
|
|
|
this.unsubscribeSubject.next(); |
|
|
|
this.unsubscribeSubject.complete(); |
|
|
|
} |
|
|
|
|
|
|
|
private initializeTheme(userPreferredColorScheme?: ColorScheme) { |
|
|
|
const isDarkTheme = userPreferredColorScheme |
|
|
|
? userPreferredColorScheme === 'DARK' |
|
|
|
@ -274,14 +271,11 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
}) { |
|
|
|
this.userService |
|
|
|
.get() |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
.subscribe((user) => { |
|
|
|
this.user = user; |
|
|
|
|
|
|
|
const dialogRef = this.dialog.open< |
|
|
|
GfHoldingDetailDialogComponent, |
|
|
|
HoldingDetailDialogParams |
|
|
|
>(GfHoldingDetailDialogComponent, { |
|
|
|
const dialogRef = this.dialog.open(GfHoldingDetailDialogComponent, { |
|
|
|
autoFocus: false, |
|
|
|
data: { |
|
|
|
dataSource, |
|
|
|
@ -296,15 +290,21 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
), |
|
|
|
hasPermissionToCreateActivity: |
|
|
|
!this.hasImpersonationId && |
|
|
|
hasPermission(this.user?.permissions, permissions.createOrder) && |
|
|
|
hasPermission( |
|
|
|
this.user?.permissions, |
|
|
|
permissions.createActivity |
|
|
|
) && |
|
|
|
!this.user?.settings?.isRestrictedView, |
|
|
|
hasPermissionToReportDataGlitch: hasPermission( |
|
|
|
this.user?.permissions, |
|
|
|
permissions.reportDataGlitch |
|
|
|
), |
|
|
|
hasPermissionToUpdateOrder: |
|
|
|
hasPermissionToUpdateActivity: |
|
|
|
!this.hasImpersonationId && |
|
|
|
hasPermission(this.user?.permissions, permissions.updateOrder) && |
|
|
|
hasPermission( |
|
|
|
this.user?.permissions, |
|
|
|
permissions.updateActivity |
|
|
|
) && |
|
|
|
!this.user?.settings?.isRestrictedView, |
|
|
|
locale: this.user?.settings?.locale |
|
|
|
}, |
|
|
|
@ -314,9 +314,9 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
|
|
|
|
dialogRef |
|
|
|
.afterClosed() |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
.subscribe(() => { |
|
|
|
this.router.navigate([], { |
|
|
|
void this.router.navigate([], { |
|
|
|
queryParams: { |
|
|
|
dataSource: null, |
|
|
|
holdingDetailDialog: null, |
|
|
|
@ -342,6 +342,6 @@ export class GfAppComponent implements OnDestroy, OnInit { |
|
|
|
|
|
|
|
this.document |
|
|
|
.querySelector('meta[name="theme-color"]') |
|
|
|
.setAttribute('content', themeColor); |
|
|
|
?.setAttribute('content', themeColor); |
|
|
|
} |
|
|
|
} |
|
|
|
|