From ee7bb911d7b5ab7549ea3911a7a03bf46dbbc55f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 21 Jun 2025 19:26:06 +0200 Subject: [PATCH] Feature/simplify data providers management of admin control panel (#4991) * Set up open color for CSS variables usage * Simplify data providers management * Update changelog --- CHANGELOG.md | 5 ++ apps/client/project.json | 3 +- .../admin-settings.component.html | 42 ++++++++++++- .../admin-settings.component.scss | 20 ++++++- .../admin-settings.component.ts | 45 +++++--------- .../admin-settings/admin-settings.module.ts | 2 + ...ghostfolio-premium-api-dialog.component.ts | 60 ------------------- .../ghostfolio-premium-api-dialog.html | 49 --------------- .../ghostfolio-premium-api-dialog.scss | 2 - .../interfaces/interfaces.ts | 4 -- 10 files changed, 83 insertions(+), 149 deletions(-) delete mode 100644 apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component.ts delete mode 100644 apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.html delete mode 100644 apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.scss delete mode 100644 apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/interfaces/interfaces.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 018a7cede..85a1da408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Set up `open-color` for CSS variable usage + ### Changed +- Simplified the data providers management of the admin control panel - Migrated the `@ghostfolio/ui/assistant` component to control flow - Migrated the `@ghostfolio/ui/value` component to control flow - Renamed `GranteeUser` to `granteeUser` in the `Access` database schema diff --git a/apps/client/project.json b/apps/client/project.json index 4bb7fe296..215c5dae1 100644 --- a/apps/client/project.json +++ b/apps/client/project.json @@ -73,7 +73,8 @@ "styles": [ "apps/client/src/assets/fonts/inter.css", "apps/client/src/styles/theme.scss", - "apps/client/src/styles.scss" + "apps/client/src/styles.scss", + "node_modules/open-color/open-color.css" ], "scripts": ["node_modules/marked/marked.min.js"], "vendorChunk": true, diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.html b/apps/client/src/app/components/admin-settings/admin-settings.component.html index 368b98da5..f00b5bc88 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.html +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -2,6 +2,42 @@

Data Providers

+ @if (isGhostfolioApiKeyValid === false) { + + + Ghostfolio Premium + + + + Fuel your self-hosted Ghostfolio with a + powerful data provider to access + 80,000+ tickers from over + 50 exchanges worldwide. + + + + Get Access + +
or
+ + Learn more + +
+
+ }
@@ -23,8 +59,10 @@ [enableLink]="false" /> @if (isGhostfolioApiKeyValid === false) { - Early Accessnew } diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.scss b/apps/client/src/app/components/admin-settings/admin-settings.component.scss index 384143300..28bab4deb 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.scss +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.scss @@ -1,16 +1,26 @@ :host { display: block; + a, button { &.special { - background: linear-gradient(45deg, rgb(228, 94, 237), rgb(104, 94, 237)); + background: linear-gradient(45deg, var(--oc-pink-5), var(--oc-violet-5)); color: #fff; } } .badge { - &.early-access { + &.new { border: 1px solid var(--mat-table-row-item-outline-color); + padding-bottom: 0.05rem; + } + } + + .mat-mdc-card { + --mdc-outlined-card-container-color: whitesmoke; + + .mat-mdc-card-actions { + min-height: 0; } } @@ -26,3 +36,9 @@ } } } + +:host-context(.theme-dark) { + .mat-mdc-card { + --mdc-outlined-card-container-color: #222222; + } +} diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.ts b/apps/client/src/app/components/admin-settings/admin-settings.component.ts index 8911fb818..209fbe9f0 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.ts +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.ts @@ -19,14 +19,9 @@ import { OnDestroy, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; import { MatTableDataSource } from '@angular/material/table'; -import { DeviceDetectorService } from 'ngx-device-detector'; import { catchError, filter, of, Subject, takeUntil } from 'rxjs'; -import { GfGhostfolioPremiumApiDialogComponent } from './ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component'; -import { GhostfolioPremiumApiDialogParams } from './ghostfolio-premium-api-dialog/interfaces/interfaces'; - @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'gf-admin-settings', @@ -43,7 +38,6 @@ export class AdminSettingsComponent implements OnDestroy, OnInit { public isLoading = false; public pricingUrl: string; - private deviceType: string; private unsubscribeSubject = new Subject(); private user: User; @@ -51,15 +45,11 @@ export class AdminSettingsComponent implements OnDestroy, OnInit { private adminService: AdminService, private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, - private deviceService: DeviceDetectorService, - private matDialog: MatDialog, private notificationService: NotificationService, private userService: UserService ) {} public ngOnInit() { - this.deviceType = this.deviceService.getDeviceInfo().deviceType; - this.userService.stateChanged .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((state) => { @@ -100,25 +90,22 @@ export class AdminSettingsComponent implements OnDestroy, OnInit { } public onSetGhostfolioApiKey() { - const dialogRef = this.matDialog.open( - GfGhostfolioPremiumApiDialogComponent, - { - autoFocus: false, - data: { - deviceType: this.deviceType, - pricingUrl: this.pricingUrl - } as GhostfolioPremiumApiDialogParams, - height: this.deviceType === 'mobile' ? '98vh' : undefined, - width: this.deviceType === 'mobile' ? '100vw' : '50rem' - } - ); - - dialogRef - .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.initialize(); - }); + this.notificationService.prompt({ + confirmFn: (value) => { + const ghostfolioApiKey = value?.trim(); + + if (ghostfolioApiKey) { + this.dataService + .putAdminSetting(PROPERTY_API_KEY_GHOSTFOLIO, { + value: ghostfolioApiKey + }) + .subscribe(() => { + this.initialize(); + }); + } + }, + title: $localize`Please enter your Ghostfolio API key.` + }); } public ngOnDestroy() { diff --git a/apps/client/src/app/components/admin-settings/admin-settings.module.ts b/apps/client/src/app/components/admin-settings/admin-settings.module.ts index 228ddef00..52aec67be 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.module.ts +++ b/apps/client/src/app/components/admin-settings/admin-settings.module.ts @@ -7,6 +7,7 @@ import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatTableModule } from '@angular/material/table'; @@ -25,6 +26,7 @@ import { AdminSettingsComponent } from './admin-settings.component'; GfPremiumIndicatorComponent, GfValueComponent, MatButtonModule, + MatCardModule, MatMenuModule, MatProgressBarModule, MatTableModule, diff --git a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component.ts b/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component.ts deleted file mode 100644 index e42e6259e..000000000 --- a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; -import { DataService } from '@ghostfolio/client/services/data.service'; -import { PROPERTY_API_KEY_GHOSTFOLIO } from '@ghostfolio/common/config'; -import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; - -import { Component, Inject } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { - MAT_DIALOG_DATA, - MatDialogModule, - MatDialogRef -} from '@angular/material/dialog'; - -import { GfDialogFooterModule } from '../../dialog-footer/dialog-footer.module'; -import { GfDialogHeaderModule } from '../../dialog-header/dialog-header.module'; -import { GhostfolioPremiumApiDialogParams } from './interfaces/interfaces'; - -@Component({ - imports: [ - GfDialogFooterModule, - GfDialogHeaderModule, - GfPremiumIndicatorComponent, - MatButtonModule, - MatDialogModule - ], - selector: 'gf-ghostfolio-premium-api-dialog', - styleUrls: ['./ghostfolio-premium-api-dialog.scss'], - templateUrl: './ghostfolio-premium-api-dialog.html' -}) -export class GfGhostfolioPremiumApiDialogComponent { - public constructor( - @Inject(MAT_DIALOG_DATA) public data: GhostfolioPremiumApiDialogParams, - private dataService: DataService, - public dialogRef: MatDialogRef, - private notificationService: NotificationService - ) {} - - public onCancel() { - this.dialogRef.close(); - } - - public onSetGhostfolioApiKey() { - this.notificationService.prompt({ - confirmFn: (value) => { - const ghostfolioApiKey = value?.trim(); - - if (ghostfolioApiKey) { - this.dataService - .putAdminSetting(PROPERTY_API_KEY_GHOSTFOLIO, { - value: ghostfolioApiKey - }) - .subscribe(() => { - this.dialogRef.close(); - }); - } - }, - title: $localize`Please enter your Ghostfolio API key.` - }); - } -} diff --git a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.html b/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.html deleted file mode 100644 index 017133f5b..000000000 --- a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.html +++ /dev/null @@ -1,49 +0,0 @@ - - -
-

- Early access to the official - Ghostfolio Premium - - - data provider for self-hosters, offering - 80’000+ tickers from over 50 exchanges, is - ready now! -

-
- Get Early Access -
- or -
- -
-
- - diff --git a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.scss b/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.scss deleted file mode 100644 index dc9093b45..000000000 --- a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.scss +++ /dev/null @@ -1,2 +0,0 @@ -:host { -} diff --git a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/interfaces/interfaces.ts deleted file mode 100644 index 0c629599e..000000000 --- a/apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/interfaces/interfaces.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface GhostfolioPremiumApiDialogParams { - deviceType: string; - pricingUrl: string; -}