Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4d4c4c5
DSM-/PEPPER-948-download-of-Onc-History-upload-template initial
Jul 12, 2023
6ab74f5
DSM-PEPPER-948-download-of-Onc-History-upload-template backend integr…
Jul 12, 2023
5d06bad
DSM-PEPPER-948-download-of-Onc-History-upload-template linter fix
Jul 12, 2023
ab5ef91
DSM-PEPPER-948-download-of-Onc-History-upload-template color adjusted
Jul 12, 2023
3601afc
DSM-PEPPER-948-download-of-Onc-History-upload-template naming fixed
Jul 12, 2023
df994f8
DSM-PEPPER-948-download-of-Onc-History-upload-template first step
Jul 14, 2023
c956227
DSM-PEPPER-948-download-of-Onc-History-upload-template comparison on …
Jul 17, 2023
e295787
DSM-PEPPER-948-download-of-Onc-History-upload-template only available…
Jul 17, 2023
2378a6b
DSM-PEPPER-948-download-of-Onc-History-upload-template other color user
Jul 17, 2023
bd84436
DSM-PEPPER-948-download-of-Onc-History-upload-template add user added
Jul 18, 2023
cd05969
DSM-PEPPER-948-download-of-Onc-History-upload-template user is adding
Jul 18, 2023
dccdb86
DSM-PEPPER-948-download-of-Onc-History-upload-template safety v1
Jul 18, 2023
c3d773b
DSM-PEPPER-948-download-of-Onc-History-upload-template more improvements
Jul 18, 2023
8b940eb
Merge branch 'develop' into DSM-PEPPER-963-user-administration-services
Jul 24, 2023
3c94019
DSM-PEPPER-963-user-administration-services disabled checkbox
Jul 25, 2023
ca36b00
DSM-PEPPER-963-user-administration-services backend integration v1
Jul 27, 2023
8bd9c85
DSM-PEPPER-963-user-administration-services backend integration v2
Jul 27, 2023
db26b22
DSM-PEPPER-963-user-administration-services linter fix
Jul 27, 2023
af2f78a
DSM-PEPPER-963-user-administration-services panel title width expanded
Jul 27, 2023
dedf437
DSM-PEPPER-963-user-administration-services integrated backend and ma…
Aug 1, 2023
8c7d6d6
DSM-PEPPER-963-user-administration-services backend integration and e…
Aug 2, 2023
b3a7f49
DSM-PEPPER-963-user-administration-services removed consoles
Aug 2, 2023
01358e3
DSM-PEPPER-963-user-administration-services sorted and logout
Aug 2, 2023
3e5d987
DSM-PEPPER-963-user-administration-services if error don't display
Aug 2, 2023
423b8ad
DSM-PEPPER-963-user-administration-services guards and edit user updated
Aug 3, 2023
095ad4d
DSM-PEPPER-963-user-administration-services linter fix
Aug 3, 2023
02bb09e
DSM-PEPPER-963-user-administration-services confirmation modal genera…
Aug 3, 2023
e933778
DSM-PEPPER-963-user-administration-services linter fix
Aug 3, 2023
37e7458
DSM-PEPPER-963-user-administration-services unit test adjusted
Aug 3, 2023
5abd7bd
Merge branch 'develop' into DSM-PEPPER-963-user-administration-services
GiCharkviani Aug 3, 2023
079e105
DSM-PEPPER-963-user-administration-services removed commented code
Aug 3, 2023
b478f6f
Merge branch 'develop' into DSM-PEPPER-963-user-administration-services
GiCharkviani Aug 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,13 @@ import {UploadFileComponent} from '../sharedLearningUpload/components/uploadFile
import {FilesTableComponent} from '../sharedLearningUpload/components/filesTable/filesTable.component';
import {
ConfirmationModalComponent
} from '../sharedLearningUpload/components/confirmationModal/confirmationModal.component';
} from '../Shared/components/confirmationModal/confirmationModal.component';
import {OncHistoryUploadComponent} from '../oncHistoryUpload/oncHistoryUpload.component';
import {OncHistoryUploadGuard} from '../guards/oncHistoryUpload.guard';
import {
UsersAndPermissionsCanActivateGuard,
UsersAndPermissionsCanLoadGuard
} from '../guards/usersAndPermissions.guard';


