Reports module

This commit is contained in:
Adina Țeudan 2022-02-07 15:02:55 +02:00
parent 7d818cb996
commit d3bd8484b2
18 changed files with 118 additions and 124 deletions

View File

@ -1,5 +1,5 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
@use 'libs/common-ui/src/assets/styles/common-mixins'; @use 'common-mixins';
.content-container { .content-container {
background-color: variables.$grey-2; background-color: variables.$grey-2;

View File

@ -1,5 +1,5 @@
@use 'variables'; @use 'variables';
@use 'libs/common-ui/src/assets/styles/common-mixins'; @use 'common-mixins';
.dialog-content { .dialog-content {
flex-direction: column; flex-direction: column;

View File

@ -13,7 +13,6 @@ import { LicenseInformationScreenComponent } from './screens/license-information
import { DigitalSignatureScreenComponent } from './screens/digital-signature/digital-signature-screen.component'; import { DigitalSignatureScreenComponent } from './screens/digital-signature/digital-signature-screen.component';
import { AuditScreenComponent } from './screens/audit/audit-screen.component'; import { AuditScreenComponent } from './screens/audit/audit-screen.component';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { ReportsScreenComponent } from './screens/reports/reports-screen.component';
import { DossierAttributesListingScreenComponent } from './screens/dossier-attributes-listing/dossier-attributes-listing-screen.component'; import { DossierAttributesListingScreenComponent } from './screens/dossier-attributes-listing/dossier-attributes-listing-screen.component';
import { TrashScreenComponent } from './screens/trash/trash-screen.component'; import { TrashScreenComponent } from './screens/trash/trash-screen.component';
import { GeneralConfigScreenComponent } from './screens/general-config/general-config-screen.component'; import { GeneralConfigScreenComponent } from './screens/general-config/general-config-screen.component';
@ -97,11 +96,12 @@ const routes: Routes = [
}, },
{ {
path: 'reports', path: 'reports',
component: ReportsScreenComponent, component: BaseDossierTemplateScreenComponent,
canActivate: [CompositeRouteGuard], canActivate: [CompositeRouteGuard],
data: { data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard], routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
}, },
loadChildren: () => import('./screens/reports/reports.module').then(m => m.ReportsModule),
}, },
{ {
path: 'dossier-attributes', path: 'dossier-attributes',

View File

@ -29,7 +29,6 @@ import { FileAttributesCsvImportDialogComponent } from './dialogs/file-attribute
import { ActiveFieldsListingComponent } from './dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component'; import { ActiveFieldsListingComponent } from './dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component';
import { AdminSideNavComponent } from './admin-side-nav/admin-side-nav.component'; import { AdminSideNavComponent } from './admin-side-nav/admin-side-nav.component';
import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
import { ReportsScreenComponent } from './screens/reports/reports-screen.component';
import { ResetPasswordComponent } from './dialogs/add-edit-user-dialog/reset-password/reset-password.component'; import { ResetPasswordComponent } from './dialogs/add-edit-user-dialog/reset-password/reset-password.component';
import { UserDetailsComponent } from './dialogs/add-edit-user-dialog/user-details/user-details.component'; import { UserDetailsComponent } from './dialogs/add-edit-user-dialog/user-details/user-details.component';
import { AddEditDossierAttributeDialogComponent } from './dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component'; import { AddEditDossierAttributeDialogComponent } from './dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component';
@ -73,7 +72,6 @@ const screens = [
LicenseInformationScreenComponent, LicenseInformationScreenComponent,
UserListingScreenComponent, UserListingScreenComponent,
GeneralConfigScreenComponent, GeneralConfigScreenComponent,
ReportsScreenComponent,
DossierAttributesListingScreenComponent, DossierAttributesListingScreenComponent,
TrashScreenComponent, TrashScreenComponent,
]; ];

View File

@ -1,88 +0,0 @@
<section>
<div class="page-header">
<redaction-dossier-template-breadcrumbs class="flex-1"></redaction-dossier-template-breadcrumbs>
<div class="actions flex-1">
<redaction-dossier-template-actions></redaction-dossier-template-actions>
<iqser-circle-button
[routerLink]="['../..']"
[tooltip]="'common.close' | translate"
icon="iqser:close"
tooltipPosition="below"
></iqser-circle-button>
</div>
</div>
<div class="content-inner">
<div class="overlay-shadow"></div>
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
<div class="content-container" iqserHasScrollbar>
<div class="heading-xl" translate="reports-screen.title"></div>
<div class="description" translate="reports-screen.description"></div>
<div class="document-setup">
<div class="all-caps-label" translate="reports-screen.document-setup-heading"></div>
<div translate="reports-screen.document-setup-description"></div>
</div>
<div class="placeholders">
<div class="all-caps-label" translate="reports-screen.table-header.placeholders"></div>
<div class="all-caps-label" translate="reports-screen.table-header.description"></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>
</div>
<div class="right-container" iqserHasScrollbar>
<div class="header">
<div class="heading" translate="reports-screen.report-documents"></div>
<iqser-circle-button
(action)="fileInput.click()"
*ngIf="permissionsService.isAdmin()"
[tooltip]="'reports-screen.upload-document' | translate"
icon="iqser:upload"
></iqser-circle-button>
</div>
<div
(click)="fileInput.click()"
*ngIf="permissionsService.isAdmin() && !availableTemplates?.length"
class="template upload-button"
translate="reports-screen.upload-document"
></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)"
[iconSize]="12"
[size]="18"
icon="iqser:download"
></iqser-circle-button>
<iqser-circle-button
(action)="deleteTemplate(template)"
*ngIf="permissionsService.isAdmin()"
[iconSize]="12"
[size]="18"
icon="iqser:trash"
></iqser-circle-button>
</div>
</div>
</div>
</div>
</section>
<input #fileInput (change)="uploadTemplate($event)" hidden type="file" />

View File

@ -0,0 +1,60 @@
<div class="content-container" iqserHasScrollbar>
<div class="heading-xl" translate="reports-screen.title"></div>
<div class="description" translate="reports-screen.description"></div>
<div class="document-setup">
<div class="all-caps-label" translate="reports-screen.document-setup-heading"></div>
<div translate="reports-screen.document-setup-description"></div>
</div>
<div *ngIf="placeholders$ | async as placeholders" class="placeholders">
<div class="all-caps-label" translate="reports-screen.table-header.placeholders"></div>
<div class="all-caps-label" translate="reports-screen.table-header.description"></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>
</div>
<div *ngIf="availableTemplates$ | async as availableTemplates" class="right-container" iqserHasScrollbar>
<div class="header">
<div class="heading" translate="reports-screen.report-documents"></div>
<iqser-circle-button
(action)="fileInput.click()"
*ngIf="permissionsService.isAdmin()"
[tooltip]="'reports-screen.upload-document' | translate"
icon="iqser:upload"
></iqser-circle-button>
</div>
<div
(click)="fileInput.click()"
*ngIf="permissionsService.isAdmin() && !availableTemplates?.length"
class="template upload-button"
translate="reports-screen.upload-document"
></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)" [iconSize]="12" [size]="18" icon="iqser:download"></iqser-circle-button>
<iqser-circle-button
(action)="deleteTemplate(template)"
*ngIf="permissionsService.isAdmin()"
[iconSize]="12"
[size]="18"
icon="iqser:trash"
></iqser-circle-button>
</div>
</div>
</div>
<input #fileInput (change)="uploadTemplate($event)" hidden type="file" />

