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 80a3fe7c6..3e179f7cd 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
@@ -30,13 +30,14 @@
-
Placeholders
-
Description
+
+
- {{ getPlaceholderDisplayValue(placeholder) }}
-
- What is and how to use it in your document. The readable content of a page when looking at its layout must be nice.
-
+ {{ placeholder.placeholder }}
+
@@ -82,4 +83,4 @@
-
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.scss b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.scss
index 880dcd769..765202e19 100644
--- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.scss
+++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.scss
@@ -103,7 +103,6 @@
.placeholder {
font-weight: 600;
- text-transform: capitalize;
margin-left: 16px;
}
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 eaa07017e..98decd5b7 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
@@ -1,11 +1,25 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AppStateService } from '@state/app-state.service';
-import { ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http';
+import { PlaceholdersResponse, ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http';
import { download } from '../../../../utils/file-download-utils';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '@services/loading.service';
import { PermissionsService } from '@services/permissions.service';
+import {
+ generalPlaceholdersDescriptionsTranslations,
+ placeholdersDescriptionsTranslations
+} from '../../translations/placeholders-descriptions-translations';
+import { removeBraces } from '../../../../utils/functions';
+
+interface Placeholder {
+ placeholder: string;
+ descriptionTranslation: string;
+ attributeName?: string;
+}
+
+type PlaceholderType = 'generalPlaceholders' | 'fileAttributePlaceholders' | 'dossierAttributePlaceholders';
+const placeholderTypes: PlaceholderType[] = ['generalPlaceholders', 'fileAttributePlaceholders', 'dossierAttributePlaceholders'];
@Component({
selector: 'redaction-reports-screen',
@@ -13,7 +27,7 @@ import { PermissionsService } from '@services/permissions.service';
styleUrls: ['./reports-screen.component.scss']
})
export class ReportsScreenComponent implements OnInit {
- placeholders: string[] = ['report', 'predefined placeholder 1', 'signature 01', 'new attribute'];
+ placeholders: Placeholder[];
availableTemplates: ReportTemplate[];
@ViewChild('fileInput') private _fileInput: ElementRef;
@@ -29,45 +43,70 @@ export class ReportsScreenComponent implements OnInit {
this._appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
}
- getPlaceholderDisplayValue(placeholder: string): string {
- return `{{${placeholder}}}`;
- }
-
async ngOnInit() {
+ this._loadingService.start();
await this._loadReportTemplates();
+ await this._loadPlaceholders();
this._loadingService.stop();
}
- async uploadFile($event) {
- this._loadingService.start();
- const file = $event.target.files[0];
-
- await this._reportTemplateService.uploadTemplateForm(this._appStateService.activeDossierTemplateId, file).toPromise();
-
- this._fileInput.nativeElement.value = null;
- await this._loadReportTemplates();
+ async uploadTemplate($event) {
+ this._loadingService.loadWhile(this._uploadTemplate($event));
}
async download(template: ReportTemplate) {
+ this._loadingService.start();
const data = await this._reportTemplateService
.downloadReportTemplate(template.dossierTemplateId, template.templateId, 'response')
.toPromise();
+ this._loadingService.stop();
download(data, template.fileName);
}
deleteTemplate(template: ReportTemplate) {
this._dialogService.openDialog('confirm', null, null, async () => {
- this._loadingService.start();
- await this._reportTemplateService.deleteTemplate(template.dossierTemplateId, template.templateId).toPromise();
- await this._loadReportTemplates();
+ this._loadingService.loadWhile(this._deleteTemplate(template));
});
}
+ private _getAttributeName(placeholder: string): string {
+ return removeBraces(placeholder).split('.').pop();
+ }
+
+ private _getPlaceholderDescriptionTranslation(type: PlaceholderType, placeholder: string): string {
+ return type === 'generalPlaceholders'
+ ? generalPlaceholdersDescriptionsTranslations[removeBraces(placeholder)]
+ : placeholdersDescriptionsTranslations[type];
+ }
+
+ 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();
+ }
+
+ private async _deleteTemplate(template: ReportTemplate) {
+ await this._reportTemplateService.deleteTemplate(template.dossierTemplateId, template.templateId).toPromise();
+ await this._loadReportTemplates();
+ }
+
private async _loadReportTemplates() {
- this._loadingService.start();
this.availableTemplates = await this._reportTemplateService
.getAvailableReportTemplates(this._appStateService.activeDossierTemplateId)
.toPromise();
- this._loadingService.stop();
+ }
+
+ private async _loadPlaceholders() {
+ const placeholdersResponse: PlaceholdersResponse = await this._reportTemplateService
+ .getAvailablePlaceholders(this._appStateService.activeDossierTemplateId)
+ .toPromise();
+ this.placeholders = placeholderTypes.flatMap(type =>
+ placeholdersResponse[type].map(placeholder => ({
+ placeholder,
+ descriptionTranslation: this._getPlaceholderDescriptionTranslation(type, placeholder),
+ attributeName: this._getAttributeName(placeholder)
+ }))
+ );
}
}
diff --git a/apps/red-ui/src/app/modules/admin/translations/placeholders-descriptions-translations.ts b/apps/red-ui/src/app/modules/admin/translations/placeholders-descriptions-translations.ts
new file mode 100644
index 000000000..277cc012f
--- /dev/null
+++ b/apps/red-ui/src/app/modules/admin/translations/placeholders-descriptions-translations.ts
@@ -0,0 +1,18 @@
+import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+
+export const placeholdersDescriptionsTranslations: { [key: string]: string } = {
+ dossierAttributePlaceholders: _('reports-screen.descriptions.dossier-attributes'),
+ fileAttributePlaceholders: _('reports-screen.descriptions.file-attributes')
+};
+
+export const generalPlaceholdersDescriptionsTranslations: { [key: string]: string } = {
+ 'file.name': _('reports-screen.descriptions.general.file.name'),
+ 'redaction.page': _('reports-screen.descriptions.general.redaction.page'),
+ 'redaction.paragraph': _('reports-screen.descriptions.general.redaction.paragraph'),
+ 'redaction.justification': _('reports-screen.descriptions.general.redaction.justification'),
+ 'date.yyyy-MM-dd': _('reports-screen.descriptions.general.date.y-m-d'),
+ 'date.dd.MM.yyyy': _('reports-screen.descriptions.general.date.d-m-y'),
+ 'date.MM/dd/yyyy': _('reports-screen.descriptions.general.date.m-d-y'),
+ 'time.HH:mm': _('reports-screen.descriptions.general.time.h-m'),
+ 'dossier.name': _('reports-screen.descriptions.general.dossier.name')
+};
diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts
index 1bf96c3b0..c4a95a2c1 100644
--- a/apps/red-ui/src/app/utils/functions.ts
+++ b/apps/red-ui/src/app/utils/functions.ts
@@ -85,3 +85,7 @@ export function getLeftDateTime(ISOString: string) {
return { daysLeft, hoursLeft, minutesLeft };
}
+
+export function removeBraces(str: any): string {
+ return str.replace(/[{}]/g, '');
+}
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index 6f12c9bcd..19f8ecc86 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -1193,9 +1193,38 @@
"reports": "Reports",
"reports-screen": {
"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}.",
+ "file-attributes": "This placeholder gets replaced with the value of the file attribute {attribute}.",
+ "general": {
+ "date": {
+ "d-m-y": "?",
+ "m-d-y": "?",
+ "y-m-d": "?"
+ },
+ "dossier": {
+ "name": "?"
+ },
+ "file": {
+ "name": "?"
+ },
+ "redaction": {
+ "justification": "?",
+ "page": "?",
+ "paragraph": "?"
+ },
+ "time": {
+ "h-m": "?"
+ }
+ }
+ },
"document-setup-description": "A short text explaining what placeholders are and how to use them in your report template. It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.",
"document-setup-heading": "Document Setup",
"report-documents": "Report Documents",
+ "table-header": {
+ "description": "Description",
+ "placeholders": "Placeholders"
+ },
"title": "Reports",
"upload-document": "Upload a Document"
},
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 ad39fcf90..53883c656 100644
--- a/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts
+++ b/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts
@@ -20,6 +20,7 @@ import { ReportTemplate } from '../model/reportTemplate';
import { BASE_PATH } from '../variables';
import { Configuration } from '../configuration';
+import { PlaceholdersResponse } from '../model/placeholdersResponse';
@Injectable()
export class ReportTemplateControllerService {
@@ -41,6 +42,61 @@ export class ReportTemplateControllerService {
}
}
+ /**
+ * Returns list of available placeholders
+ * None
+ * @param dossierTemplateId dossierTemplateId
+ * @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 getAvailablePlaceholders(
+ dossierTemplateId: string,
+ observe?: 'body',
+ reportProgress?: boolean
+ ): Observable;
+ public getAvailablePlaceholders(
+ dossierTemplateId: string,
+ observe?: 'response',
+ reportProgress?: boolean
+ ): Observable>;
+ public getAvailablePlaceholders(
+ dossierTemplateId: string,
+ observe?: 'events',
+ reportProgress?: boolean
+ ): Observable>;
+ public getAvailablePlaceholders(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 getAvailablePlaceholders.');
+ }
+
+ 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}/placeholders/${encodeURIComponent(String(dossierTemplateId))}`,
+ {
+ withCredentials: this.configuration.withCredentials,
+ headers: headers,
+ observe: observe,
+ reportProgress: reportProgress
+ }
+ );
+ }
+
/**
* Delete template file for redaction-report
* None
diff --git a/libs/red-ui-http/src/lib/model/models.ts b/libs/red-ui-http/src/lib/model/models.ts
index a4aeed8e6..8e42e0fcf 100644
--- a/libs/red-ui-http/src/lib/model/models.ts
+++ b/libs/red-ui-http/src/lib/model/models.ts
@@ -79,3 +79,4 @@ export * from './manualLegalBasisChange';
export * from './searchRequest';
export * from './searchResult';
export * from './matchedDocument';
+export * from './placeholdersResponse';
diff --git a/libs/red-ui-http/src/lib/model/placeholdersResponse.ts b/libs/red-ui-http/src/lib/model/placeholdersResponse.ts
new file mode 100644
index 000000000..a5fa97016
--- /dev/null
+++ b/libs/red-ui-http/src/lib/model/placeholdersResponse.ts
@@ -0,0 +1,20 @@
+/**
+ * API Documentation for Redaction Gateway
+ * Description for redaction
+ *
+ * OpenAPI spec version: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+/**
+ * Object containing available placeholders.
+ */
+export interface PlaceholdersResponse {
+ dossierAttributePlaceholders?: Array;
+ fileAttributePlaceholders?: Array;
+ generalPlaceholders?: Array;
+}