diff --git a/package-lock.json b/package-lock.json index 468482af1f..2f55688e60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@denbi/cloud-portal-webapp", - "version": "4.847.0", + "version": "4.848.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@denbi/cloud-portal-webapp", - "version": "4.847.0", + "version": "4.848.0", "dependencies": { "@angular-eslint/eslint-plugin": "^17.3.0", "@angular/animations": "17.3.10", @@ -88,7 +88,7 @@ "eslint-config-airbnb-base": "15.0.0", "eslint-plugin-import": "^2.29.0", "eslint-plugin-jsdoc": "48.2.7", - "eslint-plugin-no-null": "*", + "eslint-plugin-no-null": "latest", "eslint-plugin-prefer-arrow": "1.2.3", "exports-loader": "5.0.0", "file-loader": "6.2.0", @@ -17449,10 +17449,11 @@ } }, "node_modules/undici": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.15.0.tgz", - "integrity": "sha512-VviMt2tlMg1BvQ0FKXxrz1eJuyrcISrL2sPfBf7ZskX/FCEc/7LeThQaoygsMJpNqrATWQIsRVx+1Dpe4jaYuQ==", + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", + "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.17" } diff --git a/package.json b/package.json index 5afada3c1a..5dddf1e030 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@denbi/cloud-portal-webapp", - "version": "4.847.0", + "version": "4.848.0", "description": "de.NBI Cloud Portal", "scripts": { "ng": "ng serve", @@ -124,7 +124,7 @@ "webpack-cli": "5.1.4" }, "overrides": { - "undici": "6.15.0", + "undici": "6.19.2", "vite": "5.2.12" }, "lint-staged": { diff --git a/src/app/applications/application-card/application-card.component.html b/src/app/applications/application-card/application-card.component.html index 05d0a2ab73..77761eec7b 100644 --- a/src/app/applications/application-card/application-card.component.html +++ b/src/app/applications/application-card/application-card.component.html @@ -1,46 +1,49 @@ - - - - {{ application?.project_application_name }} - {{ application?.project_application_shortname }} - {{ application?.project_application_date_submitted }} - - @if (application?.project_application_user?.username) { - {{ application?.project_application_user?.username }} - } @else { - - } - - {{ application?.project_application_institute }} + + + + {{ application?.project_application_name }} + {{ application?.project_application_shortname }} + {{ application?.project_application_date_submitted }} + + @if (application?.project_application_user?.username) { + {{ application?.project_application_user?.username }} + } @else { + + } + + {{ application?.project_application_institute }} - @if (voView) { - - } @else if (facilityView) { - - } + @if (voView) { + + } @else if (facilityView) { + + } - @if (!isCollapsed) { - - } + @if (!isCollapsed) { + + } diff --git a/src/app/applications/application-card/application-card.component.ts b/src/app/applications/application-card/application-card.component.ts index e6c0a61873..41d61deec8 100644 --- a/src/app/applications/application-card/application-card.component.ts +++ b/src/app/applications/application-card/application-card.component.ts @@ -1,19 +1,16 @@ import { - Component, EventEmitter, Input, OnInit, Output, + Component, EventEmitter, Input, OnInit, Output, ViewChild, } from '@angular/core'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; -import { Subscription } from 'rxjs'; -import { HttpStatusCode } from '@angular/common/http'; +import { BsModalRef } from 'ngx-bootstrap/modal'; import { AbstractBaseClass, Application_States } from '../../shared/shared_modules/baseClass/abstract-base-class'; import { ConfirmationActions } from '../../shared/modal/confirmation_actions'; import { Application } from '../application.model/application.model'; import { ApplicationTabStates } from '../../shared/enums/application-tab-states'; import { ApplicationsService } from '../../api-connector/applications.service'; -import { NotificationModalComponent } from '../../shared/modal/notification-modal'; import { is_vo } from '../../shared/globalvar'; import { ComputecenterComponent } from '../../projectmanagement/computecenter.component'; -import { GroupService } from '../../api-connector/group.service'; import { User } from '../application.model/user.model'; +import { ApplicationDetailComponent } from '../application-detail/application-detail.component'; @Component({ selector: 'app-application-card', @@ -21,7 +18,6 @@ import { User } from '../application.model/user.model'; styleUrl: './application-card.component.scss', }) export class ApplicationCardComponent extends AbstractBaseClass implements OnInit { - private subscription: Subscription = new Subscription(); @Input() application: Application; @Input() tabState: ApplicationTabStates = ApplicationTabStates.SUBMITTED; @@ -30,10 +26,10 @@ export class ApplicationCardComponent extends AbstractBaseClass implements OnIni @Output() removeApplicationTrigger: EventEmitter = new EventEmitter(); @Input() facilityView: boolean = false; @Input() voView: boolean = false; + @ViewChild('applicationdetail') applicationDetailComponent: ApplicationDetailComponent; bsModalRef: BsModalRef; is_vo_admin: boolean = false; - selectedComputeCenter: ComputecenterComponent; ngOnInit() { this.is_vo_admin = is_vo; @@ -63,8 +59,7 @@ export class ApplicationCardComponent extends AbstractBaseClass implements OnIni constructor( private applicationsService: ApplicationsService, - private modalService: BsModalService, - private groupService: GroupService, + ) { super(); } @@ -88,288 +83,11 @@ export class ApplicationCardComponent extends AbstractBaseClass implements OnIni ); } - resetApplicationPI(): void { - this.applicationsService.resetPIValidation(this.application).subscribe(() => { - this.getApplication(); - }); - } - switchCollaps() { this.isCollapsed = !this.isCollapsed; } - showNotificationModal( - notificationModalTitle: string, - notificationModalMessage: string, - notificationModalType: string, - ) { - const initialState = { notificationModalTitle, notificationModalType, notificationModalMessage }; - if (this.bsModalRef) { - this.bsModalRef.hide(); - } - - this.bsModalRef = this.modalService.show(NotificationModalComponent, { initialState }); - this.bsModalRef.setClass('modal-lg'); - } - - createSimpleVmProjectGroup(): void { - this.showNotificationModal('Info', 'Creating Project...', 'info'); - - if (this.selectedComputeCenter && this.selectedComputeCenter.FacilityId) { - this.groupService - .createGroupByApplication(this.application.project_application_id, this.selectedComputeCenter.FacilityId) - .subscribe( - (res: any): void => { - if (!res['client_available'] && !res['created']) { - this.showNotificationModal( - 'Failed', - `The client ${res['client_name']} has not the necessary resources left!`, - 'danger', - ); - } else { - this.showNotificationModal('Success', 'The project was created!', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - } - }, - (error: any): void => { - console.log(error); - const errorMessage = error && error.error === 'locked' - ? 'Project is locked and could not be created!' - : 'Project could not be created!'; - - this.showNotificationModal('Failed', errorMessage, 'danger'); - console.log(error); - }, - ); - } - } - - approveModificationRequest(): void { - this.applicationsService.approveModificationRequest(this.application.project_application_id).subscribe( - (res: Response): void => { - this.showNotificationModal('Success', 'The resource modification request was approved!', 'success'); - if (!this.application.project_application_openstack_project) { - if (res.status === HttpStatusCode.Accepted) { - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - - // this.all_applications.splice(this.all_applications.indexOf(application), 1); - } - } else { - this.getApplication(); - } - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Approval of resource modification failed!', 'danger'); - }, - ); - } - - declineModificationRequest(): void { - this.applicationsService.deleteModificationRequest(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Declined', 'The resource modification request was declined!', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - - this.getApplication(); - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Decline of resource modification failed!', 'danger'); - }, - ); - } - - deleteApplication(): void { - // const idx: number = this.all_applications.indexOf(application); - - this.subscription.add( - this.applicationsService.deleteApplication(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Success', 'The application has been successfully removed', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (): void => { - this.updateNotificationModal('Failed', 'Application could not be removed!', true, 'danger'); - }, - ), - ); - } - - declineLifetimeExtension(): void { - this.applicationsService.deleteAdditionalLifetimeRequests(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Declined', 'The project extension was declined!', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Decline of project extension failed!', 'danger'); - }, - ); - } - - declineCreditExtension(): void { - this.applicationsService.deleteAdditionalCreditsRequests(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Declined', 'The credit extension request was declined!', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Decline of credit extension failed!', 'danger'); - }, - ); - } - - declineApplication(): void { - // const idx: number = this.all_applications.indexOf(app); - this.applicationsService.declineApplication(this.application.project_application_id).subscribe( - (): void => { - const message: string = 'The Application was declined.'; - - this.showNotificationModal('Success', message, 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (): void => { - this.showNotificationModal('Failed', 'Application could not be declined!', 'danger'); - }, - ); - } - - approveLifetimeExtension(): void { - this.applicationsService.approveAdditionalLifetime(this.application.project_application_id).subscribe( - (res: Response): void => { - if (this.application.project_application_openstack_project) { - this.getApplication(); - this.showNotificationModal('Success', 'The request has been sent to the facility manager.', 'success'); - } else { - this.showNotificationModal('Success', 'The project has been extended!', 'success'); - } - if (!this.application.project_application_openstack_project) { - if (res.status === HttpStatusCode.Accepted) { - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - } - } - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Project lifetime could not be extendend!', 'danger'); - }, - ); - } - - approveCreditExtension(): void { - this.applicationsService.approveAdditionalCreditsRequest(this.application.project_application_id).subscribe( - (res: Response): void => { - this.showNotificationModal('Success', 'The credit extension request was approved!', 'success'); - if (!this.application.project_application_openstack_project) { - if (res.status === HttpStatusCode.Accepted) { - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - } - } else { - this.getApplication(); - } - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Approval of credit extension failed!', 'danger'); - }, - ); - } - - createOpenStackProjectGroup(): void { - this.groupService - .createGroupOpenStack(this.application.project_application_id, this.selectedComputeCenter.FacilityId) - .subscribe( - (result: { [key: string]: string }): void => { - if (result['Error']) { - this.showNotificationModal('Failed', result['Error'], 'danger'); - } else { - this.showNotificationModal('Success', 'The project was assigned to the facility.', 'success'); - this.getApplication(); - // this.switchApproveLocked(false); - } - }, - (error: any): void => { - const errorMessage = error && error.error === 'locked' - ? 'Project is locked and could not be created!' - : 'Project could not be created!'; - - this.showNotificationModal('Failed', errorMessage, 'danger'); - console.log(error); - }, - ); - } - - /** - * Function to listen to modal results. - */ - subscribeToBsModalRef(): void { - this.subscription.add( - this.bsModalRef.content.event.subscribe((result: any) => { - let action = null; - if ('action' in result) { - action = result['action']; - } - if ('createSimpleVM' in result) { - this.createSimpleVmProjectGroup(); - } - if (action === ConfirmationActions.APPROVE_MODIFICATION) { - this.approveModificationRequest(); - } - if ('closed' in result) { - // this.switchApproveLocked(false); - } - if (action === ConfirmationActions.DECLINE_MODIFICATION) { - this.declineModificationRequest(); - } - if (action === ConfirmationActions.DELETE_APPLICATION) { - this.deleteApplication(); - } - if (action === ConfirmationActions.DECLINE_EXTENSION) { - this.declineLifetimeExtension(); - } - if (action === ConfirmationActions.DECLINE_CREDITS) { - this.declineCreditExtension(); - } - if (action === ConfirmationActions.DECLINE_APPLICATION) { - this.declineApplication(); - } - - if (action === ConfirmationActions.APPROVE_EXTENSION) { - this.approveLifetimeExtension(); - } - if (action === ConfirmationActions.RESET_PI) { - this.resetApplicationPI(); - } - if (action === ConfirmationActions.APPROVE_CREDITS) { - this.approveCreditExtension(); - } - if (action === ConfirmationActions.APPROVE_APPLICATION) { - if (this.application.project_application_openstack_project) { - this.createOpenStackProjectGroup(); - } - } - if (action === 'adjustedModificationRequest') { - // this.isLoaded = false; - // this.changeTabState(ApplicationTabStates.MODIFICATION_EXTENSION); - } - }), - ); - } - isCollapsed: boolean = true; protected readonly Application_States = Application_States; protected readonly ConfirmationActions = ConfirmationActions; - protected readonly ApplicationTabStates = ApplicationTabStates; } diff --git a/src/app/applications/application-detail/resource-detail/resource-detail.component.html b/src/app/applications/application-detail/resource-detail/resource-detail.component.html index fba0bb77b4..2f1d6a30fc 100644 --- a/src/app/applications/application-detail/resource-detail/resource-detail.component.html +++ b/src/app/applications/application-detail/resource-detail/resource-detail.component.html @@ -101,11 +101,11 @@ {{ flavorDiff.diff === 0 ? '' : flavorDiff.diff > 0 ? '+' : '-' }} - {{ flavorDiff.diff }} + {{ Math.abs(flavorDiff.diff) }} diff --git a/src/app/applications/application-facility-actions/application-facility-actions.component.ts b/src/app/applications/application-facility-actions/application-facility-actions.component.ts index f0435db1b8..562c3a7b0e 100644 --- a/src/app/applications/application-facility-actions/application-facility-actions.component.ts +++ b/src/app/applications/application-facility-actions/application-facility-actions.component.ts @@ -33,250 +33,256 @@ export class ApplicationFacilityActionsComponent extends AbstractBaseClass { isCollapsed: boolean = true; bsModalRef: BsModalRef; @Output() switchCollapseEvent: EventEmitter = new EventEmitter(); + @Output() reloadApplicationTrigger: EventEmitter = new EventEmitter(); - constructor( + constructor( private facilityService: FacilityService, private modalService: BsModalService, private applicationsService: ApplicationsService, - ) { - super(); - } + ) { + super(); + } - switchCollaps() { - this.switchCollapseEvent.emit(); - } + switchCollaps() { + this.switchCollapseEvent.emit(); + } - triggerRemoveApplication() { - this.removeApplicationTrigger.emit(this.application.project_application_id); - } + triggerRemoveApplication() { + this.removeApplicationTrigger.emit(this.application.project_application_id); + } - triggerReloadNumbers() { - this.reloadNumbersTrigger.emit(); - } + triggerReloadNumbers() { + this.reloadNumbersTrigger.emit(); + } - declineApplication(): void { - this.showNotificationModal('Decline Application', 'Waiting..', 'info'); + triggerReloadApplication():void { + this.reloadApplicationTrigger.emit(); - this.facilityService - .declineFacilityApplication( - this.application.project_application_compute_center.FacilityId, - this.application.project_application_id, - ) - .subscribe( - (): void => { - this.showNotificationModal('Success', 'Successfully declined the application.', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); + } - // this.getAllApplicationsHistory(this.selectedFacility['FacilityId']); - }, - (): void => { - this.showNotificationModal('Failed', 'Failed to decline the application.', 'danger'); - }, - ); - } + declineApplication(): void { + this.showNotificationModal('Decline Application', 'Waiting..', 'info'); - public approveExtension(): void { - this.applicationsService.approveAdditionalLifetime(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Success', 'Successfully approved extension!', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - }, - (): void => { - this.showNotificationModal('Failed', 'The approval of the extension request has failed.', 'danger'); - }, - ); - } + this.facilityService + .declineFacilityApplication( + this.application.project_application_compute_center.FacilityId, + this.application.project_application_id, + ) + .subscribe( + (): void => { + this.showNotificationModal('Success', 'Successfully declined the application.', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); - /** + // this.getAllApplicationsHistory(this.selectedFacility['FacilityId']); + }, + (): void => { + this.showNotificationModal('Failed', 'Failed to decline the application.', 'danger'); + }, + ); + } + + public approveExtension(): void { + this.applicationsService.approveAdditionalLifetime(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Success', 'Successfully approved extension!', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + }, + (): void => { + this.showNotificationModal('Failed', 'The approval of the extension request has failed.', 'danger'); + }, + ); + } + + /** * Decline an extension request. * * @param application_id */ - public declineExtension(): void { - this.applicationsService.declineAdditionalLifetime(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Success', 'Successfully declined extension!', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - }, - (): void => { - this.showNotificationModal('Failed', 'The decline of the extension request has failed.', 'danger'); - }, - ); - } + public declineExtension(): void { + this.applicationsService.declineAdditionalLifetime(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Success', 'Successfully declined extension!', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + }, + (): void => { + this.showNotificationModal('Failed', 'The decline of the extension request has failed.', 'danger'); + }, + ); + } - showNotificationModal( - notificationModalTitle: string, - notificationModalMessage: string, - notificationModalType: string, - ) { - const initialState = { notificationModalTitle, notificationModalType, notificationModalMessage }; - if (this.bsModalRef) { - this.bsModalRef.hide(); - } + showNotificationModal( + notificationModalTitle: string, + notificationModalMessage: string, + notificationModalType: string, + ) { + const initialState = { notificationModalTitle, notificationModalType, notificationModalMessage }; + if (this.bsModalRef) { + this.bsModalRef.hide(); + } - this.bsModalRef = this.modalService.show(NotificationModalComponent, { initialState }); - this.bsModalRef.setClass('modal-lg'); - } + this.bsModalRef = this.modalService.show(NotificationModalComponent, { initialState }); + this.bsModalRef.setClass('modal-lg'); + } - approveApplication(): void { - this.showNotificationModal('Approving Application', 'Waiting..', 'info'); - this.facilityService - .approveFacilityApplication( - this.application.project_application_compute_center.FacilityId, - this.application.project_application_id, - ) - .subscribe( - (): void => { - this.showNotificationModal('Success', 'Successfully approved the application.', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); + approveApplication(): void { + this.showNotificationModal('Approving Application', 'Waiting..', 'info'); + this.facilityService + .approveFacilityApplication( + this.application.project_application_compute_center.FacilityId, + this.application.project_application_id, + ) + .subscribe( + (): void => { + this.showNotificationModal('Success', 'Successfully approved the application.', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); - // this.getAllApplicationsHistory(this.selectedFacility['FacilityId']); - }, - (): void => { - this.showNotificationModal('Failed', 'Failed to approve the application.', 'danger'); - }, - ); - } + // this.getAllApplicationsHistory(this.selectedFacility['FacilityId']); + }, + (): void => { + this.showNotificationModal('Failed', 'Failed to approve the application.', 'danger'); + }, + ); + } - showConfirmationModal(action: ConfirmationActions): void { - const initialState = { - application: this.application, - action, - }; + showConfirmationModal(action: ConfirmationActions): void { + const initialState = { + application: this.application, + action, + }; - this.bsModalRef = this.modalService.show(ConfirmationModalComponent, { initialState, class: 'modal-lg' }); - this.subscribeToBsModalRef(); - } + this.bsModalRef = this.modalService.show(ConfirmationModalComponent, { initialState, class: 'modal-lg' }); + this.subscribeToBsModalRef(); + } - approveModification(): void { - this.applicationsService.approveModificationRequest(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Success', 'Successfully approved modification!', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - }, - (): void => { - this.showNotificationModal('Failed', 'The approval of the modification request has failed.', 'danger'); - }, - ); - } + approveModification(): void { + this.applicationsService.approveModificationRequest(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Success', 'Successfully approved modification!', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + }, + (): void => { + this.showNotificationModal('Failed', 'The approval of the modification request has failed.', 'danger'); + }, + ); + } - declineModification(): void { - this.applicationsService.declineModificationRequest(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Success', 'Successfully declined modification!', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - }, - (): void => { - this.showNotificationModal('Failed', 'The decline of the modification request has failed.', 'danger'); - }, - ); - } + declineModification(): void { + this.applicationsService.declineModificationRequest(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Success', 'Successfully declined modification!', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + }, + (): void => { + this.showNotificationModal('Failed', 'The decline of the modification request has failed.', 'danger'); + }, + ); + } - approveTermination(): void { - this.facilityService - .approveTerminationByFM( - this.application.project_application_perun_id, - this.application.project_application_compute_center.FacilityId, - ) - .subscribe( - (): void => { - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - this.showNotificationModal('Success', 'The project was terminated.', 'success'); - }, - (error: any): void => { - if (error['status'] === 409) { - this.showNotificationModal( - 'Failed', - `The project could not be terminated. Reason: ${error['error']['reason']} for ${error['error']['openstackid']}`, + approveTermination(): void { + this.facilityService + .approveTerminationByFM( + this.application.project_application_perun_id, + this.application.project_application_compute_center.FacilityId, + ) + .subscribe( + (): void => { + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + this.showNotificationModal('Success', 'The project was terminated.', 'success'); + }, + (error: any): void => { + if (error['status'] === 409) { + this.showNotificationModal( + 'Failed', + `The project could not be terminated. Reason: ${error['error']['reason']} for ${error['error']['openstackid']}`, - 'danger', - ); - } else { - this.showNotificationModal('Failed', 'The project could not be terminated.', 'danger'); - } - }, - ); - } + 'danger', + ); + } else { + this.showNotificationModal('Failed', 'The project could not be terminated.', 'danger'); + } + }, + ); + } - declineTermination(): void { - this.facilityService - .declineTerminationByFM( - this.application.project_application_perun_id, - this.application.project_application_compute_center.FacilityId, - ) - .subscribe( - (): void => { - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - this.showNotificationModal('Success', 'The termination of the project was declined.', 'success'); - }, - (error: any): void => { - if (error['status'] === 409) { - this.showNotificationModal( - 'Failed', - `The decline of the project was not successful. Reason: ${error['error']['reason']} for ${error['error']['openstackid']}`, + declineTermination(): void { + this.facilityService + .declineTerminationByFM( + this.application.project_application_perun_id, + this.application.project_application_compute_center.FacilityId, + ) + .subscribe( + (): void => { + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + this.showNotificationModal('Success', 'The termination of the project was declined.', 'success'); + }, + (error: any): void => { + if (error['status'] === 409) { + this.showNotificationModal( + 'Failed', + `The decline of the project was not successful. Reason: ${error['error']['reason']} for ${error['error']['openstackid']}`, - 'danger', - ); - } else { - this.showNotificationModal('Failed', 'The decline of the project failed.', 'danger'); - } - }, - ); - } + 'danger', + ); + } else { + this.showNotificationModal('Failed', 'The decline of the project failed.', 'danger'); + } + }, + ); + } - subscribeToBsModalRef(): void { - this.subscription.add( - this.bsModalRef.content.event.subscribe((event: any) => { - const action: ConfirmationActions = event.action; - switch (action) { - case ConfirmationActions.APPROVE_APPLICATION: { - this.approveApplication(); - break; - } - case ConfirmationActions.DECLINE_APPLICATION: { - this.declineApplication(); - break; - } - case ConfirmationActions.DECLINE_EXTENSION: { - this.declineExtension(); - break; - } - case ConfirmationActions.APPROVE_EXTENSION: { - this.approveExtension(); - break; - } - case ConfirmationActions.DECLINE_MODIFICATION: { - this.declineModification(); - break; - } - case ConfirmationActions.APPROVE_MODIFICATION: { - this.approveModification(); - break; - } - case ConfirmationActions.APPROVE_TERMINATION: { - this.approveTermination(); - break; - } - case ConfirmationActions.DECLINE_TERMINATION: { - this.declineTermination(); - break; - } - default: - break; - } - }), - ); - } + subscribeToBsModalRef(): void { + this.subscription.add( + this.bsModalRef.content.event.subscribe((event: any) => { + const action: ConfirmationActions = event.action; + switch (action) { + case ConfirmationActions.APPROVE_APPLICATION: { + this.approveApplication(); + break; + } + case ConfirmationActions.DECLINE_APPLICATION: { + this.declineApplication(); + break; + } + case ConfirmationActions.DECLINE_EXTENSION: { + this.declineExtension(); + break; + } + case ConfirmationActions.APPROVE_EXTENSION: { + this.approveExtension(); + break; + } + case ConfirmationActions.DECLINE_MODIFICATION: { + this.declineModification(); + break; + } + case ConfirmationActions.APPROVE_MODIFICATION: { + this.approveModification(); + break; + } + case ConfirmationActions.APPROVE_TERMINATION: { + this.approveTermination(); + break; + } + case ConfirmationActions.DECLINE_TERMINATION: { + this.declineTermination(); + break; + } + default: + break; + } + }), + ); + } - ngOnInit() {} + ngOnInit() {} - protected readonly Application_States = Application_States; + protected readonly Application_States = Application_States; } diff --git a/src/app/applications/application-list/application-list.component.ts b/src/app/applications/application-list/application-list.component.ts index f761a7873e..c1c4a11e4d 100644 --- a/src/app/applications/application-list/application-list.component.ts +++ b/src/app/applications/application-list/application-list.component.ts @@ -15,72 +15,73 @@ import { is_vo } from '../../shared/globalvar'; styleUrl: './application-list.component.scss', }) export class ApplicationListComponent implements OnInit, OnChanges { - @Output() reloadNumbersTrigger: EventEmitter = new EventEmitter(); + @Output() reloadNumbersTrigger: EventEmitter = new EventEmitter(); - @Input() applications: Application[] = []; - @Input() tabState: ApplicationTabStates = ApplicationTabStates.SUBMITTED; - @Input() computeCenters: ComputecenterComponent[] = []; - @Input() facilityView: boolean = false; - @Input() voView: boolean = false; - dataTestId: string = ''; + @Input() applications: Application[] = []; + @Input() tabState: ApplicationTabStates = ApplicationTabStates.SUBMITTED; + @Input() computeCenters: ComputecenterComponent[] = []; + @Input() facilityView: boolean = false; + @Input() voView: boolean = false; - is_vo_admin: boolean = false; + dataTestId: string = ''; - ngOnInit() { - this.is_vo_admin = is_vo; - this.setDataTestId(); - } + is_vo_admin: boolean = false; - ngOnChanges(changes: SimpleChanges) { - this.setDataTestId(); + ngOnInit() { + this.is_vo_admin = is_vo; + this.setDataTestId(); + } - } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ngOnChanges(changes: SimpleChanges) { + this.setDataTestId(); + } - setDataTestId(): void { - console.log('set data test id'); - switch (this.tabState) { - case ApplicationTabStates.SUBMITTED: { - this.dataTestId = 'submitted_applications_container'; - break; - } - case ApplicationTabStates.CREDITS_EXTENSION: { - this.dataTestId = 'credits_requests_applications_container'; - break; - } - case ApplicationTabStates.LIFETIME_EXTENSION: { - this.dataTestId = 'lifetime_requests_applications_container'; - break; - } - case ApplicationTabStates.MODIFICATION_EXTENSION: { - this.dataTestId = 'modification_requests_applications_container'; - break; - } - case ApplicationTabStates.TERMINATION_REQUEST: { - this.dataTestId = 'termination_requests_applications_container'; - break; - } - default: { - break; - } + setDataTestId(): void { + console.log('set data test id'); + switch (this.tabState) { + case ApplicationTabStates.SUBMITTED: { + this.dataTestId = 'submitted_applications_container'; + break; + } + case ApplicationTabStates.CREDITS_EXTENSION: { + this.dataTestId = 'credits_requests_applications_container'; + break; + } + case ApplicationTabStates.LIFETIME_EXTENSION: { + this.dataTestId = 'lifetime_requests_applications_container'; + break; + } + case ApplicationTabStates.MODIFICATION_EXTENSION: { + this.dataTestId = 'modification_requests_applications_container'; + break; + } + case ApplicationTabStates.TERMINATION_REQUEST: { + this.dataTestId = 'termination_requests_applications_container'; + break; + } + default: { + break; } - console.log(this.dataTestId); } + console.log(this.dataTestId); + } - triggerReloadNumbers() { - console.log('trigger reload 2'); - this.reloadNumbersTrigger.emit(); - } + triggerReloadNumbers() { + console.log('trigger reload 2'); + this.reloadNumbersTrigger.emit(); + } - removeApplicationFromList(application_id: string | number) { - const idx: number = this.applications.findIndex( - (application: Application) => application.project_application_id === application_id, - ); + removeApplicationFromList(application_id: string | number) { + const idx: number = this.applications.findIndex( + (application: Application) => application.project_application_id === application_id, + ); - if (idx !== -1) { - console.log('remove index'); - this.applications.splice(idx, 1); - } + if (idx !== -1) { + console.log('remove index'); + this.applications.splice(idx, 1); } + } - protected readonly Application_States = Application_States; + protected readonly Application_States = Application_States; } diff --git a/src/app/applications/application-vo-actions/application-vo-actions.component.ts b/src/app/applications/application-vo-actions/application-vo-actions.component.ts index 68191fff20..86ef775905 100644 --- a/src/app/applications/application-vo-actions/application-vo-actions.component.ts +++ b/src/app/applications/application-vo-actions/application-vo-actions.component.ts @@ -14,9 +14,15 @@ import { is_vo } from '../../shared/globalvar'; import { ApplicationsService } from '../../api-connector/applications.service'; import { VoService } from '../../api-connector/vo.service'; import { GroupService } from '../../api-connector/group.service'; -import { AdjustLifetimeRequestComponent } from '../../projectmanagement/modals/adjust-lifetime/adjust-lifetime-request.component'; -import { AdjustApplicationComponent } from '../../projectmanagement/modals/adjust-application/adjust-application.component'; -import { ModificationRequestComponent } from '../../projectmanagement/modals/modification-request/modification-request.component'; +import { + AdjustLifetimeRequestComponent, +} from '../../projectmanagement/modals/adjust-lifetime/adjust-lifetime-request.component'; +import { + AdjustApplicationComponent, +} from '../../projectmanagement/modals/adjust-application/adjust-application.component'; +import { + ModificationRequestComponent, +} from '../../projectmanagement/modals/modification-request/modification-request.component'; import { ConfirmationModalComponent } from '../../shared/modal/confirmation-modal.component'; import { ClientLimitsComponent } from '../../vo_manager/clients/modals/client-limits..component'; import { NotificationModalComponent } from '../../shared/modal/notification-modal'; @@ -29,224 +35,386 @@ import { NotificationModalComponent } from '../../shared/modal/notification-moda export class ApplicationVoActionsComponent extends AbstractBaseClass implements OnInit { private subscription: Subscription = new Subscription(); - @Input() application: Application; - @Input() tabState: ApplicationTabStates = ApplicationTabStates.SUBMITTED; - @Input() computeCenters: ComputecenterComponent[] = []; - @Output() reloadNumbersTrigger: EventEmitter = new EventEmitter(); - @Output() removeApplicationTrigger: EventEmitter = new EventEmitter(); - @Output() switchCollapseEvent: EventEmitter = new EventEmitter(); - - bsModalRef: BsModalRef; - is_vo_admin: boolean = false; - selectedComputeCenter: ComputecenterComponent; - - ngOnInit() { - this.is_vo_admin = is_vo; - } - - constructor( - private applicationsService: ApplicationsService, - private modalService: BsModalService, - private voService: VoService, - private groupService: GroupService, - private adjustLifeTimeExtensionModal: AdjustLifetimeRequestComponent, - private adjustApplicationModal: AdjustApplicationComponent, - ) { - super(); - } - - triggerRemoveApplication() { - this.removeApplicationTrigger.emit(this.application.project_application_id); - } - - showAdjustLifetimeExtensionModal() { - this.adjustLifeTimeExtensionModal - .showAdjustLifetimeExtensionModal(this.application) - .subscribe((eventSuccess: boolean) => { - if (eventSuccess) { - this.getApplication(); - this.showNotificationModal( - 'Success', - 'The lifetime of the extension request were adjusted successfully!', - 'success', - ); + @Input() application: Application; + @Input() tabState: ApplicationTabStates = ApplicationTabStates.SUBMITTED; + @Input() computeCenters: ComputecenterComponent[] = []; + @Output() reloadNumbersTrigger: EventEmitter = new EventEmitter(); + @Output() reloadApplicationTrigger: EventEmitter = new EventEmitter(); + @Output() removeApplicationTrigger: EventEmitter = new EventEmitter(); + @Output() switchCollapseEvent: EventEmitter = new EventEmitter(); + + bsModalRef: BsModalRef; + is_vo_admin: boolean = false; + selectedComputeCenter: ComputecenterComponent; + + ngOnInit() { + this.is_vo_admin = is_vo; + } + + constructor( + private applicationsService: ApplicationsService, + private modalService: BsModalService, + private voService: VoService, + private groupService: GroupService, + private adjustLifeTimeExtensionModal: AdjustLifetimeRequestComponent, + private adjustApplicationModal: AdjustApplicationComponent, + ) { + super(); + } + + triggerRemoveApplication() { + this.removeApplicationTrigger.emit(this.application.project_application_id); + } + + showAdjustLifetimeExtensionModal() { + this.adjustLifeTimeExtensionModal + .showAdjustLifetimeExtensionModal(this.application) + .subscribe((eventSuccess: boolean) => { + if (eventSuccess) { + this.triggerReloadApplication(); + this.showNotificationModal( + 'Success', + 'The lifetime of the extension request were adjusted successfully!', + 'success', + ); + } else { + this.showNotificationModal('Failed', 'The adjustment of the lifetime has failed!', 'danger'); + } + }); + } + + triggerReloadApplication(): void { + this.reloadApplicationTrigger.emit(); + + } + + showAdjustApplicationModal() { + this.adjustApplicationModal.showAdjustApplicationModal(this.application).subscribe((changed: boolean) => { + if (changed) { + this.triggerReloadApplication(); + + this.showNotificationModal('Success', 'The resources of the application were adjusted successfully!', 'success'); } else { - this.showNotificationModal('Failed', 'The adjustment of the lifetime has failed!', 'danger'); + this.showNotificationModal('Failed', 'The adjustment of the resources has failed!', 'danger'); } }); - } + } + + showModificationAdjustmentModal() { + const initialState = { + project: this.application, + adjustment: true, + }; + + this.bsModalRef = this.modalService.show(ModificationRequestComponent, { + initialState, + class: 'modal-lg', + }); + this.subscribeToBsModalRef(); + // this.subscribeForExtensionResult(this.ExtensionRequestType.MODIFICATION); + } + + triggerReloadNumbers() { + this.reloadNumbersTrigger.emit(); + } - showAdjustApplicationModal() { - this.adjustApplicationModal.showAdjustApplicationModal(this.application).subscribe((changed: boolean) => { - if (changed) { - this.getApplication(); + setCurrentUserProcessingVoManager(application: Application): void { + if (this.is_vo_admin) { + this.voService.setCurrentUserProcessingVoManager(application.project_application_id).subscribe((res: any) => { + application.processing_vo_initials = res['processing_vo_initials']; + }); + } + } - this.showNotificationModal('Success', 'The resources of the application were adjusted successfully!', 'success'); + showConfirmationModal(action: ConfirmationActions): void { + let initialState = {}; + if (action === ConfirmationActions.APPROVE_APPLICATION) { + const application_center = !this.selectedComputeCenter.FacilityId; + initialState = { application: this.application, action, application_center }; } else { - this.showNotificationModal('Failed', 'The adjustment of the resources has failed!', 'danger'); + initialState = { + application: this.application, + action, + }; } - }); - } - - showModificationAdjustmentModal() { - const initialState = { - project: this.application, - adjustment: true, - }; - - this.bsModalRef = this.modalService.show(ModificationRequestComponent, { - initialState, - class: 'modal-lg', - }); - this.subscribeToBsModalRef(); - // this.subscribeForExtensionResult(this.ExtensionRequestType.MODIFICATION); - } - - triggerReloadNumbers() { - this.reloadNumbersTrigger.emit(); - } - - setCurrentUserProcessingVoManager(application: Application): void { - if (this.is_vo_admin) { - this.voService.setCurrentUserProcessingVoManager(application.project_application_id).subscribe((res: any) => { - application.processing_vo_initials = res['processing_vo_initials']; - }); + this.bsModalRef = this.modalService.show(ConfirmationModalComponent, { initialState, class: 'modal-lg' }); + this.subscribeToBsModalRef(); } - } - - showConfirmationModal(action: ConfirmationActions): void { - let initialState = {}; - if (action === ConfirmationActions.APPROVE_APPLICATION) { - const application_center = !this.selectedComputeCenter.FacilityId; - initialState = { application: this.application, action, application_center }; - } else { - initialState = { - application: this.application, - action, - }; + + unsetProcessingVoManager(application: Application): void { + if (this.is_vo_admin) { + this.voService.unsetProcessingVoManager(application.project_application_id).subscribe(() => { + application.processing_vo_initials = null; + }); + } + } + + showClientsLimitsModal(is_modification_request: boolean = false): void { + let initialState = {}; + if (is_modification_request) { + initialState = { + compute_center_id: this.application.project_application_compute_center.FacilityId, + application: this.application, + is_modification_request, + }; + } else { + initialState = { + compute_center_id: this.selectedComputeCenter.FacilityId, + application: this.application, + is_modification_request, + }; + } + + this.bsModalRef = this.modalService.show(ClientLimitsComponent, { initialState }); + this.subscribeToBsModalRef(); + } + + removeApplicationFromFacilityConfirmation(): void { + this.groupService.removeGroupFromResource(this.application.project_application_perun_id.toString()).subscribe( + (): void => { + this.triggerReloadApplication(); + this.showNotificationModal('Success', 'The application was removed from the compute center', 'success'); + }, + (): void => { + this.showNotificationModal('Failed', 'The application was removed from the compute center', 'danger'); + }, + ); + } + + assignGroupToFacility(): void { + if (this.selectedComputeCenter) { + this.groupService + .assignGroupToResource(this.application.project_application_perun_id, this.selectedComputeCenter.FacilityId) + .subscribe( + (): void => { + this.triggerReloadApplication(); + + this.showNotificationModal('Success', 'The project was assigned to the facility.', 'success'); + }, + (error: object): void => { + console.log(error); + this.showNotificationModal('Failed', 'Project could not be created!', 'danger'); + }, + ); + } else { + this.showNotificationModal('Failed', 'You need to select an compute center!', 'danger'); + } } - this.bsModalRef = this.modalService.show(ConfirmationModalComponent, { initialState, class: 'modal-lg' }); - this.subscribeToBsModalRef(); - } - - unsetProcessingVoManager(application: Application): void { - if (this.is_vo_admin) { - this.voService.unsetProcessingVoManager(application.project_application_id).subscribe(() => { - application.processing_vo_initials = null; + + resetApplicationPI(): void { + this.applicationsService.resetPIValidation(this.application).subscribe(() => { + this.triggerReloadApplication(); }); } - } - - showClientsLimitsModal(is_modification_request: boolean = false): void { - let initialState = {}; - if (is_modification_request) { - initialState = { - compute_center_id: this.application.project_application_compute_center.FacilityId, - application: this.application, - is_modification_request, - }; - } else { - initialState = { - compute_center_id: this.selectedComputeCenter.FacilityId, - application: this.application, - is_modification_request, - }; + + switchCollaps() { + this.switchCollapseEvent.emit(); } - this.bsModalRef = this.modalService.show(ClientLimitsComponent, { initialState }); - this.subscribeToBsModalRef(); - } - - removeApplicationFromFacilityConfirmation(): void { - this.groupService.removeGroupFromResource(this.application.project_application_perun_id.toString()).subscribe( - (): void => { - this.getApplication(); - this.showNotificationModal('Success', 'The application was removed from the compute center', 'success'); - }, - (): void => { - this.showNotificationModal('Failed', 'The application was removed from the compute center', 'danger'); - }, - ); - } - - getApplication(): void { - this.applicationsService.getApplication(this.application.project_application_id.toString()).subscribe( - (aj: Application): void => { - this.application = aj; - }, - (error: any): void => { - console.log(error); - }, - ); - } - - assignGroupToFacility(): void { - if (this.selectedComputeCenter) { - this.groupService - .assignGroupToResource(this.application.project_application_perun_id, this.selectedComputeCenter.FacilityId) - .subscribe( - (): void => { - this.getApplication(); + showNotificationModal( + notificationModalTitle: string, + notificationModalMessage: string, + notificationModalType: string, + ) { + const initialState = { notificationModalTitle, notificationModalType, notificationModalMessage }; + if (this.bsModalRef) { + this.bsModalRef.hide(); + } + + this.bsModalRef = this.modalService.show(NotificationModalComponent, { initialState }); + this.bsModalRef.setClass('modal-lg'); + } + + createSimpleVmProjectGroup(): void { + this.showNotificationModal('Info', 'Creating Project...', 'info'); + + if (this.selectedComputeCenter && this.selectedComputeCenter.FacilityId) { + this.groupService + .createGroupByApplication(this.application.project_application_id, this.selectedComputeCenter.FacilityId) + .subscribe( + (res: any): void => { + if (!res['client_available'] && !res['created']) { + this.showNotificationModal( + 'Failed', + `The client ${res['client_name']} has not the necessary resources left!`, + 'danger', + ); + } else { + this.showNotificationModal('Success', 'The project was created!', 'success'); + this.triggerRemoveApplication(); + this.triggerReloadNumbers(); + } + }, + (error: any): void => { + console.log(error); + const errorMessage = error && error.error === 'locked' + ? 'Project is locked and could not be created!' + : 'Project could not be created!'; + + this.showNotificationModal('Failed', errorMessage, 'danger'); + console.log(error); + }, + ); + } + } + + approveModificationRequest(): void { + this.applicationsService.approveModificationRequest(this.application.project_application_id).subscribe( + (res: Response): void => { + this.showNotificationModal('Success', 'The resource modification request was approved!', 'success'); + if (!this.application.project_application_openstack_project) { + if (res.status === HttpStatusCode.Accepted) { + this.triggerRemoveApplication(); + this.triggerReloadNumbers(); + + // this.all_applications.splice(this.all_applications.indexOf(application), 1); + } + } else { + this.triggerReloadApplication(); + } + }, + (err: any): void => { + console.log('error', err.status); + this.showNotificationModal('Failed', 'Approval of resource modification failed!', 'danger'); + }, + ); + } + + declineModificationRequest(): void { + this.applicationsService.deleteModificationRequest(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Declined', 'The resource modification request was declined!', 'success'); + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + + this.triggerReloadApplication(); + }, + (err: any): void => { + console.log('error', err.status); + this.showNotificationModal('Failed', 'Decline of resource modification failed!', 'danger'); + }, + ); + } + + deleteApplication(): void { + // const idx: number = this.all_applications.indexOf(application); - this.showNotificationModal('Success', 'The project was assigned to the facility.', 'success'); + this.subscription.add( + this.applicationsService.deleteApplication(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Success', 'The application has been successfully removed', 'success'); + this.triggerRemoveApplication(); + this.triggerReloadNumbers(); }, - (error: object): void => { - console.log(error); - this.showNotificationModal('Failed', 'Project could not be created!', 'danger'); + (): void => { + this.updateNotificationModal('Failed', 'Application could not be removed!', true, 'danger'); }, - ); - } else { - this.showNotificationModal('Failed', 'You need to select an compute center!', 'danger'); + ), + ); } - } - - resetApplicationPI(): void { - this.applicationsService.resetPIValidation(this.application).subscribe(() => { - this.getApplication(); - }); - } - - switchCollaps() { - this.switchCollapseEvent.emit(); - } - - showNotificationModal( - notificationModalTitle: string, - notificationModalMessage: string, - notificationModalType: string, - ) { - const initialState = { notificationModalTitle, notificationModalType, notificationModalMessage }; - if (this.bsModalRef) { - this.bsModalRef.hide(); + + declineLifetimeExtension(): void { + this.applicationsService.deleteAdditionalLifetimeRequests(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Declined', 'The project extension was declined!', 'success'); + this.triggerRemoveApplication(); + this.triggerReloadNumbers(); + }, + (err: any): void => { + console.log('error', err.status); + this.showNotificationModal('Failed', 'Decline of project extension failed!', 'danger'); + }, + ); + } + + declineCreditExtension(): void { + this.applicationsService.deleteAdditionalCreditsRequests(this.application.project_application_id).subscribe( + (): void => { + this.showNotificationModal('Declined', 'The credit extension request was declined!', 'success'); + this.triggerRemoveApplication(); + this.triggerReloadNumbers(); + }, + (err: any): void => { + console.log('error', err.status); + this.showNotificationModal('Failed', 'Decline of credit extension failed!', 'danger'); + }, + ); } - this.bsModalRef = this.modalService.show(NotificationModalComponent, { initialState }); - this.bsModalRef.setClass('modal-lg'); - } + declineApplication(): void { + // const idx: number = this.all_applications.indexOf(app); + this.applicationsService.declineApplication(this.application.project_application_id).subscribe( + (): void => { + const message: string = 'The Application was declined.'; + + this.showNotificationModal('Success', message, 'success'); + this.triggerRemoveApplication(); + this.triggerReloadNumbers(); + }, + (): void => { + this.showNotificationModal('Failed', 'Application could not be declined!', 'danger'); + }, + ); + } + + approveLifetimeExtension(): void { + this.applicationsService.approveAdditionalLifetime(this.application.project_application_id).subscribe( + (res: Response): void => { + if (this.application.project_application_openstack_project) { + this.triggerReloadApplication(); + this.showNotificationModal('Success', 'The request has been sent to the facility manager.', 'success'); + } else { + this.showNotificationModal('Success', 'The project has been extended!', 'success'); + } + if (!this.application.project_application_openstack_project) { + if (res.status === HttpStatusCode.Accepted) { + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + } + } + }, + (err: any): void => { + console.log('error', err.status); + this.showNotificationModal('Failed', 'Project lifetime could not be extendend!', 'danger'); + }, + ); + } - createSimpleVmProjectGroup(): void { - this.showNotificationModal('Info', 'Creating Project...', 'info'); + approveCreditExtension(): void { + this.applicationsService.approveAdditionalCreditsRequest(this.application.project_application_id).subscribe( + (res: Response): void => { + this.showNotificationModal('Success', 'The credit extension request was approved!', 'success'); + if (!this.application.project_application_openstack_project) { + if (res.status === HttpStatusCode.Accepted) { + this.triggerReloadNumbers(); + this.triggerRemoveApplication(); + } + } else { + this.triggerReloadApplication(); + } + }, + (err: any): void => { + console.log('error', err.status); + this.showNotificationModal('Failed', 'Approval of credit extension failed!', 'danger'); + }, + ); + } - if (this.selectedComputeCenter && this.selectedComputeCenter.FacilityId) { + createOpenStackProjectGroup(): void { this.groupService - .createGroupByApplication(this.application.project_application_id, this.selectedComputeCenter.FacilityId) + .createGroupOpenStack(this.application.project_application_id, this.selectedComputeCenter.FacilityId) .subscribe( - (res: any): void => { - if (!res['client_available'] && !res['created']) { - this.showNotificationModal( - 'Failed', - `The client ${res['client_name']} has not the necessary resources left!`, - 'danger', - ); + (result: { [key: string]: string }): void => { + if (result['Error']) { + this.showNotificationModal('Failed', result['Error'], 'danger'); } else { - this.showNotificationModal('Success', 'The project was created!', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); + this.showNotificationModal('Success', 'The project was assigned to the facility.', 'success'); + this.triggerReloadApplication(); + // this.switchApproveLocked(false); } }, (error: any): void => { - console.log(error); - const errorMessage = error && error.error === 'locked' + const errorMessage = error && error.error === 'locked' ? 'Project is locked and could not be created!' : 'Project could not be created!'; @@ -255,233 +423,66 @@ export class ApplicationVoActionsComponent extends AbstractBaseClass implements }, ); } - } - - approveModificationRequest(): void { - this.applicationsService.approveModificationRequest(this.application.project_application_id).subscribe( - (res: Response): void => { - this.showNotificationModal('Success', 'The resource modification request was approved!', 'success'); - if (!this.application.project_application_openstack_project) { - if (res.status === HttpStatusCode.Accepted) { - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - // this.all_applications.splice(this.all_applications.indexOf(application), 1); + /** + * Function to listen to modal results. + */ + subscribeToBsModalRef(): void { + this.subscription.add( + this.bsModalRef.content.event.subscribe((result: any) => { + let action = null; + if ('action' in result) { + action = result['action']; } - } else { - this.getApplication(); - } - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Approval of resource modification failed!', 'danger'); - }, - ); - } - - declineModificationRequest(): void { - this.applicationsService.deleteModificationRequest(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Declined', 'The resource modification request was declined!', 'success'); - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); - - this.getApplication(); - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Decline of resource modification failed!', 'danger'); - }, - ); - } - - deleteApplication(): void { - // const idx: number = this.all_applications.indexOf(application); - - this.subscription.add( - this.applicationsService.deleteApplication(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Success', 'The application has been successfully removed', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (): void => { - this.updateNotificationModal('Failed', 'Application could not be removed!', true, 'danger'); - }, - ), - ); - } - - declineLifetimeExtension(): void { - this.applicationsService.deleteAdditionalLifetimeRequests(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Declined', 'The project extension was declined!', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Decline of project extension failed!', 'danger'); - }, - ); - } - - declineCreditExtension(): void { - this.applicationsService.deleteAdditionalCreditsRequests(this.application.project_application_id).subscribe( - (): void => { - this.showNotificationModal('Declined', 'The credit extension request was declined!', 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Decline of credit extension failed!', 'danger'); - }, - ); - } - - declineApplication(): void { - // const idx: number = this.all_applications.indexOf(app); - this.applicationsService.declineApplication(this.application.project_application_id).subscribe( - (): void => { - const message: string = 'The Application was declined.'; - - this.showNotificationModal('Success', message, 'success'); - this.triggerRemoveApplication(); - this.triggerReloadNumbers(); - }, - (): void => { - this.showNotificationModal('Failed', 'Application could not be declined!', 'danger'); - }, - ); - } - - approveLifetimeExtension(): void { - this.applicationsService.approveAdditionalLifetime(this.application.project_application_id).subscribe( - (res: Response): void => { - if (this.application.project_application_openstack_project) { - this.getApplication(); - this.showNotificationModal('Success', 'The request has been sent to the facility manager.', 'success'); - } else { - this.showNotificationModal('Success', 'The project has been extended!', 'success'); - } - if (!this.application.project_application_openstack_project) { - if (res.status === HttpStatusCode.Accepted) { - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); + if ('createSimpleVM' in result) { + this.createSimpleVmProjectGroup(); } - } - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Project lifetime could not be extendend!', 'danger'); - }, - ); - } - - approveCreditExtension(): void { - this.applicationsService.approveAdditionalCreditsRequest(this.application.project_application_id).subscribe( - (res: Response): void => { - this.showNotificationModal('Success', 'The credit extension request was approved!', 'success'); - if (!this.application.project_application_openstack_project) { - if (res.status === HttpStatusCode.Accepted) { - this.triggerReloadNumbers(); - this.triggerRemoveApplication(); + if (action === ConfirmationActions.APPROVE_MODIFICATION) { + this.approveModificationRequest(); } - } else { - this.getApplication(); - } - }, - (err: any): void => { - console.log('error', err.status); - this.showNotificationModal('Failed', 'Approval of credit extension failed!', 'danger'); - }, - ); - } - - createOpenStackProjectGroup(): void { - this.groupService - .createGroupOpenStack(this.application.project_application_id, this.selectedComputeCenter.FacilityId) - .subscribe( - (result: { [key: string]: string }): void => { - if (result['Error']) { - this.showNotificationModal('Failed', result['Error'], 'danger'); - } else { - this.showNotificationModal('Success', 'The project was assigned to the facility.', 'success'); - this.getApplication(); - // this.switchApproveLocked(false); + if ('closed' in result) { + // this.switchApproveLocked(false); + } + if (action === ConfirmationActions.DECLINE_MODIFICATION) { + this.declineModificationRequest(); + } + if (action === ConfirmationActions.DELETE_APPLICATION) { + this.deleteApplication(); + } + if (action === ConfirmationActions.DECLINE_EXTENSION) { + this.declineLifetimeExtension(); + } + if (action === ConfirmationActions.DECLINE_CREDITS) { + this.declineCreditExtension(); + } + if (action === ConfirmationActions.DECLINE_APPLICATION) { + this.declineApplication(); } - }, - (error: any): void => { - const errorMessage = error && error.error === 'locked' - ? 'Project is locked and could not be created!' - : 'Project could not be created!'; - this.showNotificationModal('Failed', errorMessage, 'danger'); - console.log(error); - }, + if (action === ConfirmationActions.APPROVE_EXTENSION) { + this.approveLifetimeExtension(); + } + if (action === ConfirmationActions.RESET_PI) { + this.resetApplicationPI(); + } + if (action === ConfirmationActions.APPROVE_CREDITS) { + this.approveCreditExtension(); + } + if (action === ConfirmationActions.APPROVE_APPLICATION) { + if (this.application.project_application_openstack_project) { + this.createOpenStackProjectGroup(); + } + } + if (action === 'adjustedModificationRequest') { + // this.isLoaded = false; + // this.changeTabState(ApplicationTabStates.MODIFICATION_EXTENSION); + } + }), ); - } - - /** - * Function to listen to modal results. - */ - subscribeToBsModalRef(): void { - this.subscription.add( - this.bsModalRef.content.event.subscribe((result: any) => { - let action = null; - if ('action' in result) { - action = result['action']; - } - if ('createSimpleVM' in result) { - this.createSimpleVmProjectGroup(); - } - if (action === ConfirmationActions.APPROVE_MODIFICATION) { - this.approveModificationRequest(); - } - if ('closed' in result) { - // this.switchApproveLocked(false); - } - if (action === ConfirmationActions.DECLINE_MODIFICATION) { - this.declineModificationRequest(); - } - if (action === ConfirmationActions.DELETE_APPLICATION) { - this.deleteApplication(); - } - if (action === ConfirmationActions.DECLINE_EXTENSION) { - this.declineLifetimeExtension(); - } - if (action === ConfirmationActions.DECLINE_CREDITS) { - this.declineCreditExtension(); - } - if (action === ConfirmationActions.DECLINE_APPLICATION) { - this.declineApplication(); - } + } - if (action === ConfirmationActions.APPROVE_EXTENSION) { - this.approveLifetimeExtension(); - } - if (action === ConfirmationActions.RESET_PI) { - this.resetApplicationPI(); - } - if (action === ConfirmationActions.APPROVE_CREDITS) { - this.approveCreditExtension(); - } - if (action === ConfirmationActions.APPROVE_APPLICATION) { - if (this.application.project_application_openstack_project) { - this.createOpenStackProjectGroup(); - } - } - if (action === 'adjustedModificationRequest') { - // this.isLoaded = false; - // this.changeTabState(ApplicationTabStates.MODIFICATION_EXTENSION); - } - }), - ); - } - - isCollapsed: boolean = true; - protected readonly Application_States = Application_States; - protected readonly ConfirmationActions = ConfirmationActions; - protected readonly ApplicationTabStates = ApplicationTabStates; + isCollapsed: boolean = true; + protected readonly Application_States = Application_States; + protected readonly ConfirmationActions = ConfirmationActions; + protected readonly ApplicationTabStates = ApplicationTabStates; } diff --git a/src/app/applications/type-overview.component.html b/src/app/applications/type-overview.component.html index 174f0f468a..e0561c5a7d 100644 --- a/src/app/applications/type-overview.component.html +++ b/src/app/applications/type-overview.component.html @@ -1,762 +1,722 @@ @if (is_vo_admin) { -
- -
- -
- Our de.NBI Cloud Project Types - -
- -
- -
- -
- -
- - -
-
-
- SimpleVM -
-
-
-
- -
-
- Ease -
-
- Ease of Use – SimpleVM lets you start and stop VMs with a few - clicks - which means that - there is no additional configuration necessary. -
-
-
- -
-
- Curve -
-
- Flat Learning Curve – If you want to use SimpleVM you don’t have to - learn about - resource management, like network configurations or storage management. No - background - knowledge in Cloud - Computing is necessary. -
-
-
- -
-
- Remote -
-
- Remote Desktop – If you don’t want to use SimpleVM via terminal you - can - easily connect - to your VM using a Remote Desktop. -
-
-
-
-
- -
-
- Workshop support – Create a workshop and start multiple configured - VMs - for your - participants with just a few clicks. To learn more about our workshop support click - here. -
-
-
- -
-
- Typical use cases: -
    -
  • - Tools and Pipelines: SimpleVM is a quick way to get up and - running with your tools - and pipelines in the cloud. -
  • -
  • - Remote Desktop: Launch your own Desktop or a browser-based - IDE - in the cloud (based - on Apache Guacamole, RStudio, Theia IDE, and more) and be able to run - programs - with graphical user - interfaces in addition to the command-line. -
  • -
-
-
+
+ +
+ +
+ Our de.NBI Cloud Project Types + +
+ +
+ +
+ +
+ +
+ + +
+
+
+ SimpleVM +
+
+
+
+ +
+
+ Ease +
+
+ Ease of Use – SimpleVM lets you start and stop VMs with a few clicks which means that + there is no additional configuration necessary. +
+
+
+ +
+
+ Curve +
+
+ Flat Learning Curve – If you want to use SimpleVM you don’t have to learn about + resource management, like network configurations or storage management. No background knowledge in + Cloud Computing is necessary. +
+
+
+ +
+
+ Remote +
+
+ Remote Desktop – If you don’t want to use SimpleVM via terminal you can easily + connect to your VM using a Remote Desktop. +
+
+
+
+
+ +
+
+ Workshop support – Create a workshop and start multiple configured VMs for your + participants with just a few clicks. To learn more about our workshop support click + here. +
+
+
+ +
+
+ Typical use cases: +
    +
  • + Tools and Pipelines: SimpleVM is a quick way to get up and running with your + tools and pipelines in the cloud. +
  • +
  • + Remote Desktop: Launch your own Desktop or a browser-based IDE in the cloud + (based on Apache Guacamole, RStudio, Theia IDE, and more) and be able to run programs with + graphical user interfaces in addition to the command-line. +
  • +
+
+
-
-
- -
-
-
- Want to learn more about SimpleVM? -
- -
-
-
- -
+
+
+ +
+
+
+ Want to learn more about SimpleVM? +
+ +
+
+
+ +
- -
- - -
-
-
- Openstack -
-
-
-
- -
-
- Scale -
-
- Scalability – Easy scaling of virtual machines and distribution of - data - for efficient - computations. -
-
-
- -
-
- Configuration -
-
- Configurability – OpenStack allows the configuration of any - resource - type available, - such as virtual machines, network, block and object storage. -
-
-
- -
-
- API -
-
- API Access – Any interaction with OpenStack can be automated via - its - API enabling users - to script actions, e.g. starting and stopping of virtual machines. -
-
-
- -
-
- Typical use cases: -
    -
  • - Distributed Workflows: Distribution of workflows on - multiple - virtual machines. -
  • -
  • Services: The ability to offer services for other - researchers. -
  • -
-
-
+ +
+ + +
+
+
+ Openstack +
+
+
+
+ +
+
+ Scale +
+
+ Scalability – Easy scaling of virtual machines and distribution of data for efficient + computations. +
+
+
+ +
+
+ Configuration +
+
+ Configurability – OpenStack allows the configuration of any resource type available, + such as virtual machines, network, block and object storage. +
+
+
+ +
+
+ API +
+
+ API Access – Any interaction with OpenStack can be automated via its API enabling + users to script actions, e.g. starting and stopping of virtual machines. +
+
+
+ +
+
+ Typical use cases: +
    +
  • + Distributed Workflows: Distribution of workflows on multiple virtual machines. +
  • +
  • Services: The ability to offer services for other researchers.
  • +
+
+
-
-
- -
-
-
- Want to learn more about Openstack? -
- -
-
-
- -
-
- - -
-
-
- Kubernetes -
-
-
-
- -
-
- Scale -
-
- Scalability – Easy scaling of virtual machines and distribution of - data for efficient - computations. -
-
-
- -
-
- Configuration -
-
- Configurability – Kubernetes allows the configuration of any - resource type available, - such as virtual machines, network. -
-
-
- -
-
- API -
-
- API Access – Any interaction with Kubernetes can be automated via - its API enabling - users to script actions, e.g. starting and stopping of containerized services. -
-
-
- -
-
- Typical use cases: -
    -
  • - Workflow Engines: Workflow engines like Nextflow allow you - to run your analysis on - top of Kubernetes. -
  • -
  • - Services: The ability to offer stateless and stateful - (databases) services for - other researchers. -
  • -
-
-
+
+
+ +
+
+
+ Want to learn more about Openstack? +
+ +
+
+
+ +
+
+ + +
+
+
+ Kubernetes +
+
+
+
+ +
+
+ Scale +
+
+ Scalability – Easy scaling of containers and distribution of data for efficient + computations. +
+
+
+ +
+
+ Configuration +
+
+ Configurability – Kubernetes allows the configuration of any resource type available, + such as virtual machines, network. +
+
+
+ +
+
+ API +
+
+ API Access – Any interaction with Kubernetes can be automated via its API enabling + users to script actions, e.g. starting and stopping of containerized services. +
+
+
+ +
+
+ Typical use cases: +
    +
  • + Workflow Engines: Workflow engines like Nextflow allow you to run your analysis + on top of Kubernetes. +
  • +
  • + Services: The ability to offer stateless and stateful (databases) services for + other researchers. +
  • +
+
+
-
-
-
-
-
- Want to learn more about Kubernetes? -
- -
-
-
- -
+
+
+
+
+
+ Want to learn more about Kubernetes? +
+ +
+
+
+ +
- - -
- -
-
- -
-
- Want to learn more about SimpleVM? -
- -
- - -
-
- Want to learn more about Openstack? -
- -
-
-
- Want to learn more about Kubernetes? -
- -
- -
-
-
-
-
-
- Want to learn the Difference? -
- -
-
-
-
- -
- -
- -
- -
- -
+ +
+ +
+
+ +
+
+ Want to learn more about SimpleVM? +
+ +
+ + +
+
+ Want to learn more about Openstack? +
+ +
+
+
+ Want to learn more about Kubernetes? +
+ +
+
+
+
+
+
+
+ Want to learn the Difference? +
+ +
+
+
+
+ +
+ +
+ +
+ +
+ +
} @else { -
- -
- -
- Our de.NBI Cloud Project Types - -
- -
- -
- - -
- -
- -
- -
-
-
- SimpleVM -
-
-
-
- -
-
- Ease -
-
- Ease of Use – SimpleVM lets you start and stop VMs with a few - clicks which means that - there is no additional configuration necessary. -
-
-
- -
-
- Curve -
-
- Flat Learning Curve – If you want to use SimpleVM you don’t have to - learn about - resource management, like network configurations or storage management. No - background knowledge in Cloud - Computing is necessary. -
-
-
- -
-
- Remote -
-
- Remote Desktop – If you don’t want to use SimpleVM via terminal you - can easily connect - to your VM using a Remote Desktop. -
-
-
-
-
- -
-
- Workshop support – Create a workshop and start multiple configured - VMs for your - participants with just a few clicks. To learn more about our workshop support click - here. -
-
-
- -
-
-
-
- Typical use cases: -
-
-
-
-
-
- • Tools and Pipelines - – SimpleVM is a quick way to get up and running with your tools and pipelines in - the cloud. -
-
-
-
-
-
- • Remote Desktop - – Launch your own Desktop or a browser based IDE in the cloud (based on Apache - Guacamole, RStudio, - Theia IDE and more) and be able to run programs with graphical user interfaces - in addition to the - command-line. -
-
-
-
-
- -
-
-
- Want to learn more about SimpleVM? -
- -
-
- -
- - - -
-
-
- Want to learn the Difference between SimpleVM and Openstack? -
- -
-
+
+ +
+ +
+ Our de.NBI Cloud Project Types + +
+ +
+ +
+ + +
+ +
+ +
+ +
+
+
+ SimpleVM +
+
+
+
+ +
+
+ Ease +
+
+ Ease of Use – SimpleVM lets you start and stop VMs with a few clicks which means that + there is no additional configuration necessary. +
+
+
+ +
+
+ Curve +
+
+ Flat Learning Curve – If you want to use SimpleVM you don’t have to learn about + resource management, like network configurations or storage management. No background knowledge in + Cloud Computing is necessary. +
+
+
+ +
+
+ Remote +
+
+ Remote Desktop – If you don’t want to use SimpleVM via terminal you can easily + connect to your VM using a Remote Desktop. +
+
+
+
+
+ +
+
+ Workshop support – Create a workshop and start multiple configured VMs for your + participants with just a few clicks. To learn more about our workshop support click + here. +
+
+
+ +
+
+
+
+ Typical use cases: +
+
+
+
+
+
+ • Tools and Pipelines + – SimpleVM is a quick way to get up and running with your tools and pipelines in the cloud. +
+
+
+
+
+
+ • Remote Desktop + – Launch your own Desktop or a browser based IDE in the cloud (based on Apache Guacamole, RStudio, + Theia IDE and more) and be able to run programs with graphical user interfaces in addition to the + command-line. +
+
+
+
+
+ +
+
+
+ Want to learn more about SimpleVM? +
+ +
+
+ +
- -
- -
-
-
- Openstack -
-
-
-
- -
-
- Scale -
-
- Scalability – Easy scaling of virtual machines and distribution of - data for efficient - computations. -
-
-
- -
-
- Configuration -
-
- Configurability – OpenStack allows the configuration of any - resource type available, - such as virtual machines, network, block and object storage. -
-
-
- -
-
- API -
-
- API Access – Any interaction with OpenStack can be automated via - its API enabling users - to script actions, e.g. starting and stopping of virtual machines. -
-
-
- -
-
-
-
- Typical use cases: -
-
-
-
-
-
- • Distributed Workflows - – Distribution of workflows on multiple virtual machines. -
-
-
-
-
-
- • Services - – The ability to offer services for other researchers. -
-
-
-
-
- -
-
-
- Want to learn more about Openstack? -
- -
-
-
- -
- -
- -
-
- -
-
- Want to learn more about SimpleVM? -
- -
- -
-
- Want to learn the Difference? -
- -
- -
-
- Want to learn more about Openstack? -
- -
-
-
- -
- -
- -
- -
- -
+ + +
+
+
+ Want to learn the Difference between SimpleVM and Openstack? +
+ +
+
-} \ No newline at end of file + +
+ +
+
+
+ Openstack +
+
+
+
+ +
+
+ Scale +
+
+ Scalability – Easy scaling of virtual machines and distribution of data for efficient + computations. +
+
+
+ +
+
+ Configuration +
+
+ Configurability – OpenStack allows the configuration of any resource type available, + such as virtual machines, network, block and object storage. +
+
+
+ +
+
+ API +
+
+ API Access – Any interaction with OpenStack can be automated via its API enabling + users to script actions, e.g. starting and stopping of virtual machines. +
+
+
+ +
+
+
+
+ Typical use cases: +
+
+
+
+
+
+ • Distributed Workflows + – Distribution of workflows on multiple virtual machines. +
+
+
+
+
+
+ • Services + – The ability to offer services for other researchers. +
+
+
+
+
+ +
+
+
+ Want to learn more about Openstack? +
+ +
+
+
+ +
+ +
+ +
+
+ +
+
+ Want to learn more about SimpleVM? +
+ +
+ +
+
+ Want to learn the Difference? +
+ +
+ +
+
+ Want to learn more about Openstack? +
+ +
+
+
+ +
+ +
+ +
+ +
+ +
+} diff --git a/src/app/vo_manager/vo-guard.service.ts b/src/app/vo_manager/vo-guard.service.ts index 51dac09551..32eef8f904 100644 --- a/src/app/vo_manager/vo-guard.service.ts +++ b/src/app/vo_manager/vo-guard.service.ts @@ -1,4 +1,6 @@ /* eslint-disable */ +/* tslint-disable */ + import { Injectable } from '@angular/core' import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router' import { Observable } from 'rxjs'