Browse Source

Migrate spacing utility classes to Bootstrap 5

pull/8163/head
Thomas Kaul 3 days ago
parent
commit
ce1c9e6fd9
  1. 2
      apps/client/src/app/app.component.html
  2. 8
      apps/client/src/app/components/access-table/access-table.component.html
  3. 8
      apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html
  4. 4
      apps/client/src/app/components/admin-market-data/admin-market-data.html
  5. 16
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
  6. 4
      apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html
  7. 10
      apps/client/src/app/components/admin-overview/admin-overview.html
  8. 4
      apps/client/src/app/components/admin-platform/admin-platform.component.html
  9. 6
      apps/client/src/app/components/admin-settings/admin-settings.component.html
  10. 4
      apps/client/src/app/components/admin-tag/admin-tag.component.html
  11. 14
      apps/client/src/app/components/admin-users/admin-users.html
  12. 4
      apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html
  13. 10
      apps/client/src/app/components/footer/footer.component.html
  14. 14
      apps/client/src/app/components/header/header.component.html
  15. 16
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html
  16. 4
      apps/client/src/app/components/home-overview/home-overview.html
  17. 2
      apps/client/src/app/components/home-watchlist/home-watchlist.html
  18. 2
      apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html
  19. 22
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html
  20. 1
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.scss
  21. 6
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html
  22. 10
      apps/client/src/app/components/rule/rule.component.html
  23. 30
      apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html
  24. 2
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
  25. 4
      apps/client/src/app/components/user-account-access/user-account-access.html
  26. 2
      apps/client/src/app/components/user-account-membership/user-account-membership.html
  27. 48
      apps/client/src/app/components/user-account-settings/user-account-settings.html
  28. 4
      apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html
  29. 2
      apps/client/src/app/pages/about/oss-friends/oss-friends-page.html
  30. 6
      apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html
  31. 2
      apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html
  32. 2
      apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.html
  33. 2
      apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.html
  34. 2
      apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.html
  35. 2
      apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.html
  36. 6
      apps/client/src/app/pages/faq/overview/faq-overview-page.html
  37. 6
      apps/client/src/app/pages/faq/saas/saas-page.html
  38. 4
      apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html
  39. 14
      apps/client/src/app/pages/features/features-page.html
  40. 26
      apps/client/src/app/pages/landing/landing-page.html
  41. 8
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
  42. 20
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html
  43. 18
      apps/client/src/app/pages/portfolio/allocations/allocations-page.html
  44. 62
      apps/client/src/app/pages/portfolio/analysis/analysis-page.html
  45. 4
      apps/client/src/app/pages/portfolio/fire/fire-page.html
  46. 6
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html
  47. 60
      apps/client/src/app/pages/pricing/pricing-page.html
  48. 2
      apps/client/src/app/pages/register/register-page.html
  49. 6
      apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html
  50. 40
      apps/client/src/styles/bootstrap.scss
  51. 8
      libs/ui/src/lib/access-level-icon/access-level-icon.component.html
  52. 6
      libs/ui/src/lib/account-balances/account-balances.component.html
  53. 4
      libs/ui/src/lib/account-selector/account-selector.component.html
  54. 12
      libs/ui/src/lib/accounts-table/accounts-table.component.html
  55. 32
      libs/ui/src/lib/activities-table/activities-table.component.html
  56. 2
      libs/ui/src/lib/assistant/assistant.html
  57. 2
      libs/ui/src/lib/benchmark/benchmark.component.html
  58. 4
      libs/ui/src/lib/currency-selector/currency-selector.component.html
  59. 4
      libs/ui/src/lib/fear-and-greed-index/fear-and-greed-index.component.html
  60. 8
      libs/ui/src/lib/fire-calculator/fire-calculator.component.html
  61. 6
      libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html
  62. 2
      libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html
  63. 2
      libs/ui/src/lib/logo/logo.component.html
  64. 2
      libs/ui/src/lib/membership-card/membership-card.component.html
  65. 2
      libs/ui/src/lib/notifications/prompt-dialog/prompt-dialog.html
  66. 4
      libs/ui/src/lib/page-tabs/page-tabs.component.html
  67. 2
      libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.html
  68. 2
      libs/ui/src/lib/tags-selector/tags-selector.component.html
  69. 10
      libs/ui/src/lib/value/value.component.html

2
apps/client/src/app/app.component.html

@ -10,7 +10,7 @@
(click)="onCreateAccount()"
>
<span i18n>You are using the Live Demo.</span>
<span class="a ml-2 p-1" i18n>Create Account</span>
<span class="a ms-2 p-1" i18n>Create Account</span>
</div>
</a>
}

8
apps/client/src/app/components/access-table/access-table.component.html

@ -70,7 +70,7 @@
[routerLink]="accessDialogRouterLinks().get(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<ion-icon class="me-2" name="create-outline" />
<span><ng-container i18n>Edit</ng-container>...</span>
</span>
</a>
@ -78,7 +78,7 @@
@if (element.type === 'PUBLIC') {
<button mat-menu-item (click)="onCopyUrlToClipboard(element.id)">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="copy-outline" />
<ion-icon class="me-2" name="copy-outline" />
<span i18n>Copy link to clipboard</span>
</span>
</button>
@ -93,10 +93,10 @@
<button mat-menu-item (click)="onDeleteAccess(element.id)">
<span class="align-items-center d-flex">
@if (isReceivedAccess()) {
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
} @else {
<ion-icon class="mr-2" name="remove-circle-outline" />
<ion-icon class="me-2" name="remove-circle-outline" />
<span i18n>Revoke</span>
}
</span>

8
apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html

@ -41,7 +41,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="reader-outline" />
<div class="d-none d-sm-block ml-2" i18n>Overview</div>
<div class="d-none d-sm-block ms-2" i18n>Overview</div>
</ng-template>
<div class="container mt-3 p-0">
<div class="row w-100">
@ -132,7 +132,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="albums-outline" />
<div class="d-none d-sm-block ml-2" i18n>Holdings</div>
<div class="d-none d-sm-block ms-2" i18n>Holdings</div>
</ng-template>
<gf-holdings-table
[hasPermissionToOpenDetails]="false"
@ -143,7 +143,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="swap-vertical-outline" />
<div class="d-none d-sm-block ml-2" i18n>Activities</div>
<div class="d-none d-sm-block ms-2" i18n>Activities</div>
</ng-template>
<gf-activities-table
[baseCurrency]="user?.settings?.baseCurrency"
@ -175,7 +175,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="cash-outline" />
<div class="d-none d-sm-block ml-2" i18n>Cash Balances</div>
<div class="d-none d-sm-block ms-2" i18n>Cash Balances</div>
</ng-template>
<gf-account-balances
[accountBalances]="accountBalances"

4
apps/client/src/app/components/admin-market-data/admin-market-data.html

@ -311,7 +311,7 @@
"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<ion-icon class="me-2" name="create-outline" />
<span><ng-container i18n>Edit</ng-container>...</span>
</span>
</a>
@ -334,7 +334,7 @@
"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

16
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html

@ -4,7 +4,7 @@
assetProfile?.name ?? data.symbol
}}</span>
<button
class="ml-1 no-min-width px-2"
class="ms-1 no-min-width px-2"
mat-button
type="button"
[matMenuTriggerFor]="assetProfileActionsMenu"
@ -112,7 +112,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="reader-outline" />
<div class="d-none d-sm-block ml-2" i18n>Overview</div>
<div class="d-none d-sm-block ms-2" i18n>Overview</div>
</ng-template>
<div class="container px-0 py-3">
<div class="row w-100">
@ -138,7 +138,7 @@
/>
</mat-form-field>
<button
class="ml-2 no-min-width px-2"
class="ms-2 no-min-width px-2"
color="primary"
mat-flat-button
type="submit"
@ -155,7 +155,7 @@
<ng-container i18n>Apply</ng-container>
</button>
<button
class="ml-2 no-min-width px-2"
class="ms-2 no-min-width px-2"
mat-button
type="button"
(click)="onCancelEditAssetProfileIdentifierMode()"
@ -493,7 +493,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="server-outline" />
<div class="d-none d-sm-block ml-2" i18n>Historical Market Data</div>
<div class="d-none d-sm-block ms-2" i18n>Historical Market Data</div>
</ng-template>
<div class="container mt-3 p-0">
<div class="no-gutters row w-100">
@ -516,7 +516,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="git-compare-outline" />
<div class="d-none d-sm-block ml-2" i18n>Splits</div>
<div class="d-none d-sm-block ms-2" i18n>Splits</div>
</ng-template>
<div class="container mt-3 p-0">
<div class="no-gutters row w-100">
@ -571,7 +571,7 @@
[matDatepicker]="dateOfSplit"
/>
<mat-datepicker-toggle
class="mr-2"
class="me-2"
matSuffix
[for]="dateOfSplit"
>
@ -632,7 +632,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="code-slash-outline" />
<div class="d-none d-sm-block ml-2" i18n>Scraper Configuration</div>
<div class="d-none d-sm-block ms-2" i18n>Scraper Configuration</div>
</ng-template>
<div class="container mt-3 p-0">
<div [formGroup]="assetProfileForm">

4
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html

@ -14,9 +14,9 @@
>
<mat-radio-button name="auto" value="auto" />
<label class="m-0" for="auto" i18n>Search</label>
<mat-radio-button class="ml-3" name="manual" value="manual" />
<mat-radio-button class="ms-3" name="manual" value="manual" />
<label class="m-0" for="manual" i18n>Add Manually</label>
<mat-radio-button class="ml-3" name="currency" value="currency" />
<mat-radio-button class="ms-3" name="currency" value="currency" />
<label class="m-0" for="currency" i18n>Add Currency</label>
</mat-radio-group>
</div>

