Skip to content

Commit 85f755a

Browse files
authored
Merge pull request #936 from utmstack/bugfix/10.5.18/updating-report-module
Bugfix/10.5.18/updating report module
2 parents 92870ec + 456e333 commit 85f755a

File tree

70 files changed

+2239
-158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2239
-158
lines changed

backend/src/main/java/com/park/utmstack/domain/compliance/UtmComplianceReportConfig.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ public class UtmComplianceReportConfig implements Serializable {
8383
@Column(name = "config_url")
8484
private String configUrl;
8585

86+
@Column(name = "config_report_note")
87+
private String configReportNote;
88+
89+
@Column(name = "config_report_name", length = 50)
90+
private String configReportName;
91+
8692
@Transient
8793
@JsonSerialize
8894
@JsonDeserialize
@@ -303,4 +309,20 @@ public UtmDashboard getAssociatedDashboard() {
303309
public void setAssociatedDashboard(UtmDashboard associatedDashboard) {
304310
this.associatedDashboard = associatedDashboard;
305311
}
312+
313+
public String getConfigReportNote() {
314+
return configReportNote;
315+
}
316+
317+
public void setConfigReportNote(String configReportNote) {
318+
this.configReportNote = configReportNote;
319+
}
320+
321+
public String getConfigReportName() {
322+
return configReportName;
323+
}
324+
325+
public void setConfigReportName(String configReportName) {
326+
this.configReportName = configReportName;
327+
}
306328
}

backend/src/main/java/com/park/utmstack/service/compliance/config/UtmComplianceReportConfigService.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.park.utmstack.util.exceptions.UtmPageNumberNotSupported;
1010
import org.springframework.dao.DataIntegrityViolationException;
1111
import org.springframework.data.domain.Page;
12+
import org.springframework.data.domain.PageImpl;
1213
import org.springframework.data.domain.Pageable;
1314
import org.springframework.stereotype.Service;
1415
import org.springframework.transaction.annotation.Transactional;
@@ -79,34 +80,51 @@ public void deleteReportsByStandardIdAndIdNotIn(Long standardId, List<Long> repo
7980
complianceReportConfigRepository.deleteReportsByStandardIdAndIdNotIn(standardId, reportIds);
8081
}
8182

82-
public List<UtmComplianceReportConfig> getReportsByFilters(Long standardId, String solution, Long sectionId, Pageable pageable) throws
83-
UtmPageNumberNotSupported {
83+
public Page<UtmComplianceReportConfig> getReportsByFilters(Long standardId, String solution, Long sectionId, Pageable pageable)
84+
throws UtmPageNumberNotSupported {
85+
// Construcción del script principal
8486
StringBuilder script = new StringBuilder(
85-
"SELECT cfg.* FROM utm_compliance_report_config cfg INNER JOIN utm_compliance_standard_section sec ON cfg.standard_section_id=sec.id INNER JOIN utm_compliance_standard st ON sec.standard_id=st.id");
87+
"SELECT cfg.* FROM utm_compliance_report_config cfg " +
88+
"INNER JOIN utm_compliance_standard_section sec ON cfg.standard_section_id = sec.id " +
89+
"INNER JOIN utm_compliance_standard st ON sec.standard_id = st.id");
90+
91+
StringBuilder countScript = new StringBuilder(
92+
"SELECT COUNT(cfg.id) FROM utm_compliance_report_config cfg " +
93+
"INNER JOIN utm_compliance_standard_section sec ON cfg.standard_section_id = sec.id " +
94+
"INNER JOIN utm_compliance_standard st ON sec.standard_id = st.id");
8695

8796
boolean hasWhere = false;
8897

8998
if (standardId != null) {
9099
hasWhere = true;
91-
script.append(" WHERE").append(" st.id = ").append(standardId);
100+
script.append(" WHERE st.id = ").append(standardId);
101+
countScript.append(" WHERE st.id = ").append(standardId);
92102
}
93103

94104
if (StringUtils.hasText(solution)) {
95105
String condition = "cfg.config_solution ILIKE '%" + solution + "%'";
96106
script.append(hasWhere ? " AND " : " WHERE ").append(condition);
107+
countScript.append(hasWhere ? " AND " : " WHERE ").append(condition);
97108
hasWhere = true;
98109
}
99110

100111
if (sectionId != null) {
101112
String condition = "sec.id = " + sectionId;
102113
script.append(hasWhere ? " AND " : " WHERE ").append(condition);
114+
countScript.append(hasWhere ? " AND " : " WHERE ").append(condition);
103115
}
104116

105-
return em.createNativeQuery(script.toString(), UtmComplianceReportConfig.class).setFirstResult(
106-
UtilPagination.getFirstForNativeSql(pageable.getPageSize(), pageable.getPageNumber())).setMaxResults(
107-
pageable.getPageSize()).getResultList();
117+
List<UtmComplianceReportConfig> results = em.createNativeQuery(script.toString(), UtmComplianceReportConfig.class)
118+
.setFirstResult(UtilPagination.getFirstForNativeSql(pageable.getPageSize(), pageable.getPageNumber()))
119+
.setMaxResults(pageable.getPageSize())
120+
.getResultList();
121+
122+
long total = ((Number) em.createNativeQuery(countScript.toString()).getSingleResult()).longValue();
123+
124+
return new PageImpl<>(results, pageable, total);
108125
}
109126

127+
110128
public void deleteAllByConfigSolutionAndSectionIdAndDashboardId(String configSolution, Long sectionId, Long dashboardId) {
111129
complianceReportConfigRepository.deleteAllByConfigSolutionAndStandardSectionIdAndDashboardId(configSolution, sectionId, dashboardId);
112130
}

backend/src/main/java/com/park/utmstack/web/rest/compliance/config/UtmComplianceReportConfigResource.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,14 @@ public ResponseEntity<List<UtmComplianceReportConfig>> getReportsByFilters(@Requ
176176
Pageable pageable) {
177177
final String ctx = CLASS_NAME + ".getReportsByFilters";
178178
try {
179-
List<UtmComplianceReportConfig> page = complianceReportConfigService.getReportsByFilters(standardId, solution, sectionId, pageable);
179+
Page<UtmComplianceReportConfig> page = complianceReportConfigService.getReportsByFilters(standardId, solution, sectionId, pageable);
180180

181181
if (!Objects.isNull(expandDashboard) && expandDashboard) {
182182
for (UtmComplianceReportConfig report : page)
183183
dashboardVisualizationService.findAllByIdDashboard(report.getDashboardId()).ifPresent(report::setDashboard);
184184
}
185-
return ResponseEntity.ok().body(page);
185+
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/utm-asset-groups/searchGroupsByFilter");
186+
return ResponseEntity.ok().headers(headers).body(page.getContent());
186187
} catch (Exception e) {
187188
String msg = ctx + ": " + e.getMessage();
188189
log.error(msg);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<databaseChangeLog
3+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
6+
7+
<changeSet id="20241120001" author="Manuel">
8+
<sql dbms="postgresql" splitStatements="true" stripComments="true">
9+
10+
UPDATE utm_menu
11+
SET name = 'Overview',
12+
url = 'compliance/report-viewer'
13+
WHERE id = 505;
14+
15+
ALTER TABLE utm_compliance_report_config
16+
ADD COLUMN config_report_note TEXT;
17+
18+
ALTER TABLE utm_compliance_report_config
19+
ADD COLUMN config_report_name varchar(250);
20+
21+
</sql>
22+
</changeSet>
23+
</databaseChangeLog>

frontend/src/app/app.component.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ export class AppComponent implements OnInit {
120120
}
121121

122122
isInExportRoute() {
123-
return this.router.url.includes('dashboard/export/') || this.router.url.includes('dashboard/export-compliance') ||
123+
return this.router.url.includes('dashboard/export/') ||
124+
this.router.url.includes('dashboard/export-compliance') ||
125+
this.router.url.includes('compliance/print-view') ||
124126
this.router.url.includes('/getting-started') ||
125127
this.router.url.includes('/dashboard/export-report/') || this.iframeView || this.router.url.includes('/data/alert/detail/');
126128
}

frontend/src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {NewAlertBehavior} from './shared/behaviors/new-alert.behavior';
3535
import {TimezoneFormatService} from './shared/services/utm-timezone.service';
3636
import {UtmSharedModule} from './shared/utm-shared.module';
3737
import {AccountService} from "./core/auth/account.service";
38+
import {AlertManagementSharedModule} from "./data-management/alert-management/shared/alert-management-shared.module";
3839

3940
export function initTimezoneFormat(timezoneService: TimezoneFormatService) {
4041
return () => timezoneService.loadTimezoneAndFormat();
@@ -73,6 +74,7 @@ export function initTimezoneFormat(timezoneService: TimezoneFormatService) {
7374
Ng2TelInputModule,
7475
NgxFlagIconCssModule,
7576
Ng2Webstorage.forRoot(),
77+
AlertManagementSharedModule,
7678
],
7779
providers: [
7880
LocalStorageService,
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.full-height {
2+
height: 90vh;
3+
overflow-y: auto;
4+
}
5+
::ng-deep app-compliance-report-viewer gridster {
6+
background-color: unset !important;
7+
}
8+
9+
.section-icon {
10+
width: 50%;
11+
padding-bottom: 5px;
12+
transition: border-color 0.3s ease, background-color 0.3s ease, transform 0.1s ease;
13+
}
14+
15+
.section-icon img {
16+
width: 1.5rem;
17+
}
18+
19+
.section-icon i {
20+
font-size: 1.5rem;
21+
color: #333;
22+
}
23+
24+
.section-label {
25+
font-size: 0.9rem;
26+
font-weight: 500;
27+
color: #333;
28+
text-align: center;
29+
}
30+
31+
.active-section {
32+
background-color: #e9e9e9;
33+
border-bottom: 3px solid #28a745;
34+
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.2);
35+
}
36+
37+
.section-icon:hover {
38+
background-color: #f0f0f0;
39+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
40+
}
41+
42+
43+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<div class="container-fluid p-2">
2+
<div class="d-flex justify-content-between align-items-center mb-2 row no-gutters">
3+
<div class="col-md-6">
4+
<h5 class="card-title mb-0 text-uppercase label-header">Reports Templates {{ standard ? ': ' + standard.standardName : '' }}</h5>
5+
</div>
6+
<div class="col-md-6">
7+
<div *appHasAnyAuthority="admin" class="d-flex justify-content-end">
8+
<button (click)="manageStandards()" class="btn utm-button utm-button-primary">
9+
<i class="icon-cog3 mr-1"></i> Change framework
10+
</button>
11+
<a (click)="exportToPdf()" class="btn utm-button utm-button-primary ml-2">
12+
<i [ngClass]="pdfExport ? 'icon-download10' : 'icon-file-pdf'" class="mr-1"></i>
13+
{{ pdfExport ? 'Generating...' : 'Save to PDF' }}
14+
</a>
15+
</div>
16+
</div>
17+
</div>
18+
19+
<div class="row m-0">
20+
<div style="max-width: 300px" class="col-lg-3 col-md-3 col-sm-12 pl-0 pr-0 full-height mr-2">
21+
<div class="h-100 card m-0">
22+
<div class="card-header header-elements-sm-inline p-0 bg-white card-header-title">
23+
<div class="d-flex justify-content-between w-100">
24+
<div class="section-icon d-flex flex-column align-items-center cursor-pointer pt-2"
25+
[ngClass]="{'active-section': action === 'compliance'}"
26+
(click)="selectAction('compliance')">
27+
<img src="assets/icons/compliance/regulatory-compliance.png" alt="compliance">
28+
<span class="section-label">Compliance</span>
29+
</div>
30+
31+
<div class="section-icon d-flex flex-column align-items-center cursor-pointer pt-2"
32+
[ngClass]="{'active-section': action === 'reports'}"
33+
(click)="selectAction('reports')">
34+
<img src="assets/icons/compliance/analysis.png" alt="reports">
35+
<span class="section-label">Reports</span>
36+
</div>
37+
</div>
38+
</div>
39+
40+
<div class="card-body p-0 m-0 bg-light">
41+
<div *ngFor="let section of sections$ | async as sections; let index = index; trackBy: trackFn" class="d-flex flex-column">
42+
<app-utm-cp-section [section]="section"
43+
[action]="action"
44+
[loadFirst]="index === activeIndexSection"
45+
[index]="index"
46+
(isActive)="onChangeSectionActive($event, sections)"
47+
[expandable]="action==='reports'">
48+
</app-utm-cp-section>
49+
</div>
50+
</div>
51+
</div>
52+
</div>
53+
54+
<div class="flex-grow-1">
55+
<div class="h-100 card m-0">
56+
<app-compliance-reports-view [section]="activeSection" *ngIf="action === 'compliance' && activeSection"></app-compliance-reports-view>
57+
<app-compliance-result-view *ngIf="action === 'reports'" [showExport]="false" [template]="'compliance'" ></app-compliance-result-view>
58+
</div>
59+
</div>
60+
</div>
61+
</div>

0 commit comments

Comments
 (0)