From 90270dbcd5612a16b4fde20e6194dd2a15901efd Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 5 Jul 2026 16:51:16 +0200 Subject: [PATCH] Add tags support in accounts --- .../holding-detail-dialog.component.ts | 15 ++++++++- .../holding-detail-dialog.html | 1 + .../tags-selector.component.html | 22 +++++++++++-- .../tags-selector/tags-selector.component.ts | 31 ++++++++++++------- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts index 3ddcd4e19..b2cdedbc5 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts @@ -77,7 +77,7 @@ import { swapVerticalOutline, walletOutline } from 'ionicons/icons'; -import { isNumber, round } from 'lodash'; +import { isNumber, round, uniqBy } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { switchMap } from 'rxjs/operators'; @@ -179,6 +179,7 @@ export class GfHoldingDetailDialogComponent implements OnInit { protected sortColumn = 'date'; protected sortDirection: SortDirection = 'desc'; protected tagsAvailable: Tag[]; + protected tagsOfAccounts: Tag[]; protected readonly translate = translate; protected user: User; protected value: number; @@ -265,6 +266,18 @@ export class GfHoldingDetailDialogComponent implements OnInit { .subscribe(({ accounts }) => { this.accounts = accounts; + this.tagsOfAccounts = uniqBy( + accounts.flatMap(({ tags }) => { + return tags ?? []; + }), + 'id' + ).map((tag) => { + return { + ...tag, + name: translate(tag.name) + }; + }); + this.changeDetectorRef.markForCheck(); }); 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 0007bedc5..04388bddb 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 @@ -427,6 +427,7 @@ [hasPermissionToCreateTag]="hasPermissionToCreateOwnTag" [readonly]="!data.hasPermissionToUpdateActivity" [tagsAvailable]="tagsAvailable" + [tagsReadOnly]="tagsOfAccounts" /> 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 82f465555..92ea2b210 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.html +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -2,10 +2,19 @@
@if (readonly) {
Tags
- @if (tags && tags.length > 0) { + @if ( + (tags && tags.length > 0) || (tagsReadOnly && tagsReadOnly.length > 0) + ) { - @for (tag of tags; track tag) { - {{ tag.name }} + @if (tagsReadOnly) { + @for (tag of tagsReadOnly; track tag) { + {{ tag.name }} + } + } + @if (tags) { + @for (tag of tags; track tag) { + {{ tag.name }} + } } } @else { @@ -15,6 +24,13 @@ Tags + @if (tagsReadOnly) { + @for (tag of tagsReadOnly; track tag.id) { + + {{ tag.name }} + + } + } @for (tag of tagsSelected(); track tag.id) { = new BehaviorSubject( [] @@ -87,12 +88,15 @@ export class GfTagsSelectorComponent } public ngOnInit() { - this.tagsSelected.set(this.tags); + this.tagsSelected.set(this.tags ?? []); this.updateFilters(); } - public ngOnChanges() { - this.tagsSelected.set(this.tags); + public ngOnChanges(changes: SimpleChanges) { + if (changes.tags) { + this.tagsSelected.set(this.tags ?? []); + } + this.updateFilters(); } @@ -123,7 +127,7 @@ export class GfTagsSelectorComponent this.tagInputControl.setValue(null); } - public onRemoveTag(tag: Tag) { + public onRemoveTag(tag: SelectedTag) { this.tagsSelected.update((tags) => { return tags.filter(({ id }) => { return id !== tag.id; @@ -159,15 +163,20 @@ export class GfTagsSelectorComponent private filterTags(query: string = ''): SelectedTag[] { const tags = this.tagsSelected() ?? []; - const tagIds = tags.map(({ id }) => { + const tagIds = [...tags, ...(this.tagsReadOnly ?? [])].map(({ id }) => { return id; }); - return this.tagsAvailable.filter(({ id, name }) => { - return ( - !tagIds.includes(id) && name.toLowerCase().includes(query.toLowerCase()) - ); - }); + return this.tagsAvailable + .filter(({ id, name }) => { + return ( + !tagIds.includes(id) && + name.toLowerCase().includes(query.toLowerCase()) + ); + }) + .sort((a, b) => { + return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); + }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars