From 7b899489b8b04e76cd9b812d65310dc9708ca5b9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:57:59 +0200 Subject: [PATCH] Feature/add total column to tag management (#7970) * Add total column (accountCount + activityCount) * Update changelog --- CHANGELOG.md | 6 ++++ .../admin-tag/admin-tag.component.html | 18 ++++++++++++ .../admin-tag/admin-tag.component.ts | 28 ++++++++++++++----- libs/common/src/lib/types/index.ts | 2 ++ ...ag-with-account-and-activity-count.type.ts | 6 ++++ libs/ui/src/lib/services/data.service.ts | 5 ++-- 6 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 libs/common/src/lib/types/tag-with-account-and-activity-count.type.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e795778177..ff42504d49 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 the total column to the table of the tag management in the admin control panel + ## 3.75.0 - 2026-09-28 ### Changed diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.html b/apps/client/src/app/components/admin-tag/admin-tag.component.html index 6cd9c12599..83f7b559d4 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.html +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -77,6 +77,24 @@ + + + Total + + + + + + diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.ts b/apps/client/src/app/components/admin-tag/admin-tag.component.ts index 12ac1f368b..b08b144cf8 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.ts +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.ts @@ -7,6 +7,7 @@ import { getLowercase, isSystemTag } from '@ghostfolio/common/helper'; +import { TagWithAccountAndActivityCount } from '@ghostfolio/common/types'; import { translate } from '@ghostfolio/ui/i18n'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { DataService } from '@ghostfolio/ui/services'; @@ -32,7 +33,6 @@ import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; -import { Tag } from '@prisma/client'; import { addIcons } from 'ionicons'; import { createOutline, @@ -63,17 +63,20 @@ import { CreateOrUpdateTagDialogParams } from './create-or-update-tag-dialog/int export class GfAdminTagComponent implements OnInit { public readonly locale = input(getLocale()); - protected dataSource = new MatTableDataSource(); + protected dataSource = + new MatTableDataSource(); + protected readonly displayedColumns = [ 'name', 'userId', 'accounts', 'activities', + 'total', 'actions' ]; protected readonly isSystemTag = isSystemTag; protected readonly pageSize = DEFAULT_PAGE_SIZE; - protected tags: Tag[]; + protected tags: TagWithAccountAndActivityCount[]; protected readonly translate = translate; private readonly deviceType = computed( @@ -120,6 +123,13 @@ export class GfAdminTagComponent implements OnInit { this.fetchTags(); } + protected getTotalCount({ + accountCount, + activityCount + }: TagWithAccountAndActivityCount) { + return accountCount + activityCount; + } + protected onDeleteTag(aId: string) { this.notificationService.confirm({ confirmFn: () => { @@ -130,7 +140,7 @@ export class GfAdminTagComponent implements OnInit { }); } - protected onUpdateTag({ id }: Tag) { + protected onUpdateTag({ id }: TagWithAccountAndActivityCount) { this.router.navigate([], { queryParams: { editTagDialog: true, tagId: id } }); @@ -164,9 +174,13 @@ export class GfAdminTagComponent implements OnInit { this.dataSource.sort = this.sort(); this.dataSource.sortingDataAccessor = (tag, path) => { - return path === 'name' - ? translate(tag.name).toLocaleLowerCase() - : (getLowercase(tag, path) as number | string); + if (path === 'name') { + return translate(tag.name).toLocaleLowerCase(); + } else if (path === 'totalCount') { + return this.getTotalCount(tag); + } + + return getLowercase(tag, path) as number | string; }; this.dataService.updateInfo(); diff --git a/libs/common/src/lib/types/index.ts b/libs/common/src/lib/types/index.ts index 9a44efc1af..fb0f6462c6 100644 --- a/libs/common/src/lib/types/index.ts +++ b/libs/common/src/lib/types/index.ts @@ -24,6 +24,7 @@ import type { PropertyKey } from './property-key.type'; import type { RequestWithUser } from './request-with-user.type'; import type { SectorName } from './sector-name.type'; import type { SubscriptionOfferKey } from './subscription-offer-key.type'; +import type { TagWithAccountAndActivityCount } from './tag-with-account-and-activity-count.type'; import type { ToggleOption } from './toggle-option.type'; import type { UserWithSettings } from './user-with-settings.type'; import type { ViewMode } from './view-mode.type'; @@ -55,6 +56,7 @@ export type { RequestWithUser, SectorName, SubscriptionOfferKey, + TagWithAccountAndActivityCount, ToggleOption, UserWithSettings, ViewMode diff --git a/libs/common/src/lib/types/tag-with-account-and-activity-count.type.ts b/libs/common/src/lib/types/tag-with-account-and-activity-count.type.ts new file mode 100644 index 0000000000..662e0f5ce9 --- /dev/null +++ b/libs/common/src/lib/types/tag-with-account-and-activity-count.type.ts @@ -0,0 +1,6 @@ +import { Tag } from '@prisma/client'; + +export type TagWithAccountAndActivityCount = Tag & { + accountCount: number; + activityCount: number; +}; diff --git a/libs/ui/src/lib/services/data.service.ts b/libs/ui/src/lib/services/data.service.ts index 2b390df3c5..e09632079c 100644 --- a/libs/ui/src/lib/services/data.service.ts +++ b/libs/ui/src/lib/services/data.service.ts @@ -62,7 +62,8 @@ import { filterGlobalPermissions } from '@ghostfolio/common/permissions'; import type { AiPromptMode, DateRange, - GroupBy + GroupBy, + TagWithAccountAndActivityCount } from '@ghostfolio/common/types'; import { translate } from '@ghostfolio/ui/i18n'; @@ -843,7 +844,7 @@ export class DataService { } public fetchTags() { - return this.http.get('/api/v1/tags'); + return this.http.get('/api/v1/tags'); } public fetchWatchlist() {