diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.html
index 3e179f7cd..3d4c0df44 100644
--- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.html
+++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.html
@@ -83,4 +83,10 @@
-
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts
index 98decd5b7..3a270ea0b 100644
--- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts
@@ -11,6 +11,8 @@ import {
placeholdersDescriptionsTranslations
} from '../../translations/placeholders-descriptions-translations';
import { removeBraces } from '../../../../utils/functions';
+import { Toaster } from '../../../../services/toaster.service';
+import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
interface Placeholder {
placeholder: string;
@@ -37,6 +39,7 @@ export class ReportsScreenComponent implements OnInit {
private readonly _appStateService: AppStateService,
private readonly _reportTemplateService: ReportTemplateControllerService,
private readonly _dialogService: AdminDialogService,
+ private readonly _toaster: Toaster,
private readonly _loadingService: LoadingService,
readonly permissionsService: PermissionsService
) {
@@ -81,9 +84,17 @@ export class ReportsScreenComponent implements OnInit {
private async _uploadTemplate($event) {
const file = $event.target.files[0];
- await this._reportTemplateService.uploadTemplateForm(this._appStateService.activeDossierTemplateId, file).toPromise();
- this._fileInput.nativeElement.value = null;
- await this._loadReportTemplates();
+
+ if (this._isValidFile(file)) {
+ await this._reportTemplateService.uploadTemplateForm(this._appStateService.activeDossierTemplateId, false, file).toPromise();
+ if (this._isExcelFile(file)) {
+ // await this._reportTemplateService.uploadTemplateForm(this._appStateService.activeDossierTemplateId, true, file).toPromise();
+ }
+ this._fileInput.nativeElement.value = null;
+ await this._loadReportTemplates();
+ } else {
+ this._toaster.error(_('reports-screen.invalid-upload'));
+ }
}
private async _deleteTemplate(template: ReportTemplate) {
@@ -109,4 +120,22 @@ export class ReportsScreenComponent implements OnInit {
}))
);
}
+
+ private _isValidFile(file: File): boolean {
+ return this._isExcelFile(file) || this._isWordFile(file);
+ }
+
+ private _isExcelFile(file: File): boolean {
+ return (
+ file.type?.toLowerCase() === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
+ file.name.toLowerCase().endsWith('.xlsx')
+ );
+ }
+
+ private _isWordFile(file: File): boolean {
+ return (
+ file.type?.toLowerCase() === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
+ file.name.toLowerCase().endsWith('.docx')
+ );
+ }
}
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index 19f8ecc86..69bec7dda 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -1192,6 +1192,7 @@
},
"reports": "Reports",
"reports-screen": {
+ "invalid-upload": "Invalid format selected for Upload! Supported formats are XLSX and DOCX",
"description": "A short text explaining how to create report documents. It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.",
"descriptions": {
"dossier-attributes": "This placeholder gets replaced with the value of the dossier attribute {attribute}.",
diff --git a/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts b/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts
index 53883c656..89726077f 100644
--- a/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts
+++ b/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts
@@ -16,17 +16,17 @@ import { CustomHttpUrlEncodingCodec } from '../encoder';
import { Observable } from 'rxjs';
+import { PlaceholdersResponse } from '../model/placeholdersResponse';
import { ReportTemplate } from '../model/reportTemplate';
import { BASE_PATH } from '../variables';
import { Configuration } from '../configuration';
-import { PlaceholdersResponse } from '../model/placeholdersResponse';
@Injectable()
export class ReportTemplateControllerService {
+ protected basePath = '';
public defaultHeaders = new HttpHeaders();
public configuration = new Configuration();
- protected basePath = '';
constructor(
protected httpClient: HttpClient,
@@ -42,6 +42,151 @@ export class ReportTemplateControllerService {
}
}
+ /**
+ * @param consumes string[] mime-types
+ * @return true: consumes contains 'multipart/form-data', false: otherwise
+ */
+ private canConsumeForm(consumes: string[]): boolean {
+ const form = 'multipart/form-data';
+ for (const consume of consumes) {
+ if (form === consume) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Delete template file for redaction-report
+ * None
+ * @param dossierTemplateId dossierTemplateId
+ * @param templateId templateId
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public deleteTemplate(dossierTemplateId: string, templateId: string, observe?: 'body', reportProgress?: boolean): Observable;
+ public deleteTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe?: 'response',
+ reportProgress?: boolean
+ ): Observable>;
+ public deleteTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe?: 'events',
+ reportProgress?: boolean
+ ): Observable>;
+ public deleteTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe: any = 'body',
+ reportProgress: boolean = false
+ ): Observable {
+ if (dossierTemplateId === null || dossierTemplateId === undefined) {
+ throw new Error('Required parameter dossierTemplateId was null or undefined when calling deleteTemplate.');
+ }
+
+ if (templateId === null || templateId === undefined) {
+ throw new Error('Required parameter templateId was null or undefined when calling deleteTemplate.');
+ }
+
+ let headers = this.defaultHeaders;
+
+ // authentication (RED-OAUTH) required
+ if (this.configuration.accessToken) {
+ const accessToken =
+ typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
+ headers = headers.set('Authorization', 'Bearer ' + accessToken);
+ }
+
+ // to determine the Accept header
+ const httpHeaderAccepts: string[] = [];
+ const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+ if (httpHeaderAcceptSelected !== undefined) {
+ headers = headers.set('Accept', httpHeaderAcceptSelected);
+ }
+
+ return this.httpClient.request(
+ 'delete',
+ `${this.basePath}/templateUpload/${encodeURIComponent(String(dossierTemplateId))}/${encodeURIComponent(String(templateId))}`,
+ {
+ withCredentials: this.configuration.withCredentials,
+ headers: headers,
+ observe: observe,
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * Download template file for redaction-report
+ * None
+ * @param dossierTemplateId dossierTemplateId
+ * @param templateId templateId
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public downloadReportTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe?: 'body',
+ reportProgress?: boolean
+ ): Observable;
+ public downloadReportTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe?: 'response',
+ reportProgress?: boolean
+ ): Observable>;
+ public downloadReportTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe?: 'events',
+ reportProgress?: boolean
+ ): Observable>;
+ public downloadReportTemplate(
+ dossierTemplateId: string,
+ templateId: string,
+ observe: any = 'body',
+ reportProgress: boolean = false
+ ): Observable {
+ if (dossierTemplateId === null || dossierTemplateId === undefined) {
+ throw new Error('Required parameter dossierTemplateId was null or undefined when calling downloadReportTemplate.');
+ }
+
+ if (templateId === null || templateId === undefined) {
+ throw new Error('Required parameter templateId was null or undefined when calling downloadReportTemplate.');
+ }
+
+ let headers = this.defaultHeaders;
+
+ // authentication (RED-OAUTH) required
+ if (this.configuration.accessToken) {
+ const accessToken =
+ typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
+ headers = headers.set('Authorization', 'Bearer ' + accessToken);
+ }
+
+ // to determine the Accept header
+ const httpHeaderAccepts: string[] = ['application/json'];
+ const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+ if (httpHeaderAcceptSelected !== undefined) {
+ headers = headers.set('Accept', httpHeaderAcceptSelected);
+ }
+
+ return this.httpClient.request(
+ 'get',
+ `${this.basePath}/templateUpload/${encodeURIComponent(String(dossierTemplateId))}/${encodeURIComponent(String(templateId))}`,
+ {
+ withCredentials: this.configuration.withCredentials,
+ headers: headers,
+ observe: observe,
+ reportProgress: reportProgress
+ }
+ );
+ }
+
/**
* Returns list of available placeholders
* None
@@ -97,144 +242,6 @@ export class ReportTemplateControllerService {
);
}
- /**
- * Delete template file for redaction-report
- * None
- * @param dossierTemplateId dossierTemplateId
- * @param templateId templateId
- * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
- * @param reportProgress flag to report request and response progress.
- */
- public deleteTemplate(dossierTemplateId: string, templateId: string, observe?: 'body', reportProgress?: boolean): Observable;
-
- public deleteTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe?: 'response',
- reportProgress?: boolean
- ): Observable>;
-
- public deleteTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe?: 'events',
- reportProgress?: boolean
- ): Observable>;
-
- public deleteTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe: any = 'body',
- reportProgress: boolean = false
- ): Observable {
- if (dossierTemplateId === null || dossierTemplateId === undefined) {
- throw new Error('Required parameter dossierTemplateId was null or undefined when calling deleteTemplate.');
- }
-
- if (templateId === null || templateId === undefined) {
- throw new Error('Required parameter templateId was null or undefined when calling deleteTemplate.');
- }
-
- let headers = this.defaultHeaders;
-
- // authentication (RED-OAUTH) required
- if (this.configuration.accessToken) {
- const accessToken =
- typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
- headers = headers.set('Authorization', 'Bearer ' + accessToken);
- }
-
- // to determine the Accept header
- const httpHeaderAccepts: string[] = [];
- const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
- if (httpHeaderAcceptSelected !== undefined) {
- headers = headers.set('Accept', httpHeaderAcceptSelected);
- }
-
- return this.httpClient.request(
- 'delete',
- `${this.basePath}/templateUpload/${encodeURIComponent(String(dossierTemplateId))}/${encodeURIComponent(String(templateId))}`,
- {
- withCredentials: this.configuration.withCredentials,
- headers: headers,
- observe: observe,
- reportProgress: reportProgress
- }
- );
- }
-
- /**
- * Download template file for redaction-report
- * None
- * @param dossierTemplateId dossierTemplateId
- * @param templateId templateId
- * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
- * @param reportProgress flag to report request and response progress.
- */
- public downloadReportTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe?: 'body',
- reportProgress?: boolean
- ): Observable;
-
- public downloadReportTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe?: 'response',
- reportProgress?: boolean
- ): Observable>;
-
- public downloadReportTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe?: 'events',
- reportProgress?: boolean
- ): Observable>;
-
- public downloadReportTemplate(
- dossierTemplateId: string,
- templateId: string,
- observe: any = 'body',
- reportProgress: boolean = false
- ): Observable {
- if (dossierTemplateId === null || dossierTemplateId === undefined) {
- throw new Error('Required parameter dossierTemplateId was null or undefined when calling downloadReportTemplate.');
- }
-
- if (templateId === null || templateId === undefined) {
- throw new Error('Required parameter templateId was null or undefined when calling downloadReportTemplate.');
- }
-
- let headers = this.defaultHeaders;
-
- // authentication (RED-OAUTH) required
- if (this.configuration.accessToken) {
- const accessToken =
- typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
- headers = headers.set('Authorization', 'Bearer ' + accessToken);
- }
-
- // to determine the Accept header
- const httpHeaderAccepts: string[] = ['application/json'];
- const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
- if (httpHeaderAcceptSelected !== undefined) {
- headers = headers.set('Accept', httpHeaderAcceptSelected);
- }
-
- return this.httpClient.request(
- 'get',
- `${this.basePath}/templateUpload/${encodeURIComponent(String(dossierTemplateId))}/${encodeURIComponent(String(templateId))}`,
- {
- withCredentials: this.configuration.withCredentials,
- responseType: 'blob',
- headers: headers,
- observe: observe,
- reportProgress: reportProgress
- }
- );
- }
-
/**
* Returns available templates for redaction-report
* None
@@ -247,19 +254,16 @@ export class ReportTemplateControllerService {
observe?: 'body',
reportProgress?: boolean
): Observable>;
-
public getAvailableReportTemplates(
dossierTemplateId: string,
observe?: 'response',
reportProgress?: boolean
): Observable>>;
-
public getAvailableReportTemplates(
dossierTemplateId: string,
observe?: 'events',
reportProgress?: boolean
): Observable>>;
-
public getAvailableReportTemplates(dossierTemplateId: string, observe: any = 'body', reportProgress: boolean = false): Observable {
if (dossierTemplateId === null || dossierTemplateId === undefined) {
throw new Error('Required parameter dossierTemplateId was null or undefined when calling getAvailableReportTemplates.');
@@ -297,33 +301,35 @@ export class ReportTemplateControllerService {
* Upload template file for redaction-report
* None
* @param dossierTemplateId The dossierTemplateId, the report template belongs to
+ * @param multiFileReport
* @param file
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public uploadTemplateForm(
dossierTemplateId: string,
+ multiFileReport?: boolean,
file?: Blob,
observe?: 'body',
reportProgress?: boolean
): Observable;
-
public uploadTemplateForm(
dossierTemplateId: string,
+ multiFileReport?: boolean,
file?: Blob,
observe?: 'response',
reportProgress?: boolean
): Observable>;
-
public uploadTemplateForm(
dossierTemplateId: string,
+ multiFileReport?: boolean,
file?: Blob,
observe?: 'events',
reportProgress?: boolean
): Observable>;
-
public uploadTemplateForm(
dossierTemplateId: string,
+ multiFileReport?: boolean,
file?: Blob,
observe: any = 'body',
reportProgress: boolean = false
@@ -365,6 +371,9 @@ export class ReportTemplateControllerService {
formParams = new HttpParams({ encoder: new CustomHttpUrlEncodingCodec() });
}
+ if (multiFileReport !== undefined) {
+ formParams = (formParams.append('multiFileReport', multiFileReport) as any) || formParams;
+ }
if (file !== undefined) {
formParams = (formParams.append('file', file) as any) || formParams;
}
@@ -381,18 +390,4 @@ export class ReportTemplateControllerService {
}
);
}
-
- /**
- * @param consumes string[] mime-types
- * @return true: consumes contains 'multipart/form-data', false: otherwise
- */
- private canConsumeForm(consumes: string[]): boolean {
- const form = 'multipart/form-data';
- for (const consume of consumes) {
- if (form === consume) {
- return true;
- }
- }
- return false;
- }
}
diff --git a/libs/red-ui-http/src/lib/model/notification.ts b/libs/red-ui-http/src/lib/model/notification.ts
index db999aeb3..0da921221 100644
--- a/libs/red-ui-http/src/lib/model/notification.ts
+++ b/libs/red-ui-http/src/lib/model/notification.ts
@@ -18,6 +18,6 @@ export interface Notification {
readDate?: string;
seenDate?: string;
softDeleted?: string;
- target?: any;
+ target?: string;
userId?: string;
}
diff --git a/libs/red-ui-http/src/lib/model/reportTemplate.ts b/libs/red-ui-http/src/lib/model/reportTemplate.ts
index 1490ce0b0..6271c26c4 100644
--- a/libs/red-ui-http/src/lib/model/reportTemplate.ts
+++ b/libs/red-ui-http/src/lib/model/reportTemplate.ts
@@ -13,6 +13,7 @@
export interface ReportTemplate {
dossierTemplateId?: string;
fileName?: string;
+ multiFileReport?: boolean;
storageId?: string;
templateId?: string;
uploadDate?: string;