From 85cc72627bf980f13029bf7c47a425ff060d38b6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:42:25 +0200 Subject: [PATCH] Feature/add user id to tag database schema (#3837) * Add user id to tag database schema * Update changelog --- CHANGELOG.md | 11 +++++++++++ apps/api/src/app/info/info.service.ts | 2 +- apps/api/src/app/platform/platform.controller.ts | 1 + apps/api/src/app/tag/tag.controller.ts | 1 + apps/api/src/app/tag/tag.service.ts | 3 ++- apps/api/src/app/user/user.service.ts | 2 +- apps/api/src/services/tag/tag.service.ts | 7 +++++-- .../admin-platform/admin-platform.component.ts | 4 ++-- .../components/admin-tag/admin-tag.component.html | 14 ++++++++++++++ .../components/admin-tag/admin-tag.component.ts | 6 +++--- .../holding-detail-dialog.component.ts | 12 ++++++------ .../create-or-update-activity-dialog.component.ts | 6 +++--- libs/common/src/lib/permissions.ts | 4 ++++ package.json | 1 + .../20240928171744_added_user_to_tag/migration.sql | 11 +++++++++++ prisma/schema.prisma | 6 +++++- 16 files changed, 71 insertions(+), 20 deletions(-) create mode 100644 prisma/migrations/20240928171744_added_user_to_tag/migration.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a3283f75..fa3fc0bdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added read `permissions` to the `Platform` model +- Added read `permissions` to the `Tag` model +- Added `userId` to the `Tag` database schema + ### Changed - Considered the availability of the date range selector in the assistant per view @@ -17,6 +23,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `prisma` from version `5.19.1` to `5.20.0` - Upgraded `webpack-bundle-analyzer` from version `4.10.1` to `4.10.2` +### Fixed + +- Fixed the content height of the create or update platform dialog in the admin control +- Fixed the content height of the create or update tag dialog in the admin control + ## 2.110.0 - 2024-09-24 ### Changed diff --git a/apps/api/src/app/info/info.service.ts b/apps/api/src/app/info/info.service.ts index acd7b315b..ee225e769 100644 --- a/apps/api/src/app/info/info.service.ts +++ b/apps/api/src/app/info/info.service.ts @@ -114,7 +114,7 @@ export class InfoService { }), this.getStatistics(), this.getSubscriptions(), - this.tagService.get() + this.tagService.getPublic() ]); if (isUserSignupEnabled) { diff --git a/apps/api/src/app/platform/platform.controller.ts b/apps/api/src/app/platform/platform.controller.ts index 4512e7df0..c91f58cf8 100644 --- a/apps/api/src/app/platform/platform.controller.ts +++ b/apps/api/src/app/platform/platform.controller.ts @@ -26,6 +26,7 @@ export class PlatformController { public constructor(private readonly platformService: PlatformService) {} @Get() + @HasPermission(permissions.readPlatforms) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async getPlatforms() { return this.platformService.getPlatformsWithAccountCount(); diff --git a/apps/api/src/app/tag/tag.controller.ts b/apps/api/src/app/tag/tag.controller.ts index 4c37b9dfe..6198a0bf5 100644 --- a/apps/api/src/app/tag/tag.controller.ts +++ b/apps/api/src/app/tag/tag.controller.ts @@ -26,6 +26,7 @@ export class TagController { public constructor(private readonly tagService: TagService) {} @Get() + @HasPermission(permissions.readTags) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async getTags() { return this.tagService.getTagsWithActivityCount(); diff --git a/apps/api/src/app/tag/tag.service.ts b/apps/api/src/app/tag/tag.service.ts index b077cbe1c..c4a5447ac 100644 --- a/apps/api/src/app/tag/tag.service.ts +++ b/apps/api/src/app/tag/tag.service.ts @@ -56,10 +56,11 @@ export class TagService { } }); - return tagsWithOrderCount.map(({ _count, id, name }) => { + return tagsWithOrderCount.map(({ _count, id, name, userId }) => { return { id, name, + userId, activityCount: _count.orders }; }); diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index edb27aead..a3dfc2fca 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -70,7 +70,7 @@ export class UserService { }, where: { userId: id } }), - this.tagService.getByUser(id) + this.tagService.getInUseByUser(id) ]); let systemMessage: SystemMessage; diff --git a/apps/api/src/services/tag/tag.service.ts b/apps/api/src/services/tag/tag.service.ts index 25e0a32c4..5426a0582 100644 --- a/apps/api/src/services/tag/tag.service.ts +++ b/apps/api/src/services/tag/tag.service.ts @@ -6,15 +6,18 @@ import { Injectable } from '@nestjs/common'; export class TagService { public constructor(private readonly prismaService: PrismaService) {} - public async get() { + public async getPublic() { return this.prismaService.tag.findMany({ orderBy: { name: 'asc' + }, + where: { + userId: null } }); } - public async getByUser(userId: string) { + public async getInUseByUser(userId: string) { return this.prismaService.tag.findMany({ orderBy: { name: 'asc' diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.ts b/apps/client/src/app/components/admin-platform/admin-platform.component.ts index bef4bc9b0..2c0aa345e 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.ts +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.ts @@ -139,7 +139,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy { url: null } }, - height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + height: this.deviceType === 'mobile' ? '97.5vh' : undefined, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); @@ -176,7 +176,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy { url } }, - height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + height: this.deviceType === 'mobile' ? '97.5vh' : undefined, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); 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 046d0a0a5..f69579ab8 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 @@ -34,6 +34,20 @@ + + + User + + + {{ element.userId }} + + + = new MatTableDataSource(); public deviceType: string; - public displayedColumns = ['name', 'activities', 'actions']; + public displayedColumns = ['name', 'userId', 'activities', 'actions']; public tags: Tag[]; private unsubscribeSubject = new Subject(); @@ -138,7 +138,7 @@ export class AdminTagComponent implements OnInit, OnDestroy { name: null } }, - height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + height: this.deviceType === 'mobile' ? '97.5vh' : undefined, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); @@ -174,7 +174,7 @@ export class AdminTagComponent implements OnInit, OnDestroy { name } }, - height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + height: this.deviceType === 'mobile' ? '97.5vh' : undefined, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); 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 8541f65ac..027c06bd6 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 @@ -158,10 +158,10 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { { id: this.data.symbol, type: 'SYMBOL' } ]; - this.tagsAvailable = tags.map(({ id, name }) => { + this.tagsAvailable = tags.map((tag) => { return { - id, - name: translate(name) + ...tag, + name: translate(tag.name) }; }); @@ -320,10 +320,10 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { this.sectors = {}; this.SymbolProfile = SymbolProfile; - this.tags = tags.map(({ id, name }) => { + this.tags = tags.map((tag) => { return { - id, - name: translate(name) + ...tag, + name: translate(tag.name) }; }); diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 323796bef..4690ab6a8 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -81,10 +81,10 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.currencies = currencies; this.defaultDateFormat = getDateFormatString(this.locale); this.platforms = platforms; - this.tagsAvailable = tags.map(({ id, name }) => { + this.tagsAvailable = tags.map((tag) => { return { - id, - name: translate(name) + ...tag, + name: translate(tag.name) }; }); diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 1a235f1a9..ab443ea5e 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -31,6 +31,8 @@ export const permissions = { enableSubscriptionInterstitial: 'enableSubscriptionInterstitial', enableSystemMessage: 'enableSystemMessage', impersonateAllUsers: 'impersonateAllUsers', + readPlatforms: 'readPlatforms', + readTags: 'readTags', reportDataGlitch: 'reportDataGlitch', toggleReadOnlyMode: 'toggleReadOnlyMode', updateAccount: 'updateAccount', @@ -64,6 +66,8 @@ export function getPermissions(aRole: Role): string[] { permissions.deletePlatform, permissions.deleteTag, permissions.deleteUser, + permissions.readPlatforms, + permissions.readTags, permissions.updateAccount, permissions.updateAuthDevice, permissions.updateOrder, diff --git a/package.json b/package.json index 5b1dfcbc6..dcb99f7ed 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "ng": "nx", "nx": "nx", "postinstall": "prisma generate", + "prisma": "prisma", "replace-placeholders-in-build": "node ./replace.build.js", "start": "node dist/apps/api/main", "start:client": "nx run client:copy-assets && nx run client:serve --configuration=development-en --hmr -o", diff --git a/prisma/migrations/20240928171744_added_user_to_tag/migration.sql b/prisma/migrations/20240928171744_added_user_to_tag/migration.sql new file mode 100644 index 000000000..679bec843 --- /dev/null +++ b/prisma/migrations/20240928171744_added_user_to_tag/migration.sql @@ -0,0 +1,11 @@ +-- DropIndex +DROP INDEX "Tag_name_key"; + +-- AlterTable +ALTER TABLE "Tag" ADD COLUMN "userId" TEXT; + +-- CreateIndex +CREATE UNIQUE INDEX "Tag_name_userId_key" ON "Tag"("name", "userId"); + +-- AddForeignKey +ALTER TABLE "Tag" ADD CONSTRAINT "Tag_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c5ced391a..0ae1df65a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -213,9 +213,12 @@ model Subscription { model Tag { id String @id @default(uuid()) - name String @unique + name String orders Order[] + userId String? + User User? @relation(fields: [userId], onDelete: Cascade, references: [id]) + @@unique([name, userId]) @@index([name]) } @@ -236,6 +239,7 @@ model User { Order Order[] Settings Settings? Subscription Subscription[] + Tag Tag[] @@index([accessToken]) @@index([createdAt])