10
apps/client/src/app/components/admin-overview/admin-overview.html

@ -112,7 +112,7 @@
mat-flat-button
(click)="onSetSystemMessage()"
>
<ion-icon class="mr-1" name="information-circle-outline" />
<ion-icon class="me-1" name="information-circle-outline" />
<span i18n>Set Message</span>
</button>
}
@ -130,12 +130,12 @@
mat-flat-button
(click)="onSyncDemoUserAccount()"
>
<ion-icon class="mr-1" name="sync-outline" />
<ion-icon class="me-1" name="sync-outline" />
<span i18n>Sync Demo User Account</span>
</button>
}
<button color="warn" mat-flat-button (click)="onFlushCache()">
<ion-icon class="mr-1" name="close-circle-outline" />
<ion-icon class="me-1" name="close-circle-outline" />
<span i18n>Flush Cache</span>
</button>
</div>
@ -232,7 +232,7 @@
(click)="onDeleteCoupon(element.code)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>
@ -264,7 +264,7 @@
</mat-card-content>
<mat-card-actions align="end">
<form #couponForm="ngForm" class="align-items-stretch d-flex">
<mat-form-field appearance="outline" class="mr-1 without-hint">
<mat-form-field appearance="outline" class="me-1 without-hint">
<mat-select
name="duration"
[value]="couponDuration"

4
apps/client/src/app/components/admin-platform/admin-platform.component.html

@ -79,7 +79,7 @@
<mat-menu #platformMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="onUpdatePlatform(element)">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<ion-icon class="me-2" name="create-outline" />
<span><ng-container i18n>Edit</ng-container>...</span>
</span>
</button>
@ -90,7 +90,7 @@
(click)="onDeletePlatform(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

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

