();
protected readonly displayedColumns = computed(() => {
- const columns = [
- 'alias',
- 'grantee',
- 'type',
- 'lastUsedAt',
- 'expiresAt',
- 'details'
- ];
+ const columns = ['alias', 'grantee', 'type', 'lastUsedAt', 'expiresAt'];
if (this.showActions()) {
columns.push('actions');
@@ -109,8 +100,6 @@ export class GfAccessTableComponent {
return !this.accesses();
});
- protected readonly mcpEndpoint = MCP_ENDPOINT;
-
private readonly clipboard = inject(Clipboard);
private readonly dataService = inject(DataService);
private readonly notificationService = inject(NotificationService);
@@ -121,7 +110,6 @@ export class GfAccessTableComponent {
copyOutline,
createOutline,
ellipsisHorizontal,
- linkOutline,
removeCircleOutline,
trashOutline
});
@@ -142,18 +130,6 @@ export class GfAccessTableComponent {
return `${this.baseUrl}/${languageCode}/${publicRoutes.public.path}/${aId}`;
}
- protected onCopyIdToClipboard(aId: string) {
- this.clipboard.copy(aId);
-
- this.snackBar.open(
- '✅ ' + $localize`Identifier has been copied to the clipboard`,
- undefined,
- {
- duration: ms('3 seconds')
- }
- );
- }
-
protected onCopyUrlToClipboard(aId: string) {
this.clipboard.copy(this.getPublicUrl(aId));
diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
index 8c2bb0353a..98275e5e78 100644
--- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
+++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
@@ -1,5 +1,5 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
-import { DEFAULT_LOCALE } from '@ghostfolio/common/config';
+import { DEFAULT_LOCALE, MCP_ENDPOINT } from '@ghostfolio/common/config';
import { CreateAccessDto, UpdateAccessDto } from '@ghostfolio/common/dtos';
import { canApplyFiltersToAccess } from '@ghostfolio/common/helper';
import { Filter, PortfolioPosition } from '@ghostfolio/common/interfaces';
@@ -27,6 +27,7 @@ import {
} from '@ghostfolio/ui/portfolio-filter-form';
import { DataService } from '@ghostfolio/ui/services';
+import { JsonPipe } from '@angular/common';
import type { HttpErrorResponse } from '@angular/common/http';
import {
ChangeDetectionStrategy,
@@ -69,6 +70,7 @@ import { CreateOrUpdateAccessDialogParams } from './interfaces/interfaces';
FormsModule,
GfAccessLevelIconComponent,
GfPortfolioFilterFormComponent,
+ JsonPipe,
MatButtonModule,
MatDatepickerModule,
MatDialogModule,
@@ -88,6 +90,7 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
public tags: Filter[] = [];
protected accessForm: FormGroup;
+ protected readonly baseUrl = window.location.origin;
protected minExpiresAt: Date;
protected readonly mode: 'create' | 'update';
protected readonly today = startOfDay(new Date());
@@ -222,6 +225,10 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
this.loadHoldings();
}
+ protected get accessId() {
+ return this.data.access?.id;
+ }
+
protected get accessLevel(): AccessLevel {
return this.accessForm?.get('accessLevel')?.value as AccessLevel;
}
@@ -234,10 +241,32 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
return this.accessType === 'PUBLIC';
}
+ protected get mcpConfiguration() {
+ return {
+ headers: {
+ Authorization: `Bearer ${this.accessId}`
+ },
+ type: 'http',
+ url: `${this.baseUrl}${MCP_ENDPOINT}`
+ };
+ }
+
protected get showExpiresAtErrorMessage() {
return this.accessForm?.get('expiresAt')?.invalid === true;
}
+ protected get showMcpDetails() {
+ return this.canGrantMcpAccess && this.isMcpAccess && this.mode === 'update';
+ }
+
+ protected get showPublicDetails() {
+ return (
+ this.hasExperimentalFeatures &&
+ this.isPublicAccess &&
+ this.mode === 'update'
+ );
+ }
+
protected onCancel() {
this.dialogRef.close();
}
@@ -250,6 +279,10 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
}
}
+ private get isMcpAccess() {
+ return this.accessType === 'MCP';
+ }
+
private async createAccess() {
const filters = this.getFilters();
@@ -343,7 +376,7 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
}
private async updateAccess() {
- const accessId = this.data.access?.id;
+ const accessId = this.accessId;
if (!accessId) {
return;
diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
index 21c0cd3a8b..31391beb0f 100644
--- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
+++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
@@ -133,6 +133,18 @@
[tags]="tags"
/>
}
+ @if (showMcpDetails || showPublicDetails) {
+ Details
+ @if (showMcpDetails) {
+ {{ mcpConfiguration | json }}
+ } @else if (showPublicDetails) {
+
+ GET {{ baseUrl }}/api/v1/public/{{ accessId }}/portfolio
+
+ }
+ }