Browse Source

#2820 Grant private access

pull/2822/head
x1c0 2 years ago
parent
commit
d541318a05
  1. 1
      CHANGELOG.md
  2. 9
      apps/api/src/app/access/access.controller.ts
  3. 21
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
  4. 12
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
  5. 18
      apps/client/src/app/components/user-account-access/user-account-access.component.ts
  6. 4
      libs/common/src/lib/interfaces/access.interface.ts

1
CHANGELOG.md

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Improved the user interface of the access table to share the portfolio - Improved the user interface of the access table to share the portfolio
- Grant private access
## 2.34.0 - 2024-01-02 ## 2.34.0 - 2024-01-02

9
apps/api/src/app/access/access.controller.ts

@ -65,13 +65,20 @@ export class AccessController {
public async createAccess( public async createAccess(
@Body() data: CreateAccessDto @Body() data: CreateAccessDto
): Promise<AccessModel> { ): Promise<AccessModel> {
return this.accessService.createAccess({ try {
return await this.accessService.createAccess({
alias: data.alias || undefined, alias: data.alias || undefined,
GranteeUser: data.granteeUserId GranteeUser: data.granteeUserId
? { connect: { id: data.granteeUserId } } ? { connect: { id: data.granteeUserId } }
: undefined, : undefined,
User: { connect: { id: this.request.user.id } } User: { connect: { id: this.request.user.id } }
}); });
} catch {
throw new HttpException(
getReasonPhrase(StatusCodes.BAD_REQUEST),
StatusCodes.BAD_REQUEST
);
}
} }
@Delete(':id') @Delete(':id')

21
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts

@ -7,6 +7,7 @@ import {
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto'; import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
import { DataService } from '@ghostfolio/client/services/data.service';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { CreateOrUpdateAccessDialogParams } from './interfaces/interfaces'; import { CreateOrUpdateAccessDialogParams } from './interfaces/interfaces';
@ -26,13 +27,15 @@ export class CreateOrUpdateAccessDialog implements OnDestroy {
public constructor( public constructor(
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateAccessDialogParams, @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateAccessDialogParams,
public dialogRef: MatDialogRef<CreateOrUpdateAccessDialog>, public dialogRef: MatDialogRef<CreateOrUpdateAccessDialog>,
private formBuilder: FormBuilder private formBuilder: FormBuilder,
private dataService: DataService
) {} ) {}
ngOnInit() { ngOnInit() {
this.accessForm = this.formBuilder.group({ this.accessForm = this.formBuilder.group({
alias: [this.data.access.alias], alias: [this.data.access.alias],
type: [this.data.access.type, Validators.required] type: [this.data.access.type, Validators.required],
userId: [this.data.access.grantee, Validators.required]
}); });
} }
@ -43,10 +46,20 @@ export class CreateOrUpdateAccessDialog implements OnDestroy {
public onSubmit() { public onSubmit() {
const access: CreateAccessDto = { const access: CreateAccessDto = {
alias: this.accessForm.controls['alias'].value, alias: this.accessForm.controls['alias'].value,
type: this.accessForm.controls['type'].value type: this.accessForm.controls['type'].value,
granteeUserId: this.accessForm.controls['userId'].value
}; };
this.dialogRef.close({ access }); this.dataService.postAccess(access).subscribe({
next: () => {
this.dialogRef.close();
},
error: (error) => {
if (error.status === 400) {
alert('It was not possible to grant access, please try again later.');
}
}
});
} }
public ngOnDestroy() { public ngOnDestroy() {

12
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html

@ -22,9 +22,21 @@
<mat-label i18n>Type</mat-label> <mat-label i18n>Type</mat-label>
<mat-select formControlName="type"> <mat-select formControlName="type">
<mat-option i18n value="PUBLIC">Public</mat-option> <mat-option i18n value="PUBLIC">Public</mat-option>
<mat-option i18n value="PRIVATE">Private</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div *ngIf="accessForm.controls['type'].value === 'PRIVATE' ">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>User ID</mat-label>
<input
formControlName="userId"
matInput
type="text"
(keydown.enter)="$event.stopPropagation()"
/>
</mat-form-field>
</div>
</div> </div>
<div class="justify-content-end" mat-dialog-actions> <div class="justify-content-end" mat-dialog-actions>
<button i18n mat-button type="button" (click)="onCancel()">Cancel</button> <button i18n mat-button type="button" (click)="onCancel()">Cancel</button>

18
apps/client/src/app/components/user-account-access/user-account-access.component.ts

@ -112,23 +112,7 @@ export class UserAccountAccessComponent implements OnDestroy, OnInit {
width: this.deviceType === 'mobile' ? '100vw' : '50rem' width: this.deviceType === 'mobile' ? '100vw' : '50rem'
}); });
dialogRef dialogRef.afterClosed().subscribe(() => {
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((data: any) => {
const access: CreateAccessDto = data?.access;
if (access) {
this.dataService
.postAccess({ alias: access.alias })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
this.update();
}
});
}
this.router.navigate(['.'], { relativeTo: this.route }); this.router.navigate(['.'], { relativeTo: this.route });
}); });
} }

4
libs/common/src/lib/interfaces/access.interface.ts

@ -1,6 +1,6 @@
export interface Access { export interface Access {
alias?: string; alias?: string;
grantee: string; grantee?: string;
id: string; id: string;
type: 'PUBLIC' | 'RESTRICTED_VIEW'; type: 'PUBLIC' | 'PRIVATE' | 'RESTRICTED_VIEW';
} }

Loading…
Cancel
Save