From 13bacbd0e248d4a7034abbcf9d39ca933139767b Mon Sep 17 00:00:00 2001 From: David Requeno Date: Tue, 29 Jul 2025 23:23:23 -0600 Subject: [PATCH] fix: Restore deleted access-table component files --- .../access-table/access-table.component.html | 84 +++++++++++++ .../access-table/access-table.component.scss | 11 ++ .../access-table/access-table.component.ts | 111 ++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 apps/client/src/app/components/access-table/access-table.component.html create mode 100644 apps/client/src/app/components/access-table/access-table.component.scss create mode 100644 apps/client/src/app/components/access-table/access-table.component.ts diff --git a/apps/client/src/app/components/access-table/access-table.component.html b/apps/client/src/app/components/access-table/access-table.component.html new file mode 100644 index 000000000..44aee1644 --- /dev/null +++ b/apps/client/src/app/components/access-table/access-table.component.html @@ -0,0 +1,84 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Alias + {{ element.alias }} + Grantee + {{ element.grantee }} + Permission +
+ @if (element.permissions.includes('READ')) { + + View + } @else if (element.permissions.includes('READ_RESTRICTED')) { + + Restricted view + } +
+
Details + @if (element.type === 'PUBLIC') { + + @if (user?.settings?.isExperimentalFeatures) { +
+ GET {{ baseUrl }}/api/v1/public/{{ + element.id + }}/portfolio +
+ } + } +
+ + + @if (element.type === 'PUBLIC') { + +
+ } + +
+
+
diff --git a/apps/client/src/app/components/access-table/access-table.component.scss b/apps/client/src/app/components/access-table/access-table.component.scss new file mode 100644 index 000000000..22a5d6732 --- /dev/null +++ b/apps/client/src/app/components/access-table/access-table.component.scss @@ -0,0 +1,11 @@ +:host { + display: block; + + a { + color: rgba(var(--palette-primary-500), 1); + + &:hover { + color: rgba(var(--palette-primary-300), 1); + } + } +} diff --git a/apps/client/src/app/components/access-table/access-table.component.ts b/apps/client/src/app/components/access-table/access-table.component.ts new file mode 100644 index 000000000..c94f86df1 --- /dev/null +++ b/apps/client/src/app/components/access-table/access-table.component.ts @@ -0,0 +1,111 @@ +import { ConfirmationDialogType } from '@ghostfolio/client/core/notification/confirmation-dialog/confirmation-dialog.type'; +import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; +import { Access, User } from '@ghostfolio/common/interfaces'; +import { publicRoutes } from '@ghostfolio/common/routes/routes'; + +import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'; +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + CUSTOM_ELEMENTS_SCHEMA, + EventEmitter, + Input, + OnChanges, + Output +} from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { RouterModule } from '@angular/router'; +import { IonIcon } from '@ionic/angular/standalone'; +import { addIcons } from 'ionicons'; +import { + ellipsisHorizontal, + linkOutline, + lockClosedOutline, + lockOpenOutline +} from 'ionicons/icons'; +import ms from 'ms'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + ClipboardModule, + CommonModule, + IonIcon, + MatButtonModule, + MatMenuModule, + MatTableModule, + RouterModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-access-table', + templateUrl: './access-table.component.html', + styleUrls: ['./access-table.component.scss'] +}) +export class GfAccessTableComponent implements OnChanges { + @Input() accesses: Access[]; + @Input() showActions: boolean; + @Input() user: User; + + @Output() accessDeleted = new EventEmitter(); + + public baseUrl = window.location.origin; + public dataSource: MatTableDataSource; + public displayedColumns = []; + + public constructor( + private clipboard: Clipboard, + private notificationService: NotificationService, + private snackBar: MatSnackBar + ) { + addIcons({ + ellipsisHorizontal, + linkOutline, + lockClosedOutline, + lockOpenOutline + }); + } + + public ngOnChanges() { + this.displayedColumns = ['alias', 'grantee', 'type', 'details']; + + if (this.showActions) { + this.displayedColumns.push('actions'); + } + + if (this.accesses) { + this.dataSource = new MatTableDataSource(this.accesses); + } + } + + public getPublicUrl(aId: string): string { + const languageCode = this.user.settings.language; + + return `${this.baseUrl}/${languageCode}/${publicRoutes.public.path}/${aId}`; + } + + public onCopyUrlToClipboard(aId: string): void { + this.clipboard.copy(this.getPublicUrl(aId)); + + this.snackBar.open( + '✅ ' + $localize`Link has been copied to the clipboard`, + undefined, + { + duration: ms('3 seconds') + } + ); + } + + public onDeleteAccess(aId: string) { + this.notificationService.confirm({ + confirmFn: () => { + this.accessDeleted.emit(aId); + }, + confirmType: ConfirmationDialogType.Warn, + title: $localize`Do you really want to revoke this granted access?` + }); + } +}