Browse Source

icons in filters

pull/2571/head
bptrgx 2 years ago
parent
commit
27b2def70a
  1. 19
      apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
  2. 20
      apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
  3. 15
      apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts
  4. 4
      apps/client/src/styles.scss
  5. 9
      libs/common/src/lib/interfaces/filter.interface.ts
  6. 38
      libs/ui/src/lib/activities-filter/activities-filter.component.html
  7. 4
      libs/ui/src/lib/activities-filter/activities-filter.component.scss
  8. 4
      libs/ui/src/lib/activities-filter/activities-filter.module.ts
  9. 21
      libs/ui/src/lib/activities-table/activities-table.component.ts
  10. 2
      libs/ui/src/lib/i18n.ts

19
apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts

@ -61,12 +61,13 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
};
};
public placeholder = '';
public platforms: {
public platformsValues: {
[id: string]: Pick<Platform, 'name'> & {
id: string;
value: number;
};
};
public platforms: Platform[];
public portfolioDetails: PortfolioDetails;
public positions: {
[symbol: string]: Pick<
@ -107,6 +108,9 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
private router: Router,
private userService: UserService
) {
const { platforms } = this.dataService.fetchInfo();
this.platforms = platforms;
route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
@ -173,8 +177,15 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
this.user = state.user;
const accountFilters: Filter[] = this.user.accounts.map(
({ id, name }) => {
({ id, name, platformId }) => {
let accountPlatformUrl = '';
for (const platform of this.platforms) {
if (platform.id === platformId) {
accountPlatformUrl = platform.url;
}
}
return {
accountPlatformUrl,
id,
label: name,
type: 'ACCOUNT'
@ -286,7 +297,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
value: 0
}
};
this.platforms = {};
this.platformsValues = {};
this.portfolioDetails = {
accounts: {},
filteredValueInPercentage: 0,
@ -517,7 +528,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
value = valueInBaseCurrency;
}
this.platforms[id] = {
this.platformsValues[id] = {
id,
name,
value

20
apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts

@ -18,7 +18,12 @@ import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.in
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DateRange, GroupBy, ToggleOption } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { AssetClass, DataSource, SymbolProfile } from '@prisma/client';
import {
AssetClass,
DataSource,
Platform,
SymbolProfile
} from '@prisma/client';
import { differenceInDays } from 'date-fns';
import { isNumber, sortBy } from 'lodash';
import { DeviceDetectorService } from 'ngx-device-detector';
@ -57,6 +62,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public performanceDataItems: HistoricalDataItem[];
public performanceDataItemsInPercentage: HistoricalDataItem[];
public placeholder = '';
public platforms: Platform[];
public portfolioEvolutionDataLabel = $localize`Deposit`;
public streaks: PortfolioInvestments['streaks'];
public top3: Position[];
@ -76,8 +82,9 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
private router: Router,
private userService: UserService
) {
const { benchmarks } = this.dataService.fetchInfo();
const { benchmarks, platforms } = this.dataService.fetchInfo();
this.benchmarks = benchmarks;
this.platforms = platforms;
route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
@ -139,8 +146,15 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
this.user = state.user;
const accountFilters: Filter[] = this.user.accounts.map(
({ id, name }) => {
({ id, name, platformId }) => {
let accountPlatformUrl = '';
for (const { id, url } of this.platforms) {
if (id === platformId) {
accountPlatformUrl = url;
}
}
return {
accountPlatformUrl,
id,
label: name,
type: 'ACCOUNT'

15
apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts

@ -14,7 +14,7 @@ import {
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { translate } from '@ghostfolio/ui/i18n';
import { AssetClass, DataSource } from '@prisma/client';
import { AssetClass, DataSource, Platform } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
import { distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators';
@ -33,6 +33,7 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
public hasPermissionToCreateOrder: boolean;
public isLoading = false;
public placeholder = '';
public platforms: Platform[];
public portfolioDetails: PortfolioDetails;
public positionsArray: PortfolioPosition[];
public user: User;
@ -49,6 +50,9 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
private router: Router,
private userService: UserService
) {
const { platforms } = this.dataService.fetchInfo();
this.platforms = platforms;
route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
@ -114,8 +118,15 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
);
const accountFilters: Filter[] = this.user.accounts.map(
({ id, name }) => {
({ id, name, platformId }) => {
let accountPlatformUrl = '';
for (const { id, url } of this.platforms) {
if (id === platformId) {
accountPlatformUrl = url;
}
}
return {
accountPlatformUrl,
id,
label: name,
type: 'ACCOUNT'

4
apps/client/src/styles.scss

@ -459,6 +459,10 @@ ngx-skeleton-loader {
}
}
.mat-mdc-optgroup-label {
font-weight: bold;
}
.mat-mdc-paginator {
background-color: rgba(var(--palette-foreground-base-light), 0.02);

9
libs/common/src/lib/interfaces/filter.interface.ts

@ -1,12 +1,19 @@
import { DataSource } from '@prisma/client';
export interface Filter {
id: string;
label?: string;
symbolDataSource?: DataSource;
accountPlatformUrl?: string;
type:
| 'ACCOUNT'
| 'ASSET_CLASS'
| 'ASSET_SUB_CLASS'
| 'CURRENCY'
| 'PRESET_ID'
| 'SEARCH_QUERY'
| 'SYMBOL'
| 'TAG';
| 'TAG'
| 'TYPE'
| 'YEAR';
}

38
libs/ui/src/lib/activities-filter/activities-filter.component.html

@ -38,7 +38,43 @@
*ngFor="let filter of filterGroup.filters"
[value]="filter.id"
>
{{ filter.label | gfSymbol }}
<ng-container *ngIf="filter.type === 'ACCOUNT'">
<gf-symbol-icon
*ngIf="filter.accountPlatformUrl"
[tooltip]="filter.label"
[url]="filter.accountPlatformUrl"
></gf-symbol-icon>
{{ filter.label }}
</ng-container>
<ng-container *ngIf="filter.type === 'CURRENCY'">
<b>{{ filter.id !== filter.label ? filter.id : '' }}</b>
{{ filter.label }}
</ng-container>
<ng-container *ngIf="filter.type === 'SYMBOL'">
<gf-symbol-icon
*ngIf="filter.symbolDataSource"
[dataSource]="filter.symbolDataSource"
[symbol]="filter.id"
[tooltip]="filter.label"
/>
<small class="text-muted">
{{ filter.id }}
</small>
{{ filter.label | gfSymbol }}
</ng-container>
<ng-container *ngIf="filter.type === 'TYPE'">
<gf-activity-type [activityType]="$any(filter.id)"></gf-activity-type>
</ng-container>
<ng-container
*ngIf="
filter.type !== 'ACCOUNT' &&
filter.type !== 'CURRENCY' &&
filter.type !== 'SYMBOL' &&
filter.type !== 'TYPE'
"
>
{{ filter.label }}
</ng-container>
</mat-option>
</mat-optgroup>
</mat-autocomplete>

4
libs/ui/src/lib/activities-filter/activities-filter.component.scss

@ -30,3 +30,7 @@
}
}
}
gf-symbol-icon {
display: contents;
}

4
libs/ui/src/lib/activities-filter/activities-filter.module.ts

@ -6,6 +6,8 @@ import { MatButtonModule } from '@angular/material/button';
import { MatChipsModule } from '@angular/material/chips';
import { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { GfActivityTypeModule } from '@ghostfolio/ui/activity-type/activity-type.module';
import { GfSymbolIconModule } from '@ghostfolio/client/components/symbol-icon/symbol-icon.module';
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { ActivitiesFilterComponent } from './activities-filter.component';
@ -15,6 +17,8 @@ import { ActivitiesFilterComponent } from './activities-filter.component';
exports: [ActivitiesFilterComponent],
imports: [
CommonModule,
GfActivityTypeModule,
GfSymbolIconModule,
GfSymbolModule,
MatAutocompleteModule,
MatButtonModule,

21
libs/ui/src/lib/activities-table/activities-table.component.ts

@ -10,6 +10,7 @@ import {
Output,
ViewChild
} from '@angular/core';
import { getCurrencySymbol } from '@angular/common';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
@ -307,15 +308,16 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy, OnInit {
fieldValueMap[activity.Account.id] = {
id: activity.Account.id,
label: activity.Account.name,
accountPlatformUrl: activity.Account.Platform?.url,
type: 'ACCOUNT'
};
}
if (activity.SymbolProfile?.currency) {
fieldValueMap[activity.SymbolProfile.currency] = {
id: activity.SymbolProfile.currency,
id: getCurrencySymbol(activity.SymbolProfile.currency, 'narrow'),
label: activity.SymbolProfile.currency,
type: 'TAG'
type: 'CURRENCY'
};
}
@ -325,21 +327,30 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy, OnInit {
) {
fieldValueMap[activity.SymbolProfile.symbol] = {
id: activity.SymbolProfile.symbol,
label: activity.SymbolProfile.symbol,
label: activity.SymbolProfile.name,
symbolDataSource: activity.SymbolProfile.dataSource,
type: 'SYMBOL'
};
}
for (const { name } of activity.tags) {
fieldValueMap[name] = {
id: name,
label: name,
type: 'TAG'
};
}
fieldValueMap[activity.type] = {
id: activity.type,
label: activity.type,
type: 'TAG'
type: 'TYPE'
};
fieldValueMap[format(new Date(activity.date), 'yyyy')] = {
id: format(new Date(activity.date), 'yyyy'),
label: format(new Date(activity.date), 'yyyy'),
type: 'TAG'
type: 'YEAR'
};
return Object.values(fieldValueMap);

2
libs/ui/src/lib/i18n.ts

@ -5,6 +5,7 @@ const locales = {
'Asia-Pacific': $localize`Asia-Pacific`,
ASSET_CLASS: $localize`Asset Class`,
ASSET_SUB_CLASS: $localize`Asset Sub Class`,
CURRENCY: $localize`Currency`,
CORE: $localize`Core`,
DATA_IMPORT_AND_EXPORT_TOOLTIP_BASIC: $localize`Switch to Ghostfolio Premium or Ghostfolio Open Source easily`,
DATA_IMPORT_AND_EXPORT_TOOLTIP_OSS: $localize`Switch to Ghostfolio Premium easily`,
@ -23,6 +24,7 @@ const locales = {
SATELLITE: $localize`Satellite`,
SYMBOL: $localize`Symbol`,
TAG: $localize`Tag`,
TYPE: $localize`Type`,
YEAR: $localize`Year`,
YEARS: $localize`Years`,

Loading…
Cancel
Save