From e496c49555f83309d648cc0eab4e15833e3f3079 Mon Sep 17 00:00:00 2001 From: Ken Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:28:04 +0700 Subject: [PATCH 1/9] Feature/set up Storybook stories for tags selector component (#4289) * feat(storybook): create story for tags selector * Update changelog --- CHANGELOG.md | 1 + .../ui/src/lib/logo/logo.component.stories.ts | 2 +- .../tags-selector.component.stories.ts | 62 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f86fccddb..5e4ae5b6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added a new static portfolio analysis rule: _Regional Market Cluster Risk_ (Europe) - Added a link to _Duck.ai_ to the _Copy AI prompt to clipboard_ action on the analysis page (experimental) - Extracted the tags selector to a reusable component used in the create or update activity dialog and holding detail dialog +- Added stories for the tags selector component ### Changed diff --git a/libs/ui/src/lib/logo/logo.component.stories.ts b/libs/ui/src/lib/logo/logo.component.stories.ts index c720ebd92..50f047184 100644 --- a/libs/ui/src/lib/logo/logo.component.stories.ts +++ b/libs/ui/src/lib/logo/logo.component.stories.ts @@ -25,7 +25,7 @@ export const Large: Story = { } }; -export const NoLabel: Story = { +export const WithoutLabel: Story = { args: { showLabel: false } diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts new file mode 100644 index 000000000..c1adf1286 --- /dev/null +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts @@ -0,0 +1,62 @@ +import { CommonModule } from '@angular/common'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { Meta, moduleMetadata, StoryObj } from '@storybook/angular'; + +import { GfTagsSelectorComponent } from './tags-selector.component'; + +export default { + title: 'Tags Selector', + component: GfTagsSelectorComponent, + decorators: [ + moduleMetadata({ + imports: [CommonModule, NoopAnimationsModule] + }) + ] +} as Meta; + +type Story = StoryObj; + +const OPTIONS = [ + { + id: '3ef7e6d9-4598-4eb2-b0e8-00e61cfc0ea6', + name: 'Gambling', + userId: 'c6a71541-d0e3-4e22-ae83-b5e5611b6695' + }, + { + id: 'EMERGENCY_FUND', + name: 'Emergency Fund', + userId: null + }, + { + id: 'RETIREMENT_FUND', + name: 'Retirement Fund', + userId: null + } +]; + +export const Default: Story = { + args: { + tags: [ + { + id: 'EMERGENCY_FUND', + name: 'Emergency Fund', + userId: null + } + ], + tagsAvailable: OPTIONS + } +}; + +export const WithoutValue: Story = { + args: { + tags: [], + tagsAvailable: OPTIONS + } +}; + +export const WithoutOptions: Story = { + args: { + tags: [], + tagsAvailable: [] + } +}; From 5b786ba1431536e30a587cd9b93e4e8a5b44acc2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 7 Feb 2025 10:32:25 +0100 Subject: [PATCH 2/9] Feature/improve error handling in CoinGecko service (#4287) * Improve error handling * Update changelog --- CHANGELOG.md | 1 + .../data-provider/coingecko/coingecko.service.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e4ae5b6d..2a6f45a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improved the caching of the portfolio snapshot in the portfolio calculator by expiring cache entries when a user changes tags in the holding detail dialog +- Improved the error handling in the _CoinGecko_ service - Improved the language localization for German (`de`) - Upgraded `svgmap` from version `2.6.0` to `2.12.2` diff --git a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts index 30dbe0ae1..fb1fa9b63 100644 --- a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts +++ b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts @@ -112,7 +112,7 @@ export class CoinGeckoService implements DataProviderInterface { [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; }> { try { - const { prices } = await fetch( + const { error, prices, status } = await fetch( `${ this.apiUrl }/coins/${symbol}/market_chart/range?vs_currency=${DEFAULT_CURRENCY.toLowerCase()}&from=${getUnixTime( @@ -124,6 +124,14 @@ export class CoinGeckoService implements DataProviderInterface { } ).then((res) => res.json()); + if (error?.status) { + throw new Error(error.status.error_message); + } + + if (status) { + throw new Error(status.error_message); + } + const result: { [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; } = { From dee612b2a289becde5a240c18714219cfc446165 Mon Sep 17 00:00:00 2001 From: Shaunak Das <51281688+shaun-ak@users.noreply.github.com> Date: Fri, 7 Feb 2025 22:38:14 +0530 Subject: [PATCH 3/9] Feature/add regional market cluster risk for emerging markets (#4291) * Add regional market cluster risk for emerging markets * Update changelog --- CHANGELOG.md | 1 + .../src/app/portfolio/portfolio.service.ts | 6 ++ apps/api/src/app/user/user.service.ts | 7 ++ .../emerging-markets.ts | 79 +++++++++++++++++++ .../x-ray-rules-settings.interface.ts | 1 + 5 files changed, 94 insertions(+) create mode 100644 apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a6f45a35..0c7008410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added a new static portfolio analysis rule: _Regional Market Cluster Risk_ (Emerging Markets) - Added a new static portfolio analysis rule: _Regional Market Cluster Risk_ (Europe) - Added a link to _Duck.ai_ to the _Copy AI prompt to clipboard_ action on the analysis page (experimental) - Extracted the tags selector to a reusable component used in the create or update activity dialog and holding detail dialog diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index bbe2a6ca5..72568f37a 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -15,6 +15,7 @@ import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/model import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets'; import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; +import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets'; import { RegionalMarketClusterRiskEurope } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/europe'; import { RegionalMarketClusterRiskNorthAmerica } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/north-america'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; @@ -1279,6 +1280,11 @@ export class PortfolioService { summary.ordersCount > 0 ? await this.rulesService.evaluate( [ + new RegionalMarketClusterRiskEmergingMarkets( + this.exchangeRateDataService, + marketsAdvancedTotalInBaseCurrency, + marketsAdvanced.emergingMarkets.valueInBaseCurrency + ), new RegionalMarketClusterRiskEurope( this.exchangeRateDataService, marketsAdvancedTotalInBaseCurrency, diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 44a29e737..1dae9d45b 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -13,6 +13,7 @@ import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/model import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets'; import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; +import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets'; import { RegionalMarketClusterRiskEurope } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/europe'; import { RegionalMarketClusterRiskNorthAmerica } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/north-america'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -271,6 +272,12 @@ export class UserService { undefined, undefined ).getSettings(user.Settings.settings), + RegionalMarketClusterRiskEmergingMarkets: + new RegionalMarketClusterRiskEmergingMarkets( + undefined, + undefined, + undefined + ).getSettings(user.Settings.settings), RegionalMarketClusterRiskEurope: new RegionalMarketClusterRiskEurope( undefined, undefined, diff --git a/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts b/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts new file mode 100644 index 000000000..2d9a3b394 --- /dev/null +++ b/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts @@ -0,0 +1,79 @@ +import { Rule } from '@ghostfolio/api/models/rule'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { UserSettings } from '@ghostfolio/common/interfaces'; + +import { Settings } from './interfaces/rule-settings.interface'; + +export class RegionalMarketClusterRiskEmergingMarkets extends Rule { + private currentValueInBaseCurrency: number; + private emergingMarketsValueInBaseCurrency: number; + + public constructor( + protected exchangeRateDataService: ExchangeRateDataService, + currentValueInBaseCurrency: number, + emergingMarketsValueInBaseCurrency: number + ) { + super(exchangeRateDataService, { + key: RegionalMarketClusterRiskEmergingMarkets.name, + name: 'Emerging Markets' + }); + + this.currentValueInBaseCurrency = currentValueInBaseCurrency; + this.emergingMarketsValueInBaseCurrency = + emergingMarketsValueInBaseCurrency; + } + + public evaluate(ruleSettings: Settings) { + const emergingMarketsValueRatio = this.currentValueInBaseCurrency + ? this.emergingMarketsValueInBaseCurrency / + this.currentValueInBaseCurrency + : 0; + + if (emergingMarketsValueRatio > ruleSettings.thresholdMax) { + return { + evaluation: `The Emerging Markets contribution of your current investment (${(emergingMarketsValueRatio * 100).toPrecision(3)}%) exceeds ${( + ruleSettings.thresholdMax * 100 + ).toPrecision(3)}%`, + value: false + }; + } else if (emergingMarketsValueRatio < ruleSettings.thresholdMin) { + return { + evaluation: `The Emerging Markets contribution of your current investment (${(emergingMarketsValueRatio * 100).toPrecision(3)}%) is below ${( + ruleSettings.thresholdMin * 100 + ).toPrecision(3)}%`, + value: false + }; + } + + return { + evaluation: `The Emerging Markets contribution of your current investment (${(emergingMarketsValueRatio * 100).toPrecision(3)}%) is within the range of ${( + ruleSettings.thresholdMin * 100 + ).toPrecision( + 3 + )}% and ${(ruleSettings.thresholdMax * 100).toPrecision(3)}%`, + value: true + }; + } + + public getConfiguration() { + return { + threshold: { + max: 1, + min: 0, + step: 0.01, + unit: '%' + }, + thresholdMax: true, + thresholdMin: true + }; + } + + public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { + return { + baseCurrency, + isActive: xRayRules?.[this.getKey()]?.isActive ?? true, + thresholdMax: xRayRules?.[this.getKey()]?.thresholdMax ?? 0.12, + thresholdMin: xRayRules?.[this.getKey()]?.thresholdMin ?? 0.08 + }; + } +} diff --git a/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts index f1ca5c683..4a31ef7b2 100644 --- a/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts +++ b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts @@ -9,6 +9,7 @@ export interface XRayRulesSettings { EconomicMarketClusterRiskEmergingMarkets?: RuleSettings; EmergencyFundSetup?: RuleSettings; FeeRatioInitialInvestment?: RuleSettings; + RegionalMarketClusterRiskEmergingMarkets?: RuleSettings; RegionalMarketClusterRiskEurope?: RuleSettings; RegionalMarketClusterRiskNorthAmerica?: RuleSettings; } From a8d353f29de6b35d6c4739d027fd6dfd6de4e2ec Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 8 Feb 2025 09:54:34 +0100 Subject: [PATCH 4/9] Feature/extend personal finance tools 20250208 (#4297) * Add Fey --- libs/common/src/lib/personal-finance-tools.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts index 63d5805cd..e4c820fb7 100644 --- a/libs/common/src/lib/personal-finance-tools.ts +++ b/libs/common/src/lib/personal-finance-tools.ts @@ -202,6 +202,16 @@ export const personalFinanceTools: Product[] = [ pricingPerYear: '$100', slogan: 'All your wealth, in one place.' }, + { + founded: 2018, + hasFreePlan: false, + hasSelfHostingAbility: false, + key: 'fey', + name: 'Fey', + origin: 'Canada', + pricingPerYear: '$300', + slogan: 'Make better investments.' + }, { founded: 2023, hasFreePlan: true, From a11e9c7f485b0eeb523c13c1c538152c9b0a7463 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 8 Feb 2025 09:56:39 +0100 Subject: [PATCH 5/9] Release 2.138.0 (#4298) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c7008410..1fc15b9c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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). -## Unreleased +## 2.138.0 - 2025-02-08 ### Added diff --git a/package-lock.json b/package-lock.json index e6be20a39..ec5cb3cb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.137.1", + "version": "2.138.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.137.1", + "version": "2.138.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 115e76bc5..7c9fda80c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.137.1", + "version": "2.138.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 72d5c713c582482012c05ab3e8874556e1e3eaad Mon Sep 17 00:00:00 2001 From: Ken Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 9 Feb 2025 02:58:55 +0700 Subject: [PATCH 6/9] Feature/import global styles in Storybook (#4302) * feat(ui): include styles in storybook build * chore(ui): cleanup * fix(ui): remove styles from storybook target * Update changelog --- CHANGELOG.md | 6 ++++++ libs/ui/.storybook/preview.js | 1 - libs/ui/project.json | 7 ++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fc15b9c1..62a8ace58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## Unreleased + +### Added + +- Added global styles to the _Storybook_ setup + ## 2.138.0 - 2025-02-08 ### Added diff --git a/libs/ui/.storybook/preview.js b/libs/ui/.storybook/preview.js index 37eb3a59d..e69de29bb 100644 --- a/libs/ui/.storybook/preview.js +++ b/libs/ui/.storybook/preview.js @@ -1 +0,0 @@ -// import '!style-loader!css-loader!sass-loader!../../../apps/client/src/styles.scss'; diff --git a/libs/ui/project.json b/libs/ui/project.json index 58e959344..1b3f0e4e7 100644 --- a/libs/ui/project.json +++ b/libs/ui/project.json @@ -44,7 +44,12 @@ "outputDir": "dist/storybook/ui", "configDir": "libs/ui/.storybook", "browserTarget": "ui:build-storybook", - "compodoc": false + "compodoc": false, + "styles": [ + "apps/client/src/assets/fonts/inter.css", + "apps/client/src/styles/theme.scss", + "apps/client/src/styles.scss" + ] }, "configurations": { "ci": { From 56f943824e8b8852c16ff3cb2d4410abd04d7b17 Mon Sep 17 00:00:00 2001 From: Ken Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 9 Feb 2025 03:20:47 +0700 Subject: [PATCH 7/9] Feature/introduce readonly attribute in tags selector component (#4301) * feat(ui): introduce readonly attribute * Update changelog --- CHANGELOG.md | 1 + .../holding-detail-dialog.html | 33 ++------ .../tags-selector.component.html | 79 +++++++++++-------- .../tags-selector.component.stories.ts | 19 +++++ .../tags-selector/tags-selector.component.ts | 1 + 5 files changed, 75 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62a8ace58..4cae16cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Extended the tags selector component by a `readonly` attribute - Added global styles to the _Storybook_ setup ## 2.138.0 - 2025-02-08 diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index a20c9af7a..d820ddf7d 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -366,33 +366,12 @@ -
-
- -
-
- - @if (!data.hasPermissionToUpdateOrder && tagsAvailable?.length > 0) { -
-
-
Tags
- - @for (tag of tags; track tag) { - {{ tag.name }} - } - -
-
- } + @if ( dataSource?.data.length > 0 && diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.html b/libs/ui/src/lib/tags-selector/tags-selector.component.html index 55f8a39f2..1b6817724 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.html +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1,32 +1,49 @@ - - Tags - - @for (tag of tagsSelected(); track tag.id) { - - {{ tag.name }} - - +
+
+ @if (readonly) { +
Tags
+ @if (tags?.length > 0) { + + @for (tag of tags; track tag) { + {{ tag.name }} + } + + } @else { +
-
+ } + } @else { + + Tags + + @for (tag of tagsSelected(); track tag.id) { + + {{ tag.name }} + + + } + + + + @for (tag of filteredOptions | async; track tag.id) { + + {{ tag.name }} + + } + + } - - - - @for (tag of filteredOptions | async; track tag.id) { - - {{ tag.name }} - - } - - +
+
diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts index c1adf1286..4fd0f7e77 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts @@ -47,6 +47,25 @@ export const Default: Story = { } }; +export const Readonly: Story = { + args: { + readonly: true, + tags: [ + { + id: 'EMERGENCY_FUND', + name: 'Emergency Fund', + userId: null + }, + { + id: 'RETIREMENT_FUND', + name: 'Retirement Fund', + userId: null + } + ], + tagsAvailable: OPTIONS + } +}; + export const WithoutValue: Story = { args: { tags: [], diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.ts index 77c776ece..6b59d53f4 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.ts @@ -42,6 +42,7 @@ import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; templateUrl: 'tags-selector.component.html' }) export class GfTagsSelectorComponent implements OnInit, OnChanges, OnDestroy { + @Input() readonly = false; @Input() tags: Tag[]; @Input() tagsAvailable: Tag[]; From 35ef06d27a840149ad15c53f99bca7694386581a Mon Sep 17 00:00:00 2001 From: Ken Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 9 Feb 2025 16:24:44 +0700 Subject: [PATCH 8/9] Feature/allow creating custom tags in tag selector component (#4305) * feat(ui): allow creating custom tags * feat(ui): add new story * Update changelog --- CHANGELOG.md | 1 + .../lib/tags-selector/tags-selector.component.html | 11 +++++++++++ .../tags-selector.component.stories.ts | 14 ++++++++++++++ .../lib/tags-selector/tags-selector.component.ts | 11 ++++++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cae16cac..295158c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Extended the tags selector component by a `readonly` attribute +- Extended the tags selector component to support creating custom tags - Added global styles to the _Storybook_ setup ## 2.138.0 - 2025-02-08 diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.html b/libs/ui/src/lib/tags-selector/tags-selector.component.html index 1b6817724..4f3929423 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.html +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -42,6 +42,17 @@ {{ tag.name }} } + + @if (hasPermissionToCreateTags && tagInputControl.value) { + + + + Create "{{ + tagInputControl.value.trim() + }}" + + + }
} diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts index 4fd0f7e77..8d1431b46 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts @@ -47,6 +47,20 @@ export const Default: Story = { } }; +export const CreateCustomTags: Story = { + args: { + hasPermissionToCreateTags: true, + tags: [ + { + id: 'EMERGENCY_FUND', + name: 'Emergency Fund', + userId: null + } + ], + tagsAvailable: OPTIONS + } +}; + export const Readonly: Story = { args: { readonly: true, diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.ts index 6b59d53f4..611c1e938 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.ts @@ -42,6 +42,7 @@ import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; templateUrl: 'tags-selector.component.html' }) export class GfTagsSelectorComponent implements OnInit, OnChanges, OnDestroy { + @Input() hasPermissionToCreateTags = false; @Input() readonly = false; @Input() tags: Tag[]; @Input() tagsAvailable: Tag[]; @@ -76,10 +77,18 @@ export class GfTagsSelectorComponent implements OnInit, OnChanges, OnDestroy { } public onAddTag(event: MatAutocompleteSelectedEvent) { - const tag = this.tagsAvailable.find(({ id }) => { + let tag = this.tagsAvailable.find(({ id }) => { return id === event.option.value; }); + if (!tag && this.hasPermissionToCreateTags) { + tag = { + id: undefined, + name: event.option.value as string, + userId: null + }; + } + this.tagsSelected.update((tags) => { return [...(tags ?? []), tag]; }); From f92c8777693380ee19ed890382e070a0f7e84cea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 9 Feb 2025 12:13:53 +0100 Subject: [PATCH 9/9] Feature/update locales 20250209 (#4304) * Update translations * Update changelog --------- Co-authored-by: github-actions[bot] Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 4 ++++ apps/client/src/locales/messages.ca.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.de.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.es.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.fr.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.it.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.nl.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.pl.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.pt.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.tr.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.uk.xlf | 16 ++++++++++++---- apps/client/src/locales/messages.xlf | 15 +++++++++++---- apps/client/src/locales/messages.zh.xlf | 16 ++++++++++++---- 13 files changed, 147 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 295158c97..349c140a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Extended the tags selector component to support creating custom tags - Added global styles to the _Storybook_ setup +### Changed + +- Improved the language localization for German (`de`) + ## 2.138.0 - 2025-02-08 ### Added diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index 3bee762a2..82f3f96bb 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -2218,12 +2218,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -2639,7 +2639,7 @@ Informar d’un Problema amb les Dades apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 9f5fd16f8..0040f8cb6 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -1357,12 +1357,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -1370,7 +1370,7 @@ Datenfehler melden apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Erstelle + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index c71d49f5d..bc6a62411 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -1358,12 +1358,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -1371,7 +1371,7 @@ Reporta un anomalía de los datos apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7749,6 +7749,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 521cfe6fa..353a2a3f6 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -969,12 +969,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -1718,7 +1718,7 @@ Signaler une Erreur de Données apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 4d428d419..c6cb7ac7a 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -1358,12 +1358,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -1371,7 +1371,7 @@ Segnala un’anomalia dei dati apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7749,6 +7749,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index a3c6c6d67..53efeab95 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -1357,12 +1357,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -1370,7 +1370,7 @@ Gegevensstoring melden apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 135e5847f..2942a4898 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -2046,12 +2046,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -2803,7 +2803,7 @@ Zgłoś Błąd Danych apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 37d4688f7..8b9b7ac03 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -1665,12 +1665,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -1678,7 +1678,7 @@ Dados do Relatório com Problema apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 0c6c72067..3c7d3f102 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -1782,12 +1782,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -2647,7 +2647,7 @@ Rapor Veri Sorunu apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 235d99bf8..26690077b 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -2258,12 +2258,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -2767,7 +2767,7 @@ Повідомити про збій даних apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7748,6 +7748,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 5a70868dc..ac05bc01a 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -1943,12 +1943,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -2623,7 +2623,7 @@ Report Data Glitch apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7007,6 +7007,13 @@ 154 + + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + + diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 984c0bed1..680906979 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -2063,12 +2063,12 @@ 87 - apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 387 + libs/ui/src/lib/tags-selector/tags-selector.component.html + 4 libs/ui/src/lib/tags-selector/tags-selector.component.html - 2 + 16 @@ -2820,7 +2820,7 @@ 报告数据故障 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 406 + 385 @@ -7749,6 +7749,14 @@ 154 + + Create + Create + + libs/ui/src/lib/tags-selector/tags-selector.component.html + 50 + +