View File

@ -1,6 +1,12 @@
@use 'variables'; @use 'variables';
@use 'common-mixins'; @use 'common-mixins';
:host {
flex-grow: 1;
overflow: hidden;
display: flex;
}
.content-container, .content-container,
.right-container { .right-container {
flex: 1; flex: 1;

View File

@ -1,4 +1,4 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { IPlaceholdersResponse, IReportTemplate } from '@red/domain'; import { IPlaceholdersResponse, IReportTemplate } from '@red/domain';
import { download } from '@utils/file-download-utils'; import { download } from '@utils/file-download-utils';
import { ConfirmationDialogInput, LoadingService, Toaster } from '@iqser/common-ui'; import { ConfirmationDialogInput, LoadingService, Toaster } from '@iqser/common-ui';
@ -6,13 +6,13 @@ import { PermissionsService } from '@services/permissions.service';
import { import {
generalPlaceholdersDescriptionsTranslations, generalPlaceholdersDescriptionsTranslations,
placeholdersDescriptionsTranslations, placeholdersDescriptionsTranslations,
} from '../../translations/placeholders-descriptions-translations'; } from '../../../translations/placeholders-descriptions-translations';
import { removeBraces } from '@utils/functions'; import { removeBraces } from '@utils/functions';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../../services/admin-dialog.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { ReportTemplateService } from '@services/report-template.service'; import { ReportTemplateService } from '@services/report-template.service';
import { firstValueFrom } from 'rxjs'; import { BehaviorSubject, firstValueFrom } from 'rxjs';
interface Placeholder { interface Placeholder {
placeholder: string; placeholder: string;
@ -27,10 +27,11 @@ const placeholderTypes: PlaceholderType[] = ['generalPlaceholders', 'fileAttribu
selector: 'redaction-reports-screen', selector: 'redaction-reports-screen',
templateUrl: './reports-screen.component.html', templateUrl: './reports-screen.component.html',
styleUrls: ['./reports-screen.component.scss'], styleUrls: ['./reports-screen.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class ReportsScreenComponent implements OnInit { export class ReportsScreenComponent implements OnInit {
placeholders: Placeholder[]; placeholders$ = new BehaviorSubject<Placeholder[]>([]);
availableTemplates: IReportTemplate[]; availableTemplates$ = new BehaviorSubject<IReportTemplate[]>([]);
@ViewChild('fileInput') private _fileInput: ElementRef; @ViewChild('fileInput') private _fileInput: ElementRef;
@ -85,7 +86,7 @@ export class ReportsScreenComponent implements OnInit {
} }
private async _uploadTemplate($event) { private async _uploadTemplate($event) {
const file = $event.target.files[0]; const file: File = $event.target.files[0];
if (!this._isValidFile(file)) { if (!this._isValidFile(file)) {
this._toaster.error(_('reports-screen.invalid-upload')); this._toaster.error(_('reports-screen.invalid-upload'));
@ -94,7 +95,7 @@ export class ReportsScreenComponent implements OnInit {
const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId;
if (this.availableTemplates.some(template => template.fileName === file.name)) { if (this.availableTemplates$.value.some(template => template.fileName === file.name)) {
const data = new ConfirmationDialogInput({ const data = new ConfirmationDialogInput({
title: _('confirmation-dialog.report-template-same-name.title'), title: _('confirmation-dialog.report-template-same-name.title'),
question: _('confirmation-dialog.report-template-same-name.question'), question: _('confirmation-dialog.report-template-same-name.question'),
@ -147,8 +148,10 @@ export class ReportsScreenComponent implements OnInit {
} }
private async _loadReportTemplates() { private async _loadReportTemplates() {
this.availableTemplates = await firstValueFrom( this.availableTemplates$.next(
this._reportTemplateService.getAvailableReportTemplates(this._dossierTemplatesService.activeDossierTemplateId), await firstValueFrom(
this._reportTemplateService.getAvailableReportTemplates(this._dossierTemplatesService.activeDossierTemplateId),
),
); );
} }
@ -156,12 +159,14 @@ export class ReportsScreenComponent implements OnInit {
const placeholdersResponse: IPlaceholdersResponse = await firstValueFrom( const placeholdersResponse: IPlaceholdersResponse = await firstValueFrom(
this._reportTemplateService.getAvailablePlaceholders(this._dossierTemplatesService.activeDossierTemplateId), this._reportTemplateService.getAvailablePlaceholders(this._dossierTemplatesService.activeDossierTemplateId),
); );
this.placeholders = placeholderTypes.flatMap(type => this.placeholders$.next(
placeholdersResponse[type].map(placeholder => ({ placeholderTypes.flatMap(type =>
placeholder, placeholdersResponse[type].map(placeholder => ({
descriptionTranslation: this._getPlaceholderDescriptionTranslation(type, placeholder), placeholder,
attributeName: this._getAttributeName(placeholder), descriptionTranslation: this._getPlaceholderDescriptionTranslation(type, placeholder),
})), attributeName: this._getAttributeName(placeholder),
})),
),
); );
} }

View File

@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { SharedModule } from '../../../shared/shared.module';
import { ReportsScreenComponent } from './reports-screen/reports-screen.component';
const routes = [{ path: '', component: ReportsScreenComponent }];
@NgModule({
declarations: [ReportsScreenComponent],
imports: [RouterModule.forChild(routes), CommonModule, SharedModule],
})
export class ReportsModule {}

View File

@ -1,4 +1,4 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
:host { :host {
display: flex; display: flex;

View File

@ -1,5 +1,5 @@
@use 'libs/common-ui/src/assets/styles/common-mixins'; @use 'common-mixins';
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
.search-container { .search-container {
margin-top: 16px; margin-top: 16px;

View File

@ -1,4 +1,4 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
.view-mode-selection { .view-mode-selection {
border-right: 1px solid variables.$separator; border-right: 1px solid variables.$separator;

View File

@ -1,4 +1,4 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
.annotation-actions { .annotation-actions {
display: none; display: none;

View File

@ -1,5 +1,5 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
@use 'libs/common-ui/src/assets/styles/common-mixins'; @use 'common-mixins';
:host { :host {
display: block; display: block;

View File

@ -1,5 +1,5 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
@use 'libs/common-ui/src/assets/styles/common-mixins'; @use 'common-mixins';
.read-only { .read-only {
padding: 13px 16px; padding: 13px 16px;

View File

@ -1,5 +1,5 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
@use 'libs/common-ui/src/assets/styles/common-mixins'; @use 'common-mixins';
:host { :host {
height: 100%; height: 100%;

View File

@ -1,4 +1,4 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
.page-wrapper { .page-wrapper {
color: variables.$accent; color: variables.$accent;

View File

@ -1,4 +1,4 @@
@use 'apps/red-ui/src/assets/styles/variables'; @use 'variables';
.page { .page {
display: flex; display: flex;