Browse Source

migrate data providers from mat-card to mat-table

pull/4704/head
Andrei D 4 months ago
parent
commit
3d3936b067
  1. 88
      apps/client/src/app/components/admin-settings/admin-settings.component.html
  2. 19
      apps/client/src/app/components/admin-settings/admin-settings.component.ts
  3. 4
      apps/client/src/app/components/admin-settings/admin-settings.module.ts

88
apps/client/src/app/components/admin-settings/admin-settings.component.html

@ -1,19 +1,17 @@
<div class="container"> <div class="container">
<div class="d-md-block d-none mb-5 row"> <div class="mb-5 row">
<div class="col"> <div class="col">
<h2 class="text-center" i18n>Data Providers</h2> <h2 class="text-center" i18n>Data Providers</h2>
<mat-card appearance="outlined"> <table class="gf-table w-100" mat-table [dataSource]="dataSource">
<mat-card-content> <ng-container matColumnDef="name">
@for (dataProvider of dataProviders; track dataProvider.name) { <th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
<div class="align-items-center d-flex my-3"> <ng-container i18n>Name</ng-container>
@if (dataProvider.name === 'Ghostfolio') { </th>
<div class="w-50"> <td *matCellDef="let element" class="px-1 py-2" mat-cell>
<div class="d-flex"> <div class="d-flex align-items-center">
<gf-asset-profile-icon <gf-asset-profile-icon class="mr-1" [url]="element.url" />
class="mr-1"
[url]="dataProvider.url"
/>
<div> <div>
@if (isGhostfolioProvider(element)) {
<a <a
class="align-items-center d-inline-flex" class="align-items-center d-inline-flex"
target="_blank" target="_blank"
@ -37,22 +35,32 @@
{{ {{
ghostfolioApiStatus?.subscription?.expiresAt ghostfolioApiStatus?.subscription?.expiresAt
| date: defaultDateFormat | date: defaultDateFormat
}}</small }}
> </small>
</div>
}
</div>
</div>
</div> </div>
<div class="w-50"> <div class="line-height-1 mt-1">
@if (isGhostfolioApiKeyValid === true) { <small class="text-muted">
<div class="align-items-center d-flex flex-wrap">
<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>
</small>
</div>
}
} @else {
{{ element.name }}
}
</div> </div>
</div>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell></th>
<td *matCellDef="let element" class="px-1 py-2 text-right" mat-cell>
@if (isGhostfolioProvider(element)) {
@if (isGhostfolioApiKeyValid === true) {
<button <button
class="mx-1 no-min-width px-2" class="mx-1 no-min-width px-2"
mat-button mat-button
@ -62,17 +70,13 @@
<ion-icon name="ellipsis-horizontal" /> <ion-icon name="ellipsis-horizontal" />
</button> </button>
<mat-menu #ghostfolioApiMenu="matMenu" xPosition="before"> <mat-menu #ghostfolioApiMenu="matMenu" xPosition="before">
<button <button mat-menu-item (click)="onRemoveGhostfolioApiKey()">
mat-menu-item
(click)="onRemoveGhostfolioApiKey()"
>
<span class="align-items-center d-flex"> <span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" /> <ion-icon class="mr-2" name="trash-outline" />
<span i18n>Remove API key</span> <span i18n>Remove API key</span>
</span> </span>
</button> </button>
</mat-menu> </mat-menu>
</div>
} @else if (isGhostfolioApiKeyValid === false) { } @else if (isGhostfolioApiKeyValid === false) {
<button <button
color="accent" color="accent"
@ -83,23 +87,23 @@
<span i18n>Set API key</span> <span i18n>Set API key</span>
</button> </button>
} }
</div>
} @else {
<div class="w-50">
<div class="d-flex">
<gf-asset-profile-icon
class="mr-1"
[url]="dataProvider.url"
/>
{{ dataProvider.name }}
</div>
</div>
<div class="w-50"></div>
} }
</div> </td>
</ng-container>
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
<tr *matRowDef="let row; columns: displayedColumns" mat-row></tr>
</table>
@if (isLoading) {
<ngx-skeleton-loader
animation="pulse"
class="px-4 py-3"
[theme]="{
height: '1.5rem',
width: '100%'
}"
/>
} }
</mat-card-content>
</mat-card>
</div> </div>
</div> </div>
<div class="mb-5 row"> <div class="mb-5 row">

