@@ -66,9 +72,17 @@
color="primary"
mat-flat-button
type="submit"
- [disabled]="!(accessForm.dirty && accessForm.valid)"
+ [disabled]="
+ mode === 'create'
+ ? !(accessForm.dirty && accessForm.valid)
+ : !accessForm.valid
+ "
>
- Save
+ @if (mode === 'create') {
+ Save
+ } @else {
+ Update
+ }
diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts
index 178df374d..bdb9af6ed 100644
--- a/apps/client/src/app/components/user-account-access/user-account-access.component.ts
+++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts
@@ -115,6 +115,8 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit {
.subscribe((params) => {
if (params['createDialog']) {
this.openCreateAccessDialog();
+ } else if (params['editDialog'] && params['accessId']) {
+ this.openUpdateAccessDialog(params['accessId']);
}
});
@@ -173,6 +175,12 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit {
});
}
+ public onUpdateAccess(aId: string) {
+ this.router.navigate([], {
+ queryParams: { accessId: aId, editDialog: true }
+ });
+ }
+
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
@@ -200,6 +208,40 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit {
});
}
+ private openUpdateAccessDialog(accessId: string) {
+ const access = this.accessesGive?.find(({ id }) => {
+ return id === accessId;
+ });
+
+ if (!access) {
+ console.log('Could not find access.');
+
+ return;
+ }
+
+ const dialogRef = this.dialog.open(GfCreateOrUpdateAccessDialogComponent, {
+ data: {
+ access: {
+ alias: access.alias,
+ id: access.id,
+ grantee: access.grantee === 'Public' ? null : access.grantee,
+ permissions: access.permissions,
+ type: access.type
+ }
+ },
+ height: this.deviceType === 'mobile' ? '98vh' : undefined,
+ width: this.deviceType === 'mobile' ? '100vw' : '50rem'
+ });
+
+ dialogRef.afterClosed().subscribe((result) => {
+ if (result) {
+ this.update();
+ }
+
+ this.router.navigate(['.'], { relativeTo: this.route });
+ });
+ }
+
private update() {
this.accessesGet = this.user.access.map(({ alias, id, permissions }) => {
return {
diff --git a/apps/client/src/app/components/user-account-access/user-account-access.html b/apps/client/src/app/components/user-account-access/user-account-access.html
index 2979fd6fa..8160c2c8e 100644
--- a/apps/client/src/app/components/user-account-access/user-account-access.html
+++ b/apps/client/src/app/components/user-account-access/user-account-access.html
@@ -64,6 +64,7 @@
[showActions]="hasPermissionToDeleteAccess"
[user]="user"
(accessDeleted)="onDeleteAccess($event)"
+ (accessToUpdate)="onUpdateAccess($event)"
/>
@if (hasPermissionToCreateAccess) {
diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts
index 6ab370399..c2678924b 100644
--- a/apps/client/src/app/services/data.service.ts
+++ b/apps/client/src/app/services/data.service.ts
@@ -1,4 +1,5 @@
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
+import { UpdateAccessDto } from '@ghostfolio/api/app/access/update-access.dto';
import { CreateAccountBalanceDto } from '@ghostfolio/api/app/account-balance/create-account-balance.dto';
import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto';
import { TransferBalanceDto } from '@ghostfolio/api/app/account/transfer-balance.dto';
@@ -792,6 +793,10 @@ export class DataService {
return this.http.post('/api/v1/watchlist', watchlistItem);
}
+ public putAccess(aAccess: UpdateAccessDto) {
+ return this.http.put
(`/api/v1/access/${aAccess.id}`, aAccess);
+ }
+
public putAccount(aAccount: UpdateAccountDto) {
return this.http.put(`/api/v1/account/${aAccount.id}`, aAccount);
}
diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts
index 52794f7dc..51f327d32 100644
--- a/libs/common/src/lib/permissions.ts
+++ b/libs/common/src/lib/permissions.ts
@@ -49,6 +49,7 @@ export const permissions = {
syncDemoUserAccount: 'syncDemoUserAccount',
toggleReadOnlyMode: 'toggleReadOnlyMode',
updateAccount: 'updateAccount',
+ updateAccess: 'updateAccess',
updateAuthDevice: 'updateAuthDevice',
updateMarketData: 'updateMarketData',
updateMarketDataOfOwnAssetProfile: 'updateMarketDataOfOwnAssetProfile',
@@ -93,6 +94,7 @@ export function getPermissions(aRole: Role): string[] {
permissions.readTags,
permissions.readWatchlist,
permissions.updateAccount,
+ permissions.updateAccess,
permissions.updateAuthDevice,
permissions.updateMarketData,
permissions.updateMarketDataOfOwnAssetProfile,
@@ -133,6 +135,7 @@ export function getPermissions(aRole: Role): string[] {
permissions.readMarketDataOfOwnAssetProfile,
permissions.readWatchlist,
permissions.updateAccount,
+ permissions.updateAccess,
permissions.updateAuthDevice,
permissions.updateMarketDataOfOwnAssetProfile,
permissions.updateOrder,
From e6ff0f65c25d981a2afad2413e82a39d2fedfcd9 Mon Sep 17 00:00:00 2001
From: SK Akram
Date: Tue, 7 Oct 2025 00:26:57 +0530
Subject: [PATCH 16/16] Task/migrate auth page component to standalone (#5695)
* Migrate auth page component to standalone
* Update changelog
---
CHANGELOG.md | 1 +
apps/client/src/app/app-routing.module.ts | 2 +-
.../app/pages/auth/auth-page-routing.module.ts | 15 ---------------
.../src/app/pages/auth/auth-page.component.ts | 5 ++---
.../src/app/pages/auth/auth-page.module.ts | 11 -----------
.../src/app/pages/auth/auth-page.routes.ts | 18 ++++++++++++++++++
6 files changed, 22 insertions(+), 30 deletions(-)
delete mode 100644 apps/client/src/app/pages/auth/auth-page-routing.module.ts
delete mode 100644 apps/client/src/app/pages/auth/auth-page.module.ts
create mode 100644 apps/client/src/app/pages/auth/auth-page.routes.ts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a595800e1..7fba8132d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the spacing around the buttons in the holding detail dialog
+- Refactored the auth page to standalone
## 2.206.0 - 2025-10-04
diff --git a/apps/client/src/app/app-routing.module.ts b/apps/client/src/app/app-routing.module.ts
index 5c5eadcab..0e5a2dead 100644
--- a/apps/client/src/app/app-routing.module.ts
+++ b/apps/client/src/app/app-routing.module.ts
@@ -42,7 +42,7 @@ const routes: Routes = [
{
path: internalRoutes.auth.path,
loadChildren: () =>
- import('./pages/auth/auth-page.module').then((m) => m.AuthPageModule),
+ import('./pages/auth/auth-page.routes').then((m) => m.routes),
title: internalRoutes.auth.title
},
{
diff --git a/apps/client/src/app/pages/auth/auth-page-routing.module.ts b/apps/client/src/app/pages/auth/auth-page-routing.module.ts
deleted file mode 100644
index 2c9741845..000000000
--- a/apps/client/src/app/pages/auth/auth-page-routing.module.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { NgModule } from '@angular/core';
-import { RouterModule, Routes } from '@angular/router';
-
-import { AuthPageComponent } from './auth-page.component';
-
-const routes: Routes = [
- { component: AuthPageComponent, path: '' },
- { component: AuthPageComponent, path: ':jwt' }
-];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class AuthPageRoutingModule {}
diff --git a/apps/client/src/app/pages/auth/auth-page.component.ts b/apps/client/src/app/pages/auth/auth-page.component.ts
index 4061dd227..082401d6d 100644
--- a/apps/client/src/app/pages/auth/auth-page.component.ts
+++ b/apps/client/src/app/pages/auth/auth-page.component.ts
@@ -11,11 +11,10 @@ import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'gf-auth-page',
- templateUrl: './auth-page.html',
styleUrls: ['./auth-page.scss'],
- standalone: false
+ templateUrl: './auth-page.html'
})
-export class AuthPageComponent implements OnDestroy, OnInit {
+export class GfAuthPageComponent implements OnDestroy, OnInit {
private unsubscribeSubject = new Subject();
public constructor(
diff --git a/apps/client/src/app/pages/auth/auth-page.module.ts b/apps/client/src/app/pages/auth/auth-page.module.ts
deleted file mode 100644
index dd6a9ebe3..000000000
--- a/apps/client/src/app/pages/auth/auth-page.module.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-
-import { AuthPageRoutingModule } from './auth-page-routing.module';
-import { AuthPageComponent } from './auth-page.component';
-
-@NgModule({
- declarations: [AuthPageComponent],
- imports: [AuthPageRoutingModule, CommonModule]
-})
-export class AuthPageModule {}
diff --git a/apps/client/src/app/pages/auth/auth-page.routes.ts b/apps/client/src/app/pages/auth/auth-page.routes.ts
new file mode 100644
index 000000000..0ed6151de
--- /dev/null
+++ b/apps/client/src/app/pages/auth/auth-page.routes.ts
@@ -0,0 +1,18 @@
+import { internalRoutes } from '@ghostfolio/common/routes/routes';
+
+import { Routes } from '@angular/router';
+
+import { GfAuthPageComponent } from './auth-page.component';
+
+export const routes: Routes = [
+ {
+ component: GfAuthPageComponent,
+ path: '',
+ title: internalRoutes.auth.title
+ },
+ {
+ component: GfAuthPageComponent,
+ path: ':jwt',
+ title: internalRoutes.auth.title
+ }
+];