Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
dweinholz committed Aug 15, 2023
2 parents bc71c58 + 4ba5677 commit 15382c6
Show file tree
Hide file tree
Showing 20 changed files with 1,653 additions and 1,064 deletions.
1,453 changes: 850 additions & 603 deletions package-lock.json

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@denbi/cloud-portal-webapp",
"version": "4.736.0",
"version": "4.749.0",
"description": "de.NBI Cloud Portal",
"scripts": {
"ng": "ng serve",
Expand All @@ -19,32 +19,32 @@
"private": true,
"dependencies": {
"@angular-eslint/eslint-plugin": "^16.0.3",
"@angular/animations": "16.1.7",
"@angular/cdk": "16.1.6",
"@angular/common": "16.1.7",
"@angular/compiler": "16.1.7",
"@angular/core": "16.1.7",
"@angular/forms": "16.1.7",
"@angular/localize": "16.1.7",
"@angular/platform-browser": "16.1.7",
"@angular/platform-browser-dynamic": "16.1.7",
"@angular/router": "16.1.7",
"@angular/service-worker": "16.1.7",
"@angular/upgrade": "16.1.7",
"@coreui/angular": "4.5.10",
"@angular/animations": "16.1.9",
"@angular/cdk": "16.1.8",
"@angular/common": "16.1.9",
"@angular/compiler": "16.1.9",
"@angular/core": "16.1.9",
"@angular/forms": "16.1.9",
"@angular/localize": "16.1.9",
"@angular/platform-browser": "16.1.9",
"@angular/platform-browser-dynamic": "16.1.9",
"@angular/router": "16.1.9",
"@angular/service-worker": "16.1.9",
"@angular/upgrade": "16.1.9",
"@coreui/angular": "4.5.14",
"@coreui/coreui": "4.2.6",
"@coreui/icons-angular": "4.5.8",
"@coreui/icons-angular": "4.5.13",
"@ng-bootstrap/ng-bootstrap": "^15.0.1",
"@ng-select/ng-select": "^11.0.0",
"@sindresorhus/transliterate": "1.6.0",
"@types/d3": "7.4.0",
"@types/jquery": "3.5.16",
"acorn": "8.10.0",
"ajv-formats": "2.1.1",
"angulartics2": "12.2.0",
"billboard.js": "3.9.1",
"angulartics2": "12.2.1",
"billboard.js": "3.9.3",
"bootstrap": "4.6.2",
"chart.js": "4.3.2",
"chart.js": "4.3.3",
"cli-color": "2.0.3",
"core-js": "3.32.0",
"css-loader": "6.8.1",
Expand Down Expand Up @@ -86,20 +86,20 @@
"@angular-eslint/schematics": "16.1.0",
"@angular-eslint/template-parser": "16.1.0",
"@angular/cli": "^16.1.4",
"@angular/compiler-cli": "16.1.7",
"@angular/compiler-cli": "16.1.9",
"@compodoc/compodoc": "1.1.21",
"@playwright/test": "1.36.2",
"@types/jasmine": "4.3.5",
"@types/node": "18.17.1",
"@types/node": "18.17.5",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"async": "3.2.4",
"audit-ci": "6.6.1",
"autoprefixer": "10.4.14",
"autoprefixer": "10.4.15",
"eslint": "^8.44.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jsdoc": "46.4.5",
"eslint-plugin-jsdoc": "46.4.6",
"eslint-plugin-no-null": "latest",
"eslint-plugin-prefer-arrow": "1.2.3",
"exports-loader": "4.0.0",
Expand All @@ -110,10 +110,10 @@
"karma": "6.4.2",
"karma-chrome-launcher": "3.2.0",
"less-loader": "11.1.3",
"lint-staged": "13.2.3",
"lint-staged": "14.0.0",
"ngx-spec": "2.1.6",
"npm-run-all": "4.1.5",
"prettier": "3.0.0",
"prettier": "3.0.1",
"raw-loader": "4.0.2",
"sass-loader": "13.3.2",
"script-loader": "0.7.2",
Expand Down
37 changes: 36 additions & 1 deletion src/app/api-connector/email.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { ApiSettings } from './api-settings.service';
import { IResponseTemplate } from './response-template';
import { CsvMailTemplateModel } from '../shared/classes/csvMailTemplate.model';

/**
* Service which provides methods for Flavors.
*/
@Injectable()
@Injectable({
providedIn: 'root',
})
export class EmailService {
constructor(private http: HttpClient) {}

Expand All @@ -17,6 +20,38 @@ export class EmailService {
});
}

sendCsvTemplate(csvFile: File): Observable<CsvMailTemplateModel> {
const formData = new FormData();
formData.append('csv_file', csvFile, csvFile.name);

return this.http.post<CsvMailTemplateModel>(`${ApiSettings.getApiBaseURL()}emails/templated/csv/`, formData, {
withCredentials: true,
});
}

sendCsvTemplatedMail(
csvFile: File,
projectIds: (string | number)[],
subject: string,
message: string,
adminsOnly: boolean,
reply?: string,
): Observable<IResponseTemplate> {
const formData = new FormData();
formData.append('csv_file', csvFile, csvFile.name);
formData.append('project_ids', JSON.stringify(projectIds));
formData.append('subject', subject);
formData.append('message', message);
formData.append('adminsOnly', String(adminsOnly));
if (reply !== undefined) {
formData.append('reply', reply);
}

return this.http.post<IResponseTemplate>(`${ApiSettings.getApiBaseURL()}emails/templated/csv/projects/`, formData, {
withCredentials: true,
});
}

sendMailToProjects(
projectIds: (string | number)[],
subject: string,
Expand Down
28 changes: 17 additions & 11 deletions src/app/facility_manager/facilityprojectsoverview.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@
Send email
</button>
</div>
<div class="col-md-2">
<button
(click)="getFacilitySupportMails(); computeCenterSupportModal.show()"
type="button"
class="btn btn-outline-primary float-right"
>
<i class="fa fa-inbox"></i>
Support email(s)
</button>
</div>
<div class="col-md-2">
<input type="file" accept=".csv" style="display: none" #fileInput (change)="onCsvFileSelected($event)" />
<button type="button " class="btn btn-outline-primary" (click)="fileInput.click()">
Send CSV Templated Email
</button>
</div>
<div class="col-md-2">
<button
(click)="openProjectMailsModal()"
Expand All @@ -49,7 +65,7 @@
</c-badge>
</button>
</div>
<div class="col-md-6" style="margin-bottom: 10px">
<div class="col-md-4" style="margin-bottom: 10px">
<select
[(ngModel)]="selectedFacility"
(ngModelChange)="onChangeSelectedFacility()"
Expand All @@ -61,16 +77,6 @@
</option>
</select>
</div>
<div class="col-md-2">
<button
(click)="getFacilitySupportMails(); computeCenterSupportModal.show()"
type="button"
class="btn btn-outline-primary float-right"
>
<i class="fa fa-inbox"></i>
Support email(s)
</button>
</div>
</div>
<div class="card">
<div class="card-header"><i class="fa fa-align-justify"></i> Projects</div>
Expand Down
31 changes: 29 additions & 2 deletions src/app/facility_manager/facilityprojectsoverview.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { AbstractBaseClass } from '../shared/shared_modules/baseClass/abstract-b
import { ProjectEmailModalComponent } from '../shared/modal/email/project-email-modal/project-email-modal.component';
import { NotificationModalComponent } from '../shared/modal/notification-modal';
import { MembersListModalComponent } from '../shared/modal/members/members-list-modal.component';
import { EmailService } from '../api-connector/email.service';
import { CsvMailTemplateModel } from '../shared/classes/csvMailTemplate.model';

/**
* Facility Project overview component.
Expand Down Expand Up @@ -95,6 +97,7 @@ export class FacilityProjectsOverviewComponent extends AbstractBaseClass impleme
private newsService: NewsService,
public sortProjectService: ProjectSortService,
private modalService: BsModalService,
private emailService: EmailService,
) {
super();
}
Expand Down Expand Up @@ -155,6 +158,21 @@ export class FacilityProjectsOverviewComponent extends AbstractBaseClass impleme
}); * */
}

onCsvFileSelected(event): void {
const inputElement = event.target as HTMLInputElement;
if (inputElement.files && inputElement.files.length > 0) {
this.emailService.sendCsvTemplate(inputElement.files[0]).subscribe(
(csvTemplate: CsvMailTemplateModel) => {
this.openProjectMailsModal(inputElement.files[0], csvTemplate);
},
(error: CsvMailTemplateModel) => {
console.log(error['error']);
this.openProjectMailsModal(inputElement.files[0], error['error']);
},
);
}
}

onSort({ column, direction }: SortEvent) {
// resetting other headers
this.headers.forEach(header => {
Expand Down Expand Up @@ -442,9 +460,18 @@ export class FacilityProjectsOverviewComponent extends AbstractBaseClass impleme
});
}

openProjectMailsModal(): void {
const initialState = { selectedProjects: this.selectedEmailProjects };
openProjectMailsModal(csvFile: File = null, csvTemplate: CsvMailTemplateModel = null): void {
let initialState = {};

if (csvFile) {
initialState = {
selectedProjects: csvTemplate.valid_projects,
csvFile,
csvMailTemplate: csvTemplate,
};
} else {
initialState = { selectedProjects: this.selectedEmailProjects };
}
this.bsModalRef = this.modalService.show(ProjectEmailModalComponent, { initialState, class: 'modal-lg' });
this.bsModalRef.content.event.subscribe((sent_successfully: boolean) => {
if (sent_successfully) {
Expand Down
8 changes: 8 additions & 0 deletions src/app/shared/classes/csvMailTemplate.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Application } from '../../applications/application.model/application.model';

export class CsvMailTemplateModel {
errors: string[] = [];
warnings: string[] = [];
valid_projects: Application[] = [];
keys: string[] = [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,52 @@ <h4 class="modal-title" data-test-id="confirmation_modal_title">Sent Mail to spe
<span aria-hidden="true">&times;</span>
</button>
</div>

<div class="modal-body">
<div>
Send Mail to:
<ul>
<li *ngFor="let pr of selectedProjects">{{ pr.project_application_shortname }}</li>
</ul>
</div>
<div class="modal-body" *ngIf="csvMailTemplate?.errors?.length > 0">
<div class="alert alert-danger">
<p><strong>Error!</strong> Unable to use the CSV file "{{ csvFile.name }}". The following errors occurred:</p>

<ul>
<li *ngFor="let err of csvMailTemplate?.errors">{{ err }}</li>
</ul>
</div>
<div class="valid-example">
<p class="valid-example-heading">
<strong>Valid Example:</strong>
</p>
<pre class="valid-example-content">{{ validCSVExample }}</pre>
</div>
</div>

<div class="alert alert-warning" *ngIf="csvMailTemplate?.warnings.length > 0">
<p>
<strong>Warning!</strong> The following issues were found in the CSV file, but sending emails is still possible:
</p>

<ul>
<li *ngFor="let war of csvMailTemplate?.warnings">{{ war }}</li>
</ul>
</div>

<form class="form-horizontal" id="email_form" #f="ngForm">
<div class="form-group row">
<div class="col-md-auto">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="emailAdminsOnly" [(ngModel)]="emailAdminsOnly" id="adminOnlyCheckbox" />
<input
class="form-check-input"
type="checkbox"
name="emailAdminsOnly"
[(ngModel)]="emailAdminsOnly"
id="adminOnlyCheckbox"
[disabled]="csvMailTemplate?.errors?.length > 0"
/>
<label class="form-check-label" for="adminOnlyCheckbox"> Group administrators only </label>
</div>
</div>
Expand All @@ -37,6 +71,7 @@ <h4 class="modal-title" data-test-id="confirmation_modal_title">Sent Mail to spe
class="form-control"
type="text"
[(ngModel)]="emailSubject"
[disabled]="csvMailTemplate?.errors?.length > 0"
minlength="1"
#emailSub="ngModel"
[ngClass]="{
Expand All @@ -57,6 +92,7 @@ <h4 class="modal-title" data-test-id="confirmation_modal_title">Sent Mail to spe
class="form-control"
type="text"
[(ngModel)]="emailReply"
[disabled]="csvMailTemplate?.errors.length > 0"
#emailRep="ngModel"
pattern="([ ]*)(?!(^[.-].*|[^@]*[.-]@|.*\.{2,}.*)|^.{254}.)([a-zA-Z0-9!#$%&'*+\/=?^_`{|}~.-]+@)(?!-.*|.*-\.)([a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,15}([ ]*)"
[ngClass]="{
Expand All @@ -77,6 +113,7 @@ <h4 class="modal-title" data-test-id="confirmation_modal_title">Sent Mail to spe
id="emailText"
name="emailText"
[(ngModel)]="emailText"
[disabled]="csvMailTemplate?.errors?.length > 0"
type="text"
#emailT="ngModel"
[ngClass]="{
Expand All @@ -87,12 +124,22 @@ <h4 class="modal-title" data-test-id="confirmation_modal_title">Sent Mail to spe
</div>
</div>
</form>
<div class="templates-container" *ngIf="csvFile">
<p>
The following keys were provided by the CSV file: <strong>{{ csvFile.name }}</strong>
</p>
<div class="templates-list">
<span *ngFor="let template of csvMailTemplate?.keys">{{ '{' + template + '}' }} </span>
</div>
</div>

<div class="templates-container">
<p>The following keys can be used as variables:</p>
<p>You can use the following keys as variables:</p>
<div class="templates-list">
<span *ngFor="let template of templates">{{ '{' + template + '}' }}, </span>
<span *ngFor="let template of templates">{{ '{' + template + '}' }} </span>
</div>
</div>

<div class="alert alert-info">
Please consider: In case any dates are part of the sent E-Mails, they will be formatted in the german
<strong>TT.MM.YYYY</strong>-format.
Expand All @@ -108,11 +155,21 @@ <h4 class="modal-title" data-test-id="confirmation_modal_title">Sent Mail to spe
Abort & Close
</button>
<button
*ngIf="!csvMailTemplate"
class="btn btn-success col-md-4"
[disabled]="f.invalid"
[disabled]="f.invalid || csvMailTemplate?.errors?.length > 0"
data-test-id="confirm_confirmation_modal_btn"
(click)="sentProjectsMail(); bsModalRef.hide()"
>
Sent Mail
</button>
<button
*ngIf="csvMailTemplate && csvFile"
class="btn btn-success col-md-4"
[disabled]="f.invalid || csvMailTemplate?.errors?.length > 0"
data-test-id="confirm_confirmation_modal_btn"
(click)="sentProjectsTemplatedMail(); bsModalRef.hide()"
>
Sent Mail
</button>
</div>
Loading

0 comments on commit 15382c6

Please sign in to comment.