-
- {{ template.fileName }} {{ template.multiFileReport ? ('reports-screen.multi-file-report' | translate) : '' }}
-
-
-
-
+@if (availableTemplates$ | async; as availableTemplates) {
+
+
+
+
+
+ @for (template of availableTemplates; track template.templateId) {
+
+
+ {{ template.fileName }}
+
+
+
+
+
+
+
+
+ }
-
+}
diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts
index edc4dfa90..814fbc2da 100644
--- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import { ChangeDetectionStrategy, Component, ElementRef, inject, OnInit, viewChild } from '@angular/core';
import { DOSSIER_TEMPLATE_ID, IPlaceholdersResponse, IReportTemplate, User } from '@red/domain';
import { download } from '@utils/file-download-utils';
import {
@@ -23,8 +23,8 @@ import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam } from '@iqser/common-ui/lib/utils';
-import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
-import { TranslateModule } from '@ngx-translate/core';
+import { AsyncPipe } from '@angular/common';
+import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { SnakeCasePipe } from '@common-ui/pipes/snake-case.pipe';
interface Placeholder {
@@ -42,15 +42,16 @@ const placeholderTypes: PlaceholderType[] = ['generalPlaceholders', 'fileAttribu
styleUrls: ['./reports-screen.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
- imports: [HasScrollbarDirective, NgIf, NgForOf, AsyncPipe, TranslateModule, CircleButtonComponent, IqserAllowDirective, SnakeCasePipe],
+ imports: [HasScrollbarDirective, AsyncPipe, TranslateModule, CircleButtonComponent, IqserAllowDirective, SnakeCasePipe],
})
export default class ReportsScreenComponent implements OnInit {
- @ViewChild('fileInput') private readonly _fileInput: ElementRef;
readonly placeholders$ = new BehaviorSubject
([]);
readonly availableTemplates$ = new BehaviorSubject([]);
readonly currentUser = getCurrentUser();
readonly roles = Roles;
readonly isDocumine = getConfig().IS_DOCUMINE;
+ readonly #translateService = inject(TranslateService);
+ private readonly _fileInput = viewChild('fileInput');
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
@@ -63,8 +64,8 @@ export default class ReportsScreenComponent implements OnInit {
async ngOnInit() {
this._loadingService.start();
- await this._loadReportTemplates();
- await this._loadPlaceholders();
+ await this.#loadReportTemplates();
+ await this.#loadPlaceholders();
this._loadingService.stop();
}
@@ -84,14 +85,14 @@ export default class ReportsScreenComponent implements OnInit {
deleteTemplate(template: IReportTemplate) {
this._dialogService.openDialog('confirm', null, () => {
- this._loadingService.loadWhile(this._deleteTemplate(template));
+ this._loadingService.loadWhile(this.#deleteTemplate(template));
});
}
uploadTemplate($event) {
const file: File = $event.target.files[0];
- if (!this._isValidFile(file)) {
+ if (!this.#isValidFile(file)) {
this._toaster.error(_('reports-screen.invalid-upload'));
return;
}
@@ -115,27 +116,31 @@ export default class ReportsScreenComponent implements OnInit {
template => template.fileName === file.name && template.multiFileReport === multiFileReport,
)
) {
- await this._openOverwriteConfirmationDialog(file, multiFileReport);
+ await this.#openOverwriteConfirmationDialog(file, multiFileReport);
} else {
- await this._uploadTemplateForm(file, multiFileReport);
+ await this.#uploadTemplateForm(file, multiFileReport);
}
}
});
- this._fileInput.nativeElement.value = null;
+ this._fileInput().nativeElement.value = null;
}
- private _getAttributeName(placeholder: string): string {
+ #getAttributeName(placeholder: string): string {
return removeBraces(placeholder).split('.').pop();
}
- private _getPlaceholderDescriptionTranslation(type: PlaceholderType, placeholder: string): string {
+ #getPlaceholderDescriptionTranslation(type: PlaceholderType, placeholder: string): string {
return type === 'generalPlaceholders'
? generalPlaceholdersDescriptionsTranslations[removeBraces(placeholder)]
: placeholdersDescriptionsTranslations[type];
}
- private async _openOverwriteConfirmationDialog(file: File, multiFileReport: boolean): Promise {
+ #getTemplateFilename(template: IReportTemplate): string {
+ return `${template.fileName} ${template.multiFileReport ? this.#translateService.instant(_('reports-screen.multi-file-report')) : ''}`.trim();
+ }
+
+ async #openOverwriteConfirmationDialog(file: File, multiFileReport: boolean): Promise {
const data: IConfirmationDialogData = {
title: _('confirmation-dialog.report-template-same-name.title'),
question: _('confirmation-dialog.report-template-same-name.question'),
@@ -148,29 +153,34 @@ export default class ReportsScreenComponent implements OnInit {
this._dialogService.openDialog('confirm', data, null, async result => {
if (result) {
- await this._uploadTemplateForm(file, multiFileReport);
+ await this.#uploadTemplateForm(file, multiFileReport);
}
});
}
- private async _uploadTemplateForm(file: File, multiFileReport: boolean): Promise {
+ async #uploadTemplateForm(file: File, multiFileReport: boolean): Promise {
this._loadingService.start();
await firstValueFrom(this._reportTemplateService.uploadTemplateForm(this.#dossierTemplateId, multiFileReport, file));
- await this._loadReportTemplates();
+ await this.#loadReportTemplates();
this._loadingService.stop();
}
- private async _deleteTemplate(template: IReportTemplate) {
+ async #deleteTemplate(template: IReportTemplate) {
await firstValueFrom(this._reportTemplateService.delete(template.dossierTemplateId, template.templateId));
- await this._loadReportTemplates();
+ await this.#loadReportTemplates();
}
- private async _loadReportTemplates() {
+ async #loadReportTemplates() {
const reportTemplates = await this._reportTemplateService.getAvailableReportTemplates(this.#dossierTemplateId);
- this.availableTemplates$.next(reportTemplates);
+ this.availableTemplates$.next(
+ reportTemplates.map(template => ({
+ ...template,
+ fileName: this.#getTemplateFilename(template),
+ })),
+ );
}
- private async _loadPlaceholders() {
+ async #loadPlaceholders() {
const placeholdersResponse: IPlaceholdersResponse = await firstValueFrom(
this._reportTemplateService.getAvailablePlaceholders(this.#dossierTemplateId),
);
@@ -178,25 +188,25 @@ export default class ReportsScreenComponent implements OnInit {
placeholderTypes.flatMap(type =>
placeholdersResponse[type].map(placeholder => ({
placeholder,
- descriptionTranslation: this._getPlaceholderDescriptionTranslation(type, placeholder),
- attributeName: this._getAttributeName(placeholder),
+ descriptionTranslation: this.#getPlaceholderDescriptionTranslation(type, placeholder),
+ attributeName: this.#getAttributeName(placeholder),
})),
),
);
}
- private _isValidFile(file: File): boolean {
- return this._isExcelFile(file) || this._isWordFile(file);
+ #isValidFile(file: File): boolean {
+ return this.#isExcelFile(file) || this.#isWordFile(file);
}
- private _isExcelFile(file: File): boolean {
+ #isExcelFile(file: File): boolean {
return (
file.type?.toLowerCase() === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
file.name.toLowerCase().endsWith('.xlsx')
);
}
- private _isWordFile(file: File): boolean {
+ #isWordFile(file: File): boolean {
return (
file.type?.toLowerCase() === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
file.name.toLowerCase().endsWith('.docx')