Browse Source

Improve label of cash positions

pull/8007/head
Thomas Kaul 2 weeks ago
parent
commit
dc8aee6d36
  1. 3
      apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
  2. 3
      apps/client/src/app/pages/public/public-page.component.ts
  3. 36
      libs/common/src/lib/helper.spec.ts
  4. 16
      libs/common/src/lib/helper.ts
  5. 12
      libs/ui/src/lib/holdings-table/holdings-table.component.html
  6. 3
      libs/ui/src/lib/holdings-table/holdings-table.component.ts
  7. 14
      libs/ui/src/lib/treemap-chart/treemap-chart.component.ts

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

@ -11,6 +11,7 @@ import {
convertValuesToPercentagesOfTotal,
getAssetProfileIdentifier,
getCountryName,
getHoldingName,
isCashPosition
} from '@ghostfolio/common/helper';
import {
@ -533,7 +534,7 @@ export class GfAllocationsPageComponent implements OnInit {
value,
dataSource: position.assetProfile.dataSource,
isClickable: canOpenHoldingDetail(position),
name: position.assetProfile.name ?? ''
name: getHoldingName(position.assetProfile)
};
}
}

3
apps/client/src/app/pages/public/public-page.component.ts

@ -3,6 +3,7 @@ import {
convertValuesToPercentagesOfTotal,
getAssetProfileIdentifier,
getCountryName,
getHoldingName,
isCashPosition
} from '@ghostfolio/common/helper';
import {
@ -260,7 +261,7 @@ export class GfPublicPageComponent implements OnInit {
this.symbols[symbol] = {
symbol,
value,
name: position.assetProfile.name ?? symbol
name: getHoldingName(position.assetProfile)
};
}
}

36
libs/common/src/lib/helper.spec.ts

@ -7,6 +7,7 @@ import {
extractNumberFromString,
getCountryCodeFromCurrency,
getEmojiFlag,
getHoldingName,
getNumberFormatGroup,
getStringOrNull,
getStringOrUndefined,
@ -143,6 +144,41 @@ describe('Helper', () => {
});
});
describe('Get holding name', () => {
it('Cash position', () => {
expect(
getHoldingName({
assetSubClass: 'CASH',
assetSubClassLabel: 'Cash',
name: 'CHF',
symbol: 'CHF'
})
).toEqual('Cash (CHF)');
});
it('Holding with name', () => {
expect(
getHoldingName({
assetSubClass: 'STOCK',
assetSubClassLabel: 'Stock',
name: 'Apple Inc.',
symbol: 'AAPL'
})
).toEqual('Apple Inc.');
});
it('Holding without name', () => {
expect(
getHoldingName({
assetSubClass: 'STOCK',
assetSubClassLabel: 'Stock',
name: undefined,
symbol: 'AAPL'
})
).toEqual('AAPL');
});
});
describe('Get number format group', () => {
let languageGetter: jest.SpyInstance<string, [], any>;

16
libs/common/src/lib/helper.ts

@ -453,6 +453,22 @@ export function getEmojiFlag(aCountryCode: string) {
});
}
export function getHoldingName({
assetSubClass,
assetSubClassLabel,
name,
symbol
}: Pick<
PortfolioPosition['assetProfile'],
'assetSubClass' | 'assetSubClassLabel' | 'name' | 'symbol'
>) {
if (isCashPosition({ assetSubClass })) {
return `${assetSubClassLabel} (${symbol})`;
}
return name ?? symbol;
}
export function getLocale() {
return navigator.language ?? DEFAULT_LOCALE;
}

12
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -20,7 +20,7 @@
[countryCode]="getCountryCodeForCashPosition(element)"
[dataSource]="element.assetProfile.dataSource"
[symbol]="element.assetProfile.symbol"
[tooltip]="element.assetProfile.name"
[tooltip]="getHoldingName(element.assetProfile)"
/>
</td>
</ng-container>
@ -40,11 +40,11 @@
mat-cell
[class.w-100]="mode() === 'simple'"
>
<div class="text-truncate" [title]="element.assetProfile.name">
{{ element.assetProfile.name }}
@if (element.assetProfile.name === element.assetProfile.symbol) {
<span>({{ element.assetProfile.assetSubClassLabel }})</span>
}
<div
class="text-truncate"
[title]="getHoldingName(element.assetProfile)"
>
{{ getHoldingName(element.assetProfile) }}
</div>
@if (mode() === 'default') {
<div>

3
libs/ui/src/lib/holdings-table/holdings-table.component.ts

@ -1,6 +1,7 @@
import {
canOpenHoldingDetail,
getCountryCodeFromCurrency,
getHoldingName,
getLocale,
getLowercase,
isCashPosition
@ -89,6 +90,8 @@ export class GfHoldingsTableComponent {
return columns;
});
protected readonly getHoldingName = getHoldingName;
protected readonly isLoading = computed(() => {
return !this.holdings();
});

14
libs/ui/src/lib/treemap-chart/treemap-chart.component.ts

@ -3,7 +3,11 @@ import {
getIntervalFromDateRange
} from '@ghostfolio/common/calculation-helper';
import { getTooltipOptions } from '@ghostfolio/common/chart-helper';
import { canOpenHoldingDetail, getLocale } from '@ghostfolio/common/helper';
import {
canOpenHoldingDetail,
getHoldingName,
getLocale
} from '@ghostfolio/common/helper';
import {
AssetProfileIdentifier,
PortfolioPosition
@ -399,20 +403,18 @@ export class GfTreemapChartComponent
const raw = context.raw as GfTreemapDataPoint;
const allocationInPercentage = `${(raw._data.allocationInPercentage * 100).toFixed(2)}%`;
const name = raw._data.assetProfile.name;
const name = getHoldingName(raw._data.assetProfile);
const sign =
raw._data.netPerformancePercentWithCurrencyEffect > 0 ? '+' : '';
const symbol = raw._data.assetProfile.symbol;
const netPerformanceInPercentageWithSign = `${sign}${(raw._data.netPerformancePercentWithCurrencyEffect * 100).toFixed(2)}%`;
if (raw._data.valueInBaseCurrency !== null) {
const value = raw._data.valueInBaseCurrency;
return [
`${name ?? symbol} (${allocationInPercentage})`,
`${name} (${allocationInPercentage})`,
`${value?.toLocaleString(this.locale(), {
maximumFractionDigits: 2,
minimumFractionDigits: 2
@ -429,7 +431,7 @@ export class GfTreemapChartComponent
];
} else {
return [
`${name ?? symbol} (${allocationInPercentage})`,
`${name} (${allocationInPercentage})`,
'',
$localize`Performance`,
netPerformanceInPercentageWithSign

Loading…
Cancel
Save