PlotlyModule.plotlyjs = PlotlyJS;
Expand Down Expand Up @@ -301,7 +305,9 @@ PlotlyModule.plotlyjs = PlotlyJS;
Statics,
Language,
DashboardStatisticsService,
OncHistoryUploadGuard
OncHistoryUploadGuard,
UsersAndPermissionsCanLoadGuard,
UsersAndPermissionsCanActivateGuard
],
exports: [RouterModule, MatFormFieldModule, MatInputModule]
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ import {DashboardStatisticsComponent} from '../dashboard-statistics/dashboard-st
import {ScannerComponent} from '../scanner/scanner.component';
import {OncHistoryUploadComponent} from '../oncHistoryUpload/oncHistoryUpload.component';
import {OncHistoryUploadGuard} from '../guards/oncHistoryUpload.guard';
import {
UsersAndPermissionsCanActivateGuard,
UsersAndPermissionsCanLoadGuard
} from '../guards/usersAndPermissions.guard';



Expand Down Expand Up @@ -94,6 +98,12 @@ export const AppRoutes: Routes = [
{path: 'oncHistoryUpload', component: OncHistoryUploadComponent, canActivate: [AuthGuard, OncHistoryUploadGuard]},

{path: 'userSettings', component: UserSettingComponent, canActivate: [AuthGuard]},
{path: 'usersAndPermissions',
canActivate: [UsersAndPermissionsCanActivateGuard],
canLoad: [UsersAndPermissionsCanLoadGuard],
loadChildren: () =>
import('../usersAndPermissions/usersAndPermissions.module').then(m => m.UsersAndPermissionsModule)
},

// Permalink
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<main id="confirmationModal" class="confirmationModal">
<section class="confirmationModal-content">
<p>Are you sure you want to delete {{fileName}}?</p>
<p>Are you sure you want to delete {{name}}?</p>
<i><span>Warning:</span> this action can't be undone</i>
</section>
<section class="confirmationModal-buttons">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@use 'commonStyles' as common;
@use 'projects/ddp-dsm-ui/src/styles/commonStyles' as common;

$yes-color: #FF595E;
$no-color: #5FA8D3;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
export class ConfirmationModalComponent {
constructor(
private readonly dialogRef: MatDialogRef<ConfirmationModalComponent>,
@Inject(MAT_DIALOG_DATA) private data: {fileName: string},
@Inject(MAT_DIALOG_DATA) private data: {name: string},
) {}

public confirmationAnswerIs(doIt: boolean): void {
this.dialogRef.close(doIt);
}

public get fileName(): string {
return this.data.fileName;
public get name(): string {
return this.data.name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('ConfirmationModalComponent', () => {
},
{
provide: MAT_DIALOG_DATA,
useValue: {fileName: 'testFile.pdf'}
useValue: {name: 'testFile.pdf'}
}
]
}).compileComponents();
Expand All @@ -38,12 +38,12 @@ describe('ConfirmationModalComponent', () => {
expect(component).toBeTruthy('Component has not been instantiated');
});

it('should display file name', () => {
it('should display name', () => {
const fileName = componentHTML
.query(By.css('section.confirmationModal-content p'))
.nativeElement.textContent;

expect(fileName).toContain('testFile.pdf', 'File name is not displayed');
expect(fileName).toContain('testFile.pdf', 'Name is not displayed');
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {Injectable} from '@angular/core';
import {
ActivatedRouteSnapshot,
CanActivate,
CanLoad,
Route,
RouterStateSnapshot,
UrlSegment,
UrlTree
} from '@angular/router';
import {RoleService} from '../services/role.service';

@Injectable()
export class UsersAndPermissionsCanLoadGuard implements CanLoad {
constructor(private readonly roleService: RoleService) {}

canLoad(route: Route, segments: UrlSegment[]): boolean | UrlTree {
return this.roleService.isStudyUserAdmin || this.roleService.isPepperAdmin;
}
}


@Injectable()
export class UsersAndPermissionsCanActivateGuard implements CanActivate {
constructor(private readonly roleService: RoleService) {}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree {
return this.roleService.isStudyUserAdmin || this.roleService.isPepperAdmin;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,26 @@ import {Observable, throwError} from 'rxjs';
import {catchError} from 'rxjs/operators';
import {Injectable} from '@angular/core';
import {ErrorsService} from '../services/errors.service';
import {Auth} from '../services/auth.service';

@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
private readonly ignoreStatuses: number[] = [401];

constructor(private errorsService: ErrorsService) {}
constructor(private readonly errorsService: ErrorsService,
private readonly authService: Auth) {}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: any) => {
error instanceof HttpErrorResponse &&
!this.ignoreStatuses.includes(error?.status) &&
this.errorsService.openSnackbar(error);


if(error instanceof HttpErrorResponse) {
!this.ignoreStatuses.includes(error?.status) &&
this.errorsService.openSnackbar(error);

error?.status === 401 && this.authService.doLogout();
}

return throwError(() => error);
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<li *ngIf="hasRole().allowedToDownloadNDI()"><a href="#" [routerLink]="['ndi']"> NDI Upload </a></li>
<li *ngIf="showOncHistoryUploadPage(selectedStudy | async)"><a [routerLink]="['oncHistoryUpload']">Onc History Upload</a></li>
<li ><a href="#" [routerLink]="['drugList']"> Drug List </a></li>
<li *ngIf="hasRole().isPepperAdmin || hasRole().isStudyUserAdmin"><a href="#" [routerLink]="['usersAndPermissions']"> Users And Permissions </a></li>
</ul>
</li>
</ul>
Expand Down
57 changes: 57 additions & 0 deletions ddp-workspace/projects/ddp-dsm-ui/src/app/services/dsm.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import {IDateRange} from '../dashboard-statistics/interfaces/IDateRange';
import {StatisticsEnum} from '../dashboard-statistics/enums/statistics.enum';
import {SomaticResultSignedUrlRequest} from '../sharedLearningUpload/interfaces/somaticResultSignedUrlRequest';
import {SendToParticipantRequest} from '../sharedLearningUpload/interfaces/sendToParticipant';
import {AddUsersRequest, RemoveUsersRequest} from '../usersAndPermissions/interfaces/addRemoveUsers';
import {EditUsers} from '../usersAndPermissions/interfaces/editUsers';
import {EditUserRoles} from '../usersAndPermissions/interfaces/role';

declare var DDP_ENV: any;

Expand Down Expand Up @@ -458,6 +461,60 @@ export class DSMService {
);
}

public getUsers(realm: string): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'admin/userRole';
const map: { name: string; value: any }[] = [];
map.push({name: DSMService.REALM, value: realm});
return this.http.get(url, this.buildQueryHeader(map)).pipe(
catchError(this.handleError)
);
}

public addUser(realm: string, addUsers: AddUsersRequest): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'admin/user';
const map: { name: string; value: any }[] = [];
map.push({name: DSMService.REALM, value: realm});
return this.http.post(url, addUsers, this.buildQueryHeader(map)).pipe(
catchError(this.handleError)
);
}

public removeUser(realm: string, removeUsers: RemoveUsersRequest): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'admin/user';
const map: { name: string; value: any }[] = [];
map.push({name: DSMService.REALM, value: realm});
return this.http.post(url, removeUsers, this.buildQueryHeader(map)).pipe(
catchError(this.handleError)
);
}

public editUsers(realm: string, editUser: EditUsers): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'admin/user';
const map: { name: string; value: any }[] = [];
map.push({name: DSMService.REALM, value: realm});
return this.http.put(url, editUser, this.buildQueryHeader(map)).pipe(
catchError(this.handleError)
);
}

public editUsersRoles(realm: string, userRoles: EditUserRoles): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'admin/userRole';
const map: { name: string; value: any }[] = [];
map.push({name: DSMService.REALM, value: realm});
return this.http.put(url, userRoles, this.buildQueryHeader(map)).pipe(
catchError(this.handleError)
);
}

public availableRoles(realm: string): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'admin/studyRole';
const map: { name: string; value: any }[] = [];
map.push({name: DSMService.REALM, value: realm});
return this.http.get(url, this.buildQueryHeader(map)).pipe(
catchError(this.handleError)
);
}

public getMedicalRecord(participantId: string, institutionId: string): Observable<any> {
const url = this.baseUrl + DSMService.UI + 'participant/' + participantId + '/institution/' + institutionId;
return this.http.get(url, this.buildHeader()).pipe(
Expand Down
21 changes: 19 additions & 2 deletions ddp-workspace/projects/ddp-dsm-ui/src/app/services/role.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export class RoleService {
private _user: string;
private _userEmail: string;
private _userSetting: UserSetting;

private _studyUserAdmin = false;
private _pepperAdmin = false;

constructor( private sessionService: SessionService,
@Inject( 'ddp.config' ) private config: ConfigurationService ) {
Expand Down Expand Up @@ -82,6 +83,8 @@ export class RoleService {
this._viewSeqOrderStatus = false;
this._uploadRorFile = false;
this._viewSharedLearnings = false;
this._studyUserAdmin = false;
this._pepperAdmin = false;
}

public setRoles( token: string ): void {
Expand Down Expand Up @@ -188,6 +191,12 @@ export class RoleService {
else if (entry === 'view_shared_learnings') {
this._viewSharedLearnings = true;
}
else if (entry === 'study_user_admin') {
this._studyUserAdmin = true;
}
else if (entry === 'pepper_admin') {
this._pepperAdmin = true;
}
}
}
const userSettings: any = this.getClaimByKeyName( token, 'USER_SETTINGS' );
Expand Down Expand Up @@ -311,7 +320,7 @@ export class RoleService {
return this._isParticipantEdit;
}

private getClaimByKeyName( token: any, key: string ): any {
public getClaimByKeyName( token: any, key: string ): any {
return this.sessionService.getDSMClaims( token )[ this.config.auth0ClaimNameSpace + key ];
}

Expand Down Expand Up @@ -350,4 +359,12 @@ export class RoleService {
public get allowViewSharedLearnings(): boolean {
return this._viewSharedLearnings;
}

public get isStudyUserAdmin(): boolean {
return this._studyUserAdmin;
}

public get isPepperAdmin(): boolean {
return this._pepperAdmin;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {catchError, filter, finalize, first, take} from 'rxjs/operators';
import {SharedLearningsStateService} from './services/sharedLearningsState.service';
import {MatDialog} from '@angular/material/dialog';
import {RoleService} from '../services/role.service';
import {ConfirmationModalComponent} from './components/confirmationModal/confirmationModal.component';
import {ConfirmationModalComponent} from '../Shared/components/confirmationModal/confirmationModal.component';
import {HttpErrorResponse} from '@angular/common/http';

@Component({
Expand Down Expand Up @@ -83,7 +83,7 @@ export class SharedLearningsUploadComponent implements OnInit, OnDestroy {

public onDeleteFile({somaticDocumentId, fileName}: SomaticResultsFileWithStatus): void {
const activeConfirmationDialog = this.matDialog
.open(ConfirmationModalComponent, {data: {fileName}, width: '500px'});
.open(ConfirmationModalComponent, {data: {name: fileName}, width: '500px'});

activeConfirmationDialog.afterClosed()
.pipe(
Expand Down
Loading