RED-10064: added id on report container for hover + component refactor.
This commit is contained in:
parent
5bb7c780a1
commit
b3de35eac7
@ -2,67 +2,74 @@
|
||||
<div [translate]="'reports-screen.title'" class="heading-xl"></div>
|
||||
|
||||
<div [translate]="'reports-screen.setup'" class="description"></div>
|
||||
<div *ngIf="!isDocumine" [translate]="'reports-screen.description'" class="description"></div>
|
||||
|
||||
<div *ngIf="!isDocumine && placeholders$ | async as placeholders" class="placeholders">
|
||||
<div [translate]="'reports-screen.table-header.placeholders'" class="all-caps-label"></div>
|
||||
<div [translate]="'reports-screen.table-header.description'" class="all-caps-label"></div>
|
||||
<ng-container *ngFor="let placeholder of placeholders">
|
||||
<div class="placeholder">{{ placeholder.placeholder }}</div>
|
||||
<div
|
||||
[innerHTML]="placeholder.descriptionTranslation | translate: { attribute: placeholder.attributeName }"
|
||||
class="description"
|
||||
></div>
|
||||
</ng-container>
|
||||
</div>
|
||||
@if (!isDocumine) {
|
||||
<div [translate]="'reports-screen.description'" class="description"></div>
|
||||
}
|
||||
@if (!isDocumine && placeholders$ | async; as placeholders) {
|
||||
<div class="placeholders">
|
||||
<div [translate]="'reports-screen.table-header.placeholders'" class="all-caps-label"></div>
|
||||
<div [translate]="'reports-screen.table-header.description'" class="all-caps-label"></div>
|
||||
@for (placeholder of placeholders; track placeholder.placeholder) {
|
||||
<div class="placeholder">{{ placeholder.placeholder }}</div>
|
||||
<div
|
||||
[innerHTML]="placeholder.descriptionTranslation | translate: { attribute: placeholder.attributeName }"
|
||||
class="description"
|
||||
></div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div *ngIf="availableTemplates$ | async as availableTemplates" class="right-container" iqserHasScrollbar>
|
||||
<div class="header">
|
||||
<div [translate]="'reports-screen.report-documents'" class="heading"></div>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="fileInput.click()"
|
||||
*allow="roles.reportTemplates.upload; if: currentUser.isAdmin"
|
||||
[tooltip]="'reports-screen.upload-document' | translate"
|
||||
[attr.help-mode-key]="'upload_report'"
|
||||
[buttonId]="'upload_report'"
|
||||
icon="iqser:upload"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
(click)="fileInput.click()"
|
||||
*allow="roles.reportTemplates.upload; if: currentUser.isAdmin && !availableTemplates?.length"
|
||||
[translate]="'reports-screen.upload-document'"
|
||||
class="template upload-button"
|
||||
></div>
|
||||
|
||||
<div *ngFor="let template of availableTemplates" class="template">
|
||||
<div class="name">
|
||||
{{ template.fileName }} {{ template.multiFileReport ? ('reports-screen.multi-file-report' | translate) : '' }}
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<iqser-circle-button
|
||||
(action)="download(template)"
|
||||
*allow="roles.reportTemplates.download"
|
||||
[buttonId]="(template.fileName | snakeCase) + '-download-button'"
|
||||
[iconSize]="12"
|
||||
[size]="18"
|
||||
icon="iqser:download"
|
||||
></iqser-circle-button>
|
||||
@if (availableTemplates$ | async; as availableTemplates) {
|
||||
<div class="right-container" iqserHasScrollbar>
|
||||
<div class="header">
|
||||
<div [translate]="'reports-screen.report-documents'" class="heading"></div>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="deleteTemplate(template)"
|
||||
*allow="roles.reportTemplates.delete; if: currentUser.isAdmin"
|
||||
[buttonId]="(template.fileName | snakeCase) + '-delete-button'"
|
||||
[iconSize]="12"
|
||||
[size]="18"
|
||||
icon="iqser:trash"
|
||||
(action)="fileInput.click()"
|
||||
*allow="roles.reportTemplates.upload; if: currentUser.isAdmin"
|
||||
[tooltip]="'reports-screen.upload-document' | translate"
|
||||
[attr.help-mode-key]="'upload_report'"
|
||||
[buttonId]="'upload_report'"
|
||||
icon="iqser:upload"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
(click)="fileInput.click()"
|
||||
*allow="roles.reportTemplates.upload; if: currentUser.isAdmin && !availableTemplates?.length"
|
||||
[translate]="'reports-screen.upload-document'"
|
||||
class="template upload-button"
|
||||
></div>
|
||||
|
||||
@for (template of availableTemplates; track template.templateId) {
|
||||
<div [id]="template.fileName | snakeCase" class="template">
|
||||
<div class="name">
|
||||
{{ template.fileName }}
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<iqser-circle-button
|
||||
(action)="download(template)"
|
||||
*allow="roles.reportTemplates.download"
|
||||
[buttonId]="(template.fileName | snakeCase) + '-download-button'"
|
||||
[iconSize]="12"
|
||||
[size]="18"
|
||||
icon="iqser:download"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="deleteTemplate(template)"
|
||||
*allow="roles.reportTemplates.delete; if: currentUser.isAdmin"
|
||||
[buttonId]="(template.fileName | snakeCase) + '-delete-button'"
|
||||
[iconSize]="12"
|
||||
[size]="18"
|
||||
icon="iqser:trash"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<input #fileInput (change)="uploadTemplate($event)" hidden type="file" />
|
||||
|
||||
@ -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<Placeholder[]>([]);
|
||||
readonly availableTemplates$ = new BehaviorSubject<IReportTemplate[]>([]);
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = Roles;
|
||||
readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly #translateService = inject(TranslateService);
|
||||
private readonly _fileInput = viewChild<ElementRef>('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<void> {
|
||||
#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<void> {
|
||||
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<void> {
|
||||
async #uploadTemplateForm(file: File, multiFileReport: boolean): Promise<void> {
|
||||
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')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user