Compare commits

..

18 Commits

Author SHA1 Message Date
f332aea9b4 Release 1.185.0 (#1207) 2022-08-30 20:53:26 +02:00
7a9fd18407 Feature/improve markets overview (#1206)
* Improve markets overview

* Update changelog
2022-08-30 20:52:13 +02:00
ca08d3154a Bugfix/disable language selector for demo user (#1204)
* Disable language selector for demo user

* Update changelog
2022-08-28 21:11:27 +02:00
01d4ae8757 Feature/move build pipeline from travis to GitHub actions (#1203)
* Remove travis configurations

* Update changelog
2022-08-28 21:10:25 +02:00
43ce2786c1 Fetch all history for all tags and branches (#1202) 2022-08-28 11:01:54 +02:00
de2092c4d2 Release 1.184.2 (#1201) 2022-08-28 10:09:59 +02:00
435a180e54 Release 1.184.1 (#1200) 2022-08-28 09:44:09 +02:00
0ad30ffabe Add version to docker tag (#1199) 2022-08-28 09:43:06 +02:00
0cc5e558f1 Release 1.184.0 (#1198) 2022-08-28 09:12:03 +02:00
63b183cc6f Feature/finalize GitHub action to create arm64 docker image (#1197)
* Change order and refactor secrets

* Update changelog
2022-08-28 09:10:18 +02:00
10bae24c5c Build arm64 docker image and use github actions (#1134)
* Setup build pipeline for arm64 docker images using GitHub Actions
2022-08-27 14:37:22 +02:00
0e29278e96 Feature/add alias to access (#1193)
* Add alias to access

* Update changelog
2022-08-27 11:29:09 +02:00
2db46e5bbf Feature/support localization in date fns (#1195)
* Add locale to date-fns (formatDistanceToNow)

* Update changelog
2022-08-27 10:54:59 +02:00
e757e90e5a Improve translation (#1196) 2022-08-27 10:42:54 +02:00
184ddc6209 Bugfix/fix missing assets in local development (#1194)
* Fix missing assets in local development

* Update changelog
2022-08-27 10:29:50 +02:00
e3662a143c Improve localization (#1191)
* Improve localization

* Update changelog
2022-08-26 20:10:59 +02:00
25afd7e07b Remove database:baseline (#1192) 2022-08-26 18:08:05 +02:00
7fceaa1350 Add language to urls (#1187) 2022-08-26 17:52:42 +02:00
39 changed files with 378 additions and 168 deletions

36
.github/workflows/build-code.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Build code
on:
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node_version:
- 16
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node_version }}
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Check formatting
run: yarn format:check
- name: Execute tests
run: yarn test
- name: Build application
run: yarn build:all

49
.github/workflows/docker-image.yml vendored Normal file
View File

@ -0,0 +1,49 @@
name: Docker image CD
on:
push:
tags:
- '*.*.*'
pull_request:
branches:
- 'main'
jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Docker metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ghostfolio/ghostfolio
tags: |
type=semver,pattern={{version}}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.output.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@ -1,30 +0,0 @@
language: node_js
git:
depth: false
node_js:
- 16
services:
- docker
cache: yarn
if: (type = pull_request) OR (tag IS present)
jobs:
include:
- stage: Install dependencies
if: type = pull_request
script: yarn --frozen-lockfile
- stage: Check formatting
if: type = pull_request
script: yarn format:check
- stage: Execute tests
if: type = pull_request
script: yarn test
- stage: Build application
if: type = pull_request
script: yarn build:all
- stage: Build and publish docker image
if: tag IS present
script: ./publish-docker-image.sh

View File

@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 1.185.0 - 30.08.2022
### Added
- Added a skeleton loader to the market mood component in the markets overview
### Changed
- Moved the build pipeline from _Travis_ to _GitHub Actions_
- Increased the caching of the benchmarks
### Fixed
- Disabled the language selector for the demo user
## 1.184.2 - 28.08.2022
### Added
- Added the alias to the `Access` database schema
- Added support for translated time distances
- Added a _GitHub Action_ to create an `arm64` docker image
### Changed
- Improved the language localization for German (`de`)
### Fixed
- Fixed the missing assets during the local development
## 1.183.0 - 24.08.2022
### Added

View File

@ -1,7 +1,6 @@
FROM node:16-alpine as builder
FROM --platform=$BUILDPLATFORM node:16-slim as builder
# Build application and add additional files
WORKDIR /ghostfolio
# Only add basic files without the application itself to avoid rebuilding
@ -10,9 +9,16 @@ COPY ./CHANGELOG.md CHANGELOG.md
COPY ./LICENSE LICENSE
COPY ./package.json package.json
COPY ./yarn.lock yarn.lock
COPY ./.yarnrc .yarnrc
COPY ./prisma/schema.prisma prisma/schema.prisma
RUN apk add --no-cache python3 g++ make openssl git
RUN apt update && apt install -y \
git \
g++ \
make \
openssl \
python3 \
&& rm -rf /var/lib/apt/lists/*
RUN yarn install
# See https://github.com/nrwl/nx/issues/6586 for further details
@ -45,7 +51,11 @@ COPY package.json /ghostfolio/dist/apps/api
RUN yarn database:generate-typings
# Image to run, copy everything needed from builder
FROM node:16-alpine
FROM node:16-slim
RUN apt update && apt install -y \
openssl \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /ghostfolio/dist/apps /ghostfolio/apps
WORKDIR /ghostfolio/apps/api
EXPOSE 3333

View File

@ -12,13 +12,11 @@
<strong>Open Source Wealth Management Software</strong>
</p>
<p>
<a href="https://ghostfol.io"><strong>Ghostfol.io</strong></a> | <a href="https://ghostfol.io/demo"><strong>Live Demo</strong></a> | <a href="https://ghostfol.io/pricing"><strong>Ghostfolio Premium</strong></a> | <a href="https://ghostfol.io/faq"><strong>FAQ</strong></a> | <a href="https://ghostfol.io/blog"><strong>Blog</strong></a> | <a href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"><strong>Slack</strong></a> | <a href="https://twitter.com/ghostfolio_"><strong>Twitter</strong></a>
<a href="https://ghostfol.io"><strong>Ghostfol.io</strong></a> | <a href="https://ghostfol.io/en/demo"><strong>Live Demo</strong></a> | <a href="https://ghostfol.io/en/pricing"><strong>Ghostfolio Premium</strong></a> | <a href="https://ghostfol.io/en/faq"><strong>FAQ</strong></a> | <a href="https://ghostfol.io/en/blog"><strong>Blog</strong></a> | <a href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"><strong>Slack</strong></a> | <a href="https://twitter.com/ghostfolio_"><strong>Twitter</strong></a>
</p>
<p>
<a href="#contributing">
<img src="https://img.shields.io/badge/contributions-welcome-orange.svg"/></a>
<a href="https://travis-ci.com/github/ghostfolio/ghostfolio" rel="nofollow">
<img src="https://travis-ci.com/ghostfolio/ghostfolio.svg?branch=main" alt="Build Status"/></a>
<a href="https://www.gnu.org/licenses/agpl-3.0" rel="nofollow">
<img src="https://img.shields.io/badge/License-AGPL%20v3-blue.svg" alt="License: AGPL v3"/></a>
</p>
@ -33,7 +31,7 @@
## Ghostfolio Premium
Our official **[Ghostfolio Premium](https://ghostfol.io/pricing)** cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. The revenue is used for covering the hosting costs.
Our official **[Ghostfolio Premium](https://ghostfol.io/en/pricing)** cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. The revenue is used for covering the hosting costs.
If you prefer to run Ghostfolio on your own infrastructure, please find further instructions in the [Self-hosting](#self-hosting) section.
@ -259,7 +257,7 @@ Ghostfolio is **100% free** and **open source**. We encourage and support an act
Not sure what to work on? We have got some ideas. Please join the Ghostfolio [Slack channel](https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg), tweet to [@ghostfolio\_](https://twitter.com/ghostfolio_) or send an e-mail to hi@ghostfol.io. We would love to hear from you.
If you like to support this project, get **[Ghostfolio Premium](https://ghostfol.io/pricing)** or **[Buy me a coffee](https://www.buymeacoffee.com/ghostfolio)**.
If you like to support this project, get **[Ghostfolio Premium](https://ghostfol.io/en/pricing)** or **[Buy me a coffee](https://www.buymeacoffee.com/ghostfolio)**.
## License

View File

@ -42,14 +42,16 @@ export class AccessController {
return accessesWithGranteeUser.map((access) => {
if (access.GranteeUser) {
return {
granteeAlias: access.GranteeUser?.alias,
alias: access.alias,
grantee: access.GranteeUser?.id,
id: access.id,
type: 'RESTRICTED_VIEW'
};
}
return {
granteeAlias: 'Public',
alias: access.alias,
grantee: 'Public',
id: access.id,
type: 'PUBLIC'
};
@ -71,6 +73,10 @@ export class AccessController {
}
return this.accessService.createAccess({
alias: data.alias || undefined,
GranteeUser: data.granteeUserId
? { connect: { id: data.granteeUserId } }
: undefined,
User: { connect: { id: this.request.user.id } }
});
}

View File

@ -1 +1,11 @@
export class CreateAccessDto {}
import { IsOptional, IsString } from 'class-validator';
export class CreateAccessDto {
@IsOptional()
@IsString()
alias?: string;
@IsOptional()
@IsString()
granteeUserId?: string;
}

View File

@ -1,30 +1,20 @@
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor';
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { PROPERTY_BENCHMARKS } from '@ghostfolio/common/config';
import { BenchmarkResponse, UniqueAsset } from '@ghostfolio/common/interfaces';
import { BenchmarkResponse } from '@ghostfolio/common/interfaces';
import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { BenchmarkService } from './benchmark.service';
@Controller('benchmark')
export class BenchmarkController {
public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly propertyService: PropertyService
) {}
public constructor(private readonly benchmarkService: BenchmarkService) {}
@Get()
@UseInterceptors(TransformDataSourceInRequestInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async getBenchmark(): Promise<BenchmarkResponse> {
const benchmarkAssets: UniqueAsset[] =
((await this.propertyService.getByKey(
PROPERTY_BENCHMARKS
)) as UniqueAsset[]) ?? [];
return {
benchmarks: await this.benchmarkService.getBenchmarks(benchmarkAssets)
benchmarks: await this.benchmarkService.getBenchmarks()
};
}
}

View File

@ -1,10 +1,13 @@
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { PROPERTY_BENCHMARKS } from '@ghostfolio/common/config';
import { BenchmarkResponse, UniqueAsset } from '@ghostfolio/common/interfaces';
import { Injectable } from '@nestjs/common';
import Big from 'big.js';
import ms from 'ms';
@Injectable()
export class BenchmarkService {
@ -13,25 +16,32 @@ export class BenchmarkService {
public constructor(
private readonly dataProviderService: DataProviderService,
private readonly marketDataService: MarketDataService,
private readonly propertyService: PropertyService,
private readonly redisCacheService: RedisCacheService,
private readonly symbolProfileService: SymbolProfileService
) {}
public async getBenchmarks(
benchmarkAssets: UniqueAsset[]
): Promise<BenchmarkResponse['benchmarks']> {
public async getBenchmarks({ useCache = true } = {}): Promise<
BenchmarkResponse['benchmarks']
> {
let benchmarks: BenchmarkResponse['benchmarks'];
try {
benchmarks = JSON.parse(
await this.redisCacheService.get(this.CACHE_KEY_BENCHMARKS)
);
if (useCache) {
try {
benchmarks = JSON.parse(
await this.redisCacheService.get(this.CACHE_KEY_BENCHMARKS)
);
if (benchmarks) {
return benchmarks;
}
} catch {}
if (benchmarks) {
return benchmarks;
}
} catch {}
}
const benchmarkAssets: UniqueAsset[] =
((await this.propertyService.getByKey(
PROPERTY_BENCHMARKS
)) as UniqueAsset[]) ?? [];
const promises: Promise<number>[] = [];
const [quotes, assetProfiles] = await Promise.all([
@ -76,7 +86,8 @@ export class BenchmarkService {
await this.redisCacheService.set(
this.CACHE_KEY_BENCHMARKS,
JSON.stringify(benchmarks)
JSON.stringify(benchmarks),
ms('4 hours') / 1000
);
return benchmarks;

View File

@ -349,6 +349,7 @@ export class PortfolioController {
const portfolioPublicDetails: PortfolioPublicDetails = {
hasDetails,
alias: access.alias,
holdings: {}
};

View File

@ -62,7 +62,7 @@ export class UserService {
tags,
access: access.map((accessItem) => {
return {
alias: accessItem.User.alias,
alias: accessItem.alias,
id: accessItem.id
};
}),

View File

@ -7,7 +7,7 @@ import { Module } from '@nestjs/common';
@Module({
exports: [TwitterBotService],
imports: [BenchmarkModule, ConfigurationModule, PropertyModule, SymbolModule],
imports: [BenchmarkModule, ConfigurationModule, SymbolModule],
providers: [TwitterBotService]
})
export class TwitterBotModule {}

View File

@ -1,9 +1,7 @@
import { BenchmarkService } from '@ghostfolio/api/app/benchmark/benchmark.service';
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
PROPERTY_BENCHMARKS,
ghostfolioFearAndGreedIndexDataSource,
ghostfolioFearAndGreedIndexSymbol
} from '@ghostfolio/common/config';
@ -11,7 +9,6 @@ import {
resolveFearAndGreedIndex,
resolveMarketCondition
} from '@ghostfolio/common/helper';
import { UniqueAsset } from '@ghostfolio/common/interfaces';
import { Injectable, Logger } from '@nestjs/common';
import { isWeekend } from 'date-fns';
import { TwitterApi, TwitterApiReadWrite } from 'twitter-api-v2';
@ -23,7 +20,6 @@ export class TwitterBotService {
public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly configurationService: ConfigurationService,
private readonly propertyService: PropertyService,
private readonly symbolService: SymbolService
) {
this.twitterClient = new TwitterApi({
@ -82,14 +78,9 @@ export class TwitterBotService {
}
private async getBenchmarkListing(aMax: number) {
const benchmarkAssets: UniqueAsset[] =
((await this.propertyService.getByKey(
PROPERTY_BENCHMARKS
)) as UniqueAsset[]) ?? [];
const benchmarks = await this.benchmarkService.getBenchmarks(
benchmarkAssets
);
const benchmarks = await this.benchmarkService.getBenchmarks({
useCache: false
});
const benchmarkListing: string[] = [];

View File

@ -2,5 +2,13 @@
"/api": {
"target": "http://localhost:3333",
"secure": false
},
"/assets": {
"target": "http://localhost:3333",
"secure": false
},
"/ionicons": {
"target": "http://localhost:3333",
"secure": false
}
}

View File

@ -1,8 +1,15 @@
<table class="gf-table w-100" mat-table [dataSource]="dataSource">
<ng-container matColumnDef="granteeAlias">
<ng-container matColumnDef="alias">
<th *matHeaderCellDef class="px-1" i18n mat-header-cell>Alias</th>
<td *matCellDef="let element" class="px-1" mat-cell>
{{ element.alias }}
</td>
</ng-container>
<ng-container matColumnDef="grantee">
<th *matHeaderCellDef class="px-1" i18n mat-header-cell>Grantee</th>
<td *matCellDef="let element" class="px-1" mat-cell>
{{ element.granteeAlias }}
{{ element.grantee }}
</td>
</ng-container>

View File

@ -33,7 +33,7 @@ export class AccessTableComponent implements OnChanges, OnInit {
public ngOnInit() {}
public ngOnChanges() {
this.displayedColumns = ['granteeAlias', 'type', 'details'];
this.displayedColumns = ['alias', 'grantee', 'type', 'details'];
if (this.showActions) {
this.displayedColumns.push('actions');

View File

@ -1,13 +1,23 @@
<div class="align-items-center d-flex flex-row">
<div class="h2 mb-0 mr-2">{{ fearAndGreedIndexEmoji }}</div>
<div>
<div class="h4 mb-0">
<span class="mr-2">{{ fearAndGreedIndexText }}</span>
<small class="text-muted"
><strong>{{ fearAndGreedIndex }}</strong
>/100</small
>
<div class="position-relative">
<div class="align-items-center d-flex flex-row" [hidden]="!fearAndGreedIndex">
<div class="h2 mb-0 mr-2">{{ fearAndGreedIndexEmoji }}</div>
<div>
<div class="h4 mb-0">
<span class="mr-2">{{ fearAndGreedIndexText }}</span>
<small class="text-muted"
><strong>{{ fearAndGreedIndex }}</strong
>/100</small
>
</div>
<small class="d-block" i18n>Current Market Mood</small>
</div>
<small class="d-block" i18n>Current Market Mood</small>
</div>
<ngx-skeleton-loader
*ngIf="!fearAndGreedIndex"
animation="pulse"
class="position-absolute w-100"
[theme]="{
height: '100%'
}"
></ngx-skeleton-loader>
</div>

View File

@ -1,3 +1,8 @@
:host {
display: block;
ngx-skeleton-loader {
bottom: 0;
top: 0;
}
}

View File

@ -1,11 +1,12 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { FearAndGreedIndexComponent } from './fear-and-greed-index.component';
@NgModule({
declarations: [FearAndGreedIndexComponent],
exports: [FearAndGreedIndexComponent],
imports: [CommonModule]
imports: [CommonModule, NgxSkeletonLoaderModule]
})
export class GfFearAndGreedIndexModule {}

View File

@ -20,7 +20,6 @@
<gf-fear-and-greed-index
class="d-flex justify-content-center"
[fearAndGreedIndex]="fearAndGreedIndex"
[hidden]="isLoading"
></gf-fear-and-greed-index>
</div>
</div>

View File

@ -10,6 +10,7 @@
[baseCurrency]="user?.settings?.baseCurrency"
[hasPermissionToUpdateUserSettings]="!hasImpersonationId && hasPermissionToUpdateUserSettings"
[isLoading]="isLoading"
[language]="user?.settings?.language"
[locale]="user?.settings?.locale"
[summary]="summary"
(emergencyFundChanged)="onChangeEmergencyFund($event)"

View File

@ -7,6 +7,7 @@ import {
OnInit,
Output
} from '@angular/core';
import { getDateFnsLocale } from '@ghostfolio/common/helper';
import { PortfolioSummary } from '@ghostfolio/common/interfaces';
import { formatDistanceToNow } from 'date-fns';
@ -20,6 +21,7 @@ export class PortfolioSummaryComponent implements OnChanges, OnInit {
@Input() baseCurrency: string;
@Input() hasPermissionToUpdateUserSettings: boolean;
@Input() isLoading: boolean;
@Input() language: string;
@Input() locale: string;
@Input() summary: PortfolioSummary;
@ -34,7 +36,9 @@ export class PortfolioSummaryComponent implements OnChanges, OnInit {
public ngOnChanges() {
if (this.summary) {
if (this.summary.firstOrderDate) {
this.timeInMarket = formatDistanceToNow(this.summary.firstOrderDate);
this.timeInMarket = formatDistanceToNow(this.summary.firstOrderDate, {
locale: getDateFnsLocale(this.language)
});
} else {
this.timeInMarket = '-';
}

View File

@ -316,6 +316,7 @@ export class AccountPageComponent implements OnDestroy, OnInit {
const dialogRef = this.dialog.open(CreateOrUpdateAccessDialog, {
data: {
access: {
alias: '',
type: 'PUBLIC'
}
},
@ -331,7 +332,7 @@ export class AccountPageComponent implements OnDestroy, OnInit {
if (access) {
this.dataService
.postAccess({})
.postAccess({ alias: access.alias })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {

View File

@ -119,6 +119,7 @@
<mat-form-field appearance="outline" class="w-100">
<mat-select
name="language"
[disabled]="!hasPermissionToUpdateUserSettings"
[value]="language"
(selectionChange)="onChangeUserSetting('language', $event.value)"
>

View File

@ -1,6 +1,17 @@
<form #addAccessForm="ngForm" class="d-flex flex-column h-100">
<h1 i18n mat-dialog-title>Grant access</h1>
<div class="flex-grow-1" mat-dialog-content>
<div>
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Alias</mat-label>
<input
matInput
name="alias"
type="text"
[(ngModel)]="data.access.alias"
/>
</mat-form-field>
</div>
<div>
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Type</mat-label>

View File

@ -4,6 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog.component';
@ -16,6 +17,7 @@ import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog.com
MatButtonModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
ReactiveFormsModule
]

View File

@ -38,7 +38,6 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
public routeQueryParams: Subscription;
public user: User;
private readonly SEARCH_PLACEHOLDER = 'Filter by account or tag...';
private unsubscribeSubject = new Subject<void>();
public constructor(
@ -84,7 +83,9 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
this.isLoading = true;
this.activeFilters = filters;
this.placeholder =
this.activeFilters.length <= 0 ? this.SEARCH_PLACEHOLDER : '';
this.activeFilters.length <= 0
? $localize`Filter by account or tag...`
: '';
return this.dataService.fetchPortfolioDetails({
filters: this.activeFilters

View File

@ -2,7 +2,8 @@
<div class="row">
<div class="col">
<h3 class="h4 mb-3 text-center" i18n>
Hello, someone has shared a <strong>Portfolio</strong> with you!
Hello, {{ portfolioPublicDetails?.alias ?? 'someone' }} has shared a
<strong>Portfolio</strong> with you!
</h3>
</div>
</div>

View File

@ -26,7 +26,7 @@
<target state="translated">Empfänger</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">3</context>
<context context-type="linenumber">10</context>
</context-group>
</trans-unit>
<trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
@ -34,7 +34,7 @@
<target state="translated">Typ</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">10</context>
<context context-type="linenumber">17</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
@ -42,7 +42,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">6</context>
<context context-type="linenumber">17</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
@ -62,7 +62,7 @@
<target state="translated">Details</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">20</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="53ea2772322e7d4d21515bb0c6dead283f8e18a5" datatype="html">
@ -70,7 +70,7 @@
<target state="translated">Widerrufen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">54</context>
</context-group>
</trans-unit>
<trans-unit id="8264698726451826067" datatype="html">
@ -131,7 +131,7 @@
</trans-unit>
<trans-unit id="d04d5b5d13ac9acf9750f1807f0227eeee98b247" datatype="html">
<source>Total</source>
<target state="translated">Total</target>
<target state="translated">Gesamt</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">18</context>
@ -366,7 +366,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">14</context>
<context context-type="linenumber">25</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
@ -390,7 +390,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">32</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
@ -798,7 +798,7 @@
<target state="translated">Registrieren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="5207635742003539443" datatype="html">
@ -1070,7 +1070,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">45</context>
</context-group>
</trans-unit>
<trans-unit id="aee7d0de4e30405c1289745e4264e622b613632a" datatype="html">
@ -1438,7 +1438,7 @@
<target state="translated">Öffentlich</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">8</context>
<context context-type="linenumber">19</context>
</context-group>
</trans-unit>
<trans-unit id="5016419499983434110" datatype="html">
@ -1678,7 +1678,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">75</context>
<context context-type="linenumber">76</context>
</context-group>
</trans-unit>
<trans-unit id="2948175671993825247" datatype="html">
@ -1782,7 +1782,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">13</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="888f6842631dc20550ad7e9a9c45ef55bf45852b" datatype="html">
@ -2041,20 +2041,12 @@
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
<trans-unit id="7081e73933b030c02e11519f76884ef7cb5d99fc" datatype="html">
<source> Hello, someone has shared a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Portfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with you! </source>
<target state="new"/>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">4,6</context>
</context-group>
</trans-unit>
<trans-unit id="4056a76e7a710ab32285892a58d66f2d1a927796" datatype="html">
<source>Currencies</source>
<target state="translated">Währungen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">29</context>
<context context-type="linenumber">30</context>
</context-group>
</trans-unit>
<trans-unit id="3c3163d370916438f3b52ea17720bfb2a68a1709" datatype="html">
@ -2062,7 +2054,7 @@
<target state="translated">Kontinente</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">59</context>
<context context-type="linenumber">60</context>
</context-group>
</trans-unit>
<trans-unit id="a3d148b40a389fda0665eb583c9e434ec5ee1ced" datatype="html">
@ -2070,7 +2062,7 @@
<target state="new"/>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">131,133</context>
<context context-type="linenumber">132,134</context>
</context-group>
</trans-unit>
<trans-unit id="8298333184054476827" datatype="html">
@ -2206,7 +2198,7 @@
<target state="translated">Möchtest du diese Aktivität wirklich löschen?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">134</context>
</context-group>
</trans-unit>
<trans-unit id="170f7de02b14690fb9c1999a16926c0044bfd5c1" datatype="html">
@ -2422,7 +2414,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">89</context>
<context context-type="linenumber">90</context>
</context-group>
</trans-unit>
<trans-unit id="81eb53c18dfd116d6e54877444847b3091d92ab0" datatype="html">
@ -2434,7 +2426,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">99</context>
</context-group>
</trans-unit>
<trans-unit id="7233cd3a1ef8913fa5c6db7a29c88044646ceacc" datatype="html">
@ -2446,7 +2438,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="add4cd82e3e38a3110fe67b3c7df56e9602644ee" datatype="html">
@ -2503,7 +2495,7 @@
</trans-unit>
<trans-unit id="e34e2478d2d30c9d01758d01b7212411171b9bd5" datatype="html">
<source>Projected Total Amount</source>
<target state="translated">Geschätzter Gesamtbetrag</target>
<target state="translated">Projizierter Gesamtbetrag</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.html</context>
<context context-type="linenumber">44</context>
@ -2616,6 +2608,38 @@
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="303469635941752458" datatype="html">
<source>Filter by account, currency, symbol or type...</source>
<target state="translated">Filtern nach Konto, Währung, Symbol oder Typ...</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">291</context>
</context-group>
</trans-unit>
<trans-unit id="fbaaeb297e70b9a800acf841b9d26c19d60651ef" datatype="html">
<source>Alias</source>
<target state="translated">Alias</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">6</context>
</context-group>
</trans-unit>
<trans-unit id="3d14940af7de691ac27efb67bef3e974cbe3281c" datatype="html">
<source> Hello, <x id="INTERPOLATION" equiv-text="{{ portfolioPublicDetails?.alias ?? &apos;someone&apos; }}"/> has shared a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Portfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with you! </source>
<target state="translated"> Hallo, <x id="INTERPOLATION" equiv-text="{{ portfolioPublicDetails?.alias ?? &apos;jemand&apos; }}"/> hat ein <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Portfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> mit dir geteilt! </target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">4,7</context>
</context-group>
</trans-unit>
</body>
</file>

View File

@ -24,14 +24,14 @@
<source>Grantee</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">3</context>
<context context-type="linenumber">10</context>
</context-group>
</trans-unit>
<trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
<source>Type</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">10</context>
<context context-type="linenumber">17</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
@ -39,7 +39,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">6</context>
<context context-type="linenumber">17</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
@ -58,14 +58,14 @@
<source>Details</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">20</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="53ea2772322e7d4d21515bb0c6dead283f8e18a5" datatype="html">
<source>Revoke</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">54</context>
</context-group>
</trans-unit>
<trans-unit id="8264698726451826067" datatype="html">
@ -337,7 +337,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">14</context>
<context context-type="linenumber">25</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
@ -360,7 +360,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">32</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
@ -726,7 +726,7 @@
<source>Get Started</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="5207635742003539443" datatype="html">
@ -968,7 +968,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">45</context>
</context-group>
</trans-unit>
<trans-unit id="aee7d0de4e30405c1289745e4264e622b613632a" datatype="html">
@ -1292,7 +1292,7 @@
<source>Public</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">8</context>
<context context-type="linenumber">19</context>
</context-group>
</trans-unit>
<trans-unit id="5016419499983434110" datatype="html">
@ -1506,7 +1506,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">75</context>
<context context-type="linenumber">76</context>
</context-group>
</trans-unit>
<trans-unit id="2948175671993825247" datatype="html">
@ -1599,7 +1599,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">13</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="888f6842631dc20550ad7e9a9c45ef55bf45852b" datatype="html">
@ -1829,32 +1829,25 @@
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
<trans-unit id="7081e73933b030c02e11519f76884ef7cb5d99fc" datatype="html">
<source> Hello, someone has shared a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Portfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with you! </source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">4,6</context>
</context-group>
</trans-unit>
<trans-unit id="4056a76e7a710ab32285892a58d66f2d1a927796" datatype="html">
<source>Currencies</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">29</context>
<context context-type="linenumber">30</context>
</context-group>
</trans-unit>
<trans-unit id="3c3163d370916438f3b52ea17720bfb2a68a1709" datatype="html">
<source>Continents</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">59</context>
<context context-type="linenumber">60</context>
</context-group>
</trans-unit>
<trans-unit id="a3d148b40a389fda0665eb583c9e434ec5ee1ced" datatype="html">
<source> Ghostfolio empowers you to keep track of your wealth. </source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">131,133</context>
<context context-type="linenumber">132,134</context>
</context-group>
</trans-unit>
<trans-unit id="8298333184054476827" datatype="html">
@ -1973,7 +1966,7 @@
<source>Do you really want to delete this activity?</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">134</context>
</context-group>
</trans-unit>
<trans-unit id="170f7de02b14690fb9c1999a16926c0044bfd5c1" datatype="html">
@ -2107,7 +2100,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">89</context>
<context context-type="linenumber">90</context>
</context-group>
</trans-unit>
<trans-unit id="27fe3d097c64eaec7ff564358f80fb7ba795f484" datatype="html">
@ -2147,7 +2140,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="81eb53c18dfd116d6e54877444847b3091d92ab0" datatype="html">
@ -2158,7 +2151,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">99</context>
</context-group>
</trans-unit>
<trans-unit id="936788a5ab949fe0d70098ba051ac7a44999ff08" datatype="html">
@ -2329,6 +2322,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
<source>Filter by...</source>
@ -2337,6 +2334,31 @@
<context context-type="linenumber">129</context>
</context-group>
</trans-unit>
<trans-unit id="303469635941752458" datatype="html">
<source>Filter by account, currency, symbol or type...</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">291</context>
</context-group>
</trans-unit>
<trans-unit id="3d14940af7de691ac27efb67bef3e974cbe3281c" datatype="html">
<source> Hello, <x id="INTERPOLATION" equiv-text="{{ portfolioPublicDetails?.alias ?? &apos;someone&apos; }}"/> has shared a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Portfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with you! </source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">4,7</context>
</context-group>
</trans-unit>
<trans-unit id="fbaaeb297e70b9a800acf841b9d26c19d60651ef" datatype="html">
<source>Alias</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">6</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -1,6 +1,7 @@
import * as currencies from '@dinero.js/currencies';
import { DataSource } from '@prisma/client';
import { getDate, getMonth, getYear, parse, subDays } from 'date-fns';
import { de } from 'date-fns/locale';
import { ghostfolioScraperApiSymbolPrefix, locale } from './config';
import { Benchmark } from './interfaces';
@ -56,6 +57,14 @@ export function getCssVariable(aCssVariable: string) {
);
}
export function getDateFnsLocale(aLanguageCode: string) {
if (aLanguageCode === 'de') {
return de;
}
return undefined;
}
export function getDateFormatString(aLocale?: string) {
const formatObject = new Intl.DateTimeFormat(aLocale).formatToParts(
new Date()

View File

@ -1,5 +1,6 @@
export interface Access {
granteeAlias: string;
alias?: string;
grantee: string;
id: string;
type: 'PUBLIC' | 'RESTRICTED_VIEW';
}

View File

@ -1,6 +1,7 @@
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
export interface PortfolioPublicDetails {
alias?: string;
hasDetails: boolean;
holdings: {
[symbol: string]: Pick<

View File

@ -65,8 +65,6 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
public totalFees: number;
public totalValue: number;
private readonly SEARCH_PLACEHOLDER =
'Filter by account, currency, symbol or type...';
private readonly SEARCH_STRING_SEPARATOR = ',';
private unsubscribeSubject = new Subject<void>();
@ -289,7 +287,9 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
});
this.placeholder =
lowercaseSearchKeywords.length <= 0 ? this.SEARCH_PLACEHOLDER : '';
lowercaseSearchKeywords.length <= 0
? $localize`Filter by account, currency, symbol or type...`
: '';
this.searchKeywords = filters.map((filter) => {
return filter.label;

View File

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "1.183.0",
"version": "1.185.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"scripts": {
@ -24,7 +24,7 @@
"database:migrate": "prisma migrate deploy",
"database:push": "prisma db push",
"database:seed": "prisma db seed",
"database:setup": "yarn database:push && yarn database:seed && yarn database:baseline",
"database:setup": "yarn database:push && yarn database:seed",
"database:validate": "prisma validate",
"dep-graph": "nx dep-graph",
"e2e": "ng e2e",

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Access" ADD COLUMN "alias" TEXT;

View File

@ -1,7 +1,7 @@
generator client {
provider = "prisma-client-js"
previewFeatures = []
binaryTargets = ["debian-openssl-1.1.x", "native"]
binaryTargets = ["debian-openssl-1.1.x", "linux-arm64-openssl-1.1.x", "native"]
}
datasource db {
@ -10,6 +10,7 @@ datasource db {
}
model Access {
alias String?
createdAt DateTime @default(now())
granteeUserId String?
id String @id @default(uuid())

View File

@ -1,5 +0,0 @@
set -xe
echo "$DOCKER_HUB_ACCESS_TOKEN" | docker login -u "$DOCKER_HUB_USERNAME" --password-stdin
docker build -t ghostfolio/ghostfolio:$TRAVIS_TAG -t ghostfolio/ghostfolio:latest .
docker push ghostfolio/ghostfolio --all-tags