@ -74,12 +74,12 @@
>
Ghostfolio Premium
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/>
@if (isGhostfolioApiKeyValid === false) {
<span
class="badge badge-pill badge-secondary ml-2 text-uppercase"
class="badge badge-pill badge-secondary ms-2 text-uppercase"
i18n
>popular</span
>
@ -193,7 +193,7 @@
>
<button mat-menu-item (click)="onRemoveGhostfolioApiKey()">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Remove API key</span>
</span>
</button>

4
apps/client/src/app/components/admin-tag/admin-tag.component.html

@ -113,7 +113,7 @@
(click)="onUpdateTag(element)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<ion-icon class="me-2" name="create-outline" />
<span><ng-container i18n>Edit</ng-container>...</span>
</span>
</button>
@ -128,7 +128,7 @@
(click)="onDeleteTag(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

14
apps/client/src/app/components/admin-users/admin-users.html

@ -29,7 +29,7 @@
>
@if (element.subscription?.expiresAt) {
<gf-premium-indicator
class="ml-1"
class="ms-1"
i18n-title
title="Expires {{
formatRelativeTime({
@ -195,12 +195,12 @@
<div class="align-items-center d-flex">
@if (element.lastRequestClient) {
<ion-icon
class="mr-1"
class="me-1"
[name]="requestClientIcons[element.lastRequestClient]"
[title]="translate(element.lastRequestClient)"
/>
} @else {
<ion-icon class="hidden mr-1" />
<ion-icon class="hidden me-1" />
}
{{
formatRelativeTime({
@ -238,7 +238,7 @@
[routerLink]="routerLinkAdminControlUsers.concat(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="person-outline" />
<ion-icon class="me-2" name="person-outline" />
<span
><ng-container i18n>View Details</ng-container>...</span
>
@ -247,7 +247,7 @@
@if (hasPermissionToImpersonateAllUsers) {
<button mat-menu-item (click)="onImpersonateUser(element.id)">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="contract-outline" />
<ion-icon class="me-2" name="contract-outline" />
<span i18n>Impersonate User</span>
</span>
</button>
@ -257,7 +257,7 @@
(click)="onGenerateAccessToken(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="key-outline" />
<ion-icon class="me-2" name="key-outline" />
<span i18n>Generate Security Token</span>
</span>
</button>
@ -273,7 +273,7 @@
(click)="onDeleteUser(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

4
apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html

@ -5,7 +5,7 @@
>
<span i18n>Performance</span>
@if (user()?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
</div>
@ -31,7 +31,7 @@
@if (hasPermissionToAccessAdminControl) {
<mat-option [routerLink]="routerLinkAdminControlMarketData">
<div class="align-items-center d-flex">
<ion-icon class="mr-2 text-muted" name="arrow-forward-outline" />
<ion-icon class="me-2 text-muted" name="arrow-forward-outline" />
<span i18n>Manage Benchmarks</span>
</div>
</mat-option>

10
apps/client/src/app/components/footer/footer.component.html

@ -70,7 +70,7 @@
href="https://status.ghostfol.io"
target="_blank"
title="Ghostfolio Status"
>Status<ion-icon class="ml-1" name="open-outline"
>Status<ion-icon class="ms-1" name="open-outline"
/></a>
</li>
}
@ -85,7 +85,7 @@
href="https://github.com/ghostfolio/ghostfolio"
target="_blank"
title="Find Ghostfolio on GitHub"
>GitHub<ion-icon class="ml-1" name="open-outline"
>GitHub<ion-icon class="ms-1" name="open-outline"
/></a>
</li>
<li>
@ -94,7 +94,7 @@
href="https://linkedin.com/company/ghostfolio"
target="_blank"
title="Follow Ghostfolio on LinkedIn"
>LinkedIn<ion-icon class="ml-1" name="open-outline"
>LinkedIn<ion-icon class="ms-1" name="open-outline"
/></a>
</li>
<li>
@ -103,7 +103,7 @@
href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"
target="_blank"
title="Join the Ghostfolio Slack community"
>Slack<ion-icon class="ml-1" name="open-outline"
>Slack<ion-icon class="ms-1" name="open-outline"
/></a>
</li>
<li>
@ -112,7 +112,7 @@
href="https://x.com/ghostfolio_"
target="_blank"
title="Follow Ghostfolio on X (formerly Twitter)"
>X (formerly Twitter)<ion-icon class="ml-1" name="open-outline"
>X (formerly Twitter)<ion-icon class="ms-1" name="open-outline"
/></a>
</li>
<li>&nbsp;</li>

14
apps/client/src/app/components/header/header.component.html

@ -105,7 +105,7 @@
<span class="align-items-center d-flex">
<span i18n>Pricing</span>
@if (currentRoute() !== routePricing && hasPromotion()) {
<span class="badge badge-warning ml-1">%</span>
<span class="badge badge-warning ms-1">%</span>
}
</span>
</a>
@ -198,7 +198,7 @@
}
</span>
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false" /></span
></a>
<hr class="m-0" />
@ -207,7 +207,7 @@
<button mat-menu-item (click)="impersonateAccount(null)">
<span class="align-items-center d-flex">
<ion-icon
class="mr-2"
class="me-2"
[name]="
hasImpersonationId
? 'radio-button-off-outline'
@ -221,7 +221,7 @@
<button mat-menu-item (click)="impersonateAccount(accessItem.id)">
<span class="align-items-center d-flex">
<ion-icon
class="mr-2"
class="me-2"
name="square-outline"
[name]="
accessItem.id === impersonationId
@ -313,7 +313,7 @@
<span class="align-items-center d-flex">
<span i18n>Pricing</span>
@if (currentRoute() !== routePricing && hasPromotion()) {
<span class="badge badge-warning ml-1">%</span>
<span class="badge badge-warning ms-1">%</span>
}
</span>
</a>
@ -388,7 +388,7 @@
<span class="align-items-center d-flex">
<span i18n>Pricing</span>
@if (currentRoute() !== routePricing && hasPromotion()) {
<span class="badge badge-warning ml-1">%</span>
<span class="badge badge-warning ms-1">%</span>
}
</span>
</a>
@ -427,7 +427,7 @@
</button>
</li>
@if (currentRoute() !== 'register' && hasPermissionToCreateUser) {
<li class="list-inline-item ml-1">
<li class="list-inline-item ms-1">
<a
class="d-none d-sm-block px-3 rounded"
color="primary"

16
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html

@ -46,7 +46,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="reader-outline" />
<div class="d-none d-sm-block ml-2" i18n>Overview</div>
<div class="d-none d-sm-block ms-2" i18n>Overview</div>
</ng-template>
<div class="container mt-3 p-0">
<div class="row w-100">
@ -371,7 +371,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="swap-vertical-outline" />
<div class="d-none d-sm-block ml-2" i18n>Activities</div>
<div class="d-none d-sm-block ms-2" i18n>Activities</div>
</ng-template>
<gf-activities-table
[baseCurrency]="data.baseCurrency"
@ -405,7 +405,7 @@
<mat-tab>
<ng-template mat-tab-label>
<ion-icon name="wallet-outline" />
<div class="d-none d-sm-block ml-2" i18n>Accounts</div>
<div class="d-none d-sm-block ms-2" i18n>Accounts</div>
</ng-template>
<gf-accounts-table
[accounts]="accounts"
@ -425,9 +425,9 @@
<mat-tab [disabled]="!hasPermissionToReadMarketDataOfOwnAssetProfile">
<ng-template mat-tab-label>
<ion-icon name="server-outline" />
<div class="d-none d-sm-block ml-2" i18n>Market Data</div>
<div class="d-none d-sm-block ms-2" i18n>Market Data</div>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
}
</ng-template>
<gf-historical-market-data-editor
@ -459,7 +459,7 @@
mat-stroked-button
(click)="onCloseHolding()"
>
<ion-icon class="mr-1" name="arrow-down-circle-outline" /><span
<ion-icon class="me-1" name="arrow-down-circle-outline" /><span
i18n
>Close Holding</span
>
@ -473,7 +473,7 @@
color="warn"
mat-stroked-button
[href]="reportDataGlitchMailHref"
><ion-icon class="mr-1" name="flag-outline" /><span i18n
><ion-icon class="me-1" name="flag-outline" /><span i18n
>Report Data Glitch</span
>...</a
>
@ -488,7 +488,7 @@
)
"
(click)="onClose()"
><ion-icon class="mr-1" name="create-outline" /><span i18n
><ion-icon class="me-1" name="create-outline" /><span i18n
>Manage Asset Profile</span
>...</a
>

4
apps/client/src/app/components/home-overview/home-overview.html

@ -70,7 +70,7 @@
<gf-line-chart
class="position-absolute"
unit="%"
[class.pr-3]="deviceType() === 'mobile'"
[class.pe-3]="deviceType() === 'mobile'"
[colorScheme]="user()?.settings?.colorScheme"
[hidden]="historicalDataItems()?.length === 0"
[historicalDataItems]="historicalDataItems()"
@ -96,7 +96,7 @@
</div>
</div>
@if (showExperimentalHoldings()) {
<div class="col-xl-4 d-none d-xl-block ml-5 p-0 position-relative">
<div class="col-xl-4 d-none d-xl-block ms-5 p-0 position-relative">
<mat-card
appearance="outlined"
class="h-100 holdings position-absolute w-100"

2
apps/client/src/app/components/home-watchlist/home-watchlist.html

@ -3,7 +3,7 @@
<span class="align-items-center d-flex justify-content-center">
<span i18n>Watchlist</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</span>
</h1>

2
apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html

@ -40,7 +40,7 @@
href="../api/v1/auth/google"
mat-stroked-button
><img
class="mr-2"
class="me-2"
src="../assets/icons/google.svg"
style="height: 1rem"
/><span i18n>Sign in with Google</span></a

22
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html

@ -27,7 +27,7 @@
other {activities}
}</ng-container>
<span
class="align-items-center d-none d-sm-flex ml-1"
class="align-items-center d-none d-sm-flex ms-1"
matTooltipPosition="above"
[matTooltip]="buyAndSellActivitiesTooltip"
>
@ -116,7 +116,7 @@
<div class="flex-grow-1 text-truncate" i18n>Fees</div>
<div class="d-flex justify-content-end">
@if (isNumber(summary?.fees)) {
<span class="mr-1">-</span>
<span class="me-1">-</span>
}
<gf-value
class="justify-content-end"
@ -154,7 +154,7 @@
PerformanceCalculationType.ROAI
) {
<abbr
class="d-none d-sm-inline-block initialism ml-2 text-muted"
class="d-none d-sm-inline-block initialism ms-2 text-muted"
i18n-title
title="Return on Average Investment (total return with dividends)"
>(ROAI)</abbr
@ -214,7 +214,7 @@
>
@if (hasHoldingsBreakdown) {
<span
class="align-items-center caret-container d-inline-flex justify-content-center ml-n3"
class="align-items-center caret-container d-inline-flex justify-content-center"
>
<ion-icon
class="caret text-muted"
@ -230,7 +230,7 @@
user?.settings?.isExperimentalFeatures
) {
<gf-value
class="d-lg-inline-block d-none ml-2 small text-muted"
class="d-lg-inline-block d-none ms-2 small text-muted"
[isLoading]="isLoading"
[isPercent]="true"
[locale]="locale"
@ -292,7 +292,7 @@
>
@if (hasCashBreakdown) {
<span
class="align-items-center caret-container d-inline-flex justify-content-center ml-n3"
class="align-items-center caret-container d-inline-flex justify-content-center"
>
<ion-icon
class="caret text-muted"
@ -308,7 +308,7 @@
user?.settings?.isExperimentalFeatures
) {
<gf-value
class="d-lg-inline-block d-none ml-2 small text-muted"
class="d-lg-inline-block d-none ms-2 small text-muted"
[isLoading]="isLoading"
[isPercent]="true"
[locale]="locale"
@ -371,7 +371,7 @@
user?.settings?.isExperimentalFeatures
) {
<gf-value
class="d-lg-inline-block d-none ml-2 small text-muted"
class="d-lg-inline-block d-none ms-2 small text-muted"
[isLoading]="isLoading"
[isPercent]="true"
[locale]="locale"
@ -398,7 +398,7 @@
<div class="flex-grow-1 text-truncate" i18n>Liabilities</div>
<div class="d-flex justify-content-end">
@if (isNumber(summary?.liabilitiesInBaseCurrency)) {
<span class="mr-1">-</span>
<span class="me-1">-</span>
}
<gf-value
class="justify-content-end"
@ -456,7 +456,7 @@
user?.settings?.isExperimentalFeatures
) {
<gf-value
class="d-lg-inline-block d-none ml-2 small text-muted"
class="d-lg-inline-block d-none ms-2 small text-muted"
[isLoading]="isLoading"
[isPercent]="true"
[locale]="locale"
@ -486,7 +486,7 @@
user?.subscription?.type !== 'Basic'
) {
<ion-icon
class="mr-1 text-muted"
class="me-1 text-muted"
name="ellipsis-horizontal-circle-outline"
/>
}

1
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.scss

@ -2,6 +2,7 @@
display: block;
.caret-container {
margin-left: -1rem;
width: 1rem;
.caret {

6
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html

@ -15,7 +15,7 @@
<h6 class="d-flex mb-0">
<ng-container i18n>Threshold range</ng-container>:
<gf-value
class="ml-1"
class="ms-1"
[isPercent]="threshold.unit === '%'"
[locale]="data.locale"
[precision]="2"
@ -61,7 +61,7 @@
<h6 class="d-flex mb-0">
<ng-container i18n>Threshold Min</ng-container>:
<gf-value
class="ml-1"
class="ms-1"
[isPercent]="threshold.unit === '%'"
[locale]="data.locale"
[precision]="2"
@ -99,7 +99,7 @@
<h6 class="d-flex mb-0">
<ng-container i18n>Threshold Max</ng-container>:
<gf-value
class="ml-1"
class="ms-1"
[isPercent]="threshold.unit === '%'"
[locale]="data.locale"
[precision]="2"

10
apps/client/src/app/components/rule/rule.component.html

@ -4,7 +4,7 @@
<div>
<ngx-skeleton-loader
animation="pulse"
class="mr-2"
class="me-2"
[theme]="{
height: '2rem',
width: '2rem'
@ -13,7 +13,7 @@
</div>
} @else {
<div
class="align-items-center d-flex icon-container mr-2 px-2"
class="align-items-center d-flex icon-container me-2 px-2"
[class]="{
okay: rule?.value === true,
warn: rule?.value === false
@ -65,7 +65,7 @@
@if (rule?.isActive && rule?.configuration) {
<button mat-menu-item (click)="onCustomizeRule(rule)">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="options-outline" />
<ion-icon class="me-2" name="options-outline" />
<span><ng-container i18n>Customize</ng-container>...</span>
</span>
</button>
@ -74,12 +74,12 @@
<button mat-menu-item (click)="onUpdateRule(rule)">
@if (rule?.isActive) {
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="remove-circle-outline" />
<ion-icon class="me-2" name="remove-circle-outline" />
<span i18n>Deactivate</span>
</span>
} @else {
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="add-circle-outline" />
<ion-icon class="me-2" name="add-circle-outline" />
<span i18n>Activate</span>
</span>
}

30
apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html

@ -9,7 +9,7 @@
<div>
<h5 class="align-items-center d-flex justify-content-center mb-3">
<span>Ghostfolio Premium</span>
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
</h5>
<div class="font-weight-normal h5 mb-3 text-center" i18n>
Are you an ambitious investor who needs the full picture?
@ -18,29 +18,29 @@
Upgrade to Ghostfolio Premium today and gain access to exclusive
features to enhance your investment experience:
</p>
<ul class="list-unstyled mb-3 pl-3">
<ul class="list-unstyled mb-3 ps-3">
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Summary</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Allocations</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Performance Benchmarks</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>FIRE Calculator</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Professional Data Provider</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>and more Features...</span>
</li>
</ul>
@ -68,7 +68,7 @@
(click)="closeDialog()"
>
<span i18n>Upgrade Plan</span>
<ion-icon class="ml-1" name="arrow-forward-outline" />
<ion-icon class="ms-1" name="arrow-forward-outline" />
</a>
</div>
}
@ -86,7 +86,7 @@
<p class="my-2 text-center" i18n>with</p>
<h5 class="align-items-center d-flex justify-content-center">
<span>Ghostfolio Premium</span>
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
</h5>
</div>
</div>
@ -108,7 +108,7 @@
(click)="closeDialog()"
>
<span i18n>Upgrade Plan</span>
<ion-icon class="ml-1" name="arrow-forward-outline" />
<ion-icon class="ms-1" name="arrow-forward-outline" />
</a>
</div>
}
@ -122,7 +122,7 @@
<div>
<h5 class="align-items-center d-flex justify-content-center">
<span>Ghostfolio Premium</span>
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
</h5>
<p class="my-2 text-center" i18n>for</p>
<div class="font-weight-normal h5 text-center">
@ -151,7 +151,7 @@
(click)="closeDialog()"
>
<span i18n>Upgrade Plan</span>
<ion-icon class="ml-1" name="arrow-forward-outline" />
<ion-icon class="ms-1" name="arrow-forward-outline" />
</a>
</div>
}
@ -161,7 +161,7 @@
mat-dialog-title
>
<span>Ghostfolio Premium</span>
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
</h1>
<div class="flex-grow-1 pt-0" mat-dialog-content>
<div class="align-items-center d-flex h-100 justify-content-center">
@ -191,7 +191,7 @@
(click)="closeDialog()"
>
<span i18n>Join now</span>
<ion-icon class="ml-1" name="arrow-forward-outline" />
<ion-icon class="ms-1" name="arrow-forward-outline" />
</a>
</div>
}

2
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html

@ -58,7 +58,7 @@
[matDatepicker]="expiresAt"
[min]="minExpiresAt"
/>
<mat-datepicker-toggle class="mr-2" matSuffix [for]="expiresAt">
<mat-datepicker-toggle class="me-2" matSuffix [for]="expiresAt">
<ion-icon
class="text-muted"
matDatepickerToggleIcon

4
apps/client/src/app/components/user-account-access/user-account-access.html

@ -31,7 +31,7 @@
/>
</button>
</mat-form-field>
<div class="pl-2">
<div class="ps-2">
<button
color="warn"
mat-flat-button
@ -65,7 +65,7 @@
<h1 class="align-items-center d-flex h3 justify-content-center mb-3">
<span i18n>Granted Access</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</h1>
<gf-access-table

2
apps/client/src/app/components/user-account-membership/user-account-membership.html

@ -57,7 +57,7 @@
[href]="trySubscriptionMailHref"
><span i18n>Try Premium</span>
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/>
</a>

48
apps/client/src/app/components/user-account-settings/user-account-settings.html

@ -12,7 +12,7 @@
<div class="align-items-center d-flex pt-1 pt-1 w-50">
<ng-container i18n>Base Currency</ng-container>
</div>
<div class="pl-1 w-50" [formGroup]="baseCurrencyForm">
<div class="ps-1 w-50" [formGroup]="baseCurrencyForm">
<mat-form-field
appearance="outline"
class="w-100"
@ -35,7 +35,7 @@
<div class="align-items-center d-flex pt-1 pt-1 w-50">
<ng-container i18n>Performance Calculation</ng-container>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-select
name="performanceCalculationType"
@ -57,7 +57,7 @@
</div>
}
<div class="align-items-center d-flex mb-2">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div i18n>Language</div>
@if (isCommunityLanguage()) {
<div class="hint-text text-muted" i18n>
@ -72,7 +72,7 @@
</div>
}
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-select
name="language"
@ -152,13 +152,13 @@
</div>
</div>
<div class="align-items-center d-flex mb-4">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div i18n>Locale</div>
<div class="hint-text text-muted">
<ng-container i18n>Date and number format</ng-container>
</div>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-form-field
appearance="outline"
class="w-100 with-value-hint"
@ -197,10 +197,10 @@
</div>
</div>
<div class="d-flex">
<div class="align-items-center d-flex pr-1 pt-1 w-50">
<div class="align-items-center d-flex pe-1 pt-1 w-50">
<ng-container i18n>Appearance</ng-container>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-select
class="with-placeholder-as-option"
@ -222,14 +222,14 @@
</div>
</div>
<div class="align-items-center d-flex mt-4 py-1">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div i18n>Presenter View</div>
<div class="hint-text text-muted" i18n>
Protection for sensitive information like absolute performances and
quantity values
</div>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-slide-toggle
color="primary"
hideIcon="true"
@ -240,13 +240,13 @@
</div>
</div>
<div class="d-flex mt-4 py-1">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div i18n>Zen Mode</div>
<div class="hint-text text-muted" i18n>
Distraction-free experience for turbulent times
</div>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-slide-toggle
color="primary"
hideIcon="true"
@ -257,11 +257,11 @@
</div>
</div>
<div class="align-items-center d-flex mt-4 py-1">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div i18n>Biometric Authentication</div>
<div class="hint-text text-muted" i18n>Sign in with fingerprint</div>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-slide-toggle
color="primary"
hideIcon="true"
@ -274,13 +274,13 @@
</div>
</div>
<div class="align-items-center d-flex mt-4 py-1">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div i18n>Experimental Features</div>
<div class="hint-text text-muted" i18n>
Sneak peek at upcoming functionality
</div>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-slide-toggle
color="primary"
hideIcon="true"
@ -292,13 +292,13 @@
</div>
@if (deviceType() !== 'mobile' && hasPermissionToEnableGhostfolioAi) {
<div class="align-items-center d-flex mt-4 py-1">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
<div>Ghostfolio AI</div>
<div class="hint-text text-muted" i18n>
Powered by third-party AI providers
</div>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<mat-slide-toggle
color="primary"
hideIcon="true"
@ -310,10 +310,10 @@
</div>
}
<div class="align-items-center d-flex mt-4 py-1">
<div class="pr-1 w-50">
<div class="pe-1 w-50">
Ghostfolio <ng-container i18n>User ID</ng-container>
</div>
<div class="pl-1 w-50">
<div class="ps-1 w-50">
<gf-value
class="text-monospace"
[enableCopyToClipboardButton]="true"
@ -323,8 +323,8 @@
</div>
</div>
<div class="align-items-center d-flex py-1">
<div class="pr-1 w-50"></div>
<div class="pl-1 text-monospace w-50">
<div class="pe-1 w-50"></div>
<div class="ps-1 text-monospace w-50">
<button color="primary" i18n mat-flat-button (click)="onExport()">
Export Data
</button>
@ -335,8 +335,8 @@
) {
<hr class="mt-5" />
<div class="d-flex py-1">
<div class="pr-1 text-danger w-50" i18n>Danger Zone</div>
<div class="pl-1 w-50">
<div class="pe-1 text-danger w-50" i18n>Danger Zone</div>
<div class="ps-1 w-50">
@if (
hasPermissionToDeleteOwnUser &&
hasPermissionToUpdateOwnAccessToken

4
apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html

@ -1,6 +1,6 @@
<div class="align-items-center d-flex justify-content-end" mat-dialog-title>
<button
class="ml-1 no-min-width px-2"
class="ms-1 no-min-width px-2"
mat-button
type="button"
[matMenuTriggerFor]="userDetailActionsMenu"
@ -229,7 +229,7 @@
>
@if (element.price === null) {
<span>–</span>
<span class="ml-1">{{ baseCurrency }}</span>
<span class="ms-1">{{ baseCurrency }}</span>
} @else {
<gf-value
class="d-inline-block justify-content-end"

2
apps/client/src/app/pages/about/oss-friends/oss-friends-page.html

@ -27,7 +27,7 @@
<span
><ng-container i18n>Visit</ng-container>
{{ ossFriend.name }}</span
><ion-icon class="ml-1" name="arrow-forward-outline" />
><ion-icon class="ms-1" name="arrow-forward-outline" />
</a>
</mat-card-actions>
</mat-card>

6
apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html

@ -38,7 +38,7 @@
type="number"
(keydown.enter)="$event.stopPropagation()"
/>
<span class="ml-2" matTextSuffix>{{
<span class="ms-2" matTextSuffix>{{
accountForm.get('currency')?.value
}}</span>
</mat-form-field>
@ -48,7 +48,7 @@
<mat-label i18n>Platform</mat-label>
@if (selectedPlatform) {
<gf-entity-logo
class="ml-3"
class="ms-3"
matPrefix
[hasPlaceholder]="true"
[tooltip]="selectedPlatform.name ?? ''"
@ -71,7 +71,7 @@
<mat-option [value]="platformEntry">
<span class="d-flex">
<gf-entity-logo
class="mr-1"
class="me-1"
[hasPlaceholder]="true"
[tooltip]="platformEntry.name ?? ''"
[url]="platformEntry.url"

2
apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html

@ -29,7 +29,7 @@
type="number"
(keydown.enter)="$event.stopPropagation()"
/>
<span class="ml-2" matTextSuffix>{{ currency }}</span>
<span class="ms-2" matTextSuffix>{{ currency }}</span>
</mat-form-field>
</div>
</div>

2
apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.html

@ -18,7 +18,7 @@
<span class="align-items-center d-inline-flex"
><strong>Ghostfolio Premium</strong>
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/>
</span>

2
apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.html

@ -19,7 +19,7 @@
<span class="align-items-center d-inline-flex"
><strong>Ghostfolio Premium</strong>
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/>
</span>

2
apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.html

@ -19,7 +19,7 @@
<span class="align-items-center d-inline-flex"
>Ghostfolio Premium
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/>
</span>

2
apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.html

@ -18,7 +18,7 @@
<span class="align-items-center d-inline-flex"
>Ghostfolio Premium
<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/>
</span>

6
apps/client/src/app/pages/faq/overview/faq-overview-page.html

@ -136,7 +136,7 @@
fully available as open source software (OSS). Thanks to our generous
<a class="align-items-center d-inline-flex" [href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/></a>
users and
@ -164,7 +164,7 @@
>By offering
<a class="align-items-center d-inline-flex" [href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false" /></a
>, a subscription plan with a managed hosting service and enhanced
features, we fund our business while providing added value to our
@ -190,7 +190,7 @@
>Any support for Ghostfolio is welcome. Be it with a
<a class="align-items-center d-inline-flex" [href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/></a>
subscription to finance the operational costs for the hosting

6
apps/client/src/app/pages/faq/saas/saas-page.html

@ -54,7 +54,7 @@
target="_blank"
[href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/></a>
is a fully managed Ghostfolio cloud offering for ambitious investors.
@ -78,7 +78,7 @@
target="_blank"
[href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/></a>
by signing up for Ghostfolio and applying for a trial (see
@ -114,7 +114,7 @@
target="_blank"
[href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/></a>
does not include auto-renewal. Upon expiration, you can choose whether

4
apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html

@ -145,7 +145,7 @@
target="_blank"
[href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false" /></a
>), <code>MANUAL</code>, and <code>YAHOO</code> are officially
supported while all other data providers are considered
@ -166,7 +166,7 @@
target="_blank"
[href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
class="d-inline-block ms-1"
[enableLink]="false"
/></a>
subscription via an API key.</mat-card-content

14
apps/client/src/app/pages/features/features-page.html

@ -140,7 +140,7 @@
<h4 class="gf-text-wrap-balance">
<span i18n>Portfolio Calculations</span>
@if (hasPermissionForSubscription) {
<gf-premium-indicator class="d-inline-block ml-1" />
<gf-premium-indicator class="d-inline-block ms-1" />
}
</h4>
<p class="m-0">
@ -160,7 +160,7 @@
<h4 class="gf-text-wrap-balance">
<span i18n>Portfolio Allocations</span>
@if (hasPermissionForSubscription) {
<gf-premium-indicator class="d-inline-block ml-1" />
<gf-premium-indicator class="d-inline-block ms-1" />
}
</h4>
<p class="m-0">
@ -178,7 +178,7 @@
<h4 class="gf-text-wrap-balance">
<span i18n>Static Analysis</span>
@if (hasPermissionForSubscription) {
<gf-premium-indicator class="d-inline-block ml-1" />
<gf-premium-indicator class="d-inline-block ms-1" />
}
</h4>
<p class="m-0">
@ -196,7 +196,7 @@
<h4 class="gf-text-wrap-balance">
<span i18n>Watchlist</span>
@if (hasPermissionForSubscription) {
<gf-premium-indicator class="d-inline-block ml-1" />
<gf-premium-indicator class="d-inline-block ms-1" />
}
</h4>
<p class="m-0">
@ -214,11 +214,11 @@
<span class="gf-text-wrap-balance">
<span>Ghostfolio MCP</span>
@if (hasPermissionForSubscription) {
<gf-premium-indicator class="d-inline-block ml-1" />
<gf-premium-indicator class="d-inline-block ms-1" />
}
</span>
<span
class="badge badge-pill badge-secondary ml-auto text-uppercase"
class="badge badge-pill badge-secondary ms-auto text-uppercase"
i18n
>new</span
>
@ -238,7 +238,7 @@
<div class="flex-grow-1">
<h4 class="gf-text-wrap-balance">
<span i18n>Market Mood</span>
<gf-premium-indicator class="d-inline-block ml-1" />
<gf-premium-indicator class="d-inline-block ms-1" />
</h4>
<p class="m-0">
Check the current market mood (<a

26
apps/client/src/app/pages/landing/landing-page.html

@ -177,43 +177,43 @@
</p>
<ul class="list-unstyled">
<li class="d-flex mb-3">
<span class="mr-3">💼 </span
<span class="me-3">💼 </span
><span i18n
>trading stocks, ETFs or cryptocurrencies on multiple
platforms</span
>
</li>
<li class="d-flex mb-3">
<span class="mr-3">🏦</span
<span class="me-3">🏦</span
><span i18n>pursuing a buy & hold strategy</span>
</li>
<li class="d-flex mb-3">
<span class="mr-3">🎯</span
<span class="me-3">🎯</span
><span i18n
>interested in getting insights of your portfolio composition</span
>
</li>
<li class="d-flex mb-3">
<span class="mr-3">👻</span
<span class="me-3">👻</span
><span i18n>valuing privacy and data ownership</span>
</li>
<li class="d-flex mb-3">
<span class="mr-3">🧘</span><span i18n>into minimalism</span>
<span class="me-3">🧘</span><span i18n>into minimalism</span>
</li>
<li class="d-flex mb-3">
<span class="mr-3">🧺</span
<span class="me-3">🧺</span
><span i18n>caring about diversifying your financial resources</span>
</li>
<li class="d-flex mb-3">
<span class="mr-3">🆓</span
<span class="me-3">🆓</span
><span i18n>interested in financial independence</span>
</li>
<li class="d-flex mb-3">
<span class="mr-3">🙅</span
<span class="me-3">🙅</span
><span i18n>saying no to spreadsheets in {{ currentYear }}</span>
</li>
<li class="d-flex mb-3">
<span class="mr-3">😎</span><span i18n>still reading this list</span>
<span class="me-3">😎</span><span i18n>still reading this list</span>
</li>
</ul>
<div class="mt-4 text-center">
@ -236,7 +236,7 @@
<div #carouselItem gfCarouselItem>
<div class="d-flex px-4">
<gf-logo
class="mr-3 mt-2 pt-1"
class="me-3 mt-2 pt-1"
size="medium"
[showLabel]="false"
/>
@ -296,7 +296,7 @@
<small>* no e-mail address nor credit card required</small>
</div>
</div>
<div class="pl-2 text-muted text-right">1</div>
<div class="ps-2 text-muted text-right">1</div>
</mat-card-content>
</mat-card>
</div>
@ -308,7 +308,7 @@
Add any of your historical transactions
</div>
</div>
<div class="pl-2 text-muted text-right">2</div>
<div class="ps-2 text-muted text-right">2</div>
</mat-card-content>
</mat-card>
</div>
@ -320,7 +320,7 @@
Get valuable insights of your portfolio composition
</div>
</div>
<div class="pl-2 text-muted text-right">3</div>
<div class="ps-2 text-muted text-right">3</div>
</mat-card-content>
</mat-card>
</div>

8
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html

@ -142,7 +142,7 @@
[matDatepicker]="date"
[matDatepickerFilter]="dateFilter"
/>
<mat-datepicker-toggle class="mr-2" matSuffix [for]="date">
<mat-datepicker-toggle class="me-2" matSuffix [for]="date">
<ion-icon
class="text-muted"
matDatepickerToggleIcon
@ -193,7 +193,7 @@
</mat-label>
<input formControlName="unitPrice" matInput type="number" />
<div
class="ml-2"
class="ms-2"
matTextSuffix
[class.d-none]="!activityForm.get('currency')?.value"
>
@ -215,7 +215,7 @@
isToday(activityForm.get('date')?.value)
) {
<button
class="ml-2 mt-1 no-min-width"
class="ms-2 mt-1 no-min-width"
i18n-title
mat-button
title="Apply current market price"
@ -239,7 +239,7 @@
<mat-label i18n>Fee</mat-label>
<input formControlName="fee" matInput type="number" />
<div
class="ml-2"
class="ms-2"
matTextSuffix
[class.d-none]="!activityForm.get('currency')?.value"
>

20
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html

@ -99,7 +99,7 @@
}
<p class="mb-0 mt-3 text-center">
<small>
<span class="mr-1" i18n
<span class="me-1" i18n
>The following file formats are supported:</span
>
<a
@ -108,7 +108,7 @@
>CSV</a
>
@if (isGhostfolioAiEnabled) {
<span class="mr-1">, JPG,</span>
<span class="me-1">, JPG,</span>
} @else {
<span class="mx-1" i18n>or</span>
}
@ -165,9 +165,9 @@
@if (rowsWithoutMatch.length > 0) {
<mat-accordion class="d-block mb-3" displayMode="flat">
<mat-expansion-panel>
<mat-expansion-panel-header class="pl-1">
<mat-expansion-panel-header class="ps-1">
<mat-panel-title>
<div class="align-items-center d-flex mr-2">
<div class="align-items-center d-flex me-2">
<ion-icon name="warning-outline" />
</div>
<ng-container i18n>{rowsWithoutMatch.length, plural,
@ -188,8 +188,8 @@
</mat-accordion>
}
@if (isMaxActivitiesOfGhostfolioAiReached) {
<div class="align-items-center d-flex mb-3 pl-1">
<ion-icon class="mr-2" name="warning-outline" />
<div class="align-items-center d-flex mb-3 ps-1">
<ion-icon class="me-2" name="warning-outline" />
<span i18n
>Ghostfolio AI has processed the maximum of
{{ maxActivitiesOfGhostfolioAi }} activities. The file can
@ -223,7 +223,7 @@
<ng-container i18n>Back</ng-container>
</button>
<button
class="ml-1"
class="ms-1"
color="primary"
mat-flat-button
[disabled]="!selectedActivities?.length"
@ -237,10 +237,10 @@
<mat-accordion displayMode="flat">
@for (message of errorMessages; track message; let i = $index) {
<mat-expansion-panel [disabled]="!details[i]">
<mat-expansion-panel-header class="pl-1">
<mat-expansion-panel-header class="ps-1">
<mat-panel-title class="w-100">
<div class="d-flex w-100">
<div class="align-items-center d-flex mr-2">
<div class="align-items-center d-flex me-2">
<ion-icon name="warning-outline" />
</div>
<div class="text-truncate" title="{{ message }}">
@ -261,7 +261,7 @@
<ng-container i18n>Back</ng-container>
</button>
<button
class="ml-1"
class="ms-1"
color="primary"
mat-flat-button
[disabled]="true"

18
apps/client/src/app/pages/portfolio/allocations/allocations-page.html

@ -59,7 +59,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By Currency</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -81,7 +81,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By Asset Class</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -126,7 +126,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By Sector</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -149,7 +149,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By Continent</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -171,7 +171,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By Market</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -194,7 +194,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>Regions</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -262,7 +262,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By Country</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -304,7 +304,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By ETF Provider</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
</mat-card-header>
@ -329,7 +329,7 @@
<mat-card-title class="align-items-center d-flex text-truncate">
<span i18n>By ETF Holding</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</mat-card-title>
<mat-card-subtitle>

62
apps/client/src/app/pages/portfolio/analysis/analysis-page.html

@ -26,16 +26,16 @@
>
<span class="align-items-center d-flex">
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="mr-2" />
<gf-premium-indicator class="me-2" />
} @else {
@if (isLoadingPortfolioPrompt) {
<mat-spinner
class="mr-2"
class="me-2"
color="accent"
[diameter]="16"
/>
} @else {
<ion-icon class="mr-2" name="copy-outline" />
<ion-icon class="me-2" name="copy-outline" />
}
}
<ng-container i18n
@ -51,16 +51,16 @@
>
<span class="align-items-center d-flex">
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="mr-2" />
<gf-premium-indicator class="me-2" />
} @else {
@if (isLoadingAnalysisPrompt) {
<mat-spinner
class="mr-2"
class="me-2"
color="accent"
[diameter]="16"
/>
} @else {
<ion-icon class="mr-2" name="copy-outline" />
<ion-icon class="me-2" name="copy-outline" />
}
}
<ng-container i18n
@ -152,11 +152,11 @@
<mat-card-content>
<div class="d-flex py-1">
<div
class="align-items-center d-flex flex-grow-1 mr-2 text-truncate"
class="align-items-center d-flex flex-grow-1 me-2 text-truncate"
>
<span i18n>Absolute Asset Performance</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
<div class="d-flex justify-content-end">
@ -171,8 +171,8 @@
/>
</div>
</div>
<div class="d-flex mb-3 ml-3 py-1">
<div class="flex-grow-1 mr-2 text-truncate">
<div class="d-flex mb-3 ms-3 py-1">
<div class="flex-grow-1 me-2 text-truncate">
<ng-container i18n>Asset Performance</ng-container>
</div>
<div class="d-flex justify-content-end">
@ -189,11 +189,11 @@
</div>
<div class="d-flex py-1">
<div
class="align-items-center d-flex flex-grow-1 mr-2 text-truncate"
class="align-items-center d-flex flex-grow-1 me-2 text-truncate"
>
<span i18n>Absolute Currency Performance</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
<div class="d-flex justify-content-end">
@ -213,8 +213,8 @@
/>
</div>
</div>
<div class="d-flex ml-3 py-1">
<div class="flex-grow-1 mr-2 text-truncate">
<div class="d-flex ms-3 py-1">
<div class="flex-grow-1 me-2 text-truncate">
<ng-container i18n>Currency Performance</ng-container>
</div>
<div class="d-flex justify-content-end">
@ -236,7 +236,7 @@
</div>
<div><hr /></div>
<div class="d-flex py-1">
<div class="flex-grow-1 mr-2 text-truncate">
<div class="flex-grow-1 me-2 text-truncate">
<ng-container i18n>Absolute Net Performance</ng-container>
</div>
<div class="d-flex justify-content-end">
@ -251,15 +251,15 @@
/>
</div>
</div>
<div class="d-flex ml-3 py-1">
<div class="flex-grow-1 mr-2 text-truncate">
<div class="d-flex ms-3 py-1">
<div class="flex-grow-1 me-2 text-truncate">
<ng-container i18n>Net Performance</ng-container>
@if (
user?.settings?.performanceCalculationType ===
PerformanceCalculationType.ROAI
) {
<abbr
class="d-none d-sm-inline-block initialism ml-2 text-muted"
class="d-none d-sm-inline-block initialism ms-2 text-muted"
i18n-title
title="Return on Average Investment (total return with dividends)"
>(ROAI)</abbr
@ -280,13 +280,13 @@
/>
</div>
</div>
<div class="d-flex ml-3 py-1 text-muted">
<div class="d-flex ms-3 py-1 text-muted">
<div
class="align-items-center d-flex flex-grow-1 mr-2 text-truncate"
class="align-items-center d-flex flex-grow-1 me-2 text-truncate"
>
<span i18n>thereof Dividend</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
<div class="d-flex justify-content-end">
@ -301,8 +301,8 @@
/>
</div>
</div>
<div class="d-flex ml-3 py-1 text-muted">
<div class="flex-grow-1 mr-2 text-truncate">
<div class="d-flex ms-3 py-1 text-muted">
<div class="flex-grow-1 me-2 text-truncate">
<ng-container i18n>thereof Dividend Performance</ng-container>
</div>
<div class="d-flex justify-content-end">
@ -330,7 +330,7 @@
>
</mat-card-header>
<mat-card-content>
<ol class="holdings mb-0 ml-1 pl-3">
<ol class="holdings mb-0 ms-1 ps-3">
@for (holding of top3; track holding) {
<li class="py-1">
<a
@ -342,7 +342,7 @@
}"
[routerLink]="[]"
>
<div class="flex-grow-1 mr-2 name">
<div class="flex-grow-1 me-2 name">
<span class="align-top d-inline-block mw-100 text-truncate">
{{ holding.assetProfile.name }}
</span>
@ -383,7 +383,7 @@
>
</mat-card-header>
<mat-card-content>
<ol class="holdings mb-0 ml-1 pl-3">
<ol class="holdings mb-0 ms-1 ps-3">
@for (holding of bottom3; track holding) {
<li class="py-1">
<a
@ -395,7 +395,7 @@
}"
[routerLink]="[]"
>
<div class="flex-grow-1 mr-2 name">
<div class="flex-grow-1 me-2 name">
<span class="align-top d-inline-block mw-100 text-truncate">
{{ holding.assetProfile.name }}
</span>
@ -439,7 +439,7 @@
>
<span i18n>Performance Timeline</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
</div>
@ -467,7 +467,7 @@
>
<span i18n>Portfolio Evolution</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
</div>
@ -495,7 +495,7 @@
>
<span i18n>Investment Timeline</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
<gf-toggle
@ -553,7 +553,7 @@
>
<span i18n>Dividend Timeline</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</div>
<gf-toggle

4
apps/client/src/app/pages/portfolio/fire/fire-page.html

@ -6,7 +6,7 @@
<h4 class="align-items-center d-flex mb-3">
<span i18n>Calculator</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</h4>
<gf-fire-calculator
@ -41,7 +41,7 @@
<h4 class="align-items-center d-flex">
<span i18n>Sustainable retirement income</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</h4>
@if (isLoading) {

6
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html

@ -19,7 +19,7 @@
<div class="d-flex">
<ngx-skeleton-loader
animation="pulse"
class="mr-2"
class="me-2"
[theme]="{
height: '2rem',
width: '2rem'
@ -36,7 +36,7 @@
</div>
} @else {
<div
class="align-items-center d-flex icon-container mr-2 px-2"
class="align-items-center d-flex icon-container me-2 px-2"
[class]="{
okay:
statistics?.rulesFulfilledCount ===
@ -71,7 +71,7 @@
<h4 class="align-items-center d-flex m-0">
<span>{{ category.name }}</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
<gf-premium-indicator class="ms-1" />
}
</h4>
<gf-rules

60
apps/client/src/app/pages/pricing/pricing-page.html

@ -31,42 +31,42 @@
<ng-container>&nbsp;</ng-container>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Unlimited Transactions</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Unlimited Accounts</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Performance</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Summary</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Allocations</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Performance Benchmarks</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>FIRE Calculator</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span>Ghostfolio MCP</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Data Import and Export</span>
<span
class="align-items-center d-flex ml-1"
class="align-items-center d-flex ms-1"
matTooltipPosition="above"
[matTooltip]="importAndExportTooltipOSS"
>
@ -74,13 +74,13 @@
</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<a i18n [routerLink]="routerLinkFeatures"
>and more Features...</a
>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Community Support</span>
</li>
</ul>
@ -115,7 +115,7 @@
<h4 class="flex-grow-1 m-0">Basic</h4>
@if (user?.subscription?.type === 'Basic') {
<div>
<ion-icon class="mr-1" name="checkmark-outline" />
<ion-icon class="me-1" name="checkmark-outline" />
</div>
}
</div>
@ -127,22 +127,22 @@
<ng-container>&nbsp;</ng-container>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Unlimited Transactions</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Unlimited Accounts</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Performance</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Data Import and Export</span>
<span
class="align-items-center d-flex ml-1"
class="align-items-center d-flex ms-1"
matTooltipPosition="above"
[matTooltip]="importAndExportTooltipBasic"
>
@ -185,11 +185,11 @@
<div class="align-items-center d-flex mb-2">
<h4 class="align-items-center d-flex flex-grow-1 m-0">
<span>Premium</span>
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
</h4>
@if (user?.subscription?.type === 'Premium') {
<div>
<ion-icon class="mr-1" name="checkmark-outline" />
<ion-icon class="me-1" name="checkmark-outline" />
</div>
}
</div>
@ -204,30 +204,30 @@
>:
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Summary</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Portfolio Allocations</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Performance Benchmarks</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>FIRE Calculator</span>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span>Ghostfolio MCP</span>
</li>
<li class="align-items-center d-flex">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Professional Data Provider</span>
<span
class="align-items-center d-flex ml-1"
class="align-items-center d-flex ms-1"
matTooltipPosition="above"
[matTooltip]="professionalDataProviderTooltipPremium"
>
@ -236,7 +236,7 @@
</li>
<li class="align-items-center d-flex line-height-1 mb-1">
<ion-icon
class="hidden mr-1"
class="hidden me-1"
name="checkmark-circle-outline"
/>
<small
@ -246,13 +246,13 @@
>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<a i18n [routerLink]="routerLinkFeatures"
>and more Features...</a
>
</li>
<li class="align-items-center d-flex mb-1">
<ion-icon class="mr-1" name="checkmark-circle-outline" />
<ion-icon class="me-1" name="checkmark-circle-outline" />
<span i18n>Email and Chat Support</span>
</li>
</ul>

2
apps/client/src/app/pages/register/register-page.html

@ -35,7 +35,7 @@
href="../api/v1/auth/google"
mat-stroked-button
><img
class="mr-2"
class="me-2"
src="../assets/icons/google.svg"
style="height: 1rem"
/><span i18n>Continue with Google</span></a

6
apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html

@ -1,7 +1,7 @@
<h1 mat-dialog-title>
<span i18n>Create Account</span>
@if (role === 'ADMIN') {
<span class="badge badge-light ml-2">{{ role }}</span>
<span class="badge badge-light ms-2">{{ role }}</span>
}
</h1>
<div class="px-0" mat-dialog-content>
@ -56,7 +56,7 @@
(click)="createAccount()"
>
<span i18n>Continue</span>
<ion-icon class="ml-1" name="arrow-forward-outline" />
<ion-icon class="ms-1" name="arrow-forward-outline" />
</button>
</div>
</div>
@ -85,7 +85,7 @@
[cdkCopyToClipboard]="accessToken ?? ''"
(click)="enableCreateAccountButton()"
>
<ion-icon class="mr-1" name="copy-outline" />
<ion-icon class="me-1" name="copy-outline" />
<span i18n>Copy to clipboard</span>
</button>
</div>

40
apps/client/src/styles/bootstrap.scss

@ -47,46 +47,6 @@ $table-cell-padding-y: 0.75rem;
$utilities: map.merge(
$utilities,
(
'margin-right-compat': (
responsive: true,
property: margin-right,
class: mr,
values: map.merge(
map.merge(
$spacers,
(
auto: auto
)
),
negativify-map($spacers)
)
),
'margin-left-compat': (
responsive: true,
property: margin-left,
class: ml,
values: map.merge(
map.merge(
$spacers,
(
auto: auto
)
),
negativify-map($spacers)
)
),
'padding-right-compat': (
responsive: true,
property: padding-right,
class: pr,
values: $spacers
),
'padding-left-compat': (
responsive: true,
property: padding-left,
class: pl,
values: $spacers
),
'text-align-compat': (
responsive: true,
property: text-align,

8
libs/ui/src/lib/access-level-icon/access-level-icon.component.html

@ -1,19 +1,19 @@
<span class="align-items-center d-flex">
@switch (accessLevel()) {
@case ('CREATE_READ_RESTRICTED_UPDATE_DELETE') {
<span aria-hidden="true" class="mr-1">🔏</span>
<span aria-hidden="true" class="me-1">🔏</span>
<ng-container i18n>Restricted view and manage</ng-container>
}
@case ('CREATE_READ_UPDATE_DELETE') {
<span aria-hidden="true" class="mr-1">🖋️</span>
<span aria-hidden="true" class="me-1">🖋️</span>
<ng-container i18n>View and manage</ng-container>
}
@case ('READ') {
<span aria-hidden="true" class="mr-1">🔓</span>
<span aria-hidden="true" class="me-1">🔓</span>
<ng-container i18n>View</ng-container>
}
@case ('READ_RESTRICTED') {
<span aria-hidden="true" class="mr-1">🔒</span>
<span aria-hidden="true" class="me-1">🔒</span>
<ng-container i18n>Restricted view</ng-container>
}
}

6
libs/ui/src/lib/account-balances/account-balances.component.html

@ -22,7 +22,7 @@
[matDatepicker]="date"
[max]="maxDate"
/>
<mat-datepicker-toggle class="mr-2" matSuffix [for]="date">
<mat-datepicker-toggle class="me-2" matSuffix [for]="date">
<ion-icon
class="text-muted"
matDatepickerToggleIcon
@ -52,7 +52,7 @@
<div class="d-flex justify-content-end">
<mat-form-field appearance="outline" class="without-hint">
<input formControlName="balance" matInput type="number" />
<div class="ml-2" matTextSuffix>
<div class="ms-2" matTextSuffix>
{{ accountCurrency() }}
</div>
</mat-form-field>
@ -81,7 +81,7 @@
(click)="onDeleteAccountBalance(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

4
libs/ui/src/lib/account-selector/account-selector.component.html

@ -14,7 +14,7 @@
<div class="align-items-center align-middle d-inline-flex line-height-1">
@if (selectedAccount()?.platform?.url) {
<gf-entity-logo
class="mr-1"
class="me-1"
[tooltip]="selectedAccount()?.platform?.name ?? ''"
[url]="selectedAccount()?.platform?.url ?? ''"
/>
@ -31,7 +31,7 @@
<mat-option [value]="account.id">
<div class="align-items-center d-flex">
<gf-entity-logo
class="mr-1"
class="me-1"
[hasPlaceholder]="true"
[tooltip]="account.platform?.name ?? ''"
[url]="account.platform?.url ?? ''"

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

@ -6,7 +6,7 @@
[disabled]="dataSource?.data.length < 2"
[routerLink]="transferCashBalanceRouterLink"
>
<ion-icon class="mr-2" name="arrow-redo-outline" />
<ion-icon class="me-2" name="arrow-redo-outline" />
<span><ng-container i18n>Transfer Cash Balance</ng-container>...</span>
</button>
</div>
@ -52,7 +52,7 @@
<td *matCellDef="let element" class="px-1 text-nowrap" mat-cell>
<div class="align-items-center d-flex">
<gf-entity-logo
class="d-sm-none mr-1"
class="d-sm-none me-1"
[hasPlaceholder]="true"
[tooltip]="element.platform?.name"
[url]="element.platform?.url"
@ -100,7 +100,7 @@
>
<div class="d-flex">
<gf-entity-logo
class="mr-1"
class="me-1"
[hasPlaceholder]="true"
[tooltip]="element.platform?.name"
[url]="element.platform?.url"
@ -335,7 +335,7 @@
[routerLink]="accountDialogRouterLinks().get(element.id)?.detail"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="wallet-outline" />
<ion-icon class="me-2" name="wallet-outline" />
<span><ng-container i18n>View Details</ng-container>...</span>
</span>
</a>
@ -346,7 +346,7 @@
[routerLink]="accountDialogRouterLinks().get(element.id)?.update"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<ion-icon class="me-2" name="create-outline" />
<span><ng-container i18n>Edit</ng-container>...</span>
</span>
</a>
@ -359,7 +359,7 @@
(click)="onDeleteAccount(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

32
libs/ui/src/lib/activities-table/activities-table.component.html

@ -27,7 +27,7 @@
mat-stroked-button
(click)="onImport()"
>
<ion-icon class="mr-2" name="cloud-upload-outline" />
<ion-icon class="me-2" name="cloud-upload-outline" />
<span><ng-container i18n>Import Activities</ng-container>...</span>
</button>
}
@ -53,7 +53,7 @@
(click)="onImportDividends()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="color-wand-outline" />
<ion-icon class="me-2" name="color-wand-outline" />
<span><ng-container i18n>Import Dividends</ng-container>...</span>
</span>
</button>
@ -66,7 +66,7 @@
(click)="onExport()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="cloud-download-outline" />
<ion-icon class="me-2" name="cloud-download-outline" />
@if (canExportActivities()) {
<span i18n
>Export {{ (totalItems ?? 0) > 1 ? totalItems : '' }}
@ -86,7 +86,7 @@
(click)="onExportDrafts()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="calendar-clear-outline" />
<ion-icon class="me-2" name="calendar-clear-outline" />
<span i18n>Export Drafts as ICS</span>
</span>
</button>
@ -104,7 +104,7 @@
(click)="onDeleteActivities()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
@if (canDeleteActivities()) {
<span i18n
>Delete {{ (totalItems ?? 0) > 1 ? totalItems : '' }}
@ -188,7 +188,7 @@
<div class="align-items-center d-flex text-nowrap">
<span class="text-truncate">{{ element.assetProfile?.name }}</span>
@if (isDraftActivity(element)) {
<span class="badge badge-secondary ml-1" i18n>Draft</span>
<span class="badge badge-secondary ms-1" i18n>Draft</span>
}
</div>
@if (
@ -367,7 +367,7 @@
<td *matCellDef="let element" class="px-1" mat-cell>
<div class="d-flex">
<gf-entity-logo
class="mr-1"
class="me-1"
[hasPlaceholder]="true"
[tooltip]="element.account?.platform?.name"
[url]="element.account?.platform?.url"
@ -430,7 +430,7 @@
(click)="onImport()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="cloud-upload-outline" />
<ion-icon class="me-2" name="cloud-upload-outline" />
<span
><ng-container i18n>Import Activities</ng-container>...</span
>
@ -444,7 +444,7 @@
(click)="onImportDividends()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="color-wand-outline" />
<ion-icon class="me-2" name="color-wand-outline" />
<span
><ng-container i18n>Import Dividends</ng-container>...</span
>
@ -459,7 +459,7 @@
(click)="onExport()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="cloud-download-outline" />
<ion-icon class="me-2" name="cloud-download-outline" />
<span i18n>Export Activities</span>
</span>
</button>
@ -472,7 +472,7 @@
(click)="onExportDrafts()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="calendar-clear-outline" />
<ion-icon class="me-2" name="calendar-clear-outline" />
<span i18n>Export Drafts as ICS</span>
</span>
</button>
@ -498,7 +498,7 @@
@if (canClickActivity(element)) {
<button mat-menu-item (click)="onClickActivity(element)">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="tablet-landscape-outline" />
<ion-icon class="me-2" name="tablet-landscape-outline" />
<span><ng-container i18n>View Holding</ng-container>...</span>
</span>
</button>
@ -509,7 +509,7 @@
[routerLink]="activityDialogRouterLinks().get(element.id)?.update"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<ion-icon class="me-2" name="create-outline" />
<span><ng-container i18n>Edit</ng-container>...</span>
</span>
</a>
@ -520,7 +520,7 @@
[routerLink]="activityDialogRouterLinks().get(element.id)?.clone"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="copy-outline" />
<ion-icon class="me-2" name="copy-outline" />
<span><ng-container i18n>Clone</ng-container>...</span>
</span>
</a>
@ -532,7 +532,7 @@
(click)="onExportDraft(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="calendar-clear-outline" />
<ion-icon class="me-2" name="calendar-clear-outline" />
<span i18n>Export Draft as ICS</span>
</span>
</button>
@ -544,7 +544,7 @@
(click)="onDeleteActivity(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

2
libs/ui/src/lib/assistant/assistant.html

@ -4,7 +4,7 @@
(keydown.tab)="$event.stopPropagation()"
>
<div class="align-items-center d-flex search-container">
<ion-icon class="ml-2 mr-0" name="search-outline" />
<ion-icon class="me-0 ms-2" name="search-outline" />
<input
#search
autocomplete="off"

2
libs/ui/src/lib/benchmark/benchmark.component.html

@ -193,7 +193,7 @@
"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<ion-icon class="me-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>

4
libs/ui/src/lib/currency-selector/currency-selector.component.html

@ -1,6 +1,6 @@
@if (countryCodeOfSelectedCurrency) {
<gf-entity-logo
class="flex-shrink-0 mr-1"
class="flex-shrink-0 me-1"
[countryCode]="countryCodeOfSelectedCurrency"
/>
}
@ -23,7 +23,7 @@
<mat-option class="line-height-1" [value]="currency">
<span class="align-items-center d-flex">
<gf-entity-logo
class="mr-1"
class="me-1"
[countryCode]="getCountryCodeFromCurrency(currency)"
[hasPlaceholder]="true"
/>

4
libs/ui/src/lib/fear-and-greed-index/fear-and-greed-index.component.html

@ -8,10 +8,10 @@
/>
} @else {
<div class="align-items-center d-flex flex-row">
<div class="h2 mb-0 mr-2">{{ fearAndGreedIndexEmoji() }}</div>
<div class="h2 mb-0 me-2">{{ fearAndGreedIndexEmoji() }}</div>
<div>
<div class="h4 mb-0">
<span class="mr-2">{{ fearAndGreedIndexText() }}</span>
<span class="me-2">{{ fearAndGreedIndexText() }}</span>
@let value = fearAndGreedIndex() | number: '1.0-0';
<small class="text-muted"
><span [class.font-weight-bold]="value">{{

8
libs/ui/src/lib/fire-calculator/fire-calculator.component.html

@ -14,7 +14,7 @@
step="100"
type="number"
/>
<span class="ml-2" matTextSuffix>{{ currency }}</span>
<span class="ms-2" matTextSuffix>{{ currency }}</span>
</mat-form-field>
<mat-form-field appearance="outline" class="w-100">
@ -25,7 +25,7 @@
step="0.25"
type="number"
/>
<div class="ml-2" matTextSuffix>%</div>
<div class="ms-2" matTextSuffix>%</div>
</mat-form-field>
<mat-form-field appearance="outline" class="w-100">
@ -39,7 +39,7 @@
[min]="minDate"
/>
<mat-datepicker-toggle
class="mr-2"
class="me-2"
matSuffix
[disabled]="hasPermissionToUpdateUserSettings !== true"
[for]="date"
@ -66,7 +66,7 @@
step="100"
type="number"
/>
<span class="ml-2" matTextSuffix>{{ currency }}</span>
<span class="ms-2" matTextSuffix>{{ currency }}</span>
</mat-form-field>
</form>
</div>

6
libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html

@ -9,7 +9,7 @@
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Date</mat-label>
<input formControlName="date" matInput [matDatepicker]="date" />
<mat-datepicker-toggle class="mr-2" matSuffix [for]="date">
<mat-datepicker-toggle class="me-2" matSuffix [for]="date">
<ion-icon
class="text-muted"
matDatepickerToggleIcon
@ -23,10 +23,10 @@
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Market Price</mat-label>
<input formControlName="marketPrice" matInput type="number" />
<span class="ml-2" matTextSuffix>{{ data.currency }}</span>
<span class="ms-2" matTextSuffix>{{ data.currency }}</span>
</mat-form-field>
<button
class="ml-2 mt-1 no-min-width"
class="ms-2 mt-1 no-min-width"
i18n-title
mat-button
title="Fetch market price"

2
libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html

@ -1,7 +1,7 @@
<div>
@for (itemByMonth of marketDataByMonth | keyvalue; track itemByMonth) {
<div class="d-flex">
<div class="date mr-1 text-nowrap">{{ itemByMonth.key }}</div>
<div class="date me-1 text-nowrap">{{ itemByMonth.key }}</div>
<div class="align-items-center d-flex flex-grow-1 px-1">
@for (day of days; track day) {
<div

2
libs/ui/src/lib/logo/logo.component.html

@ -1,5 +1,5 @@
<span class="align-items-center d-flex"
><span class="d-inline-block logo" [class.mr-1]="showLabel"></span>
><span class="d-inline-block logo" [class.me-1]="showLabel"></span>
@if (showLabel) {
<span class="label">{{ label ?? 'Ghostfolio' }}</span>
}

2
libs/ui/src/lib/membership-card/membership-card.component.html

@ -21,7 +21,7 @@
<div class="heading text-muted" i18n>API Key</div>
<div class="align-items-center d-flex">
<div class="text-monospace value">* * * * * * * * *</div>
<div class="ml-1">
<div class="ms-1">
<button
class="bg-transparent no-min-width"
i18n-title

2
libs/ui/src/lib/notifications/prompt-dialog/prompt-dialog.html

@ -9,7 +9,7 @@
}
<input matInput [formControl]="formControl" />
@if (valueSuffix) {
<span class="ml-2" matTextSuffix>{{ valueSuffix }}</span>
<span class="ms-2" matTextSuffix>{{ valueSuffix }}</span>
}
</mat-form-field>
</div>

4
libs/ui/src/lib/page-tabs/page-tabs.component.html

@ -21,7 +21,7 @@
*ngTemplateOutlet="tabContent; context: { $implicit: tab }"
/>
<ion-icon
class="d-none d-sm-block external-link-icon ml-auto text-muted"
class="d-none d-sm-block external-link-icon ms-auto text-muted"
name="open-outline"
/>
</button>
@ -52,7 +52,7 @@
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<span
class="d-none d-sm-block line-height-normal ml-1 overflow-hidden p-0 text-truncate"
class="d-none d-sm-block line-height-normal ms-1 overflow-hidden p-0 text-truncate"
[innerHTML]="tab.label"
></span>
</span>

2
libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.html

@ -22,7 +22,7 @@
<span class="align-items-center d-flex line-height-1"
><span>{{ lookupItem.name }}</span>
@if (lookupItem.dataProviderInfo.isPremium) {
<gf-premium-indicator class="ml-1" [enableLink]="false" />
<gf-premium-indicator class="ms-1" [enableLink]="false" />
}
</span>
<small class="text-muted"

2
libs/ui/src/lib/tags-selector/tags-selector.component.html

@ -58,7 +58,7 @@
@if (hasPermissionToCreateTag && tagNameToCreate()) {
<mat-option [value]="tagNameToCreate()">
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="add-circle-outline" />
<ion-icon class="me-2" name="add-circle-outline" />
<ng-container i18n>Create</ng-container> "{{
tagNameToCreate()
}}"

10
libs/ui/src/lib/value/value.component.html

@ -1,5 +1,5 @@
@if (icon) {
<div class="align-self-center mr-3">
<div class="align-self-center me-3">
<ion-icon class="h3 m-0" [name]="icon" />
</div>
}
@ -12,7 +12,7 @@
<ng-template #copyIcon>
@if (enableCopyToClipboardButton) {
<button
class="ml-1 no-height no-min-width p-1"
class="ms-1 no-height no-min-width p-1"
mat-button
type="button"
[title]="isCopied ? copiedTitle : copyToClipboardTitle"
@ -44,10 +44,10 @@
@if (isNumber || value === null) {
@if (colorizeSign && !useAbsoluteValue && value !== null) {
@if (+value > 0) {
<div class="mr-1 text-success">+</div>
<div class="me-1 text-success">+</div>
}
@if (+value < 0) {
<div class="mr-1 text-danger">-</div>
<div class="me-1 text-danger">-</div>
}
}
<div
@ -63,7 +63,7 @@
}
</div>
@if (isPercent || unit) {
<div class="ml-1">
<div class="ms-1">
{{ isPercent ? '%' : unit }}
</div>
}

Loading…
Cancel
Save