From 81576e4ceb2fc53e59035c68f6ec318e0692fdc5 Mon Sep 17 00:00:00 2001 From: dweinholz Date: Wed, 19 Apr 2023 14:03:12 +0200 Subject: [PATCH 01/15] mail works --- src/app/api-connector/vo.service.ts | 444 ++++---- .../project-email-modal.component.html | 127 +++ .../project-email-modal.component.ts | 54 + .../projext-email-modal.component.scss | 10 + .../shared_modules/shared-module.module.ts | 61 +- src/app/vo_manager/VoOverviewComponent.ts | 992 +++++++++--------- src/app/vo_manager/voOverview.component.html | 8 + 7 files changed, 974 insertions(+), 722 deletions(-) create mode 100644 src/app/shared/modal/email/project-email-modal/project-email-modal.component.html create mode 100644 src/app/shared/modal/email/project-email-modal/project-email-modal.component.ts create mode 100644 src/app/shared/modal/email/project-email-modal/projext-email-modal.component.scss diff --git a/src/app/api-connector/vo.service.ts b/src/app/api-connector/vo.service.ts index b175667402..dc69559cd8 100644 --- a/src/app/api-connector/vo.service.ts +++ b/src/app/api-connector/vo.service.ts @@ -1,217 +1,241 @@ -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { HttpClient, HttpParams } from '@angular/common/http'; -import { map } from 'rxjs/operators'; -import { ApiSettings } from './api-settings.service'; -import { IResponseTemplate } from './response-template'; -import { Resources } from '../vo_manager/resources/resources'; -import { ProjectMember } from '../projectmanagement/project_member.model'; -import { Application } from '../applications/application.model/application.model'; -import { MaintenanceTimeFrame } from '../vo_manager/maintenance/maintenanceTimeFrame.model'; +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; +import {HttpClient, HttpParams} from '@angular/common/http'; +import {map} from 'rxjs/operators'; +import {ApiSettings} from './api-settings.service'; +import {IResponseTemplate} from './response-template'; +import {Resources} from '../vo_manager/resources/resources'; +import {ProjectMember} from '../projectmanagement/project_member.model'; +import {Application} from '../applications/application.model/application.model'; +import {MaintenanceTimeFrame} from '../vo_manager/maintenance/maintenanceTimeFrame.model'; /** * Service which provides vo methods. */ @Injectable() export class VoService { - constructor(private http: HttpClient) { - this.http = http; - } - - sendTestError(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}voManagers/test_bug/`, { - withCredentials: true, - }); - } - - isVo(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}voManagers/current/status/`, { - withCredentials: true, - }); - } - - getNewsletterSubscriptionCounter(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}newsletter/subscription/counter/`, { - withCredentials: true, - }); - } - - terminateProject(groupId: number | string): Observable { - return this.http.delete(`${ApiSettings.getApiBaseURL()}vo/projects/${groupId}/`, { - withCredentials: true, - }); - } - - removeResourceFromGroup(groupid: number | string): Observable { - return this.http.delete(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/resource/`, { - withCredentials: true, - }); - } - - resumeProject(groupid: number | string): Observable { - return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/resource/`, null, { - withCredentials: true, - }); - } - - getAllGroupsWithDetails(): Observable { - return this.http - .get(`${ApiSettings.getApiBaseURL()}vo/projects/details/`, { - withCredentials: true, - }) - .pipe( - map((applications: Application[]): Application[] => applications.map((application: Application): Application => new Application(application))), - ); - } - - getProjectStatus(groupid: number | string): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/status/`, { - withCredentials: true, - }); - } - - getVoProjectResources(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/resources/`, { - withCredentials: true, - }); - } - - getVoProjectResourcesTimeframes(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/resources/timeFrames/`, { - withCredentials: true, - }); - } - - getVoProjectDates(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/dates/`, { - withCredentials: true, - }); - } - - getVoProjectCounter(): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/counter/`, { - withCredentials: true, - }); - } - - setProjectStatus(groupid: number | string, status: number): Observable { - const params: HttpParams = new HttpParams().set('status', status.toString()); - - return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/status/`, params, { - withCredentials: true, - }); - } - - sendNewsletterToVo( - subject: string, - message: string, - type: string, - adminsOnly: boolean, - reply?: string, - ): Observable { - const params: HttpParams = new HttpParams() - .set('subject', subject) - .set('message', message) - .set('admins_only', adminsOnly) - .set('reply', reply) - .set('type', type); - - return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/current/newsletter/`, params, { - withCredentials: true, - }); - } - - sendMailToVo( - subject: string, - message: string, - facility: string, - type: string, - adminsOnly: boolean, - expiredTemplate: boolean, - removalDate: Date, - reply?: string, - ): Observable { - const params: HttpParams = new HttpParams() - .set('subject', subject) - .set('message', message) - .set('admins_only', adminsOnly) - .set('reply', reply) - .set('facility', facility) - .set('expired_template', expiredTemplate) - .set('removal_date', removalDate.toUTCString()) - .set('type', type); - - return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/current/voMail/`, params, { - withCredentials: true, - }); - } - - /** - * Get members of a project with emails. - * - * @param groupid id of the group - * @returns - */ - getVoGroupRichMembers(groupid: number | string): Observable { - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/members/`, { - withCredentials: true, - }); - } - - setCurrentUserProcessingVoManager(application_id: number | string): Observable { - return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${application_id}/vo_manager/`, null, { - withCredentials: true, - }); - } - - unsetProcessingVoManager(application_id: number | string): Observable { - return this.http.delete(`${ApiSettings.getApiBaseURL()}vo/projects/${application_id}/vo_manager/`, { - withCredentials: true, - }); - } - - setProtected(groupid: number | string, set: boolean): Observable { - const parameters: HttpParams = new HttpParams().set('action', set ? 'set' : 'unset'); - - return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/protected/`, { - withCredentials: true, - params: parameters, - }); - } - - declineTermination(groupid: number | string): Observable { - return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/termination/decline/`, { - withCredentials: true, - }); - } - - loadMaintenanceTimeFrames(): Observable { - return this.http - .get(`${ApiSettings.getApiBaseURL()}voManagers/maintenance/`, { - withCredentials: true, - }) - .pipe( - map((maintenanceTimeFrames: MaintenanceTimeFrame[]): MaintenanceTimeFrame[] => maintenanceTimeFrames.map( - (maintenanceTimeFrame: MaintenanceTimeFrame): MaintenanceTimeFrame => new MaintenanceTimeFrame(maintenanceTimeFrame), - )), - ); - } - - addMaintenanceTimeFrame(timeframe: MaintenanceTimeFrame): Observable { - const params: HttpParams = new HttpParams() - .set('start_time', timeframe.start_time.toJSON()) - .set('end_time', timeframe.end_time.toJSON()) - .set('name', timeframe.name) - .set('message', timeframe.message); - - return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/maintenance/`, params, { - withCredentials: true, - }); - } - - deleteMaintenanceTimeFrame(timeframe: MaintenanceTimeFrame): Observable { - return this.http.delete(`${ApiSettings.getApiBaseURL()}voManagers/maintenance/${timeframe.id}/`, { - withCredentials: true, - }); - } + constructor(private http: HttpClient) { + this.http = http; + } + + sendTestError(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}voManagers/test_bug/`, { + withCredentials: true, + }); + } + + isVo(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}voManagers/current/status/`, { + withCredentials: true, + }); + } + + getNewsletterSubscriptionCounter(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}newsletter/subscription/counter/`, { + withCredentials: true, + }); + } + + terminateProject(groupId: number | string): Observable { + return this.http.delete(`${ApiSettings.getApiBaseURL()}vo/projects/${groupId}/`, { + withCredentials: true, + }); + } + + removeResourceFromGroup(groupid: number | string): Observable { + return this.http.delete(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/resource/`, { + withCredentials: true, + }); + } + + resumeProject(groupid: number | string): Observable { + return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/resource/`, null, { + withCredentials: true, + }); + } + + getAllGroupsWithDetails(): Observable { + return this.http + .get(`${ApiSettings.getApiBaseURL()}vo/projects/details/`, { + withCredentials: true, + }) + .pipe( + map((applications: Application[]): Application[] => applications.map((application: Application): Application => new Application(application))), + ); + } + + getProjectStatus(groupid: number | string): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/status/`, { + withCredentials: true, + }); + } + + getVoProjectResources(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/resources/`, { + withCredentials: true, + }); + } + + getVoProjectResourcesTimeframes(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/resources/timeFrames/`, { + withCredentials: true, + }); + } + + getVoProjectDates(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/dates/`, { + withCredentials: true, + }); + } + + getVoProjectCounter(): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/counter/`, { + withCredentials: true, + }); + } + + setProjectStatus(groupid: number | string, status: number): Observable { + const params: HttpParams = new HttpParams().set('status', status.toString()); + + return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/status/`, params, { + withCredentials: true, + }); + } + + sendNewsletterToVo( + subject: string, + message: string, + type: string, + adminsOnly: boolean, + reply?: string, + ): Observable { + const params: HttpParams = new HttpParams() + .set('subject', subject) + .set('message', message) + .set('admins_only', adminsOnly) + .set('reply', reply) + .set('type', type); + + return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/current/newsletter/`, params, { + withCredentials: true, + }); + } + + sendMailToVo( + subject: string, + message: string, + facility: string, + type: string, + adminsOnly: boolean, + expiredTemplate: boolean, + removalDate: Date, + reply?: string, + ): Observable { + const params: HttpParams = new HttpParams() + .set('subject', subject) + .set('message', message) + .set('admins_only', adminsOnly) + .set('reply', reply) + .set('facility', facility) + .set('expired_template', expiredTemplate) + .set('removal_date', removalDate.toUTCString()) + .set('type', type); + + return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/current/voMail/`, params, { + withCredentials: true, + }); + } + + sendMailToProjects( + projectIds: (string | number)[], + subject: string, + message: string, + adminsOnly: boolean, + reply?: string, + ): Observable { + + + return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/current/voMail/projects/`, + {project_ids: projectIds, subject: subject, message: message, adminsOnly: adminsOnly, reply: reply}, { + withCredentials: true, + }); + } + + + getMailTemplates(): Observable { + + + return this.http.get(`${ApiSettings.getApiBaseURL()}voManagers/current/voMail/projects/templates/`, { + withCredentials: true, + }); + } + + /** + * Get members of a project with emails. + * + * @param groupid id of the group + * @returns + */ + getVoGroupRichMembers(groupid: number | string): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/members/`, { + withCredentials: true, + }); + } + + setCurrentUserProcessingVoManager(application_id: number | string): Observable { + return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${application_id}/vo_manager/`, null, { + withCredentials: true, + }); + } + + unsetProcessingVoManager(application_id: number | string): Observable { + return this.http.delete(`${ApiSettings.getApiBaseURL()}vo/projects/${application_id}/vo_manager/`, { + withCredentials: true, + }); + } + + setProtected(groupid: number | string, set: boolean): Observable { + const parameters: HttpParams = new HttpParams().set('action', set ? 'set' : 'unset'); + + return this.http.get(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/protected/`, { + withCredentials: true, + params: parameters, + }); + } + + declineTermination(groupid: number | string): Observable { + return this.http.post(`${ApiSettings.getApiBaseURL()}vo/projects/${groupid}/termination/decline/`, { + withCredentials: true, + }); + } + + loadMaintenanceTimeFrames(): Observable { + return this.http + .get(`${ApiSettings.getApiBaseURL()}voManagers/maintenance/`, { + withCredentials: true, + }) + .pipe( + map((maintenanceTimeFrames: MaintenanceTimeFrame[]): MaintenanceTimeFrame[] => maintenanceTimeFrames.map( + (maintenanceTimeFrame: MaintenanceTimeFrame): MaintenanceTimeFrame => new MaintenanceTimeFrame(maintenanceTimeFrame), + )), + ); + } + + addMaintenanceTimeFrame(timeframe: MaintenanceTimeFrame): Observable { + const params: HttpParams = new HttpParams() + .set('start_time', timeframe.start_time.toJSON()) + .set('end_time', timeframe.end_time.toJSON()) + .set('name', timeframe.name) + .set('message', timeframe.message); + + return this.http.post(`${ApiSettings.getApiBaseURL()}voManagers/maintenance/`, params, { + withCredentials: true, + }); + } + + deleteMaintenanceTimeFrame(timeframe: MaintenanceTimeFrame): Observable { + return this.http.delete(`${ApiSettings.getApiBaseURL()}voManagers/maintenance/${timeframe.id}/`, { + withCredentials: true, + }); + } } diff --git a/src/app/shared/modal/email/project-email-modal/project-email-modal.component.html b/src/app/shared/modal/email/project-email-modal/project-email-modal.component.html new file mode 100644 index 0000000000..cea130c303 --- /dev/null +++ b/src/app/shared/modal/email/project-email-modal/project-email-modal.component.html @@ -0,0 +1,127 @@ + + + diff --git a/src/app/shared/modal/email/project-email-modal/project-email-modal.component.ts b/src/app/shared/modal/email/project-email-modal/project-email-modal.component.ts new file mode 100644 index 0000000000..e810f9c2a6 --- /dev/null +++ b/src/app/shared/modal/email/project-email-modal/project-email-modal.component.ts @@ -0,0 +1,54 @@ +import {Component, EventEmitter, Input, OnInit} from '@angular/core'; +import {Application} from '../../../../applications/application.model/application.model'; +import {BsModalRef} from 'ngx-bootstrap/modal'; +import {VoService} from '../../../../api-connector/vo.service'; +import {IResponseTemplate} from '../../../../api-connector/response-template'; + +@Component({ + selector: 'app-project-email-modal', + templateUrl: './project-email-modal.component.html', + styleUrls: ['./projext-email-modal.component.scss'], + +}) +export class ProjectEmailModalComponent implements OnInit { + + //currently only for vo + @Input() selectedProjects: Application[]; + emailAdminsOnly: boolean; + emailSubject: string; + emailReply: string; + emailText: string; + templates: string[]; + + public mailSuccesfullySent: EventEmitter = new EventEmitter(); + + constructor(public bsModalRef: BsModalRef, private voService: VoService) { + // eslint-disable-next-line no-empty-function + } + + ngOnInit() { + this.getMailTemplates() + } + + getMailTemplates(): void { + this.voService.getMailTemplates().subscribe((res: string[]) => { + this.templates = res + }) + } + + sentProjectsMail(): void { + const project_ids = this.selectedProjects.map((pr: Application) => { + return pr.project_application_perun_id; + }); + + this.voService.sendMailToProjects(project_ids, this.emailSubject, this.emailText, this.emailAdminsOnly, this.emailReply).subscribe((res: IResponseTemplate) => { + this.mailSuccesfullySent.emit(res.value as boolean) + }, () => { + this.mailSuccesfullySent.emit(false) + }) + } + + ngOnDestroy(): void { + this.bsModalRef.hide(); + } +} diff --git a/src/app/shared/modal/email/project-email-modal/projext-email-modal.component.scss b/src/app/shared/modal/email/project-email-modal/projext-email-modal.component.scss new file mode 100644 index 0000000000..6e91f2f7da --- /dev/null +++ b/src/app/shared/modal/email/project-email-modal/projext-email-modal.component.scss @@ -0,0 +1,10 @@ +.templates-container { + border: 1px solid #ccc; + padding: 10px; + background-color: #f9f9f9; +} + +.templates-list { + margin: 10px 0; + font-family: monospace; +} diff --git a/src/app/shared/shared_modules/shared-module.module.ts b/src/app/shared/shared_modules/shared-module.module.ts index 065edc176a..21aacbc5e6 100644 --- a/src/app/shared/shared_modules/shared-module.module.ts +++ b/src/app/shared/shared_modules/shared-module.module.ts @@ -1,34 +1,39 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { ModalModule } from 'ngx-bootstrap/modal'; -import { ProgressModule, ToastModule } from '@coreui/angular'; -import { ApplicationBaseClassComponent } from './baseClass/application-base-class.component'; -import { NotificationModalComponent } from '../modal/notification-modal'; -import { InformationToastComponent } from '../toaster/information-toast.component'; -import { ConfirmationModalComponent } from '../modal/confirmation-modal.component'; -import { MigrationInformationComponent } from './migration-information/migration-information.component'; -import { ApplicationBadgesComponent } from './components/applications/application-badges/application-badges.component'; +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {ModalModule} from 'ngx-bootstrap/modal'; +import {ProgressModule, ToastModule} from '@coreui/angular'; +import {ApplicationBaseClassComponent} from './baseClass/application-base-class.component'; +import {NotificationModalComponent} from '../modal/notification-modal'; +import {InformationToastComponent} from '../toaster/information-toast.component'; +import {ConfirmationModalComponent} from '../modal/confirmation-modal.component'; +import {MigrationInformationComponent} from './migration-information/migration-information.component'; +import {ApplicationBadgesComponent} from './components/applications/application-badges/application-badges.component'; +import {ProjectEmailModalComponent} from '../modal/email/project-email-modal/project-email-modal.component'; +import {FormsModule} from '@angular/forms'; /** * Shared module. */ @NgModule({ - exports: [ - ApplicationBaseClassComponent, - NotificationModalComponent, - ConfirmationModalComponent, - InformationToastComponent, - MigrationInformationComponent, - ApplicationBadgesComponent, - ], - imports: [CommonModule, ModalModule.forRoot(), ToastModule, ProgressModule], - declarations: [ - ApplicationBaseClassComponent, - NotificationModalComponent, - ConfirmationModalComponent, - InformationToastComponent, - MigrationInformationComponent, - ApplicationBadgesComponent, - ], + exports: [ + ApplicationBaseClassComponent, + NotificationModalComponent, + ConfirmationModalComponent, + InformationToastComponent, + MigrationInformationComponent, + ApplicationBadgesComponent, + ProjectEmailModalComponent + ], + imports: [CommonModule, ModalModule.forRoot(), ToastModule, ProgressModule, FormsModule], + declarations: [ + ApplicationBaseClassComponent, + NotificationModalComponent, + ConfirmationModalComponent, + InformationToastComponent, + MigrationInformationComponent, + ApplicationBadgesComponent, + ProjectEmailModalComponent + ], }) -export class SharedModuleModule {} +export class SharedModuleModule { +} diff --git a/src/app/vo_manager/VoOverviewComponent.ts b/src/app/vo_manager/VoOverviewComponent.ts index 407ea8f21f..472e7824cf 100644 --- a/src/app/vo_manager/VoOverviewComponent.ts +++ b/src/app/vo_manager/VoOverviewComponent.ts @@ -1,515 +1,539 @@ -import { ngxCsv } from 'ngx-csv/ngx-csv'; +import {ngxCsv} from 'ngx-csv/ngx-csv'; import { - Component, OnInit, QueryList, ViewChildren, + Component, OnInit, QueryList, ViewChildren, } from '@angular/core'; -import { DomSanitizer } from '@angular/platform-browser'; -import { Observable } from 'rxjs'; -import { VoService } from '../api-connector/vo.service'; -import { ProjectMember } from '../projectmanagement/project_member.model'; -import { GroupService } from '../api-connector/group.service'; -import { ComputecenterComponent } from '../projectmanagement/computecenter.component'; -import { IResponseTemplate } from '../api-connector/response-template'; -import { FacilityService } from '../api-connector/facility.service'; -import { FullLayoutComponent } from '../layouts/full-layout.component'; -import { Application } from '../applications/application.model/application.model'; -import { AbstractBaseClass, Application_States } from '../shared/shared_modules/baseClass/abstract-base-class'; +import {DomSanitizer} from '@angular/platform-browser'; +import {Observable} from 'rxjs'; +import {VoService} from '../api-connector/vo.service'; +import {ProjectMember} from '../projectmanagement/project_member.model'; +import {GroupService} from '../api-connector/group.service'; +import {ComputecenterComponent} from '../projectmanagement/computecenter.component'; +import {IResponseTemplate} from '../api-connector/response-template'; +import {FacilityService} from '../api-connector/facility.service'; +import {FullLayoutComponent} from '../layouts/full-layout.component'; +import {Application} from '../applications/application.model/application.model'; +import {AbstractBaseClass, Application_States} from '../shared/shared_modules/baseClass/abstract-base-class'; import { - NgbdSortableHeaderDirective, - SortEvent, + NgbdSortableHeaderDirective, + SortEvent, } from '../shared/shared_modules/directives/nbd-sortable-header.directive'; -import { ProjectSortService } from '../shared/shared_modules/services/project-sort.service'; +import {ProjectSortService} from '../shared/shared_modules/services/project-sort.service'; +import {StopVmComponent} from '../virtualmachines/modals/stop-vm/stop-vm.component'; +import {BsModalRef, BsModalService} from 'ngx-bootstrap/modal'; +import {ProjectEmailModalComponent} from '../shared/modal/email/project-email-modal/project-email-modal.component'; /** * Vo Overview component. */ @Component({ - selector: 'app-vo-overview', - templateUrl: 'voOverview.component.html', - providers: [VoService, GroupService, FacilityService, ProjectSortService], + selector: 'app-vo-overview', + templateUrl: 'voOverview.component.html', + providers: [VoService, GroupService, FacilityService, ProjectSortService], }) export class VoOverviewComponent extends AbstractBaseClass implements OnInit { - title: string = 'VO Overview'; - public emailSubject: string; - public emailReply: string = ''; - public emailText: string; - public emailStatus: number = 0; - - public emailHeader: string; - public emailVerify: string; - public emailType: number; - public emailAdminsOnly: boolean = false; - public expiredTemplated: boolean = false; - - public removalDate: Date = new Date(); - public selectedProject: Application; - computecenters: ComputecenterComponent[] = []; - - show_openstack_projects: boolean = true; - show_simple_vm_projects: boolean = true; - show_simple_vm: boolean = true; - show_openstack: boolean = true; - - selectedProjectType: string = 'ALL'; - selectedFacility: string | number = 'ALL'; - - public newsletterSubscriptionCounter: number; - isLoaded: boolean = false; - member_id: number; - projects: Application[] = []; - projects_filtered: Application[] = []; - - // modal variables for User list - public usersModalProjectMembers: ProjectMember[] = []; - public usersModalProjectID: number; - public usersModalProjectName: string; - public managerFacilities: [string, number][]; - @ViewChildren(NgbdSortableHeaderDirective) headers: QueryList; - - applictions$: Observable; - total$: Observable; - - // public selectedFacility: [string, number]; - - constructor( - private fullLayout: FullLayoutComponent, - private sanitizer: DomSanitizer, - private voService: VoService, - private groupservice: GroupService, - private facilityService: FacilityService, - public sortProjectService: ProjectSortService, - ) { - super(); - } - - ngOnInit(): void { - this.getVoProjects(); - this.getComputeCenters(); - this.voService.getNewsletterSubscriptionCounter().subscribe((result: IResponseTemplate): void => { - this.newsletterSubscriptionCounter = result.value as number; - }); - } - - onSort({ column, direction }: SortEvent) { - // resetting other headers - this.headers.forEach(header => { - if (header.appSortable !== column) { - header.direction = ''; - } - }); - - this.sortProjectService.sortColumn = column; - this.sortProjectService.sortDirection = direction; - } - - switchShowSimpleVmProjects(): void { - this.show_simple_vm_projects = !this.show_simple_vm_projects; - } - - switchOpenStackVmProjects(): void { - this.show_openstack_projects = !this.show_openstack_projects; - } - - getApplicationInfos(): void { - this.voService.getVoProjectResourcesTimeframes().subscribe(); - - this.voService.getVoProjectCounter().subscribe(); - this.voService.getVoProjectDates().subscribe(); - } - - sendEmail(subject: string, message: string, reply?: string): void { - if (reply) { - reply = reply.trim(); + title: string = 'VO Overview'; + public emailSubject: string; + public emailReply: string = ''; + public emailText: string; + public emailStatus: number = 0; + + public emailHeader: string; + public emailVerify: string; + public emailType: number; + public emailAdminsOnly: boolean = false; + public expiredTemplated: boolean = false; + + public removalDate: Date = new Date(); + public selectedProject: Application; + computecenters: ComputecenterComponent[] = []; + bsModalRef: BsModalRef; + + + show_openstack_projects: boolean = true; + show_simple_vm_projects: boolean = true; + show_simple_vm: boolean = true; + show_openstack: boolean = true; + + selectedProjectType: string = 'ALL'; + selectedFacility: string | number = 'ALL'; + + public newsletterSubscriptionCounter: number; + isLoaded: boolean = false; + member_id: number; + projects: Application[] = []; + projects_filtered: Application[] = []; + + // modal variables for User list + public usersModalProjectMembers: ProjectMember[] = []; + public usersModalProjectID: number; + public usersModalProjectName: string; + public managerFacilities: [string, number][]; + + projectMailTemplates: string[] = [] + @ViewChildren(NgbdSortableHeaderDirective) headers: QueryList; + + applictions$: Observable; + total$: Observable; + + // public selectedFacility: [string, number]; + + constructor( + private fullLayout: FullLayoutComponent, + private sanitizer: DomSanitizer, + private voService: VoService, + private groupservice: GroupService, + private facilityService: FacilityService, + public sortProjectService: ProjectSortService, + private modalService: BsModalService, + ) { + super(); } - switch (this.emailType) { - case 0: { - this.sendMailToVo( - subject, - message, - this.selectedFacility.toString(), - this.selectedProjectType, - this.emailAdminsOnly, - this.expiredTemplated, - this.removalDate, - reply, - ); - break; - } - case 1: { - this.sendNewsletterToVo(subject, message, this.selectedProjectType, this.emailAdminsOnly, reply); - break; - } - default: + + ngOnInit(): void { + this.getVoProjects(); + this.getMailTemplates() + this.getComputeCenters(); + this.voService.getNewsletterSubscriptionCounter().subscribe((result: IResponseTemplate): void => { + this.newsletterSubscriptionCounter = result.value as number; + }); } - } - - sendTestBug(): void { - this.voService.sendTestError().subscribe(); - } - - sendNewsletterToVo( - subject: string, - message: string, - selectedProjectType: string, - adminsOnly: boolean, - reply?: string, - ): void { - this.voService - .sendNewsletterToVo( - encodeURIComponent(subject), - encodeURIComponent(message), - selectedProjectType, - adminsOnly, - encodeURIComponent(reply), - ) - .subscribe((result: IResponseTemplate): void => { - if ((result.value as boolean) === true) { - this.emailStatus = 1; - } else { - this.emailStatus = 2; + + + openProjectMailsModal(): void { + const initialState = {selectedProjects: this.projects}; + + this.bsModalRef = this.modalService.show(ProjectEmailModalComponent, {initialState}); + this.bsModalRef.setClass('modal-lg'); + } + + getMailTemplates(): void { + this.voService.getMailTemplates().subscribe((res: string[]) => { + this.projectMailTemplates = res + console.log(this.projectMailTemplates) + }) + } + + onSort({column, direction}: SortEvent) { + // resetting other headers + this.headers.forEach(header => { + if (header.appSortable !== column) { + header.direction = ''; + } + }); + + this.sortProjectService.sortColumn = column; + this.sortProjectService.sortDirection = direction; + } + + switchShowSimpleVmProjects(): void { + this.show_simple_vm_projects = !this.show_simple_vm_projects; + } + + switchOpenStackVmProjects(): void { + this.show_openstack_projects = !this.show_openstack_projects; + } + + getApplicationInfos(): void { + this.voService.getVoProjectResourcesTimeframes().subscribe(); + + this.voService.getVoProjectCounter().subscribe(); + this.voService.getVoProjectDates().subscribe(); + } + + sendEmail(subject: string, message: string, reply?: string): void { + if (reply) { + reply = reply.trim(); } - }); - } - - sendMailToVo( - subject: string, - message: string, - facility: string, - type: string, - adminsOnly: boolean, - expiredTemplate: boolean, - removalDate: Date, - reply?: string, - ): void { - this.voService - .sendMailToVo( - encodeURIComponent(subject), - encodeURIComponent(message), - facility, - type, - adminsOnly, - expiredTemplate, - removalDate, - encodeURIComponent(reply), - ) - .subscribe((result: IResponseTemplate): void => { - if ((result.value as boolean) === true) { - this.emailStatus = 1; - } else { - this.emailStatus = 2; + switch (this.emailType) { + case 0: { + this.sendMailToVo( + subject, + message, + this.selectedFacility.toString(), + this.selectedProjectType, + this.emailAdminsOnly, + this.expiredTemplated, + this.removalDate, + reply, + ); + break; + } + case 1: { + this.sendNewsletterToVo(subject, message, this.selectedProjectType, this.emailAdminsOnly, reply); + break; + } + default: } - this.selectedProjectType = 'ALL'; - this.selectedFacility = 'ALL'; - }); - } - - dayChanged(date: { year: number; month: number; day: number }): void { - this.removalDate.setDate(date.day); - this.removalDate.setMonth(date.month - 1); - this.removalDate.setFullYear(date.year); - } - - setEmailType(type: number): void { - this.emailType = type; - switch (this.emailType) { - case 0: { - this.emailHeader = 'Send email to selected members of the VO'; - break; - } - case 1: { - this.emailHeader = 'Send newsletter to VO'; - break; - } - default: } - this.emailVerify = 'Are you sure you want to send this newsletter to all members of the de.NBI VO?'; - } - - getFacilityName(): string { - if (this.selectedFacility === 'ALL') { - return 'of the de.NBI VO'; - } else { - const temp_cc = this.computecenters.find(cc => cc.FacilityId === this.selectedFacility); - if (temp_cc === undefined) { - return 'of the de.NBI VO'; - } else { - return `of the facility "${temp_cc.Name}"`; - } + + sendTestBug(): void { + this.voService.sendTestError().subscribe(); } - } - - getMailConfinementByProjectType(): string { - switch (this.selectedProjectType) { - case 'ALL_GM': - return 'of all active projects'; - case 'EXP': - return 'of all expired projects'; - case 'SVP': - return 'of all SimpleVM projects'; - case 'OVP': - return 'of all OpenStack projects'; - case 'WSH': - return 'of all Workshops'; - default: - return ''; + + sendNewsletterToVo( + subject: string, + message: string, + selectedProjectType: string, + adminsOnly: boolean, + reply?: string, + ): void { + this.voService + .sendNewsletterToVo( + encodeURIComponent(subject), + encodeURIComponent(message), + selectedProjectType, + adminsOnly, + encodeURIComponent(reply), + ) + .subscribe((result: IResponseTemplate): void => { + if ((result.value as boolean) === true) { + this.emailStatus = 1; + } else { + this.emailStatus = 2; + } + }); } - } - - adjustVerifyText(): void { - switch (this.emailType) { - case 0: { - this.emailVerify = `Are you sure you want to send this email to all ${ - this.emailAdminsOnly ? ' group administrators' : 'members' - } ${this.getMailConfinementByProjectType()} ${this.getFacilityName()} ?`; - break; - } - case 1: { - this.emailVerify = `Are you sure you want to send this newsletter to all members ${this.getMailConfinementByProjectType()} ${this.getFacilityName()} ?`; - break; - } - default: - this.emailVerify = 'Are you sure you want to send this?'; + + sendMailToVo( + subject: string, + message: string, + facility: string, + type: string, + adminsOnly: boolean, + expiredTemplate: boolean, + removalDate: Date, + reply?: string, + ): void { + this.voService + .sendMailToVo( + encodeURIComponent(subject), + encodeURIComponent(message), + facility, + type, + adminsOnly, + expiredTemplate, + removalDate, + encodeURIComponent(reply), + ) + .subscribe((result: IResponseTemplate): void => { + if ((result.value as boolean) === true) { + this.emailStatus = 1; + } else { + this.emailStatus = 2; + } + this.selectedProjectType = 'ALL'; + this.selectedFacility = 'ALL'; + }); } - if (this.selectedProjectType !== 'EXP') { - this.expiredTemplated = false; + + dayChanged(date: { year: number; month: number; day: number }): void { + this.removalDate.setDate(date.day); + this.removalDate.setMonth(date.month - 1); + this.removalDate.setFullYear(date.year); } - } - - getVoProjects(): void { - this.projects = []; - this.voService.getAllGroupsWithDetails().subscribe((applications: Application[]): void => { - for (const application of applications) { - if (application.project_application_lifetime > 0) { - application.lifetime_reached = this.lifeTimeReached(application.lifetime_days, application.DaysRunning); + + setEmailType(type: number): void { + this.emailType = type; + switch (this.emailType) { + case 0: { + this.emailHeader = 'Send email to selected members of the VO'; + break; + } + case 1: { + this.emailHeader = 'Send newsletter to VO'; + break; + } + default: } - this.projects.push(application); - } - this.sortProjectService.applications = this.projects; - this.applictions$ = this.sortProjectService.applications$; - this.total$ = this.sortProjectService.total$; - - this.isLoaded = true; - }); - } - - resetEmailModal(): void { - this.emailHeader = null; - this.emailSubject = null; - this.emailText = null; - this.emailType = null; - this.emailVerify = null; - this.emailReply = ''; - this.emailStatus = 0; - this.emailAdminsOnly = false; - } - - public resetNotificationModal(): void { - this.notificationModalTitle = 'Notification'; - this.notificationModalMessage = 'Please wait...'; - this.notificationModalIsClosable = false; - this.notificationModalType = 'info'; - } - - /** - * Get all computecenters. - */ - getComputeCenters(): void { - this.facilityService.getComputeCenters().subscribe((result: any): void => { - for (const cc of result) { - const compute_center: ComputecenterComponent = new ComputecenterComponent( - cc['compute_center_facility_id'], - cc['compute_center_name'], - cc['compute_center_login'], - cc['compute_center_support_mail'], - ); - this.computecenters.push(compute_center); - } - }); - } - - /** - * Bugfix not scrollable site after closing modal - */ - removeModalOpen(): void { - document.body.classList.remove('modal-open'); - } - - public terminateProject(): void { - this.voService.terminateProject(this.selectedProject.project_application_perun_id).subscribe( - (): void => { - const indexAll: number = this.projects.indexOf(this.selectedProject, 0); - if (!this.selectedProject.project_application_openstack_project) { - this.projects.splice(indexAll, 1); - this.sortProjectService.applications = this.projects; + this.emailVerify = 'Are you sure you want to send this newsletter to all members of the de.NBI VO?'; + } + + getFacilityName(): string { + if (this.selectedFacility === 'ALL') { + return 'of the de.NBI VO'; } else { - this.getProjectStatus(this.projects[indexAll]); + const temp_cc = this.computecenters.find(cc => cc.FacilityId === this.selectedFacility); + if (temp_cc === undefined) { + return 'of the de.NBI VO'; + } else { + return `of the facility "${temp_cc.Name}"`; + } } - this.fullLayout.getGroupsEnumeration(); - if (this.selectedProject.project_application_openstack_project) { - this.updateNotificationModal( - 'Success', - 'The request to terminate the project was forwarded to the facility manager.', - true, - 'success', - ); - } else { - this.updateNotificationModal('Success', 'The project was terminated.', true, 'success'); + } + + getMailConfinementByProjectType(): string { + switch (this.selectedProjectType) { + case 'ALL_GM': + return 'of all active projects'; + case 'EXP': + return 'of all expired projects'; + case 'SVP': + return 'of all SimpleVM projects'; + case 'OVP': + return 'of all OpenStack projects'; + case 'WSH': + return 'of all Workshops'; + default: + return ''; } - }, - (error: any): void => { - if (error['status'] === 409) { - this.updateNotificationModal( - 'Failed', - `The project could not be terminated. Reason: ${error['error']['reason']} for ${error['error']['openstackid']}`, - true, - 'danger', - ); - } else { - this.updateNotificationModal('Failed', 'The project could not be terminated.', true, 'danger'); + } + + adjustVerifyText(): void { + switch (this.emailType) { + case 0: { + this.emailVerify = `Are you sure you want to send this email to all ${ + this.emailAdminsOnly ? ' group administrators' : 'members' + } ${this.getMailConfinementByProjectType()} ${this.getFacilityName()} ?`; + break; + } + case 1: { + this.emailVerify = `Are you sure you want to send this newsletter to all members ${this.getMailConfinementByProjectType()} ${this.getFacilityName()} ?`; + break; + } + default: + this.emailVerify = 'Are you sure you want to send this?'; } - }, - ); - } - - getProjectStatus(project: Application): void { - this.voService.getProjectStatus(project.project_application_perun_id).subscribe((res: any): void => { - project.project_application_statuses = res['status']; - }); - } - - suspendProject(project: Application): void { - this.voService.removeResourceFromGroup(project.project_application_perun_id).subscribe((): void => { - this.getProjectStatus(project); - project.project_application_compute_center = null; - }); - } - - resumeProject(project: Application): void { - this.voService.resumeProject(project.project_application_perun_id).subscribe((): void => { - this.getVoProjects(); - }); - } - - declineTermination(project: Application): void { - this.voService.declineTermination(project.project_application_perun_id).subscribe( - (): void => { - this.updateNotificationModal('Success', 'The termination was successfully declined', true, 'success'); - const indexAll: number = this.projects.indexOf(project, 0); - this.getProjectStatus(this.projects[indexAll]); - }, - (): void => { - this.updateNotificationModal('Failed', 'The status change was not successful.', true, 'danger'); - }, - ); - } - - setProtected(project: Application, set: boolean): void { - this.voService.setProtected(project.project_application_perun_id, set).subscribe( - (result: any): void => { - this.updateNotificationModal( - 'Success', - result['result'] === 'set' - ? 'The project was successfully set as protected.' - : 'The status "Protected" was removed successfully', - true, - 'success', - ); - const indexAll: number = this.projects.indexOf(project, 0); - this.getProjectStatus(this.projects[indexAll]); - }, - (error: any): void => { - if (error['status'] === 500) { - this.updateNotificationModal('Failed', 'The status change was not successful.', true, 'danger'); + if (this.selectedProjectType !== 'EXP') { + this.expiredTemplated = false; } - }, - ); - } - - getMembersOfTheProject(projectid: number, projectname: string): void { - this.voService.getVoGroupRichMembers(projectid).subscribe((members: ProjectMember[]): void => { - this.usersModalProjectID = projectid; - this.usersModalProjectName = projectname; - this.usersModalProjectMembers = members; - }); - } - - showMembersOfTheProject(projectid: number, projectname: string): void { - this.getMembersOfTheProject(projectid, projectname); - } - - exportTSV(): void { - const data = []; - this.sortProjectService.sorted_applications.forEach(application => { - const entry = {}; - for (const key in application) { - if (typeof application[key] === 'object') { - if (key === 'project_application_pi') { - entry['project_application_pi_name'] = application[key].username; - entry['project_application_pi_email'] = application[key].email; - entry['project_application_pi_affiliations'] = JSON.stringify(application[key].user_affiliations); - } else if (key === 'project_application_statuses') { - const statuses_strings = []; - application[key].forEach(status => { - statuses_strings.push(Application_States[status]); - }); - entry[key] = JSON.stringify(statuses_strings); - } else if (key === 'project_credit_request') { - if (application[key] == null) { - entry['project_credit_requested'] = 'FALSE'; - entry['project_credit_request_id'] = 'NONE'; - entry['project_credit_request_comment'] = 'NONE'; - entry['project_credit_request_date_submitted'] = 'NONE'; - entry['project_credit_request_extra_credits'] = 'NONE'; - entry['project_credit_request_user_name'] = 'NONE'; - entry['project_credit_request_user_email'] = 'NONE'; - } else { - entry['project_credit_requested'] = 'TRUE'; - entry['project_credit_request_id'] = JSON.stringify(application[key].Id); - entry['project_credit_request_comment'] = application[key].comment; - entry['project_credit_request_date_submitted'] = JSON.stringify(application[key].date_submitted); - entry['project_credit_request_extra_credits'] = JSON.stringify(application[key].extra_credits); - entry['project_credit_request_user_name'] = JSON.stringify(application[key].user.username); - entry['project_credit_request_user_email'] = JSON.stringify(application[key].user.email); + } + + getVoProjects(): void { + this.projects = []; + this.voService.getAllGroupsWithDetails().subscribe((applications: Application[]): void => { + for (const application of applications) { + if (application.project_application_lifetime > 0) { + application.lifetime_reached = this.lifeTimeReached(application.lifetime_days, application.DaysRunning); + } + this.projects.push(application); } - } else if (key === 'project_application_edam_terms') { - const edam_names = []; - application[key].forEach(edam => { - edam_names.push(edam.name); - }); - entry['project_application_edam_terms'] = JSON.stringify(edam_names); - } else if (key === 'flavors') { - const flavor_names = []; - application[key].forEach(flavor => { - flavor_names.push(flavor.name); + this.sortProjectService.applications = this.projects; + this.applictions$ = this.sortProjectService.applications$; + this.total$ = this.sortProjectService.total$; + + this.isLoaded = true; + }); + } + + resetEmailModal(): void { + this.emailHeader = null; + this.emailSubject = null; + this.emailText = null; + this.emailType = null; + this.emailVerify = null; + this.emailReply = ''; + this.emailStatus = 0; + this.emailAdminsOnly = false; + } + + public resetNotificationModal(): void { + this.notificationModalTitle = 'Notification'; + this.notificationModalMessage = 'Please wait...'; + this.notificationModalIsClosable = false; + this.notificationModalType = 'info'; + } + + /** + * Get all computecenters. + */ + getComputeCenters(): void { + this.facilityService.getComputeCenters().subscribe((result: any): void => { + for (const cc of result) { + const compute_center: ComputecenterComponent = new ComputecenterComponent( + cc['compute_center_facility_id'], + cc['compute_center_name'], + cc['compute_center_login'], + cc['compute_center_support_mail'], + ); + this.computecenters.push(compute_center); + } + }); + } + + /** + * Bugfix not scrollable site after closing modal + */ + removeModalOpen(): void { + document.body.classList.remove('modal-open'); + } + + public terminateProject(): void { + this.voService.terminateProject(this.selectedProject.project_application_perun_id).subscribe( + (): void => { + const indexAll: number = this.projects.indexOf(this.selectedProject, 0); + if (!this.selectedProject.project_application_openstack_project) { + this.projects.splice(indexAll, 1); + this.sortProjectService.applications = this.projects; + } else { + this.getProjectStatus(this.projects[indexAll]); + } + this.fullLayout.getGroupsEnumeration(); + if (this.selectedProject.project_application_openstack_project) { + this.updateNotificationModal( + 'Success', + 'The request to terminate the project was forwarded to the facility manager.', + true, + 'success', + ); + } else { + this.updateNotificationModal('Success', 'The project was terminated.', true, 'success'); + } + }, + (error: any): void => { + if (error['status'] === 409) { + this.updateNotificationModal( + 'Failed', + `The project could not be terminated. Reason: ${error['error']['reason']} for ${error['error']['openstackid']}`, + true, + 'danger', + ); + } else { + this.updateNotificationModal('Failed', 'The project could not be terminated.', true, 'danger'); + } + }, + ); + } + + getProjectStatus(project: Application): void { + this.voService.getProjectStatus(project.project_application_perun_id).subscribe((res: any): void => { + project.project_application_statuses = res['status']; + }); + } + + suspendProject(project: Application): void { + this.voService.removeResourceFromGroup(project.project_application_perun_id).subscribe((): void => { + this.getProjectStatus(project); + project.project_application_compute_center = null; + }); + } + + resumeProject(project: Application): void { + this.voService.resumeProject(project.project_application_perun_id).subscribe((): void => { + this.getVoProjects(); + }); + } + + declineTermination(project: Application): void { + this.voService.declineTermination(project.project_application_perun_id).subscribe( + (): void => { + this.updateNotificationModal('Success', 'The termination was successfully declined', true, 'success'); + const indexAll: number = this.projects.indexOf(project, 0); + this.getProjectStatus(this.projects[indexAll]); + }, + (): void => { + this.updateNotificationModal('Failed', 'The status change was not successful.', true, 'danger'); + }, + ); + } + + setProtected(project: Application, set: boolean): void { + this.voService.setProtected(project.project_application_perun_id, set).subscribe( + (result: any): void => { + this.updateNotificationModal( + 'Success', + result['result'] === 'set' + ? 'The project was successfully set as protected.' + : 'The status "Protected" was removed successfully', + true, + 'success', + ); + const indexAll: number = this.projects.indexOf(project, 0); + this.getProjectStatus(this.projects[indexAll]); + }, + (error: any): void => { + if (error['status'] === 500) { + this.updateNotificationModal('Failed', 'The status change was not successful.', true, 'danger'); + } + }, + ); + } + + getMembersOfTheProject(projectid: number, projectname: string): void { + this.voService.getVoGroupRichMembers(projectid).subscribe((members: ProjectMember[]): void => { + this.usersModalProjectID = projectid; + this.usersModalProjectName = projectname; + this.usersModalProjectMembers = members; + }); + } + + showMembersOfTheProject(projectid: number, projectname: string): void { + this.getMembersOfTheProject(projectid, projectname); + } + + exportTSV(): void { + const data = []; + this.sortProjectService.sorted_applications.forEach(application => { + const entry = {}; + for (const key in application) { + if (typeof application[key] === 'object') { + if (key === 'project_application_pi') { + entry['project_application_pi_name'] = application[key].username; + entry['project_application_pi_email'] = application[key].email; + entry['project_application_pi_affiliations'] = JSON.stringify(application[key].user_affiliations); + } else if (key === 'project_application_statuses') { + const statuses_strings = []; + application[key].forEach(status => { + statuses_strings.push(Application_States[status]); + }); + entry[key] = JSON.stringify(statuses_strings); + } else if (key === 'project_credit_request') { + if (application[key] == null) { + entry['project_credit_requested'] = 'FALSE'; + entry['project_credit_request_id'] = 'NONE'; + entry['project_credit_request_comment'] = 'NONE'; + entry['project_credit_request_date_submitted'] = 'NONE'; + entry['project_credit_request_extra_credits'] = 'NONE'; + entry['project_credit_request_user_name'] = 'NONE'; + entry['project_credit_request_user_email'] = 'NONE'; + } else { + entry['project_credit_requested'] = 'TRUE'; + entry['project_credit_request_id'] = JSON.stringify(application[key].Id); + entry['project_credit_request_comment'] = application[key].comment; + entry['project_credit_request_date_submitted'] = JSON.stringify(application[key].date_submitted); + entry['project_credit_request_extra_credits'] = JSON.stringify(application[key].extra_credits); + entry['project_credit_request_user_name'] = JSON.stringify(application[key].user.username); + entry['project_credit_request_user_email'] = JSON.stringify(application[key].user.email); + } + } else if (key === 'project_application_edam_terms') { + const edam_names = []; + application[key].forEach(edam => { + edam_names.push(edam.name); + }); + entry['project_application_edam_terms'] = JSON.stringify(edam_names); + } else if (key === 'flavors') { + const flavor_names = []; + application[key].forEach(flavor => { + flavor_names.push(flavor.name); + }); + } else if (key === 'dissemination') { + /* empty */ + } else if (key === 'project_application_compute_center') { + entry[key] = application[key].Name; + entry['project_application_compute_center_id'] = application[key].FacilityId; + } else { + entry[key] = JSON.stringify(application[key]); + } + } else { + entry[key] = application[key]; + } + } + data.push(entry); + }); + if (data.length > 0) { + // create CSV file first for convenience + const currentDate = new Date().toISOString().split('T')[0]; + // eslint-disable-next-line + const csv = new ngxCsv(data, 'cloud_projects_' + currentDate, { + showLabels: true, + headers: Object.keys(data[0]), + fieldSeparator: '\t', + noDownload: true, }); - } else if (key === 'dissemination') { - /* empty */ - } else if (key === 'project_application_compute_center') { - entry[key] = application[key].Name; - entry['project_application_compute_center_id'] = application[key].FacilityId; - } else { - entry[key] = JSON.stringify(application[key]); - } - } else { - entry[key] = application[key]; + // create TSV file and download it + const link = document.createElement('a'); + link.href = `data:text/tab-separated-values,${encodeURIComponent(csv.getCsv())}`; + link.download = `cloud_projects_${currentDate}.tsv`; + link.click(); } - } - data.push(entry); - }); - if (data.length > 0) { - // create CSV file first for convenience - const currentDate = new Date().toISOString().split('T')[0]; - // eslint-disable-next-line - const csv = new ngxCsv(data, 'cloud_projects_' + currentDate, { - showLabels: true, - headers: Object.keys(data[0]), - fieldSeparator: '\t', - noDownload: true, - }); - // create TSV file and download it - const link = document.createElement('a'); - link.href = `data:text/tab-separated-values,${encodeURIComponent(csv.getCsv())}`; - link.download = `cloud_projects_${currentDate}.tsv`; - link.click(); } - } } diff --git a/src/app/vo_manager/voOverview.component.html b/src/app/vo_manager/voOverview.component.html index af9aad0c76..ced497c5b1 100644 --- a/src/app/vo_manager/voOverview.component.html +++ b/src/app/vo_manager/voOverview.component.html @@ -23,6 +23,14 @@ Send newsletter ({{ newsletterSubscriptionCounter }}) + +
+ - + - - + + - + -
-
Projects
+
+
Projects
-
-
- - +
+
+ - -
+
+ -
-
- -
- -
- Loading... -
-
- -
-
-
+ -
-
-
+ + +
+ + +
+
+ +
+ +
+ Loading... +
+
+ +
+
+
+ +
+
+ -
-
- +
+
+ -
-
- +
+
+ -
-
- +
+
+ -
+ +
-
- +
+
+ +
-
-
-
- +
+
+ -
-
- +
+
+ -
-
- - - - - + /> + {{ + application_states[application_states.WAIT_FOR_TERMINATION_FM] + }} + + + +
Facility
+ + + + - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + + - - + - - - + + + + - + - - - -
FacilityProject IDProject NameDetailsStatusRamCoresGPUs + Project ID + + Project Name + DetailsStatus + Ram + + Cores + + GPUs + CreditsActions
- - - - - > - - - - Credits + Actions
+ + + + + + + > + + + + - - + + + {{ project_states[project_states.ACTIVE] }} + *ngIf="project | hasstatusinlist : project_states.ACTIVE" + style="margin-left: 5px" + class="badge bg-success" + >{{ project_states[project_states.ACTIVE] }} - {{ lifetime_states[lifetime_states.EXPIRED] }} + style="margin-left: 5px" + class="badge bg-danger" + >{{ lifetime_states[lifetime_states.EXPIRED] }} - {{ lifetime_states[lifetime_states.EXPIRES_SOON] }} - {{ project_states[project_states.SUSPENDED] }} + {{ lifetime_states[lifetime_states.EXPIRES_SOON] }} + {{ project_states[project_states.SUSPENDED] }} - WAIT FOR CONFIRMATION + WAIT FOR CONFIRMATION - TERMINATION REQUESTED + TERMINATION REQUESTED - WAIT FOR TERMINATION BY FM + WAIT FOR TERMINATION BY FM - PROTECTED + PROTECTED - - - - > - - - > - - + + + > + + + > + + - > - - / - > - - + > + + / + > + + -
- - + > +  Show Members + + - - - - - - -
-
-
-
-
-
- -
+ + + + + + +
+ + + + +
+
+ + + + + + + + + + + From f225e2563851d40c031dea93f2212aee16cae8c1 Mon Sep 17 00:00:00 2001 From: vktrrdk Date: Wed, 19 Apr 2023 16:55:52 +0200 Subject: [PATCH 03/15] fix(Volume Overview): Change of facility reflects on reload of volumes --- .../volumes/volumeOverview.component.html | 151 +++++++++--------- 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/src/app/virtualmachines/volumes/volumeOverview.component.html b/src/app/virtualmachines/volumes/volumeOverview.component.html index ace577c4d0..922f150049 100644 --- a/src/app/virtualmachines/volumes/volumeOverview.component.html +++ b/src/app/virtualmachines/volumes/volumeOverview.component.html @@ -39,11 +39,14 @@
-
- Volumes – Overview -
+
Volumes – Overview
- @@ -158,7 +161,8 @@
Select all + Select all
@@ -191,82 +195,82 @@
{{ volume?.volume_storage }} GB
-
+
- - -
-
-
-
- This volume is part of a migrated project! + Attach Volume + +
  • + Extend Volume +
  • +
  • + Rename Volume +
  • +
    +
    +
    This volume is part of a migrated project!
    +
    Create & Attach Volume " > - From 434626096bc723524138872550ec7e92c4db5152 Mon Sep 17 00:00:00 2001 From: vktrrdk Date: Wed, 19 Apr 2023 16:59:08 +0200 Subject: [PATCH 04/15] Revert "fix(Volume Overview): Change of facility reflects on reload of volumes" This reverts commit f225e2563851d40c031dea93f2212aee16cae8c1. --- .../volumes/volumeOverview.component.html | 151 +++++++++--------- 1 file changed, 72 insertions(+), 79 deletions(-) diff --git a/src/app/virtualmachines/volumes/volumeOverview.component.html b/src/app/virtualmachines/volumes/volumeOverview.component.html index 922f150049..ace577c4d0 100644 --- a/src/app/virtualmachines/volumes/volumeOverview.component.html +++ b/src/app/virtualmachines/volumes/volumeOverview.component.html @@ -39,14 +39,11 @@
    -
    Volumes – Overview
    +
    + Volumes – Overview +
    - @@ -161,8 +158,7 @@
    - Select all Select all
    @@ -195,82 +191,82 @@
    {{ volume?.volume_storage }} GB
    -
    +
    + +
    + +
  • + Extend Volume +
  • +
  • + Rename Volume +
  • +
    -
    -
    This volume is part of a migrated project!
    +
    +
    +
    + This volume is part of a migrated project! +
    Create & Attach Volume " > - From 643192f85b438d8228e11a204b7000b3b3cf1b2d Mon Sep 17 00:00:00 2001 From: Viktor Rudko <43116821+vktrrdk@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:55:50 +0200 Subject: [PATCH 05/15] Fix/fm overview spinner (#5641) * fix(FM Overview): Change loading status for spinner on facility selection change * fix(Linting):blacked code * fix(Volume Overview): Change of facility reflects on reload of volumes --------- Co-authored-by: vktrrdk Co-authored-by: dweinholz --- .../facilityprojectsoverview.component.ts | 1 + .../volumes/volumeOverview.component.html | 151 +++++++++--------- 2 files changed, 80 insertions(+), 72 deletions(-) diff --git a/src/app/facility_manager/facilityprojectsoverview.component.ts b/src/app/facility_manager/facilityprojectsoverview.component.ts index 3770c914ee..90e9ce3eae 100644 --- a/src/app/facility_manager/facilityprojectsoverview.component.ts +++ b/src/app/facility_manager/facilityprojectsoverview.component.ts @@ -198,6 +198,7 @@ export class FacilityProjectsOverviewComponent extends AbstractBaseClass impleme * Gets projects and sets email subject prefix when selected facility changes. */ onChangeSelectedFacility(): void { + this.isLoaded = false; this.getFacilityProjects(this.selectedFacility['FacilityId']); this.emailSubject = `[${this.selectedFacility['Facility']}]`; } diff --git a/src/app/virtualmachines/volumes/volumeOverview.component.html b/src/app/virtualmachines/volumes/volumeOverview.component.html index ace577c4d0..922f150049 100644 --- a/src/app/virtualmachines/volumes/volumeOverview.component.html +++ b/src/app/virtualmachines/volumes/volumeOverview.component.html @@ -39,11 +39,14 @@
    -
    - Volumes – Overview -
    +
    Volumes – Overview
    - @@ -158,7 +161,8 @@
    Select all + Select all
    @@ -191,82 +195,82 @@
    {{ volume?.volume_storage }} GB
    -
    +
    - - -
    -
    -
    -
    - This volume is part of a migrated project! + Attach Volume + +
  • + Extend Volume +
  • +
  • + Rename Volume +
  • +
    +
    +
    This volume is part of a migrated project!
    +
    Create & Attach Volume " > - From 5d8793bfc53d54c404c7cb9ebb5498ba0cfd12f2 Mon Sep 17 00:00:00 2001 From: Viktor Rudko <43116821+vktrrdk@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:02:19 +0200 Subject: [PATCH 06/15] feat(Workshop): Added link to wiki (#5643) --- .../workshop-overview/workshop-overview.component.html | 3 +++ .../workshop-overview/workshop-overview.component.ts | 8 +++++++- src/links/links.ts | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.html b/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.html index a1ff30a22b..b8a75d3e85 100644 --- a/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.html +++ b/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.html @@ -321,6 +321,9 @@ timeframes are displayed using the "Central European Time". The date you enter is dependent on the timezone of your browser . Please enter the time slots day by day, to be more precise! +
    + See more on timeframes + here.
    Existing timeframes
    diff --git a/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.ts b/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.ts index 64ff111191..4d2dc699e8 100644 --- a/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.ts +++ b/src/app/virtualmachines/workshop/workshop-overview/workshop-overview.component.ts @@ -8,7 +8,12 @@ import { UrlData } from '../workshop-urlinfo.model'; import { WorkshopService } from '../../../api-connector/workshop.service'; import { ProjectMember } from '../../../projectmanagement/project_member.model'; import { WorkshopVM } from '../workshop-vm.model'; -import { WIKI_WORKSHOPS, CLOUD_PORTAL_SUPPORT_MAIL, LIFESCIENCE_HOSTEL_SIGNUP } from '../../../../links/links'; +import { + WIKI_WORKSHOPS, + CLOUD_PORTAL_SUPPORT_MAIL, + LIFESCIENCE_HOSTEL_SIGNUP, + WIKI_WORKSHOP_TIMEFRAMES, +} from '../../../../links/links'; import { WorkshopTimeFrame } from '../workshopTimeFrame.model'; interface MemberVm { @@ -30,6 +35,7 @@ export class WorkshopOverviewComponent implements OnInit, OnDestroy { WIKI_WORKSHOPS: string = WIKI_WORKSHOPS; LIFESCIENCE_HOSTEL_SIGNUP: string = LIFESCIENCE_HOSTEL_SIGNUP; CLOUD_PORTAL_SUPPORT_MAIL: string = CLOUD_PORTAL_SUPPORT_MAIL; + WIKI_WORKSHOP_TIMEFRAMES: string = WIKI_WORKSHOP_TIMEFRAMES; subscription: Subscription = new Subscription(); resend_info: boolean = false; sending_mails = false; diff --git a/src/links/links.ts b/src/links/links.ts index 9d68a1300e..94bf03e061 100644 --- a/src/links/links.ts +++ b/src/links/links.ts @@ -29,6 +29,7 @@ export const SCALE_SCRIPT_LINK: string = 'https://raw.githubusercontent.com/deNB export const WIKI_MOUNT_VOLUME: string = `${environment.WIKI_PRE}simple_vm/volumes/#mount-a-volume`; export const WIKI_VOLUMES_LINK: string = `${environment.WIKI_PRE}simple_vm/volumes/`; export const WIKI_MOSH_LINK: string = `${environment.WIKI_PRE}Tutorials/Mosh/`; +export const WIKI_WORKSHOP_TIMEFRAMES: string = `${environment.WIKI_PRE}simple_vm/workshop/#workshop-timeframes`; export const WIKI_EPHEMERAL_LINK: string = `${environment.WIKI_PRE}simple_vm/new_instance/#information-for-ephemeral-flavors`; export const WIKI_GROUP_INVITATIONS: string = `${environment.WIKI_PRE}simple_vm/project_overview/#inviting-members`; export const SCALING_UP_WIKI: string = `${environment.WIKI_PRE}simple_vm/Cluster/cluster_overview/#3-scale-up`; @@ -79,6 +80,7 @@ export const WIKI_LINKS: string[] = [ WIKI_MOSH_LINK, WIKI_PERSONAL_DATA, WIKI_SVM_MIGRATION_LINK, + WIKI_WORKSHOP_TIMEFRAMES, ]; export const LANDING_PAGE_LINKS: string[] = [ From 327724f514504597c62db9e68ce2cfb86dd1515b Mon Sep 17 00:00:00 2001 From: Viktor Rudko <43116821+vktrrdk@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:09:33 +0200 Subject: [PATCH 07/15] =?UTF-8?q?fix(Application):=20Added=20missing=20pos?= =?UTF-8?q?sibility=20of=20changing=20of=20personal=20d=E2=80=A6=20(#5570)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(Application): Added missing possibility of changing of personal data parameters on adjustment * fix(Linting):blacked code (#5638) Co-authored-by: vktrrdk --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: vktrrdk From 25d47587b5d02e81d9d8e233977bef163c61a401 Mon Sep 17 00:00:00 2001 From: Viktor Rudko <43116821+vktrrdk@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:09:48 +0200 Subject: [PATCH 08/15] feat(VM): Users are able to initiate restart for VMs in error-state (#5644) * feat(VM): Users are able to initiate restart for VMs in error-state * also added handling for instance detail page --- .../vmcard/vmcard.component.html | 10 +- .../vmdetail/vmdetail.component.html | 159 +++++++++++------- 2 files changed, 98 insertions(+), 71 deletions(-) diff --git a/src/app/virtualmachines/vmcard/vmcard.component.html b/src/app/virtualmachines/vmcard/vmcard.component.html index 4d74001e59..7a4ebb2844 100644 --- a/src/app/virtualmachines/vmcard/vmcard.component.html +++ b/src/app/virtualmachines/vmcard/vmcard.component.html @@ -318,7 +318,8 @@ !(vm?.status | hasStatus : VirtualMachineStates.staticPORT_CLOSED)) || (vm?.status | hasStatus : VirtualMachineStates.staticNOT_FOUND) || (vm?.status | hasStatus : VirtualMachineStates.staticDELETED) || - this.vm.project_is_migrated_to_simple_vm || this.vm.migrate_project_to_simple_vm + this.vm.project_is_migrated_to_simple_vm || + this.vm.migrate_project_to_simple_vm " [id]="'showActionsButton_' + vm?.name" [attr.data-test-id]="'show_actions_button_' + vm?.name" @@ -508,12 +509,7 @@ vm.client.features['VM_REBOOT'] && !( vm?.status - | statusInList - : [ - VirtualMachineStates.staticDELETED, - VirtualMachineStates.staticERROR, - VirtualMachineStates.staticCREATION_FAILED - ] + | statusInList : [VirtualMachineStates.staticDELETED, VirtualMachineStates.staticCREATION_FAILED] ) " > diff --git a/src/app/virtualmachines/vmdetail/vmdetail.component.html b/src/app/virtualmachines/vmdetail/vmdetail.component.html index 8454826dce..aa9fc0aa94 100644 --- a/src/app/virtualmachines/vmdetail/vmdetail.component.html +++ b/src/app/virtualmachines/vmdetail/vmdetail.component.html @@ -68,76 +68,102 @@
    -
    -
    - Connect Information -
    -
    -
    -
    -
    - via
    - {{ mode.name }} +
    +
    + + Connect Information +
    +
    +
    +
    +
    + via
    + {{ mode.name }} +
    -
    -
    -
    - with
    - +
    +
    + with
    + +
    +
    +
    +
    + Copy Command +
    -
    -
    - Copy Command +
    +
    +

    + Learn more about persistent terminal sessions when using ssh: + Tutorial +

    -
    -
    -
    -

    - Learn more about persistent terminal sessions when using ssh: - Tutorial -

    +
    +
    + Research Environment: +
    +
    + {{ + virtualMachine?.res_env_url + }} +
    + For RStudio credentials please visit: + {{ + WIKI_RSTUDIO_LINK + }} +
    + For Apache Guacamole credentials please visit: + {{ + WIKI_GUACAMOLE_LINK + }} +
    -
    -
    - Research Environment: -
    -
    - {{ - virtualMachine?.res_env_url - }} -
    - For RStudio credentials please visit: - {{ - WIKI_RSTUDIO_LINK - }} -
    - For Apache Guacamole credentials please visit: - {{ - WIKI_GUACAMOLE_LINK - }} +
    + + + Connect Information +
    +
    +
    + There currently is no connect information available, as the machine is in error-state.
    -
    + +
    Actions @@ -156,8 +182,13 @@
    + +
    @@ -986,10 +950,10 @@ Information + type="button" + class="btn btn-secondary"> + Remove Application + - + - + - + - + - +
    - - - - - - - - - - - - - - - + {{ application?.project_application_name }} {{ application?.project_application_shortname }}
    From cf68168788d1960b09db4a02c903dd334d5384ea Mon Sep 17 00:00:00 2001 From: dweinholz Date: Tue, 25 Apr 2023 16:17:19 +0200 Subject: [PATCH 13/15] fixed label --- .../information-detail/information-detail.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/applications/application-detail/information-detail/information-detail.component.html b/src/app/applications/application-detail/information-detail/information-detail.component.html index 980f5b9cbe..32b3f7d522 100644 --- a/src/app/applications/application-detail/information-detail/information-detail.component.html +++ b/src/app/applications/application-detail/information-detail/information-detail.component.html @@ -96,7 +96,7 @@
    Person Related DataProject processes data of human subjects

    Yes

    No

    @@ -117,7 +117,7 @@
    Sensitive Personal data [Articles 4 (13,14,15), 9 GDPR and Recital 51] Sensitive Personal data [Articles 4 (13,14,15), 9 GDPR and Recital 51]

    Yes

    No

    From fa71ff5d53983c22f28a144a20ba5e7517a21ca9 Mon Sep 17 00:00:00 2001 From: dweinholz Date: Tue, 25 Apr 2023 16:19:07 +0200 Subject: [PATCH 14/15] fixed label --- .../information-detail/information-detail.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/applications/application-detail/information-detail/information-detail.component.html b/src/app/applications/application-detail/information-detail/information-detail.component.html index 32b3f7d522..4e76c095e6 100644 --- a/src/app/applications/application-detail/information-detail/information-detail.component.html +++ b/src/app/applications/application-detail/information-detail/information-detail.component.html @@ -103,21 +103,21 @@
    No Personal Data (Anonymous)a) No Personal Data (Anonymous)

    Yes

    No

    Personal data [Article 4 (1) GDPR] (e.g. name, e-mail)b) Personal data [Article 4 (1) GDPR] (e.g. name, e-mail)

    Yes

    No

    Sensitive Personal data [Articles 4 (13,14,15), 9 GDPR and Recital 51]c) Sensitive Personal data [Articles 4 (13,14,15), 9 GDPR and Recital 51]

    Yes

    No

    From 0d54a519199776e265c084cb06ea5dca25c51600 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:52:03 +0000 Subject: [PATCH 15/15] feat(Dependencies): Update all non-major dependencies | datasource | package | from | to | | ---------- | --------------------------------- | ------- | ------- | | npm | @angular/animations | 15.2.7 | 15.2.8 | | npm | @angular/cdk | 15.2.7 | 15.2.8 | | npm | @angular/common | 15.2.7 | 15.2.8 | | npm | @angular/compiler | 15.2.7 | 15.2.8 | | npm | @angular/compiler-cli | 15.2.7 | 15.2.8 | | npm | @angular/core | 15.2.7 | 15.2.8 | | npm | @angular/forms | 15.2.7 | 15.2.8 | | npm | @angular/localize | 15.2.7 | 15.2.8 | | npm | @angular/platform-browser | 15.2.7 | 15.2.8 | | npm | @angular/platform-browser-dynamic | 15.2.7 | 15.2.8 | | npm | @angular/router | 15.2.7 | 15.2.8 | | npm | @angular/service-worker | 15.2.7 | 15.2.8 | | npm | @angular/upgrade | 15.2.7 | 15.2.8 | | npm | @types/node | 18.16.0 | 18.16.1 | | npm | @typescript-eslint/eslint-plugin | 5.59.0 | 5.59.1 | | npm | @typescript-eslint/parser | 5.59.0 | 5.59.1 | | npm | html-to-pdfmake | 2.4.16 | 2.4.20 | | npm | karma | 6.4.1 | 6.4.2 | | npm | prettier | 2.8.7 | 2.8.8 | | npm | slash | 5.0.0 | 5.0.1 | | npm | webpack-cli | 5.0.1 | 5.0.2 | --- package-lock.json | 531 +++++++++++++++++++++++++--------------------- package.json | 38 ++-- 2 files changed, 310 insertions(+), 259 deletions(-) diff --git a/package-lock.json b/package-lock.json index 719e6183d7..afee481935 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,26 @@ { "name": "@denbi/cloud-portal-webapp", - "version": "4.683.0", + "version": "4.684.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@denbi/cloud-portal-webapp", - "version": "4.683.0", + "version": "4.684.0", "dependencies": { "@angular-eslint/eslint-plugin": "^15.2.0", - "@angular/animations": "15.2.7", - "@angular/cdk": "15.2.7", - "@angular/common": "15.2.7", - "@angular/compiler": "15.2.7", - "@angular/core": "15.2.7", - "@angular/forms": "15.2.7", - "@angular/localize": "15.2.7", - "@angular/platform-browser": "15.2.7", - "@angular/platform-browser-dynamic": "15.2.7", - "@angular/router": "15.2.7", - "@angular/service-worker": "15.2.7", - "@angular/upgrade": "15.2.7", + "@angular/animations": "15.2.8", + "@angular/cdk": "15.2.8", + "@angular/common": "15.2.8", + "@angular/compiler": "15.2.8", + "@angular/core": "15.2.8", + "@angular/forms": "15.2.8", + "@angular/localize": "15.2.8", + "@angular/platform-browser": "15.2.8", + "@angular/platform-browser-dynamic": "15.2.8", + "@angular/router": "15.2.8", + "@angular/service-worker": "15.2.8", + "@angular/upgrade": "15.2.8", "@coreui/angular": "^4.3.4", "@coreui/coreui": "4.2.6", "@coreui/icons-angular": "^4.3.0", @@ -40,12 +40,13 @@ "css-loader": "6.7.3", "cssnano": "6.0.0", "d3": "7.8.4", + "eslint": "^8.28.0", "export-to-csv": "0.2.1", "express": "4.18.2", "file-saver": "2.0.5", "follow-redirects": "1.15.2", "globby": "13.1.4", - "html-to-pdfmake": "2.4.16", + "html-to-pdfmake": "2.4.20", "html2canvas": "1.4.1", "http-server": "14.1.1", "is-promise": "4.0.0", @@ -82,11 +83,11 @@ "@angular-eslint/schematics": "15.2.1", "@angular-eslint/template-parser": "15.2.1", "@angular/cli": "15.2.6", - "@angular/compiler-cli": "15.2.7", + "@angular/compiler-cli": "15.2.8", "@compodoc/compodoc": "1.1.19", "@playwright/test": "1.32.3", "@types/jasmine": "4.3.1", - "@types/node": "18.16.0", + "@types/node": "18.16.1", "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", "async": "3.2.4", @@ -103,13 +104,13 @@ "html-webpack-plugin": "5.5.1", "husky": "8.0.3", "json-loader": "0.5.7", - "karma": "6.4.1", + "karma": "6.4.2", "karma-chrome-launcher": "3.2.0", "less-loader": "11.1.0", "lint-staged": "13.2.1", "ngx-spec": "2.1.5", "npm-run-all": "4.1.5", - "prettier": "2.8.7", + "prettier": "2.8.8", "raw-loader": "4.0.2", "sass-loader": "13.2.2", "script-loader": "0.7.2", @@ -119,7 +120,7 @@ "ts-node": "10.9.1", "typescript": "4.9.5", "url-loader": "4.1.1", - "webpack-cli": "5.0.1" + "webpack-cli": "5.0.2" } }, "node_modules/@adobe/css-tools": { @@ -639,9 +640,9 @@ } }, "node_modules/@angular/animations": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.7.tgz", - "integrity": "sha512-Vmy0AljHc/GOp87O2x0mxUDiyfJFW8ndDE9Xrm/g0rnLnNWsaLtLXr1TWbwF7eTqKA3k/QcUvYAjLMWKvjyKgQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.8.tgz", + "integrity": "sha512-I3xh8EASQ04s3qXQYpIORI0jFiFmvBQERBqS70TieTCIML7banOf9R3K7sAWB9frG5J0CEUwr+wtF47DCs/7eQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -649,13 +650,13 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.7" + "@angular/core": "15.2.8" } }, "node_modules/@angular/cdk": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.7.tgz", - "integrity": "sha512-IQg/EuZ3LC/vOHZtcLvkM+FSACXW5PVv2NddJgsBOtfcf1HcTk97VhegtB4WGQTUe1pcxiLGz/aWYuIRknjitw==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.8.tgz", + "integrity": "sha512-jiCoxfBFMH29IZIiPmVUzIWetfUNpMIvC20xYVF8RMM819vPogoObzwK4DN/sXcp/6oVbBzZFaYdijhhIt9soQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -720,9 +721,9 @@ } }, "node_modules/@angular/common": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.7.tgz", - "integrity": "sha512-CbmrQeZ0yChQrF/ab3v+gv6x2uLbv/s1wZNUBSO/p1STz6BZzHRJqObVlfPlQvyBx5btBBy/+I1sUh1yumARDA==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.8.tgz", + "integrity": "sha512-yLDQihiRcVl38HrWMPbqgzOaSUw85AQH5BsGdjbS6BpoBQj3EXOpccCMFsuxOKxPG4toatgawNqrEnK0Jpv9Mw==", "dependencies": { "tslib": "^2.3.0" }, @@ -730,14 +731,14 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.7", + "@angular/core": "15.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.7.tgz", - "integrity": "sha512-SesyYI2ExUa13XukXgIsmfg3ar90HbWeWDJTgmzsIfph0M9t6+SaPGpf3FCtdBgNADIpUFp3cieCOJgLESzxYQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.8.tgz", + "integrity": "sha512-+dvspIDvuGoYqdL7r/3o9ojkR3fH1zevgC0ISJivcIrMi+WcJ0FV2JmJdnm8V52oNsHy+sMF9eEZGEbCbACE/A==", "dependencies": { "tslib": "^2.3.0" }, @@ -745,7 +746,7 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.7" + "@angular/core": "15.2.8" }, "peerDependenciesMeta": { "@angular/core": { @@ -754,9 +755,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.7.tgz", - "integrity": "sha512-4v51dOaT8GDUzRh6+mCLZOaYuU9FYX6vOHaLod9np3tVWPhcpoF2ZklRSiQDeFqrhr5B4vuCp/Lh9N2wzc22XQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.8.tgz", + "integrity": "sha512-fFxaDlbILo0t2t662qA0cjgn+kWItGlc1tFYKU6X7bvYb3t2e0cd9FzrFPLXUQVboGis83ULcJ2zkDxScnuPuQ==", "dependencies": { "@babel/core": "7.19.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -778,7 +779,7 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "15.2.7", + "@angular/compiler": "15.2.8", "typescript": ">=4.8.2 <5.0" } }, @@ -820,9 +821,9 @@ } }, "node_modules/@angular/core": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.7.tgz", - "integrity": "sha512-iS7JCJubRFqdndoUdAnvNkQRT3tY5tNFupBQS/sytkwxVrdBg+Is5jpdgk741n824vTMsE+CnuY0SETar8rN6g==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.8.tgz", + "integrity": "sha512-NDs+g4uM4EhyCvluf8a0YBCFXsDAEfCMHOD5cS00Bl+liTQ7JwtmepkWXMyjLB92irC9JaR79kdy4BoIKOh8WA==", "dependencies": { "tslib": "^2.3.0" }, @@ -835,9 +836,9 @@ } }, "node_modules/@angular/forms": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.7.tgz", - "integrity": "sha512-rzrebDIrtxxOeMcBzRBxqaOBZ+T1DJrysG/6YWZy428W/Z3MfPxUarPxgfx/oZI+x5uUsDaZmyoRdhVPJ2KhZg==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.8.tgz", + "integrity": "sha512-VyevVj20DdQWjAQUyiFTe+DAzqG9GqfAOWn376Y/lhPcwxAojXePTGNgtQud566/urDrNrP5haaLD6O36/3n+w==", "dependencies": { "tslib": "^2.3.0" }, @@ -845,16 +846,16 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7", + "@angular/common": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/localize": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.7.tgz", - "integrity": "sha512-ySuy35QKApWH9sW3PfnAAnZjLl3NT+SacvlEWigrTeCqfBEuDPUG57ugvc1/Lzuo09UOh3HQkrQBbdWAILd8JA==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.8.tgz", + "integrity": "sha512-wJLBp0MUnET9kHzBtqIlZ3RQ56JFItXSgmBXagQq+MU+uJZmGvuw6fez0i5wkgv9Rgnr25oCULVtpTF+T5RGYA==", "dependencies": { "@babel/core": "7.19.3", "glob": "8.1.0", @@ -869,8 +870,8 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "15.2.7", - "@angular/compiler-cli": "15.2.7" + "@angular/compiler": "15.2.8", + "@angular/compiler-cli": "15.2.8" } }, "node_modules/@angular/localize/node_modules/@babel/core": { @@ -911,9 +912,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.7.tgz", - "integrity": "sha512-aCbd7xyuP7c2eDITkOTDO2mqP550WHCBN8U6VnjysqtB5ocbJtR6z/MIRItN/Zx+xj3piiaKei//XIkb3Q5fXQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.8.tgz", + "integrity": "sha512-8sKFUld54inj0FnQ1ydhFxnDgsbbf43W9FALye/5uEtLgwwE/ZvkNYMaQ7hq1JPuQRMDj3gJkFqaLeFjplpHDA==", "dependencies": { "tslib": "^2.3.0" }, @@ -921,9 +922,9 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/animations": "15.2.7", - "@angular/common": "15.2.7", - "@angular/core": "15.2.7" + "@angular/animations": "15.2.8", + "@angular/common": "15.2.8", + "@angular/core": "15.2.8" }, "peerDependenciesMeta": { "@angular/animations": { @@ -932,9 +933,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.7.tgz", - "integrity": "sha512-t1Nf7hgbcYvhmxuzgUtsV47jrI5CXUBqrtz5I0ilWG92zZTig5qvfd1/2Ub8NHz87uHNrnggyZpL2+4MJ26nyQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.8.tgz", + "integrity": "sha512-75HyoZNibA3u/FvdK4Aw5KMzUmS/nDk5N8s7gfM09fe1resSPgFiW8JJEkr1xiUdA2WtSRbHs34y5rHLDe7n1Q==", "dependencies": { "tslib": "^2.3.0" }, @@ -942,16 +943,16 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/compiler": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7" + "@angular/common": "15.2.8", + "@angular/compiler": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8" } }, "node_modules/@angular/router": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.7.tgz", - "integrity": "sha512-Wkk+oJSUrVafJjmv9uE1SoY4wDE9bjX7ald+UXePz+QyM/PFoLkm/CzLYjFBkJnsOkOVxw1VmvacoUjWN6BCTQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.8.tgz", + "integrity": "sha512-C62QBEeJSBTNTrQHZiklPrxwJwuENoZzWX22MMJ7dxl+7VjRgnmj8J7mcX9fLjHlL+mC3RvesMlX7sGZRQV1cg==", "dependencies": { "tslib": "^2.3.0" }, @@ -959,16 +960,16 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7", + "@angular/common": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-15.2.7.tgz", - "integrity": "sha512-lDUWIXpPFd4iICczzvfWJgWgMJ7Q/7ZBQF1IciXP4W5UpE+Vjgxx5mV4y0njzQLb2tn2VNDAOksJK26Y5ks43w==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-15.2.8.tgz", + "integrity": "sha512-iD3qsqN/N2014uCuCka77pu0tqPPsLcP9rUZgAJEM01o/A/ez+E3TmWW2PYvSq2zLZQnZZ40a7dWonIAclJq3Q==", "dependencies": { "tslib": "^2.3.0" }, @@ -979,14 +980,14 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/core": "15.2.7" + "@angular/common": "15.2.8", + "@angular/core": "15.2.8" } }, "node_modules/@angular/upgrade": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/upgrade/-/upgrade-15.2.7.tgz", - "integrity": "sha512-9hxJyplabtc5Oia5IDoQG1DKK8d9QbGc8GJ8XlB0HBqMJ9jrsLiFTGqFHpQf4hodE0n/MWfLuPa/xzGFS1g7Bg==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/upgrade/-/upgrade-15.2.8.tgz", + "integrity": "sha512-KDkJmJ36tIkzCTaBhRvd9S4Y+7ILnuCv1BFPo5bnmlGhboWNwoj/40Bo1lGDOWtf6rQA7qVjDptFqdyZS8eUJg==", "dependencies": { "tslib": "^2.3.0" }, @@ -994,10 +995,10 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7", - "@angular/platform-browser-dynamic": "15.2.7" + "@angular/compiler": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8", + "@angular/platform-browser-dynamic": "15.2.8" } }, "node_modules/@assemblyscript/loader": { @@ -4259,9 +4260,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.16.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.0.tgz", - "integrity": "sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==" + "version": "18.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz", + "integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -4336,15 +4337,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz", - "integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", + "integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/type-utils": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/type-utils": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -4370,13 +4371,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz", - "integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", + "integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4397,17 +4398,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz", - "integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz", + "integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -4445,14 +4446,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz", - "integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz", + "integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "debug": "^4.3.4" }, "engines": { @@ -4472,13 +4473,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz", - "integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", + "integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0" + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4597,9 +4598,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", - "integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz", + "integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4610,13 +4611,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz", - "integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", + "integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4799,12 +4800,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz", - "integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", + "integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/types": "5.59.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4956,9 +4957,10 @@ } }, "node_modules/@webpack-cli/serve": { - "version": "2.0.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.2.tgz", + "integrity": "sha512-S9h3GmOmzUseyeFW3tYNnWS7gNUuwxZ3mmMq0JyW78Vx1SGKPSkt5bT4pB0rUnVfHjP0EL9gW2bOzmtiTfQt0A==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.15.0" }, @@ -9964,8 +9966,9 @@ } }, "node_modules/html-to-pdfmake": { - "version": "2.4.16", - "license": "MIT" + "version": "2.4.20", + "resolved": "https://registry.npmjs.org/html-to-pdfmake/-/html-to-pdfmake-2.4.20.tgz", + "integrity": "sha512-+tId1Lp3fMoOVdgD1jXeZqznnUXtsxFm3UH7yiMhgpFtY6jHjuNUPkIcjxC8SNnLe0UTX7R0F3vv5TZ23YM1kQ==" }, "node_modules/html-webpack-plugin": { "version": "5.5.1", @@ -11202,9 +11205,10 @@ } }, "node_modules/karma": { - "version": "6.4.1", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", + "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", "dev": true, - "license": "MIT", "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -11269,8 +11273,9 @@ }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -11279,8 +11284,9 @@ }, "node_modules/karma/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11298,8 +11304,9 @@ }, "node_modules/karma/node_modules/mime": { "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, - "license": "MIT", "bin": { "mime": "cli.js" }, @@ -11309,16 +11316,18 @@ }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/karma/node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -11334,8 +11343,9 @@ }, "node_modules/karma/node_modules/yargs-parser": { "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } @@ -14501,9 +14511,9 @@ } }, "node_modules/prettier": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", - "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -15798,8 +15808,9 @@ } }, "node_modules/slash": { - "version": "5.0.0", - "license": "MIT", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.0.1.tgz", + "integrity": "sha512-ywNzUOiXwetmLvTUiCBZpLi+vxqN3i+zDqjs2HHfUSV3wN4UJxVVKWrS1JZDeiJIeBFNgB5pmioC2g0IUTL+rQ==", "engines": { "node": ">=14.16" }, @@ -17657,16 +17668,17 @@ } }, "node_modules/webpack-cli": { - "version": "5.0.1", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.2.tgz", + "integrity": "sha512-4y3W5Dawri5+8dXm3+diW6Mn1Ya+Dei6eEVAdIduAmYNLzv1koKVAqsfgrrc9P2mhrYHQphx5htnGkcNwtubyQ==", "dev": true, - "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.0.1", "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.1", + "@webpack-cli/serve": "^2.0.2", "colorette": "^2.0.14", - "commander": "^9.4.1", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", @@ -17700,6 +17712,15 @@ } } }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/webpack-dev-middleware": { "version": "6.0.1", "dev": true, @@ -18631,17 +18652,17 @@ } }, "@angular/animations": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.7.tgz", - "integrity": "sha512-Vmy0AljHc/GOp87O2x0mxUDiyfJFW8ndDE9Xrm/g0rnLnNWsaLtLXr1TWbwF7eTqKA3k/QcUvYAjLMWKvjyKgQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.8.tgz", + "integrity": "sha512-I3xh8EASQ04s3qXQYpIORI0jFiFmvBQERBqS70TieTCIML7banOf9R3K7sAWB9frG5J0CEUwr+wtF47DCs/7eQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/cdk": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.7.tgz", - "integrity": "sha512-IQg/EuZ3LC/vOHZtcLvkM+FSACXW5PVv2NddJgsBOtfcf1HcTk97VhegtB4WGQTUe1pcxiLGz/aWYuIRknjitw==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.8.tgz", + "integrity": "sha512-jiCoxfBFMH29IZIiPmVUzIWetfUNpMIvC20xYVF8RMM819vPogoObzwK4DN/sXcp/6oVbBzZFaYdijhhIt9soQ==", "requires": { "parse5": "^7.1.2", "tslib": "^2.3.0" @@ -18687,25 +18708,25 @@ } }, "@angular/common": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.7.tgz", - "integrity": "sha512-CbmrQeZ0yChQrF/ab3v+gv6x2uLbv/s1wZNUBSO/p1STz6BZzHRJqObVlfPlQvyBx5btBBy/+I1sUh1yumARDA==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.8.tgz", + "integrity": "sha512-yLDQihiRcVl38HrWMPbqgzOaSUw85AQH5BsGdjbS6BpoBQj3EXOpccCMFsuxOKxPG4toatgawNqrEnK0Jpv9Mw==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.7.tgz", - "integrity": "sha512-SesyYI2ExUa13XukXgIsmfg3ar90HbWeWDJTgmzsIfph0M9t6+SaPGpf3FCtdBgNADIpUFp3cieCOJgLESzxYQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.8.tgz", + "integrity": "sha512-+dvspIDvuGoYqdL7r/3o9ojkR3fH1zevgC0ISJivcIrMi+WcJ0FV2JmJdnm8V52oNsHy+sMF9eEZGEbCbACE/A==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler-cli": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.7.tgz", - "integrity": "sha512-4v51dOaT8GDUzRh6+mCLZOaYuU9FYX6vOHaLod9np3tVWPhcpoF2ZklRSiQDeFqrhr5B4vuCp/Lh9N2wzc22XQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.8.tgz", + "integrity": "sha512-fFxaDlbILo0t2t662qA0cjgn+kWItGlc1tFYKU6X7bvYb3t2e0cd9FzrFPLXUQVboGis83ULcJ2zkDxScnuPuQ==", "requires": { "@babel/core": "7.19.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -18751,25 +18772,25 @@ } }, "@angular/core": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.7.tgz", - "integrity": "sha512-iS7JCJubRFqdndoUdAnvNkQRT3tY5tNFupBQS/sytkwxVrdBg+Is5jpdgk741n824vTMsE+CnuY0SETar8rN6g==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.8.tgz", + "integrity": "sha512-NDs+g4uM4EhyCvluf8a0YBCFXsDAEfCMHOD5cS00Bl+liTQ7JwtmepkWXMyjLB92irC9JaR79kdy4BoIKOh8WA==", "requires": { "tslib": "^2.3.0" } }, "@angular/forms": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.7.tgz", - "integrity": "sha512-rzrebDIrtxxOeMcBzRBxqaOBZ+T1DJrysG/6YWZy428W/Z3MfPxUarPxgfx/oZI+x5uUsDaZmyoRdhVPJ2KhZg==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.8.tgz", + "integrity": "sha512-VyevVj20DdQWjAQUyiFTe+DAzqG9GqfAOWn376Y/lhPcwxAojXePTGNgtQud566/urDrNrP5haaLD6O36/3n+w==", "requires": { "tslib": "^2.3.0" } }, "@angular/localize": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.7.tgz", - "integrity": "sha512-ySuy35QKApWH9sW3PfnAAnZjLl3NT+SacvlEWigrTeCqfBEuDPUG57ugvc1/Lzuo09UOh3HQkrQBbdWAILd8JA==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.8.tgz", + "integrity": "sha512-wJLBp0MUnET9kHzBtqIlZ3RQ56JFItXSgmBXagQq+MU+uJZmGvuw6fez0i5wkgv9Rgnr25oCULVtpTF+T5RGYA==", "requires": { "@babel/core": "7.19.3", "glob": "8.1.0", @@ -18806,41 +18827,41 @@ } }, "@angular/platform-browser": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.7.tgz", - "integrity": "sha512-aCbd7xyuP7c2eDITkOTDO2mqP550WHCBN8U6VnjysqtB5ocbJtR6z/MIRItN/Zx+xj3piiaKei//XIkb3Q5fXQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.8.tgz", + "integrity": "sha512-8sKFUld54inj0FnQ1ydhFxnDgsbbf43W9FALye/5uEtLgwwE/ZvkNYMaQ7hq1JPuQRMDj3gJkFqaLeFjplpHDA==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser-dynamic": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.7.tgz", - "integrity": "sha512-t1Nf7hgbcYvhmxuzgUtsV47jrI5CXUBqrtz5I0ilWG92zZTig5qvfd1/2Ub8NHz87uHNrnggyZpL2+4MJ26nyQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.8.tgz", + "integrity": "sha512-75HyoZNibA3u/FvdK4Aw5KMzUmS/nDk5N8s7gfM09fe1resSPgFiW8JJEkr1xiUdA2WtSRbHs34y5rHLDe7n1Q==", "requires": { "tslib": "^2.3.0" } }, "@angular/router": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.7.tgz", - "integrity": "sha512-Wkk+oJSUrVafJjmv9uE1SoY4wDE9bjX7ald+UXePz+QyM/PFoLkm/CzLYjFBkJnsOkOVxw1VmvacoUjWN6BCTQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.8.tgz", + "integrity": "sha512-C62QBEeJSBTNTrQHZiklPrxwJwuENoZzWX22MMJ7dxl+7VjRgnmj8J7mcX9fLjHlL+mC3RvesMlX7sGZRQV1cg==", "requires": { "tslib": "^2.3.0" } }, "@angular/service-worker": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-15.2.7.tgz", - "integrity": "sha512-lDUWIXpPFd4iICczzvfWJgWgMJ7Q/7ZBQF1IciXP4W5UpE+Vjgxx5mV4y0njzQLb2tn2VNDAOksJK26Y5ks43w==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-15.2.8.tgz", + "integrity": "sha512-iD3qsqN/N2014uCuCka77pu0tqPPsLcP9rUZgAJEM01o/A/ez+E3TmWW2PYvSq2zLZQnZZ40a7dWonIAclJq3Q==", "requires": { "tslib": "^2.3.0" } }, "@angular/upgrade": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/upgrade/-/upgrade-15.2.7.tgz", - "integrity": "sha512-9hxJyplabtc5Oia5IDoQG1DKK8d9QbGc8GJ8XlB0HBqMJ9jrsLiFTGqFHpQf4hodE0n/MWfLuPa/xzGFS1g7Bg==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/upgrade/-/upgrade-15.2.8.tgz", + "integrity": "sha512-KDkJmJ36tIkzCTaBhRvd9S4Y+7ILnuCv1BFPo5bnmlGhboWNwoj/40Bo1lGDOWtf6rQA7qVjDptFqdyZS8eUJg==", "requires": { "tslib": "^2.3.0" } @@ -20908,9 +20929,9 @@ "dev": true }, "@types/node": { - "version": "18.16.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.0.tgz", - "integrity": "sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==" + "version": "18.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz", + "integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==" }, "@types/parse-json": { "version": "4.0.0" @@ -20981,15 +21002,15 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz", - "integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", + "integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/type-utils": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/type-utils": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -20999,29 +21020,29 @@ }, "dependencies": { "@typescript-eslint/type-utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz", - "integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", + "integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz", - "integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz", + "integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } @@ -21045,25 +21066,25 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz", - "integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz", + "integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz", - "integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", + "integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0" + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1" } }, "@typescript-eslint/type-utils": { @@ -21122,19 +21143,19 @@ } }, "@typescript-eslint/types": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", - "integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz", + "integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz", - "integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", + "integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -21233,12 +21254,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz", - "integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", + "integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/types": "5.59.1", "eslint-visitor-keys": "^3.3.0" } }, @@ -21354,7 +21375,9 @@ "requires": {} }, "@webpack-cli/serve": { - "version": "2.0.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.2.tgz", + "integrity": "sha512-S9h3GmOmzUseyeFW3tYNnWS7gNUuwxZ3mmMq0JyW78Vx1SGKPSkt5bT4pB0rUnVfHjP0EL9gW2bOzmtiTfQt0A==", "dev": true, "requires": {} }, @@ -24641,7 +24664,9 @@ } }, "html-to-pdfmake": { - "version": "2.4.16" + "version": "2.4.20", + "resolved": "https://registry.npmjs.org/html-to-pdfmake/-/html-to-pdfmake-2.4.20.tgz", + "integrity": "sha512-+tId1Lp3fMoOVdgD1jXeZqznnUXtsxFm3UH7yiMhgpFtY6jHjuNUPkIcjxC8SNnLe0UTX7R0F3vv5TZ23YM1kQ==" }, "html-webpack-plugin": { "version": "5.5.1", @@ -25356,7 +25381,9 @@ } }, "karma": { - "version": "6.4.1", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", + "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", "dev": true, "requires": { "@colors/colors": "1.5.0", @@ -25387,6 +25414,8 @@ "dependencies": { "cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -25396,6 +25425,8 @@ }, "glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -25408,14 +25439,20 @@ }, "mime": { "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true }, "source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -25429,6 +25466,8 @@ }, "yargs-parser": { "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } @@ -27448,9 +27487,9 @@ "version": "1.2.1" }, "prettier": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", - "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, "pretty-bytes": { @@ -28290,7 +28329,9 @@ } }, "slash": { - "version": "5.0.0" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.0.1.tgz", + "integrity": "sha512-ywNzUOiXwetmLvTUiCBZpLi+vxqN3i+zDqjs2HHfUSV3wN4UJxVVKWrS1JZDeiJIeBFNgB5pmioC2g0IUTL+rQ==" }, "slice-ansi": { "version": "5.0.0", @@ -29532,15 +29573,17 @@ } }, "webpack-cli": { - "version": "5.0.1", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.2.tgz", + "integrity": "sha512-4y3W5Dawri5+8dXm3+diW6Mn1Ya+Dei6eEVAdIduAmYNLzv1koKVAqsfgrrc9P2mhrYHQphx5htnGkcNwtubyQ==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.0.1", "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.1", + "@webpack-cli/serve": "^2.0.2", "colorette": "^2.0.14", - "commander": "^9.4.1", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", @@ -29548,6 +29591,14 @@ "interpret": "^3.1.1", "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + } } }, "webpack-dev-middleware": { diff --git a/package.json b/package.json index 0d3981ddfd..a6ffaa0275 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@denbi/cloud-portal-webapp", - "version": "4.683.0", + "version": "4.684.0", "description": "de.NBI Cloud Portal", "scripts": { "ng": "ng serve", @@ -19,18 +19,18 @@ "private": true, "dependencies": { "@angular-eslint/eslint-plugin": "^15.2.0", - "@angular/animations": "15.2.7", - "@angular/cdk": "15.2.7", - "@angular/common": "15.2.7", - "@angular/compiler": "15.2.7", - "@angular/core": "15.2.7", - "@angular/forms": "15.2.7", - "@angular/localize": "15.2.7", - "@angular/platform-browser": "15.2.7", - "@angular/platform-browser-dynamic": "15.2.7", - "@angular/router": "15.2.7", - "@angular/service-worker": "15.2.7", - "@angular/upgrade": "15.2.7", + "@angular/animations": "15.2.8", + "@angular/cdk": "15.2.8", + "@angular/common": "15.2.8", + "@angular/compiler": "15.2.8", + "@angular/core": "15.2.8", + "@angular/forms": "15.2.8", + "@angular/localize": "15.2.8", + "@angular/platform-browser": "15.2.8", + "@angular/platform-browser-dynamic": "15.2.8", + "@angular/router": "15.2.8", + "@angular/service-worker": "15.2.8", + "@angular/upgrade": "15.2.8", "@coreui/angular": "^4.3.4", "@coreui/coreui": "4.2.6", "@coreui/icons-angular": "^4.3.0", @@ -56,7 +56,7 @@ "file-saver": "2.0.5", "follow-redirects": "1.15.2", "globby": "13.1.4", - "html-to-pdfmake": "2.4.16", + "html-to-pdfmake": "2.4.20", "html2canvas": "1.4.1", "http-server": "14.1.1", "is-promise": "4.0.0", @@ -93,11 +93,11 @@ "@angular-eslint/schematics": "15.2.1", "@angular-eslint/template-parser": "15.2.1", "@angular/cli": "15.2.6", - "@angular/compiler-cli": "15.2.7", + "@angular/compiler-cli": "15.2.8", "@compodoc/compodoc": "1.1.19", "@playwright/test": "1.32.3", "@types/jasmine": "4.3.1", - "@types/node": "18.16.0", + "@types/node": "18.16.1", "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", "async": "3.2.4", @@ -114,13 +114,13 @@ "html-webpack-plugin": "5.5.1", "husky": "8.0.3", "json-loader": "0.5.7", - "karma": "6.4.1", + "karma": "6.4.2", "karma-chrome-launcher": "3.2.0", "less-loader": "11.1.0", "lint-staged": "13.2.1", "ngx-spec": "2.1.5", "npm-run-all": "4.1.5", - "prettier": "2.8.7", + "prettier": "2.8.8", "raw-loader": "4.0.2", "sass-loader": "13.2.2", "script-loader": "0.7.2", @@ -130,7 +130,7 @@ "ts-node": "10.9.1", "typescript": "4.9.5", "url-loader": "4.1.1", - "webpack-cli": "5.0.1" + "webpack-cli": "5.0.2" }, "lint-staged": { "*.{js,jsx,ts}": [