Feature/improve usability of Ghostfolio data provider (#4086)
* Improve usability
This commit is contained in:
parent
11a32a75c6
commit
3194ed2145
@ -191,9 +191,6 @@ export class GhostfolioController {
|
|||||||
@HasPermission(permissions.enableDataProviderGhostfolio)
|
@HasPermission(permissions.enableDataProviderGhostfolio)
|
||||||
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
||||||
public async getStatus(): Promise<DataProviderGhostfolioStatusResponse> {
|
public async getStatus(): Promise<DataProviderGhostfolioStatusResponse> {
|
||||||
return {
|
return this.ghostfolioService.getStatus({ user: this.request.user });
|
||||||
dailyRequests: this.request.user.dataProviderGhostfolioDailyRequests,
|
|
||||||
dailyRequestsMax: await this.ghostfolioService.getMaxDailyRequests()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
LookupResponse,
|
LookupResponse,
|
||||||
QuotesResponse
|
QuotesResponse
|
||||||
} from '@ghostfolio/common/interfaces';
|
} from '@ghostfolio/common/interfaces';
|
||||||
|
import { UserWithSettings } from '@ghostfolio/common/types';
|
||||||
|
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { DataSource } from '@prisma/client';
|
import { DataSource } from '@prisma/client';
|
||||||
@ -208,6 +209,14 @@ export class GhostfolioService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getStatus({ user }: { user: UserWithSettings }) {
|
||||||
|
return {
|
||||||
|
dailyRequests: user.dataProviderGhostfolioDailyRequests,
|
||||||
|
dailyRequestsMax: await this.getMaxDailyRequests(),
|
||||||
|
subscription: user.subscription
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public async incrementDailyRequests({ userId }: { userId: string }) {
|
public async incrementDailyRequests({ userId }: { userId: string }) {
|
||||||
await this.prismaService.analytics.update({
|
await this.prismaService.analytics.update({
|
||||||
data: {
|
data: {
|
||||||
|
@ -20,23 +20,43 @@
|
|||||||
[enableLink]="false"
|
[enableLink]="false"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
@if (isGhostfolioApiKeyValid === true) {
|
||||||
|
<div class="line-height-1">
|
||||||
|
<small class="text-muted">
|
||||||
|
<ng-container i18n>Valid until</ng-container>
|
||||||
|
{{
|
||||||
|
ghostfolioApiStatus?.subscription?.expiresAt
|
||||||
|
| date: defaultDateFormat
|
||||||
|
}}</small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="w-50">
|
<div class="w-50">
|
||||||
@if (isGhostfolioApiKeyValid === true) {
|
@if (isGhostfolioApiKeyValid === true) {
|
||||||
<div class="align-items-center d-flex flex-wrap">
|
<div class="align-items-center d-flex flex-wrap">
|
||||||
<div class="mr-3">
|
<div class="flex-grow-1 mr-3">
|
||||||
{{ ghostfolioApiStatus.dailyRequests }}
|
{{ ghostfolioApiStatus.dailyRequests }}
|
||||||
<ng-container i18n>of</ng-container>
|
<ng-container i18n>of</ng-container>
|
||||||
{{ ghostfolioApiStatus.dailyRequestsMax }}
|
{{ ghostfolioApiStatus.dailyRequestsMax }}
|
||||||
<ng-container i18n>daily requests</ng-container>
|
<ng-container i18n>daily requests</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
color="warn"
|
class="mx-1 no-min-width px-2"
|
||||||
mat-flat-button
|
mat-button
|
||||||
(click)="onRemoveGhostfolioApiKey()"
|
[matMenuTriggerFor]="ghostfolioApiMenu"
|
||||||
|
(click)="$event.stopPropagation()"
|
||||||
>
|
>
|
||||||
<span i18n>Remove API key</span>
|
<ion-icon name="ellipsis-horizontal" />
|
||||||
</button>
|
</button>
|
||||||
|
<mat-menu #ghostfolioApiMenu="matMenu" xPosition="before">
|
||||||
|
<button mat-menu-item (click)="onRemoveGhostfolioApiKey()">
|
||||||
|
<span class="align-items-center d-flex">
|
||||||
|
<ion-icon class="mr-2" name="trash-outline" />
|
||||||
|
<span i18n>Remove API key</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
} @else if (isGhostfolioApiKeyValid === false) {
|
} @else if (isGhostfolioApiKeyValid === false) {
|
||||||
<button
|
<button
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
DEFAULT_LANGUAGE_CODE,
|
DEFAULT_LANGUAGE_CODE,
|
||||||
PROPERTY_API_KEY_GHOSTFOLIO
|
PROPERTY_API_KEY_GHOSTFOLIO
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
|
import { getDateFormatString } from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
DataProviderGhostfolioStatusResponse,
|
DataProviderGhostfolioStatusResponse,
|
||||||
User
|
User
|
||||||
@ -32,6 +33,7 @@ import { GfGhostfolioPremiumApiDialogComponent } from './ghostfolio-premium-api-
|
|||||||
templateUrl: './admin-settings.component.html'
|
templateUrl: './admin-settings.component.html'
|
||||||
})
|
})
|
||||||
export class AdminSettingsComponent implements OnDestroy, OnInit {
|
export class AdminSettingsComponent implements OnDestroy, OnInit {
|
||||||
|
public defaultDateFormat: string;
|
||||||
public ghostfolioApiStatus: DataProviderGhostfolioStatusResponse;
|
public ghostfolioApiStatus: DataProviderGhostfolioStatusResponse;
|
||||||
public isGhostfolioApiKeyValid: boolean;
|
public isGhostfolioApiKeyValid: boolean;
|
||||||
public pricingUrl: string;
|
public pricingUrl: string;
|
||||||
@ -59,6 +61,10 @@ export class AdminSettingsComponent implements OnDestroy, OnInit {
|
|||||||
if (state?.user) {
|
if (state?.user) {
|
||||||
this.user = state.user;
|
this.user = state.user;
|
||||||
|
|
||||||
|
this.defaultDateFormat = getDateFormatString(
|
||||||
|
this.user?.settings?.locale
|
||||||
|
);
|
||||||
|
|
||||||
const languageCode =
|
const languageCode =
|
||||||
this.user?.settings?.language ?? DEFAULT_LANGUAGE_CODE;
|
this.user?.settings?.language ?? DEFAULT_LANGUAGE_CODE;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { AdminSettingsComponent } from './admin-settings.component';
|
import { AdminSettingsComponent } from './admin-settings.component';
|
||||||
@ -19,6 +20,7 @@ import { AdminSettingsComponent } from './admin-settings.component';
|
|||||||
GfPremiumIndicatorComponent,
|
GfPremiumIndicatorComponent,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
|
MatMenuModule,
|
||||||
RouterModule
|
RouterModule
|
||||||
],
|
],
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
import { UserWithSettings } from '@ghostfolio/common/types';
|
||||||
|
|
||||||
export interface DataProviderGhostfolioStatusResponse {
|
export interface DataProviderGhostfolioStatusResponse {
|
||||||
dailyRequests: number;
|
dailyRequests: number;
|
||||||
dailyRequestsMax: number;
|
dailyRequestsMax: number;
|
||||||
|
subscription: UserWithSettings['subscription'];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user