19
apps/client/src/app/components/admin-settings/admin-settings.component.ts

@ -22,6 +22,7 @@ import {
OnInit OnInit
} from '@angular/core'; } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MatTableDataSource } from '@angular/material/table';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
import { catchError, filter, of, Subject, takeUntil } from 'rxjs'; import { catchError, filter, of, Subject, takeUntil } from 'rxjs';
@ -36,11 +37,13 @@ import { GhostfolioPremiumApiDialogParams } from './ghostfolio-premium-api-dialo
standalone: false standalone: false
}) })
export class AdminSettingsComponent implements OnDestroy, OnInit { export class AdminSettingsComponent implements OnDestroy, OnInit {
public dataProviders: DataProviderInfo[]; public dataSource = new MatTableDataSource<DataProviderInfo>();
public defaultDateFormat: string; public defaultDateFormat: string;
public ghostfolioApiStatus: DataProviderGhostfolioStatusResponse; public ghostfolioApiStatus: DataProviderGhostfolioStatusResponse;
public isGhostfolioApiKeyValid: boolean; public isGhostfolioApiKeyValid: boolean;
public pricingUrl: string; public pricingUrl: string;
public displayedColumns = ['name', 'actions'];
public isLoading = false;
private deviceType: string; private deviceType: string;
private unsubscribeSubject = new Subject<void>(); private unsubscribeSubject = new Subject<void>();
@ -119,20 +122,28 @@ export class AdminSettingsComponent implements OnDestroy, OnInit {
}); });
} }
public isGhostfolioProvider(provider: DataProviderInfo): boolean {
return provider.name === 'Ghostfolio';
}
public ngOnDestroy() { public ngOnDestroy() {
this.unsubscribeSubject.next(); this.unsubscribeSubject.next();
this.unsubscribeSubject.complete(); this.unsubscribeSubject.complete();
} }
private initialize() { private initialize() {
this.isLoading = true;
this.adminService this.adminService
.fetchAdminData() .fetchAdminData()
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ dataProviders, settings }) => { .subscribe(({ dataProviders, settings }) => {
this.dataProviders = dataProviders.filter(({ dataSource }) => { const filteredProviders = dataProviders.filter(({ dataSource }) => {
return dataSource !== 'MANUAL'; return dataSource !== 'MANUAL';
}); });
this.dataSource = new MatTableDataSource(filteredProviders);
this.adminService this.adminService
.fetchGhostfolioDataProviderStatus( .fetchGhostfolioDataProviderStatus(
settings[PROPERTY_API_KEY_GHOSTFOLIO] as string settings[PROPERTY_API_KEY_GHOSTFOLIO] as string
@ -140,7 +151,7 @@ export class AdminSettingsComponent implements OnDestroy, OnInit {
.pipe( .pipe(
catchError(() => { catchError(() => {
this.isGhostfolioApiKeyValid = false; this.isGhostfolioApiKeyValid = false;
this.isLoading = false;
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
return of(null); return of(null);
@ -153,7 +164,7 @@ export class AdminSettingsComponent implements OnDestroy, OnInit {
.subscribe((status) => { .subscribe((status) => {
this.ghostfolioApiStatus = status; this.ghostfolioApiStatus = status;
this.isGhostfolioApiKeyValid = true; this.isGhostfolioApiKeyValid = true;
this.isLoading = false;
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
}); });

4
apps/client/src/app/components/admin-settings/admin-settings.module.ts

@ -8,6 +8,7 @@ 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 { MatMenuModule } from '@angular/material/menu';
import { MatTableModule } from '@angular/material/table';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { AdminSettingsComponent } from './admin-settings.component'; import { AdminSettingsComponent } from './admin-settings.component';
@ -23,7 +24,8 @@ import { AdminSettingsComponent } from './admin-settings.component';
MatButtonModule, MatButtonModule,
MatCardModule, MatCardModule,
MatMenuModule, MatMenuModule,
RouterModule RouterModule,
MatTableModule
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}) })

Loading…
Cancel
Save